Commit 08eff112 authored by konstantin@mysql.com's avatar konstantin@mysql.com

Merge mysql.com:/opt/local/work/tmp_merge2

into  mysql.com:/opt/local/work/mysql-5.1-merge
parents 365c7aea d360687d
...@@ -880,3 +880,49 @@ select row_count(); ...@@ -880,3 +880,49 @@ select row_count();
row_count() row_count()
1 1
drop table t1; drop table t1;
create table t1 (a int, b int);
insert into t1 (a,b) values (2,8),(1,9),(3,7);
prepare stmt from "select * from t1 order by ?";
execute stmt using @a;
a b
2 8
1 9
3 7
set @a=1;
execute stmt using @a;
a b
1 9
2 8
3 7
set @a=2;
execute stmt using @a;
a b
3 7
2 8
1 9
deallocate prepare stmt;
select * from t1 order by 1;
a b
1 9
2 8
3 7
prepare stmt from "select * from t1 order by ?+1";
set @a=0;
execute stmt using @a;
a b
2 8
1 9
3 7
set @a=1;
execute stmt using @a;
a b
2 8
1 9
3 7
deallocate prepare stmt;
select * from t1 order by 1+1;
a b
2 8
1 9
3 7
drop table t1;
...@@ -634,10 +634,18 @@ flush tables; ...@@ -634,10 +634,18 @@ flush tables;
return 5; return 5;
end| end|
ERROR 0A000: FLUSH is not allowed in stored function or trigger ERROR 0A000: FLUSH is not allowed in stored function or trigger
create procedure bug9529_90123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123() create procedure bug9529_901234567890123456789012345678901234567890123456789012345()
begin begin
end| end|
ERROR 42000: Identifier name 'bug9529_90123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' is too long ERROR 42000: Identifier name 'bug9529_901234567890123456789012345678901234567890123456789012345' is too long
drop procedure if exists bug17015_0123456789012345678901234567890123456789012345678901234|
create procedure bug17015_0123456789012345678901234567890123456789012345678901234()
begin
end|
show procedure status like 'bug17015%'|
Db Name Type Definer Modified Created Security_type Comment
test bug17015_0123456789012345678901234567890123456789012345678901234 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
drop procedure bug17015_0123456789012345678901234567890123456789012345678901234|
drop procedure if exists bug10969| drop procedure if exists bug10969|
create procedure bug10969() create procedure bug10969()
begin begin
......
...@@ -214,3 +214,26 @@ drop function f1; ...@@ -214,3 +214,26 @@ drop function f1;
drop function f2; drop function f2;
drop function f3; drop function f3;
drop procedure sp1; drop procedure sp1;
drop table if exists t1;
drop view if exists v1, v2, v3;
drop function if exists bug15683;
create table t1 (f1 bigint, f2 varchar(20), f3 bigint);
insert into t1 set f1 = 1, f2 = 'schoenenbourg', f3 = 1;
create view v1 as select 1 from t1 union all select 1;
create view v2 as select 1 from v1;
create view v3 as select 1 as f1 from v2;
create function bug15683() returns bigint
begin
return (select count(*) from v3);
end|
prepare stmt from "select bug15683()";
execute stmt;
bug15683()
2
execute stmt;
bug15683()
2
deallocate prepare stmt;
drop table t1;
drop view v1, v2, v3;
drop function bug15683;
...@@ -4812,4 +4812,39 @@ f1 bug13575(f1) ...@@ -4812,4 +4812,39 @@ f1 bug13575(f1)
3 ccc 3 ccc
drop function bug13575; drop function bug13575;
drop table t3| drop table t3|
drop procedure if exists bug16474_1|
drop procedure if exists bug16474_2|
delete from t1|
insert into t1 values ('c', 2), ('b', 3), ('a', 1)|
create procedure bug16474_1()
begin
declare x int;
select id from t1 order by x;
end|
create procedure bug16474_2(x int)
select id from t1 order by x|
call bug16474_1()|
id
c
b
a
call bug16474_2(1)|
id
c
b
a
call bug16474_2(2)|
id
c
b
a
drop procedure bug16474_1|
drop procedure bug16474_2|
set @x = 2|
select * from t1 order by @x|
id data
c 2
b 3
a 1
delete from t1|
drop table t1,t2; drop table t1,t2;
...@@ -2,6 +2,7 @@ drop table if exists t1, t2, t3, t4; ...@@ -2,6 +2,7 @@ drop table if exists t1, t2, t3, t4;
drop view if exists v1; drop view if exists v1;
drop database if exists mysqltest; drop database if exists mysqltest;
drop function if exists f1; drop function if exists f1;
drop function if exists f2;
drop procedure if exists p1; drop procedure if exists p1;
create table t1 (i int); create table t1 (i int);
create trigger trg before insert on t1 for each row set @a:=1; create trigger trg before insert on t1 for each row set @a:=1;
...@@ -928,3 +929,26 @@ create trigger t1_bi before insert on t1 for each row return 0; ...@@ -928,3 +929,26 @@ create trigger t1_bi before insert on t1 for each row return 0;
ERROR 42000: RETURN is only allowed in a FUNCTION ERROR 42000: RETURN is only allowed in a FUNCTION
insert into t1 values (1); insert into t1 values (1);
drop table t1; drop table t1;
create table t1 (a varchar(64), b int);
create table t2 like t1;
create trigger t1_ai after insert on t1 for each row
set @a:= (select max(a) from t1);
insert into t1 (a) values
("Twas"),("brillig"),("and"),("the"),("slithy"),("toves"),
("Did"),("gyre"),("and"),("gimble"),("in"),("the"),("wabe");
create trigger t2_ai after insert on t2 for each row
set @a:= (select max(a) from t2);
insert into t2 select * from t1;
load data infile '../std_data_ln/words.dat' into table t1 (a);
drop trigger t1_ai;
drop trigger t2_ai;
create function f1() returns int return (select max(b) from t1);
insert into t1 values
("All",f1()),("mimsy",f1()),("were",f1()),("the",f1()),("borogoves",f1()),
("And",f1()),("the",f1()),("mome", f1()),("raths",f1()),("outgrabe",f1());
create function f2() returns int return (select max(b) from t2);
insert into t2 select a, f2() from t1;
load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
drop table t1;
drop function f1;
drop function f2;
...@@ -933,4 +933,38 @@ execute ins_call; ...@@ -933,4 +933,38 @@ execute ins_call;
select row_count(); select row_count();
drop table t1; drop table t1;
#
# BUG#16474: SP crashed MySQL
# (when using "order by localvar", where 'localvar' is just that.
# The actual bug test is in sp.test, this is just testing that we get the
# expected result for prepared statements too, i.e. place holders work as
# textual substitution. If it's a single integer, it works as the (deprecated)
# "order by column#", otherwise it's an expression.
#
create table t1 (a int, b int);
insert into t1 (a,b) values (2,8),(1,9),(3,7);
# Will order by index
prepare stmt from "select * from t1 order by ?";
execute stmt using @a;
set @a=1;
execute stmt using @a;
set @a=2;
execute stmt using @a;
deallocate prepare stmt;
# For reference:
select * from t1 order by 1;
# Will not order by index.
prepare stmt from "select * from t1 order by ?+1";
set @a=0;
execute stmt using @a;
set @a=1;
execute stmt using @a;
deallocate prepare stmt;
# For reference:
select * from t1 order by 1+1;
drop table t1;
# End of 5.0 tests # End of 5.0 tests
...@@ -904,12 +904,26 @@ end| ...@@ -904,12 +904,26 @@ end|
# #
# BUG#9529: Stored Procedures: No Warning on truncation of procedure name # BUG#9529: Stored Procedures: No Warning on truncation of procedure name
# during creation. # during creation.
# Note: When using utf8 for mysql.proc, this limit is much higher than before # BUG#17015: Routine name truncation not an error
# When we started using utf8 for mysql.proc, this limit appeared
# to be higher, but in reality the names were truncated.
--error ER_TOO_LONG_IDENT --error ER_TOO_LONG_IDENT
create procedure bug9529_90123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123() create procedure bug9529_901234567890123456789012345678901234567890123456789012345()
begin begin
end| end|
--disable_warnings
drop procedure if exists bug17015_0123456789012345678901234567890123456789012345678901234|
--enable_warnings
# Check the upper limit, just to make sure.
create procedure bug17015_0123456789012345678901234567890123456789012345678901234()
begin
end|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show procedure status like 'bug17015%'|
drop procedure bug17015_0123456789012345678901234567890123456789012345678901234|
# #
# BUG#10969: Stored procedures: crash if default() function # BUG#10969: Stored procedures: crash if default() function
...@@ -1717,4 +1731,3 @@ end| ...@@ -1717,4 +1731,3 @@ end|
#drop procedure if exists bugNNNN| #drop procedure if exists bugNNNN|
#--enable_warnings #--enable_warnings
#create procedure bugNNNN... #create procedure bugNNNN...
...@@ -240,3 +240,37 @@ drop function f1; ...@@ -240,3 +240,37 @@ drop function f1;
drop function f2; drop function f2;
drop function f3; drop function f3;
drop procedure sp1; drop procedure sp1;
#
# Bug#15683 "crash, Function on nested VIEWs, Prepared statement"
# Check that when creating the prelocking list a nested view
# is not merged until it's used.
#
--disable_warnings
drop table if exists t1;
drop view if exists v1, v2, v3;
drop function if exists bug15683;
--enable_warnings
create table t1 (f1 bigint, f2 varchar(20), f3 bigint);
insert into t1 set f1 = 1, f2 = 'schoenenbourg', f3 = 1;
create view v1 as select 1 from t1 union all select 1;
create view v2 as select 1 from v1;
create view v3 as select 1 as f1 from v2;
delimiter |;
create function bug15683() returns bigint
begin
return (select count(*) from v3);
end|
delimiter ;|
prepare stmt from "select bug15683()";
execute stmt;
execute stmt;
deallocate prepare stmt;
drop table t1;
drop view v1, v2, v3;
drop function bug15683;
#
# End of 5.0 tests
#
...@@ -5653,6 +5653,42 @@ select distinct f1, bug13575(f1) from t3 order by f1| ...@@ -5653,6 +5653,42 @@ select distinct f1, bug13575(f1) from t3 order by f1|
drop function bug13575; drop function bug13575;
drop table t3| drop table t3|
#
# BUG#16474: SP crashed MySQL
# (when using "order by localvar", where 'localvar' is just that.
#
--disable_warnings
drop procedure if exists bug16474_1|
drop procedure if exists bug16474_2|
--enable_warnings
delete from t1|
insert into t1 values ('c', 2), ('b', 3), ('a', 1)|
create procedure bug16474_1()
begin
declare x int;
select id from t1 order by x;
end|
# This does NOT order by column index; variable is an expression.
create procedure bug16474_2(x int)
select id from t1 order by x|
call bug16474_1()|
call bug16474_2(1)|
call bug16474_2(2)|
drop procedure bug16474_1|
drop procedure bug16474_2|
# For reference: user variables are expressions too and do not affect ordering.
set @x = 2|
select * from t1 order by @x|
delete from t1|
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
......
...@@ -7,6 +7,7 @@ drop table if exists t1, t2, t3, t4; ...@@ -7,6 +7,7 @@ drop table if exists t1, t2, t3, t4;
drop view if exists v1; drop view if exists v1;
drop database if exists mysqltest; drop database if exists mysqltest;
drop function if exists f1; drop function if exists f1;
drop function if exists f2;
drop procedure if exists p1; drop procedure if exists p1;
--enable_warnings --enable_warnings
...@@ -1080,3 +1081,36 @@ create table t1 (i int); ...@@ -1080,3 +1081,36 @@ create table t1 (i int);
create trigger t1_bi before insert on t1 for each row return 0; create trigger t1_bi before insert on t1 for each row return 0;
insert into t1 values (1); insert into t1 values (1);
drop table t1; drop table t1;
# Test for bug #17764 "Trigger crashes MyISAM table"
#
# Table was reported as crashed when it was subject table of trigger invoked
# by insert statement which was executed with enabled bulk insert mode (which
# is actually set of optimizations enabled by handler::start_bulk_insert())
# and this trigger also explicitly referenced it.
# The same problem arose when table to which bulk insert was done was also
# referenced in function called by insert statement.
create table t1 (a varchar(64), b int);
create table t2 like t1;
create trigger t1_ai after insert on t1 for each row
set @a:= (select max(a) from t1);
insert into t1 (a) values
("Twas"),("brillig"),("and"),("the"),("slithy"),("toves"),
("Did"),("gyre"),("and"),("gimble"),("in"),("the"),("wabe");
create trigger t2_ai after insert on t2 for each row
set @a:= (select max(a) from t2);
insert into t2 select * from t1;
load data infile '../std_data_ln/words.dat' into table t1 (a);
drop trigger t1_ai;
drop trigger t2_ai;
# Test that the problem for functions is fixed as well
create function f1() returns int return (select max(b) from t1);
insert into t1 values
("All",f1()),("mimsy",f1()),("were",f1()),("the",f1()),("borogoves",f1()),
("And",f1()),("the",f1()),("mome", f1()),("raths",f1()),("outgrabe",f1());
create function f2() returns int return (select max(b) from t2);
insert into t2 select a, f2() from t1;
load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
drop table t1;
drop function f1;
drop function f2;
...@@ -350,6 +350,12 @@ class Field ...@@ -350,6 +350,12 @@ class Field
/* convert decimal to longlong with overflow check */ /* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag, longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
int *err); int *err);
/* The max. number of characters */
inline uint32 char_length() const
{
return field_length / charset()->mbmaxlen;
}
friend bool reopen_table(THD *,struct st_table *,bool); friend bool reopen_table(THD *,struct st_table *,bool);
friend int cre_myisam(my_string name, register TABLE *form, uint options, friend int cre_myisam(my_string name, register TABLE *form, uint options,
ulonglong auto_increment_value); ulonglong auto_increment_value);
......
...@@ -535,7 +535,11 @@ db_create_routine(THD *thd, int type, sp_head *sp) ...@@ -535,7 +535,11 @@ db_create_routine(THD *thd, int type, sp_head *sp)
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
goto done; goto done;
} }
if (sp->m_name.length > table->field[MYSQL_PROC_FIELD_NAME]->field_length)
if (system_charset_info->cset->numchars(system_charset_info,
sp->m_name.str,
sp->m_name.str+sp->m_name.length) >
table->field[MYSQL_PROC_FIELD_NAME]->char_length())
{ {
ret= SP_BAD_IDENTIFIER; ret= SP_BAD_IDENTIFIER;
goto done; goto done;
......
...@@ -419,11 +419,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -419,11 +419,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
let's *try* to start bulk inserts. It won't necessary let's *try* to start bulk inserts. It won't necessary
start them as values_list.elements should be greater than start them as values_list.elements should be greater than
some - handler dependent - threshold. some - handler dependent - threshold.
We should not start bulk inserts if this statement uses
functions or invokes triggers since they may access
to the same table and therefore should not see its
inconsistent state created by this optimization.
So we call start_bulk_insert to perform nesessary checks on So we call start_bulk_insert to perform nesessary checks on
values_list.elements, and - if nothing else - to initialize values_list.elements, and - if nothing else - to initialize
the code to make the call of end_bulk_insert() below safe. the code to make the call of end_bulk_insert() below safe.
*/ */
if (lock_type != TL_WRITE_DELAYED) if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
table->file->start_bulk_insert(values_list.elements); table->file->start_bulk_insert(values_list.elements);
thd->no_trans_update= 0; thd->no_trans_update= 0;
...@@ -549,7 +553,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -549,7 +553,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
else else
#endif #endif
{ {
if (table->file->end_bulk_insert() && !error) if (!thd->prelocked_mode && table->file->end_bulk_insert() && !error)
{ {
table->file->print_error(my_errno,MYF(0)); table->file->print_error(my_errno,MYF(0));
error=1; error=1;
...@@ -2230,7 +2234,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -2230,7 +2234,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
lex->current_select->options|= OPTION_BUFFER_RESULT; lex->current_select->options|= OPTION_BUFFER_RESULT;
lex->current_select->join->select_options|= OPTION_BUFFER_RESULT; lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
} }
else else if (!thd->prelocked_mode)
{ {
/* /*
We must not yet prepare the result table if it is the same as one of the We must not yet prepare the result table if it is the same as one of the
...@@ -2238,6 +2242,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -2238,6 +2242,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
indexes on the result table, which may be used during the select, if it indexes on the result table, which may be used during the select, if it
is the same table (Bug #6034). Do the preparation after the select phase is the same table (Bug #6034). Do the preparation after the select phase
in select_insert::prepare2(). in select_insert::prepare2().
We won't start bulk inserts at all if this statement uses functions or
should invoke triggers since they may access to the same table too.
*/ */
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
} }
...@@ -2288,7 +2294,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -2288,7 +2294,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
int select_insert::prepare2(void) int select_insert::prepare2(void)
{ {
DBUG_ENTER("select_insert::prepare2"); DBUG_ENTER("select_insert::prepare2");
if (thd->lex->current_select->options & OPTION_BUFFER_RESULT) if (thd->lex->current_select->options & OPTION_BUFFER_RESULT &&
!thd->prelocked_mode)
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2391,6 +2398,7 @@ void select_insert::send_error(uint errcode,const char *err) ...@@ -2391,6 +2398,7 @@ void select_insert::send_error(uint errcode,const char *err)
*/ */
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
if (!thd->prelocked_mode)
table->file->end_bulk_insert(); table->file->end_bulk_insert();
/* /*
If at least one row has been inserted/modified and will stay in the table If at least one row has been inserted/modified and will stay in the table
...@@ -2447,7 +2455,7 @@ bool select_insert::send_eof() ...@@ -2447,7 +2455,7 @@ bool select_insert::send_eof()
int error,error2; int error,error2;
DBUG_ENTER("select_insert::send_eof"); DBUG_ENTER("select_insert::send_eof");
error=table->file->end_bulk_insert(); error= (!thd->prelocked_mode) ? table->file->end_bulk_insert():0;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
/* /*
...@@ -2556,6 +2564,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -2556,6 +2564,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.ignore || info.handle_duplicates != DUP_ERROR) if (info.ignore || info.handle_duplicates != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (!thd->prelocked_mode)
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
thd->no_trans_update= 0; thd->no_trans_update= 0;
thd->abort_on_warning= (!info.ignore && thd->abort_on_warning= (!info.ignore &&
......
...@@ -367,6 +367,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -367,6 +367,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (ignore || if (ignore ||
handle_duplicates == DUP_REPLACE) handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (!thd->prelocked_mode)
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
table->copy_blobs=1; table->copy_blobs=1;
...@@ -384,7 +385,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -384,7 +385,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
error= read_sep_field(thd, info, table_list, fields_vars, error= read_sep_field(thd, info, table_list, fields_vars,
set_fields, set_values, read_info, set_fields, set_values, read_info,
*enclosed, skip_lines, ignore); *enclosed, skip_lines, ignore);
if (table->file->end_bulk_insert() && !error) if (!thd->prelocked_mode && table->file->end_bulk_insert() && !error)
{ {
table->file->print_error(my_errno, MYF(0)); table->file->print_error(my_errno, MYF(0));
error= 1; error= 1;
......
...@@ -12410,7 +12410,11 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, ...@@ -12410,7 +12410,11 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
Item **select_item; /* The corresponding item from the SELECT clause. */ Item **select_item; /* The corresponding item from the SELECT clause. */
Field *from_field; /* The corresponding field from the FROM clause. */ Field *from_field; /* The corresponding field from the FROM clause. */
if (order_item->type() == Item::INT_ITEM) /*
Local SP variables may be int but are expressions, not positions.
(And they can't be used before fix_fields is called for them).
*/
if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
{ /* Order by position */ { /* Order by position */
uint count= (uint) order_item->val_int(); uint count= (uint) order_item->val_int();
if (!count || count > fields.elements) if (!count || count > fields.elements)
......
...@@ -940,6 +940,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) ...@@ -940,6 +940,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
tbl->skip_temporary= 1; tbl->skip_temporary= 1;
tbl->belong_to_view= top_view; tbl->belong_to_view= top_view;
tbl->referencing_view= table; tbl->referencing_view= table;
tbl->prelocking_placeholder= table->prelocking_placeholder;
/* /*
First we fill want_privilege with SELECT_ACL (this is needed for the First we fill want_privilege with SELECT_ACL (this is needed for the
tables which belongs to view subqueries and temporary table views, tables which belongs to view subqueries and temporary table views,
......
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