oracle-databaseinline-view

Oracle 12c Inline View Evaluation


A long time ago in a database far, far away a developer wrote a query in which he/she was reliant on the order in which predicates were written.

For example,

select x
  from a, b
 where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
   and a.char_column = b.numeric_column; 

(explain plan suggests a to_number conversion will be applied to a.char_column)

I think by chance more than design this "just works" (Oracle 11g). However, the order of the predicates isn't adhered to when running in Oracle 12c, so this query breaks with an invalid number exception. I'm aware that I could try to force 12c to evaluate the predicates in order by using the ORDERED_PREDICATES hint as follows

select /*+ ORDERED_PREDICATES +*/ x
  from a, b
 where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
   and a.char_column = b.numeric_column

.. Or cast one of the values using to_char for the comparison. The downside is that to_char could operate on say a million rows. I think the following inline view is probably a better solution. Am I guaranteed that the inline view will be evaluated first?

select x
  from b
  inner join (
              select only_rows_with_numeric_values as numeric_column
                from a 
               where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
             )  c
     on c.numeric_column = b.numeric_column;

Solution

  • About predicate order - look at https://jonathanlewis.wordpress.com/2015/06/02/predicate-order-2/

    You should rewrite your last query to next using rownum according to doc(https://docs.oracle.com/database/121/SQLRF/queries008.htm#SQLRF52358)

    select x
      from b
      inner join (
                  select only_rows_with_numeric_values as numeric_column,
                    rownum
                    from a 
                   where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
                 )  c
         on c.numeric_column = b.numeric_column;
    

    to suppress query unnesting or simply using hint /*+ no_unnest*/