ANSI 合規性

在 Spark SQL 中,有兩個選項符合 SQL 標準:spark.sql.ansi.enabledspark.sql.storeAssignmentPolicy(請參閱下表了解詳細資訊)。

spark.sql.ansi.enabled 設為 true 時,Spark SQL 會使用符合 ANSI 的方言,而不是符合 Hive。例如,如果 SQL 算子/函數的輸入無效,Spark 會在執行時擲回例外,而不是傳回 null 結果。某些 ANSI 方言功能可能並非直接來自 ANSI SQL 標準,但其行為與 ANSI SQL 的樣式一致。

此外,Spark SQL 有獨立的選項來控制在表格中插入列時的隱式轉換行為。轉換行為在標準中定義為儲存指定規則。

spark.sql.storeAssignmentPolicy 設為 ANSI 時,Spark SQL 會符合 ANSI 儲存指定規則。這是獨立的設定,因為其預設值為 ANSI,而設定 spark.sql.ansi.enabled 預設為停用。

屬性名稱 預設值 意義 自版本
spark.sql.ansi.enabled false 為 true 時,Spark 會嘗試符合 ANSI SQL 規格
1. Spark SQL 會對無效的運算擲回執行時例外,包括整數溢位錯誤、字串剖析錯誤等。
2. Spark 會使用不同的類型強制轉換規則來解決資料類型之間的衝突。這些規則始終基於資料類型優先順序。
3.0.0
spark.sql.storeAssignmentPolicy ANSI 在將值插入具有不同資料類型的欄位時,Spark 會執行類型轉換。目前,我們支援類型強制轉換規則的 3 個政策:ANSI、舊版和嚴格。
1. 使用 ANSI 政策時,Spark 會根據 ANSI SQL 執行類型強制轉換。實際上,行為大多與 PostgreSQL 相同。它不允許某些不合理的類型轉換,例如將字串轉換為 int 或將 double 轉換為布林。在插入數字類型欄位時,如果值超出目標資料類型的範圍,將會擲回溢位錯誤。
2. 使用舊版政策時,只要是有效的 Cast,Spark 就允許類型強制轉換,這非常寬鬆。例如,允許將字串轉換為 int 或將 double 轉換為布林。這也是 Spark 2.x 中唯一的行為,並且與 Hive 相容。
3. 使用嚴格政策時,Spark 不允許類型強制轉換中任何可能的精度損失或資料截斷,例如不允許將 double 轉換為 int 或將 decimal 轉換為 double。
3.0.0

下列小節說明在啟用 ANSI 模式時,算術運算、類型轉換和 SQL 解析的行為變更。對於 Spark SQL 中的類型轉換,有下列三種類型,本文將逐一說明:轉換、儲存指定和類型強制轉換。

算術運算

在 Spark SQL 中,預設不會檢查數字類型(小數除外)所執行的算術運算是否有溢位。這表示如果運算造成溢位,結果會與 Java/Scala 程式中的對應運算相同(例如,如果 2 個整數的總和高於可表示的最大值,結果會是負數)。另一方面,Spark SQL 會傳回小數溢位的 null。當 spark.sql.ansi.enabled 設為 true,且數字和區間算術運算發生溢位時,它會在執行階段擲出算術例外。

-- `spark.sql.ansi.enabled=true`
SELECT 2147483647 + 1;
org.apache.spark.SparkArithmeticException: [ARITHMETIC_OVERFLOW] integer overflow. Use 'try_add' to tolerate overflow and return NULL instead. If necessary set spark.sql.ansi.enabled to "false" to bypass this error.
== SQL(line 1, position 8) ==
SELECT 2147483647 + 1
       ^^^^^^^^^^^^^^

SELECT abs(-2147483648);
org.apache.spark.SparkArithmeticException: [ARITHMETIC_OVERFLOW] integer overflow. If necessary set spark.sql.ansi.enabled to "false" to bypass this error.

