Névfeloldás

A következőkre vonatkozik:jelölje be az igennel jelölt jelölőnégyzetet Databricks SQL jelölje be az igennel jelölt jelölőnégyzetet Databricks Runtime

A névfeloldás az a folyamat, amellyel az azonosítók adott oszlop-, mező-, paraméter- vagy táblahivatkozásokra lesznek feloldva.

Oszlop, mező, paraméter és változófelbontás

A kifejezések azonosítói az alábbiak bármelyikére hivatkozhatnak:

  • Oszlopnév nézet, táblázat, közös táblakifejezés (CTE) vagy oszlop_alias alapján.
  • Mezőnév vagy térképkulcs egy struccban vagy térképen belül. A mezőknek és kulcsoknak mindig meg kell jelölniük a hovatartozásukat.
  • Egy SQL-felhasználó által definiált függvény vagy SQL-eljárásparaméterneve.
  • Munkamenet- vagy SQL-szkript helyi változónév.
  • Egy speciális függvény, például current_user vagy current_date, amely nem követeli meg () használatát.
  • A(z) DEFAULT kulcsszó olyan kontextusokban használatos, mint a INSERT, UPDATE, MERGE vagy SET VARIABLE, hogy egy oszlop vagy változó értékét alapértelmezettként állítsa be.

A névfeloldás a következő alapelveket alkalmazza:

  • A legközelebbi egyező hivatkozás nyer, és
  • Oszlopok és paraméterek nyernek a mezők és kulcsok felett.

