Athena 引擎版本 3 - Amazon Athena
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Athena 引擎版本 3

对于引擎版本 3,Athena 还引入了一种用于开源软件管理的持续集成方法,以提高与 TrinoPresto 项目并发的能力,从而让您能够更快地获得在 Athena 引擎中集成和优化的社区改进。

本次发布的 Athena 引擎版本 3 支持 Athena 引擎版本 2 的所有功能。本文档重点介绍了 Athena 引擎版本 2 和 Athena 引擎版本 3 之间的主要区别。有关更多信息,请参阅 Amazon 大数据博客文章升级到 Athena 引擎版本 3 以提高查询性能并访问更多分析功能

开始使用

首先,请创建一个使用 Athena 引擎版本 3 的新 Athena 工作组,或将现有工作组配置为使用版本 3。所有 Athena 工作组都可以在不中断查询提交能力的情况下,从引擎版本 2 升级到引擎版本 3。

有关更多信息,请参阅 更改 Athena 引擎版本

改进功能和新功能

列出的功能和更新包括 Athena 本身的改进以及开源 Trino 项目集成功能的改进。有关 SQL 查询运算符和函数的详尽列表,请参阅 Trino 文档

增加的功能

支持 Apache Spark 分桶算法

Athena 可以读取 Spark 哈希算法生成的桶。要指定数据最初是由 Spark 哈希算法编写的,请在 CREATE TABLE 语句的 TBLPROPERTIES 子句中输入 ('bucketing_format'='spark')。如果未指定此属性,则将使用 Hive 哈希算法。

CREATE EXTERNAL TABLE `spark_bucket_table`( `id` int, `name` string ) CLUSTERED BY (`name`) INTO 8 BUCKETS STORED AS PARQUET LOCATION 's3://path/to/bucketed/table/' TBLPROPERTIES ('bucketing_format'='spark')

已添加的函数

这一部分介绍的函数是 Athena 引擎版本 3 新引入的函数。

聚合函数

listagg(x, separator) – 返回由分隔符字符串分隔的级联输入值。

SELECT listagg(value, ',') WITHIN GROUP (ORDER BY value) csv_value FROM (VALUES 'a', 'c', 'b') t(value);

数组函数

contains_sequence(x, seq) – 如果数组 x 将所有数组序列作为顺序子集包含在内(所有值的连续顺序相同),则返回 true。

SELECT contains_sequence(ARRAY [1,2,3,4,5,6], ARRAY[1,2]);

二进制函数

murmur3(binary) – 计算二进制的 128 位 MurmurHash3 哈希值。

SELECT murmur3(from_base64('aaaaaa'));

转换函数

format_number(number) – 返回使用单位符号的格式化字符串。

SELECT format_number(123456); -- '123K'
SELECT format_number(1000000); -- '1M'

日期和时间函数

timezone_hour(timestamp) – 返回时区与时间戳偏移的小时数。

SELECT EXTRACT(TIMEZONE_HOUR FROM TIMESTAMP '2020-05-10 12:34:56 +08:35');

timezone_minute(timestamp) – 返回时区与时间戳偏移的分钟数。

SELECT EXTRACT(TIMEZONE_MINUTE FROM TIMESTAMP '2020-05-10 12:34:56 +08:35');

地理空间函数

to_encoded_polyline(Geometry) – 将线串或多点编码为折线。

SELECT to_encoded_polyline(ST_GeometryFromText( 'LINESTRING (-120.2 38.5, -120.95 40.7, -126.453 43.252)'));

from_encoded_polyline(varchar) – 将折线解码为线串。

SELECT ST_AsText(from_encoded_polyline('_p~iF~ps|U_ulLnnqC_mqNvxq`@'));

to_geojson_geometry(SphericalGeography) – 以 GeoJSON 格式返回指定的球面地理位置。

SELECT to_geojson_geometry(to_spherical_geography(ST_GeometryFromText( 'LINESTRING (0 0, 1 2, 3 4)')));

from_geojson_geometry(varchar) – 返回 GeoJSON 表示中的球面地理位置类型对象,去除非几何键/值。不支持 FeatureFeatureCollection

SELECT from_geojson_geometry(to_geojson_geometry(to_spherical_geography(ST_GeometryFromText( 'LINESTRING (0 0, 1 2, 3 4)'))));

