Databricks Runtime 中的 ANSI 合规性

适用于: 勾选“是” Databricks Runtime

本文介绍 Databricks Runtime 中的 ANSI 合规性。 有关 Databricks SQL 中的 ANSI 模式,请参阅 ANSI_MODE

Spark SQL 提供两个有助于符合 ANSI 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 规范:

- 如果在对整数或十进制数字段进行任何操作时发生溢出,则会引发运行时异常。
- 禁止在 SQL 分析器中使用 ANSI SQL 的保留关键字作为标识符。
spark.sql.storeAssignmentPolicy ANSI 向列中存储另一数据类型的值时,Spark 会执行类型转换。 类型强制转换规则有三种策略:ANSIlegacystrict

- ANSI:Spark 根据 ANSI SQL 执行类型强制转换。 实际上,此行为与 PostgreSQL 基本相同。 它不允许某些不合理的类型转换,例如将字符串转换为 int 或将 double 转换为布尔。
- legacy:Spark 允许类型强制转换,前提是它是有效的强制转换,这非常宽松。 例如,允许将字符串转换为 int 或将 double 转换为布尔。 它也是 Spark 2.x 中的唯一行为,并与 Hive 兼容。
- strict:Spark 不允许类型强制转换过程出现任何可能的精度受损或数据截断,例如,不允许将 double 转换为 int 或将 decimal 转换为 double。

以下各子部分显示了启用 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;
 error: integer overflow

-- `spark.sql.ansi.enabled=false`
> SELECT 2147483647 + 1;
  -2147483648

强制转换

根据标准中定义的非法强制转换模式,将 spark.sql.ansi.enabled 设置为 true 时,通过 CAST 语法进行显式强制转换(例如将字符串转换为整数)会引发运行时异常。

Spark ANSI 模式的 CAST 子句遵循 ISO/IEC 9075-2:2011 信息技术 — 数据库语言 - SQL — 第 2 部分:Foundation (SQL/Foundation) 中 6.13 节“强制转换规范”的语法规则,但它特别允许 ANSI 标准禁止的以下简单类型转换:

  • NumericType <=> BooleanType
  • StringType <=> BinaryType

下表提供了 CAST 表达式中源数据类型和目标数据类型的有效组合。 “Y”表示组合在语法上有效(没有限制),“N”表示组合无效。

SourceTarget 数值 字符串 Date 时间戳 时间间隔 布尔 二进制 数组 映射 结构
Numeric Y Y N N N Y N N N N
字符串 Y Y Y Y Y Y Y N N N
Date N Y Y Y N N N N N N
时间戳 N Y Y Y N N N N N N
时间间隔 N Y N N Y N N N N N
布尔 Y Y N N N Y N N N N
二进制 Y N N N N N Y N N N
数组 N N N N N N N Y N N
映射 N N N N N N N N Y N
结构 N N N N N N N N N Y
-- Examples of explicit casting

-- `spark.sql.ansi.enabled=true`
> SELECT CAST('a' AS INT);
  ERROR: [CAST_INVALID_INPUT] The value 'a' of the type "STRING" cannot be cast to "INT" because it is malformed.

> SELECT CAST(2147483648L AS INT);
  ERROR: [CAST_OVERFLOW] The value 2147483648L of the type "BIGINT" cannot be cast to "INT" due to an overflow.

> SELECT CAST(DATE'2020-01-01' AS INT)
  ERROR: [DATATYPE_MISMATCH.CAST_WITH_FUNC_SUGGESTION] Cannot resolve "CAST(DATE '2020-01-01' AS INT)" due to data type mismatch: cannot cast "DATE" to "INT".

-- `spark.sql.ansi.enabled=false` (This is a default behavior)
> SELECT cast('a' AS INT);
  null

> SELECT CAST(2147483648L AS INT);
  -2147483648

> SELECT CAST(DATE'2020-01-01' AS INT);
  null

存储分配

此设置 spark.sql.storeAssignmentPolicy 默认设置为 ANSI. 使用此设置时,当源值的数据类型与目标列类型不匹配时,Spark SQL 会自动将 ANSI CAST 子句添加到 INSERT 语句。 在此策略下插入表期间,Spark 会检查并拒绝无效强制转换,引发异常以确保数据质量。 这意味着,如果插入尝试由于类型不匹配而失败,则不会导致任何数据部分写入表中。

