<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	>
<channel>
	<title>
	Comments on: optimizer_secure_view_merging and plsql_declarations	</title>
	<atom:link href="https://www.salvis.com/blog/2022/10/30/optimizer_secure_view_merging-and-plsql_declarations/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.salvis.com/blog/2022/10/30/optimizer_secure_view_merging-and-plsql_declarations/</link>
	<description>Database-centric development</description>
	<lastBuildDate>Wed, 08 Nov 2023 17:04:24 +0000</lastBuildDate>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/>
<atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/>
<atom:link rel="hub" href="https://websubhub.com/hub"/>
<atom:link rel="self" href="https://www.salvis.com/blog/2022/10/30/optimizer_secure_view_merging-and-plsql_declarations/feed/"/>
	<item>
		<title>
		By: Philipp Salvisberg		</title>
		<link>https://www.salvis.com/blog/2022/10/30/optimizer_secure_view_merging-and-plsql_declarations/#comment-105319</link>

		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Thu, 17 Nov 2022 19:41:59 +0000</pubDate>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=11897#comment-105319</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;https://www.salvis.com/blog/2022/10/30/optimizer_secure_view_merging-and-plsql_declarations/#comment-105315&quot;&gt;IUDITH MENTZEL&lt;/a&gt;.

Hi Iudith,
&lt;blockquote&gt;There is a note in this post, stating the following:

&quot;Note: while your Handler can slow down the Select operation, it cannot abort it nor can it change the query being executed. Even when your Handler raises an exception, the query will proceed unhamperedly and return its results.&quot;

So, as I understand from here, raising an exception in an FGA policy handler, as in your proposed workaround, will NOT prevent
the SELECT from executing.

I would be grateful if you could confirm or infirm the correctness of the note above&lt;/blockquote&gt;
Well, I can confirm that this is not correct.