geometry_nearest_points(Geometry, Geometry) – 返回每个几何体上彼此最近的点。如果任何一个几何体为空,则返回 NULL。否则,返回由几何体上任意两点间距离最小的两个 Point 对象组成的行。第一个点来自第一个 Geometry 参数,第二个点来自第二个 Geometry 参数。如果有多对点具有相同的最小距离,则任意选择一对。

SELECT geometry_nearest_points(ST_GeometryFromText( 'LINESTRING (50 100, 50 200)'), ST_GeometryFromText( 'LINESTRING (10 10, 20 20)'));

设置摘要函数

make_set_digest(x) – 将 x 的所有输入值合成一个 setdigest。

SELECT make_set_digest(value) FROM (VALUES 1, 2, 3) T(value);

字符串函数

soundex(char) – 返回一个包含字符语音表示的字符串。

SELECT name FROM nation WHERE SOUNDEX(name) = SOUNDEX('CHYNA'); -- CHINA

concat_ws(string0, string1, ..., stringN) – 返回以 string0 为分隔符的 string1, string2, ..., stringN 级联。如果 string0 为 null,则返回值为 null。参数中跳过分隔符后提供的任何空值。

SELECT concat_ws(',', 'def', 'pqr', 'mno');

窗口函数

GROUPS – 增加对基于组的窗口框架的支持。

SELECT array_agg(a) OVER( ORDER BY a ASC NULLS FIRST GROUPS BETWEEN 1 PRECEDING AND 2 FOLLOWING) FROM (VALUES 3, 3, 3, 2, 2, 1, null, null) T(a);

性能改进

Athena 引擎版本 3 中的性能改进包括以下方面。

  • 更快的 Amazon Glue 表元数据检索 – 涉及多个表的查询可缩短查询计划时间。

  • RIGHT JOIN 动态筛选 – 现在可为具有相等连接条件的右连接启用动态筛选,如下例所示。

    SELECT * FROM lineitem RIGHT JOIN tpch.tiny.supplier ON lineitem.suppkey = supplier.suppkey WHERE supplier.name = 'abc';
  • 大型预编译语句 – 将默认 HTTP 请求/响应标头的大小增加到 2 MB,以方便使用大型预编译语句。

  • approx_percentile() - approx_percentile 函数现在使用 tdigest 而不是 qdigest 从分布中检索近似分位数值。这样可以提高性能并降低内存使用量。请注意,进行此更改后,该函数返回的结果与 Athena 引擎版本 2 中的结果不同。有关更多信息,请参阅approx_percentile 函数将返回不同的结果

可靠性增强

Athena 引擎版本 3 改进了整体引擎内存使用和跟踪性能。降低了大型查询因节点崩溃而失败的可能性。

查询语法增强

INTERSECT ALL – 增加了对 INTERSECT ALL 的支持。

SELECT * FROM (VALUES 1, 2, 3, 4) INTERSECT ALL SELECT * FROM (VALUES 3, 4);

EXCEPT ALL – 增加了对 EXCEPT ALL 的支持。

SELECT * FROM (VALUES 1, 2, 3, 4) EXCEPT ALL SELECT * FROM (VALUES 3, 4);

RANGE PRECEDING – 在窗口函数中增加了对 RANGE PRECEDING 的支持。

SELECT sum(x) over (order by x range 1 preceding) FROM (values (1), (1), (2), (2)) t(x);

MATCH_RECOGNIZE – 增加了对行模式匹配的支持,如下例所示。

SELECT m.id AS row_id, m.match, m.val, m.label FROM (VALUES(1, 90),(2, 80),(3, 70),(4, 70)) t(id, value) MATCH_RECOGNIZE ( ORDER BY id MEASURES match_number() AS match, RUNNING LAST(value) AS val, classifier() AS label ALL ROWS PER MATCH AFTER MATCH SKIP PAST LAST ROW PATTERN (() | A) DEFINE A AS true ) AS m;

数据格式和数据类型增强

