List:Commits« Previous MessageNext Message »
From:dlenev Date:June 20 2006 8:37pm
Subject:bk commit into 5.0 tree (dlenev:1.2187) BUG#18437
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of dlenev. When dlenev does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2187 06/06/21 00:36:53 dlenev@stripped +3 -0
  Fix for bug#19634 "Re-execution of multi-delete which involve trigger/stored
  function crashes server" which was exposed by tests for bug#18437.
  
  Attempts to execute prepared multi-delete statement which involved trigger or
  stored function caused server crashes (the same happened for such statements
  included in stored procedures in cases when one tried to execute them more
  than once).
  
  The problem was caused by yet another incorrect usage of check_table_access()
  routine (the latter assumes that table list which it gets as argument
  corresponds to value LEX::query_tables_own_last). We solve this problem by
  juggling with LEX::query_tables_own_last value when we call
  check_table_access() for LEX::auxilliary_table_list (better solution is too
  intrusive and should be done in 5.1).

  sql/sql_parse.cc
    1.551 06/06/21 00:36:47 dlenev@stripped +36 -4
    To call safely check_table_access() for LEX::auxilliary_table_list we have
    to juggle with LEX::query_tables_own_last value.

  mysql-test/t/sp-prelocking.test
    1.5 06/06/21 00:36:47 dlenev@stripped +31 -0
    Added test for bug#19634 "Re-execution of multi-delete which involve trigger/
    stored function crashes server".

  mysql-test/r/sp-prelocking.result
    1.5 06/06/21 00:36:47 dlenev@stripped +18 -0
    Added test for bug#19634 "Re-execution of multi-delete which involve trigger/
    stored function crashes server".

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	dlenev
# Host:	jabberwock.site
# Root:	/home/dlenev/mysql-5.0-bg19634

--- 1.550/sql/sql_parse.cc	2006-06-17 00:49:13 +04:00
+++ 1.551/sql/sql_parse.cc	2006-06-21 00:36:47 +04:00
@@ -5202,8 +5202,26 @@
 
 
 /*
-  Check the privilege for all used tables.  Table privileges are cached
-  in the table list for GRANT checking
+  Check the privilege for all used tables.
+
+  SYNOPSYS
+    check_table_access()
+      thd          Thread context
+      want_access  Privileges requested
+      tables       List of tables to be checked
+      no_errors    FALSE/TRUE - report/don't report error to
+                   the client (using my_error() call).
+
+  NOTES
+    Table privileges are cached in the table list for GRANT checking.
+    This functions assumes that table list used and
+    thd->lex->query_tables_own_last value correspond to each other
+    (the latter should be either 0 or point to next_global member
+    of one of elements of this table list).
+
+  RETURN VALUE
+    FALSE - OK
+    TRUE  - Access denied
 */
 
 bool
@@ -7068,14 +7086,28 @@
   SELECT_LEX *select_lex= &thd->lex->select_lex;
   TABLE_LIST *aux_tables=
     (TABLE_LIST *)thd->lex->auxilliary_table_list.first;
+  TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
   DBUG_ENTER("multi_delete_precheck");
 
   /* sql_yacc guarantees that tables and aux_tables are not zero */
   DBUG_ASSERT(aux_tables != 0);
   if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
-      check_table_access(thd,SELECT_ACL, tables,0) ||
-      check_table_access(thd,DELETE_ACL, aux_tables,0))
+      check_table_access(thd, SELECT_ACL, tables, 0))
+    DBUG_RETURN(TRUE);
+
+  /*
+    Since aux_tables list is not part of LEX::query_tables list we
+    have to juggle with LEX::query_tables_own_last value to be able
+    call check_table_access() safely.
+  */
+  thd->lex->query_tables_own_last= 0;
+  if (check_table_access(thd, DELETE_ACL, aux_tables, 0))
+  {
+    thd->lex->query_tables_own_last= save_query_tables_own_last;
     DBUG_RETURN(TRUE);
+  }
+  thd->lex->query_tables_own_last= save_query_tables_own_last;
+
   if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
   {
     my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,

--- 1.4/mysql-test/r/sp-prelocking.result	2006-03-28 15:06:17 +04:00
+++ 1.5/mysql-test/r/sp-prelocking.result	2006-06-21 00:36:47 +04:00
@@ -237,3 +237,21 @@
 drop table t1;
 drop view v1, v2, v3;
 drop function bug15683;
+drop table if exists t1, t2, t3;
+drop function if exists bug19634;
+create table t1 (id int, data int);
+create table t2 (id int);
+create table t3 (data int);
+create function bug19634() returns int return (select count(*) from t3);
+prepare stmt from "delete t1 from t1, t2 where t1.id = t2.id and bug19634()";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+create trigger t1_bi before delete on t1 for each row insert into t3 values (old.data);
+prepare stmt from "delete t1 from t1, t2 where t1.id = t2.id";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+drop function bug19634;
+drop table t1, t2, t3;
+End of 5.0 tests

--- 1.4/mysql-test/t/sp-prelocking.test	2006-03-28 15:06:17 +04:00
+++ 1.5/mysql-test/t/sp-prelocking.test	2006-06-21 00:36:47 +04:00
@@ -272,3 +272,34 @@
 drop view v1, v2, v3;
 drop function bug15683;
 
+
+#
+# Bug#19634 "Re-execution of multi-delete which involve trigger/stored 
+#            function crashes server"
+#
+--disable_warnings
+drop table if exists t1, t2, t3;
+drop function if exists bug19634;
+--enable_warnings
+create table t1 (id int, data int);
+create table t2 (id int);
+create table t3 (data int);
+create function bug19634() returns int return (select count(*) from t3);
+prepare stmt from "delete t1 from t1, t2 where t1.id = t2.id and bug19634()";
+# This should not crash server
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+create trigger t1_bi before delete on t1 for each row insert into t3 values (old.data);
+prepare stmt from "delete t1 from t1, t2 where t1.id = t2.id";
+
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+drop function bug19634;
+drop table t1, t2, t3;
+
+
+--echo End of 5.0 tests
Thread
bk commit into 5.0 tree (dlenev:1.2187) BUG#18437dlenev20 Jun