<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Question Re: NULL equals NULL oddity in Technology Q&amp;A</title>
    <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844258#M4875101</link>
    <description>&lt;P&gt;But is it expected behaviour that plans are cached for non-deterministic functions?&lt;/P&gt;</description>
    <pubDate>Wed, 15 Nov 2017 16:58:11 GMT</pubDate>
    <dc:creator>VolkerBarth</dc:creator>
    <dc:date>2017-11-15T16:58:11Z</dc:date>
    <item>
      <title>NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaq-p/13844252</link>
      <description>&lt;P&gt;User defined functions seem to be believing that NULL = NULL after being called multiple times. &lt;/P&gt;
&lt;P&gt;I can reproduce this in all the builds of v16 I can find (including 2546), different windows versions, machines etc. The ANSINULL database option is ON (the default).&lt;/P&gt;
&lt;P&gt;Run this script in isql:
&lt;/P&gt;&lt;PRE&gt;CREATE TABLE Test1 (PK CHAR(20) NOT NULL, Col CHAR(12) NULL, PRIMARY KEY ( PK ASC ));&lt;P&gt;&lt;/P&gt;
&lt;P&gt;insert into Test1 (PK) values ('Blah1');
commit;&lt;/P&gt;
&lt;P&gt;CREATE INDEX Test1_Col ON Test1 ( Col ASC );&lt;/P&gt;
&lt;P&gt;create or replace FUNCTION TestFn (in val char(12)) returns char(20) NOT DETERMINISTIC
begin
  declare rv char(20);
  select first PK into rv from Test1 where Col = val;
  return(rv);
end;
&lt;/P&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;
&lt;P&gt;If you run this query:&lt;/P&gt;
&lt;PRE&gt;select TestFn(null);&lt;/PRE&gt;

&lt;P&gt;the first 10 times it produces the correct result, "NULL", since NULL should not equate to NULL. After that it matches the first record it finds - in this case there's only one record so you get 'Blah1' (ie it matches NULL = NULL).&lt;/P&gt;
&lt;P&gt;This is as stripped down as I can get the reproducible (the original was spotted in a far more complex situation). You have to use a function, running a straight SELECT in isql does not have issues. The index appears to be the key - no index and everything works fine. &lt;/P&gt;
&lt;P&gt;Different queries seem to fail after 10 calls, the number of records in the table doesn't seem relevant either - the example above with 20000 records still fails on the eleventh go.&lt;/P&gt;
&lt;P&gt;Data type doesn't seem relevant either, the above example works the same with Col as char, int or date.&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 09:31:35 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaq-p/13844252</guid>
      <dc:creator>justin_willey</dc:creator>
      <dc:date>2017-11-15T09:31:35Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844254#M4875097</link>
      <description>&lt;P&gt;How do you call the function - within DBISQL? Does it differ if you "consume" the return value, say by storing it in a table or summing it up? I remember cases where DBISQL ignored/skipped repeated calls... Just very wild guessing...&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 10:05:34 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844254#M4875097</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-11-15T10:05:34Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844255#M4875098</link>
      <description>&lt;P&gt;Reference:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://sqlanywhere-forum.sap.com/questions/25326/may-dbisql-skip-select-statements-in-a-sql-batch-part-ii"&gt;http://sqlanywhere-forum.sap.com/questions/25326/may-dbisql-skip-select-statements-in-a-sql-batch-part-ii&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 10:10:31 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844255#M4875098</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-11-15T10:10:31Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844256#M4875099</link>
      <description>&lt;P&gt;I'm testing in isql but it happens if you call it in other ways. For example this function &lt;/P&gt;&lt;PRE&gt;create or replace function test1(@tests int default 20)
returns char(250)
BEGIN
declare @Result char(250);
declare @counter int default 1;
while @counter &amp;lt;= @tests loop
    set @Result = string(@Result,' : ',@Counter,'-',(select TestFn(null)));
    set @counter=@counter+1;
    message @Counter;
end loop;
return @Result;
end;
&lt;/PRE&gt; &lt;P&gt;&lt;/P&gt;
&lt;P&gt;Then running select test1(20), gives:&lt;/P&gt;&lt;PRE&gt; : 1- : 2- : 3- : 4- : 5- : 6- : 7- : 8- : 9- : 10- : 11-Blah1 : 12-Blah1 : 13-Blah1 : 14-Blah1 : 15-Blah1 : 16-Blah1 : 17-Blah1 : 18-Blah1 : 19-Blah1 : 20-Blah1&lt;/PRE&gt; showing the result changes after the tenth run.&lt;P&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 11:06:06 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844256#M4875099</guid>
      <dc:creator>justin_willey</dc:creator>
      <dc:date>2017-11-15T11:06:06Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844257#M4875100</link>
      <description>&lt;P&gt;Does (client) plan caching play a role here?&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 14:26:48 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844257#M4875100</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-11-15T14:26:48Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844253#M4875096</link>
      <description>&lt;P&gt;Thanks for reporting this.  I've confirmed that this is indeed a bug with plan caching, as Volker suggested.  In v16, plans for statements in procedures are built for 10 training executions and a reusable plan built on the 11th execution.  The reusable plan that is being built on the 11th iteration appears to be semantically incorrect for an equality predicate on a nullable column that uses an index---I'm currently investigating why.  In v17 the semantic incorrectness bug still exists, but the logic for deciding when to cache plans has changed which makes the repro less deterministic.&lt;/P&gt;