Athena 引擎版本 3 提供了以下数据格式和数据类型增强。

  • LZ4 和 ZSTD – 增加了对读取 LZ4 和 ZSTD 压缩格式的 Parquet 数据的支持。增加了对写入 ZSTD 压缩格式的 ORC 数据的支持。

  • 基于符号链接的表 – 增加了对在 Avro 文件上创建基于符号链接的表的支持。下面是一个示例。

    CREATE TABLE test_avro_symlink ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe' ... INPUTFORMAT 'org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat'
  • SphericalGeography – SphericalGeography 类型为地理坐标(有时也称大地测量坐标、纬度/经度或经度/纬度)上表示的空间要素提供原生支持。地理坐标是以角度单位(度)表示的球面坐标。

    to_spherical_geography 函数将从几何(平面)坐标返回地理(球面)坐标,如下例所示。

    SELECT to_spherical_geography(ST_GeometryFromText( 'LINESTRING (-40.2 28.9, -40.2 31.9, -37.2 31.9)'));

重大更改

从 Athena 引擎版本 2 迁移到 Athena 引擎版本 3 时,某些更改可能会影响表 Schema、语法或数据类型的用法。这一部分列出了相关的错误消息并提供了解决方法建议。

查询语法更改

IGNORE NULLS 不能与非值窗口函数一起使用

错误消息无法为 bool_or 函数指定空值处理子句。

原因:现在,IGNORE NULLS 只能与值函数 first_valuelast_valuenth_valueleadlag 一起使用。此更改是为了符合 ANSI SQL 规范。

建议的解决方案:从查询字符串的非值窗口函数中移除 IGNORE NULLS

CONCAT 函数必须有两个或以上的参数

错误消息INVALID_FUNCTION_ARGUMENT: There must be two or more concatenation arguments(INVALID_FUNCTION_ARGUMENT:必须有两个或更多串联参数)

原因:以前,CONCAT 字符串函数接受单个参数。在 Athena 引擎版本 3 中,CONCAT 函数至少需要两个参数。

建议的解决方法:将 CONCAT(str) 的出现次数更改为 CONCAT(str, '')

在 Athena 引擎版本 3 中,函数的参数不能超过 127 个。有关更多信息,请参阅函数调用的参数太多

approx_percentile 函数将返回不同的结果

approx_percentile 函数在 Athena 引擎版本 3 中返回的结果与在 Athena 引擎版本 2 中返回的结果不同。

错误消息:无。

原因approx_percentile 函数会受到版本变更的影响。

重要

由于 approx_percentile 函数的输出是近似值,并且近似值可能会因版本而异,因此在关键应用中不应依赖 approx_percentile 函数。

建议的解决方案:要近似 approx_percentile 的 Athena 引擎版本 2 行为,可以在 Athena 引擎版本 3 中使用一组不同的函数。例如,假设您在 Athena 引擎版本 2 中具有以下查询:

SELECT approx_percentile(somecol, 2E-1)

要在 Athena 引擎版本 3 中获得近似相同的输出,可以尝试使用 qdigest_aggvalue_at_quantile 函数,如以下示例所示。请注意,即使使用这种解决方法,也不能保证会出现相同的行为。

SELECT value_at_quantile(qdigest_agg(somecol, 1), 2E-1)

地理空间函数不支持 varbinary 输入

错误消息FUNCTION_NOT_FOUND for st_XXX(未找到 st_XXX 的函数)

原因:一些地理空间函数不再支持遗留的 VARBINARY 输入类型或与文本相关的函数签名。

建议的解决方法:使用地理空间函数将输入类型转换为支持的类型。错误消息中指示了支持的输入类型。

在 GROUP BY 子句中,嵌套列必须包含在双引号中

错误消息"column_name"."nested_column" 必须是聚合表达式或者出现在 GROUP BY 子句中

原因:Athena 引擎版本 3 要求 GROUP BY 子句中的嵌套列名包含在双引号中。例如,以下查询会产生错误,因为 GROUP BY 子句中 user.name 没有包含在双引号中。

SELECT "user"."name" FROM dataset GROUP BY user.name

建议的解决方案:在 GROUP BY 子句中将嵌套的列名称包含在双引号中,如以下示例所示。

SELECT "user"."name" FROM dataset GROUP BY "user"."name"

Log() 函数的参数顺序

在 Athena 引擎版本 2 中,log() 函数的参数顺序为 log(value, base)。在 Athena 引擎版本 3 中,为符合 SQL 标准,参数顺序已更改 log(base, value)

