Re: Explain Plan and Security

  • From: Andy Klock <andy@xxxxxxxxxxxxxxx>
  • To: mauro.pagano@xxxxxxxxx
  • Date: Thu, 14 Jun 2018 11:56:38 -0400

Agreed. It's kind of a cool idea, however, BINDs are checked after the
DBMS_SQL.PARSE call and is only evaluated after the call to DBMS_SQL.EXECUTE

https://docs.oracle.com/database/121/ARPLS/d_sql.htm#i996870

I ran a quick test to see what shows up in the cursor cache after setting
bind_variable, but not calling EXECUTE and as expected you don't get a plan
at all.


SQL> DECLARE
 cursor_name    INTEGER;
 rows_processed INTEGER;
BEGIN
  cursor_name := dbms_sql.open_cursor;
  dbms_sql.parse(cursor_name, 'select /* SQL_PARSE TEST */ * from
parse_test where n = 1', dbms_sql.NATIVE);
END;
/

PL/SQL procedure successfully completed.


SQL> DECLARE
 cursor_name    INTEGER;
 rows_processed INTEGER;
BEGIN
  cursor_name := dbms_sql.open_cursor;
  dbms_sql.parse(cursor_name, 'select /* SQL_PARSE TEST BIND */ * from
parse_test where n = :n', dbms_sql.NATIVE);
  dbms_sql.bind_variable(cursor_name, ':n', 2);
END;
/

PL/SQL procedure successfully completed.

SQL> DECLARE
 cursor_name    INTEGER;
 rows_processed INTEGER;
BEGIN
  cursor_name := dbms_sql.open_cursor;
  dbms_sql.parse(cursor_name, 'select /* SQL_PARSE TEST BIND 2 */ * from
parse_test where n = :n', dbms_sql.NATIVE);
  dbms_sql.bind_variable(cursor_name, ':n', 2);
  rows_processed := dbms_sql.execute(cursor_name);
  dbms_sql.close_cursor(cursor_name);
END;
/

PL/SQL procedure successfully completed.

SQL> @findsq SQL_PARSE

SQL_ID       PLAN_HASH_VALUE LENGTH(SQL_FULLTEXT) SUB_TEXT       EXECUTIONS
AVG_ELAPSED
------------- --------------- --------------------
-------------------------------------------------- ---------- -----------
4wbhzrjq0k7fd     464636435 57 select /* SQL_PARSE TEST */ * from
parse_test wher        0     .002671
8xbgz1hbjk0vz     0 63 select /* SQL_PARSE TEST BIND */ * from parse_test
     0     .000467
0bavj3vaszvw2     464636435 65 select /* SQL_PARSE TEST BIND 2 */ * from
parse_te        1      .00503

Final note, if you don't actually execute the SQL then you don't get all
that other Oracle runtime stuff like cardinality feedback or dynamic
sampling, etc which adds to even more headaches.

Andy K

On Thu, Jun 14, 2018 at 11:45 AM, Mauro Pagano <mauro.pagano@xxxxxxxxx>
wrote:

Lothar,

To add on Jonathan's "odd note", because of 9630032 (disabled by default)
you might see an even odder behavior (difference between describe vs exec).
Just saying that DBMS_SQL might translate in some headaches :-(

Cheers,
Mauro

On Thu, Jun 14, 2018 at 7:13 AM, Jonathan Lewis <
jonathan@xxxxxxxxxxxxxxxxxx> wrote:


As far as I know explain plan will produce a misleading plan only if:

a) the query uses bind variables - which can't be peeked and are assumed
to be character
or
b) the literals used in the explain plan are a bad choice compared to
what happens in production
   (which includes wrong type, wrong character set, wrong implicit date
format etc.)

Using dbms_sql won't (necessarily) be any better. If you supply a
statement with a bind variable in the text the call to dbms_parse will
assume that it's an unknown varchar - just as explain plan will.  This is
why you sometimes see systems with lots of statements parsed twice per
execute - the first time was a parse call the that used guesses for bind
types, the second was with information about the actual bind types.

(I have an odd note from 16 years ago that you don't get the plan on the
call to dbms_parse, but have to call dbms_describe_colums as well).

Regards
Jonathan Lewis

________________________________________
From: oracle-l-bounce@xxxxxxxxxxxxx <oracle-l-bounce@xxxxxxxxxxxxx> on
behalf of l.flatz@xxxxxxxxxx <l.flatz@xxxxxxxxxx>
Sent: 14 June 2018 13:36:46
To: oracle-l@xxxxxxxxxxxxx
Subject: Explain Plan and Security

Hi,

you might know Kerry┬┤s classic blog: http://kerryosborne.oracle-guy
.com/2008/10/explain-plan-lies/.
Normally my work around for explain plan issues is to run the query and
use dbms_xplan.display_cursor.
Now I am working in an environment where I must not run a query, but I
can do explain plan.
But still I think I can not tolerate explain plan weaknesses.
I think it should be possble to use DBMS_SQL to parse a statement and
receive a proper plan without actually running the statement.
Then use dbms_xplan.display_cursor.
Before I spent time, has anybody done it already?

Regards

Lothar

--
//www.freelists.org/webpage/oracle-l




Other related posts: