Resolução de nomes

Aplica-se a: Marque Sim Databricks SQL Marque Sim Databricks Runtime

A resolução de nomes é o processo pelo qual os identificadores são resolvidos para 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:

  • Nome da coluna com base em um modo de exibição, tabela, expressão de tabela comum (CTE) ou um column_alias.
  • Nome do campo ou chave do mapa dentro de um struct ou mapa. Campos e chaves nunca podem ser desqualificados.
  • Nome do parâmetro de uma função definida pelo usuário SQL.
  • Nome da variável.
  • Uma função especial, como current_user ou current_date que não requer o uso de ().
  • A DEFAULT palavra-chave que é usada no contexto de , UPDATE, MERGE, ou SET VARIABLE para definir um valor de INSERTcoluna 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
  • Colunas e parâmetros conquistam campos e chaves.

Em detalhe, a resolução de identificadores para uma referência específica segue estas regras em 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, gere 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. Coluna especificação DEFAULT

      Se o identificador não for qualificado, corresponde default e compõe toda a expressão no contexto de um UPDATE SET, INSERT VALUESou MERGE WHEN [NOT] MATCHED: Resolver como o respetivo DEFAULT valor 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:

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

      Se houver mais de uma correspondência, gere 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 correspondido, gere um erro FIELD_NOT_FOUND .

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

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

        Um eror de tempo de execução pode ocorrer 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 à direita como um campo. Aplique as regras (A) e (B) enquanto houver um identificador restante para interpretar como uma coluna.

  2. Aliasing da coluna lateral

    Aplica-se a: Marque Sim Databricks SQL Marque Sim Databricks Runtime 12.2 LTS e superior

    Se a expressão estiver dentro de uma SELECT lista, corresponda o identificador à esquerda a um alias de coluna anterior nessa SELECT lista.

    Se houver mais de uma correspondência, gere um erro AMBIGUOUS_LATERAL_COLUMN_ALIAS .

    Corresponda a cada identificador restante como um campo ou uma chave de mapa e gere FIELD_NOT_FOUND ou AMBIGUOUS_COLUMN_OR_FIELD erro se não puderem ser correspondidos.

  3. Correlação

    • LATERAIS

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

    • Regular

      Se a consulta for uma subconsulta escalar, , ou EXISTS subconsulta, INaplique 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

    Reaplique a regra 3 iterando sobre os níveis de aninhamento da consulta.

  5. Parâmetros de rotina

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

    1. Corresponder o identificador a um nome de parâmetro. Se o identificador for qualificado, o qualificador deverá corresponder ao nome da função.
    2. Se o identificador for qualificado, corresponda a uma chave de campo ou mapa de um parâmetro seguindo a regra 1.c
  6. Variáveis

    1. Corresponder o identificador a um nome de variável. Se o identificador for qualificado, o qualificador deve ser session ou system.session.
    2. Se o identificador for qualificado, corresponda a uma chave de campo ou mapa de uma variável seguindo a regra 1.c

Limitações

Para evitar a execução de consultas correlacionadas potencialmente caras, o Azure Databricks limita a correlação suportada a um nível. Essa restrição também se aplica a referências de parâmetros 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 tabelas e vistas

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

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 é qualificado com o resultado de SELECT current_catalog() torná-lo único.

  • Não qualificado

    1. Expressão de tabela comum

      Se a referência estiver dentro do escopo de uma WITH cláusula, faça a correspondência do identificador com um CTE, começando com a cláusula imediatamente contendo WITH e movendo-se para fora a partir daí.

    2. Vista temporária

      Corresponder o identificador a qualquer exibição temporária definida na sessão atual.

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

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

Uma referência de função é reconhecida pelo conjunto obrigatório de parênteses à direita.

Pode resolver a:

  • 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 definida pelo usuário persistente armazenada no metastore hive ou no Unity Catalog.

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, é único.

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

    A função é entã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):

    1. Função integrada

      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 função não puder ser resolvida, o Azure Databricks gerará um UNRESOLVED_ROUTINE erro.

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