名前解決
適用対象: Databricks SQL Databricks Runtime
名前解決は、識別子が特定の列参照、フィールド参照、パラメーター参照、またはテーブル参照に解決されるプロセスです。
列、フィールド、パラメーター、変数の解決
式内の識別子は、次のいずれかへの参照にすることができます。
- ビュー、テーブル、共通テーブル式 (CTE)、または column_alias に基づく列名。
- 構造体またはマップ内のフィールド名またはマップ キー。 フィールドとキーを非修飾にすることはできません。
- SQL ユーザー定義関数のパラメーター名。
- 変数名。
()
の使用を必要としないcurrent_user
またはcurrent_date
などの特殊な関数。- 列または変数の値を既定値に設定するために、
INSERT
、UPDATE
、MERGE
またはSET VARIABLE
のコンテキストで使用されるDEFAULT
キーワード。
名前解決では、次の原則が適用されます。
- 最も近い一致参照が優先され、
- 列とパラメーターは、フィールドとキーより優先されます。
詳しく言うと、特定の参照への識別子の解決は、次の規則に次の順番で従います。
ローカル参照
列参照
識別子 (修飾されている場合がある) を、
FROM clause
のテーブル参照内の列名と照合します。このような一致が複数ある場合は、AMBIGUOUS_COLUMN_OR_FIELD エラーが発生します。
パラメーターなしの関数参照
識別子が修飾されておらず、
current_user
、current_date
、またはcurrent_timestamp
と一致する場合: これらのいずれかの関数として解決します。列の DEFAULT の指定
識別子が修飾されておらず、
default
と一致し、UPDATE SET
、INSERT VALUES
、またはMERGE WHEN [NOT] MATCHED
のコンテキストで全体の式が構成されている場合:INSERT
、UPDATE
、またはMERGE
のターゲット テーブルの各DEFAULT
値として解決します。構造体フィールドまたはマップ キー参照
識別子が修飾されている場合、次の手順に従って、フィールドまたはマップ キーとの照合を試みます。
A. 最後の識別子を削除し、それをフィールドまたはキーとして扱います。 B. 残りを
FROM clause
の テーブル参照の列と照合します。このような一致が複数ある場合は、AMBIGUOUS_COLUMN_OR_FIELD エラーが発生します。
一致があり、列が次の場合:
STRUCT
: フィールドと一致します。フィールドに一致しない場合は、FIELD_NOT_FOUND エラーが発生します。
複数のフィールドがある場合は、AMBIGUOUS_COLUMN_OR_FIELD エラーが発生します。
MAP
: キーが修飾されている場合、エラーが発生します。キーが実際にマップに存在しない場合は、ランタイム エラーが発生する可能性があります。
その他の型: エラーが発生します。 C. 前の手順を繰り返して、末尾の識別子をフィールドとして削除します。 列として解釈する残りの識別子がある間、ルール (A) と (B) を適用します。
ラテラル列のエイリアス化
適用対象: Databricks SQL Databricks Runtime 12.2 LTS 以降
式が
SELECT
リスト内にある場合、先頭の識別子を、そのSELECT
リスト内の前の列の別名と照合します。このような一致が複数ある場合は、AMBIGUOUS_LATERAL_COLUMN_ALIAS エラーが発生します。
残りの各識別子をフィールドまたはマップ キーとして照合し、一致しない場合は、FIELD_NOT_FOUND または AMBIGUOUS_COLUMN_OR_FIELD エラーが発生します。
相関関係
LATERAL
クエリの前に
LATERAL
キーワードが付いている場合は、クエリを含み、LATERAL
が前に付いたFROM
内のテーブル参照を考慮して、ルール 1.a と 1.d を適用します。通常
クエリがスカラー サブクエリ、
IN
、またはEXISTS
サブクエリの場合、含まれているクエリのFROM
句内のテーブル参照を考慮して、ルール 1.a、1.d、および 2 が適用されます。
入れ子になった相関関係
クエリの入れ子のレベルを反復処理するルール 3 を再適用します。
ルーチン パラメーター
式が CREATE FUNCTION ステートメントの一部である場合:
- 識別子をパラメーター名と照合します。 識別子が修飾されている場合、修飾子は関数の名前と一致する必要があります。
- 識別子が修飾されている場合、ルール 1.c に従ってパラメーターのフィールドまたはマップ キーと照合します
変数
- 識別子を変数名と一致させます。 識別子が修飾されている場合、修飾子は
session
またはsystem.session
である必要があります。 - 識別子が修飾されている場合、ルール 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()
の結果でさらに修飾されます。非修飾
共通テーブル式
参照が
WITH
句のスコープ内にある場合、識別子を CTE と照合します。これは、すぐに含まれているWITH
句から始め、そこから外側に移動します。一時ビュー
識別子を、現在のセッション内で定義されている一時ビューと照合します。
永続化されたテーブル
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
) に従います。組み込み関数
この名前の関数が一連の組み込み関数の中に存在する場合は、その関数が選択されます。
一時関数
この名前の関数が一連の一時関数の中に存在する場合は、その関数が選択されます。
永続化された関数
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