Поделиться через


Разрешение имен

Область применения:флажок Databricks SQL флажок Databricks Runtime

Разрешение имен — это процесс, с помощью которого идентификаторы разрешаются для определенных -, field-, parameter-или -references.

Column, разрешение полей, параметров и переменных

Идентификаторы в выражениях могут ссылаться на любой из следующих элементов:

  • Column имя на основе представления, table, общего выражения table (CTE) или column_alias.
  • Имя поля или ключ карты в структуре или карте. Поля и ключи никогда не могут быть незаквалифицироваться.
  • Имя параметра определяемой пользователем функции SQL.
  • Имя переменной.
  • Специальная функция, например current_user или current_date которая не требует использования ().
  • Ключевое слово DEFAULT, используемое в контексте INSERT, UPDATE, MERGEили SET VARIABLE для set значения column или переменной по умолчанию.

Разрешение имен применяет следующие принципы:

  • Ближайшие победы в сопоставлении ссылок и
  • Columns и параметр выигрывают над полями и ключами.

Подробные сведения о разрешении идентификаторов для конкретной ссылки соответствуют следующим правилам:

  1. Локальные ссылки

    1. справочник Column

      Соответствует identifier, который может быть квалифицирован, с именем column в table ссылкеFROM clause.

      Если существует несколько таких совпадений, вызовет ошибку AMBIGUOUS_COLUMN_OR_FIELD .

    2. Справочник по функции без параметров

      Если identifier неквалифицированный и совпадает с current_user, current_dateили current_timestamp: разрешить его как одну из этих функций.

    3. Column спецификации DEFAULT

      Если identifier неквалифицированный, соответствует default и составляет полностью выражение в контексте UPDATE SET, INSERT VALUESили MERGE WHEN [NOT] MATCHED: разрешить как соответствующее значение DEFAULT для целевого table в INSERT, UPDATE или MERGE.

    4. Ссылка на поле структуры или ключ карты

      Если identifier квалифицирован, выполните попытку сопоставить его с полем или ключом карты в соответствии со следующими шагами:

      А. Remove последний identifier и рассматривать его как поле или ключ. B. Сопоставьте остаток с в справочнике .

      Если существует несколько таких совпадений, вызовет ошибку AMBIGUOUS_COLUMN_OR_FIELD .

      Если имеется совпадение, и column является:

      • STRUCT: соответствует полю.

        Если поле не удается сопоставить, вызовите ошибку FIELD_NOT_FOUND .

        Если существует несколько полей, возникает ошибка AMBIGUOUS_COLUMN_OR_FIELD .

      • MAP: возникает ошибка, если ключ квалифицирован.

        Средство выполнения может произойти, если ключ на самом деле отсутствует в карте.

      • Любой другой тип: вызов ошибки. В. Повторите предыдущий шаг, чтобы remove конечный identifier в качестве поля. Применяйте правила (A) и (B), пока identifier не будет интерпретировано как column.

  2. боковой column псевдоним

    Область применения:флажок Databricks SQL флажок Databricks Runtime 12.2 LTS и выше

    Если выражение находится в пределах , соотнесите начальный с предыдущим алиасом для в этом .

    Если существует несколько таких совпадений, вызовет ошибку AMBIGUOUS_LATERAL_COLUMN_ALIAS .

    Сопоставляйте каждый оставшийся identifier как поле или ключ отображения, и вызывайте ошибку FIELD_NOT_FOUND или AMBIGUOUS_COLUMN_OR_FIELD, если они не могут быть сопоставлены.

  3. Корреляция

    • БОКОВОЙ

      Если перед запросом находится ключевое слово LATERAL, примените правила 1.a и 1.d, учитывая ссылки table в FROM, содержащем запрос, и предшествующие LATERAL.

    • Периодически

      Если запрос является скалярным вложенным запросом ,, INили вложенным запросом EXISTS, применяются правила 1.a, 1.d и 2 с учетом ссылок table в предложении FROM запроса.

  4. Вложенная корреляция

    Повторно примените правило 3 итерации по уровням вложенности запроса.

  5. Рутины parameters

    Если выражение является частью инструкции CREATE FUNCTION:

    1. Сопоставьте identifier с именем параметра . Если identifier квалифицирован, квалификатор должен соответствовать имени функции.
    2. Если identifier соответствует условиям, сопоставьте с полем или ключом отображения параметра, согласно правилу 1.c
  6. Переменные

    1. Соотнесите identifier с переменной . Если identifier квалифицирован, квалификатор должен быть session или system.session.
    2. Если identifier квалифицирован, сопоставьте его с полем или ключом карты переменной в соответствии с правилом 1.c.

Ограничения

Чтобы предотвратить выполнение потенциально дорогостоящих сопоставленных запросов, Azure Databricks ограничивает поддерживаемую корреляцию на один уровень. Это ограничение также применяется к ссылкам на параметры в функциях SQL.

Примеры

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

Table и разрешение вида

identifier в table-reference может быть одним из следующих вариантов:

Решение по identifier зависит от того, соответствует ли оно необходимым квалификациям.

  • Квалифицирован

    Если identifier полностью заполнено тремя частями: catalog.schema.relation, это уникально.

    Если identifier состоит из двух частей: schema.relation, оно дополнительно уточняется результатом SELECT current_catalog(), чтобы стать уникальным.

  • Неквалифицированный

    1. общее table выражение

      Если ссылка находится в пределах предложения WITH, сопоставляйте identifier с CTE, начиная с наиболее внутреннего предложения WITH и продвигаясь наружу оттуда.

    2. Временное представление

      Сопоставьте identifier с любым временным представлением, определенным в текущем сеансе.

    3. сохранённые table

      Полностью qualifyidentifier, добавив в начало результат SELECT current_catalog() и SELECT current_schema(), и найдите это как постоянное соотношение.

Если связь не может быть разрешена ни с одним table, представлением или CTE, Databricks вызывает ошибку TABLE_OR_VIEW_NOT_FOUND.

Примеры

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

Разрешение функций

Ссылка на функцию распознается по обязательному set в конце круглых скобок.

Он может разрешить следующие возможности:

  • Встроенная функция, предоставляемая Azure Databricks,
  • Временная определяемая пользователем функция , ограниченная текущим сеансом или
  • Постоянная определяемая пользователем функция, хранящаяся в хранилище метаданных Hive или Unity Catalog.

Разрешение имени функции зависит от того, является ли оно квалифицированным:

  • Квалифицирован

    Если имя полностью заполнено тремя частями: catalog.schema.functionэто уникально.

    Если имя состоит из двух частей: schema.functionоно дополнительно квалифицировано с результатом SELECT current_catalog() , чтобы сделать его уникальным.

    Затем функция ищется в catalog.

  • Неквалифицированный

    Для неквалифицированных имен функций Azure Databricks следует фиксированному порядку приоритета (PATH):

    1. Встроенная функция

      Если функция по этому имени существует среди set встроенных функций, эта функция выбирается.

    2. Временная функция

      Если функция по этому имени существует среди set временных функций, эта функция выбирается.

    3. Сохраняемая функция

      Полностью qualify имя функции путем предварительного ожидания результата SELECT current_catalog() и SELECT current_schema() и поиска в качестве постоянной функции.

Если не удается разрешить функцию Azure Databricks, возникает UNRESOLVED_ROUTINE ошибка.

Примеры

> 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