Resolução de nomes

Aplica-se a: marca de seleção positiva SQL do Databricks marca de seleção positiva 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:

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:

  1. Referências de local

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

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

      Se o identificador não for qualificado e corresponder a current_user, current_date ou current_timestamp: resolva-o como uma dessas funções.

    3. Especificação de coluna DEFAULT

      Se o identificador não for qualificado, corresponder a default e criar a expressão inteira no contexto de um UPDATE SET, INSERT VALUES ou MERGE WHEN [NOT] MATCHED: resolva como o respectivo valor DEFAULT da tabela de destino de INSERT, UPDATE ou MERGE.

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

  2. Alias de coluna lateral

    Aplica-se a:verificação marcada como sim SQL do Databricks verificação marcada como sim 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 lista SELECT.

    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.

  3. 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 no FROM que contém a consulta e precedendo a LATERAL.

    • Regular

      Se a consulta for uma subconsulta escalar, IN ou EXISTS, a subconsulta aplicará as regras 1.a, 1.d e 2 considerando as referências de tabela na cláusula FROM contida na consulta.

  4. Correlação aninhada

    Aplique novamente 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. Corresponda 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 um campo ou chave de 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 deverá ser session ou system.session.
    2. Se o identificador for qualificado, corresponda a um campo ou chave de mapeamento de uma variável seguindo a regra 1.c

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 de SELECT current_catalog() para torná-lo exclusivo.

  • Não qualificado

    1. 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áusula WITH imediatamente contida e movendo para fora dela.

    2. Exibição temporária

      Corresponda o identificador a qualquer exibição temporária definida dentro da sessão atual.

    3. Tabela persistida

      Qualifique totalmente o identificador pré-pendente do 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 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:

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 de SELECT 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):

    1. Função interna

      Se existir uma função com esse nome entre o conjunto de funções internas, essa função será escolhida.

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

    3. Função persistida

      Qualifique totalmente a função pré-pendente do resultado de SELECT current_catalog() e SELECT 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