示例:

-- spark.sql.storeAssignmentPolicy=ANSI
> CREATE TABLE test(i INT);
> INSERT INTO test VALUES (2147483648L);
  ERROR: [CAST_OVERFLOW_IN_TABLE_INSERT] Fail to insert a value of "BIGINT" type into the "INT" type column `i` due to an overflow.

> INSERT INTO test VALUES ('a');
  ERROR: [CAST_INVALID_INPUT ERROR] The value 'a' of the type "STRING" cannot be cast to "INT" because it is malformed

这些示例显示 Spark SQL 会防止插入不兼容的数据,从而保持数据完整性。

spark.sql.storeAssignmentPolicy 设置为 LEGACY 时,Spark SQL 会回退到 Spark 2.x 之前普遍存在的行为。 在此模式下,它会应用旧的 CAST 操作,而不是使用 ANSI CAST。 在此策略下,在表插入期间无效强制转换会导致插入 NULL 值或错误值,而不是引发异常。 示例:

-- spark.sql.storeAssignmentPolicy=LEGACY
> CREATE TABLE test(i INT);
> INSERT INTO test VALUES (2147483648L);
> INSERT INTO test VALUES ('a');
> SELECT * FROM test;

-- Results
-- -2147483648 (incorrect value due to overflow)
-- null (cannot cast 'a' to INT)

类型强制

类型提升和优先级

spark.sql.ansi.enabled 设置为 true 时,Spark SQL 使用几个规则来管理解决数据类型之间冲突的方式。 此冲突解决方法的核心是类型优先级列表,该列表定义给定数据类型的值是否可以隐式提升为另一种数据类型。

数据类型 优先级列表(从低到高)
Byte Byte -> Short -> Int -> Long -> Decimal -> Float* -> Double
Short Short -> Int -> Long -> Decimal-> Float* -> Double
int Int -> Long -> Decimal -> Float* -> Double
Long Long -> Decimal -> Float* -> Double
小数 Decimal -> Float* -> Double
Float Float -> Double
Double Double
Date Date -> Timestamp
时间戳 时间戳
字符串 String
二进制 二进制
布尔 布尔
时间间隔 时间间隔
映射 Map**
数组 Array**
结构 Struct**
  • 对于最不常见的类型解析,会跳过 Float 以避免精度损失。

** 对于复杂类型,优先级规则以递归顺序应用于其组件元素。

特殊规则适用于字符串类型和非类型化 NULL。 NULL 可以提升为任何其他类型,而字符串可以提升为任何简单数据类型。

这是对有向树形式的优先级列表的图形描述:优先级规则的图形表示形式

最不常见的类型解析

一组类型中最不常见的类型是在由该类型组的所有元素构成的优先级列表中可达到的最低优先级的类型。

最不常见的类型解析用于:

  • 确定是否可以使用优先级较低类型的实参调用需要某类型的形参的函数。
  • 为需要多个形参的共享实参类型的函数(例如 coalesce、least 或 greatest)派生实参类型。
  • 派生运算符(如算术运算符或比较运算符)的操作数类型。
  • 派生表达式(如 case 表达式)的结果类型。
  • 派生数组和映射构造函数的元素、键或值类型。

如果最不常见的类型解析为 FLOAT,则应用特殊规则。 使用 float 类型值时,如果任何类型为 INT、BIGINT 或 DECIMAL,则推出的最不常见类型均为 DOUBLE,以避免可能的数字丢失。

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

-- The substring function expects arguments of type INT for the start and length parameters.
> SELECT substring('hello', 1Y, 2);
he

> SELECT substring('hello', '1', 2);
he

> SELECT substring('hello', 1L, 2);
Error: Argument 2 requires an INT type.

> SELECT substring('hello', str, 2) FROM VALUES(CAST('1' AS STRING)) AS T(str);
Error: Argument 2 requires an INT type.

SQL 函数