&lt;P&gt;As a workaround, you should disable plan caching by setting option max_plans_cached=0 at the connection, user, or database level.&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 16:55:42 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844253#M4875096</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2017-11-15T16:55:42Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844258#M4875101</link>
      <description>&lt;P&gt;But is it expected behaviour that plans are cached for non-deterministic functions?&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 16:58:11 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844258#M4875101</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-11-15T16:58:11Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844259#M4875102</link>
      <description>&lt;P&gt;Thanks David - that's great to have that pinned down.&lt;/P&gt;
&lt;P&gt;I think we can protect against the problem in most cases with "AND whatever IS NOT NULL" so long as we can identify where we are relying on NULLS not matching. If you find out when the issue first arose, that would be useful to know.&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 18:35:55 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844259#M4875102</guid>
      <dc:creator>justin_willey</dc:creator>
      <dc:date>2017-11-15T18:35:55Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844260#M4875103</link>
      <description>&lt;P&gt;Yes and no.&lt;/P&gt;
&lt;P&gt;When functions are marked as NOT DETERMINISTIC, the optimizer will not cache plans for the FUNCTION CALL---i.e. it impacts optimization of statements that REFERENCE expressions marked as non-deterministic.&lt;/P&gt;
&lt;P&gt;In this case, the plan being cached is for a statement within the function definition itself.  The execution of statements WITHIN the function are not impacted by the NOT DETERMINISTIC keyword.  Granted, in this particular function it is the query itself that is the source of the non-determinism due to the FIRST keyword without an ORDER BY.  Once we cache a particular plan, the query execution will be deterministic as long as we are running that cached plan.  However, that is acceptable because the NOT DETERMINISTIC keyword is essentially a warning that execution MAY be non-deterministic---not a promise that it will be.&lt;/P&gt;</description>
      <pubDate>Thu, 16 Nov 2017 08:34:05 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844260#M4875103</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2017-11-16T08:34:05Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844261#M4875104</link>
      <description>&lt;P&gt;Thanks for the detailed explanation, highly appreciated!&lt;/P&gt;</description>
      <pubDate>Thu, 16 Nov 2017 09:28:24 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844261#M4875104</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-11-16T09:28:24Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844262#M4875105</link>
      <description>&lt;P&gt;The bug is specific to reusable plans built by the optimizer bypass, so another workaround is to use HINT(FORCE OPTIMIZATION) to disable the optimizer bypass (and plan caching) for specific statements.&lt;/P&gt;
&lt;P&gt;From a few simple experiments, I've reproduced the bug in v11.0.1 GA (early 2009) but not in v10.0.1.4157 (although it's possible it was present in v10 but with different repro conditions).&lt;/P&gt;</description>
      <pubDate>Thu, 16 Nov 2017 11:56:34 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844262#M4875105</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2017-11-16T11:56:34Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844263#M4875106</link>
      <description>&lt;P&gt;Thank you David, that's very helpful indeed. It means that the effect on us must be pretty limited or we would have seen it elsewhere in the last 10 years! We can protect against it in the couple of places we know are vulnerable and wait for the ebf.&lt;/P&gt;</description>
      <pubDate>Thu, 16 Nov 2017 15:17:54 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844263#M4875106</guid>
      <dc:creator>justin_willey</dc:creator>
      <dc:date>2017-11-16T15:17:54Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844264#M4875107</link>
      <description>&lt;P&gt;The fix for this bug has been submitted to the v16 (build 2606+) and v17 (build 4104+) codelines and should appear in future ebfs exceeding those build numbers.&lt;/P&gt;</description>
      <pubDate>Fri, 24 Nov 2017 16:40:22 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844264#M4875107</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2017-11-24T16:40:22Z</dc:date>
    </item>
    <item>
      <title>Re: NULL equals NULL oddity</title>
      <link>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844265#M4875108</link>
      <description>&lt;P&gt;Many thanks David, for the swift action on this one.&lt;/P&gt;</description>
      <pubDate>Sun, 26 Nov 2017 19:51:42 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/null-equals-null-oddity/qaa-p/13844265#M4875108</guid>
      <dc:creator>justin_willey</dc:creator>
      <dc:date>2017-11-26T19:51:42Z</dc:date>
    </item>
  </channel>
</rss>