Az azonosítók egy adott hivatkozásra történő feloldása a következő szabályok szerint történik:

  1. Helyi hivatkozások

    1. Oszlop hivatkozás

      Egyeztesse az azonosítót, amely minősíthető, a táblahivatkozás oszlopnevével.

      Ha egynél több ilyen egyezés van, AMBIGUOUS_COLUMN_OR_FIELD hibát jelez.

    2. Paraméter nélküli függvényhivatkozás

      Ha az azonosító nem minősített, és megegyezik current_user, current_datevagy current_timestamp: Oldja fel a függvények egyikeként.

    3. Oszlop ALAPÉRTELMEZETT specifikáció

      Ha az azonosító nincs minősítve, megegyezik default-val/vel, és az egész kifejezést alkotja a UPDATE SET, INSERT VALUES vagy MERGE WHEN [NOT] MATCHED kontextusában: Oldja fel a céltábla megfelelő DEFAULT értékeként a INSERT, UPDATE vagy MERGE esetében.

    4. Strukturálási mező vagy térképkulcs referenciája

      Ha az azonosító minősített, az alábbi lépéseknek megfelelően törekedjen egy mező vagy térképkulcs egyeztetésére:

      Egy. Távolítsa el az utolsó azonosítót, és kezelje mezőként vagy kulcsként. B. A fennmaradó részt egyeztesse a táblahivatkozás egy oszlopávalFROM clause.

      Ha egynél több ilyen egyezés van, AMBIGUOUS_COLUMN_OR_FIELD hibát jelez.

      Ha van egyezés, és az oszlop a következő:

      • STRUCT: Egyezzen a mezővel.

        Ha a mező nem feleltethető meg, FIELD_NOT_FOUND hibát jelez.

        Ha egynél több mező van, AMBIGUOUS_COLUMN_OR_FIELD hibát jelez.

      • MAP: Hibát jelez, ha a kulcs meg van jelölve.

        Futásidejű hiba akkor fordulhat elő, ha a kulcs valójában nem szerepel a térképen.

      • Bármilyen más típus: Hiba felmerülése. C. Ismételje meg az előző lépést, hogy eltávolítsa az utolsó azonosítót, mint mezőt. Alkalmazza a szabályokat (A) és (B), amíg van egy azonosító, amelyet oszlopként kell értelmezni.

  2. Oldalirányú oszlop aliasolása

    A következőkre vonatkozik:jelölje be az igennel jelölt jelölőnégyzetet Databricks SQL jelölje be az igennel jelölt jelölőnégyzetet Databricks Runtime 12.2 LTS és újabb

    Ha a kifejezés egy SELECT listában található, a vezető azonosító feleljen meg egy előző oszlop alias-nak azon a SELECT listán.

    Ha egynél több ilyen egyezés van, AMBIGUOUS_LATERAL_COLUMN_ALIAS hibát jelez.

    Hasonlítsa össze minden fennmaradó azonosítót mezőként vagy térképkulcsként, és adjon ki FIELD_NOT_FOUND vagy AMBIGUOUS_COLUMN_OR_FIELD hibát, ha nem lehet őket azonosítani.

  3. Korreláció

    • OLDALSÓ

      Ha a lekérdezést egy LATERAL kulcsszó előzi meg, alkalmazza az 1.a és az 1.d szabályt, figyelembe véve a lekérdezést tartalmazó és a lekérdezést megelőző FROMtáblahivatkozásokatLATERAL.

    • Rendszeres

      Ha a lekérdezés egy skaláris al-lekérdezés, IN vagy EXISTS al-lekérdezés, akkor alkalmazza az 1.a, 1.d és 2 szabályt, figyelembe véve a táblahivatkozásokat a lekérdezés FROM záradékában.

  4. Beágyazott korreláció

    Alkalmazza újra a 3. szabályt a lekérdezés beágyazási szintjein ismétlődően.

  5. FOR hurok

    Ha az utasítás egy FOR ciklusban található:

    Egy. Párosítsa az azonosítót a FOR ciklus lekérdezés egyik oszlopával. Ha az azonosító minősített, a minősítőnek meg kell egyeznie a FOR hurokváltozó nevével, ha meg van adva. B. Ha az azonosító minősített, egyeznie kell egy paraméter mező- vagy térképkulcsával az 1.c szabályt követve

  6. Összetett utasítás

    Ha az utasítás összetett utasításban található:

    Egy. Rendelje az azonosítót az összetett utasításban deklarált változóhoz. Ha az azonosító meg van határozva, a minősítőnek meg kell egyeznie az összetett utasítás címkéjével, ha meg lett határozva. B. Ha az azonosító minősített, egy változó mezőjéhez vagy térképkulcsához illeszkedik az 1.c szabály szerint.

  7. beágyazott összetett utasítás vagy FOR hurok

    Ismét alkalmazza az 5. és 6. szabályt, ismételve az összetett utasítás beágyazási szintjein.

  8. Rutinparaméterek

    Ha a kifejezés egy CREATE FUNCTIONCREATE PROCEDURE utasítás része:

    1. Rendelje hozzá az azonosítót egy paraméternévhez. Ha az azonosító minősített, a minősítőnek meg kell egyeznie a rutin nevével.
    2. Ha az azonosító minősített, egyeznie kell egy paraméter mező- vagy térképkulcsával az 1.c szabályt követve
  9. munkamenet-változók

    1. Párosítsa az azonosítót egy változónévhez. Ha az azonosító minősített, a minősítőnek session-nak vagy system.session-nek kell lennie.
    2. Ha az azonosító minősített, egy változó mezőjéhez vagy térképkulcsához illeszkedik az 1.c szabály szerint.

Névfeloldás a következőben: HAVING, ORDER BYés QUALIFY

A HAVING, ORDER BYés QUALIFY záradékok hivatkozhatnak a SELECT listából származó nevekre, valamint az alapul szolgáló táblák oszlopaira. Ha az egyik záradékban szereplő név megegyezik a lista és a SELECT tábla oszlopában lévő oszlop aliasával, a záradékok másképp oldják fel a kétértelműséget:

  • ORDER BYA lista aliasátSELECT részesíti előnyben a táblázat oszlopában.
  • HAVING a táblázat oszlopát részesíti előnyben a lista aliasa SELECT helyett.
  • QUALIFY A táblázat oszlopát részesíti előnyben a SELECT lista aliasával szemben (ugyanaz, mint HAVING).

Példák

> CREATE OR REPLACE TEMPORARY VIEW t(a, b) AS VALUES (1, 10), (2, 20), (3, 30);

-- ORDER BY prefers the alias over the column.
-- 'a' in ORDER BY refers to the alias (-a), not column 'a',
-- so the row with the largest column 'a' comes first.
> SELECT -a AS a FROM t ORDER BY a LIMIT 1;
  -3

-- HAVING prefers the column over the alias.
-- 'a' in HAVING refers to column 'a', not the alias sum(b).
> SELECT sum(b) AS a FROM t GROUP BY a HAVING a > 1;
  20
  30

