名前解決

適用対象:「はい」のチェック マーク Databricks SQL 「はい」のチェック マーク Databricks Runtime

名前解決は、識別子が特定の列参照、フィールド参照、パラメーター参照、またはテーブル参照に解決されるプロセスです。

列、フィールド、パラメーター、変数の解決

式内の識別子は、次のいずれかへの参照にすることができます。

  • ビュー、テーブル、共通テーブル式 (CTE)、または column_alias に基づく列名
  • 構造体またはマップ内のフィールド名またはマップ キー。 フィールドとキーを非修飾にすることはできません。
  • SQL ユーザー定義関数パラメーター名
  • 変数名
  • () の使用を必要としない current_user または current_date などの特殊な関数。
  • 列または変数の値を既定値に設定するために、INSERTUPDATEMERGE または SET VARIABLE のコンテキストで使用される DEFAULT キーワード。

名前解決では、次の原則が適用されます。

  • 最も近い一致参照が優先され、
  • 列とパラメーターは、フィールドとキーより優先されます。

詳しく言うと、特定の参照への識別子の解決は、次の規則に次の順番で従います。

  1. ローカル参照

    1. 列参照

      識別子 (修飾されている場合がある) を、FROM clauseテーブル参照内の列名と照合します。

      このような一致が複数ある場合は、AMBIGUOUS_COLUMN_OR_FIELD エラーが発生します。

    2. パラメーターなしの関数参照

      識別子が修飾されておらず、current_usercurrent_date、または current_timestamp と一致する場合: これらのいずれかの関数として解決します。

    3. 列の DEFAULT の指定

      識別子が修飾されておらず、default と一致し、UPDATE SETINSERT VALUES、または MERGE WHEN [NOT] MATCHED のコンテキストで全体の式が構成されている場合: INSERTUPDATE、または MERGE のターゲット テーブルの各 DEFAULT 値として解決します。

    4. 構造体フィールドまたはマップ キー参照

      識別子が修飾されている場合、次の手順に従って、フィールドまたはマップ キーとの照合を試みます。

      A. 最後の識別子を削除し、それをフィールドまたはキーとして扱います。 B. 残りを FROM clauseテーブル参照の列と照合します。

      このような一致が複数ある場合は、AMBIGUOUS_COLUMN_OR_FIELD エラーが発生します。

      一致があり、列が次の場合:

      • STRUCT: フィールドと一致します。

        フィールドに一致しない場合は、FIELD_NOT_FOUND エラーが発生します。

        複数のフィールドがある場合は、AMBIGUOUS_COLUMN_OR_FIELD エラーが発生します。

      • MAP: キーが修飾されている場合、エラーが発生します。

        キーが実際にマップに存在しない場合は、ランタイム エラーが発生する可能性があります。

      • その他の型: エラーが発生します。 C. 前の手順を繰り返して、末尾の識別子をフィールドとして削除します。 列として解釈する残りの識別子がある間、ルール (A) と (B) を適用します。

  2. ラテラル列のエイリアス化

    適用対象:check marked yes Databricks SQL Databricks Runtime 12.2 LTS 以降

    式が SELECT リスト内にある場合、先頭の識別子を、その SELECT リスト内の前の列の別名と照合します。

    このような一致が複数ある場合は、AMBIGUOUS_LATERAL_COLUMN_ALIAS エラーが発生します。

    残りの各識別子をフィールドまたはマップ キーとして照合し、一致しない場合は、FIELD_NOT_FOUND または AMBIGUOUS_COLUMN_OR_FIELD エラーが発生します。

  3. 相関関係

    • LATERAL

      クエリの前に LATERAL キーワードが付いている場合は、クエリを含み、LATERAL が前に付いた FROM 内のテーブル参照を考慮して、ルール 1.a と 1.d を適用します。

    • 通常

      クエリがスカラー サブクエリIN、または EXISTS サブクエリの場合、含まれているクエリの FROM 句内のテーブル参照を考慮して、ルール 1.a、1.d、および 2 が適用されます。

  4. 入れ子になった相関関係

    クエリの入れ子のレベルを反復処理するルール 3 を再適用します。

  5. ルーチン パラメーター

    式が CREATE FUNCTION ステートメントの一部である場合:

    1. 識別子をパラメーター名と照合します。 識別子が修飾されている場合、修飾子は関数の名前と一致する必要があります。
    2. 識別子が修飾されている場合、ルール 1.c に従ってパラメーターのフィールドまたはマップ キーと照合します
  6. 変数

    1. 識別子を変数名と一致させます。 識別子が修飾されている場合、修飾子は session または system.session である必要があります。
    2. 識別子が修飾されている場合、ルール 1.c に従って変数のフィールドまたはマップ キーと照合します

制限事項

高コストになる可能性のある相関クエリの実行を防ぐために、Azure Databricks ではサポートされる相関関係を 1 つのレベルに制限しています。 この制限は、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

テーブルとビューの解決

テーブル参照の識別子は、次のいずれかにすることができます。

  • Unity Catalog または Hive メタストアの永続的なテーブルまたはビュー
  • 共通テーブル式 (CTE)
  • 一時ビュー

識別子の解決は、それが修飾されているかどうかによって異なります。

  • 修飾

    識別子が 3 つの部分で完全修飾されている場合: catalog.schema.relation、それは一意になります。

    識別子が 2 つの部分で構成されている場合: schema.relation、それは一意にするために SELECT current_catalog() の結果でさらに修飾されます。

  • 非修飾

    1. 共通テーブル式

      参照が WITH 句のスコープ内にある場合、識別子を CTE と照合します。これは、すぐに含まれている WITH 句から始め、そこから外側に移動します。

    2. 一時ビュー

      識別子を、現在のセッション内で定義されている一時ビューと照合します。

    3. 永続化されたテーブル

      SELECT current_catalog()SELECT current_schema() の結果を先頭に付けて、識別子を完全修飾し、それを永続的な関係として検索します。

関係をテーブル、ビュー、または 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.

関数の解決

関数参照は、必須の末尾の一連の括弧によって認識されます。

これは次に解決できます。

  • Azure Databricks によって提供される組み込み関数
  • 現在のセッションをスコープとした一時的なユーザー定義関数、または
  • Hive メタストアまたは Unity Catalog に格納されている永続的なユーザー定義関数。

関数名の解決は、それが修飾されているかどうかによって異なります。

  • 修飾

    名前が 3 つの部分で完全修飾されている場合: catalog.schema.function、それは一意になります。

    名前が 2 つの部分で構成されている場合: schema.function、それは一意にするために SELECT current_catalog() の結果でさらに修飾されます。

    その後、関数はカタログ内で検索されます。

  • 非修飾

    非修飾関数名の場合、Azure Databricks では固定の優先順位 (PATH) に従います。

    1. 組み込み関数

      この名前の関数が一連の組み込み関数の中に存在する場合は、その関数が選択されます。

    2. 一時関数

      この名前の関数が一連の一時関数の中に存在する場合は、その関数が選択されます。

    3. 永続化された関数

      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