Namnmatchning

Gäller för: markerad ja Databricks SQL markerad ja Databricks Runtime

Namnmatchning är den process genom vilken identifierare matchas till specifika kolumn-, fält-, parameter- eller tabellreferenser.

Kolumn, fält, parameter och variabelmatchning

Identifierare i uttryck kan vara referenser till något av följande:

  • Kolumnnamn baserat på en vy, tabell, ett vanligt tabelluttryck (CTE) eller en column_alias.
  • Fältnamn eller kartnyckel i en struct eller karta. Fält och nycklar kan aldrig vara okvalificerade.
  • Parameternamn för en SQL-användardefinierad funktion.
  • Variabelnamn.
  • En särskild funktion som current_user eller current_date som inte kräver användning av ().
  • Nyckelordet DEFAULT som används i kontexten INSERT, UPDATE, MERGEeller SET VARIABLE för att ange ett kolumn- eller variabelvärde till standardvärdet.

Namnmatchning tillämpar följande principer:

  • Den närmaste matchande referensen vinner och
  • Kolumner och parameter vinner över fält och nycklar.

I detalj följer lösningen av identifierare till en specifik referens dessa regler i ordning:

  1. Lokala referenser

    1. Kolumnreferens

      Matcha identifieraren, som kan vara kvalificerad, med ett kolumnnamn i en tabellreferens för FROM clause.

      Om det finns fler än en sådan matchning skapar du ett AMBIGUOUS_COLUMN_OR_FIELD fel.

    2. Parameterlös funktionsreferens

      Om identifieraren är okvalificerad och matchar current_user, current_dateeller current_timestamp: Lös det som en av dessa funktioner.

    3. Standardspecifikation för kolumn

      Om identifieraren är okvalificerad matchar default och utgör hela uttrycket i kontexten för en UPDATE SET, INSERT VALUESeller MERGE WHEN [NOT] MATCHED: Lös som respektive DEFAULT värde för måltabellen i INSERT, UPDATE eller MERGE.

    4. Referens för struct-fält eller kartnyckel

      Om identifieraren är kvalificerad ska du försöka matcha den med ett fält eller en kartnyckel enligt följande steg:

      A. Ta bort den sista identifieraren och behandla den som ett fält eller en nyckel. B. Matcha resten med en kolumn i tabellreferensen för FROM clause.

      Om det finns fler än en sådan matchning skapar du ett AMBIGUOUS_COLUMN_OR_FIELD fel.

      Om det finns en matchning och kolumnen är en:

      • STRUCT: Matcha fältet.

        Om fältet inte kan matchas skapar du ett FIELD_NOT_FOUND fel.

        Om det finns fler än ett fält skapar du ett AMBIGUOUS_COLUMN_OR_FIELD fel.

      • MAP: Skapa ett fel om nyckeln är kvalificerad.

        En körningsfel kan inträffa om nyckeln inte finns på kartan.

      • Annan typ: Skapa ett fel. C. Upprepa föregående steg för att ta bort den avslutande identifieraren som ett fält. Tillämpa regler (A) och (B) medan det finns en identifierare kvar att tolka som en kolumn.

  2. Alias för lateral kolumn

    Gäller för: markerad ja Databricks SQL markerad ja Databricks Runtime 12.2 LTS och senare

    Om uttrycket finns i en SELECT lista matchar du den inledande identifieraren med ett föregående kolumnalias i SELECT listan.

    Om det finns fler än en sådan matchning skapar du ett AMBIGUOUS_LATERAL_COLUMN_ALIAS fel.

    Matcha varje återstående identifierare som ett fält eller en kartnyckel och generera FIELD_NOT_FOUND eller AMBIGUOUS_COLUMN_OR_FIELD fel om de inte kan matchas.

  3. Korrelation

    • LATERAL

      Om frågan föregås av ett LATERAL nyckelord tillämpar du reglerna 1.a och 1.d med tanke på tabellreferenserna i den FROM som innehåller frågan och före LATERAL.

    • Vanligt

      Om frågan är en skalär underfråga, IN, eller EXISTS underfråga tillämpar du reglerna 1.a, 1.d och 2 med tanke på tabellreferenserna i den innehållande frågans sats FROM .

  4. Kapslad korrelation

    Re-apply rule 3 iterating over the nesting levels of the query.

  5. Rutinparametrar

    Om uttrycket ingår i en CREATE FUNCTION-instruktion :

    1. Matcha identifieraren med ett parameternamn. Om identifieraren är kvalificerad måste kvalificeraren matcha namnet på funktionen.
    2. Om identifieraren är kvalificerad matchar du ett fält eller en mappningsnyckel för en parameter enligt regel 1.c
  6. Variabler

    1. Matcha identifieraren med ett variabelnamn. Om identifieraren är kvalificerad måste kvalificeraren vara session eller system.session.
    2. Om identifieraren är kvalificerad matchar du en fält- eller kartnyckel för en variabel enligt regel 1.c