Minute() 函数不支持年和月间隔

错误消息Unexpected parameters (interval year to month) for function minute. [函数分钟的意外参数(年到月的间隔)。] Expected: minute(timestamp with time zone) , minute(time with time zone) , minute(timestamp) , minute(time) , minute(interval day to second). [minute 函数参数不符合预期(年和月间隔)。预期参数:minute(时间戳及时区), minute(时间及时区), minute(时间戳), minute(时间), minute(天到秒间隔)。]

原因:在 Athena 引擎版本 3 中,根据 ANSI SQL 规范,EXTRACT 的类型检查变得更加精确。

建议的解决方法:更新查询,确保类型与建议的函数签名相匹配。

ORDER BY 表达式必须显示在 SELECT 列表中。

错误消息For SELECT DISTINCT, ORDER BY expressions must appear in SELECT list(对于 SELECT DISTINCT,ORDER BY 表达式必须在 SELECT 列表中显示)

原因SELECT 子句中使用了不正确的表别名。

建议的解决方法:仔细检查 ORDER BY 表达式中的所有列,确认其在 SELECT DISTINCT 子句中的引用是否正确。

比较子查询返回的多列时查询失败

错误消息示例值表达式和子查询结果的类型必须相同:row(varchar, varchar) 与 row(row(varchar, varchar))

原因:由于 Athena 引擎版本 3 中的语法更新,当查询尝试比较子查询返回的多个值时,如果子查询 SELECT 语句将其列列表包含在括号内,就会出现此错误,如以下示例所示。

SELECT * FROM table1 WHERE (t1_col1, t1_col2) IN (SELECT (t2_col1, t2_col2) FROM table2)

解决方案:在 Athena 引擎版本 3 中,移除子查询 SELECT 语句中列列表两边的括号,如以下更新后的示例查询所示。

SELECT * FROM table1 WHERE (t1_col1, t1_col2) IN (SELECT t2_col1, t2_col2 FROM table2)

SKIP 是 DML 查询的保留字

SKIP 现在是 DML 查询的保留字,与 SELECT 一样。要在 DML 查询中将 SKIP 用作标识符,请用双引号将其括起来。

有关 Athena 中保留字的更多信息,请参阅 保留关键字

时间旅行已弃用 SYSTEM_TIME 和 SYSTEM_VERSION 子句

错误消息mismatched input 'SYSTEM_TIME'.(不匹配的输入“SYSTEM_TIME”。) Expecting: 'TIMESTAMP', 'VERSION'(预期输入:“TIMESTAMP”、“VERSION”)

原因:在 Athena 引擎版本 2 中,Iceberg 表使用 FOR SYSTEM_TIME AS OFFOR SYSTEM_VERSION AS OF 子句来表示时间戳和版本时间旅行。Athena 引擎版本 3 使用 FOR TIMESTAMP AS OFFOR VERSION AS OF 子句。

建议的解决方法:更新 SQL 查询以使用 TIMESTAMP AS OFVERSION AS OF 子句进行时间旅行操作,如下例所示。

按时间戳划分的时间旅行:

SELECT * FROM TABLE FOR TIMESTAMP AS OF (current_timestamp - interval '1' day)

按版本划分的时间旅行:

SELECT * FROM TABLE FOR VERSION AS OF 949530903748831860

数组构造函数的参数过多

错误消息TOO_MANY_ARGUMENTS:数组构造函数的参数过多。

原因:数组构造函数中的最大元素数现在设置为 254。

建议的解决方案:将元素分解为多个数组,每个数组的元素不超过 254 个,然后使用 CONCAT 函数连接这些数组,如以下示例所示。

CONCAT( ARRAY[x1,x2,x3...x254], ARRAY[y1,y2,y3...y254], ... )

不允许使用零长度分隔标识符

错误消息Zero–length delimited identifier not allowed.(不允许使用零长度分隔标识符。)

原因:查询使用空字符串作为列别名。

建议的解决方法:更新查询,为列使用非空别名。

数据处理更改

存储桶验证

错误消息HIVE_INVALID_BUCKET_FILES:Hive 表已损坏。

