共用方式為


名稱解析

適用於:核取記號為「是」Databricks SQL 核取記號為「是」Databricks Runtime

名稱解析是將 標識符 解析為特定的 column、欄位、參數或 table參照的過程。

Column、欄位、參數和變數解析

運算式中的識別碼可以是下列任一項的參考:

  • 根據檢視、table、通用 table 表示式 (CTE) 或 column_aliasColumn 名稱
  • 結構或對應內的功能變數名稱或對應索引鍵。 欄位和索引鍵永遠無法限定。
  • SQL 使用者定義函數的參數名稱。
  • 變數名稱
  • 特殊函式,例如 current_usercurrent_date ,不需要 使用 ()
  • DEFAULT 關鍵詞,用於 INSERTUPDATEMERGESET VARIABLE 的內容中,將 column 或變數值 set 為其預設值。

名稱解析會套用下列原則:

  • 最接近比對參考會獲勝,且
  • Columns 和參數優先於欄位和鍵值。

詳細來說,將標識碼解析為特定參考會遵循下列規則:

  1. 本機參考

    1. Column 參考

      FROM clausetable 的 參考中,將可能限定的 identifier比對到 column 名稱。

      如果有一個以上的相符專案,請引發 AMBIGUOUS_COLUMN_OR_FIELD 錯誤。

    2. 無參數函式參考

      如果 identifier 不合格,且符合 current_usercurrent_datecurrent_timestamp:將其解析為下列其中一個函式。

    3. Column DEFAULT(規格)

      如果 identifier 不合格,則會比對 default,並在 UPDATE SETINSERT VALUESMERGE WHEN [NOT] MATCHED的上下文中構成整個表達式:將其解析為 INSERTUPDATEMERGE之目標 table 的相應 DEFAULT 值。

    4. 結構欄位或對應索引鍵參考

      如果 identifier 符合條件,請按照下列步驟,嘗試將其比對到欄位或映射鍵:

      A. Remove 最後一個 identifier,並將它視為字段或索引鍵。 B. 比對 table 參考FROM clause中的餘數與 column。

      如果有一個以上的相符專案,請引發 AMBIGUOUS_COLUMN_OR_FIELD 錯誤。

      如果有相符項目,且 column 是:

      • STRUCT:比對欄位。

        如果無法比對欄位,請引發 FIELD_NOT_FOUND 錯誤。

        如果有多個字段,請引發 AMBIGUOUS_COLUMN_OR_FIELD 錯誤。

      • MAP:如果索引鍵為限定,則引發錯誤。

        如果索引鍵實際上不存在於對應中,可能會發生運行時間錯誤。

      • 任何其他類型:引發錯誤。 C. 重複上述步驟,將 identifier 的尾端 remove 設為欄位。 套用規則 (A) 和 (B) ,而左側有 identifier,以解譯為 column。

  2. 橫向 column 別名

    適用於:核取記號為「是」 Databricks SQL 核取記號為「是」 Databricks Runtime 12.2 LTS 和更新版本

    如果表達式位於 SELECTlist內,請將前置 identifier 與該 SELECTlist中的前置 column 別名 相符。

    如果有一個以上的相符專案,請引發 AMBIGUOUS_LATERAL_COLUMN_ALIAS 錯誤。

    比對每個剩餘的 identifier 作為字段或地圖索引鍵,並在無法比對時引發 FIELD_NOT_FOUNDAMBIGUOUS_COLUMN_OR_FIELD 錯誤。

  3. 相互關聯

    • 側面的

      如果查詢前面加上 LATERAL 關鍵詞,請套用規則 1.a 和 1.d,考慮包含查詢的 FROM 中 table 參考,並在 LATERAL之前。

    • 一般

      如果查詢是 純量子查詢、子查詢、IN子查詢或 EXISTS 子查詢,則套用規則 1.a、1.d 和 2,並考慮包含查詢的 FROM 子句中的 table 參考。

  4. 巢狀相互關聯

    重新套用規則 3 逐一查看查詢的巢狀層級。

  5. 例程 parameters

    如果表達式是 CREATE FUNCTION 語句的一部分:

    1. 請將 identifier 匹配到 參數名稱。 如果 identifier 符合資格,則限定符必須與函式的名稱相匹配。
    2. 如果 identifier 合格,依照規則 1.c,將其匹配至參數的欄位或映射鍵
  6. 變數

    1. 比對 identifier 與 變數名稱。 如果 identifier 是合格的,那麼限定符必須是 sessionsystem.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 和檢視解析度

table-reference 中的 identifier 可以是下列任一項:

  • 持續性 table 或在 Unity 中的檢視 Catalog 或 Hive 中繼資料存放區
  • 常用 table 表達式 (CTE)
  • 暫存檢視

identifier 的解決取決於其是否合格:

  • 合格

    如果 identifier 由三個部分完整限定為 catalog.schema.relation,則是唯一的。

    如果 identifier 包含兩個部分:schema.relation,則會進一步限定 SELECT current_catalog() 的結果,使其是唯一的。

  • 不合格的

    1. 常見 table 表示式

      如果參考位於 WITH 子句的範圍內,請將 identifier 與 CTE 進行匹配,從立即包含的 WITH 子句開始,然後向外進行搜尋。

    2. 暫存檢視

      比對 identifier 與目前會話內定義的任何暫存檢視。

    3. 持續 table

      完全 qualify 和 identifier,方法是將 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 來識別。

它可以解析為:

函式名稱的解析取決於函式名稱是否合格:

  • 合格

    如果名稱具有三個部分的完整名稱: catalog.schema.function,則是唯一的。

    如果名稱包含兩個部分: schema.function,則會進一步限定其結果 SELECT current_catalog() ,使其是唯一的。

    函式接著會在 catalog中查閱。

  • 不合格的

    針對未限定的函式名稱,Azure Databricks 會遵循固定優先順序 (PATH):

    1. 內建函式

      如果此名稱的函式存在於內建函式 set 中,則會選擇該函式。

    2. 暫存函式

      如果此名稱的函式存在於暫存函式 set 中,則會選擇該函式。

    3. Persisted 函式

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