-- `spark.sql.ansi.enabled=false`
SELECT 2147483647 + 1;
+----------------+
|(2147483647 + 1)|
+----------------+
|     -2147483648|
+----------------+

SELECT abs(-2147483648);
+----------------+
|abs(-2147483648)|
+----------------+
|     -2147483648|
+----------------+

轉換

spark.sql.ansi.enabled 設為 true 時,CAST 語法所做的明確轉換會為標準中定義的非法轉換模式擲出執行階段例外,例如字串轉換為整數。

此外,ANSI SQL 模式不允許下列類型轉換,而這些轉換在關閉 ANSI 模式時是允許的

CAST 運算式中,來源和目標資料類型的有效組合由下表提供。「Y」表示組合在語法上有效且沒有限制,「N」表示組合無效。

來源\目標 數字 字串 日期 時間戳記 Timestamp_NTZ 區間 布林 二進位 陣列 對應 結構
數字 Y Y N Y N Y Y N N N N
字串 Y Y Y Y Y Y Y Y N N N
日期 N Y Y Y Y N N N N N N
時間戳記 Y Y Y Y Y N N N N N N
Timestamp_NTZ N Y Y Y Y N N N N N N
區間 Y Y N N N Y N N N N N
布林 Y Y N N N N Y N N N N
二進位 N Y N N N N N Y N N N
陣列 N Y N N N N N N Y N N
對應 N Y N N N N N N N Y N
結構 N Y N N N N N N N N Y

在上述表格中,所有使用新語法進行的 CAST 都標示為紅色 Y

-- Examples of explicit casting

-- `spark.sql.ansi.enabled=true`
SELECT CAST('a' AS INT);
org.apache.spark.SparkNumberFormatException: [CAST_INVALID_INPUT] The value 'a' of the type "STRING" cannot be cast to "INT" because it is malformed. Correct the value as per the syntax, or change its target type. Use `try_cast` to tolerate malformed input and return NULL instead. If necessary set "spark.sql.ansi.enabled" to "false" to bypass this error.
== SQL(line 1, position 8) ==
SELECT CAST('a' AS INT)
       ^^^^^^^^^^^^^^^^

SELECT CAST(2147483648L AS INT);
org.apache.spark.SparkArithmeticException: [CAST_OVERFLOW] The value 2147483648L of the type "BIGINT" cannot be cast to "INT" due to an overflow. Use `try_cast` to tolerate overflow and return NULL instead. If necessary set "spark.sql.ansi.enabled" to "false" to bypass this error.

SELECT CAST(DATE'2020-01-01' AS INT);
org.apache.spark.sql.AnalysisException: cannot resolve 'CAST(DATE '2020-01-01' AS INT)' due to data type mismatch: cannot cast date to int.
To convert values from date to int, you can use function UNIX_DATE instead.

-- `spark.sql.ansi.enabled=false` (This is a default behaviour)
SELECT CAST('a' AS INT);
+--------------+
|CAST(a AS INT)|
+--------------+
|          null|
+--------------+

SELECT CAST(2147483648L AS INT);
+-----------------------+
|CAST(2147483648 AS INT)|
+-----------------------+
|            -2147483648|
+-----------------------+

SELECT CAST(DATE'2020-01-01' AS INT)
+------------------------------+
|CAST(DATE '2020-01-01' AS INT)|
+------------------------------+
|                          null|
+------------------------------+

-- Examples of store assignment rules
CREATE TABLE t (v INT);

-- `spark.sql.storeAssignmentPolicy=ANSI`
INSERT INTO t VALUES ('1');
org.apache.spark.sql.AnalysisException: [INCOMPATIBLE_DATA_FOR_TABLE.CANNOT_SAFELY_CAST] Cannot write incompatible data for table `spark_catalog`.`default`.`t`: Cannot safely cast `v`: "STRING" to "INT".

-- `spark.sql.storeAssignmentPolicy=LEGACY` (This is a legacy behaviour until Spark 2.x)
INSERT INTO t VALUES ('1');
SELECT * FROM t;
+---+
|  v|
+---+
|  1|
+---+

