on 2012 Oct 19 2:54 AM
Hi,
I've recently found a very strange behavior on SQL Anywhere versions 11.0.1.2867 and 12.0.1.3769.
Below is a sample script to prepare for reproduction of the situation.
// 1. Create table and procedure and fill table with values. begin declare @id integer; if exists(select 1 from systable where table_name = '_test_nulls') then drop table _test_nulls end if; create table _test_nulls ( id integer primary key default autoincrement, code varchar(60) null ); create unique index idx_code ON _test_nulls(code); if exists(select 1 from sysprocedure where proc_name = '_test_nulls') then drop procedure _test_nulls end if; create procedure _test_nulls() result(id integer) begin declare @id integer; declare @code varchar(60); select min(id) into @id from _test_nulls where code = @code; select @id /* if this row is ommitted (and the row above is without 'into @id') then we have different behavior but still incorrect */ end; insert into _test_nulls (code) values (null); insert into _test_nulls (code) values (null); insert into _test_nulls (code) values (null); /* if this last row is ommitted then we have different behavior but still incorrect */ commit; end
Now we want to select data from procedure.
// 2. A few queries from the procedure that was created above. begin declare @id integer; select id into @id from _test_nulls(); message string('1. ', if @id is null then 'NULL' else 'NOT NULL' endif) to client; select id into @id from _test_nulls(); message string('2. ', if @id is null then 'NULL' else 'NOT NULL' endif) to client; select id into @id from _test_nulls(); message string('3. ', if @id is null then 'NULL' else 'NOT NULL' endif) to client; select id into @id from _test_nulls(); message string('4. ', if @id is null then 'NULL' else 'NOT NULL' endif) to client; end
Normally we should always get NULL. But that is only correct in the 1st query. All subsequent queries return NOT NULL.
If we recompile the procedure (alter procedure _test_nulls recompile) then again we get the 1st result NULL but all subsequent queries return NOT NULL.
I think this is a bug.
Request clarification before answering.
If you disable plan caching, I.e., max_query_cache=0, do you still see this issue?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I am confused now: above you said the first call returns always the expected NULL.
"Normally we should always get NULL. But that is only correct in the 1st query. All subsequent queries return NOT NULL. If we recompile the procedure (alter procedure _test_nulls recompile) then again we get the 1st result NULL but all subsequent queries return NOT NULL."
IMHO, that's no contradiction:
the first call returns always the expected NULL
In my understanding, this is the first call after creating/recompiling the procedure.
after disconnecting and connecting again the procedure returns NOT NULL even at the first call (except when it was recompiled before)
So that's another (i.e. not first) call without creating/recompiling.
I would expect the comparison where code = @code to return an unreliable response if you are specifically looking for a null. From the documentation:
The NULL value compared using any comparison operator with any value (including the NULL value) is "UNKNOWN." The only search condition that returns TRUE is the IS NULL predicate.
http://dcx.sybase.com/index.html#1201/en/dbreference/nulls.html
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
To clarify: MIN() and MAX() are documented to return NULL when applied on an empty group. You can chech this with
select min(dummy_col) from dummy where 1 = 2; -- this will return NULL select min(dummy_col) from dummy where 1 = null; -- this will also return NULL
When applying MIN(), it doesn't play a role whether the underlying result set is empty because the search condition returns FALSE (as 1 = 2) or UNKNOWN (as code = @code in Arthoor' sample).
So the expected result is not "an unreliable response" but the documented behaviour of aggregate functions and three-valued logic...
User | Count |
---|---|
82 | |
29 | |
9 | |
8 | |
7 | |
7 | |
7 | |
6 | |
6 | |
5 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.