目前,线上反馈一个问题:同一张表,使用Hive查询正常,但是使用Impala查询,返回的数据中,部分字段值为NULL。 我们使用impala执行了invalidate metadata xxx,排查了元数据不一致的问题,同时查看源文件,也排除了数据本身的问题。最终,通过在Impalad的web页面上查看该SQL的profile发现,其中存在如下的Errors:
通过查询相关的错误,我们发现官方对于这块有相应地解释: For text-based formats (text, RCFile, and SequenceFile tables), you can issue an ALTER TABLE … REPLACE COLUMNS statement to change the precision and scale of an existing DECIMAL column. As long as the values in the column fit within the new precision and scale, they are returned correctly by a query. Any values that do not fit within the new precision and scale are returned as NULL, and Impala reports the conversion error. Leading zeros do not count against the precision value, but trailing zeros after the decimal point do. 这段话主要的意思就是,如果通过alter table操作,修改了DECIMAL类型的precision和scale,如果实际值和新设置的DECIMAL不匹配的话,那么就会返回NULL。例如:如果数据是1.234,column定义是DECIMAL(4, 2),那么就会返回NULL。 我们可以通过如下的SQL进行简单的测试验证:
代码语言:javascript复制create table text_decimals (x string);
insert into text_decimals values ("1"), ("2"), ("99.99"), ("1.234"), ("000001"), ("1.000000000");
alter table text_decimals replace columns (x decimal(4,2));
select * from text_decimals;
如果用Impala执行最后一行,那么返回的记录中,第四行和第六行都是NULL;如果用Hive执行,则第四行和第六行分别是1.23和1.00。感兴趣的同事可以自行测试一下。 目前Impala还没有提供参数项配置,可以像Hive一样返回一个四舍五入的近似值,因此我们需要保证在定义的时候,不会出现这种情况。但是在实际测试的过程中我们发现,对于1.234,如果column定义是DECIMAL(4, 5),那么查询可以正常返回1.234,这意味着Impala是不允许精度丢失。值得注意的是,如果我们先执行set abort_on_error=1,再执行select查询,那么SQL会直接返回失败,而不是NULL,如下所示:
官方链接参考:https://docs.cloudera.com/documentation/enterprise/5-16-x/topics/impala_decimal.html#decimal