<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PL/SQL Cop Archives - Philipp Salvisberg&#039;s Blog</title>
	<atom:link href="https://www.salvis.com/blog/tag/plsql-cop/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.salvis.com/blog/tag/plsql-cop/</link>
	<description>Database-centric development</description>
	<lastBuildDate>Wed, 08 Nov 2023 15:36:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.salvis.com/blog/wp-content/uploads/2014/04/favicon.png</url>
	<title>PL/SQL Cop Archives - Philipp Salvisberg&#039;s Blog</title>
	<link>https://www.salvis.com/blog/tag/plsql-cop/</link>
	<width>32</width>
	<height>32</height>
</image> 
<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/tag/plsql-cop/feed/"/>
	<item>
		<title>Finding Wrong Hints</title>
		<link>https://www.salvis.com/blog/2022/01/14/finding-wrong-hints/</link>
					<comments>https://www.salvis.com/blog/2022/01/14/finding-wrong-hints/#comments</comments>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Fri, 14 Jan 2022 19:32:55 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Arbori]]></category>
		<category><![CDATA[Code Analysis]]></category>
		<category><![CDATA[PL/SQL Cop]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Developer]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=11443</guid>

					<description><![CDATA[<p>Introduction I have used the Oracle Database for many years. And I use hints. For experiments, but also in production code. There are cases when you know more than the Oracle Database. For example about the cardinality of a data source or the number of result rows to process or the number<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2022/01/14/finding-wrong-hints/">Finding Wrong Hints</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Introduction</h2>



<p>I have used the Oracle Database for many years. And I use hints. For experiments, but also in production code. There are cases when you know more than the Oracle Database. For example about the cardinality of a data source or the number of result rows to process or the number of expected executions of a statement. Hints are a way to provide additional information, limit the solution space and enable the database to do a better job. That&#8217;s a good thing.</p>



<h2 class="wp-block-heading">Hints Are Instructions</h2>



<p>Hints are passed as special comments at a certain position in SQL statements. They are comments, but they are also instructions. They have to be followed. However, there are cases when hints are not applicable. For example when you request the optimizer to use an index when there is no index defined for the underlying table. In such a case the Oracle Database has basically two options. Either throw an error or ignore the invalid instruction and find another solution. The Oracle Database does the latter.</p>



<h2 class="wp-block-heading">Hint Report</h2>



<p>Starting with version 19c you can produce a hint report that reveals unused hints. Here&#8217;s an example:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Unused hint</span><span role="button" tabindex="0" data-code="create table t (c1 integer, c2 varchar2(20));
insert into t values (1, 'one');
insert into t values (2, 'two');
select /*+ index(t) */ * from t where c1 &gt; 0;
select * from dbms_xplan.display_cursor(format =&gt; 'basic +hint_report');

EXPLAINED SQL STATEMENT:
------------------------
select /*+ index(t) */ * from t where c1 &gt; 0
 
Plan hash value: 1601196873
 
------------------------------------------
| Id  | Operation                 | Name |
------------------------------------------
|   0 | SELECT STATEMENT          |      |
|   1 |  TABLE ACCESS STORAGE FULL| T    |
------------------------------------------
 
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1 (U - Unused (1))
---------------------------------------------------------------------------
 
   1 -  SEL$1 / &quot;T&quot;@&quot;SEL$1&quot;
         U -  index(t)" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">t</span><span style="color: #D4D4D4"> (c1 </span><span style="color: #569CD6">integer</span><span style="color: #D4D4D4">, c2 </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #569CD6">insert into</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;one&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">insert into</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;two&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line cbp-line-highlight"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ index(t) */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> c1 &gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dbms_xplan.display_cursor(format =&gt; </span><span style="color: #CE9178">&#39;basic +hint_report&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">EXPLAINED </span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #6A9955">------------------------</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ index(t) */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> c1 &gt; </span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan </span><span style="color: #569CD6">hash</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">value</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">1601196873</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                 | </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4"> |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">          |      |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> |  </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> ACCESS STORAGE FULL| T    |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Hint Report (identified </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> operation id / Query </span><span style="color: #569CD6">Block</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4"> / </span><span style="color: #569CD6">Object</span><span style="color: #D4D4D4"> Alias):</span></span>
<span class="line"><span style="color: #D4D4D4">Total hints </span><span style="color: #569CD6">for</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">statement</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> (U - Unused (</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">))</span></span>
<span class="line"><span style="color: #6A9955">---------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> -  SEL$</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> / </span><span style="color: #CE9178">&quot;T&quot;</span><span style="color: #D4D4D4">@</span><span style="color: #CE9178">&quot;SEL$1&quot;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         U -  </span><span style="color: #569CD6">index</span><span style="color: #D4D4D4">(t)</span></span></code></pre></div>



<p>The hint <code>index(t)</code> defined on line 4 is valid, but it&#8217;s reported as unused on line 25. No wonder. There is no index defined on table <code>t</code>.</p>



<p>Let&#8217;s create an index and rerun the query.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Used hint</span><span role="button" tabindex="0" data-code="create unique index t_c1_i on t(c1);
select /*+ index(t) */ * from t where c1 &gt; 0;
select * from dbms_xplan.display_cursor(format =&gt; 'basic +hint_report');

EXPLAINED SQL STATEMENT:
------------------------
select /*+ index(t) */ * from t where c1 &gt; 0
 
Plan hash value: 2704710798
 
------------------------------------------------------
| Id  | Operation                           | Name   |
------------------------------------------------------
|   0 | SELECT STATEMENT                    |        |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T      |
|   2 |   INDEX RANGE SCAN                  | T_C1_I |
------------------------------------------------------
 
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1
---------------------------------------------------------------------------
 
   1 -  SEL$1 / &quot;T&quot;@&quot;SEL$1&quot;
           -  index(t)" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">unique index</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">t_c1_i</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> t(c1);</span></span>
<span class="line cbp-line-highlight"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ index(t) */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> c1 &gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dbms_xplan.display_cursor(format =&gt; </span><span style="color: #CE9178">&#39;basic +hint_report&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">EXPLAINED </span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #6A9955">------------------------</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ index(t) */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> c1 &gt; </span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan </span><span style="color: #569CD6">hash</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">value</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">2704710798</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                           | </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4">   |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">                    |        |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> |  </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> ACCESS </span><span style="color: #569CD6">BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">INDEX</span><span style="color: #D4D4D4"> ROWID BATCHED| T      |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> |   </span><span style="color: #569CD6">INDEX</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">RANGE</span><span style="color: #D4D4D4"> SCAN                  | T_C1_I |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Hint Report (identified </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> operation id / Query </span><span style="color: #569CD6">Block</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4"> / </span><span style="color: #569CD6">Object</span><span style="color: #D4D4D4"> Alias):</span></span>
<span class="line"><span style="color: #D4D4D4">Total hints </span><span style="color: #569CD6">for</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">statement</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #6A9955">---------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> -  SEL$</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> / </span><span style="color: #CE9178">&quot;T&quot;</span><span style="color: #D4D4D4">@</span><span style="color: #CE9178">&quot;SEL$1&quot;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">           -  </span><span style="color: #569CD6">index</span><span style="color: #D4D4D4">(t)</span></span></code></pre></div>



<p>Now the hint <code>index(t)</code> defined on line 2 is reported as used on line 24.</p>



<h2 class="wp-block-heading">Mixing Hints and Comments</h2>



<p>What happens if we mix hints and comments? It depends on where you place the comment. Let&#8217;s look at the next example.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Hint followed by unknown tokens</span><span role="button" tabindex="0" data-code="select /*+ index(t) forcing unnecessary index access */ * from t where c1 &gt; 0;
select * from dbms_xplan.display_cursor(format =&gt; 'basic +hint_report');

EXPLAINED SQL STATEMENT:
------------------------
select /*+ index(t) forcing unnecessary index access */ * from t where 
c1 &gt; 0
 
Plan hash value: 2704710798
 
------------------------------------------------------
| Id  | Operation                           | Name   |
------------------------------------------------------
|   0 | SELECT STATEMENT                    |        |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T      |
|   2 |   INDEX RANGE SCAN                  | T_C1_I |
------------------------------------------------------
 
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 4 (E - Syntax error (3))
---------------------------------------------------------------------------
 
   1 -  SEL$1
         E -  forcing
         E -  index 
         E -  unnecessary
 
   1 -  SEL$1 / &quot;T&quot;@&quot;SEL$1&quot;
           -  index(t)" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line cbp-line-highlight"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ index(t) forcing unnecessary index access */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> c1 &gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dbms_xplan.display_cursor(format =&gt; </span><span style="color: #CE9178">&#39;basic +hint_report&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">EXPLAINED </span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #6A9955">------------------------</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ index(t) forcing unnecessary index access */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">c1 &gt; </span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan </span><span style="color: #569CD6">hash</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">value</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">2704710798</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                           | </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4">   |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">                    |        |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> |  </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> ACCESS </span><span style="color: #569CD6">BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">INDEX</span><span style="color: #D4D4D4"> ROWID BATCHED| T      |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> |   </span><span style="color: #569CD6">INDEX</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">RANGE</span><span style="color: #D4D4D4"> SCAN                  | T_C1_I |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Hint Report (identified </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> operation id / Query </span><span style="color: #569CD6">Block</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4"> / </span><span style="color: #569CD6">Object</span><span style="color: #D4D4D4"> Alias):</span></span>
<span class="line"><span style="color: #D4D4D4">Total hints </span><span style="color: #569CD6">for</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">statement</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4"> (E - Syntax error (</span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4">))</span></span>
<span class="line"><span style="color: #6A9955">---------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> -  SEL$</span><span style="color: #B5CEA8">1</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         E -  forcing</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         E -  </span><span style="color: #569CD6">index</span><span style="color: #D4D4D4"> </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         E -  unnecessary</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> -  SEL$</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> / </span><span style="color: #CE9178">&quot;T&quot;</span><span style="color: #D4D4D4">@</span><span style="color: #CE9178">&quot;SEL$1&quot;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">           -  </span><span style="color: #569CD6">index</span><span style="color: #D4D4D4">(t)</span></span></code></pre></div>



<p>The comment <code>forcing unnecessary index access</code> on line 1 is interpreted as a series of hints and reported as errors on lines 24 to 26. The token <code>access</code> was not reported. However, the hint <code>index(t)</code> was reported as used on line 29.</p>



<p>What happens if we move the comment to the beginning?</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Unknown tokens followed by hint</span><span role="button" tabindex="0" data-code="select /*+ forcing unnecessary index access index(t) */ * from t where c1 &gt; 0;
select * from dbms_xplan.display_cursor(format =&gt; 'basic +hint_report');

EXPLAINED SQL STATEMENT:
------------------------
select /*+ forcing unnecessary index access index(t) */ * from t where 
c1 &gt; 0
 
Plan hash value: 2704710798
 
------------------------------------------------------
| Id  | Operation                           | Name   |
------------------------------------------------------
|   0 | SELECT STATEMENT                    |        |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T      |
|   2 |   INDEX RANGE SCAN                  | T_C1_I |
------------------------------------------------------
 
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 3 (E - Syntax error (3))
---------------------------------------------------------------------------
 
   1 -  SEL$1
         E -  forcing
         E -  index 
         E -  unnecessary" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line cbp-line-highlight"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ forcing unnecessary index access index(t) */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> c1 &gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dbms_xplan.display_cursor(format =&gt; </span><span style="color: #CE9178">&#39;basic +hint_report&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">EXPLAINED </span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #6A9955">------------------------</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ forcing unnecessary index access index(t) */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">c1 &gt; </span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan </span><span style="color: #569CD6">hash</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">value</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">2704710798</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                           | </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4">   |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">                    |        |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> |  </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> ACCESS </span><span style="color: #569CD6">BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">INDEX</span><span style="color: #D4D4D4"> ROWID BATCHED| T      |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> |   </span><span style="color: #569CD6">INDEX</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">RANGE</span><span style="color: #D4D4D4"> SCAN                  | T_C1_I |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Hint Report (identified </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> operation id / Query </span><span style="color: #569CD6">Block</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4"> / </span><span style="color: #569CD6">Object</span><span style="color: #D4D4D4"> Alias):</span></span>
<span class="line"><span style="color: #D4D4D4">Total hints </span><span style="color: #569CD6">for</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">statement</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4"> (E - Syntax error (</span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4">))</span></span>
<span class="line"><span style="color: #6A9955">---------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> -  SEL$</span><span style="color: #B5CEA8">1</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         E -  forcing</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         E -  </span><span style="color: #569CD6">index</span><span style="color: #D4D4D4"> </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         E -  unnecessary</span></span></code></pre></div>



<p>The same invalid hints are reported as before on lines 24 to 26. However, the hint <code>index(t)</code> was used but not reported as such. This seems to be a limitation of the current hint report in the Oracle Database 21c.</p>



<p>Anyways, it clearly shows that you should not mix comments and hints. Instead, you should write it like this:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Distinguish between comments and hints</span><span role="button" tabindex="0" data-code="select /* forcing unnecessary index access */ /*+ index(t) */ * from t where c1 &gt; 0;
select * from dbms_xplan.display_cursor(format =&gt; 'basic +hint_report');

EXPLAINED SQL STATEMENT:
------------------------
select /* forcing unnecessary index access */ /*+ index(t) */ * from t 
where c1 &gt; 0
 
Plan hash value: 2704710798
 
------------------------------------------------------
| Id  | Operation                           | Name   |
------------------------------------------------------
|   0 | SELECT STATEMENT                    |        |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T      |
|   2 |   INDEX RANGE SCAN                  | T_C1_I |
------------------------------------------------------
 
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1
---------------------------------------------------------------------------
 
   1 -  SEL$1 / &quot;T&quot;@&quot;SEL$1&quot;
           -  index(t)" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line cbp-line-highlight"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/* forcing unnecessary index access */</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ index(t) */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> c1 &gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dbms_xplan.display_cursor(format =&gt; </span><span style="color: #CE9178">&#39;basic +hint_report&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">EXPLAINED </span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #6A9955">------------------------</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/* forcing unnecessary index access */</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ index(t) */</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> t </span></span>
<span class="line"><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> c1 &gt; </span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan </span><span style="color: #569CD6">hash</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">value</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">2704710798</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                           | </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4">   |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">                    |        |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> |  </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> ACCESS </span><span style="color: #569CD6">BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">INDEX</span><span style="color: #D4D4D4"> ROWID BATCHED| T      |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> |   </span><span style="color: #569CD6">INDEX</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">RANGE</span><span style="color: #D4D4D4"> SCAN                  | T_C1_I |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Hint Report (identified </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> operation id / Query </span><span style="color: #569CD6">Block</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4"> / </span><span style="color: #569CD6">Object</span><span style="color: #D4D4D4"> Alias):</span></span>
<span class="line"><span style="color: #D4D4D4">Total hints </span><span style="color: #569CD6">for</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">statement</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #6A9955">---------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> -  SEL$</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> / </span><span style="color: #CE9178">&quot;T&quot;</span><span style="color: #D4D4D4">@</span><span style="color: #CE9178">&quot;SEL$1&quot;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">           -  </span><span style="color: #569CD6">index</span><span style="color: #D4D4D4">(t)</span></span></code></pre></div>



<p>Now the hint <code>index(t)</code> is reported as used. All good, right?</p>



<h2 class="wp-block-heading">The Problem</h2>



<p>I like statically-type languages. Mainly because errors are reported at compile time whenever possible. However, to check hints I need to produce an explain plan. This is possible for a single statement only. This is cumbersome especially when you write code in PL/SQL. As far as I know, there is no option to produce a compile error for invalid hints.</p>



<p>I recently reviewed a system and found a lot of invalid hints. Here are some real-life hints copied from a production code base:</p>



<ul class="wp-block-list">
<li><code>/*+ parallel 4 */</code></li>



<li><code>/*+ no_xml_query_rewrite +materialize */</code></li>



<li><code>/*+ materialized */</code></li>



<li><code>/*+ first rows cardinality (a,10) */</code></li>



<li><code>/*+ append nologging */</code></li>



<li><code>/*+ le ading(g) u se_nl(g) u se_hash(p, b) */</code></li>
</ul>



<p>The last example is a kind of commented-out hint series. In this case, it&#8217;s clearly commented-out code. But if you see just a single hint like <code>/*+ le ading(g) */</code> in the code, you do not know if the space after <code>le</code> was entered intentionally or by accident.</p>



<p>So, how can we identify invalid hints in our code?</p>



<h2 class="wp-block-heading">Step 1 &#8211; Distinguish Between Comments and Hints</h2>



<p>We can configure Oracle&#8217;s SQL Developer to show hints in a different colour than comments. Here&#8217;s the screenshot of an example I showed above:</p>



<figure class="wp-block-image"><a href="https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints.png"><img fetchpriority="high" decoding="async" width="2170" height="70" src="https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints.png" alt="Distinguish between comments and hints" class="wp-image-11455" srcset="https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints.png 2170w, https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints-300x10.png 300w, https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints-1024x33.png 1024w, https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints-768x25.png 768w, https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints-1536x50.png 1536w, https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints-2048x66.png 2048w, https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints-260x8.png 260w, https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints-50x2.png 50w, https://www.salvis.com/blog/wp-content/uploads/2022/01/distinguish-between-comments-and-hints-150x5.png 150w" sizes="(max-width:767px) 480px, (max-width:2170px) 100vw, 2170px" /></a></figure>



<p>Go to <a href="https://github.com/Trivadis/plsql-syntax-colors#installation">this GitHub repository</a> and follow the instructions to configure your SQL Developer installation accordingly. See also <a href="https://www.salvis.com/blog/2020/09/07/highlight-hints-in-sql-developer/">this blog post</a> for more information about the Arbori code that makes such code highlighting possible.</p>



<p>This step make hints stand out in your code. However, it does not reveal invalid hints.</p>



<h2 class="wp-block-heading">Step 2 &#8211; Install db* CODECOP for SQL Developer</h2>



<p>To reveal invalid hints we need a linter. A tool that does some static code analysis. db* CODECOP is such a tool suite. The SQL Developer extension is available for free. It checks the editor content for violations of the <a href="https://trivadis.github.io/plsql-and-sql-coding-guidelines" rel="nofollow">Trivadis PL/SQL &amp; SQL Coding Guidelines</a>. Furthermore, db* CODECOP allows you to implement custom guideline checks. The <a href="https://github.com/Trivadis/plsql-cop-validators#hint">example GitHub repository</a> provides the following four guideline checks regarding hints:</p>



<ul class="wp-block-list">
<li>G-9600: Never define more than one comment with hints.</li>



<li>G-9601: Never use unknown hints.</li>



<li>G-9602: Always use the alias name instead of the table name.</li>



<li>G-9603: Never reference an unknown table/alias.</li>
</ul>



<p>To install db* CODECOP and these additional custom guideline checks follow the instructions in this <a href="https://github.com/Trivadis/plsql-cop-validators#use-in-db-codecop-for-sql-developer">GitHub repository</a>.</p>



<h2 class="wp-block-heading">Finding Wrong Hints With db* CODECOP</h2>



<p>I asked my followers on <a href="https://twitter.com/phsalvisberg/status/1481641087164846085?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1481641087164846085%7Ctwgr%5E%7Ctwcon%5Es1_c10&amp;ref_url=https%3A%2F%2Fpublish.twitter.com%2F%3Fquery%3Dhttps3A2F2Ftwitter.com2Fphsalvisberg2Fstatus2F1481641087164846085widget%3DTweet">Twitter</a> if this hint is valid:</p>



<figure class="wp-block-image is-resized"><a href="https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll.png"><img decoding="async" width="1200" height="742" src="https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll.png" alt="Twitter Poll" class="wp-image-11459" style="width:600px" srcset="https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll.png 1200w, https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll-300x186.png 300w, https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll-1024x633.png 1024w, https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll-768x475.png 768w, https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll-236x146.png 236w, https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll-50x31.png 50w, https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll-121x75.png 121w, https://www.salvis.com/blog/wp-content/uploads/2022/01/twitter-poll-1x1.png 1w" sizes="(max-width:767px) 480px, (max-width:1200px) 100vw, 1200px" /></a></figure>



<p>The result is not really representative. However, 25% thought that <code>/*+ +materialize */</code> is a valid hint.</p>



<p>Checking the code with db* CODECOP reveals that the hint is invalid and the majority of the poll participants were right.</p>



<figure class="wp-block-image is-resized"><a href="https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint.png"><img decoding="async" width="1168" height="476" src="https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint.png" alt="Invalid hint" class="wp-image-11457" style="width:584px" srcset="https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint.png 1168w, https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint-300x122.png 300w, https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint-1024x417.png 1024w, https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint-768x313.png 768w, https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint-260x106.png 260w, https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint-50x20.png 50w, https://www.salvis.com/blog/wp-content/uploads/2022/01/invalid-hint-150x61.png 150w" sizes="(max-width:767px) 480px, (max-width:1168px) 100vw, 1168px" /></a></figure>



<h2 class="wp-block-heading">Verify Result</h2>



<p>But is the result of db* CODECOP correct? The following explain plan shows that the hint <code>/*+ +materialize */</code> is not reported at all. It&#8217;s treated as a comment. Another example is where the hint report is incomplete.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Hint report for +materialize</span><span role="button" tabindex="0" data-code="with e as (
   select /*+ +materialize */ *
     from emp
    where deptno = 10
)
select *
  from e;
select * from dbms_xplan.display_cursor(format =&gt; 'basic +hint_report');

EXPLAINED SQL STATEMENT:
------------------------
with e as (    select /*+ +materialize */ *      from emp     where 
deptno = 10 ) select *   from e
 
Plan hash value: 3956160932
 
------------------------------------------
| Id  | Operation                 | Name |
------------------------------------------
|   0 | SELECT STATEMENT          |      |
|   1 |  TABLE ACCESS STORAGE FULL| EMP  |
------------------------------------------" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">with</span><span style="color: #D4D4D4"> e </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> (</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ +materialize */</span><span style="color: #D4D4D4"> *</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> deptno = </span><span style="color: #B5CEA8">10</span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> *</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> e;</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dbms_xplan.display_cursor(format =&gt; </span><span style="color: #CE9178">&#39;basic +hint_report&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">EXPLAINED </span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #6A9955">------------------------</span></span>
<span class="line"><span style="color: #569CD6">with</span><span style="color: #D4D4D4"> e </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> (    </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ +materialize */</span><span style="color: #D4D4D4"> *      </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp     </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">deptno = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> ) </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> *   </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> e</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan </span><span style="color: #569CD6">hash</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">value</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">3956160932</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                 | </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4"> |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">          |      |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> |  </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> ACCESS STORAGE FULL| EMP  |</span></span>
<span class="line"><span style="color: #6A9955">------------------------------------------</span></span></code></pre></div>



<p>Let&#8217;s run the same query after removing the extra <code>+</code> in the hint:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Hint report for materialize</span><span role="button" tabindex="0" data-code="with e as (
   select /*+ materialize */ *
     from emp
    where deptno = 10
)
select *
  from e;
select * from dbms_xplan.display_cursor(format =&gt; 'basic +hint_report');

EXPLAINED SQL STATEMENT:
------------------------
with e as (    select /*+ materialize */ *      from emp     where 
deptno = 10 ) select *   from e
 
Plan hash value: 3494145522
 
--------------------------------------------------------------------------------
| Id  | Operation                                | Name                        |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                         |                             |
|   1 |  TEMP TABLE TRANSFORMATION               |                             |
|   2 |   LOAD AS SELECT (CURSOR DURATION MEMORY)| SYS_TEMP_DFD9DB186_8AAEBD74 |
|   3 |    TABLE ACCESS STORAGE FULL             | EMP                         |
|   4 |   VIEW                                   |                             |
|   5 |    TABLE ACCESS STORAGE FULL             | SYS_TEMP_DFD9DB186_8AAEBD74 |
--------------------------------------------------------------------------------
 
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1
---------------------------------------------------------------------------
 
   2 -  SEL$1
           -  materialize" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">with</span><span style="color: #D4D4D4"> e </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> (</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ materialize */</span><span style="color: #D4D4D4"> *</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> deptno = </span><span style="color: #B5CEA8">10</span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> *</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> e;</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dbms_xplan.display_cursor(format =&gt; </span><span style="color: #CE9178">&#39;basic +hint_report&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">EXPLAINED </span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #6A9955">------------------------</span></span>
<span class="line"><span style="color: #569CD6">with</span><span style="color: #D4D4D4"> e </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> (    </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955">/*+ materialize */</span><span style="color: #D4D4D4"> *      </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp     </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">deptno = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> ) </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> *   </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> e</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan </span><span style="color: #569CD6">hash</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">value</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">3494145522</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #6A9955">--------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                                | </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4">                        |</span></span>
<span class="line"><span style="color: #6A9955">--------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">STATEMENT</span><span style="color: #D4D4D4">                         |                             |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> |  TEMP </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> TRANSFORMATION               |                             |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> |   </span><span style="color: #569CD6">LOAD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> (</span><span style="color: #569CD6">CURSOR</span><span style="color: #D4D4D4"> DURATION MEMORY)| SYS_TEMP_DFD9DB186_8AAEBD74 |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4"> |    </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> ACCESS STORAGE FULL             | EMP                         |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4"> |   VIEW                                   |                             |</span></span>
<span class="line"><span style="color: #D4D4D4">|   </span><span style="color: #B5CEA8">5</span><span style="color: #D4D4D4"> |    </span><span style="color: #569CD6">TABLE</span><span style="color: #D4D4D4"> ACCESS STORAGE FULL             | SYS_TEMP_DFD9DB186_8AAEBD74 |</span></span>
<span class="line"><span style="color: #6A9955">--------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Hint Report (identified </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> operation id / Query </span><span style="color: #569CD6">Block</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Name</span><span style="color: #D4D4D4"> / </span><span style="color: #569CD6">Object</span><span style="color: #D4D4D4"> Alias):</span></span>
<span class="line"><span style="color: #D4D4D4">Total hints </span><span style="color: #569CD6">for</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">statement</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #6A9955">---------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> -  SEL$</span><span style="color: #B5CEA8">1</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">           -  materialize</span></span></code></pre></div>



<p>Now, the <code>materialize</code> hint has an effect on the execution plan and the hint is reported as used on line 33.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>I believe that hints are required for certain use cases. You may have a different opinion. However, if you are using hints in your code you should ensure that they are valid. db* CODECOP can help you to do that. The SQL Developer extension is free. Just use it.</p>
<p>The post <a href="https://www.salvis.com/blog/2022/01/14/finding-wrong-hints/">Finding Wrong Hints</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.salvis.com/blog/2022/01/14/finding-wrong-hints/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Names Matter</title>
		<link>https://www.salvis.com/blog/2020/06/21/names-matter/</link>
					<comments>https://www.salvis.com/blog/2020/06/21/names-matter/#comments</comments>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Sun, 21 Jun 2020 15:00:30 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[accessible_by_clause]]></category>
		<category><![CDATA[Decision Time]]></category>
		<category><![CDATA[Flashback]]></category>
		<category><![CDATA[Flashback Data Archive]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[PL/SQL Cop]]></category>
		<category><![CDATA[SonarQube]]></category>
		<category><![CDATA[Transaction Time]]></category>
		<category><![CDATA[Valid Time]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=9890</guid>

					<description><![CDATA[<p>This is one of my favourite quotes: There are only two hard things in Computer Science: cache invalidation and naming things.&#8212; Phil Karlton IT is my daily life. And this quote is so true. Lately, I&#8217;ve been thinking much more than usual about naming, and that names really matter. This led to<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2020/06/21/names-matter/">Names Matter</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>This is one of my favourite quotes:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>There are only two hard things in Computer Science: cache invalidation and naming things.<br />&#8212; Phil Karlton</p>
</blockquote>



<p>IT is my daily life. And this quote is so true. Lately, I&#8217;ve been thinking much more than usual about naming, and that names really matter. This led to some refactoring activities.</p>



<h2 class="wp-block-heading">Why Is Naming Important?</h2>



<p>When a person with German mother tongue hears the word &#8220;eagle&#8221;, she or he automatically associates it with a &#8220;hedgehog&#8221;. Simply because the German word for it (&#8220;Igel&#8221;) is pronounced exactly the same. Of course, language skills and the concrete context play a role. The point is, a wrong association is likely. When we give a name to a thing, we basically want to avoid such false associations. In the best case, they are not helpful. In the worst case, this leads to rejection, as the next example shows.</p>



<p>In 1982 Mitsubishi Motors launched a SUV with the name &#8220;Pajero&#8221;. This name had to be changed in some regions, because &#8220;pajero&#8221; means &#8220;wanker&#8221; in Spanish. This example also shows that it is more important what others think about a name than we do.</p>



<p>In IT we have to name many things. Databases, schemas, tables, columns, views, packages, triggers, variables, fields, methods, classes, modules, components, products, etc. etc. Using an established name with a known and accepted definition help others to understand it better.</p>



<p>When we use a name, it is actually associated with a definition and properties, whether we like it or not. When names have a common and widely accepted meaning, it simplifies the communication. For example &#8220;banana&#8221;. Everybody knows what it means. <a href="https://www.merriam-webster.com/dictionary/banana">Merriam-Webster&#8217;s definition</a> is:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>An elongated usually tapering tropical fruit with soft pulpy flesh enclosed in a soft usually yellow rind.</p>
</blockquote>



<p>And I am sure that each of us could add a few characteristics to this definition.</p>



<h2 class="wp-block-heading">Why Is Naming Difficult?</h2>



<p>A name must fulfil many characteristics. For example</p>



<ul class="wp-block-list">
<li>Short</li>



<li>Fitting (naturally relates to the intended meaning, and characteristics)</li>



<li>Easy to spell,&nbsp;pronounce, remember</li>



<li>Not associated with unwanted characteristics</li>



<li>Common and widely accepted meaning and definition, that fits the intention (for names without commercial value)</li>



<li>New, not used already (for marketable names)</li>
</ul>



<p>Depending on context there are some goal conflicts. However, even without a major conflict, it is difficult to name something adequately in the early stages. Because we do not know enough about the thing we want to name. Hence, we use an iterative approach. We name something (e.g. an entity, package or class) and while working on it we find out that the name does not fit (anymore) and we change it. Maybe we split the thing and have to name now two things, etc. etc.</p>



<p>Finding a fitting name means doing some research. How have others named that thing? What is the definition of it? Does it fit 100 percent? This is an interesting and instructive work. In any case, it takes time. And at the time we need a new name, we want it now (e.g. when a wizard asks for a name). We can always rename it later, right? &#8211; Technically yes. And often we do. But the longer we wait, the less likely we are renaming.</p>



<h2 class="wp-block-heading">Are Some Names More Important Than Others?</h2>



<p>Yes. The more visible a name is the more important it is.</p>



<p>For example, the names behind an API are very easy to change. We do not have to ask anyone before changing it. It&#8217;s no problem as long as the API provides the same results. That&#8217;s one of the reasons we strive for tight APIs, right? To get some leeway.</p>



<p>As soon as others are involved, we are not fully in control of the change anymore. For example, when I change a name in one of my blog posts, this change is visible immediately to everyone visiting my blog. But I cannot control the caches of others, like search engines, blog mirrors and other services that copy web content to third-party storages. Remember, cache invalidation is the other hard thing in IT.</p>



<p>As a consequence, before we release an artefact that becomes visible to others, we should take some time to verify the used names. We cannot take back what we&#8217;ve said (at least not completely). However, we are in control of what we say in the future.</p>



<h2 class="wp-block-heading">Banned Names on This Blog</h2>



<p>Some terms (names) were discussed recently (again) due to a series of sad events. I used these terms as well. I never really thought about them as &#8220;bad&#8221;. However, I&#8217;ve changed my mind. I&#8217;m part of the problem. And I do not like it. One thing I can do is to stop using terms, that a large group of people associate with slavery and racism. No big deal, right?</p>



<p>This is another quote I like very much:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>One cannot not communicate<br />&#8212; Paul Watzlawick</p>
</blockquote>



<p>It is difficult to draw a line for certain terms. However, I believe that &#8220;you cannot not decide&#8221;. You decide either explicitly or implicitly. Of course, very seldom something is purely black or white. It&#8217;s much more often a shade of grey. Some decision take some time. And that&#8217;s okay. But it is impossible to postpone a decision forever. At a certain point, it becomes a decision.</p>



<p>So, I decided to decommission some terms on this blog and introduce new ones. Here&#8217;s the list:</p>



<table id="tablepress-16" class="tablepress tablepress-id-16">
<thead>
<tr class="row-1">
	<th class="column-1">Current Term</th><th class="column-2">Decommissioned Term</th><th class="column-3">Context</th>
</tr>
</thead>
<tbody class="row-striping row-hover">
<tr class="row-2">
	<td class="column-1">accessible</td><td class="column-2"><del>white listed</del></td><td class="column-3">PL/SQL accessible_by clause</td>
</tr>
<tr class="row-3">
	<td class="column-1">agent</td><td class="column-2"><del>slave</del></td><td class="column-3">Jenkins</td>
</tr>
<tr class="row-4">
	<td class="column-1">exclusion list</td><td class="column-2"><del>blacklist</del></td><td class="column-3">PL/SQL Cop, PL/SQL accessible_by clause</td>
</tr>
<tr class="row-5">
	<td class="column-1">inclusion list</td><td class="column-2"><del>whitelist</del></td><td class="column-3">PL/SQL Cop, PL/SQL accessible_by clause</td>
</tr>
<tr class="row-6">
	<td class="column-1">main</td><td class="column-2"><del>master</del></td><td class="column-3">Git branch</td>
</tr>
<tr class="row-7">
	<td class="column-1">transaction structure data + enterprise structure data</td><td class="column-2"><del>master data</del></td><td class="column-3">Data modeling</td>
</tr>
<tr class="row-8">
	<td class="column-1">worker</td><td class="column-2"><del>slave</del></td><td class="column-3">Oracle DB background process </td>
</tr>
</tbody>
</table>
<!-- #tablepress-16 from cache -->


<p>Finding alternative names was surprisingly easy because others had already done the work and defined alternative names. They existed for years&#8230;</p>



<h3 class="wp-block-heading">Master Data</h3>



<p>However, finding an alternative for <a href="https://en.wikipedia.org/wiki/Master_data">master data</a> was harder. I reached out to my friends on Twitter. And got some helpful feedback. Finally, Robert Marti suggested having a look at <a href="https://www.linkedin.com/in/malcolmchisholm/">Malcolm Chisholm</a>&#8216;s book <a href="https://books.google.ch/books?id=WxtW5SUUAYAC&amp;printsec=frontcover#v=onepage&amp;q&amp;f=false">Managing Reference Data in Enterprise Databases</a>. On page <a href="https://books.google.ch/books?id=WxtW5SUUAYAC&amp;lpg=PP1&amp;pg=PA258#v=onepage&amp;q&amp;f=false">258ff</a> the different data classes are defined and explained. The book is from 2000. In the meantime Malcolm Chisholm has published revised definitions <a href="https://www.topquadrant.com/docs/whitepapers/TopBraid_ReferenceDataManagementWhitepaper-3-18-15.pdf">here</a> and <a href="https://www.topquadrant.com/resources/blogs/semantic-ecosystem-journal/docs/RefDataPrepMCRC-Final060215.pdf">here</a>.</p>



<p>In the next subchapter, I repeat the definition of the data groups defined by Malcolm Chisholm on slide 5 in <a href="https://www.topquadrant.com/resources/blogs/semantic-ecosystem-journal/docs/RefDataPrepMCRC-Final060215.pdf">this deck</a>. I like these definitions and plan to use them in the future.</p>



<h4 class="wp-block-heading">Metadata</h4>



<p>The data that describes all aspects of an enterprise’s information assets, and enables the enterprise to effectively use and manage these assets.</p>



<p><em>Here it is confined to the structure of databases. Found in a database’s system catalog. Sometimes included in database tables.</em></p>



<h4 class="wp-block-heading">Reference Data</h4>



<p>Any kind of data that is used solely to categorize other data found in a database, or solely for relating data in a database to information beyond the boundaries of the enterprise.</p>



<p><em>Codes and descriptions. Tables containing this data usually have just a few rows and columns.</em></p>



<h4 class="wp-block-heading">Transaction Structure Data</h4>



<p>Data that represents the direct participants in a transaction, and which must be present before a transaction fires.</p>



<p><em>The parties to the transactions of the enterprise. E.g. Customer, Product.</em></p>



<h4 class="wp-block-heading">Enterprise Structure Data</h4>



<p>Data that permits business activity to be reported and/or analyzed by business responsibility.</p>



<p><em>Typically, data that describes the structure of the enterprise. E.g. organizational or financial structure.</em></p>



<h4 class="wp-block-heading">Transaction Activity Data</h4>



<p>Data that represents the operations an enterprise carries out.</p>



<p><em>Traditional focus of IT – in many enterprises the only focus.</em></p>



<h4 class="wp-block-heading">Transaction Audit Data</h4>



<p>Data that tracks the life cycle of individual transactions.</p>



<p><em>Includes application logs, database logs, web server logs<span class="s1">.</span></em></p>



<h2 class="wp-block-heading">Summary</h2>



<p>You use a name to simplify communication. A name is a proxy for a longer definition and meaning. If the meaning is badly received by others and especially by the target community, this does not simplify communication. Using a different name sounds like a simple solution. Why not, if changing a name is simple enough?</p>



<p>In this case, I only had to edit a few blog posts. I handled them like typos. This means that I did not add any update information. I also had to register new URL redirects. That was straightforward. However, changing the branch name in 26 GitHub repositories was a bit more work than anticipated, because I also had to change URLs in several related files. For certain GitHub pages, I had to keep a non-default master branch. I suppose that sooner or later GitHub will allow me to get rid of them as well. If I had to change more repositories, I would probably automate this task.</p>



<p>Most of the time I spent finding an alternative name for &#8220;master data&#8221;. In the end, I learned something new and found good names and definitions. That will help me in the future.</p>
<p>The post <a href="https://www.salvis.com/blog/2020/06/21/names-matter/">Names Matter</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.salvis.com/blog/2020/06/21/names-matter/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Moving to GitHub</title>
		<link>https://www.salvis.com/blog/2019/12/22/moving-to-github/</link>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Sat, 21 Dec 2019 23:51:56 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PL/SQL Analyzer]]></category>
		<category><![CDATA[PL/SQL Cop]]></category>
		<category><![CDATA[PL/SQL Unwrapper]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=9495</guid>

					<description><![CDATA[<p>Over the years, my blog has become one big mess. It was no longer a blog. It contained product pages, change logs, software downloads, FAQs and even a forum. That was a nice experiment. But now it&#8217;s time to move everything that doesn&#8217;t belong in my personal blog to another place. A<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2019/12/22/moving-to-github/">Moving to GitHub</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Over the years, my blog has become one big mess. It was no longer a blog. It contained product pages, change logs, software downloads, FAQs and even a forum. That was a nice experiment. But now it&#8217;s time to move everything that doesn&#8217;t belong in my personal blog to another place. A place where the content can be properly managed. GitHub.</p>



<h2 class="wp-block-heading">Moved</h2>



<p>I moved all product information including change logs and frequently asked questions to the following GitHub repositories:</p>



<ul class="wp-block-list">
<li><a href="https://github.com/Trivadis/plsql-analyzer">PL/SQL Analyzer</a></li>



<li><a href="https://github.com/Trivadis/plsql-cop-cli">PL/SQL Cop Command Line</a></li>



<li><a href="https://github.com/Trivadis/plsql-cop-validators">PL/SQL Cop Validators</a></li>



<li><a href="https://github.com/Trivadis/plsql-cop-sonar">PL/SQL Cop for SonarQube</a></li>



<li><a href="https://github.com/Trivadis/plsql-cop-sqldev">PL/SQL Cop for SQL Developer</a></li>



<li><a href="https://github.com/Trivadis/plsql-unwrapper-sqldev">PL/SQL Unwrapper for SQL Developer</a></li>



<li><a href="https://github.com/PhilippSalvisberg/plscope-utils/tree/main/sqldev">plscope-utils for SQL Developer</a></li>
</ul>



<p>These repositories contain the product information and the software releases including the release history. The idea is to manage all issues in GitHub repositories, regardless of the public availability of the product source code. I&#8217;m sure this will simplify the work of all involved parties.</p>



<h2 class="wp-block-heading">Stashed</h2>



<p>I removed the forum from the main menu. However, it is still there. If you know the URL (e.g. by guessing or because you have some forum e-mails) then you may access it. For the time being, I keep it in read-only mode. However, I plan to delete the forum without migrating the content.</p>



<h2 class="wp-block-heading">Kept</h2>



<p>The Download area is still there. However, all links including download links point to other websites.</p>



<h2 class="wp-block-heading">Summary</h2>



<p>The move to GitHub is complete. I registered a lot of redirects. So I expect all links to salvis.com to work still and show the expected content. Please leave a comment, If you experience dead links. Thank you.</p>
<p>The post <a href="https://www.salvis.com/blog/2019/12/22/moving-to-github/">Moving to GitHub</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