原因:表可能已损坏。为了确保分桶表的查询正确性,Athena 引擎版本 3 支持对分桶表进行额外验证,以确保查询正确并避免在运行时出现意外故障。

建议的解决方案:使用 Athena 引擎版本 3 重新创建表。

将结构体转换为 JSON 现在会返回字段名称

当您在 Athena 引擎版本 3 的 SELECT 查询中将 struct 转换为 JSON 时,这种转换现在会返回字段名称和值(例如 "useragent":null),而不仅仅是值(例如 null)。

Iceberg 表列级安全执行更改

错误消息Access Denied: Cannot select from columns(访问被拒绝:无法从列中选择)

原因:Iceberg 表是在 Athena 之外创建的,使用的是早于 0.13.0 的 Apache Iceberg SDK 版本。由于早期的 SDK 版本不填充 Amazon Glue 中的列,因此 Lake Formation 无法确定已获访问授权的列。

建议的解决方法:使用 Athena ALTER TABLE SET PROPERTIES 语句执行更新,或者使用最新的 Iceberg SDK 修复该表并更新 Amazon Glue 中的列信息。

List 数据类型中的空值现在会传播到 UDF

错误消息Null Pointer Exception(空指针异常)

原因:如果您使用 UDF 连接器并实施了用户定义的 Lambda 函数,则可能出现此问题。

Athena 引擎版本 2 会过滤掉传递给用户定义函数的 List 数据类型中的空值。在 Athena 引擎版本 3 中,空值现在将被保留并传递到 UDF。如果 UDF 尝试在不检查的情况下取消引用空元素,则可能会导致空指针异常。

例如,假设您在 DynamoDB 等原始数据来源中有数据 [null, 1, null, 2, 3, 4],则将传递给用户定义的 Lambda 函数的实际数据将会如下:

Athena 引擎版本 2[1,2,3,4]

Athena 引擎版本 3[null, 1, null, 2, 3, 4]

建议的解决方法:确保用户定义的 Lambda 函数会处理列表数据类型中的空元素。

字符数组中的子字符串不再包含填充空格

错误消息:No error is thrown, but the string returned no longer contains padded spaces.(不会触发错误,但返回的字符串不再包含填充空格。) 例如,substr(char[20],1,100) 现在返回长度为 20 而不是 100 的字符串。

建议的解决方法:无需执行任何操作。

不支持的十进制列类型强制

错误消息HIVE_CURSOR_ERROR:无法读取 Parquet 文件:s3://DOC-EXAMPLE-BUCKET/path/file_name.parquetParquet 列([column_name])的列类型(varchar)不受支持

原因:Athena 引擎版本 2 在尝试将数据类型从 varchar 强制转换为十进制时偶尔会成功(但经常失败)。由于 Athena 引擎版本 3 具有在尝试读取值之前检查类型是否兼容的类型验证,因此这种尝试强制操作现在总是会失败。

建议的解决方案:对于 Athena 引擎版本 2 和 Athena 引擎版本 3,在 Amazon Glue 中将架构修改为在 Parquet 文件的十进制列中使用数值数据类型,而不是 varchar。重新爬取数据,确保新列数据类型为十进制类型,或在 Athena 中手动重新创建表,然后使用语法 decimal(precision, scale) 为列指定 decimal 数据类型。

无法再将浮点型或双精度 NaN 值转换为 bigint

错误消息INVALID_CAST_ARGUMENT:无法将实数/双精度 NaN 转换为 bigint

原因:在 Athena 引擎版本 3 中,NaN 无法转换为 0 (bigint)。

建议的解决方案:确保在转换为 bigintfloatdouble 列中不存在 NaN 值。

uuid() 函数返回类型更改

以下问题会影响表和视图。

错误消息Hive 类型不受支持:uuid

原因:在 Athena 引擎版本 2 中,uuid() 函数返回一个字符串,但在 Athena 引擎版本 3 中,它返回一个随机生成的伪 UUID(类型 4)。由于 Athena 不支持 UUID 列数据类型,因此在 Athena 引擎版本 3 中,无法再在 CTAS 查询中直接使用 uuid() 函数来生成 UUID 列。

例如,以下 CREATE TABLE 语句可在 Athena 引擎版本 2 中成功完成,但在 Athena 引擎版本 3 中,将返回 NOT_SUPPORTED:Hive 类型不受支持:uuid