-- QUALIFY prefers the column over the alias (same as HAVING).
-- 'a' in QUALIFY refers to column 'a', not the alias -row_number().
> SELECT -row_number() OVER (ORDER BY b) AS a FROM t QUALIFY a > 1;
  -2
  -3

Mező kinyerési és névfeloldási prioritása

Ha egy minősített név , például a.b használt HAVING vagy ORDER BY, a fenti prioritási szabályok továbbra is érvényesek, de egy további szempont: az előnyben részesített jelöltnek támogatnia kell a strukturált mező vagy a térképkulcs kinyerésének támogatását. Ha nem, akkor helyette a másik jelöltet használja a rendszer.

Ha például az alias a egyszerűINT, de a tábla oszlopa aSTRUCT mezővel rendelkezőx, akkor az oszlopot azért választja ORDER BY ki, STRUCT mert egy mező nem nyerhető ki az INT aliasból. Ezzel szemben, ha a tábla oszlopa egyszerű INT , és az alias egy STRUCT, HAVING akkor a mező kinyeréséhez visszakerül az aliasra.

Példák

-- ORDER BY fallback: the table column is a STRUCT, the alias is an INT.
-- ORDER BY normally prefers the alias, but the alias (INT) cannot have
-- field 'x' extracted, so the struct column wins.
> CREATE OR REPLACE TEMPORARY VIEW s1(a) AS VALUES (named_struct('x', 1)), (named_struct('x', 2));

> SELECT -a.x AS a FROM s1 ORDER BY a.x LIMIT 1;
  -1

-- HAVING fallback: the table column is an INT, the alias is a STRUCT.
-- HAVING normally prefers the table column, but the column (INT) cannot have
-- field 'x' extracted, so the alias wins.
> CREATE OR REPLACE TEMPORARY VIEW s2(a) AS VALUES (1), (2);

> SELECT named_struct('x', 2) AS a FROM s2 GROUP BY a HAVING a.x > 1;
  {"x":2}
  {"x":2}

-- Map key extraction follows the same rules.
-- ORDER BY fallback: alias (INT) cannot have key extracted, map column wins.
> CREATE OR REPLACE TEMPORARY VIEW s3(a) AS VALUES (map('key', 100)), (map('key', 200));

> SELECT -a['key'] AS a FROM s3 ORDER BY a['key'] LIMIT 1;
  -100

-- HAVING fallback: column (INT) cannot have key extracted, map alias wins.
> CREATE OR REPLACE TEMPORARY VIEW s4(a) AS VALUES (100), (200);

> SELECT map('key', 200) AS a FROM s4 GROUP BY a HAVING a['key'] > 100;
  {"key":200}
  {"key":200}

Korlátozások

A potenciálisan költséges korrelált lekérdezések végrehajtásának megakadályozása érdekében az Azure Databricks egy szintre korlátozza a támogatott korrelációt. Ez a korlátozás az SQL-függvények paraméterhivatkozásaira is vonatkozik.

Példák

-- Differentiating columns and fields
> SELECT a FROM VALUES(1) AS t(a);
 1

> SELECT t.a FROM VALUES(1) AS t(a);
 1

> SELECT t.a FROM VALUES(named_struct('a', 1)) AS t(t);
 1

-- A column takes precedence over a field
> SELECT t.a FROM VALUES(named_struct('a', 1), 2) AS t(t, a);
 2

-- Implict lateral column alias
> SELECT c1 AS a, a + c1 FROM VALUES(2) AS T(c1);
 2  4

-- A local column reference takes precedence, over a lateral column alias
> SELECT c1 AS a, a + c1 FROM VALUES(2, 3) AS T(c1, a);
 2  5

-- A scalar subquery correlation to S.c3
> SELECT (SELECT c1 FROM VALUES(1, 2) AS t(c1, c2)
           WHERE t.c2 * 2 = c3)
    FROM VALUES(4) AS s(c3);
 1

-- A local reference takes precedence over correlation
> SELECT (SELECT c1 FROM VALUES(1, 2, 2) AS t(c1, c2, c3)
           WHERE t.c2 * 2 = c3)
    FROM VALUES(4) AS s(c3);
  NULL

-- An explicit scalar subquery correlation to s.c3
> SELECT (SELECT c1 FROM VALUES(1, 2, 2) AS t(c1, c2, c3)
           WHERE t.c2 * 2 = s.c3)
    FROM VALUES(4) AS s(c3);
 1

