Resolução de nomes

Aplica-se a:Assinalado sim Databricks SQL Assinalado sim Databricks Runtime

A resolução de nomes é o processo pelo qual identificadores são associados a referências específicas de coluna, campo, parâmetro ou tabela.

Resolução de colunas, campos, parâmetros e variáveis

Os identificadores em expressões podem ser referências a qualquer um dos seguintes:

A resolução de nomes aplica os seguintes princípios:

  • A referência correspondente mais próxima vence, e
  • Colunas e parâmetros superam campos e chaves.

Em detalhe, a resolução de identificadores para uma referência específica segue estas regras na seguinte ordem:

  1. Referências locais

    1. Referência da coluna

      Corresponder o identificador, que pode ser qualificado, a um nome de coluna em uma referência de tabela do FROM clause.

      Se houver mais de uma correspondência, levante um erro AMBIGUOUS_COLUMN_OR_FIELD.

    2. Referência de função sem parâmetros

      Se o identificador não for qualificado e corresponder a current_user, current_dateou current_timestamp, resolva-o como uma destas funções.

    3. Especificação padrão da coluna

      Se o identificador não for qualificado, corresponder ao default e constituir toda a expressão no contexto de um UPDATE SET, INSERT VALUESou MERGE WHEN [NOT] MATCHED, resolve-se como o respetivo valor de DEFAULT da tabela de destino do INSERT, UPDATE ou MERGE.

    4. Referência da chave do campo struct ou do mapa

      Se o identificador for qualificado, tente combiná-lo com uma chave de campo ou mapa de acordo com as seguintes etapas:

      Um. Remova o último identificador e trate-o como um campo ou chave. B. Corresponder o resto a uma coluna na referência de tabela de do FROM clause.

      Se houver mais de uma correspondência, levante um erro AMBIGUOUS_COLUMN_OR_FIELD.

      Se houver uma correspondência e a coluna for uma:

      • STRUCT: Corresponda ao campo.

        Se o campo não puder ser encontrado, gere um erro FIELD_NOT_FOUND.

        Se houver mais de um campo, levante um erro AMBIGUOUS_COLUMN_OR_FIELD.

      • MAP: Provocar um erro se a chave estiver qualificada.

        Pode ocorrer um erro de execução se a chave não estiver realmente presente no mapa.

      • Qualquer outro tipo: Gerar um erro. C. Repita a etapa anterior para remover o identificador final do campo. Aplique as regras (A) e (B) enquanto houver um identificador restante para interpretar como uma coluna.

  2. Aliasing de coluna lateral

    Aplica-se a:assinalado como sim Databricks SQL assinalado como sim Databricks Runtime 12.2 LTS e superior

    Se a expressão estiver dentro de uma lista SELECT, alinhe o identificador inicial a um alias de coluna anterior nessa lista SELECT.

    Se houver mais de uma dessas correspondências, levante um erro AMBIGUOUS_LATERAL_COLUMN_ALIAS.

    Corresponder cada identificador restante como um campo ou uma chave de mapa e gerar um erro de FIELD_NOT_FOUND ou AMBIGUOUS_COLUMN_OR_FIELD se eles não puderem ser correspondidos.

  3. Correlação

    • LATERAIS

      Se a consulta for precedida por uma palavra-chave LATERAL, aplique as regras 1.a e 1.d considerando as referências de tabela no FROM que contém a consulta e precede a LATERAL.

    • Regular

      Se a consulta for uma subconsulta escalar, IN, ou subconsulta EXISTS, aplique as regras 1.a, 1.d e 2 considerando as referências de tabela na cláusula da consulta que a contémFROM.

  4. Correlação aninhada

    Aplica-se a:assinalado Databricks SQL assinalado sim Databricks Runtime 20.0 e superiores

    Reaplique-se a regra 3, iterando sobre os níveis de aninhamento da consulta, para que um identificador possa resolver para uma referência correlacionada em qualquer consulta envolvente, não apenas na que encerra imediatamente.

  5. Loop FOR

    Se a instrução estiver contida em um loop FOR:

    Um. Corresponda o identificador a uma coluna em uma consulta de instrução de loop FOR. Se o identificador for qualificado, o qualificador deverá corresponder ao nome da variável de loop FOR, se definido. B. Se o identificador for qualificado, corresponda, seguindo a regra 1.c, a uma chave de campo ou mapa de um parâmetro.

  6. Declaração composta

    Se a declaração estiver contida numa declaração composta:

    Um. Corresponder o identificador a uma variável declarada nessa instrução composta. Se o identificador for qualificado, o qualificador deve corresponder ao rótulo da instrução composta caso este tenha sido definido. B. Se o identificador for qualificado, corresponda a um campo ou chave de mapa de uma variável seguindo a regra 1.c

  7. Instrução composta aninhada ou loop FOR

    Reaplique as regras 5 e 6, percorrendo os níveis de aninhamento da declaração composta.

  8. Parâmetros de rotina

    Se a expressão fizer parte de uma instrução CREATE FUNCTION ou CREATE PROCEDURE:

    1. Corresponda o identificador a um nome de parâmetro . Se o identificador for qualificado, o qualificador deverá corresponder ao nome da rotina.
    2. Se o identificador for qualificado, corresponda, seguindo a regra 1.c, a uma chave de campo ou mapa de um parâmetro.
  9. variáveis de sessão

    1. Corresponder o identificador a um nome de variável. Se o identificador for qualificado, o qualificador deve ser session ou system.session. No Databricks SQL e Databricks Runtime 19 e superiores, um identificador não qualificado corresponde a uma variável de sessão apenas se system.session estiver no PATH.
    2. Se o identificador for qualificado, corresponda a um campo ou chave de mapa de uma variável seguindo a regra 1.c