轉換中的捨入

在將帶有小數的十進位數轉換為以 SECOND 為結束單位的間隔類型(例如 INTERVAL HOUR TO SECOND)時,Spark 會將小數部分捨入到「最接近鄰居」,除非兩個鄰居等距,則向上捨入。

儲存指派

如一開始所述,當 spark.sql.storeAssignmentPolicy 設為 ANSI(這是預設值)時,Spark SQL 會在表格插入時遵守 ANSI 儲存指派規則。表格插入中來源和目標資料類型的有效組合由下表提供。

來源\目標 數字 字串 日期 時間戳記 Timestamp_NTZ 區間 布林 二進位 陣列 對應 結構
數字 Y Y N N N N N N N N N
字串 N Y N N N N N N N N N
日期 N Y Y Y Y N N N N N N
時間戳記 N Y Y Y Y N N N N N N
Timestamp_NTZ N Y Y Y Y N N N N N N
區間 N Y N N N N* N N N N N
布林 N Y N N N N Y N N N N
二進位 N Y N N N N N Y N N N
陣列 N N N N N N N N Y** N N
對應 N N N N N N N N N Y** N
結構 N N N N N N N N N N Y**

* Spark 不支援間隔類型表格欄位。

** 對於陣列/對應/結構類型,資料類型檢查規則會遞迴套用至其組成元素。

在表格插入期間,Spark 會在數字值溢位時擲回例外狀況。

CREATE TABLE test(i INT);

INSERT INTO test VALUES (2147483648L);
org.apache.spark.SparkArithmeticException: [CAST_OVERFLOW_IN_TABLE_INSERT] Fail to insert a value of "BIGINT" type into the "INT" type column `i` due to an overflow. Use `try_cast` on the input value to tolerate overflow and return NULL instead.

類型強制轉換

類型提升和優先順序

spark.sql.ansi.enabled 設為 true 時,Spark SQL 會使用數個規則來管理如何解決資料類型之間的衝突。此衝突解決的核心是類型優先順序清單,它定義了特定資料類型的值是否可以隱含提升至另一資料類型。

資料類型 優先順序清單(從最窄到最寬)
位元組 位元組 -> 短整數 -> 整數 -> 長整數 -> 十進位 -> 浮點數* -> 雙精度浮點數
短整數 短整數 -> 整數 -> 長整數 -> 十進位 -> 浮點數* -> 雙精度浮點數
整數 整數 -> 長整數 -> 十進位 -> 浮點數* -> 雙精度浮點數
長整數 長整數 -> 十進位 -> 浮點數* -> 雙精度浮點數
十進位 十進位 -> 浮點數* -> 雙精度浮點數
浮點數 浮點數 -> 雙精度浮點數
雙精度浮點數 雙精度浮點數
日期 日期 -> Timestamp_NTZ -> Timestamp
時間戳記 時間戳記
字串 字串、長整數 -> 雙精度浮點數、日期 -> Timestamp_NTZ -> Timestamp、布林值、二進位 **
二進位 二進位
布林 布林
區間 區間
對應 Map***
陣列 陣列***
結構 結構***

* 為了最低公因數類型解析,浮點數會被略過以避免精度損失。

** 字串可以提升為多種資料類型。請注意,位元組/短整數/整數/十進位/浮點數不在此優先清單中。位元組/短整數/整數和字串之間的最低公因數類型是長整數,而十進位/浮點數之間的最低公因數類型是雙精度浮點數。

*** 對於複雜類型,優先規則會遞迴套用於其組成元素。

未類型化的 NULL 適用特殊規則。NULL 可以提升為任何其他類型。

這是優先清單的圖形化描述,以有向樹表示: 類型優先清單

最低公因數類型解析

一組類型中的最低公因數類型是由優先清單中所有類型元素可達到的最窄類型。

最低公因數類型解析用於

