Share via


Namensauflösung

Gilt für:durch Häkchen mit „Ja“ markiert Databricks SQL durch Häkchen mit „Ja“ markiert Databricks Runtime

Die Namensauflösung ist der Prozess, mit dem Bezeichner in bestimmte Spalten-, Feld-, Parameter- oder Tabellenverweise aufgelöst werden.

Auflösung von Spalten, Feldern, Parametern und Variablen

Bezeichner in Ausdrücken können Verweise auf eines der folgenden Elemente sein:

  • Spaltenname basierend auf einer Sicht, einer Tabelle, einem allgemeinen Tabellenausdruck (Common Table Expression, CTE) oder einem column_alias.
  • Feldname oder Zuordnungsschlüssel in einer Struktur oder Zuordnung. Felder und Schlüssel können niemals nicht qualifiziert sein.
  • Parametername einer benutzerdefinierten SQL-Funktion.
  • Variablenname.
  • Eine spezielle Funktion wie current_user oder current_date, für die eine Verwendung von () nicht erforderlich ist.
  • Das Schlüsselwort DEFAULT, das im Kontext von INSERT, UPDATE, MERGE oder SET VARIABLE verwendet wird, um einen Spalten- oder Variablenwert auf den Standardwert festzulegen.

Bei der Namensauflösung werden die folgenden Prinzipien angewendet:

  • Der am genauesten übereinstimmende Verweis gewinnt.
  • Spalten und Parameter haben Vorrang vor Feldern und Schlüsseln.

Im Detail folgt die Auflösung von Bezeichnern in einen bestimmten Verweis den folgenden Regeln in dieser Reihenfolge:

  1. Lokale Verweise

    1. Spaltenverweis

      Der Bezeichner, der qualifiziert werden kann, wird mit einem Spaltennamen in einem Tabellenverweis der FROM clause abgeglichen.

      Wenn mehr als eine solche Übereinstimmung vorhanden ist, wird ein AMBIGUOUS_COLUMN_OR_FIELD-Fehler ausgelöst.

    2. Referenz für parameterlose Funktionen

      Wenn der Bezeichner nicht qualifiziert ist und mit current_user, current_date oder current_timestampübereinstimmt, wird er als eine dieser Funktionen aufgelöst.

    3. DEFAULT-Spaltenspezifikation

      Wenn der Bezeichner nicht qualifiziert ist, mit default übereinstimmt und den gesamten Ausdruck im Kontext von UPDATE SET, INSERT VALUES oder MERGE WHEN [NOT] MATCHED erstellt: Die Auflösung erfolgt als entsprechender DEFAULT-Wert der Zieltabelle von INSERT, UPDATE oder MERGE.

    4. Referenz für Strukturfeld oder Zuordnungsschlüssel

      Wenn der Bezeichner qualifiziert ist, wird versucht, ihn gemäß den folgenden Schritten mit einem Feld- oder Zuordnungsschlüssel abzugleichen:

      A. Der letzte Bezeichner wird entfernt und als Feld oder Schlüssel behandelt. B: Der Rest wird mit einer Spalte im Tabellenverweis der FROM clause abgeglichen.

      Wenn mehr als eine solche Übereinstimmung vorhanden ist, wird ein AMBIGUOUS_COLUMN_OR_FIELD-Fehler ausgelöst.

      Wenn eine Übereinstimmung vorhanden ist und die Spalte eines der folgenden Elemente ist:

      • STRUCT: Das Feld wird abgeglichen.

        Wenn das Feld nicht abgeglichen werden kann, wird ein FIELD_NOT_FOUND-Fehler ausgelöst.

        Wenn mehr als ein Feld vorhanden ist, wird ein AMBIGUOUS_COLUMN_OR_FIELD-Fehler ausgelöst.

      • MAP: Es wird ein Fehler ausgelöst, wenn der Schlüssel qualifiziert ist.

        Es kann ein Laufzeitfehler auftreten, wenn der Schlüssel nicht tatsächlich in der Zuordnung vorhanden ist.

      • Jeder andere Typ: Es wird ein Fehler ausgelöst. C. Der vorherige Schritt wird wiederholt, um den nachgestellten Bezeichner als Feld zu entfernen. Die Regeln (A) und (B) werden angewendet, sofern noch ein Bezeichner vorhanden ist, der als Spalte interpretiert werden soll.

  2. Laterales Spaltenaliasing

    Gilt für:Häkchen ja Databricks SQL Häkchen gesetzt ja Databricks Runtime 12.2 LTS und höher

    Wenn sich der Ausdruck in einer SELECT-Liste befindet, wird der führende Bezeichner mit einem vorangehenden Spaltenalias in dieser SELECT-Liste abgeglichen.

    Wenn mehr als eine solche Übereinstimmung vorhanden ist, wird ein AMBIGUOUS_LATERAL_COLUMN_ALIAS-Fehler ausgelöst.

    Jeder verbleibende Bezeichner wird als Feld- oder Zuordnungsschlüssel abgeglichen, und es wird der Fehler FIELD_NOT_FOUND oder AMBIGUOUS_COLUMN_OR_FIELD ausgelöst, wenn keine Übereinstimmung vorhanden ist.

  3. Korrelation

    • LATERAL

      Wenn der Abfrage ein LATERAL-Schlüsselwort vorangestellt ist, werden die Regeln 1.a und 1.d unter Berücksichtigung der Tabellenverweise im FROM-Element angewendet, das die Abfrage enthält und LATERAL vorangeht.

    • Regulär

      Wenn die Abfrage eine skalare Unterabfrage oder eine IN- oder EXISTS-Unterabfrage ist, werden die Regeln 1.a, 1.d und 2 angewendet, unter Berücksichtigung der Tabellenverweise in der FROM-Klausel der enthaltenden Abfrage.

  4. Geschachtelte Korrelation

    Regel 3 wird beim Durchlaufen der Schachtelungsebenen der Abfrage erneut angewendet.

  5. Routineparameter

    Wenn der Ausdruck Teil einer CREATE FUNCTION-Anweisung ist:

    1. Der Bezeichner wird mit einem Parameternamen abgeglichen. Wenn der Bezeichner qualifiziert ist, muss der Qualifizierer mit dem Namen der Funktion übereinstimmen.
    2. Wenn der Bezeichner qualifiziert ist, erfolgt ein Abgleich mit einem Feld- oder Zuordnungsschlüssel eines Parameters gemäß Regel 1.c.
  6. Variablen

    1. Entspricht dem Bezeichner für einen Variablennamen. Wenn der Bezeichner qualifiziert ist, muss der Qualifizierer session oder system.session sein.
    2. Wenn der Bezeichner qualifiziert ist, erfolgt ein Abgleich mit einem Feld- oder Zuordnungsschlüssel einer Variable gemäß Regel 1.c.