Resolução de nomes em HAVING, ORDER BY, e QUALIFY

As HAVINGcláusulas , ORDER BY, e QUALIFY podem referenciar nomes da SELECT lista, bem como colunas das tabelas subjacentes. Quando um nome numa destas cláusulas corresponde tanto a um alias de coluna na SELECT lista como a uma coluna de tabela, as cláusulas resolvem a ambiguidade de forma diferente:

  • ORDER BY prefere o SELECT alias de lista à coluna da tabela.
  • HAVING prefere a coluna da tabela ao SELECT alias da lista.
  • QUALIFY prefere a coluna da tabela ao SELECT alias da lista (igual a HAVING).

Exemplos

> CREATE OR REPLACE TEMPORARY VIEW t(a, b) AS VALUES (1, 10), (2, 20), (3, 30);

-- ORDER BY prefers the alias over the column.
-- 'a' in ORDER BY refers to the alias (-a), not column 'a',
-- so the row with the largest column 'a' comes first.
> SELECT -a AS a FROM t ORDER BY a LIMIT 1;
  -3

-- HAVING prefers the column over the alias.
-- 'a' in HAVING refers to column 'a', not the alias sum(b).
> SELECT sum(b) AS a FROM t GROUP BY a HAVING a > 1;
  20
  30

-- QUALIFY prefers the column over the alias (same as HAVING).
-- 'a' in QUALIFY refers to column 'a', not the alias -row_number().
> SELECT -row_number() OVER (ORDER BY b) AS a FROM t QUALIFY a > 1;
  -2
  -3

Extração de campos e prioridade de resolução de nomes

Quando um nome qualificado, como a.b o que é usado em HAVING ou ORDER BY, as regras de prioridade acima ainda se aplicam, mas com uma consideração adicional: o candidato preferido deve suportar a extração de campos de estruturas ou de chaves de mapa. Se não o fizer, é usado o outro candidato em seu lugar.

Por exemplo, se o alias a se resolve para um plano INT mas a coluna a da tabela for um STRUCT campo xcom , ORDER BY escolhe a STRUCT coluna porque um campo não pode ser extraído do INT alias. Por outro lado, se a coluna da tabela for um plano INT e o alias for um STRUCT, HAVING recorre ao alias para extração de campos.

Exemplos

-- ORDER BY fallback: the table column is a STRUCT, the alias is an INT.
-- ORDER BY normally prefers the alias, but the alias (INT) cannot have
-- field 'x' extracted, so the struct column wins.
> CREATE OR REPLACE TEMPORARY VIEW s1(a) AS VALUES (named_struct('x', 1)), (named_struct('x', 2));

> SELECT -a.x AS a FROM s1 ORDER BY a.x LIMIT 1;
  -1

-- HAVING fallback: the table column is an INT, the alias is a STRUCT.
-- HAVING normally prefers the table column, but the column (INT) cannot have
-- field 'x' extracted, so the alias wins.
> CREATE OR REPLACE TEMPORARY VIEW s2(a) AS VALUES (1), (2);

> SELECT named_struct('x', 2) AS a FROM s2 GROUP BY a HAVING a.x > 1;
  {"x":2}
  {"x":2}