-- The coalesce function accepts any set of argument types as long as they share a least common type. 
-- The result type is the least common type of the arguments.
> SET spark.sql.ansi.enabled=true;
> SELECT typeof(coalesce(1Y, 1L, NULL));
BIGINT
> SELECT typeof(coalesce(1, DATE'2020-01-01'));
Error: Incompatible types [INT, DATE]

> SELECT typeof(coalesce(ARRAY(1Y), ARRAY(1L)));
ARRAY<BIGINT>
> SELECT typeof(coalesce(1, 1F));
DOUBLE
> SELECT typeof(coalesce(1L, 1F));
DOUBLE
> SELECT (typeof(coalesce(1BD, 1F)));
DOUBLE

> SELECT typeof(coalesce(1, '2147483648'))
BIGINT
> SELECT typeof(coalesce(1.0, '2147483648'))
DOUBLE
> SELECT typeof(coalesce(DATE'2021-01-01', '2022-01-01'))
DATE

SQL 函數

函數呼叫

在 ANSI 模式下(spark.sql.ansi.enabled=true),Spark SQL 的函數呼叫

> SET spark.sql.ansi.enabled=true;
-- implicitly cast Int to String type
> SELECT concat('total number: ', 1);
total number: 1
-- implicitly cast Timestamp to Date type
> select datediff(now(), current_date);
0

-- implicitly cast String to Double type
> SELECT ceil('0.1');
1
-- special rule: implicitly cast NULL to Date type
> SELECT year(null);
NULL

> CREATE TABLE t(s string);
-- Can't store String column as Numeric types.
> SELECT ceil(s) from t;
Error in query: cannot resolve 'CEIL(spark_catalog.default.t.s)' due to data type mismatch
-- Can't store String column as Date type.
> select year(s) from t;
Error in query: cannot resolve 'year(spark_catalog.default.t.s)' due to data type mismatch

行為不同的函數

某些 SQL 函數的行為在 ANSI 模式(spark.sql.ansi.enabled=true)下可能不同。

SQL 算子

在 ANSI 模式下(spark.sql.ansi.enabled=true),某些 SQL 算子的行為可能有所不同。

ANSI 模式的實用函數

當 ANSI 模式開啟時,它會對無效作業擲回例外狀況。您可以使用以下 SQL 函數來抑制此類例外狀況。

SQL 關鍵字(選用,預設停用)

spark.sql.ansi.enabledspark.sql.ansi.enforceReservedKeywords 皆為 true 時,Spark SQL 會使用 ANSI 模式剖析器。

使用 ANSI 模式剖析器時,Spark SQL 有兩種關鍵字

使用預設剖析器時,Spark SQL 有兩種關鍵字

預設情況下,spark.sql.ansi.enabledspark.sql.ansi.enforceReservedKeywords 皆為 false。

以下是 Spark SQL 中所有關鍵字的清單。