在 ANSI 模式 (spark.sql.ansi.enabled=true) 下,某些 SQL 函数的行为可能会有所不同。

  • size:在 ANSI 模式下,对于 NULL 输入,此函数将返回 NULL。
  • element_at:
    • 如果使用无效索引,则此函数会引发 ArrayIndexOutOfBoundsException
    • 如果映射中不存在键,则此函数会引发 NoSuchElementException
  • elt:如果使用无效索引,则此函数会引发 ArrayIndexOutOfBoundsException
  • make_date:如果结果日期无效,则此函数会失败并出现异常。
  • make_timestamp:如果结果时间戳无效,则此函数会失败并出现异常。
  • make_interval:如果结果间隔无效,则此函数会失败并出现异常。
  • next_day:如果输入不是有效的星期几,则此函数会引发 IllegalArgumentException
  • parse_url:如果输入字符串不是有效的 URL,则此函数会引发 IllegalArgumentException
  • to_date:如果无法分析输入字符串或模式字符串无效,则此函数会失败并出现异常。
  • to_timestamp:如果无法分析输入字符串或模式字符串无效,则此函数会失败并出现异常。
  • to_unix_timestamp:如果无法分析输入字符串或模式字符串无效,则此函数会失败并出现异常。
  • unix_timestamp:如果无法分析输入字符串或模式字符串无效,则此函数会失败并出现异常。

SQL 运算符

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

  • array_col[index]:如果使用无效索引,则此运算符会引发 ArrayIndexOutOfBoundsException
  • map_col[key]:如果映射中不存在键,则此运算符会引发 NoSuchElementException
  • CAST(string_col AS TIMESTAMP):如果无法分析输入字符串,则此运算符会失败并出现异常。
  • CAST(string_col AS DATE):如果无法分析输入字符串,则此运算符会失败并出现异常。

适用于 ANSI 模式的函数

ANSI 模式打开时,会针对无效操作引发异常。 可以使用以下 SQL 函数来阻止此类异常。

  • try_cast:与 CAST 相同,只不过它返回 NULL 结果而不是在出现运行时错误时引发异常。
  • try_add:与加法运算符 + 相同,只不过它返回 NULL 结果而不是在整型值溢出时引发异常。
  • try_divide:与除法运算符 / 相同,只不过它返回 NULL 结果而不是在除以 0 时引发异常。

SQL 关键字

如果 spark.sql.ansi.enabled 为 true,Spark SQL 将使用 ANSI 模式分析器。 在此模式下,Spark SQL 有两种关键字:

  • 保留关键字:保留的关键字,不能用作表、视图、列、函数、别名等的标识符。
  • 非保留关键字:仅在特定上下文中具有特殊含义的关键字,在其他上下文中可用作标识符。 例如,EXPLAIN SELECT ... 是一个命令,但 EXPLAIN 在其他位置可用作标识符。

禁用 ANSI 模式时,Spark SQL 有两种关键字:

  • 非保留关键字:与 ANSI 模式处于启用状态下的定义相同。
  • 严格非保留关键字:非保留关键字的 strict 版本,无法用作表别名。

默认情况下,spark.sql.ansi.enabled 为 false。

下面是 Spark SQL 中所有关键字的列表。