CREATE TABLE uuid_table AS SELECT uuid() AS myuuid

同样,以下 CREATE VIEW 语句可在 Athena 引擎版本 2 中成功完成,但在 Athena 引擎版本 3 中,将返回列 myuuid 的列类型无效:Hive 类型不受支持:uuid

CREATE VIEW uuid_view AS SELECT uuid() AS myuuid

在 Athena 引擎版本 3 中查询在 Athena 引擎版本 2 中如此创建的视图时,会出现如下所示的错误:

VIEW_IS_STALE:第 1:15 行:视图 'awsdatacatalog.mydatabase.uuid_view' 已过时或处于无效状态:从查询视图投影到位置 0 的 uuid 类型的列 [myuuid] 无法强制转换为视图定义中存储的 varchar 类型的列 [myuuid]

建议的解决方案:创建表或视图时,使用 cast() 函数将 uuid() 的输出转换为 varchar,如以下示例所示:

CREATE TABLE uuid_table AS SELECT CAST(uuid() AS VARCHAR) AS myuuid
CREATE VIEW uuid_view AS SELECT CAST(uuid() AS VARCHAR) AS myuuid

CHAR 和 VARCHAR 强制转换问题

如果您在 Athena 引擎版本 3 中遇到 varcharchar 强制转换问题,请使用本节中的解决方法。如果您无法使用这些解决方法,请联系 Amazon Web Services Support。

采用混合 CHAR 和 VARCHAR 输入时 CONCAT 函数失败

问题:在 Athena 引擎版本 2 中,以下查询将成功。

SELECT concat(CAST('abc' AS VARCHAR(20)), '12', CAST('a' AS CHAR(1)))

但是,在 Athena 引擎版本 3 上,相同的查询会失败,并显示以下内容:

错误消息FUNCTION_NOT_FOUND:第 1:8 行:函数 concat 包含非预期参数(varchar(20)、varchar(2)、char(1))。预期参数:concat(char(x), char(y))、concat(array(E), E) E、concat(E, array(E)) E、concat(array(E)) E、concat(varchar)、concat(varbinary)

建议的解决方案:使用 concat 函数时,转换为 charvarchar,但不要转换为两者的组合。

使用 CHAR 和 VARCHAR 输入时 SQL || 联接失败

在 Athena 引擎版本 3 中,双竖线 || 联接运算符需要 varchar 作为输入。输入不能是 varcharchar 类型的组合。

错误消息TYPE_NOT_FOUND:第 1:26 行:类型未知:char(65537)

原因:使用 || 联接 charvarchar 的查询可能会产生错误,如以下示例所示。

SELECT CAST('a' AS CHAR) || CAST('b' AS VARCHAR)

建议的解决方案:联接 varchar varchar,如以下示例所示。

SELECT CAST('a' AS VARCHAR) || CAST('b' AS VARCHAR)
CHAR 和 VARCHAR UNION 查询失败

错误消息NOT_SUPPORTED:Hive 类型不受支持:char(65536)。支持的 CHAR 类型:CHAR(<=255)

原因:尝试组合 charvarchar 的查询,如以下示例所示:

CREATE TABLE t1 (c1) AS SELECT CAST('a' as CHAR) as c1 UNION ALL SELECT CAST('b' AS VARCHAR) AS c1

建议的解决方案:在示例查询中,将 'a' 转换为 varchar 而不是 char

在 CHAR 或 VARCHAR 强制转换之后出现不必要的空格

在 Athena 引擎版本 3 中,如果 char(X)varchar 数据在形成数组或单列时强制为单一类型,则 char(65535) 为目标类型,并且每个字段都包含许多不需要的尾随空格。

原因:Athena 引擎版本 3 将 varcharchar(X) 强制转换为 char(65535),然后在数据后面填充空格。

建议的解决方案:将每个字段显式转换为 varchar

时间戳更改

将带时区的 Timestamp 转换为 varchar 时的行为更改

在 Athena 引擎版本 2 中,如果将带时区的 Timestamp 投影到 varchar,则导致某些时区文字发生变化(例如,会将 US/Eastern 更改为 America/New_York)。在 Athena 引擎版本 3 中不会出现此行为。

