Condividi tramite


Risoluzione dei nomi

Si applica a:segno di spunta sì Databricks SQL segno di spunta sì Databricks Runtime

La risoluzione dei nomi è il processo in base al quale gli identificatori vengono risolti in riferimenti specifici column, di campo, di parametro o table.

Column, campo, parametro e risoluzione delle variabili

Gli identificatori nelle espressioni possono essere riferimenti a uno dei seguenti elementi:

  • Column nome basato su una vista, table, un'espressione table comune (CTE) o un column_alias.
  • Nome del campo o chiave della mappa all'interno di uno struct o di una mappa. I campi e le chiavi non possono mai essere non qualificati.
  • Nome del parametro di una funzione definita dall'utente SQL.
  • Nome variabile.
  • Una funzione speciale, current_user ad esempio o current_date che non richiede l'utilizzo di ().
  • Parola chiave DEFAULT utilizzata nel contesto di INSERT, UPDATE, MERGEo SET VARIABLE per set un valore di column o variabile sul valore predefinito.

La risoluzione dei nomi applica i principi seguenti:

  • Il riferimento corrispondente più vicino vince e
  • Columns e il parametro hanno la precedenza su campi e chiavi.

In dettaglio, la risoluzione degli identificatori a un riferimento specifico segue queste regole nell'ordine seguente:

  1. Riferimenti locali

    1. Column riferimento

      Abbina il identifier, che può essere qualificato, a un nome column in un di riferimentotable del FROM clause.

      Se sono presenti più corrispondenze di questo tipo, generare un errore di AMBIGUOUS_COLUMN_OR_FIELD .

    2. Informazioni di riferimento sulle funzioni senza parametri

      Se il identifier non è qualificato e corrisponde a current_user, current_dateo current_timestamp: risolvilo come una di queste funzioni.

    3. Column specifica DEFAULT

      Se il identifier non è qualificato, corrisponde a default e costituisce l'intera espressione nel contesto di un UPDATE SET, INSERT VALUESo MERGE WHEN [NOT] MATCHED: Risolvi come il rispettivo valore DEFAULT del table di destinazione del INSERT, UPDATE o MERGE.

    4. Informazioni di riferimento sul campo Struct o sulla chiave della mappa

      Se il identifier è qualificato, cerca di abbinarlo a un campo o a una chiave della mappa in base ai passaggi seguenti:

      R. Remove l'ultimo identifier e quindi considerarlo come campo o chiave. B. Abbinare il resto a un column in table di riferimento del FROM clause.

      Se sono presenti più corrispondenze di questo tipo, generare un errore di AMBIGUOUS_COLUMN_OR_FIELD .

      Se c'è una corrispondenza e il column è:

      • STRUCT: trova la corrispondenza con il campo.

        Se il campo non può essere confrontato, generare un errore di FIELD_NOT_FOUND .

        Se sono presenti più campi, generare un errore di AMBIGUOUS_COLUMN_OR_FIELD .

      • MAP: genera un errore se la chiave è qualificata.

        Un runtime eror può verificarsi se la chiave non è effettivamente presente nella mappa.

      • Qualsiasi altro tipo: generare un errore. C. Ripetere il passaggio precedente per remove il identifier finale come campo. Applicare le regole (A) e (B) fintanto che esiste un identifier che rimane da interpretare come column.

  2. aliasing laterale column

    Si applica a:segno di spunta sì Databricks SQL segno di spunta sì Databricks Runtime 12.2 LTS e versioni successive

    Se l'espressione si trova all'interno di un , far corrispondere il iniziale a un alias di un precedente in tale .

    Se sono presenti più corrispondenze di questo tipo, generare un errore di AMBIGUOUS_LATERAL_COLUMN_ALIAS .

    Trova la corrispondenza di ogni identifier rimanente come campo o chiave della mappa e, se non è possibile stabilire una corrispondenza, genera un errore FIELD_NOT_FOUND o AMBIGUOUS_COLUMN_OR_FIELD.

  3. Correlazione

    • LATERALE

      Se la query è preceduta da una parola chiave LATERAL, applicare le regole 1.a e 1.d considerando i riferimenti table nelle FROM che contengono la query e che precedono il LATERAL.

    • Regolare

      Se la query è una sottoquery scalare , una sottoquery, IN, o EXISTS, si devono applicare le regole 1.a, 1.d e 2 considerando i riferimenti table nella clausola FROM della query contenitore.

  4. Correlazione annidata

    Riapplicare la regola 3 che esegue l'iterazione sui livelli di annidamento della query.

  5. Routine parameters

    Se l'espressione è parte di un'istruzione CREATE FUNCTION:

    1. Associare il identifier a un nome di parametro . Se il identifier è qualificato, il qualificatore deve corrispondere al nome della funzione.
    2. Se la identifier è qualificata, abbinala a un campo o a una chiave di una mappa di un parametro che segue la regola 1.c.
  6. Variabili

    1. Associare il identifier a un nome di variabile . Se il identifier è qualificato, il qualificatore deve essere session o system.session.
    2. Se il identifier è qualificato, abbina a un campo o a una chiave della mappa di una variabile secondo la regola 1.c