-- Map key extraction follows the same rules.
-- ORDER BY fallback: alias (INT) cannot have key extracted, map column wins.
> CREATE OR REPLACE TEMPORARY VIEW s3(a) AS VALUES (map('key', 100)), (map('key', 200));

> SELECT -a['key'] AS a FROM s3 ORDER BY a['key'] LIMIT 1;
  -100

-- HAVING fallback: column (INT) cannot have key extracted, map alias wins.
> CREATE OR REPLACE TEMPORARY VIEW s4(a) AS VALUES (100), (200);

> SELECT map('key', 200) AS a FROM s4 GROUP BY a HAVING a['key'] > 100;
  {"key":200}
  {"key":200}

Limitações

No Databricks SQL e Databricks Runtime 20.0 e superiores, é suportada correlação aninhada (uma subconsulta que faz referência a colunas de uma consulta anexa para além do seu pai imediato), com as seguintes limitações:

  • A correlação aninhada não é suportada para subconsultas numa HAVING cláusula.
  • Uma LATERAL subconsulta não pode ser aninhada-correlacionada. As suas referências externas devem ser resolvidas para a consulta diretamente anexa.

Nas versões de Runtime do Databricks abaixo da 20.0, a correlação limita-se a um único nível: uma subconsulta só pode referenciar colunas da consulta que a envolve imediatamente.

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

-- Nested correlation: the innermost EXISTS references t1.a from the outermost query
> CREATE OR REPLACE TEMPORARY VIEW t1(a) AS VALUES(1), (2), (3);
> CREATE OR REPLACE TEMPORARY VIEW t2(b) AS VALUES(1), (2);
> CREATE OR REPLACE TEMPORARY VIEW t3(c) AS VALUES(2), (3);

> SELECT a FROM t1
    WHERE EXISTS(SELECT 1 FROM t2
                  WHERE t2.b = t1.a
                    AND EXISTS(SELECT 1 FROM t3
                                WHERE t3.c = t1.a));
 2

-- 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 tabelas e visualizações

Um identificador na referência de tabela pode ser qualquer um dos seguintes:

  • Tabela ou exibição persistente no Unity Catalog ou no Hive Metastore
  • Expressão de tabela comum (CTE)
  • Vista temporária ou tabela temporária

A resolução de um identificador depende de ele ser qualificado:

  • Qualificado

    Se o identificador for totalmente qualificado com três partes: catalog.schema.relation, ele é exclusivo.

    Se o identificador consistir em duas partes: schema.relation, ele é ainda mais qualificado com o resultado de SELECT current_catalog() para torná-lo único.

    Se o esquema for session, é ainda qualificado com system e interpretado como uma vista temporária ou tabela temporária. Se o esquema for global_temp, é ainda qualificado e system interpretado como uma vista global temporária no Databricks Runtime.

  • Não qualificado

    1. Expressão de tabela comum

      Se a referência estiver dentro do escopo de uma cláusula WITH, associe o identificador a um CTE, começando pela cláusula que contém imediatamente WITH e movendo-se para fora a partir daí.

    2. Caminho de pesquisa de esquemas

      No Databricks SQL e Databricks Runtime 19 e superior, qualifica-se a relação com cada esquema no PATH, por ordem, até ser encontrada uma correspondência.

      • Catálogos ou esquemas em falta: Catálogos ou esquemas em falta no caminho são saltados. Um objeto para o qual o utilizador tem privilégios insuficientes não é ignorado; O Azure Databricks gera o erro correspondente.
      • Vistas e tabelas temporárias: Vistas temporárias e tabelas temporárias vivem em system.session, pelo que são alcançadas sempre que system.session está no PATH.
      • Tabelas e vistas persistentes no esquema atual: Tabelas persistentes e vistas no esquema atual são acedidas através da entrada virtual CURRENT_SCHEMA .

      O caminho aplica-se a nomes de relações não qualificadas em consultas e DML, e a nomes não qualificados numa consulta que faz parte de uma instrução DDL.

      • Onde o caminho se aplica:

        Contexto Caminho utilizado
        Consultas e DML (SELECT, INSERT, UPDATE, DELETE, MERGE) Sessão PATH
        Consulta de CREATE TABLE AS Sessão PATH
        Consulta de um persistente CREATE VIEW PATH capturado em tempo de criação
        Sujeito de CREATE, DROP, ALTER, e semelhantes current_catalog.current_schema (não é uma pesquisa de caminho)
      • Versões anteriores: No Databricks Runtime 18 e inferiores, uma relação não qualificada que não é um CTE é resolvida numa ordem fixa.

        1. Vista temporária ou tabela temporária

          Associe o identificador a qualquer vista temporária ou tabela temporária definida na sessão atual.

        2. Tabela persistente

          Qualifique totalmente o identificador antecipando o resultado de SELECT current_catalog() e SELECT current_schema() e procure-o como uma relação persistente.

