Commit 1b458888 authored by unknown's avatar unknown
Browse files

Merge bk-internal.mysql.com:/home/bk/mysql-5.0-runtime

into  mysql.com:/home/dlenev/mysql-5.0-bg17764


mysql-test/r/trigger.result:
  Auto merged
mysql-test/t/trigger.test:
  Auto merged
sql/sql_insert.cc:
  Auto merged
parents 53595c70 1d166b17
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ drop table if exists t1, t2, t3, t4;
drop view if exists v1;
drop database if exists mysqltest;
drop function if exists f1;
drop function if exists f2;
drop procedure if exists p1;
create table t1 (i int);
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;
ERROR 42000: RETURN is only allowed in a FUNCTION
insert into t1 values (1);
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;
+34 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ drop table if exists t1, t2, t3, t4;
drop view if exists v1;
drop database if exists mysqltest;
drop function if exists f1;
drop function if exists f2;
drop procedure if exists p1;
--enable_warnings

@@ -1080,3 +1081,36 @@ create table t1 (i int);
create trigger t1_bi before insert on t1 for each row return 0;
insert into t1 values (1);
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;
+16 −7
Original line number Diff line number Diff line
@@ -405,11 +405,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
    let's *try* to start bulk inserts. It won't necessary
    start them as values_list.elements should be greater than
    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
    values_list.elements, and - if nothing else - to initialize
    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);

  thd->no_trans_update= 0;
@@ -535,7 +539,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
  else
#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));
      error=1;
@@ -2190,7 +2194,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
    lex->current_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 
@@ -2198,6 +2202,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
      is the same table (Bug #6034). Do the preparation after the select phase
      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);
  }
@@ -2238,7 +2244,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
int select_insert::prepare2(void)
{
  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);
  DBUG_RETURN(0);
}
@@ -2341,6 +2348,7 @@ void select_insert::send_error(uint errcode,const char *err)
    */
    DBUG_VOID_RETURN;
  }
  if (!thd->prelocked_mode)
    table->file->end_bulk_insert();
  /*
    If at least one row has been inserted/modified and will stay in the table
@@ -2376,7 +2384,7 @@ bool select_insert::send_eof()
  int error,error2;
  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);

  /*
@@ -2459,6 +2467,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
  thd->cuted_fields=0;
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
  if (!thd->prelocked_mode)
    table->file->start_bulk_insert((ha_rows) 0);
  thd->no_trans_update= 0;
  thd->abort_on_warning= (!info.ignore &&
+3 −2
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
    if (ignore ||
	handle_duplicates == DUP_REPLACE)
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
    if (!thd->prelocked_mode)
      table->file->start_bulk_insert((ha_rows) 0);
    table->copy_blobs=1;

@@ -373,7 +374,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
      error= read_sep_field(thd, info, table_list, fields_vars,
                            set_fields, set_values, read_info,
			    *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));
      error= 1;