关键字 Spark SQL ANSI 模式 Spark SQL 默认模式 SQL-2016
ADD non-reserved non-reserved non-reserved
AFTER non-reserved non-reserved non-reserved
ALL reserved non-reserved reserved
ALTER non-reserved non-reserved reserved
ALWAYS non-reserved non-reserved non-reserved
分析 non-reserved non-reserved non-reserved
AND reserved non-reserved reserved
ANTI non-reserved strict-non-reserved non-reserved
ANY reserved non-reserved reserved
存档 non-reserved non-reserved non-reserved
ARRAY non-reserved non-reserved reserved
AS reserved non-reserved reserved
ASC non-reserved non-reserved non-reserved
AT non-reserved non-reserved reserved
AUTHORIZATION reserved non-reserved reserved
BETWEEN non-reserved non-reserved reserved
BOTH reserved non-reserved reserved
BUCKET non-reserved non-reserved non-reserved
BUCKETS non-reserved non-reserved non-reserved
BY non-reserved non-reserved reserved
CACHE non-reserved non-reserved non-reserved
CASCADE non-reserved non-reserved non-reserved
CASE reserved non-reserved reserved
CAST reserved non-reserved reserved
更改 non-reserved non-reserved non-reserved
CHECK reserved non-reserved reserved
CLEAR non-reserved non-reserved non-reserved
CLUSTER non-reserved non-reserved non-reserved
CLUSTERED non-reserved non-reserved non-reserved
CODEGEN non-reserved non-reserved non-reserved
COLLATE reserved non-reserved reserved
COLLECTION non-reserved non-reserved non-reserved
COLUMN reserved non-reserved reserved
COLUMNS non-reserved non-reserved non-reserved
COMMENT non-reserved non-reserved non-reserved
COMMIT non-reserved non-reserved reserved
COMPACT non-reserved non-reserved non-reserved
COMPACTIONS non-reserved non-reserved non-reserved
COMPUTE non-reserved non-reserved non-reserved
CONCATENATE non-reserved non-reserved non-reserved
CONSTRAINT reserved non-reserved reserved
COST non-reserved non-reserved non-reserved
CREATE reserved non-reserved reserved
CROSS reserved strict-non-reserved reserved
CUBE non-reserved non-reserved reserved
CURRENT non-reserved non-reserved reserved
CURRENT_DATE reserved non-reserved reserved
CURRENT_TIME reserved non-reserved reserved
CURRENT_TIMESTAMP reserved non-reserved reserved
CURRENT_USER reserved non-reserved reserved
DATA non-reserved non-reserved non-reserved
DATABASE non-reserved non-reserved non-reserved
数据库 non-reserved non-reserved non-reserved
DAY non-reserved non-reserved non-reserved
DBPROPERTIES non-reserved non-reserved non-reserved
DEFINED non-reserved non-reserved non-reserved
删除 non-reserved non-reserved reserved
DELIMITED non-reserved non-reserved non-reserved
DESC non-reserved non-reserved non-reserved
DESCRIBE non-reserved non-reserved reserved
DFS non-reserved non-reserved non-reserved
DIRECTORIES non-reserved non-reserved non-reserved
目录 non-reserved non-reserved non-reserved
DISTINCT reserved non-reserved reserved
DISTRIBUTE non-reserved non-reserved non-reserved
DIV non-reserved non-reserved 非关键字
DROP non-reserved non-reserved reserved
ELSE reserved non-reserved reserved
End reserved non-reserved reserved
ESCAPE reserved non-reserved reserved
ESCAPED non-reserved non-reserved non-reserved
EXCEPT reserved strict-non-reserved reserved
EXCHANGE non-reserved non-reserved non-reserved
EXISTS non-reserved non-reserved reserved
EXPLAIN non-reserved non-reserved non-reserved
EXPORT non-reserved non-reserved non-reserved
EXTENDED non-reserved non-reserved non-reserved
EXTERNAL non-reserved non-reserved reserved
EXTRACT non-reserved non-reserved reserved
FALSE reserved non-reserved reserved
FETCH reserved non-reserved reserved
字段 non-reserved non-reserved non-reserved
FILTER reserved non-reserved reserved
FILEFORMAT non-reserved non-reserved non-reserved
FIRST non-reserved non-reserved non-reserved
FN non-reserved non-reserved non-reserved
FOLLOWING non-reserved non-reserved non-reserved
FOR reserved non-reserved reserved
FOREIGN reserved non-reserved reserved
FORMAT non-reserved non-reserved non-reserved
FORMATTED non-reserved non-reserved non-reserved
FROM reserved non-reserved reserved
FULL reserved strict-non-reserved reserved
FUNCTION non-reserved non-reserved reserved
FUNCTIONS non-reserved non-reserved non-reserved
GENERATED non-reserved non-reserved non-reserved
GLOBAL non-reserved non-reserved reserved
GRANT reserved non-reserved reserved
GRANTS non-reserved non-reserved non-reserved
GROUP reserved non-reserved reserved
GROUPING non-reserved non-reserved reserved
HAVING reserved non-reserved reserved
HOUR non-reserved non-reserved non-reserved
IF non-reserved non-reserved 非关键字
IGNORE non-reserved non-reserved non-reserved
IMPORT non-reserved non-reserved non-reserved
IN reserved non-reserved reserved
INDEX non-reserved non-reserved non-reserved
索引 non-reserved non-reserved non-reserved
INNER reserved strict-non-reserved reserved
INPATH non-reserved non-reserved non-reserved
INPUTFORMAT non-reserved non-reserved non-reserved
INSERT non-reserved non-reserved reserved
INTERSECT reserved strict-non-reserved reserved
INTERVAL non-reserved non-reserved reserved
INTO reserved non-reserved reserved
IS reserved non-reserved reserved
non-reserved non-reserved non-reserved
JOIN reserved strict-non-reserved reserved
KEY non-reserved non-reserved non-reserved
密钥 non-reserved non-reserved non-reserved
LAST non-reserved non-reserved non-reserved
LATERAL reserved strict-non-reserved reserved
LAZY non-reserved non-reserved non-reserved
LEADING reserved non-reserved reserved
LEFT reserved strict-non-reserved reserved
LIKE non-reserved non-reserved reserved
ILIKE non-reserved non-reserved non-reserved
LIMIT non-reserved non-reserved non-reserved
LINES non-reserved non-reserved non-reserved
列表 non-reserved non-reserved non-reserved
LOAD non-reserved non-reserved non-reserved
LOCAL non-reserved non-reserved reserved
LOCATION non-reserved non-reserved non-reserved
LOCK non-reserved non-reserved non-reserved
LOCKS non-reserved non-reserved non-reserved
LOGICAL non-reserved non-reserved non-reserved
MACRO non-reserved non-reserved non-reserved
MAP non-reserved non-reserved non-reserved
MATCHED non-reserved non-reserved non-reserved
MERGE non-reserved non-reserved non-reserved
MINUTE non-reserved non-reserved non-reserved
MINUS non-reserved strict-non-reserved non-reserved
MONTH non-reserved non-reserved non-reserved
MSCK non-reserved non-reserved non-reserved
命名空间 non-reserved non-reserved non-reserved
命名空间 non-reserved non-reserved non-reserved
NATURAL reserved strict-non-reserved reserved
non-reserved non-reserved reserved
NOT reserved non-reserved reserved
Null reserved non-reserved reserved
NULLS non-reserved non-reserved non-reserved
OF non-reserved non-reserved reserved
ON reserved strict-non-reserved reserved
ONLY reserved non-reserved reserved
OPTION non-reserved non-reserved non-reserved
OPTIONS non-reserved non-reserved non-reserved
reserved non-reserved reserved
ORDER reserved non-reserved reserved
OUT non-reserved non-reserved reserved
OUTER reserved non-reserved reserved
OUTPUTFORMAT non-reserved non-reserved non-reserved
OVER non-reserved non-reserved non-reserved
OVERLAPS reserved non-reserved reserved
OVERLAY non-reserved non-reserved non-reserved
OVERWRITE non-reserved non-reserved non-reserved
PARTITION non-reserved non-reserved reserved
PARTITIONED non-reserved non-reserved non-reserved
分区 non-reserved non-reserved non-reserved
PERCENT non-reserved non-reserved non-reserved
PIVOT non-reserved non-reserved non-reserved
PLACING non-reserved non-reserved non-reserved
POSITION non-reserved non-reserved reserved
PRECEDING non-reserved non-reserved non-reserved
PRIMARY reserved non-reserved reserved
PRINCIPALS non-reserved non-reserved non-reserved
PROPERTIES non-reserved non-reserved non-reserved
PURGE non-reserved non-reserved non-reserved
QUALIFY reserved non-reserved reserved
QUERY non-reserved non-reserved non-reserved
RANGE non-reserved non-reserved reserved
收件人 non-reserved non-reserved non-reserved
收件人 non-reserved non-reserved non-reserved
RECORDREADER non-reserved non-reserved non-reserved
RECORDWRITER non-reserved non-reserved non-reserved
RECOVER non-reserved non-reserved non-reserved
REDUCE non-reserved non-reserved non-reserved
REFERENCES reserved non-reserved reserved
REFRESH non-reserved non-reserved non-reserved
REGEXP non-reserved non-reserved 非关键字
REMOVE non-reserved non-reserved non-reserved
RENAME non-reserved non-reserved non-reserved
REPAIR non-reserved non-reserved non-reserved
REPLACE non-reserved non-reserved non-reserved
RESET non-reserved non-reserved non-reserved
RESPECT non-reserved non-reserved non-reserved
RESTRICT non-reserved non-reserved non-reserved
REVOKE non-reserved non-reserved reserved
RIGHT reserved strict-non-reserved reserved
RLIKE non-reserved non-reserved non-reserved
ROLE non-reserved non-reserved non-reserved
ROLES non-reserved non-reserved non-reserved
ROLLBACK non-reserved non-reserved reserved
ROLLUP non-reserved non-reserved reserved
ROW non-reserved non-reserved reserved
ROWS non-reserved non-reserved reserved
SCHEMA non-reserved non-reserved non-reserved
SCHEMAS non-reserved non-reserved 非关键字
SECOND non-reserved non-reserved non-reserved
SELECT reserved non-reserved reserved
SEMI non-reserved strict-non-reserved non-reserved
SEPARATED non-reserved non-reserved non-reserved
SERDE non-reserved non-reserved non-reserved
SERDEPROPERTIES non-reserved non-reserved non-reserved
SESSION_USER reserved non-reserved reserved
SET non-reserved non-reserved reserved
SETS non-reserved non-reserved non-reserved
共享 non-reserved non-reserved non-reserved
SHARES non-reserved non-reserved non-reserved
SHOW non-reserved non-reserved non-reserved
SKEWED non-reserved non-reserved non-reserved
SOME reserved non-reserved reserved
SORT non-reserved non-reserved non-reserved
SORTED non-reserved non-reserved non-reserved
START non-reserved non-reserved reserved
STATISTICS non-reserved non-reserved non-reserved
STORED non-reserved non-reserved non-reserved
STRATIFY non-reserved non-reserved non-reserved
STRUCT non-reserved non-reserved non-reserved
SUBSTR non-reserved non-reserved non-reserved
SUBSTRING non-reserved non-reserved non-reserved
同步 non-reserved non-reserved non-reserved
TABLE reserved non-reserved reserved
TABLES non-reserved non-reserved non-reserved
TABLESAMPLE non-reserved non-reserved reserved
TBLPROPERTIES non-reserved non-reserved non-reserved
TEMP non-reserved non-reserved 非关键字
TEMPORARY non-reserved non-reserved non-reserved
已终止 non-reserved non-reserved non-reserved
THEN reserved non-reserved reserved
TIME reserved non-reserved reserved
TO reserved non-reserved reserved
TOUCH non-reserved non-reserved non-reserved
TRAILING reserved non-reserved reserved
TRANSACTION non-reserved non-reserved non-reserved
TRANSACTIONS non-reserved non-reserved non-reserved
TRANSFORM non-reserved non-reserved non-reserved
TRIM non-reserved non-reserved non-reserved
TRUE non-reserved non-reserved reserved
TRUNCATE non-reserved non-reserved reserved
TRY_CAST non-reserved non-reserved non-reserved
TYPE non-reserved non-reserved non-reserved
UNARCHIVE non-reserved non-reserved non-reserved
UNBOUNDED non-reserved non-reserved non-reserved
UNCACHE non-reserved non-reserved non-reserved
UNION reserved strict-non-reserved reserved
UNIQUE reserved non-reserved reserved
未知 reserved non-reserved reserved
UNLOCK non-reserved non-reserved non-reserved
UNSET non-reserved non-reserved non-reserved
UPDATE non-reserved non-reserved reserved
USE non-reserved non-reserved non-reserved
USER reserved non-reserved reserved
USING reserved strict-non-reserved reserved
VALUES non-reserved non-reserved reserved
VIEW non-reserved non-reserved non-reserved
VIEWS non-reserved non-reserved non-reserved
WHEN reserved non-reserved reserved
WHERE reserved non-reserved reserved
WINDOW non-reserved non-reserved reserved
WITH reserved non-reserved reserved
YEAR non-reserved non-reserved non-reserved
ZONE non-reserved non-reserved non-reserved