Commit 1da6d9f1 authored by Kristofer Pettersson's avatar Kristofer Pettersson

Auto commit

parents 2c576fa9 3345b64f
...@@ -111,3 +111,6 @@ set @a=-14632475938453979136; ...@@ -111,3 +111,6 @@ set @a=-14632475938453979136;
execute s using @a, @a; execute s using @a, @a;
ERROR HY000: Incorrect arguments to EXECUTE ERROR HY000: Incorrect arguments to EXECUTE
End of 5.0 tests End of 5.0 tests
select 1 as a limit 4294967296,10;
a
End of 5.1 tests
...@@ -99,3 +99,37 @@ kill query ...@@ -99,3 +99,37 @@ kill query
ERROR 70100: Query execution was interrupted ERROR 70100: Query execution was interrupted
unlock tables; unlock tables;
drop table t1; drop table t1;
CREATE TABLE t1 (
a int(11) unsigned default NULL,
b varchar(255) default NULL,
UNIQUE KEY a (a),
KEY b (b)
);
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
CREATE TABLE t2 SELECT * FROM t1;
CREATE TABLE t3 SELECT * FROM t1;
# test altering of columns that multiupdate doesn't use
# normal mode
# PS mode
# test altering of columns that multiupdate uses
# normal mode
# PS mode
DROP TABLE t1, t2, t3;
CREATE TABLE t1( a INT, b INT );
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
# 1. test regular tables
# 1.1. test altering of columns that multiupdate doesn't use
# 1.1.1. normal mode
# 1.1.2. PS mode
# 1.2. test altering of columns that multiupdate uses
# 1.2.1. normal mode
# 1.2.2. PS mode
ALTER TABLE t1 ADD COLUMN a INT;
# 2. test UNIONs
# 2.1. test altering of columns that multiupdate doesn't use
# 2.1.1. normal mode
# 2.1.2. PS mode
# 2.2. test altering of columns that multiupdate uses
# 2.2.1. normal mode
# 2.2.2. PS mode
DROP TABLE t1;
...@@ -181,4 +181,21 @@ c1 c2 ...@@ -181,4 +181,21 @@ c1 c2
3 3 3 3
DROP VIEW v1,v2; DROP VIEW v1,v2;
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (i INT, d DATE);
INSERT INTO t1 VALUES (1, '2008-01-01'), (2, '2008-01-02'), (3, '2008-01-03');
SELECT COALESCE(d, d), IFNULL(d, d), IF(i, d, d),
CASE i WHEN i THEN d ELSE d END, GREATEST(d, d), LEAST(d, d)
FROM t1 ORDER BY RAND();
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
2008-01-01 2008-01-01 2008-01-01 2008-01-01 2008-01-01 2008-01-01
2008-01-02 2008-01-02 2008-01-02 2008-01-02 2008-01-02 2008-01-02
2008-01-03 2008-01-03 2008-01-03 2008-01-03 2008-01-03 2008-01-03
COALESCE(d, d) IFNULL(d, d) IF(i, d, d) CASE i WHEN i THEN d ELSE d END GREATEST(d, d) LEAST(d, d)
def CASE i WHEN i THEN d ELSE d END CASE i WHEN i THEN d ELSE d END 10 10 10 Y 128 0 63
def COALESCE(d, d) COALESCE(d, d) 10 10 10 Y 128 0 63
def GREATEST(d, d) GREATEST(d, d) 10 10 10 Y 128 0 63
def IF(i, d, d) IF(i, d, d) 10 10 10 Y 128 0 63
def IFNULL(d, d) IFNULL(d, d) 10 10 10 Y 128 0 63
def LEAST(d, d) LEAST(d, d) 10 10 10 Y 128 0 63
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
...@@ -1076,3 +1076,19 @@ set session max_sort_length= 2180; ...@@ -1076,3 +1076,19 @@ set session max_sort_length= 2180;
select * from t1 order by b; select * from t1 order by b;
ERROR HY001: Out of sort memory; increase server sort buffer size ERROR HY001: Out of sort memory; increase server sort buffer size
drop table t1; drop table t1;
#
# Bug #39844: Query Crash Mysql Server 5.0.67
#
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT PRIMARY KEY, b INT);
CREATE TABLE t3 (c INT);
INSERT INTO t1 (a) VALUES (1), (2);
INSERT INTO t2 (a,b) VALUES (1,2), (2,3);
INSERT INTO t3 (c) VALUES (1), (2);
SELECT
(SELECT t1.a FROM t1, t2 WHERE t1.a = t2.b AND t2.a = t3.c ORDER BY t1.a)
FROM t3;
(SELECT t1.a FROM t1, t2 WHERE t1.a = t2.b AND t2.a = t3.c ORDER BY t1.a)
2
NULL
DROP TABLE t1, t2, t3;
...@@ -6672,6 +6672,19 @@ select substr(`str`, `pos`+ 1 ) into `str`; ...@@ -6672,6 +6672,19 @@ select substr(`str`, `pos`+ 1 ) into `str`;
end $ end $
call `p2`('s s s s s s'); call `p2`('s s s s s s');
drop procedure `p2`; drop procedure `p2`;
drop table if exists t1;
drop procedure if exists p1;
create procedure p1() begin select * from t1; end$
call p1$
ERROR 42S02: Table 'test.t1' doesn't exist
create table t1 (a integer)$
call p1$
a
alter table t1 add b integer;
call p1$
a
drop table t1;
drop procedure p1;
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# -- End of 5.0 tests # -- End of 5.0 tests
# ------------------------------------------------------------------ # ------------------------------------------------------------------
...@@ -779,4 +779,20 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0); ...@@ -779,4 +779,20 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
1 1
1 1
DROP TABLE t1, t2; DROP TABLE t1, t2;
CREATE TABLE t1 (
pk INT PRIMARY KEY,
int_key INT,
varchar_key VARCHAR(5) UNIQUE,
varchar_nokey VARCHAR(5)
);
INSERT INTO t1 VALUES (9, 7,NULL,NULL), (10,8,'p' ,'p');
SELECT varchar_nokey
FROM t1
WHERE NULL NOT IN (
SELECT INNR.pk FROM t1 AS INNR2
LEFT JOIN t1 AS INNR ON ( INNR2.int_key = INNR.int_key )
WHERE INNR.varchar_key > 'n{'
);
varchar_nokey
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
...@@ -18,4 +18,5 @@ EXPLAIN SELECT * FROM t1 WHERE b = (SELECT max(2)); ...@@ -18,4 +18,5 @@ EXPLAIN SELECT * FROM t1 WHERE b = (SELECT max(2));
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
DROP TABLE t1;
End of 5.0 tests. End of 5.0 tests.
...@@ -95,3 +95,11 @@ set @a=-14632475938453979136; ...@@ -95,3 +95,11 @@ set @a=-14632475938453979136;
execute s using @a, @a; execute s using @a, @a;
--echo End of 5.0 tests --echo End of 5.0 tests
#
# Bug#37075: offset of limit clause might be truncated to 0 on 32-bits server w/o big tables
#
select 1 as a limit 4294967296,10;
--echo End of 5.1 tests
...@@ -281,4 +281,325 @@ unlock tables; ...@@ -281,4 +281,325 @@ unlock tables;
connection default; connection default;
drop table t1; drop table t1;
#
# Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
# ``FLUSH TABLES WITH READ LOCK''
#
--connection default
CREATE TABLE t1 (
a int(11) unsigned default NULL,
b varchar(255) default NULL,
UNIQUE KEY a (a),
KEY b (b)
);
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
CREATE TABLE t2 SELECT * FROM t1;
CREATE TABLE t3 SELECT * FROM t1;
--echo # test altering of columns that multiupdate doesn't use
--echo # normal mode
--disable_query_log
let $i = 100;
while ($i) {
--dec $i
--connection writer
send UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a)
SET a = NULL WHERE t1.b <> t2.b;
--connection locker
ALTER TABLE t2 ADD COLUMN (c INT);
ALTER TABLE t2 DROP COLUMN c;
--connection writer
--reap
}
--echo # PS mode
--connection writer
PREPARE stmt FROM 'UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a)
SET a = NULL WHERE t1.b <> t2.b';
let $i = 100;
while ($i) {
--dec $i
--connection writer
--send EXECUTE stmt
--connection locker
ALTER TABLE t2 ADD COLUMN (c INT);
ALTER TABLE t2 DROP COLUMN c;
--connection writer
--reap
}
--enable_query_log
--echo # test altering of columns that multiupdate uses
--echo # normal mode
--connection default
--disable_query_log
let $i = 100;
while ($i) {
dec $i;
--connection locker
--error 0,1060
ALTER TABLE t2 ADD COLUMN a int(11) unsigned default NULL;
UPDATE t2 SET a=b;
--connection writer
--send UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a) SET a = NULL WHERE t1.b <> t2.b
--connection locker
--error 0,1091
ALTER TABLE t2 DROP COLUMN a;
--connection writer
--error 0,1054
--reap
}
--enable_query_log
--echo # PS mode
--disable_query_log
let $i = 100;
while ($i) {
dec $i;
--connection locker
--error 0,1060
ALTER TABLE t2 ADD COLUMN a int(11) unsigned default NULL;
UPDATE t2 SET a=b;
--connection writer
PREPARE stmt FROM 'UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a) SET a = NULL WHERE t1.b <> t2.b';
--send EXECUTE stmt
--connection locker
--error 0,1091
ALTER TABLE t2 DROP COLUMN a;
--connection writer
--error 0,1054
--reap
}
--enable_query_log
--connection default
DROP TABLE t1, t2, t3;
#
# Bug#38499: flush tables and multitable table update with derived table cause
# crash
#
CREATE TABLE t1( a INT, b INT );
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
--echo # 1. test regular tables
--echo # 1.1. test altering of columns that multiupdate doesn't use
--echo # 1.1.1. normal mode
--disable_query_log
let $i = 100;
while ($i) {
--dec $i
--connection writer
send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
--connection locker
ALTER TABLE t1 ADD COLUMN (c INT);
ALTER TABLE t1 DROP COLUMN c;
--connection writer
--reap
}
--echo # 1.1.2. PS mode
--connection writer
PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
let $i = 100;
while ($i) {
--dec $i
--connection writer
--send EXECUTE stmt
--connection locker
ALTER TABLE t1 ADD COLUMN (c INT);
ALTER TABLE t1 DROP COLUMN c;
--connection writer
--reap
}
--enable_query_log
--echo # 1.2. test altering of columns that multiupdate uses
--echo # 1.2.1. normal mode
--connection default
--disable_query_log
let $i = 100;
while ($i) {
dec $i;
--connection locker
--error 0,1060
ALTER TABLE t1 ADD COLUMN a int(11) unsigned default NULL;
UPDATE t1 SET a=b;
--connection writer
--send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
--connection locker
--error 0,1091
ALTER TABLE t1 DROP COLUMN a;
--connection writer
--error 0,1054 # unknown column error
--reap
}
--enable_query_log
--echo # 1.2.2. PS mode
--disable_query_log
let $i = 100;
while ($i) {
dec $i;
--connection locker
--error 0,1060
ALTER TABLE t1 ADD COLUMN a INT;
UPDATE t1 SET a=b;
--connection writer
PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
--send EXECUTE stmt
--connection locker
--error 0,1091
ALTER TABLE t1 DROP COLUMN a;
--connection writer
--error 0,1054 # Unknown column 'a' in 'field list'
--reap
}
--enable_query_log
--connection default
ALTER TABLE t1 ADD COLUMN a INT;
--echo # 2. test UNIONs
--echo # 2.1. test altering of columns that multiupdate doesn't use
--echo # 2.1.1. normal mode
--disable_query_log
let $i = 100;
while ($i) {
--dec $i
--connection writer
send UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0;
--connection locker
ALTER TABLE t1 ADD COLUMN (c INT);
ALTER TABLE t1 DROP COLUMN c;
--connection writer
--reap
}
--echo # 2.1.2. PS mode
--connection writer
PREPARE stmt FROM 'UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0';
let $i = 100;
while ($i) {
--dec $i
--connection writer
--send EXECUTE stmt
--connection locker
ALTER TABLE t1 ADD COLUMN (c INT);
ALTER TABLE t1 DROP COLUMN c;
--connection writer
--reap
}
--enable_query_log
--echo # 2.2. test altering of columns that multiupdate uses
--echo # 2.2.1. normal mode
--connection default
--disable_query_log
let $i = 100;
while ($i) {
dec $i;
--connection locker
--error 0,1060
ALTER TABLE t1 ADD COLUMN a int(11) unsigned default NULL;
UPDATE t1 SET a=b;
--connection writer
--send UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0;
--connection locker
--error 0,1091
ALTER TABLE t1 DROP COLUMN a;
--connection writer
--error 0,1054 # Unknown column 'a' in 'field list'
--reap
}
--enable_query_log
--echo # 2.2.2. PS mode
--disable_query_log
let $i = 100;
while ($i) {
dec $i;
--connection locker
--error 0,1060
ALTER TABLE t1 ADD COLUMN a INT;
UPDATE t1 SET a=b;
--connection writer
PREPARE stmt FROM 'UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0';
--send EXECUTE stmt
--connection locker
--error 0,1091
ALTER TABLE t1 DROP COLUMN a;
--connection writer
--error 0,1054 # Unknown column 'a' in 'field list'
--reap
}
--enable_query_log
--connection default
DROP TABLE t1;
# End of 5.0 tests # End of 5.0 tests
...@@ -112,4 +112,21 @@ SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1 ORDER BY v2.c2; ...@@ -112,4 +112,21 @@ SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1 ORDER BY v2.c2;
DROP VIEW v1,v2; DROP VIEW v1,v2;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug #39283: Date returned as VARBINARY to client for queries
# with COALESCE and JOIN
#
CREATE TABLE t1 (i INT, d DATE);
INSERT INTO t1 VALUES (1, '2008-01-01'), (2, '2008-01-02'), (3, '2008-01-03');
--enable_metadata
--sorted_result
SELECT COALESCE(d, d), IFNULL(d, d), IF(i, d, d),
CASE i WHEN i THEN d ELSE d END, GREATEST(d, d), LEAST(d, d)
FROM t1 ORDER BY RAND(); # force filesort
--disable_metadata
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -738,3 +738,21 @@ set session max_sort_length= 2180; ...@@ -738,3 +738,21 @@ set session max_sort_length= 2180;
select * from t1 order by b; select * from t1 order by b;
drop table t1; drop table t1;
--echo #
--echo # Bug #39844: Query Crash Mysql Server 5.0.67
--echo #
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT PRIMARY KEY, b INT);
CREATE TABLE t3 (c INT);
INSERT INTO t1 (a) VALUES (1), (2);
INSERT INTO t2 (a,b) VALUES (1,2), (2,3);
INSERT INTO t3 (c) VALUES (1), (2);
SELECT
(SELECT t1.a FROM t1, t2 WHERE t1.a = t2.b AND t2.a = t3.c ORDER BY t1.a)
FROM t3;
DROP TABLE t1, t2, t3;
...@@ -7836,6 +7836,28 @@ delimiter ;$ ...@@ -7836,6 +7836,28 @@ delimiter ;$
call `p2`('s s s s s s'); call `p2`('s s s s s s');
drop procedure `p2`; drop procedure `p2`;
#
# Bug#38823: Invalid memory access when a SP statement does wildcard expansion
#
--disable_warnings
drop table if exists t1;
drop procedure if exists p1;
--enable_warnings
delimiter $;
create procedure p1() begin select * from t1; end$
--error ER_NO_SUCH_TABLE
call p1$
create table t1 (a integer)$
call p1$
alter table t1 add b integer;
call p1$
delimiter ;$
drop table t1;
drop procedure p1;
--echo # ------------------------------------------------------------------ --echo # ------------------------------------------------------------------
--echo # -- End of 5.0 tests --echo # -- End of 5.0 tests
--echo # ------------------------------------------------------------------ --echo # ------------------------------------------------------------------
...@@ -618,4 +618,26 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0); ...@@ -618,4 +618,26 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
DROP TABLE t1, t2; DROP TABLE t1, t2;
#
# Bug #37894: Assertion in init_read_record_seq in handler.h line 1444
#
CREATE TABLE t1 (
pk INT PRIMARY KEY,
int_key INT,
varchar_key VARCHAR(5) UNIQUE,
varchar_nokey VARCHAR(5)
);
INSERT INTO t1 VALUES (9, 7,NULL,NULL), (10,8,'p' ,'p');
SELECT varchar_nokey
FROM t1
WHERE NULL NOT IN (
SELECT INNR.pk FROM t1 AS INNR2
LEFT JOIN t1 AS INNR ON ( INNR2.int_key = INNR.int_key )
WHERE INNR.varchar_key > 'n{'
);
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -33,5 +33,6 @@ drop table t1; ...@@ -33,5 +33,6 @@ drop table t1;
# #
CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (1,1); CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (1,1);
EXPLAIN SELECT * FROM t1 WHERE b = (SELECT max(2)); EXPLAIN SELECT * FROM t1 WHERE b = (SELECT max(2));
DROP TABLE t1;
--echo End of 5.0 tests. --echo End of 5.0 tests.
...@@ -1758,13 +1758,16 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, ...@@ -1758,13 +1758,16 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg,
We need to copy db_name, table_name and field_name because they must We need to copy db_name, table_name and field_name because they must
be allocated in the statement memory, not in table memory (the table be allocated in the statement memory, not in table memory (the table
structure can go away and pop up again between subsequent executions structure can go away and pop up again between subsequent executions
of a prepared statement). of a prepared statement or after the close_tables_for_reopen() call
in mysql_multi_update_prepare() or due to wildcard expansion in stored
procedures).
*/ */
if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
{ {
if (db_name) if (db_name)
orig_db_name= thd->strdup(db_name); orig_db_name= thd->strdup(db_name);
if (table_name)
orig_table_name= thd->strdup(table_name); orig_table_name= thd->strdup(table_name);
if (field_name)
orig_field_name= thd->strdup(field_name); orig_field_name= thd->strdup(field_name);
/* /*
We don't restore 'name' in cleanup because it's not changed We don't restore 'name' in cleanup because it's not changed
......
...@@ -1015,7 +1015,7 @@ int QUICK_RANGE_SELECT::init() ...@@ -1015,7 +1015,7 @@ int QUICK_RANGE_SELECT::init()
if (file->inited != handler::NONE) if (file->inited != handler::NONE)
file->ha_index_or_rnd_end(); file->ha_index_or_rnd_end();
DBUG_RETURN(error= file->ha_index_init(index)); DBUG_RETURN(FALSE);
} }
......
...@@ -3617,8 +3617,21 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, ...@@ -3617,8 +3617,21 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
{ {
/* This is a base table. */ /* This is a base table. */
DBUG_ASSERT(nj_col->view_field == NULL); DBUG_ASSERT(nj_col->view_field == NULL);
DBUG_ASSERT(nj_col->table_ref->table == nj_col->table_field->table); /*
found_field= nj_col->table_field; This fix_fields is not necessary (initially this item is fixed by
the Item_field constructor; after reopen_tables the Item_func_eq
calls fix_fields on that item), it's just a check during table
reopening for columns that was dropped by the concurrent connection.
*/
if (!nj_col->table_field->fixed &&
nj_col->table_field->fix_fields(thd, (Item **)&nj_col->table_field))
{
DBUG_PRINT("info", ("column '%s' was dropped by the concurrent connection",
nj_col->table_field->name));
DBUG_RETURN(NULL);
}
DBUG_ASSERT(nj_col->table_ref->table == nj_col->table_field->field->table);
found_field= nj_col->table_field->field;
update_field_dependencies(thd, found_field, nj_col->table_ref->table); update_field_dependencies(thd, found_field, nj_col->table_ref->table);
} }
...@@ -4450,7 +4463,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, ...@@ -4450,7 +4463,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
const char *field_name_1; const char *field_name_1;
/* true if field_name_1 is a member of using_fields */ /* true if field_name_1 is a member of using_fields */
bool is_using_column_1; bool is_using_column_1;
if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1))) if (!(nj_col_1= it_1.get_or_create_column_ref(thd, leaf_1)))
goto err; goto err;
field_name_1= nj_col_1->name(); field_name_1= nj_col_1->name();
is_using_column_1= using_fields && is_using_column_1= using_fields &&
...@@ -4471,7 +4484,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, ...@@ -4471,7 +4484,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
{ {
Natural_join_column *cur_nj_col_2; Natural_join_column *cur_nj_col_2;
const char *cur_field_name_2; const char *cur_field_name_2;
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(leaf_2))) if (!(cur_nj_col_2= it_2.get_or_create_column_ref(thd, leaf_2)))
goto err; goto err;
cur_field_name_2= cur_nj_col_2->name(); cur_field_name_2= cur_nj_col_2->name();
DBUG_PRINT ("info", ("cur_field_name_2=%s.%s", DBUG_PRINT ("info", ("cur_field_name_2=%s.%s",
...@@ -4957,15 +4970,24 @@ static bool setup_natural_join_row_types(THD *thd, ...@@ -4957,15 +4970,24 @@ static bool setup_natural_join_row_types(THD *thd,
TABLE_LIST *left_neighbor; TABLE_LIST *left_neighbor;
/* Table reference to the right of the current. */ /* Table reference to the right of the current. */
TABLE_LIST *right_neighbor= NULL; TABLE_LIST *right_neighbor= NULL;
bool save_first_natural_join_processing=
context->select_lex->first_natural_join_processing;
context->select_lex->first_natural_join_processing= FALSE;
/* Note that tables in the list are in reversed order */ /* Note that tables in the list are in reversed order */
for (left_neighbor= table_ref_it++; left_neighbor ; ) for (left_neighbor= table_ref_it++; left_neighbor ; )
{ {
table_ref= left_neighbor; table_ref= left_neighbor;
left_neighbor= table_ref_it++; left_neighbor= table_ref_it++;
/* For stored procedures do not redo work if already done. */ /*
if (context->select_lex->first_execution) Do not redo work if already done:
1) for stored procedures,
2) for multitable update after lock failure and table reopening.
*/
if (save_first_natural_join_processing)
{ {
context->select_lex->first_natural_join_processing= FALSE;
if (store_top_level_join_columns(thd, table_ref, if (store_top_level_join_columns(thd, table_ref,
left_neighbor, right_neighbor)) left_neighbor, right_neighbor))
return TRUE; return TRUE;
......
...@@ -1205,6 +1205,7 @@ void st_select_lex::init_query() ...@@ -1205,6 +1205,7 @@ void st_select_lex::init_query()
subquery_in_having= explicit_limit= 0; subquery_in_having= explicit_limit= 0;
is_item_list_lookup= 0; is_item_list_lookup= 0;
first_execution= 1; first_execution= 1;
first_natural_join_processing= 1;
first_cond_optimization= 1; first_cond_optimization= 1;
parsing_place= NO_MATTER; parsing_place= NO_MATTER;
exclude_from_table_unique_test= no_wrap_view_item= FALSE; exclude_from_table_unique_test= no_wrap_view_item= FALSE;
...@@ -2040,12 +2041,26 @@ st_lex::copy_db_to(char **p_db, uint *p_db_length) const ...@@ -2040,12 +2041,26 @@ st_lex::copy_db_to(char **p_db, uint *p_db_length) const
void st_select_lex_unit::set_limit(SELECT_LEX *sl) void st_select_lex_unit::set_limit(SELECT_LEX *sl)
{ {
ha_rows select_limit_val; ha_rows select_limit_val;
ulonglong val;
DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare()); DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare());
select_limit_val= (ha_rows)(sl->select_limit ? sl->select_limit->val_uint() : val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
HA_POS_ERROR); select_limit_val= (ha_rows)val;
offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() : #ifndef BIG_TABLES
ULL(0)); /*
Check for overflow : ha_rows can be smaller then ulonglong if
BIG_TABLES is off.
*/
if (val != (ulonglong)select_limit_val)
select_limit_val= HA_POS_ERROR;
#endif
val= sl->offset_limit ? sl->offset_limit->val_uint() : ULL(0);
offset_limit_cnt= (ha_rows)val;
#ifndef BIG_TABLES
/* Check for truncation. */
if (val != (ulonglong)offset_limit_cnt)
offset_limit_cnt= HA_POS_ERROR;
#endif
select_limit_cnt= select_limit_val + offset_limit_cnt; select_limit_cnt= select_limit_val + offset_limit_cnt;
if (select_limit_cnt < select_limit_val) if (select_limit_cnt < select_limit_val)
select_limit_cnt= HA_POS_ERROR; // no limit select_limit_cnt= HA_POS_ERROR; // no limit
......
...@@ -586,6 +586,7 @@ public: ...@@ -586,6 +586,7 @@ public:
case of an error during prepare the PS is not created. case of an error during prepare the PS is not created.
*/ */
bool first_execution; bool first_execution;
bool first_natural_join_processing;
bool first_cond_optimization; bool first_cond_optimization;
/* do not wrap view fields with Item_ref */ /* do not wrap view fields with Item_ref */
bool no_wrap_view_item; bool no_wrap_view_item;
......
...@@ -6574,6 +6574,7 @@ only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables) ...@@ -6574,6 +6574,7 @@ only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
{ {
if (specialflag & SPECIAL_SAFE_MODE) if (specialflag & SPECIAL_SAFE_MODE)
return 0; // skip this optimize /* purecov: inspected */ return 0; // skip this optimize /* purecov: inspected */
tables&= ~PSEUDO_TABLE_BITS;
for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1) for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
{ {
if (tables & 1 && !eq_ref_table(join, order, *tab)) if (tables & 1 && !eq_ref_table(join, order, *tab))
...@@ -8964,6 +8965,7 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, ...@@ -8964,6 +8965,7 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
*/ */
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME || if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE || type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE ||
type == MYSQL_TYPE_NEWDATE ||
type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_GEOMETRY) type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_GEOMETRY)
new_field= item->tmp_table_field_from_field_type(table); new_field= item->tmp_table_field_from_field_type(table);
/* /*
......
...@@ -399,7 +399,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -399,7 +399,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
} }
else else
{ {
DBUG_ASSERT(!thd->stmt_arena->is_conventional());
/* /*
We're in execution of a prepared statement or stored procedure: We're in execution of a prepared statement or stored procedure:
reset field items to point at fields from the created temporary table. reset field items to point at fields from the created temporary table.
......
...@@ -852,11 +852,14 @@ reopen_tables: ...@@ -852,11 +852,14 @@ reopen_tables:
} }
/* now lock and fill tables */ /* now lock and fill tables */
if (lock_tables(thd, table_list, table_count, &need_reopen)) if (!thd->stmt_arena->is_stmt_prepare() &&
lock_tables(thd, table_list, table_count, &need_reopen))
{ {
if (!need_reopen) if (!need_reopen)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
DBUG_PRINT("info", ("lock_tables failed, reopening"));
/* /*
We have to reopen tables since some of them were altered or dropped We have to reopen tables since some of them were altered or dropped
during lock_tables() or something was done with their triggers. during lock_tables() or something was done with their triggers.
...@@ -872,6 +875,34 @@ reopen_tables: ...@@ -872,6 +875,34 @@ reopen_tables:
for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global) for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
tbl->cleanup_items(); tbl->cleanup_items();
/*
To not to hog memory (as a result of the
unit->reinit_exec_mechanism() call below):
*/
lex->unit.cleanup();
for (SELECT_LEX *sl= lex->all_selects_list;
sl;
sl= sl->next_select_in_list())
{
SELECT_LEX_UNIT *unit= sl->master_unit();
unit->reinit_exec_mechanism(); // reset unit->prepared flags
/*
Reset 'clean' flag back to force normal execution of
unit->cleanup() in Prepared_statement::cleanup_stmt()
(call to lex->unit.cleanup() above sets this flag to TRUE).
*/
unit->unclean();
}
/*
Also we need to cleanup Natural_join_column::table_field items.
To not to traverse a join tree we will cleanup whole
thd->free_list (in PS execution mode that list may not contain
items from 'fields' list, so the cleanup above is necessary to.
*/
cleanup_items(thd->free_list);
close_tables_for_reopen(thd, &table_list); close_tables_for_reopen(thd, &table_list);
goto reopen_tables; goto reopen_tables;
} }
......
...@@ -2191,7 +2191,7 @@ TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find) ...@@ -2191,7 +2191,7 @@ TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
} }
/* /*
cleunup items belonged to view fields translation table cleanup items belonged to view fields translation table
SYNOPSIS SYNOPSIS
TABLE_LIST::cleanup_items() TABLE_LIST::cleanup_items()
...@@ -2637,10 +2637,10 @@ Natural_join_column::Natural_join_column(Field_translator *field_param, ...@@ -2637,10 +2637,10 @@ Natural_join_column::Natural_join_column(Field_translator *field_param,
} }
Natural_join_column::Natural_join_column(Field *field_param, Natural_join_column::Natural_join_column(Item_field *field_param,
TABLE_LIST *tab) TABLE_LIST *tab)
{ {
DBUG_ASSERT(tab->table == field_param->table); DBUG_ASSERT(tab->table == field_param->field->table);
table_field= field_param; table_field= field_param;
view_field= NULL; view_field= NULL;
table_ref= tab; table_ref= tab;
...@@ -2668,7 +2668,7 @@ Item *Natural_join_column::create_item(THD *thd) ...@@ -2668,7 +2668,7 @@ Item *Natural_join_column::create_item(THD *thd)
return create_view_field(thd, table_ref, &view_field->item, return create_view_field(thd, table_ref, &view_field->item,
view_field->name); view_field->name);
} }
return new Item_field(thd, &thd->lex->current_select->context, table_field); return table_field;
} }
...@@ -2679,7 +2679,7 @@ Field *Natural_join_column::field() ...@@ -2679,7 +2679,7 @@ Field *Natural_join_column::field()
DBUG_ASSERT(table_field == NULL); DBUG_ASSERT(table_field == NULL);
return NULL; return NULL;
} }
return table_field; return table_field->field;
} }
...@@ -2811,7 +2811,7 @@ void Field_iterator_natural_join::next() ...@@ -2811,7 +2811,7 @@ void Field_iterator_natural_join::next()
cur_column_ref= column_ref_it++; cur_column_ref= column_ref_it++;
DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field || DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
cur_column_ref->table_ref->table == cur_column_ref->table_ref->table ==
cur_column_ref->table_field->table); cur_column_ref->table_field->field->table);
} }
...@@ -2975,7 +2975,7 @@ GRANT_INFO *Field_iterator_table_ref::grant() ...@@ -2975,7 +2975,7 @@ GRANT_INFO *Field_iterator_table_ref::grant()
*/ */
Natural_join_column * Natural_join_column *
Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref) Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_table_ref)
{ {
Natural_join_column *nj_col; Natural_join_column *nj_col;
bool is_created= TRUE; bool is_created= TRUE;
...@@ -2988,7 +2988,11 @@ Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref) ...@@ -2988,7 +2988,11 @@ Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
{ {
/* The field belongs to a stored table. */ /* The field belongs to a stored table. */
Field *tmp_field= table_field_it.field(); Field *tmp_field= table_field_it.field();
nj_col= new Natural_join_column(tmp_field, table_ref); Item_field *tmp_item=
new Item_field(thd, &thd->lex->current_select->context, tmp_field);
if (!tmp_item)
return NULL;
nj_col= new Natural_join_column(tmp_item, table_ref);
field_count= table_ref->table->s->fields; field_count= table_ref->table->s->fields;
} }
else if (field_it == &view_field_it) else if (field_it == &view_field_it)
...@@ -3012,7 +3016,7 @@ Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref) ...@@ -3012,7 +3016,7 @@ Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
DBUG_ASSERT(nj_col); DBUG_ASSERT(nj_col);
} }
DBUG_ASSERT(!nj_col->table_field || DBUG_ASSERT(!nj_col->table_field ||
nj_col->table_ref->table == nj_col->table_field->table); nj_col->table_ref->table == nj_col->table_field->field->table);
/* /*
If the natural join column was just created add it to the list of If the natural join column was just created add it to the list of
...@@ -3077,7 +3081,7 @@ Field_iterator_table_ref::get_natural_column_ref() ...@@ -3077,7 +3081,7 @@ Field_iterator_table_ref::get_natural_column_ref()
nj_col= natural_join_it.column_ref(); nj_col= natural_join_it.column_ref();
DBUG_ASSERT(nj_col && DBUG_ASSERT(nj_col &&
(!nj_col->table_field || (!nj_col->table_field ||
nj_col->table_ref->table == nj_col->table_field->table)); nj_col->table_ref->table == nj_col->table_field->field->table));
return nj_col; return nj_col;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
class Item; /* Needed by ORDER */ class Item; /* Needed by ORDER */
class Item_subselect; class Item_subselect;
class Item_field;
class GRANT_TABLE; class GRANT_TABLE;
class st_select_lex_unit; class st_select_lex_unit;
class st_select_lex; class st_select_lex;
...@@ -469,7 +470,7 @@ class Natural_join_column: public Sql_alloc ...@@ -469,7 +470,7 @@ class Natural_join_column: public Sql_alloc
{ {
public: public:
Field_translator *view_field; /* Column reference of merge view. */ Field_translator *view_field; /* Column reference of merge view. */
Field *table_field; /* Column reference of table or temp view. */ Item_field *table_field; /* Column reference of table or temp view. */
TABLE_LIST *table_ref; /* Original base table/view reference. */ TABLE_LIST *table_ref; /* Original base table/view reference. */
/* /*
True if a common join column of two NATURAL/USING join operands. Notice True if a common join column of two NATURAL/USING join operands. Notice
...@@ -481,7 +482,7 @@ public: ...@@ -481,7 +482,7 @@ public:
bool is_common; bool is_common;
public: public:
Natural_join_column(Field_translator *field_param, TABLE_LIST *tab); Natural_join_column(Field_translator *field_param, TABLE_LIST *tab);
Natural_join_column(Field *field_param, TABLE_LIST *tab); Natural_join_column(Item_field *field_param, TABLE_LIST *tab);
const char *name(); const char *name();
Item *create_item(THD *thd); Item *create_item(THD *thd);
Field *field(); Field *field();
...@@ -899,7 +900,7 @@ public: ...@@ -899,7 +900,7 @@ public:
GRANT_INFO *grant(); GRANT_INFO *grant();
Item *create_item(THD *thd) { return field_it->create_item(thd); } Item *create_item(THD *thd) { return field_it->create_item(thd); }
Field *field() { return field_it->field(); } Field *field() { return field_it->field(); }
Natural_join_column *get_or_create_column_ref(TABLE_LIST *parent_table_ref); Natural_join_column *get_or_create_column_ref(THD *thd, TABLE_LIST *parent_table_ref);
Natural_join_column *get_natural_column_ref(); Natural_join_column *get_natural_column_ref();
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment