Résolution de noms
S’applique à : Databricks SQL Databricks Runtime
La résolution de noms est le processus par lequel les identificateurs sont résolus en références de colonne, de champ, de paramètre ou de table spécifiques.
Résolution de colonnes, champs, paramètres et variables
Les identificateurs contenus dans les expressions peuvent faire référence aux éléments suivants :
- Nom de colonne basé sur une vue, une table, une expression de table commune (CTE) ou un alias de colonne.
- Nom de champ ou clé de mappage dans un struct ou un mappage. Les champs et les clés ne peuvent jamais être non qualifiés.
- Nom de paramètre d’une fonction SQL définie par l’utilisateur.
- Nom de la variable.
- Fonction spéciale (par exemple
current_user
oucurrent_date
) pour laquelle les parenthèses()
ne sont pas nécessaires. - Le mot clé
DEFAULT
utilisé dans le contexte deINSERT
, deUPDATE
, deMERGE
ou deSET VARIABLE
pour définir une colonne ou une variable à sa valeur par défaut.
La résolution de noms applique les principes suivants :
- La référence correspondante la plus proche gagne.
- Les colonnes et les paramètres l’emportent sur les champs et les clés.
Dans le détail, la résolution des identificateurs en une référence spécifique suit les règles suivantes, dans l’ordre :
Références locales
Référence de colonne
Faire correspondre l’identificateur, qui peut être qualifié, à un nom de colonne dans une référence de table de la clause
FROM clause
.S’il existe plusieurs correspondances de ce type, déclencher une erreur AMBIGUOUS_COLUMN_OR_FIELD.
Référence de fonction sans paramètre
Si l’identificateur n’est pas qualifié et correspond à
current_user
, àcurrent_date
ou àcurrent_timestamp
, le résoudre comme l’une de ces fonctions.Spécification DEFAULT de colonne
Si l’identificateur n’est pas qualifié, correspond à
default
et compose la totalité de l’expression dans le contexte d’une instructionUPDATE SET
,INSERT VALUES
ouMERGE WHEN [NOT] MATCHED
, le résoudre comme la valeurDEFAULT
associée de la table cible de l’instructionINSERT
,UPDATE
ouMERGE
.Référence de champ de struct ou de clé de mappage
Si l’identificateur est qualifié, tenter de le faire correspondre à un champ ou à une clé de mappage en procédant comme suit :
R. Supprimer le dernier identificateur et le traiter comme un champ ou une clé. B. Faire correspondre le reste à une colonne dans la référence de table de la clause
FROM clause
.S’il existe plusieurs correspondances de ce type, déclencher une erreur AMBIGUOUS_COLUMN_OR_FIELD.
S’il existe une correspondance, la résolution dépend de la nature de la colonne :
STRUCT
: correspond au champ.S’il n’est pas possible de faire correspondre le champ, déclencher une erreur FIELD_NOT_FOUND.
S’il existe plusieurs champs, déclencher une erreur AMBIGUOUS_COLUMN_OR_FIELD.
MAP
: déclencher une erreur si la clé est qualifiée.Une erreur d’exécution peut se produire si la clé n’est pas réellement présente dans le mappage.
Tout autre type : déclencher une erreur. C. Répéter l’étape précédente pour supprimer le champ d’identificateur de fin. Appliquer les règles A et B lorsqu’il reste un identificateur à interpréter comme colonne.
Création d’un alias de colonne latérale
S’applique à : Databricks SQL Databricks Runtime 12.2 LTS et versions ultérieures
Si l’expression se trouve dans une liste
SELECT
, faire correspondre l’identificateur de début à un alias de colonne précédent dans cette listeSELECT
.S’il existe plusieurs correspondances de ce type, déclencher une erreur AMBIGUOUS_LATERAL_COLUMN_ALIAS.
Faire correspondre chaque identificateur restant comme champ ou clé de mappage et, si ce n’est pas possible, déclencher une erreur FIELD_NOT_FOUND ou AMBIGUOUS_COLUMN_OR_FIELD.
Corrélation
LATÉRALE
Si la requête est précédée d’un mot clé
LATERAL
, appliquer les règles 1.a et 1.d en tenant compte des références de table de la clauseFROM
contenant la requête et précédant le mot cléLATERAL
.Regular
Si la requête correspond à une sous-requête scalaire,
IN
ouEXISTS
, appliquer les règles 1.a, 1.d et 2 en tenant compte des références de table qui figurent dans la clauseFROM
de la requête qui l’englobe.
Corrélation imbriquée
Réappliquer la règle 3 en effectuant des itérations sur les niveaux d’imbrication de la requête.
Paramètres de routine
Si l’expression fait partie d’une instruction CREATE FUNCTION, procéder comme suit :
- Faire correspondre l’identificateur à un nom de paramètre. Si l’identificateur est qualifié, il doit correspondre au nom de la fonction.
- Si l’identificateur est qualifié, le faire correspondre à un champ ou à une clé de mappage d’un paramètre suivant la règle 1.c.
Variables
- Faire correspondre l’identificateur à un nom de variable. Si l’identificateur est qualifié, il doit être
session
ousystem.session
. - Si l’identificateur est qualifié, le faire correspondre à un champ ou à la clé de mappage d’une variable suivant la règle 1.c
- Faire correspondre l’identificateur à un nom de variable. Si l’identificateur est qualifié, il doit être
Limites
Pour empêcher l’exécution de requêtes corrélées potentiellement coûteuses, Azure Databricks limite la corrélation prise en charge à un seul niveau. Cette restriction s’applique également aux références de paramètres dans les fonctions SQL.
Exemples
-- 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
Résolution de table et de vue
Un identificateur contenu dans une référence de table peut correspondre à l’un des éléments suivants :
- Table ou vue persistante dans Unity Catalog ou le metastore Hive
- Expression de table commune (CTE)
- Vue temporaire
La résolution d’un identificateur dépend de son caractère qualifié ou non :
Qualifié
Si l’identificateur est complet et comporte trois parties
catalog.schema.relation
, il est unique.Si l’identificateur se compose de deux parties
schema.relation
, il est qualifié davantage avec le résultat de l’instructionSELECT current_catalog()
de façon à devenir unique.Non qualifié
Expression commune de table
Si la référence se trouve dans l’étendue d’une clause
WITH
, faire correspondre l’identificateur à une expression de table commune en commençant par la clauseWITH
directement englobante et en se déplaçant vers l’extérieur.Vue temporaire
Faire correspondre l’identificateur à n’importe quelle vue temporaire définie dans la session active.
Table persistante
Qualifier entièrement l’identificateur en le faisant précéder du résultat de
SELECT current_catalog()
et deSELECT current_schema()
et le rechercher comme une relation persistante.
S’il n’est pas possible de résoudre la relation en une table, une vue ni une expression de table commune, Databricks génère une erreur TABLE_OR_VIEW_NOT_FOUND.
Exemples
-- 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.
Résolution de fonction
Une référence de fonction se reconnaît à l’ensemble obligatoire de parenthèses de fin.
Elle peut se résoudre en différents types de fonctions :
- Une fonction intégrée fournie par Azure Databricks
- Une fonction temporaire définie par l’utilisateur dans l’étendue de la session active
- Une fonction persistante définie par l’utilisateur stockée dans le metastore Hive ou Unity Catalog
La résolution d’un nom de fonction dépend de son caractère qualifié ou non :
Qualifié
Si le nom est complet et comporte trois parties
catalog.schema.function
, il est unique.Si le nom se compose de deux parties
schema.function
, il est qualifié davantage avec le résultat de l’instructionSELECT current_catalog()
de façon à devenir unique.La fonction est ensuite recherchée dans le catalogue.
Non qualifié
Dans le cas des noms de fonction non qualifiés, Azure Databricks suit un ordre de priorité fixe (
PATH
) :Fonction intégrée
Si une fonction de ce nom existe parmi l’ensemble de fonctions intégrées, choisir cette fonction.
Fonction temporaire
Si une fonction de ce nom existe parmi l’ensemble de fonctions temporaires, choisir cette fonction.
Fonction persistante
Qualifier entièrement le nom de fonction en le faisant précéder du résultat de
SELECT current_catalog()
et deSELECT current_schema()
et le rechercher comme une fonction persistante.
S’il n’est pas possible de résoudre la fonction, Azure Databricks génère une erreur UNRESOLVED_ROUTINE
.
Exemples
> 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