Begränsningar

För att förhindra körning av potentiellt dyra korrelerade frågor begränsar Azure Databricks korrelationen till en nivå. Den här begränsningen gäller även för parameterreferenser i SQL-funktioner.

Exempel

-- 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 precendece 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

Tabell- och vymatchning

En identifierare i tabellreferens kan vara något av följande:

  • Beständiga tabeller eller vyer i Unity-katalogen eller Hive-metaarkivet
  • Common Table Expression (CTE)
  • Tillfällig vy

Lösningen på en identifierare beror på om den är kvalificerad:

  • Kvalificerad

    Om identifieraren är fullständigt kvalificerad med tre delar: catalog.schema.relationär den unik.

    Om identifieraren består av två delar: schema.relationär den ytterligare kvalificerad med resultatet av SELECT current_catalog() för att göra den unik.

  • Okvalificerad

    1. Vanligt tabelluttryck

      Om referensen ligger inom omfånget för en WITH sats matchar du identifieraren med en CTE som börjar med den omedelbart innehållande WITH satsen och flyttar utåt därifrån.

    2. Tillfällig vy

      Matcha identifieraren med en temporär vy som definierats i den aktuella sessionen.

    3. Sparad tabell

      Fullständigt kvalificera identifieraren genom att vänta i förväg på resultatet av SELECT current_catalog() och SELECT current_schema() leta upp den som en beständig relation.

Om relationen inte kan matchas till någon tabell, vy eller CTE, genererar Databricks ett TABLE_OR_VIEW_NOT_FOUND fel.

Exempel

-- 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.

Funktionsupplösning

En funktionsreferens identifieras av den obligatoriska avslutande uppsättningen parenteser.

Det kan matcha för att:

  • En inbyggd funktion som tillhandahålls av Azure Databricks,
  • En tillfällig användardefinierad funktion som är begränsad till den aktuella sessionen, eller
  • En beständig användardefinierad funktion som lagras i hive-metaarkivet eller Unity-katalogen.

Lösning av ett funktionsnamn beror på om det är kvalificerat:

  • Kvalificerad

    Om namnet är fullständigt kvalificerat med tre delar: catalog.schema.functionär det unikt.

    Om namnet består av två delar: schema.functionär det ytterligare kvalificerat med resultatet av SELECT current_catalog() för att göra det unikt.

    Funktionen söks sedan upp i katalogen.

  • Okvalificerad

    För okvalificerade funktionsnamn följer Azure Databricks en fast prioritetsordning (PATH):

    1. Inbyggd funktion

      Om det finns en funktion med det här namnet bland uppsättningen inbyggda funktioner väljs den funktionen.

    2. Tillfällig funktion

      Om det finns en funktion med det här namnet bland uppsättningen med tillfälliga funktioner väljs den funktionen.

    3. Beständiga funktioner

      Fullständigt kvalificera funktionsnamnet genom att vänta i förväg på resultatet av SELECT current_catalog() och SELECT current_schema() leta upp det som en beständig funktion.

Om funktionen inte kan lösas genererar Azure Databricks ett UNRESOLVED_ROUTINE fel.

Exempel

> 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