Namensauflösung
Gilt für: Databricks SQL 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
odercurrent_date
, für die eine Verwendung von()
nicht erforderlich ist. - Das Schlüsselwort
DEFAULT
, das im Kontext vonINSERT
,UPDATE
,MERGE
oderSET 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:
Lokale Verweise
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.
Referenz für parameterlose Funktionen
Wenn der Bezeichner nicht qualifiziert ist und mit
current_user
,current_date
odercurrent_timestamp
übereinstimmt, wird er als eine dieser Funktionen aufgelöst.DEFAULT-Spaltenspezifikation
Wenn der Bezeichner nicht qualifiziert ist, mit
default
übereinstimmt und den gesamten Ausdruck im Kontext vonUPDATE SET
,INSERT VALUES
oderMERGE WHEN [NOT] MATCHED
erstellt: Die Auflösung erfolgt als entsprechenderDEFAULT
-Wert der Zieltabelle vonINSERT
,UPDATE
oderMERGE
.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.
Laterales Spaltenaliasing
Gilt für: Databricks SQL 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 dieserSELECT
-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.
Korrelation
LATERAL
Wenn der Abfrage ein
LATERAL
-Schlüsselwort vorangestellt ist, werden die Regeln 1.a und 1.d unter Berücksichtigung der Tabellenverweise imFROM
-Element angewendet, das die Abfrage enthält undLATERAL
vorangeht.Regulär
Wenn die Abfrage eine skalare Unterabfrage oder eine
IN
- oderEXISTS
-Unterabfrage ist, werden die Regeln 1.a, 1.d und 2 angewendet, unter Berücksichtigung der Tabellenverweise in derFROM
-Klausel der enthaltenden Abfrage.
Geschachtelte Korrelation
Regel 3 wird beim Durchlaufen der Schachtelungsebenen der Abfrage erneut angewendet.
Routineparameter
Wenn der Ausdruck Teil einer CREATE FUNCTION-Anweisung ist:
- Der Bezeichner wird mit einem Parameternamen abgeglichen. Wenn der Bezeichner qualifiziert ist, muss der Qualifizierer mit dem Namen der Funktion übereinstimmen.
- Wenn der Bezeichner qualifiziert ist, erfolgt ein Abgleich mit einem Feld- oder Zuordnungsschlüssel eines Parameters gemäß Regel 1.c.
Variablen
- Entspricht dem Bezeichner für einen Variablennamen. Wenn der Bezeichner qualifiziert ist, muss der Qualifizierer
session
odersystem.session
sein. - Wenn der Bezeichner qualifiziert ist, erfolgt ein Abgleich mit einem Feld- oder Zuordnungsschlüssel einer Variable gemäß Regel 1.c.
- Entspricht dem Bezeichner für einen Variablennamen. Wenn der Bezeichner qualifiziert ist, muss der Qualifizierer
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 vonSELECT current_catalog()
weiter qualifiziert, um ihn eindeutig zu machen.Nicht qualifiziert
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 enthaltendenWITH
-Klausel und wird von dort nach außen fortgesetzt.Temporäre Sicht
Der Bezeichner wird mit einer temporären Sicht abgeglichen, die in der aktuellen Sitzung definiert ist.
Persistente Tabelle
Der Bezeichner wird als vollqualifiziert festgelegt, indem das Ergebnis von
SELECT current_catalog()
undSELECT 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 vonSELECT 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
):Integrierte Funktion
Wenn eine Funktion mit diesem Namen im Satz integrierter Funktionen vorhanden ist, wird diese Funktion ausgewählt.
Temporäre Funktion
Wenn eine Funktion mit diesem Namen im Satz temporärer Funktionen vorhanden ist, wird diese Funktion ausgewählt.
Persistente Funktion
Der Funktionsname wird als vollqualifiziert festgelegt, indem das Ergebnis von
SELECT current_catalog()
undSELECT 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