關鍵字 Spark SQL
ANSI 模式
Spark SQL
預設模式
SQL-2016
ADD 非保留 非保留 非保留
AFTER 非保留 非保留 非保留
ALL 保留 非保留 保留
ALTER 非保留 非保留 保留
ALWAYS 非保留 非保留 非保留
ANALYZE 非保留 非保留 非保留
AND 保留 非保留 保留
ANTI 非保留 嚴格非保留 非保留
ANY 保留 非保留 保留
ANY_VALUE 非保留 非保留 非保留
ARCHIVE 非保留 非保留 非保留
ARRAY 非保留 非保留 保留
AS 保留 非保留 保留
ASC 非保留 非保留 非保留
AT 非保留 非保留 保留
AUTHORIZATION 保留 非保留 保留
BETWEEN 非保留 非保留 保留
BIGINT 非保留 非保留 保留
BINARY 非保留 非保留 保留
布林值 非保留 非保留 保留
兩者 保留 非保留 保留
儲存區 非保留 非保留 非保留
儲存區 非保留 非保留 非保留
依據 非保留 非保留 保留
位元組 非保留 非保留 非保留
快取 非保留 非保留 非保留
串接 非保留 非保留 非保留
案例 保留 非保留 保留
轉換 保留 非保留 保留
目錄 非保留 非保留 非保留
目錄 非保留 非保留 非保留
變更 非保留 非保留 非保留
字元 非保留 非保留 保留
字元 非保留 非保留 保留
檢查 保留 非保留 保留
清除 非保留 非保留 非保留
叢集 非保留 非保留 非保留
叢集 非保留 非保留 非保留
程式碼產生 非保留 非保留 非保留
校對 保留 非保留 保留
集合 非保留 非保留 非保留
保留 非保留 保留
非保留 非保留 非保留
註解 非保留 非保留 非保留
提交 非保留 非保留 保留
壓縮 非保留 非保留 非保留
壓縮 非保留 非保留 非保留
運算 非保留 非保留 非保留
串接 非保留 非保留 非保留
約束 保留 非保留 保留
成本 非保留 非保留 非保留
建立 保留 非保留 保留
交叉 保留 嚴格非保留 保留
立方體 非保留 非保留 保留
目前 非保留 非保留 保留
目前日期 保留 非保留 保留
目前時間 保留 非保留 保留
目前時間戳記 保留 非保留 保留
目前使用者 保留 非保留 保留
資料 非保留 非保留 非保留
日期 非保留 非保留 保留
資料庫 非保留 非保留 非保留
資料庫 非保留 非保留 非保留
DATEADD 非保留 非保留 非保留
DATE_ADD 非保留 非保留 非保留
DATEDIFF 非保留 非保留 非保留
DATE_DIFF 非保留 非保留 非保留
非保留 非保留 非保留
非保留 非保留 非保留
DAYOFYEAR 非保留 非保留 非保留
DBPROPERTIES 非保留 非保留 非保留
DEC 非保留 非保留 保留
十進位 非保留 非保留 保留
預設 非保留 非保留 非保留
已定義 非保留 非保留 非保留
刪除 非保留 非保留 保留
分隔 非保留 非保留 非保留
降冪 非保留 非保留 非保留
描述 非保留 非保留 保留
DFS 非保留 非保留 非保留
目錄 非保留 非保留 非保留
目錄 非保留 非保留 非保留
相異 保留 非保留 保留
分配 非保留 非保留 非保留
DIV 非保留 非保留 非關鍵字
雙倍 非保留 非保留 保留
刪除 非保留 非保留 保留
否則 保留 非保留 保留
結束 保留 非保留 保留
跳脫 保留 非保留 保留
已跳脫 非保留 非保留 非保留
排除 保留 嚴格非保留 保留
交換 非保留 非保留 非保留
排除 非保留 非保留 非保留
存在 非保留 非保留 保留
說明 非保留 非保留 非保留
匯出 非保留 非保留 非保留
延伸 非保留 非保留 非保留
外部 非保留 非保留 保留
萃取 非保留 非保留 保留
保留 非保留 保留
擷取 保留 非保留 保留
欄位 非保留 非保留 非保留
篩選 保留 非保留 保留
檔案格式 非保留 非保留 非保留
第一個 非保留 非保留 非保留
浮點數 非保留 非保留 保留
後續 非保留 非保留 非保留
對於 保留 非保留 保留
外部 保留 非保留 保留
格式 非保留 非保留 非保留
已格式化 非保留 非保留 非保留
來自 保留 非保留 保留
完整 保留 嚴格非保留 保留
函數 非保留 非保留 保留
函數 非保留 非保留 非保留
已產生 非保留 非保留 非保留
全域 非保留 非保留 保留
授予 保留 非保留 保留
群組 保留 非保留 保留
群組 非保留 非保留 保留
具有 保留 非保留 保留
小時 非保留 非保留 非保留
小時 非保留 非保留 非保留
識別碼 非保留 非保留 非保留
如果 非保留 非保留 非關鍵字
忽略 非保留 非保留 非保留
匯入 非保留 非保留 非保留
保留 非保留 保留
包含 非保留 非保留 非保留
索引 非保留 非保留 非保留
索引 非保留 非保留 非保留
內部 保留 嚴格非保留 保留
INPATH 非保留 非保留 非保留
輸入格式 非保留 非保留 非保留
插入 非保留 非保留 保留
INT 非保留 非保留 保留
整數 非保留 非保留 保留
相交 保留 嚴格非保留 保留
區間 非保留 非保留 保留
進入 保留 非保留 保留
保留 非保留 保留
項目 非保留 非保留 非保留
加入 保留 嚴格非保留 保留
金鑰 非保留 非保留 非保留
最後一個 非保留 非保留 非保留
側向 保留 嚴格非保留 保留
延遲 非保留 非保留 非保留
前導 保留 非保留 保留
保留 嚴格非保留 保留
類似 非保留 非保留 保留
ILIKE 非保留 非保留 非保留
限制 非保留 非保留 非保留
非保留 非保留 非保留
清單 非保留 非保留 非保留
載入 非保留 非保留 非保留
本機 非保留 非保留 保留
位置 非保留 非保留 非保留
鎖定 非保留 非保留 非保留
鎖定 非保留 非保留 非保留
邏輯 非保留 非保留 非保留
長整數 非保留 非保留 非保留
巨集 非保留 非保留 非保留
對應 非保留 非保留 非保留
已比對 非保留 非保留 非保留
合併 非保留 非保留 非保留
微秒 非保留 非保留 非保留
微秒 非保留 非保留 非保留
毫秒 非保留 非保留 非保留
毫秒 非保留 非保留 非保留
分鐘 非保留 非保留 非保留
分鐘 非保留 非保留 非保留
非保留 嚴格非保留 非保留
非保留 非保留 非保留
非保留 非保留 非保留
MSCK 非保留 非保留 非保留
名稱 非保留 非保留 非保留
名稱空間 非保留 非保留 非保留
名稱空間 非保留 非保留 非保留
奈秒 非保留 非保留 非保留
奈秒 非保留 非保留 非保留
自然 保留 嚴格非保留 保留
非保留 非保留 保留
保留 非保留 保留
NULL 保留 非保留 保留
NULL 非保留 非保留 非保留
數字 非保留 非保留 非保留
非保留 非保留 保留
偏移 保留 非保留 保留
開啟 保留 嚴格非保留 保留
保留 非保留 保留
選項 非保留 非保留 非保留
選項 非保留 非保留 非保留
保留 非保留 保留
順序 保留 非保留 保留
輸出 非保留 非保留 保留
外部 保留 非保留 保留
輸出格式 非保留 非保留 非保留
超過 非保留 非保留 非保留
重疊 保留 非保留 保留
覆蓋 非保留 非保留 非保留
覆寫 非保留 非保留 非保留
分割 非保留 非保留 保留
已分割 非保留 非保留 非保留
分割 非保留 非保留 非保留
百分比 非保留 非保留 非保留
百分位數_連續 保留 非保留 非保留
百分位數_離散 保留 非保留 非保留
樞紐 非保留 非保留 非保留
放置 非保留 非保留 非保留
位置 非保留 非保留 保留
前置 非保留 非保留 非保留
主要 保留 非保留 保留
原則 非保留 非保留 非保留
屬性 非保留 非保留 非保留
清除 非保留 非保留 非保留
非保留 非保留 非保留
查詢 非保留 非保留 非保留
範圍 非保留 非保留 保留
實數 非保留 非保留 保留
記錄讀取器 非保留 非保留 非保留
記錄寫入器 非保留 非保留 非保留
復原 非保留 非保留 非保留
簡化 非保留 非保留 非保留
參考 保留 非保留 保留
重新整理 非保留 非保留 非保留
正規表示式 非保留 非保留 非關鍵字
重新命名 非保留 非保留 非保留
修復 非保留 非保留 非保留
可重複 非保留 非保留 非保留
取代 非保留 非保留 非保留
重設 非保留 非保留 非保留
尊重 非保留 非保留 非保留
限制 非保留 非保留 非保留
撤銷 非保留 非保留 保留
保留 嚴格非保留 保留
RLIKE 非保留 非保留 非保留
角色 非保留 非保留 非保留
角色 非保留 非保留 非保留
回滾 非保留 非保留 保留
彙總 非保留 非保留 保留
非保留 非保留 保留
非保留 非保留 保留
架構 非保留 非保留 非保留
架構 非保留 非保留 非保留
非保留 非保留 非保留
非保留 非保留 非保留
選取 保留 非保留 保留
非保留 嚴格非保留 非保留
分隔 非保留 非保留 非保留
SERDE 非保留 非保留 非保留
SERDE屬性 非保留 非保留 非保留
工作階段使用者 保留 非保留 保留
設定 非保留 非保留 保留
設定 非保留 非保留 非保留
短整數 非保留 非保留 非保留
顯示 非保留 非保留 非保留
傾斜 非保留 非保留 非保留
小整數 非保留 非保留 保留
某些 保留 非保留 保留
排序 非保留 非保留 非保留
已排序 非保留 非保留 非保留
來源 非保留 非保留 非保留
開始 非保留 非保留 保留
統計資料 非保留 非保留 非保留
已儲存 非保留 非保留 非保留
分層 非保留 非保留 非保留
字串 非保留 非保留 非保留
結構 非保留 非保留 非保留
子字串 非保留 非保留 非保留
子字串 非保留 非保留 非保留
同步 非保留 非保留 非保留
系統時間 非保留 非保留 非保留
系統版本 非保留 非保留 非保留
資料表 保留 非保留 保留
資料表 非保留 非保留 非保留
資料表範例 非保留 非保留 保留
目標 非保留 非保留 非保留
TBL屬性 非保留 非保留 非保留
暫存 非保留 非保留 非關鍵字
暫時 非保留 非保留 非保留
終止 非保留 非保留 非保留
然後 保留 非保留 保留
時間 保留 非保留 保留
時間戳記 非保留 非保留 非保留
時間戳記_LTZ 非保留 非保留 非保留
時間戳記_NTZ 非保留 非保留 非保留
時間戳記加總 非保留 非保留 非保留
時間戳記差異 非保留 非保留 非保留
TINYINT 非保留 非保留 非保留
TO 保留 非保留 保留
TOUCH 非保留 非保留 非保留
TRAILING 保留 非保留 保留
TRANSACTION 非保留 非保留 非保留
TRANSACTIONS 非保留 非保留 非保留
TRANSFORM 非保留 非保留 非保留
TRIM 非保留 非保留 非保留
TRUE 非保留 非保留 保留
TRUNCATE 非保留 非保留 保留
TRY_CAST 非保留 非保留 非保留
TYPE 非保留 非保留 非保留
UNARCHIVE 非保留 非保留 非保留
UNBOUNDED 非保留 非保留 非保留
UNCACHE 非保留 非保留 非保留
UNION 保留 嚴格非保留 保留
UNIQUE 保留 非保留 保留
UNKNOWN 保留 非保留 保留
UNLOCK 非保留 非保留 非保留
UNPIVOT 非保留 非保留 非保留
UNSET 非保留 非保留 非保留
UPDATE 非保留 非保留 保留
USE 非保留 非保留 非保留
USER 保留 非保留 保留
USING 保留 嚴格非保留 保留
VALUES 非保留 非保留 保留
VARCHAR 非保留 非保留 保留
VERSION 非保留 非保留 非保留
VIEW 非保留 非保留 非保留
VIEWS 非保留 非保留 非保留
VOID 非保留 非保留 非保留
WEEK 非保留 非保留 非保留
WEEKS 非保留 非保留 非保留
WHEN 保留 非保留 保留
WHERE 保留 非保留 保留
WINDOW 非保留 非保留 保留
WITH 保留 非保留 保留
WITHIN 保留 非保留 保留
X 非保留 非保留 非保留
YEAR 非保留 非保留 非保留
YEARS 非保留 非保留 非保留
ZONE 非保留 非保留 非保留