-- Correlation from an EXISTS predicate to t.c2
> SELECT c1 FROM VALUES(1, 2) AS T(c1, c2)
    WHERE EXISTS(SELECT 1 FROM VALUES(2) AS S(c2)
                  WHERE S.c2 = T.c2);
 1

-- Attempt a lateral correlation to t.c2
> SELECT c1, c2, c3
    FROM VALUES(1, 2) AS t(c1, c2),
         (SELECT c3 FROM VALUES(3, 4) AS s(c3, c4)
           WHERE c4 = c2 * 2);
 [UNRESOLVED_COLUMN] `c2`

-- Successsful usage of lateral correlation with keyword LATERAL
> SELECT c1, c2, c3
    FROM VALUES(1, 2) AS t(c1, c2),
         LATERAL(SELECT c3 FROM VALUES(3, 4) AS s(c3, c4)
                  WHERE c4 = c2 * 2);
 1  2  3

-- Referencing a parameter of a SQL function
> CREATE OR REPLACE TEMPORARY FUNCTION func(a INT) RETURNS INT
    RETURN (SELECT c1 FROM VALUES(1) AS T(c1) WHERE c1 = a);
> SELECT func(1), func(2);
 1  NULL

-- A column takes precedence over a parameter
> CREATE OR REPLACE TEMPORARY FUNCTION func(a INT) RETURNS INT
    RETURN (SELECT a FROM VALUES(1) AS T(a) WHERE t.a = a);
> SELECT func(1), func(2);
 1  1

-- Qualify the parameter with the function name
> CREATE OR REPLACE TEMPORARY FUNCTION func(a INT) RETURNS INT
    RETURN (SELECT a FROM VALUES(1) AS T(a) WHERE t.a = func.a);
> SELECT func(1), func(2);
 1  NULL

-- Lateral alias takes precedence over correlated reference
> SELECT (SELECT c2 FROM (SELECT 1 AS c1, c1 AS c2) WHERE c2 > 5)
    FROM VALUES(6) AS t(c1)
  NULL

-- Lateral alias takes precedence over function parameters
> CREATE OR REPLACE TEMPORARY FUNCTION func(x INT)
    RETURNS TABLE (a INT, b INT, c DOUBLE)
    RETURN SELECT x + 1 AS x, x
> SELECT * FROM func(1)
  2 2

-- All together now
> CREATE OR REPLACE TEMPORARY VIEW lat(a, b) AS VALUES('lat.a', 'lat.b');

> CREATE OR REPLACE TEMPORARY VIEW frm(a) AS VALUES('frm.a');

> CREATE OR REPLACE TEMPORARY FUNCTION func(a INT, b int, c int)
  RETURNS TABLE
  RETURN SELECT t.*
    FROM lat,
         LATERAL(SELECT a, b, c
                   FROM frm) AS t;

> VALUES func('func.a', 'func.b', 'func.c');
  a      b      c
  -----  -----  ------
  frm.a  lat.b  func.c

Táblázat- és nézetfeloldás

A táblahivatkozásban szereplő azonosító az alábbiak bármelyike lehet:

  • Állandó tábla vagy nézet a Unity Katalógusban vagy a Hive Metastore-ban
  • Gyakori táblakifejezés (CTE)
  • Ideiglenes nézet vagy ideiglenes tábla

Az azonosító feloldása attól függ, hogy van-e minősítése:

  • Képesített

    Ha az azonosító három részből áll: catalog.schema.relation, akkor egyedi.

    Ha az azonosító két részből áll: schema.relationakkor az egyedivé tétele további SELECT current_catalog() minősítést eredményez.

  • Képzetlen

    1. Gyakori táblakifejezés

      Ha a hivatkozás egy WITH záradék hatókörébe esik, rendelje hozzá az azonosítót egy CTE-hez, kezdve a közvetlenül tartalmazó WITH záradékkal, majd haladjon kifelé.

    2. Ideiglenes nézet vagy ideiglenes tábla

      Egyezzen az azonosítóval az aktuális munkamenetben definiált bármely ideiglenes nézethez vagy ideiglenes táblához.

    3. Megőrzött tábla

      Az azonosítót teljesen minősítse úgy, hogy előre hozzáfűzi a SELECT current_catalog() és SELECT current_schema() eredményét, és állandó kapcsolatként keresse meg.

