PG 中表达式的计算顺序

表达式的计算顺序,没有什么意外的。

()* / + -   > <  ....  not  and  or   。。。。

这个是没有疑问的,那么还讲什么呢?


今天看到了这句了:
The order of evaluation of subexpressions is not defined. In particular, the inputs of an operator or function are not necessarily evaluated left-to-right or in any other fixed order.

在一个表达式里面的字表达式的计算顺序是没有定义的,可认为是乱序的,或者特定的开发人员的设定了。

第一个问题:

例如:

1)   ;  selelct  true  or  (3 >2) ;   

2)   ;  select (3>2) or true  ;

这连个sql是不定价的,根据短路原则, 1) sql中的3>2 是不会执行的, 2) sql中的 (3>2)是一定会执行的 ,
 
这是我们常规认为的从左到右的执行顺序下的思考。

pg里面是没有定义的。不一定是这个样子的,所以对于上面的两个sql 第二个要比第一个安全,即确保函数或者表达式(3 >2) 能够被计算一次。


第二个问题:

因为子表达式的计算顺序的不去定性,引发了第二个问题,

具有副作用的函数是不适合作为复杂表达式的一部分而存在的。

尤 其是认为在where  having 等字句里的计算是有顺序的时候,副作用函数的的使用将更具有危险性的 ,因为这些字句在开发执行计划的过程中,广泛的被重新设计,  在这些字句里的逻辑运算符(AND OR NOT ) ,可能被以任何逻辑运算所允许的方式从新组织和计算。
这个时候,具有副作用的函数,可能会在其中的某个部分发挥他的副作用,从而影响到最终的执行结果。

所以强制安排各个字表达式的执行顺序是非常必要的。


例如:

下面的sql

select  * from  t  where x >0 and y/x>1.5 ;  

不一定会确保 y/x 不会发生被零 除的错误。

正确的写法:

select * from  t  where case  when  x > 0  then  y/x >1.5  else  false  end case  ;

当然这个sql 中更适合写为   y  》1.5*x 。


切记   表达式的计算顺序是确定的,但是子表达式的计算顺序是么有定义的


请使用浏览器的分享功能分享到微信等