Limiti

Per evitare l'esecuzione di query correlate potenzialmente costose, Azure Databricks limita la correlazione supportata a un livello. Questa restrizione si applica anche ai riferimenti ai parametri nelle funzioni SQL.

Esempi

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

Table e risoluzione dello schermo

Un identifier in table-reference può essere uno dei seguenti:

  • table o visualizzazione persistente in Unity Catalog o nel metastore Hive
  • Espressione table comune (CTE)
  • Visualizzazione temporanea

La risoluzione di un identifier dipende dal fatto che sia qualificato:

  • Qualificato

    Se il identifier è completamente qualificato con tre parti: catalog.schema.relation, risulta unico.

    Se il identifier si compone di due parti, cioè schema.relation, viene ulteriormente specificato con il risultato di SELECT current_catalog() per renderlo univoco.

  • Ineleggibile

    1. espressione comune table

      Se il riferimento è compreso nell'ambito di una clausola WITH, abbina il identifier a un CTE iniziando dalla clausola WITH che lo contiene immediatamente e procedendo verso l'esterno.

    2. Visualizzazione temporanea

      Trova la corrispondenza tra il identifier e qualsiasi visualizzazione temporanea definita all'interno della sessione corrente.

    3. table persistente

      Completare qualify il identifier anteponendo il risultato di SELECT current_catalog() e SELECT current_schema() e verificarlo come relazione persistente.

Se la relazione non può essere risolta in qualsiasi table, vista o CTE, Databricks genera un errore di TABLE_OR_VIEW_NOT_FOUND.

Esempi

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

Risoluzione delle funzioni

Un riferimento a una funzione viene riconosciuto dal carattere obbligatorio set che segue le parentesi.

Può essere risolto in:

  • Funzione predefinita fornita da Azure Databricks,
  • Una funzione definita dall'utente temporanea con ambito alla sessione corrente o
  • Funzione definita dall'utente persistente archiviata nel metastore Hive o Unity Catalog.

La risoluzione di un nome di funzione dipende dal fatto che sia qualificato:

  • Qualificato

    Se il nome è completo con tre parti: catalog.schema.function, è univoco.

    Se il nome è costituito da due parti: schema.function, è ulteriormente qualificato con il risultato di SELECT current_catalog() per renderlo univoco.

    La funzione viene quindi cercata nella catalog.

  • Ineleggibile

    Per i nomi di funzione non qualificati, Azure Databricks segue un ordine di precedenza fisso (PATH):

    1. Funzione Builtin

      Se esiste una funzione con questo nome tra le set di funzioni predefinite, viene scelta tale funzione.

    2. Funzione temporanea

      Se esiste una funzione con questo nome tra le set delle funzioni temporanee, viene scelta tale funzione.

    3. Funzione persistente

      Completamente qualify il nome della funzione anteponendo il risultato di SELECT current_catalog() e SELECT current_schema() e cercarlo come funzione persistente.

Se la funzione non può essere risolta, Azure Databricks genera un UNRESOLVED_ROUTINE errore.

Esempi

> 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