日期时间戳溢出引发错误

错误消息Millis overflow: XXX(Millis 溢出:XXX)

原因:由于 Athena 引擎版本 2 中不会检查 ISO 8601 日期是否溢出,因此部分日期会产生负时间戳。Athena 引擎版本 3 会检查此溢出并引发异常。

建议的解决方法:确保时间戳在范围内。

不支持带时间的政治时区

错误消息INVALID LITERAL(文字无效)

原因:查询类似于 SELECT TIME '13:21:32.424 America/Los_Angeles'

建议的解决方法:避免使用带 TIME 的政治时区。

Timestamp 列中的精度不匹配会导致序列化错误

错误消息SERIALIZATION_ERROR: Could not serialize column 'COLUMNZ' of type 'timestamp(3)' at position X:Y(序列化错误:无法序列化位置 X:Y 处类型为“timestamp(3)”的列“COLUMNZ”)

COLUMNZ 是导致问题的列的输出名称。数字 X:Y 表示该列在输出中的位置。

原因:Athena 引擎版本 3 会进行检查,以确保数据中时间戳的精度与表规范中为列数据类型指定的精度相同。目前,此精度始终为 3。如果数据的精度大于此值,则查询会失败并提示错误。

建议的解决方法:检查数据,确保您的时间戳精度为毫秒。

Iceberg 表的 UNLOAD 和 CTAS 查询中的时间戳精度错误

错误消息时间戳(6)的时间戳精度错误;配置的精度为毫秒

原因:Athena 引擎版本 3 会进行检查,以确保数据中时间戳的精度与表规范中为列数据类型指定的精度相同。目前,此精度始终为 3。如果数据的精度大于此值(例如,使用微秒而不是毫秒),则查询可能失败并显示注明的错误。

解决方案:要解决此问题,首先通过 CAST 将时间戳精度转换为 6,如创建 Iceberg 表的以下 CTAS 示例所示。请注意,必须将精度指定为 6 而不是 3,以免出现错误时间戳精度(3)不适用于 Iceberg

CREATE TABLE my_iceberg_ctas WITH (table_type = 'ICEBERG', location = 's3://DOC-EXAMPLE-BUCKET/table_ctas/', format = 'PARQUET') AS SELECT id, CAST(dt AS timestamp(6)) AS "dt" FROM my_iceberg

然后,由于 Athena 不支持时间戳 6,因此再次将该值转换为时间戳(例如,在视图中)。下面的示例基于 my_iceberg_ctas 表创建了一个视图。

CREATE OR REPLACE VIEW my_iceberg_ctas_view AS SELECT cast(dt AS timestamp) AS dt FROM my_iceberg_ctas

现在,将 ORC 文件中的 Long 类型读取为 Timestamp 或将 Timestamp 读取为 Long 类型时,都将导致错误“ORC 文件格式错误”

错误消息Error opening Hive split ‘FILE (SPLIT POSITION)’ Malformed ORC file.(打开 Hive split“FILE (SPLIT POSITION)”错误 ORC 文件时出错。) Cannot read SQL type timestamp from ORC stream .long_type of type LONG [打开 Hive 拆分文件“FILE (SPLIT POSITION)”时出错。ORC 文件格式不正确。无法从 LONG 类型的 .long_type ORC 流中读取 SQL 类型时间戳]

原因:Athena 引擎版本 3 现在拒绝在 Long 数据类型与 TimestampTimestampLong 之间进行隐式强制转换。以前,Long 值会被视作纪元毫秒,并隐式转换为时间戳。

建议的解决方法:使用 from_unixtime 函数显式转换列,或使用 from_unixtime 函数为未来的查询创建其他列。

不支持时间加年和月间隔

错误消息TYPE MISMATCH(类型不匹配)

原因:Athena 引擎版本 3 不支持时间加年和月间隔(例如,SELECT TIME '01:00' + INTERVAL '3' MONTH)。

int96 Parquet 格式的时间戳溢出

错误消息Invalid timeOfDayNanos(timeOfDayNanos 无效)

原因int96 Parquet 格式的时间戳溢出。