Firstly, &lt;a href=&quot;https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/using-transparent-sensitive-data-protection.html#GUID-F852F1BE-D835-426C-9779-89139B066EEE&quot; rel=&quot;nofollow ugc&quot;&gt;the documentation&lt;/a&gt; clearly states the following:
&lt;blockquote&gt;Function name of the event handler. Include the package name if necessary. This function is invoked only after the first row that matches the audit condition in the query is processed. If the procedure fails with an exception, then the user’s SQL statement fails as well.&lt;/blockquote&gt;
Secondly, and more importantly, I have tested it. I ran the following query as user `u2` after creating the policy as described above:
&lt;pre class=&quot;lang:plsql decode:true &quot; title=&quot;Test failing FGA handler&quot;&gt;set serveroutput on size unlimited
with
   function spy(
      in_id  in number,
      in_pad in varchar2
   ) return number as
   begin
      dbms_output.put_line(&#039;id=&#039;
         &#124;&#124; in_id
         &#124;&#124; &#039; pad=&#039;
         &#124;&#124; in_pad);
      return 1;
   end;
select id, pad
  from u1.v
 where id between 1 and 5
   and spy(id, pad) = 1
/

Error starting at line : 2 in command -
with
   function spy(
      in_id  in number,
      in_pad in varchar2
   ) return number as
   begin
      dbms_output.put_line(&#039;id=&#039;
         &#124;&#124; in_id
         &#124;&#124; &#039; pad=&#039;
         &#124;&#124; in_pad);
      return 1;
   end;
select id, pad
  from u1.v
 where id between 1 and 5
   and spy(id, pad) = 1
Error report -
ORA-28144: Failed to execute fine-grained audit handler
ORA-20942: plsql_declarations are not allowed in the with_clause. See policy SUPPRESS_PLSQL_DELCARATIONS_POLICY for U1.V
ORA-06512: at &quot;U1.SUPPRESS_PLSQL_DELCARATIONS_HANDLER&quot;, line 8
ORA-06512: at line 1&lt;/pre&gt;
The statement was not executed and no results were returned. However, the execution was logged in &lt;code&gt;dba_fga_audit_trail&lt;/code&gt;.
&lt;blockquote&gt;I just thought about another possible option that seems to solve the problem, namely, using a NO_MERGE hint in the view definition itself.&lt;/blockquote&gt;
Yes, in this simplistic case you can do that. However, IMO this is still a workaround and not a solution. &lt;code&gt;optimizer_secure_view_merging=true&lt;/code&gt; should ensure that such predicates are not applied to an intermediate result no matter where the predicate was declared. In the end we do not want to add &lt;code&gt;no_merge&lt;/code&gt; hints in every view.

Cheers,
Philipp]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="https://www.salvis.com/blog/2022/10/30/optimizer_secure_view_merging-and-plsql_declarations/#comment-105315">IUDITH MENTZEL</a>.</p>
<p>Hi Iudith,</p>
<blockquote><p>There is a note in this post, stating the following:</p>
<p>&#8220;Note: while your Handler can slow down the Select operation, it cannot abort it nor can it change the query being executed. Even when your Handler raises an exception, the query will proceed unhamperedly and return its results.&#8221;</p>
<p>So, as I understand from here, raising an exception in an FGA policy handler, as in your proposed workaround, will NOT prevent<br />
the SELECT from executing.</p>
<p>I would be grateful if you could confirm or infirm the correctness of the note above</p></blockquote>
<p>Well, I can confirm that this is not correct.</p>
<p>Firstly, <a href="https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/using-transparent-sensitive-data-protection.html#GUID-F852F1BE-D835-426C-9779-89139B066EEE" rel="nofollow ugc">the documentation</a> clearly states the following:</p>
<blockquote><p>Function name of the event handler. Include the package name if necessary. This function is invoked only after the first row that matches the audit condition in the query is processed. If the procedure fails with an exception, then the user’s SQL statement fails as well.</p></blockquote>
<p>Secondly, and more importantly, I have tested it. I ran the following query as user `u2` after creating the policy as described above:</p>
<pre class="lang:plsql decode:true " title="Test failing FGA handler">set serveroutput on size unlimited
with
   function spy(
      in_id  in number,
      in_pad in varchar2
   ) return number as
   begin
      dbms_output.put_line('id='
         || in_id
         || ' pad='
         || in_pad);
      return 1;
   end;
select id, pad
  from u1.v
 where id between 1 and 5
   and spy(id, pad) = 1
/

Error starting at line : 2 in command -
with
   function spy(
      in_id  in number,
      in_pad in varchar2
   ) return number as
   begin
      dbms_output.put_line('id='
         || in_id
         || ' pad='
         || in_pad);
      return 1;
   end;
select id, pad
  from u1.v
 where id between 1 and 5
   and spy(id, pad) = 1
Error report -
ORA-28144: Failed to execute fine-grained audit handler
ORA-20942: plsql_declarations are not allowed in the with_clause. See policy SUPPRESS_PLSQL_DELCARATIONS_POLICY for U1.V
ORA-06512: at "U1.SUPPRESS_PLSQL_DELCARATIONS_HANDLER", line 8
ORA-06512: at line 1</pre>
<p>The statement was not executed and no results were returned. However, the execution was logged in <code>dba_fga_audit_trail</code>.</p>
<blockquote><p>I just thought about another possible option that seems to solve the problem, namely, using a NO_MERGE hint in the view definition itself.</p></blockquote>
<p>Yes, in this simplistic case you can do that. However, IMO this is still a workaround and not a solution. <code>optimizer_secure_view_merging=true</code> should ensure that such predicates are not applied to an intermediate result no matter where the predicate was declared. In the end we do not want to add <code>no_merge</code> hints in every view.</p>
<p>Cheers,<br />
Philipp</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: IUDITH MENTZEL		</title>
		<link>https://www.salvis.com/blog/2022/10/30/optimizer_secure_view_merging-and-plsql_declarations/#comment-105315</link>

		<dc:creator><![CDATA[IUDITH MENTZEL]]></dc:creator>
		<pubDate>Thu, 17 Nov 2022 18:18:46 +0000</pubDate>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=11897#comment-105315</guid>

					<description><![CDATA[Hi Philipp,

Though I don&#039;t have too much practical experience with DBMS_FGA, your post however reminded me of something that I read many years ago,
in a post from Lucas Jellema:

https://technology.amis.nl/it/select-trigger-in-oracle-database-introducing-fine-grained-auditing/

There is a note in this post, stating the following:

&quot;Note: while your Handler can slow down the Select operation, it cannot abort it nor can it change the query being executed. Even when your Handler raises an exception, the query will proceed unhamperedly and return its results.&quot;

So, as I understand from here, raising an exception in an FGA policy handler, as in your proposed workaround, will NOT prevent
the SELECT from executing.

I would be grateful if you could confirm or infirm the correctness of the note above

I just thought about another possible option that seems to solve the problem, namely, using a NO_MERGE hint in the view definition itself.

For your example, this works for both cases, using a stored function or a WITH clause function:

create or replace view v2 as
  select /*+ NO_MERGE */ *
     from t
    where f(class) = 1
/

View created.


select id, pad
  from v2
 where id between 1 and 5
   and spy(id, pad) = 1
/

ID	PAD
---------------------
1	DrMLTDXxxq
4	AszBGEUGEL

2 rows selected.

id=1 pad=DrMLTDXxxq
id=4 pad=AszBGEUGEL

 

with
   function spy(
      in_id  in number,
      in_pad in varchar2
   ) return number as
   begin
      dbms_output.put_line(&#039;id=&#039;
         &#124;&#124; in_id
         &#124;&#124; &#039; pad=&#039;
         &#124;&#124; in_pad);
      return 1;
   end;
select id, pad
  from v2
 where id between 1 and 5
   and spy(id, pad) = 1;
/
 
ID	PAD
----------------------
1	DrMLTDXxxq
4	AszBGEUGEL

id=1 pad=DrMLTDXxxq
id=4 pad=AszBGEUGEL


As a general comment: 

Considering the fact that the optimizer might decide in some cases to ignore hints for one reason or another,
using a hint is not always a 100% solution, so, I think that using MERGE VIEW is probably the way to go.
If Oracle already decided to introduce a documented feature that specifically targets this scenario, I don&#039;t think that it is good
to avoid using it because of administrative issues.

Also, I think that Oracle could have implemented this feature also as part of the view definition itself, using a MERGEABLE/NONMERGEABLE 
clause, aka the equivalent of an &quot;enforced&quot; hint.
This would make the view not mergeable for ALL users, while the MERGE VIEW privilege may be granted selectively to specific users
or roles.

Cheers &#038; Best Regards,
Iudith Mentzel]]></description>
			<content:encoded><![CDATA[<p>Hi Philipp,</p>
<p>Though I don&#8217;t have too much practical experience with DBMS_FGA, your post however reminded me of something that I read many years ago,<br />
in a post from Lucas Jellema:</p>
<p><a href="https://technology.amis.nl/it/select-trigger-in-oracle-database-introducing-fine-grained-auditing/" rel="nofollow ugc">https://technology.amis.nl/it/select-trigger-in-oracle-database-introducing-fine-grained-auditing/</a></p>
<p>There is a note in this post, stating the following:</p>
<p>&#8220;Note: while your Handler can slow down the Select operation, it cannot abort it nor can it change the query being executed. Even when your Handler raises an exception, the query will proceed unhamperedly and return its results.&#8221;</p>
<p>So, as I understand from here, raising an exception in an FGA policy handler, as in your proposed workaround, will NOT prevent<br />
the SELECT from executing.</p>
<p>I would be grateful if you could confirm or infirm the correctness of the note above</p>
<p>I just thought about another possible option that seems to solve the problem, namely, using a NO_MERGE hint in the view definition itself.</p>
<p>For your example, this works for both cases, using a stored function or a WITH clause function:</p>
<p>create or replace view v2 as<br />
  select /*+ NO_MERGE */ *<br />
     from t<br />
    where f(class) = 1<br />
/</p>
<p>View created.</p>
<p>select id, pad<br />
  from v2<br />
 where id between 1 and 5<br />
   and spy(id, pad) = 1<br />
/</p>
<p>ID	PAD<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
1	DrMLTDXxxq<br />
4	AszBGEUGEL</p>
<p>2 rows selected.</p>
<p>id=1 pad=DrMLTDXxxq<br />
id=4 pad=AszBGEUGEL</p>
<p>with<br />
   function spy(<br />
      in_id  in number,<br />
      in_pad in varchar2<br />
   ) return number as<br />
   begin<br />
      dbms_output.put_line(&#8216;id=&#8217;<br />
         || in_id<br />
         || &#8216; pad=&#8217;<br />
         || in_pad);<br />
      return 1;<br />
   end;<br />
select id, pad<br />
  from v2<br />
 where id between 1 and 5<br />
   and spy(id, pad) = 1;<br />
/</p>
<p>ID	PAD<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
1	DrMLTDXxxq<br />
4	AszBGEUGEL</p>
<p>id=1 pad=DrMLTDXxxq<br />
id=4 pad=AszBGEUGEL</p>
<p>As a general comment: </p>
<p>Considering the fact that the optimizer might decide in some cases to ignore hints for one reason or another,<br />
using a hint is not always a 100% solution, so, I think that using MERGE VIEW is probably the way to go.<br />
If Oracle already decided to introduce a documented feature that specifically targets this scenario, I don&#8217;t think that it is good<br />
to avoid using it because of administrative issues.</p>
<p>Also, I think that Oracle could have implemented this feature also as part of the view definition itself, using a MERGEABLE/NONMERGEABLE<br />
clause, aka the equivalent of an &#8220;enforced&#8221; hint.<br />
This would make the view not mergeable for ALL users, while the MERGE VIEW privilege may be granted selectively to specific users<br />
or roles.</p>
<p>Cheers &amp; Best Regards,<br />
Iudith Mentzel</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: rvo		</title>
		<link>https://www.salvis.com/blog/2022/10/30/optimizer_secure_view_merging-and-plsql_declarations/#comment-104799</link>

		<dc:creator><![CDATA[rvo]]></dc:creator>
		<pubDate>Sat, 05 Nov 2022 12:31:06 +0000</pubDate>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=11897#comment-104799</guid>

					<description><![CDATA[Hi Philipp, 

Thank you for this eye-opening article!

The plot would thicken a little should the user U2 have the CREATE VIEW privilege, as that would enable to conveniently hide the inline PL/SQL function into a view, thereby circumventing the above FGA policy.

(Granting CREATE VIEW to end users in a context where VPD and/or FGA would be used is probably not a good idea in the first place.)

Regards,]]></description>
			<content:encoded><![CDATA[<p>Hi Philipp, </p>
<p>Thank you for this eye-opening article!</p>
<p>The plot would thicken a little should the user U2 have the CREATE VIEW privilege, as that would enable to conveniently hide the inline PL/SQL function into a view, thereby circumventing the above FGA policy.</p>
<p>(Granting CREATE VIEW to end users in a context where VPD and/or FGA would be used is probably not a good idea in the first place.)</p>
<p>Regards,</p>
]]></content:encoded>
		
			</item>
	</channel>
</rss>
