Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizer must take in account result of previous evaluation of separate values in "NOT IN( ...)"-list [CORE5850] #2200

Open
firebird-automations opened this issue Jun 20, 2018 · 1 comment

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: @pavel-zotov

Launch TRACE and then run this script:

recreate table t1(id int);
recreate table t2(id int);
recreate table t3(id int);
recreate table t4(id int);
recreate table t5(id int);

insert into t1(id) select null from rdb$types rows 11;
insert into t2(id) select null from rdb$types rows 22;
insert into t3(id) select null from rdb$types rows 33;
insert into t4(id) select null from rdb$types rows 44;
insert into t5(id) select null from rdb$types rows 55;
commit;

set list on;

select sum(id) from t1;
select sum(id) from t2 ;
select count(id) from t3;
select sum(id) from t4 ;
select sum(id) from t5 ;
------------------------------------------------------

set count on;

select 1
from rdb$database
where 0 not in (
( select sum(id) from t1 )
, ( select sum(id) from t2 )
, 1000 / (select count( id) from t3 ) ----------------------- [1 ]
, ( select sum(id) from t4 )
, ( select sum(id) from t5 )
);
quit;

Output will be:

SUM <null>
SUM <null>
COUNT 0
SUM <null>
SUM <null>

Statement failed, SQLSTATE = 22012
arithmetic exception, numeric overflow, or string truncation
-Integer divide by zero. The code attempted to divide an integer value by an integer divisor of zero.
Records affected: 0

Consider line marked as "[ 1 ]".
Why this is evaluated ?
Does not optimizer need to stop any further evaluation after get NULL in "(select sum(id) from t1) " ?

Trace shows that
1) optimizer evaluates NOT-IN list from left to right;
2) THREE tables was scanned instead on one (T1):

0 records fetched
0 ms, 79 fetch(es)

Table Natural
*******************************************
RDB$DATABASE 1
T1 11
T2 22
T3 33

PS.
This question was originally raised in discuss with dimitr, 14-JUL-2015. I remember that some optimizations related to this issue should be made in 4.0 only. But i decided to write here this because otherwise it can be forgotten.

@firebird-automations
Copy link
Collaborator Author

Modified by: @pavel-zotov

description: Launch TRACE and then run this script:

recreate table t1(id int);
recreate table t2(id int);
recreate table t3(id int);
recreate table t4(id int);
recreate table t5(id int);

insert into t1(id) select null from rdb$types rows 11;
insert into t2(id) select null from rdb$types rows 22;
insert into t3(id) select null from rdb$types rows 33;
insert into t4(id) select null from rdb$types rows 44;
insert into t5(id) select null from rdb$types rows 55;
commit;

set list on;

select sum(id) from t1;
select sum(id) from t2 ;
select count(id) from t3;
select sum(id) from t4 ;
select sum(id) from t5 ;
------------------------------------------------------

set count on;

select 1
from rdb$database
where 0 not in (
( select sum(id) from t1 )
, ( select sum(id) from t2 )
, 1000 / (select count( id) from t3 ) ----------------------- [1 ]
, ( select sum(id) from t4 )
, ( select sum(id) from t5 )
);
quit;

Output will be:

SUM <null>
SUM <null>
COUNT 0
SUM <null>
SUM <null>

Statement failed, SQLSTATE = 22012
arithmetic exception, numeric overflow, or string truncation
-Integer divide by zero. The code attempted to divide an integer value by an integer divisor of zero.
Records affected: 0

Consider line marked as "[ 1 ]".
Why this is evaluated ? Don't optimizer need to stop any further evaluation after get NULL in "(select sum(id) from t1) " ?

Trace shows that
1) optimizer evaluates NOT-IN list from left to right;
2) THREE tables was scanned instead on one (T1):

0 records fetched
0 ms, 79 fetch(es)

Table Natural
*******************************************
RDB$DATABASE 1
T1 11
T2 22
T3 33

PS.
This question was originally raised in discuss with dimitr, 14-JUL-2015. I remember that some optimizations related to this issue should be made in 4.0 only. But i decided to write here this because otherwise it can be forgotten.

=>

Launch TRACE and then run this script:

recreate table t1(id int);
recreate table t2(id int);
recreate table t3(id int);
recreate table t4(id int);
recreate table t5(id int);

insert into t1(id) select null from rdb$types rows 11;
insert into t2(id) select null from rdb$types rows 22;
insert into t3(id) select null from rdb$types rows 33;
insert into t4(id) select null from rdb$types rows 44;
insert into t5(id) select null from rdb$types rows 55;
commit;

set list on;

select sum(id) from t1;
select sum(id) from t2 ;
select count(id) from t3;
select sum(id) from t4 ;
select sum(id) from t5 ;
------------------------------------------------------

set count on;

select 1
from rdb$database
where 0 not in (
( select sum(id) from t1 )
, ( select sum(id) from t2 )
, 1000 / (select count( id) from t3 ) ----------------------- [1 ]
, ( select sum(id) from t4 )
, ( select sum(id) from t5 )
);
quit;

Output will be:

SUM <null>
SUM <null>
COUNT 0
SUM <null>
SUM <null>

Statement failed, SQLSTATE = 22012
arithmetic exception, numeric overflow, or string truncation
-Integer divide by zero. The code attempted to divide an integer value by an integer divisor of zero.
Records affected: 0

Consider line marked as "[ 1 ]".
Why this is evaluated ?
Does not optimizer need to stop any further evaluation after get NULL in "(select sum(id) from t1) " ?

Trace shows that
1) optimizer evaluates NOT-IN list from left to right;
2) THREE tables was scanned instead on one (T1):

0 records fetched
0 ms, 79 fetch(es)

Table Natural
*******************************************
RDB$DATABASE 1
T1 11
T2 22
T3 33

PS.
This question was originally raised in discuss with dimitr, 14-JUL-2015. I remember that some optimizations related to this issue should be made in 4.0 only. But i decided to write here this because otherwise it can be forgotten.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant