Resolução de nomes
Aplica-se a: SQL do Databricks Azure Databricks Runtime
Resolução de nomes é o processo pelo qual identificadores são resolvidos para referências de coluna, campo, parâmetro ou tabela específicas.
Resolução da variável, coluna, campo e parâmetro
Identificadores em expressões podem ser referências a qualquer um dos seguintes itens:
- Nome da coluna com base em uma exibição, tabela, CTE (expressão de tabela comum) ou um column_alias.
- Nome do campo ou chave de mapa em um struct ou mapa. Campos e chaves nunca podem ser desqualificados.
- Nome do parâmetro de uma Função definida pelo usuário do SQL.
- Nome da variável.
- Uma função especial, como
current_user
oucurrent_date
que não requer o uso de()
. - A palavra-chave
DEFAULT
utilizada no contexto deINSERT
,UPDATE
,MERGE
ouSET VARIABLE
para definir um valor de coluna ou variável como padrão.
A resolução de nomes aplica os seguintes princípios:
- A referência correspondente mais próxima vence; e
- As colunas e o parâmetro vencem sobre campos e chaves.
Em detalhes, a resolução de identificadores para uma referência específica segue estas regras na ordem:
Referências de local
Referência de coluna
Corresponde o identificador, que pode ser qualificado, a um nome de coluna em uma referência de tabela da
FROM clause
.Se houver mais de uma correspondência desse tipo, gera um erro AMBIGUOUS_COLUMN_OR_FIELD.
Referência de função sem parâmetros
Se o identificador não for qualificado e corresponder a
current_user
,current_date
oucurrent_timestamp
: resolva-o como uma dessas funções.Especificação de coluna DEFAULT
Se o identificador não for qualificado, corresponder a
default
e criar a expressão inteira no contexto de umUPDATE SET
,INSERT VALUES
ouMERGE WHEN [NOT] MATCHED
: resolva como o respectivo valorDEFAULT
da tabela de destino deINSERT
,UPDATE
ouMERGE
.Referência de chave de mapa ou campo struct
Se o identificador for qualificado, tente combiná-lo com um campo ou uma chave de mapa de acordo com as seguintes etapas:
a. Remova o último identificador e trate-o como um campo ou chave. B. Corresponda o restante a uma coluna na referência de tabela da
FROM clause
.Se houver mais de uma correspondência desse tipo, gera um erro AMBIGUOUS_COLUMN_OR_FIELD.
Se houver uma correspondência e a coluna for:
STRUCT
: corresponda ao campo.Se o campo não puder ser correspondido, gera um erro de FIELD_NOT_FOUND.
Se houver mais de um campo, gera um erro AMBIGUOUS_COLUMN_OR_FIELD.
MAP
: gera um erro se a chave for qualificada.Um erro em tempo de execução poderá ocorrer se a chave não estiver realmente presente no mapa.
Qualquer outro tipo: gera um erro. C. Repita a etapa anterior para remover o identificador à direita como um campo. Aplique as regras (A) e (B) enquanto houver um identificador à esquerda para interpretar como uma coluna.
Alias de coluna lateral
Aplica-se a: SQL do Databricks Databricks Runtime 12.2 LTS e versões posteriores
Se a expressão estiver dentro de uma lista
SELECT
, corresponde o identificador principal a um alias de coluna anterior nessa listaSELECT
.Se houver mais de uma correspondência desse tipo, gera um erro AMBIGUOUS_LATERAL_COLUMN_ALIAS.
Corresponde cada identificador restante como um campo ou uma chave de mapa e gera o erro FIELD_NOT_FOUND ou AMBIGUOUS_COLUMN_OR_FIELD se eles não puderem ser correspondidos.
Correlação
LATERAL
Se a consulta for precedida por uma palavra-chave
LATERAL
, aplique as regras 1.a e 1.d considerando as referências de tabela noFROM
que contém a consulta e precedendo aLATERAL
.Regular
Se a consulta for uma subconsulta escalar,
IN
ouEXISTS
, a subconsulta aplicará as regras 1.a, 1.d e 2 considerando as referências de tabela na cláusulaFROM
contida na consulta.
Correlação aninhada
Aplique novamente a regra 3 iterando sobre os níveis de aninhamento da consulta.
Parâmetros de rotina
Se a expressão fizer parte de uma instrução CREATE FUNCTION:
- Corresponda o identificador a um nome de parâmetro. Se o identificador for qualificado, o qualificador deverá corresponder ao nome da função.
- Se o identificador for qualificado, corresponda a um campo ou chave de mapa de um parâmetro seguindo a regra 1.c
Variáveis
- Corresponder o identificador a um nome de variável. Se o identificador for qualificado, o qualificador deverá ser
session
ousystem.session
. - Se o identificador for qualificado, corresponda a um campo ou chave de mapeamento de uma variável seguindo a regra 1.c
- Corresponder o identificador a um nome de variável. Se o identificador for qualificado, o qualificador deverá ser
Limitações
Para impedir a execução de consultas correlacionadas potencialmente caras, o Azure Databricks limita a correlação com suporte a um nível. Essa restrição também se aplica a referências de parâmetro em funções SQL.
Exemplos
-- 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
Resolução de tabela e exibição
Um identificador em table-reference pode ser qualquer um dos seguintes:
- Tabela ou exibição persistente no Catálogo Unity ou no Metastore do Hive
- CTE (expressão de tabela comum)
- Exibição temporária
A resolução de um identificador depende se ele é qualificado:
Qualificado
Se o identificador for totalmente qualificado com três partes:
catalog.schema.relation
, ele será exclusivo.Se o identificador consistir em duas partes:
schema.relation
, ele será qualificado adicionalmente com o resultado deSELECT current_catalog()
para torná-lo exclusivo.Não qualificado
Expressão de tabela comum
Se a referência estiver dentro do escopo de uma cláusula
WITH
, corresponda o identificador a uma CTE começando com a cláusulaWITH
imediatamente contida e movendo para fora dela.Exibição temporária
Corresponda o identificador a qualquer exibição temporária definida dentro da sessão atual.
Tabela persistida
Qualifique totalmente o identificador pré-pendente do resultado de
SELECT current_catalog()
eSELECT current_schema()
e procure-o como uma relação persistente.
Se a relação não puder ser resolvida para nenhuma tabela, exibição ou CTE, o Databricks gerará um erro de TABLE_OR_VIEW_NOT_FOUND.
Exemplos
-- 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.
Resolução de função
Uma referência de função é reconhecida pelo conjunto de parênteses à direita obrigatório.
Ela pode resolver para:
- Uma função interna fornecida pelo Azure Databricks,
- Uma função temporária definida pelo usuário com escopo para a sessão atual, ou
- Uma função persistente definida pelo usuário armazenada no metastore do hive ou no Catálogo Unity.
A resolução de um nome de função depende se ele é qualificado:
Qualificado
Se o nome for totalmente qualificado com três partes:
catalog.schema.function
, ele será exclusivo.Se o nome consistir em duas partes:
schema.function
, ele será qualificado adicionalmente com o resultado deSELECT current_catalog()
para torná-lo exclusivo.Em seguida, a função é pesquisada no catálogo.
Não qualificado
Para nomes de função não qualificados, o Azure Databricks segue uma ordem fixa de precedência (
PATH
):Função interna
Se existir uma função com esse nome entre o conjunto de funções internas, essa função será escolhida.
Função temporária
Se existir uma função com esse nome entre o conjunto de funções temporárias, essa função será escolhida.
Função persistida
Qualifique totalmente a função pré-pendente do resultado de
SELECT current_catalog()
eSELECT current_schema()
e procure-a como uma função persistente.
Se a função não puder ser resolvida, o Azure Databricks gerará um erro UNRESOLVED_ROUTINE
.
Exemplos
> 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