mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
3a0d0b4ce5
In the code that converts IN predicates to EXISTS predicates it is changing the select list elements to constant 1. Example : SELECT ... FROM ... WHERE a IN (SELECT c FROM ...) is transformed to : SELECT ... FROM ... WHERE EXISTS (SELECT 1 FROM ... HAVING a = c) However there can be no FROM clause in the IN subquery and it may not be a simple select : SELECT ... FROM ... WHERE a IN (SELECT f(..) AS c UNION SELECT ...) This query is transformed to : SELECT ... FROM ... WHERE EXISTS (SELECT 1 FROM (SELECT f(..) AS c UNION SELECT ...) x HAVING a = c) In the above query c in the HAVING clause is made to be an Item_null_helper (a subclass of Item_ref) pointing to the real Item_field (which is not referenced anywhere else in the query anymore). This is done because Item_ref_null_helper collects information whether there are NULL values in the result. This is OK for directly executed statements, because the Item_field pointed by the Item_null_helper is already fixed when the transformation is done. But when executed as a prepared statement all the Item instances are "un-fixed" before the recompilation of the prepared statement. So when the Item_null_helper gets fixed it discovers that the Item_field it points to is not fixed and issues an error. The remedy is to keep the original select list references when there are no tables in the FROM clause. So the above becomes : SELECT ... FROM ... WHERE EXISTS (SELECT c FROM (SELECT f(..) AS c UNION SELECT ...) x HAVING a = c) In this way c is referenced directly in the select list as well as by reference in the HAVING clause. So it gets correctly fixed even with prepared statements. And since the Item_null_helper subclass of Item_ref_null_helper is not used anywhere else it's taken out. mysql-test/r/ps_11bugs.result: Test case for the bug mysql-test/r/subselect.result: Explain updated because of the tranformation mysql-test/t/ps_11bugs.test: Testcase for the bug sql/item.cc: Taking out Item_null_helper as it's no longer needed sql/item.h: Taking out Item_null_helper as it's no longer needed sql/item_subselect.cc: The described change to the IN->EXISTS transformation
146 lines
5.5 KiB
Text
146 lines
5.5 KiB
Text
###############################################
|
|
# #
|
|
# Prepared Statements #
|
|
# re-testing bug DB entries #
|
|
# #
|
|
# The bugs are reported as "closed". #
|
|
# Command sequences taken from bug report. #
|
|
# No other test contains the bug# as comment. #
|
|
# #
|
|
# Tests drop/create tables 't1', 't2', ... #
|
|
# #
|
|
###############################################
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
|
|
# bug#1180: optimized away part of WHERE clause cause incorect prepared satatement results
|
|
|
|
CREATE TABLE t1(session_id char(9) NOT NULL);
|
|
INSERT INTO t1 VALUES ("abc");
|
|
SELECT * FROM t1;
|
|
|
|
prepare st_1180 from 'SELECT * FROM t1 WHERE ?="1111" and session_id = "abc"';
|
|
|
|
# Must not find a row
|
|
set @arg1= 'abc';
|
|
execute st_1180 using @arg1;
|
|
|
|
# Now, it should find one row
|
|
set @arg1= '1111';
|
|
execute st_1180 using @arg1;
|
|
|
|
# Back to non-matching
|
|
set @arg1= 'abc';
|
|
execute st_1180 using @arg1;
|
|
|
|
drop table t1;
|
|
|
|
# end of bug#1180
|
|
|
|
|
|
# bug#1644: Insertion of more than 3 NULL columns with parameter binding fails
|
|
|
|
# Using prepared statements, insertion of more than three columns with NULL
|
|
# values fails to insert additional NULLS. After the third column NULLS will
|
|
# be inserted into the database as zeros.
|
|
# First insert four columns of a value (i.e. 22) to verify binding is working
|
|
# correctly. Then Bind to each columns bind parameter an is_null value of 1.
|
|
# Then insert four more columns of integers, just for sanity.
|
|
# A subsequent select on the server will result in this:
|
|
# mysql> select * from foo_dfr;
|
|
# +------+------+------+------+
|
|
# | col1 | col2 | col3 | col4 |
|
|
# +------+------+------+------+
|
|
# | 22 | 22 | 22 | 22 |
|
|
# | NULL | NULL | NULL | 0 |
|
|
# | 88 | 88 | 88 | 88 |
|
|
# +------+------+------+------+
|
|
|
|
# Test is extended to more columns - code stores bit vector in bytes.
|
|
|
|
create table t1 (
|
|
c_01 char(6), c_02 integer, c_03 real, c_04 int(3), c_05 varchar(20),
|
|
c_06 date, c_07 char(1), c_08 real, c_09 int(11), c_10 time,
|
|
c_11 char(6), c_12 integer, c_13 real, c_14 int(3), c_15 varchar(20),
|
|
c_16 date, c_17 char(1), c_18 real, c_19 int(11), c_20 text);
|
|
# Do not use "timestamp" type, because it has a non-NULL default as of 4.1.2
|
|
|
|
prepare st_1644 from 'insert into t1 values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
|
|
|
set @arg01= 'row_1'; set @arg02= 1; set @arg03= 1.1; set @arg04= 111; set @arg05= 'row_one';
|
|
set @arg06= '2004-10-12'; set @arg07= '1'; set @arg08= 1.1; set @arg09= '100100100'; set @arg10= '12:34:56';
|
|
set @arg11= 'row_1'; set @arg12= 1; set @arg13= 1.1; set @arg14= 111; set @arg15= 'row_one';
|
|
set @arg16= '2004-10-12'; set @arg17= '1'; set @arg18= 1.1; set @arg19= '100100100'; set @arg20= '12:34:56';
|
|
execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10,
|
|
@arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20;
|
|
|
|
set @arg01= NULL; set @arg02= NULL; set @arg03= NULL; set @arg04= NULL; set @arg05= NULL;
|
|
set @arg06= NULL; set @arg07= NULL; set @arg08= NULL; set @arg09= NULL; set @arg10= NULL;
|
|
set @arg11= NULL; set @arg12= NULL; set @arg13= NULL; set @arg14= NULL; set @arg15= NULL;
|
|
set @arg16= NULL; set @arg17= NULL; set @arg18= NULL; set @arg19= NULL; set @arg20= NULL;
|
|
execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10,
|
|
@arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20;
|
|
|
|
set @arg01= 'row_3'; set @arg02= 3; set @arg03= 3.3; set @arg04= 333; set @arg05= 'row_three';
|
|
set @arg06= '2004-10-12'; set @arg07= '3'; set @arg08= 3.3; set @arg09= '300300300'; set @arg10= '12:34:56';
|
|
set @arg11= 'row_3'; set @arg12= 3; set @arg13= 3.3; set @arg14= 333; set @arg15= 'row_three';
|
|
set @arg16= '2004-10-12'; set @arg17= '3'; set @arg18= 3.3; set @arg19= '300300300'; set @arg20= '12:34:56';
|
|
execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10,
|
|
@arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20;
|
|
|
|
select * from t1;
|
|
|
|
drop table t1;
|
|
|
|
# end of bug#1644
|
|
|
|
|
|
# bug#1676: Prepared statement two-table join returns no rows when one is expected
|
|
|
|
create table t1(
|
|
cola varchar(50) not null,
|
|
colb varchar(8) not null,
|
|
colc varchar(12) not null,
|
|
cold varchar(2) not null,
|
|
primary key (cola, colb, cold));
|
|
|
|
create table t2(
|
|
cola varchar(50) not null,
|
|
colb varchar(8) not null,
|
|
colc varchar(2) not null,
|
|
cold float,
|
|
primary key (cold));
|
|
|
|
insert into t1 values ('aaaa', 'yyyy', 'yyyy-dd-mm', 'R');
|
|
|
|
insert into t2 values ('aaaa', 'yyyy', 'R', 203), ('bbbb', 'zzzz', 'C', 201);
|
|
|
|
prepare st_1676 from 'select a.cola, a.colb, a.cold from t1 a, t2 b where a.cola = ? and a.colb = ? and a.cold = ? and b.cola = a.cola and b.colb = a.colb and b.colc = a.cold';
|
|
|
|
set @arg0= "aaaa";
|
|
set @arg1= "yyyy";
|
|
set @arg2= "R";
|
|
|
|
execute st_1676 using @arg0, @arg1, @arg2;
|
|
|
|
drop table t1, t2;
|
|
|
|
# end of bug#1676
|
|
|
|
# End of 4.1 tests
|
|
|
|
# bug#18492: mysqld reports ER_ILLEGAL_REFERENCE in --ps-protocol
|
|
|
|
create table t1 (a int primary key);
|
|
insert into t1 values (1);
|
|
|
|
explain select * from t1 where 3 in (select (1+1) union select 1);
|
|
|
|
select * from t1 where 3 in (select (1+1) union select 1);
|
|
|
|
prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1)';
|
|
execute st_18492;
|
|
|
|
drop table t1;
|