Begrenzungen

Um die Ausführung potenziell teurer korrelierter Abfragen zu verhindern, beschränkt Azure Databricks die unterstützte Korrelation auf eine Ebene. Diese Einschränkung gilt auch für Parameterverweise in SQL-Funktionen.

Beispiele

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

Auflösung von Tabellen und Sichten

Ein Bezeichner in einem Tabellenverweis kann eines der folgenden Elemente sein:

  • Persistente Tabelle oder Sicht in Unity Catalog oder dem Hive-Metastore
  • Allgemeine Tabellenausdrücke (CTE, Common Table Expression)
  • Temporäre Sicht

Die Auflösung eines Bezeichners hängt davon ab, ob er qualifiziert ist:

  • Qualifiziert

    Wenn der Bezeichner mit drei Teilen vollqualifiziert ist, catalog.schema.relation, ist er eindeutig.

    Wenn der Bezeichner aus zwei Teilen besteht, schema.relation, wird er mit dem Ergebnis von SELECT current_catalog() weiter qualifiziert, um ihn eindeutig zu machen.

  • Nicht qualifiziert

    1. Allgemeiner Tabellenausdruck

      Wenn sich der Verweis im Bereich einer WITH-Klausel befindet, wird der Bezeichner mit einem CTE abgeglichen. Der Abgleich beginnt mit der direkt enthaltenden WITH-Klausel und wird von dort nach außen fortgesetzt.

    2. Temporäre Sicht

      Der Bezeichner wird mit einer temporären Sicht abgeglichen, die in der aktuellen Sitzung definiert ist.

    3. Persistente Tabelle

      Der Bezeichner wird als vollqualifiziert festgelegt, indem das Ergebnis von SELECT current_catalog() und SELECT current_schema() vorab als ausstehend markiert und als persistente Beziehung nachgeschlagen wird.

Wenn die Beziehung weder in eine Tabelle, eine Sicht oder einen CTE aufgelöst werden kann, löst Databricks einen TABLE_OR_VIEW_NOT_FOUND-Fehler aus.

Beispiele

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

Funktionsauflösung

Ein Funktionsverweis wird anhand des obligatorischen nachgestellten Satzes von Klammern erkannt.

Er kann in Folgendes aufgelöst werden:

  • Eine integrierte Funktion, die von Azure Databricks bereitgestellt wird
  • Eine temporäre benutzerdefinierte Funktion, die auf die aktuelle Sitzung beschränkt ist
  • Eine persistente benutzerdefinierte Funktion, die im Hive-Metastore oder in Unity Catalog gespeichert ist

Die Auflösung eines Funktionsnamens hängt davon ab, ob er qualifiziert ist:

  • Qualifiziert

    Wenn der Name mit drei Teilen vollqualifiziert ist, catalog.schema.function, ist er eindeutig.

    Wenn der Name aus zwei Teilen besteht, schema.function, wird er mit dem Ergebnis von SELECT current_catalog() weiter qualifiziert, um ihn eindeutig zu machen.

    Dann wird die Funktion im Katalog nachgeschlagen.

  • Nicht qualifiziert

    Für nicht qualifizierte Funktionsnamen folgt Azure Databricks einer festen Rangfolge (PATH):

    1. Integrierte Funktion

      Wenn eine Funktion mit diesem Namen im Satz integrierter Funktionen vorhanden ist, wird diese Funktion ausgewählt.

    2. Temporäre Funktion

      Wenn eine Funktion mit diesem Namen im Satz temporärer Funktionen vorhanden ist, wird diese Funktion ausgewählt.

    3. Persistente Funktion

      Der Funktionsname wird als vollqualifiziert festgelegt, indem das Ergebnis von SELECT current_catalog() und SELECT current_schema() vorab als ausstehend markiert und als persistente Funktion nachgeschlagen wird.

Wenn die Funktion nicht aufgelöst werden kann, löst Azure Databricks einen UNRESOLVED_ROUTINE-Fehler aus.

Beispiele

> 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