建议的解决方法:找出存在问题的特定文件。然后使用众所周知的最新 Parquet 库重新生成数据文件,或者使用 Athena CTAS。如果问题仍然存在,请联系 Athena 支持人员并告知我们数据文件是如何生成的。

将字符串转换为时间戳时,日期和时间值之间需要空间

错误消息INVALID_CAST_ARGUMENT:无法将值转换为时间戳

原因:Athena 引擎版本 3 不再接受连字符作为 cast 输入字符串中日期和时间值之间的有效分隔符。例如,以下查询在 Athena 引擎版本 2 中起作用,但在 Athena 引擎版本 3 中不起作用:

SELECT CAST('2021-06-06-23:38:46' AS timestamp) AS this_time

建议的解决方案:在 Athena 引擎版本 3 中,将日期和时间之间的连字符替换为空格,如以下示例所示。

SELECT CAST('2021-06-06 23:38:46' AS timestamp) AS this_time

to_iso8601() 时间戳返回值更改

错误消息:无

原因:在 Athena 引擎版本 2 中,即使传递给函数的值不包含时区,to_iso8601 函数也会返回包含时区的时间戳。在 Athena 引擎版本 3 中,仅当传递的参数包含时区时,to_iso8601 函数才会返回包含时区的时间戳。

例如,以下查询将当前日期传递给 to_iso8601 函数两次:第一次作为包含时区的时间戳,第二次作为时间戳。

SELECT TO_ISO8601(CAST(CURRENT_DATE AS TIMESTAMP WITH TIME ZONE)), TO_ISO8601(CAST(CURRENT_DATE AS TIMESTAMP))

以下输出显示了每个引擎中的查询结果。

Athena 引擎版本 2:

# _col0 _col1
1

2023-02-24T00:00:00.000Z

2023-02-24T00:00:00.000Z

Athena 引擎版本 3:

# _col0 _col1
1

2023-02-24T00:00:00.000Z

2023-02-24T00:00:00.000

建议的解决方案:要复制之前的行为,可以先将时间戳值传递给 with_timezone 函数,然后再将其传递给函数 to_iso8601,如以下示例所示:

SELECT to_iso8601(with_timezone(TIMESTAMP '2023-01-01 00:00:00.000', 'UTC'))

结果

# _col0
1 2023-01-01T00:00:00.000Z

at_timezone() 第一个参数必须指定日期

问题:在 Athena 引擎版本 3 中,at_timezone 函数不能将 time_with_timezone 值作为第一个参数。

原因:如果没有日期信息,就无法确定传递的值是夏令时还是标准时间。例如,at_timezone('12:00:00 UTC', 'America/Los_Angeles') 存在歧义,因为无法确定传递的值是太平洋夏令时间(PDT)还是太平洋标准时间(PST)。

限制

Athena 引擎版本 3 具有以下限制。

  • 查询性能 – 许多查询在 Athena 引擎版本 3 上运行会更快,但某些查询计划可能与 Athena 引擎版本 2 有所不同。因此,某些查询的延迟或成本也可能有差异。

  • Trino 和 Presto 连接器 – 不支持 TrinoPresto 连接器。使用 Amazon Athena 联合查询连接数据来源。有关更多信息,请参阅使用 Amazon Athena 联合查询

  • 容错执行 – 不支持 Trino 容错执行(Trino Tardigrade)。

  • 函数参数限制 - 函数的参数不能超过 127 个。有关更多信息,请参阅函数调用的参数太多

Athena 引擎版本 2 中引入了以下限制,以确保查询不会因资源限制而失败。用户无法配置这些限制。

  • 结果元素的数量 – 结果元素的数量 n 对于函数 min(col, n)max(col, n)min_by(col1, col2, n)max_by(col1, col2, n) 将限制在 10,000 或更少。

  • GROUPING SETS – 分组集中的最大切片数为 2048。

  • 最大文本文件行长度 – 文本文件的默认最大行长为 200MB。

  • 序列函数最大结果大小 – 序列函数的最大结果大小为 50000 个条目。例如,SELECT sequence(0,45000,1) 成功,但 SELECT sequence(0,55000,1) 会失败并显示错误消息 The result of the sequence function must not have more than 50000 entries(序列函数的结果不得超过 50000 个条目)。此限制适用于序列函数的所有输入类型,包括时间戳。