GaussDB(DWS)条件表达式函数返回错误结果集排查
(一)案例背景
客户使用greatest获取并返回参数列表中值最大的表达式的值,子查询中查询结果与将子查询的结果粘出来单独执行结果集不一致。
select greatest(1,2,100,-1,0,nvl(null,0)) --结果为2,select nvl(null,0)的结果为0
select greatest(1,2,100,-1,0,0) --结果为100
(二)问题排查
首先我们要了解greatest和nvl两个函数的用法
备注:参数expr1和expr2可以为任意类型,当NVL的两个参数不属于同类型时,看第二个参数是否可以向第一个参数进行隐式转换,如果可以则返回第一个参数类型。如果第二个参数不能向第一个参数进行隐式转换而第一个参数可以向第二个参数进行隐式转换,则返回第二个参数的类型。如果两个参数之间不存在隐式类型转换并且也不属于同一类型则报错。
客户使用的版本为dws820环境为mysql兼容模式,nvl(null,0)结果类型为unknown的类型即为text;
第一条greatest(1,2,100,-1,0,nvl(null,0))参数中存在int和text,即按字符排序2最大;(字符按位比较,第一位2最大,故此处结果为2)
第二条greatest(1,2,100,-1,0)参数均为int,输出按数值排序100最大;
拓展:
对于一些非条件表达式函数可以通过\df+ 函数名(这里用min来举例) 查找入参和出参的数据类型
或者先使用 select proname,proisstrict,provolatile,prorettype,proargtypes,prosrc,proshippable from pg_proc where proname = '函数名';
再使用select oid,typname from pg_type where oid =‘xxx’;(这里oid根据上述的prorettype,proargtypes来查询)
具体函数重要属性参考
GaussDB(DWS)函数下推属性介绍
https://bbs.huaweicloud.com/blogs/250351
(三)解决方案
从上述排查中可知将,改写第一条语句,使用nvl(null,0)::int替换nvl(null,0)使得greatest函数中所有数据类型均为int即可
SELECT greatest(1,2,100,-1,0,nvl(null,0)::int)
此时结果是,100符合客户预期结果。
- 点赞
- 收藏
- 关注作者
评论(0)