Re: Operator and condition precedence

From: Tanel Poder <tanel_at_poderc.com>
Date: Thu, 10 Sep 2009 03:31:53 +0800
Message-ID: <4602f23c0909091231t144f1211n84068a6d05a09963_at_mail.gmail.com>



Oh, it looks like IS NULL (or = '') stuff is checked differently than when comparing to a real value.

Execution plan's different (10.2.0.4):

*First checking for NULL (as empty string '' is NULL in oracle):

*select * from dual where dummy = '' and to_number(dummy) > 0



| Id | Operation | Name | E-Rows |
|*  1 |  FILTER            |      |        |
|*  2 |   TABLE ACCESS FULL| DUAL |      1 |
--------------------------------------------

Predicate Information (identified by operation id):


  • 1 - filter(NULL IS NOT NULL)
  • 2 - filter(TO_NUMBER("DUMMY")>0)

*In above case we never get to predicate 2 - the to_number() > 0 check as
the parent rowsource filter always evaluates to false.

When comparing to a real value, the query fails:

*

SQL> select * from dual where dummy = 'blah' and to_number(dummy) > 0; select * from dual where dummy = 'blah' and to_number(dummy) > 0

                                            *
ERROR at line 1:
ORA-01722: invalid number

| Id | Operation | Name | E-Rows |

|* 1 | TABLE ACCESS FULL| DUAL | 1 |

Predicate Information (identified by operation id):


   1 - filter((*TO_NUMBER("DUMMY")>0* AND "DUMMY"='blah'))

*So in above case the filter predicate checks are done in "wrong order",
first the TO_NUMBER check for some reason.

I can work around this with ordered predicates hint and the query works again:

*SQL> select /*+ ordered_predicates */ * from dual where dummy = 'blah' and
to_number(dummy) > 0;

no rows selected



| Id | Operation | Name | E-Rows |

|* 1 | TABLE ACCESS FULL| DUAL | 1 |

Predicate Information (identified by operation id):


   1 - filter(("DUMMY"='blah' AND TO_NUMBER("DUMMY")>0))
*

Predicate order above is different from previous case...

*--

Tanel Poder
http://blog.tanelpoder.com

*
*

On Thu, Sep 10, 2009 at 3:17 AM, Martin Berger <martin.a.berger_at_gmail.com>wrote:

> thank you Tanel for this additiional info: '' <-> NULL (and it's shourcut)
> so one more test:
>
> select * from dual where 'xyz'>' ' and to_number('abc') > 0
>                                                  *
> ERROR at line 1:
> ORA-01722: invalid number
>
> select * from dual where to_number('abc') > 0 and 'xyz'>' '
>                                    *
> ERROR at line 1:
> ORA-01722: invalid number
>
> select * from dual where dummy > ' ' and to_number(dummy) > 0
>                                          *
> ERROR at line 1:
> ORA-01722: invalid number
>
> select * from dual where to_number(dummy) > 0 and dummy>' '
>                          *
> ERROR at line 1:
> ORA-01722: invalid number
>
> So with '<space>' instead of '' (equals NULL), all these 4 statements
> fails, without any difference in order of if it's based on a constant or
> column.
>
> funny to play :-) (no, I will not check 10053 trace, it's to late for me
> today)
>  Martin
>
>
>
>

--
http://www.freelists.org/webpage/oracle-l
Received on Wed Sep 09 2009 - 14:31:53 CDT

Original text of this message