在Apache Drill中查询Decimal字段时出现异常求助
看起来你在使用Apache Drill查询Parquet文件中的Decimal字段时遇到了类型转换异常,我来帮你梳理几个可能的原因和对应的解决办法:
1. 先确认Decimal字段的元数据信息
首先建议你先查看目标字段SETTLE_AMOUNT_IMPACT的具体类型定义,Parquet中的Decimal类型会包含精度(precision)和刻度(scale)属性,Drill对不同精度的Decimal处理逻辑有所不同。你可以执行以下命令查看表元数据:
DESCRIBE dfs.`/iswdata/storage/products/superswitch/parquet/transactions`;
重点关注SETTLE_AMOUNT_IMPACT的类型,比如是否是DECIMAL(p,s)格式,其中p是总位数,s是小数位数。
2. 优化Decimal到数值类型的转换方式
你的原查询中直接将Decimal转成double,这种转换可能会因为Decimal精度过高(比如超过double的有效范围)或者数据值异常导致抛出异常。建议先将Decimal转成合适精度的Decimal类型,再进行计算,避免精度丢失或转换错误:
SELECT pan, count(*) as number_of_transactions, terminal_id, sum((CAST(SETTLE_AMOUNT_IMPACT AS DECIMAL(18,2)) * -1) / 100) as settle_amount_impact FROM dfs.`/iswdata/storage/products/superswitch/parquet/transactions` WHERE pan like '506126%' and terminal_id like '1%' and sink_node_name like 'SWTDB%' and source_node_name not like 'SWTDBLsrc' and tran_completed = 1 -- 补充你的剩余WHERE条件 GROUP BY pan, terminal_id;
这里用DECIMAL(18,2)作为中间转换类型,你可以根据实际字段的精度调整这个参数。
3. 检查Drill的Decimal转换配置
如果是因为Decimal转double时出现溢出导致的异常,你可以调整Drill的配置参数来改变溢出行为。在Drill的drill-override.conf中添加或修改以下配置:
drill.exec.functions.cast_decimal_to_double_overflow_behavior: "ROUND"
可选值有ERROR(默认,抛出异常)、ROUND(四舍五入)、TRUNCATE(截断)。修改后需要重启Drill生效。
4. 排查单条数据的转换问题
如果上述方法都无效,建议先简化查询,只测试单个字段的转换,排查是否是某条数据的异常值导致的问题:
SELECT pan, SETTLE_AMOUNT_IMPACT, CAST(SETTLE_AMOUNT_IMPACT AS DOUBLE) FROM dfs.`/iswdata/storage/products/superswitch/parquet/transactions` WHERE pan like '506126%' and terminal_id like '1%' and sink_node_name like 'SWTDB%' and source_node_name not like 'SWTDBLsrc' and tran_completed = 1 LIMIT 100;
如果这条查询抛出异常,说明结果集中存在无法转成double的Decimal值,你可以针对性地处理这些异常数据(比如过滤掉或者用TRY_CAST替代CAST来返回NULL而不是抛出异常):
sum((TRY_CAST(SETTLE_AMOUNT_IMPACT AS DOUBLE) * -1) / 100) as settle_amount_impact
内容的提问来源于stack exchange,提问作者Paul Plato

