意外查询成功

zer*_*kms 12 sql oracle oracle10g

SELECT COUNT (*)
  FROM rps2_workflow
 WHERE     workflow_added > TO_DATE ('01.09.2011', 'dd.mm.yyyy')
       AND workflow_finished < TO_DATE ('wtf', 'dd.mm.yyyy')
       AND workflow_status IN (7, 12, 17)
       AND workflow_worker = 159
Run Code Online (Sandbox Code Playgroud)

我希望此查询失败,因为日期无效,但它返回0

此查询的计划显示,在8步无效条款处理:

8 TABLE ACCESS BY INDEX ROWID TABLE RPS2.RPS2_WORKFLOW Object Instance: 1  Filter Predicates: ("WORKFLOW_STATUS"=7 OR "WORKFLOW_STATUS"=12 OR "WORKFLOW_STATUS"=17) AND SYS_EXTRACT_UTC("WORKFLOW_FINISHED")<SYS_EXTRACT_UTC(TO_DATE('wtf','dd.mm.yyyy'))  Cost: 11  Bytes: 33  Cardinality: 1  CPU Cost: 8 M  IO Cost: 10  Time: 1                     
Run Code Online (Sandbox Code Playgroud)

如果我们评论出AND workflow_status IN (7, 12, 17)条件 - 那么我们预计会得到ORA-01858: a non-numeric character was found where a numeric was expected

如果我们注释掉AND workflow_finished < TO_DATE ('wtf', 'dd.mm.yyyy')那么我们得到符合条件的记录数量(> 0)

这怎么可能?

UPD:

提示/*+no_index(rps2_workflow) */不会改变任何东西(而在计划中我们看到执行了fullscan)

SELECT STATEMENT  ALL_ROWSCost: 254  Bytes: 31  Cardinality: 1  CPU Cost: 34 M  IO Cost: 248  Time: 4       
2 SORT AGGREGATE  Bytes: 31  Cardinality: 1     
    1 TABLE ACCESS FULL TABLE RPS2.RPS2_WORKFLOW Object Instance: 1  Filter Predicates: "WORKFLOW_WORKER"=159 AND ("WORKFLOW_STATUS"=7 OR "WORKFLOW_STATUS"=12 OR "WORKFLOW_STATUS"=17) AND SYS_EXTRACT_UTC("WORKFLOW_ADDED")>SYS_EXTRACT_UTC(TIMESTAMP' 2011-09-01 00:00:00') AND SYS_EXTRACT_UTC("WORKFLOW_FINISHED")<SYS_EXTRACT_UTC(TO_DATE('wtf','dd.mm.yyyy'))  Cost: 254  Bytes: 31  Cardinality: 1  CPU Cost: 34 M  IO Cost: 248  Time: 4  
Run Code Online (Sandbox Code Playgroud)

evi*_*tto 7

如果优化器决定它不需要评估函数,它就不会,所以函数永远不会抛出异常:

select 1 from dual where 1 = 1 OR to_date('asdasdasd','asdasdasdas') > sysdate ;

         1
----------
         1
Run Code Online (Sandbox Code Playgroud)

该函数仅在实际得到评估时引发异常:

SQL> select 1 from dual where 1 = 1 AND to_date('asdasd','asdas') > sysdate ;
select 1 from dual where 1 = 1 AND to_date('asdasd','asdas') > sysdate
                                                    *
ERROR at line 1:
ORA-01821: date format not recognized
Run Code Online (Sandbox Code Playgroud)

但是,如果解析器可以静态地判断查询是无效的 - 因为函数具有错误类型的参数或者查询具有无效类型,那么解析器将在优化器获得摆动之前引发异常:

SQL> select 1 from dual where 1 = 1 or to_date('asdasdasd',0) > sysdate ;
select 1 from dual where 1 = 1 or to_date('asdasdasd',0) > sysdate
                                                         *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected DATE got NUMBER


SQL> select 1 from dual where 1 = 1 or to_date('asdasdasd','asdasdasdas') > 42 ;
select 1 from dual where 1 = 1 or to_date('asdasdasd','asdasdasdas') > 42
                                                                        *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected DATE got NUMBER
Run Code Online (Sandbox Code Playgroud)


ale*_*sdm 3

它可能发现满足所有其他条件的每条记录都有一个NULL workflow_finished字段。

与 相比的任何内容NULL都是未知的,因此不需要评估另一个操作数。