Resolución de nombres

Se aplica a:casilla marcada como Sí Databricks SQL casilla marcada como Sí Databricks Runtime

La resolución de nombres es el proceso por el que los identificadores se resuelven como referencias de columna, campo, parámetro o tabla específicas.

Resolución de columnas, campos, parámetros y variables

Los identificadores de las expresiones pueden ser referencias a cualquiera de los siguientes elementos:

La resolución de nombres aplica los siguientes principios:

  • Gana la mejor coincidencia.
  • Las columnas y los parámetros ganan por encima de los campos y las claves.

En detalle, la resolución de identificadores como una referencia específica sigue estas reglas en orden:

  1. Referencias locales

    1. Referencia de columna

      Busca una coincidencia del identificador, que puede estar completo, con un nombre de columna en una referencia de tabla de FROM clause.

      Si hay más de una coincidencia, genera el error AMBIGUOUS_COLUMN_OR_FIELD.

    2. Referencia de función sin parámetros

      Si el identificador no está completo y coincide con current_user, current_date o current_timestamp, lo resuelve como una de estas funciones.

    3. Especificación de columna DEFAULT

      Si el identificador no está completo, coincide con default y compone toda la expresión en el contexto de UPDATE SET, INSERT VALUESo MERGE WHEN [NOT] MATCHED, lo resuelve como el valor DEFAULT de la tabla de destino correspondiente a INSERT, UPDATE o MERGE.

    4. Referencia de campo de estructura o clave de asignación

      Si el identificador está completo, busca una coincidencia con un campo o una clave de asignación según los pasos siguientes:

      A. Quita el último identificador y lo trata como un campo o una clave. B. Busca una coincidencia del resto con una columna de la referencia de tabla o de FROM clause.

      Si hay más de una coincidencia, genera el error AMBIGUOUS_COLUMN_OR_FIELD.

      Si hay una coincidencia y la columna es:

      • STRUCT: establece la coincidencia con el campo.

        Si no puede establecer una coincidencia con el campo, genera el error FIELD_NOT_FOUND.

        Si hay más de un campo, genera el error AMBIGUOUS_COLUMN_OR_FIELD.

      • MAP: genera un error si la clave está completa.

        Puede producirse un error en tiempo de ejecución si la clave no está presente realmente en la asignación.

      • Cualquier otro tipo: genera un error. C. Repita el paso anterior para quitar el identificador final como un campo. Aplique las reglas (A) y (B) mientras quede un identificador para interpretarlo como una columna.

  2. Alias de columna lateral

    Se aplica a:casilla marcada como sí Databricks SQL casilla marcada como Sí Databricks Runtime 12.2 LTS y versiones posteriores

    Si la expresión está dentro de una lista SELECT, haga coincidir el identificador inicial con un alias de columna anterior en esa lista SELECT.

    Si hay más de una coincidencia de ese tipo, genera el error AMBIGUOUS_LATERAL_COLUMN_ALIAS.

    Busca una coincidencia del resto del identificador con un campo o una clave de asignación y genera el error FIELD_NOT_FOUND o AMBIGUOUS_COLUMN_OR_FIELD si no puede establecer una coincidencia.

  3. Correlación

    • LATERAL

      Si la consulta va precedida de una palabra clave LATERAL, aplica las reglas 1.a y 1.d teniendo en cuenta las referencias de tabla de FROM que contienen la consulta y preceden a LATERAL.

    • Regular

      Si la consulta es una subconsulta escalar, IN o EXISTS, aplica las reglas 1.a, 1.d y 2 teniendo en cuenta las referencias de tabla de la cláusula FROM de la consulta contenedora.

  4. Correlación anidada

    Vuelve a aplicar la regla 3 iterándola en los niveles de anidamiento de la consulta.

  5. Parámetros de rutina

    Si la expresión forma parte de una instrucción CREATE FUNCTION:

    1. Busca una coincidencia del identificador con un nombre de parámetro. Si el identificador está completo, el calificador debe coincidir con el nombre de la función.
    2. Si el identificador está completo, busca una coincidencia con un campo o una clave de asignación de un parámetro siguiendo la regla 1.c.
  6. Variables

    1. Haga coincidir el identificador con un nombre de variable. Si el identificador está calificado, el calificador debe ser session o system.session.
    2. Si el identificador está completo, busque una coincidencia con un campo o una clave de asignación de una variable siguiendo la regla 1.c

Limitaciones

Para evitar la ejecución de consultas que puedan consumir muchos recursos, Azure Databricks limita la correlación a un nivel. Esta restricción se aplica también a las referencias de parámetros en las funciones SQL.

Ejemplos

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

Resolución de tablas y vistas

Un identificador en una referencia de tabla puede ser cualquiera de los siguientes elementos:

  • Tabla o vista persistente en Unity Catalog o el metastore de Hive
  • Expresión de tabla común (CTE)
  • Vista temporal

La resolución de un identificador depende de si está completo (calificado) o no:

  • Apto

    Si el identificador está completo con tres partes (catalog.schema.relation), es único.

    Si el identificador consta de dos partes (schema.relation) se completa con el resultado de SELECT current_catalog() para que sea único.

  • Incompleto

    1. Expresión de tabla común

      Si la referencia está dentro del ámbito de una cláusula WITH, busca una coincidencia del identificador con un CTE que empiece con la cláusula contenedora WITH inmediata y se desplaza hacia fuera desde ahí.

    2. Vista temporal

      Busca una coincidencia del identificador con alguna vista temporal definida dentro de la sesión actual.

    3. Tabla persistente

      Completa el identificador anteponiendo el resultado de SELECT current_catalog() y SELECT current_schema(), y lo busca como una relación persistente.

Si la relación no se puede resolver como una tabla, vista o CTE, Databricks genera el error TABLE_OR_VIEW_NOT_FOUND.

Ejemplos

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

Resolución de funciones

Una referencia de función se reconoce por el conjunto de paréntesis finales obligatorios.

Se puede resolver como:

La resolución del nombre de una función depende de si está completo (calificado) o no:

  • Apto

    Si el nombre está completo con tres partes (catalog.schema.function), es único.

    Si el nombre consta de dos partes (schema.function), se completa con el resultado de SELECT current_catalog() para que sea único.

    A continuación, se busca la función en el catálogo.

  • Incompleto

    En el caso de los nombres de función incompletos, Azure Databricks sigue un orden de prioridad fijo (PATH):

    1. Función integrada

      Si existe una función con este nombre en el conjunto de funciones integradas, se elige esa función.

    2. Función temporal

      Si existe una función con este nombre en el conjunto de funciones temporales, se elige esa función.

    3. Función persistente

      Completa el nombre de la función anteponiendo el resultado de SELECT current_catalog() y SELECT current_schema(), y lo busca como una función persistente.

Si la función no se puede resolver, Azure Databricks genera el error UNRESOLVED_ROUTINE.

Ejemplos

> 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