Ha a reláció nem oldható fel egyetlen táblához, nézethez vagy CTE-hez sem, a Databricks TABLE_OR_VIEW_NOT_FOUND hibát jelez.

Példák

-- Setting up a scenario
> USE CATALOG spark_catalog;
> USE SCHEMA default;

> CREATE TABLE rel(c1 int);
> INSERT INTO rel VALUES(1);

-- An fully qualified reference to rel:
> SELECT c1 FROM spark_catalog.default.rel;
 1

-- A partially qualified reference to rel:
> SELECT c1 FROM default.rel;
 1

-- An unqualified reference to rel:
> SELECT c1 FROM rel;
 1

-- Add a temporary view with a conflicting name:
> CREATE TEMPORARY VIEW rel(c1) AS VALUES(2);

-- For unqualified references the temporary view takes precedence over the persisted table:
> SELECT c1 FROM rel;
 2

-- Temporary views cannot be qualified, so qualifiecation resolved to the table:
> SELECT c1 FROM default.rel;
 1

-- An unqualified reference to a common table expression wins even over a temporary view:
> WITH rel(c1) AS (VALUES(3))
    SELECT * FROM rel;
 3

-- If CTEs are nested, the match nearest to the table reference takes precedence.
> WITH rel(c1) AS (VALUES(3))
    (WITH rel(c1) AS (VALUES(4))
      SELECT * FROM rel);
  4

-- To resolve the table instead of the CTE, qualify it:
> WITH rel(c1) AS (VALUES(3))
    (WITH rel(c1) AS (VALUES(4))
      SELECT * FROM default.rel);
  1

-- For a CTE to be visible it must contain the query
> SELECT * FROM (WITH cte(c1) AS (VALUES(1))
                   SELECT 1),
                cte;
  [TABLE_OR_VIEW_NOT_FOUND] The table or view `cte` cannot be found.

Függvényfeloldás

A függvényhivatkozást a kötelezően hozzá tartozó zárójelek alapján ismerjük fel.

Az alábbiakat oldhatja fel:

A függvénynév feloldása attól függ, hogy kvalifikált-e.

  • Képesített

    Ha a név három részből áll: catalog.schema.function, akkor egyedi.

    Ha a név két részből áll: schema.function, akkor a SELECT current_catalog() eredményével tovább minősítik, hogy egyedi legyen.

    A függvény ezután fel lesz keresve a katalógusban.

  • Képzetlen

    A nem minősített függvénynevek esetében az Azure Databricks egy rögzített sorrendet követ(PATH):

    1. Beépített függvény

      Ha egy ilyen nevű függvény létezik a beépített függvények halmaza között, akkor ezt a függvényt választja ki.

    2. Ideiglenes függvény

      Ha egy ilyen nevű függvény szerepel az ideiglenes függvények halmazában, akkor a függvény lesz kiválasztva.

    3. Perzisztált függvény

      Teljes mértékben kvalifikálja a függvény nevét, azáltal, hogy előtte hozzáadja a SELECT current_catalog() és SELECT current_schema() eredményét, majd keresse meg perzisztens függvényként.

Ha a függvény nem oldható meg, az Azure Databricks hibát jelez UNRESOLVED_ROUTINE .

Példák

> USE CATALOG spark_catalog;
> USE SCHEMA default;

-- Create a function with the same name as a builtin
> CREATE FUNCTION concat(a STRING, b STRING) RETURNS STRING
    RETURN b || a;

-- unqualified reference resolves to the builtin CONCAT
> SELECT concat('hello', 'world');
 helloworld

-- Qualified reference resolves to the persistent function
> SELECT default.concat('hello', 'world');
 worldhello

-- Create a persistent function
> CREATE FUNCTION func(a INT, b INT) RETURNS INT
    RETURN a + b;

-- The persistent function is resolved without qualifying it
> SELECT func(4, 2);
 6

-- Create a conflicting temporary function
> CREATE FUNCTION func(a INT, b INT) RETURNS INT
    RETURN a / b;

-- The temporary function takes precedent
> SELECT func(4, 2);
 2

-- To resolve the persistent function it now needs qualification
> SELECT spark_catalog.default.func(4, 3);
 6