Se a relação não puder ser resolvida para qualquer tabela, exibição ou CTE, o Databricks gerará um erro TABLE_OR_VIEW_NOT_FOUND.

Caminho capturado

Uma vista persistente capta o PATH da sessão no momento de criação. Consultas posteriores à vista resolvem nomes não qualificados contra esse caminho capturado, não contra o caminho da sessão do invocador. current_path() e current_schema() nessa consulta ainda devolvem os valores da sessão do invocador.

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ções e procedimentos

Uma referência rotineira (uma chamada de função ou chamada de procedimento) é reconhecida pelo conjunto obrigatório de parênteses.

Pode resolver em:

  • Uma função incorporada fornecida pelo Azure Databricks,
  • Uma função temporária definida pelo usuário com escopo para a sessão atual, ou
  • Uma função ou procedimento persistente definido pelo utilizador armazenado no Metastore Hive ou no Catálogo Unity.

A resolução de um nome rotineiro depende de este ser qualificado:

  • Qualificado

    Se o nome for totalmente qualificado com três partes: catalog.schema.routine, é considerado único.

    Se o nome consiste em duas partes: schema.routine, ele é ainda mais especificado com o resultado de SELECT current_catalog() para torná-lo único.

    Se o esquema for session, é ainda qualificado com system e interpretado como uma função temporária.

    A rotina é então consultada no catálogo.

  • Não qualificado

    • Caminho de pesquisa de esquema: No Databricks SQL e Databricks Runtime 19 e superiores, qualifica o nome da rotina com cada esquema no PATH por ordem e escolhe a primeira correspondência.
    • Catálogos ou esquemas em falta: Catálogos ou esquemas em falta no caminho são saltados. Um objeto para o qual o utilizador tem privilégios insuficientes não é ignorado; O Azure Databricks gera o erro correspondente.
    • Onde vivem as rotinas: Funções escalares e de tabela incorporadas estão em system.builtin, funções de IA em system.ai, e funções temporárias em system.session.
    • Caminho padrão: O padrão PATH é system.session, então system.builtin, então system.ai, então CURRENT_SCHEMA.

    Warning

    Funções temporárias com o mesmo nome que funções incorporadas têm precedência porque system.session vêm antes system.builtin no caminho padrão. Podes reordenar o caminho com SET o PATH. Não dependa de funções temporárias que acompanham funções incorporadas.

    • Onde o caminho se aplica:

      Contexto Caminho utilizado
      Nomes de rotinas não qualificadas em consultas e DML Sessão PATH
      Corpo de uma função SQL definida pelo utilizador PATH capturado em tempo de criação
      Corpo de um SQL SECURITY DEFINER procedimento PATH capturado no momento de criação, sem system.session
      Corpo de um SQL SECURITY INVOKER procedimento PATH em direto do ouvinte
      Sujeito de CREATE FUNCTION, DROP FUNCTION, CREATE PROCEDURE, e semelhantes Esquema atual (não uma pesquisa de caminho)
    • Versões anteriores: No Databricks Runtime 18 e inferiores, o Azure Databricks segue uma ordem fixa de precedência.

      1. Função embutida

        Se existir uma função com este nome entre o conjunto de funções incorporadas, essa função é escolhida.

      2. Função temporária

        Se existir uma função com este nome entre o conjunto de funções temporárias, essa função é escolhida.

      3. Função persistente

        Qualifique totalmente o nome da função antecipando o resultado de SELECT current_catalog() e SELECT current_schema() e procure-o como uma função persistente.

Se a rotina não puder ser resolvida, o Azure Databricks gera um UNRESOLVED_ROUTINE erro.

Caminho capturado

  • Função definida pelo utilizador do SQL: Nomes não qualificados no corpo são resolvidos contra o PATH capturado em CREATE FUNCTION, e não no caminho de sessão do invocador. current_path() e current_schema() nesse corpo ainda retornam os valores da sessão do invocador.
  • Procedimento com SQL SECURITY DEFINER: Nomes não qualificados são resolvidos contra o PATH capturado no CRIAR PROCEDIMENTO, com system.session omitido. current_path() nesse corpo retorna esse mesmo caminho capturado.
  • Procedimento com: SQL SECURITY INVOKERNomes não qualificados usam o percurso em direto do chamador.

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