List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:February 9 2006 11:36am
Subject:bk commit into 5.1 tree (konstantin:1.2094)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of kostja. When kostja 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.2094 06/02/09 13:35:59 konstantin@stripped +37 -0
  Merge mysql.com:/home/kostja/mysql/mysql-5.0-root
  into  mysql.com:/home/kostja/mysql/mysql-5.1-merge

  mysql-test/t/disabled.def
    1.61 06/02/09 13:35:53 konstantin@stripped +2 -1
    Manual merge.

  storage/ndb/tools/delete_all.cpp
    1.19 06/02/09 13:34:38 konstantin@stripped +0 -0
    Auto merged

  storage/ndb/test/ndbapi/testBlobs.cpp
    1.30 06/02/09 13:34:38 konstantin@stripped +0 -0
    Auto merged

  storage/ndb/src/ndbapi/NdbBlob.cpp
    1.36 06/02/09 13:34:38 konstantin@stripped +0 -2
    Auto merged

  storage/ndb/src/kernel/vm/Configuration.hpp
    1.19 06/02/09 13:34:38 konstantin@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/vm/Configuration.cpp
    1.45 06/02/09 13:34:38 konstantin@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/main.cpp
    1.58 06/02/09 13:34:38 konstantin@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
    1.27 06/02/09 13:34:38 konstantin@stripped +0 -0
    Auto merged

  sql/sql_yacc.yy
    1.454 06/02/09 13:34:38 konstantin@stripped +0 -0
    Auto merged

  sql/sql_select.cc
    1.388 06/02/09 13:34:37 konstantin@stripped +0 -0
    Auto merged

  sql/sql_prepare.cc
    1.161 06/02/09 13:34:37 konstantin@stripped +0 -0
    Auto merged

  sql/sql_parse.cc
    1.519 06/02/09 13:34:36 konstantin@stripped +0 -0
    Auto merged

  sql/sql_load.cc
    1.92 06/02/09 13:34:36 konstantin@stripped +0 -5
    Auto merged

  sql/sql_lex.h
    1.215 06/02/09 13:34:36 konstantin@stripped +0 -0
    Auto merged

  sql/sql_lex.cc
    1.171 06/02/09 13:34:36 konstantin@stripped +0 -0
    Auto merged

  sql/sql_base.cc
    1.300 06/02/09 13:34:36 konstantin@stripped +0 -0
    Auto merged

  sql/sql_acl.cc
    1.179 06/02/09 13:34:36 konstantin@stripped +0 -0
    Auto merged

  sql/sp_head.h
    1.80 06/02/09 13:34:35 konstantin@stripped +0 -0
    Auto merged

  sql/sp_head.cc
    1.201 06/02/09 13:34:35 konstantin@stripped +0 -0
    Auto merged

  sql/sp.h
    1.34 06/02/09 13:34:35 konstantin@stripped +0 -0
    Auto merged

  sql/sp.cc
    1.102 06/02/09 13:34:35 konstantin@stripped +0 -0
    Auto merged

  sql/opt_range.cc
    1.200 06/02/09 13:34:35 konstantin@stripped +0 -0
    Auto merged

  sql/item_func.cc
    1.274 06/02/09 13:34:35 konstantin@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.h
    1.117 06/02/09 13:34:35 konstantin@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.cc
    1.264 06/02/09 13:34:35 konstantin@stripped +0 -23
    Auto merged

  mysql-test/t/view.test
    1.136 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  mysql-test/t/sp.test
    1.175 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  mysql-test/t/sp-destruct.test
    1.7 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  mysql-test/t/fulltext.test
    1.81 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  mysql-test/r/view.result
    1.148 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  mysql-test/r/sp.result
    1.186 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  mysql-test/r/sp-code.result
    1.6 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  mysql-test/r/ndb_blob.result
    1.17 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  mysql-test/r/fulltext.result
    1.86 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  extra/perror.c
    1.46 06/02/09 13:34:34 konstantin@stripped +0 -0
    Auto merged

  BitKeeper/deleted/.del-ndb_load.test
    1.2 06/02/09 13:34:34 konstantin@stripped +0 -0
    Delete: mysql-test/t/ndb_load.test

  BitKeeper/deleted/.del-ndb_load.result
    1.2 06/02/09 13:34:24 konstantin@stripped +0 -0
    Delete: mysql-test/r/ndb_load.result

  storage/ndb/tools/delete_all.cpp
    1.16.1.2 06/02/09 13:31:54 konstantin@stripped +0 -0
    Merge rename: ndb/tools/delete_all.cpp -> storage/ndb/tools/delete_all.cpp

  storage/ndb/test/ndbapi/testBlobs.cpp
    1.20.10.4 06/02/09 13:31:54 konstantin@stripped +0 -0
    Merge rename: ndb/test/ndbapi/testBlobs.cpp ->
storage/ndb/test/ndbapi/testBlobs.cpp

  storage/ndb/src/ndbapi/NdbBlob.cpp
    1.22.4.3 06/02/09 13:31:54 konstantin@stripped +0 -0
    Merge rename: ndb/src/ndbapi/NdbBlob.cpp -> storage/ndb/src/ndbapi/NdbBlob.cpp

  storage/ndb/src/kernel/vm/Configuration.hpp
    1.15.3.2 06/02/09 13:31:54 konstantin@stripped +0 -0
    Merge rename: ndb/src/kernel/vm/Configuration.hpp ->
storage/ndb/src/kernel/vm/Configuration.hpp

  storage/ndb/src/kernel/vm/Configuration.cpp
    1.39.3.2 06/02/09 13:31:54 konstantin@stripped +0 -0
    Merge rename: ndb/src/kernel/vm/Configuration.cpp ->
storage/ndb/src/kernel/vm/Configuration.cpp

  storage/ndb/src/kernel/main.cpp
    1.48.10.3 06/02/09 13:31:54 konstantin@stripped +0 -0
    Merge rename: ndb/src/kernel/main.cpp -> storage/ndb/src/kernel/main.cpp

  storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
    1.18.5.2 06/02/09 13:31:54 konstantin@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/dbacc/Dbacc.hpp ->
storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp

# 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:	konstantin
# Host:	oak.local
# Root:	/home/kostja/mysql/mysql-5.1-merge/RESYNC

--- 1.45/extra/perror.c	2005-12-05 16:17:39 +03:00
+++ 1.46/extra/perror.c	2006-02-09 13:34:34 +03:00
@@ -239,10 +239,24 @@
 	if ((ndb_error_string(code, ndb_string, sizeof(ndb_string)) < 0) &&
 	    (ndbd_exit_string(code, ndb_string, sizeof(ndb_string)) < 0))
 	{
-	    msg= 0;
+          msg= 0;
 	}
 	else
 	  msg= ndb_string;
+        if (msg)
+        {
+          if (verbose)
+            printf("NDB error code %3d: %s\n",code,msg);
+          else
+            puts(msg);
+        }
+        else
+        {
+	  fprintf(stderr,"Illegal ndb error code: %d\n",code);
+          error= 1;
+        }
+        found= 1;
+        msg= 0;
       }
       else 
 #endif

--- 1.273/sql/item_func.cc	2006-02-02 23:20:17 +03:00
+++ 1.274/sql/item_func.cc	2006-02-09 13:34:35 +03:00
@@ -1865,28 +1865,30 @@
     return value; // integer have not digits after point
 
   abs_dec= -dec;
-  double tmp;
-  /*
-    tmp2 is here to avoid return the value with 80 bit precision
-    This will fix that the test round(0.1,1) = round(0.1,1) is true
-  */
-  volatile double tmp2;
-
-  tmp= (abs_dec < array_elements(log_10) ?
-        log_10[abs_dec] : pow(10.0, (double) abs_dec));
-
+  longlong tmp;
+  
+  if(abs_dec >= array_elements(log_10_int))
+    return 0;
+  
+  tmp= log_10_int[abs_dec];
+  
   if (truncate)
   {
     if (unsigned_flag)
-      tmp2= floor(ulonglong2double(value)/tmp)*tmp;
-    else if (value >= 0)
-      tmp2= floor(((double)value)/tmp)*tmp;
+      value= (ulonglong(value)/tmp)*tmp;
     else
-      tmp2= ceil(((double)value)/tmp)*tmp;
+      value= (value/tmp)*tmp;
   }
   else
-    tmp2= rint(((double)value)/tmp)*tmp;
-  return (longlong)tmp2;
+  {
+    if (unsigned_flag)
+      value= ((ulonglong(value)+(tmp>>1))/tmp)*tmp;
+    else if ( value >= 0)
+      value= ((value+(tmp>>1))/tmp)*tmp;
+    else
+      value= ((value-(tmp>>1))/tmp)*tmp;
+  }
+  return value;
 }
 
 

--- 1.199/sql/opt_range.cc	2006-02-02 16:48:05 +03:00
+++ 1.200/sql/opt_range.cc	2006-02-09 13:34:35 +03:00
@@ -9068,6 +9068,7 @@
     quick_prefix_selectivity= (double) quick_prefix_records /
                               (double) table_records;
     num_groups= (uint) rint(num_groups * quick_prefix_selectivity);
+    set_if_bigger(num_groups, 1);
   }
 
   if (used_key_parts > group_key_parts)

--- 1.178/sql/sql_acl.cc	2006-02-02 23:20:18 +03:00
+++ 1.179/sql/sql_acl.cc	2006-02-09 13:34:36 +03:00
@@ -3045,7 +3045,7 @@
 
   if (!revoke_grant)
   {
-    if (sp_exists_routine(thd, table_list, is_proc, no_error)<0)
+    if (sp_exist_routines(thd, table_list, is_proc, no_error)<0)
       DBUG_RETURN(TRUE);
   }
 

--- 1.170/sql/sql_lex.cc	2006-01-19 00:18:37 +03:00
+++ 1.171/sql/sql_lex.cc	2006-02-09 13:34:36 +03:00
@@ -1128,7 +1128,7 @@
   embedding= leaf_tables= 0;
   item_list.empty();
   join= 0;
-  having= where= prep_where= 0;
+  having= prep_having= where= prep_where= 0;
   olap= UNSPECIFIED_OLAP_TYPE;
   having_fix_field= 0;
   context.select_lex= this;

--- 1.214/sql/sql_lex.h	2006-01-30 15:31:18 +03:00
+++ 1.215/sql/sql_lex.h	2006-02-09 13:34:36 +03:00
@@ -493,6 +493,7 @@
   char *db;
   Item *where, *having;                         /* WHERE & HAVING clauses */
   Item *prep_where; /* saved WHERE clause for prepared statement processing */
+  Item *prep_having;/* saved HAVING clause for prepared statement processing */
   /* point on lex in which it was created, used in view subquery detection */
   st_lex *parent_lex;
   enum olap_type olap;

--- 1.518/sql/sql_parse.cc	2006-02-08 23:52:05 +03:00
+++ 1.519/sql/sql_parse.cc	2006-02-09 13:34:36 +03:00
@@ -4490,21 +4490,17 @@
   case SQLCOM_DROP_PROCEDURE:
   case SQLCOM_DROP_FUNCTION:
     {
-      sp_head *sp;
       int result;
-      char *db, *name;
+      int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
+                 TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
 
-      if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
-        sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
-                            &thd->sp_proc_cache, FALSE);
-      else
-        sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
-                            &thd->sp_func_cache, FALSE);
+      result= sp_routine_exists_in_table(thd, type, lex->spname);
       mysql_reset_errors(thd, 0);
-      if (sp)
+      if (result == SP_OK)
       {
-        db= thd->strdup(sp->m_db.str);
-	name= thd->strdup(sp->m_name.str);
+        char *db= lex->spname->m_db.str;
+	char *name= lex->spname->m_name.str;
+
 	if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
                                  lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
           goto error;
@@ -4644,7 +4640,7 @@
       else
         sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
                             &thd->sp_func_cache, FALSE);
-      if (!sp || !sp->show_routine_code(thd))
+      if (!sp || sp->show_routine_code(thd))
       {
         /* We don't distinguish between errors for now */
         my_error(ER_SP_DOES_NOT_EXIST, MYF(0),

--- 1.387/sql/sql_select.cc	2006-02-08 23:52:05 +03:00
+++ 1.388/sql/sql_select.cc	2006-02-09 13:34:37 +03:00
@@ -612,6 +612,7 @@
     build_bitmap_for_nested_joins(join_list, 0);
 
     sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
+    sel->prep_having= having ? having->copy_andor_structure(thd) : 0;
 
     if (arena)
       thd->restore_active_arena(arena, &backup);
@@ -625,13 +626,26 @@
     DBUG_RETURN(1);
   }
 
-  if (cond_value == Item::COND_FALSE ||
-      (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
-  {						/* Impossible cond */
-    DBUG_PRINT("info", ("Impossible WHERE"));
-    zero_result_cause= "Impossible WHERE";
-    error= 0;
-    DBUG_RETURN(0);
+  {
+    Item::cond_result having_value;
+    having= optimize_cond(this, having, join_list, &having_value);
+    if (thd->net.report_error)
+    {
+      error= 1;
+      DBUG_PRINT("error",("Error from optimize_cond"));
+      DBUG_RETURN(1);
+    }
+
+    if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE || 
+        (!unit->select_limit_cnt && !(select_options &
OPTION_FOUND_ROWS)))
+    {						/* Impossible cond */
+      DBUG_PRINT("info", (having_value == Item::COND_FALSE ? 
+                            "Impossible HAVING" : "Impossible WHERE"));
+      zero_result_cause=  having_value == Item::COND_FALSE ?
+                           "Impossible HAVING" : "Impossible WHERE";
+      error= 0;
+      DBUG_RETURN(0);
+    }
   }
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -12472,7 +12486,8 @@
         overshadows the column reference from the SELECT list.
       */
       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
-                          ER(ER_NON_UNIQ_ERROR), from_field->field_name,
+                          ER(ER_NON_UNIQ_ERROR),
+                          ((Item_ident*) order_item)->field_name,
                           current_thd->where);
     }
   }

--- 1.453/sql/sql_yacc.yy	2006-02-08 13:11:36 +03:00
+++ 1.454/sql/sql_yacc.yy	2006-02-09 13:34:38 +03:00
@@ -2400,17 +2400,18 @@
 	    sp_head *sp= lex->sphead;
 	    sp_pcontext *parsing_ctx= lex->spcont;
 	    int case_expr_id= parsing_ctx->register_case_expr();
+            sp_instr_set_case_expr *i;
 	    
 	    if (parsing_ctx->push_case_expr_id(case_expr_id))
               YYABORT;
-	    
-	    sp->add_instr(
-	      new sp_instr_set_case_expr(sp->instructions(),
-	                                 parsing_ctx,
-	                                 case_expr_id,
-	                                 $3,
-	                                 lex));
-	    
+
+            i= new sp_instr_set_case_expr(sp->instructions(),
+                                          parsing_ctx,
+                                          case_expr_id,
+                                          $3,
+                                          lex);
+            sp->add_cont_backpatch(i);
+            sp->add_instr(i);
 	    sp->m_flags|= sp_head::IN_SIMPLE_CASE;
 	    sp->restore_lex(YYTHD);
 	  }

--- 1.147/mysql-test/r/view.result	2006-02-07 22:54:34 +03:00
+++ 1.148/mysql-test/r/view.result	2006-02-09 13:34:34 +03:00
@@ -2495,3 +2495,37 @@
 1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Select tables optimized away
 DROP VIEW v1;
 DROP TABLE t1;
+CREATE TABLE t1 (x varchar(10));
+INSERT INTO t1 VALUES (null), ('foo'), ('bar'), (null);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT IF(x IS NULL, 'blank', 'not blank') FROM v1 GROUP BY x;
+IF(x IS NULL, 'blank', 'not blank')
+blank
+not blank
+not blank
+SELECT IF(x IS NULL, 'blank', 'not blank') AS x FROM t1 GROUP BY x;
+x
+blank
+not blank
+not blank
+Warnings:
+Warning	1052	Column 'x' in group statement is ambiguous
+SELECT IF(x IS NULL, 'blank', 'not blank') AS x FROM v1;
+x
+blank
+not blank
+not blank
+blank
+SELECT IF(x IS NULL, 'blank', 'not blank') AS y FROM v1 GROUP BY y;
+y
+blank
+not blank
+SELECT IF(x IS NULL, 'blank', 'not blank') AS x FROM v1 GROUP BY x;
+x
+blank
+not blank
+not blank
+Warnings:
+Warning	1052	Column 'x' in group statement is ambiguous
+DROP VIEW v1;
+DROP TABLE t1;

--- 1.135/mysql-test/t/view.test	2006-02-07 22:54:35 +03:00
+++ 1.136/mysql-test/t/view.test	2006-02-09 13:34:34 +03:00
@@ -2358,3 +2358,20 @@
 
 DROP VIEW v1;
 DROP TABLE t1;
+
+#
+# Bug#16382: grouping name is resolved against a view column name
+#            which coincides with a select column name
+
+CREATE TABLE t1 (x varchar(10));
+INSERT INTO t1 VALUES (null), ('foo'), ('bar'), (null);
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT IF(x IS NULL, 'blank', 'not blank') FROM v1 GROUP BY x;
+SELECT IF(x IS NULL, 'blank', 'not blank') AS x FROM t1 GROUP BY x;
+SELECT IF(x IS NULL, 'blank', 'not blank') AS x FROM v1;
+SELECT IF(x IS NULL, 'blank', 'not blank') AS y FROM v1 GROUP BY y;
+SELECT IF(x IS NULL, 'blank', 'not blank') AS x FROM v1 GROUP BY x;
+
+DROP VIEW v1;
+DROP TABLE t1;

--- 1.60/mysql-test/t/disabled.def	2006-02-07 16:49:46 +03:00
+++ 1.61/mysql-test/t/disabled.def	2006-02-09 13:35:53 +03:00
@@ -33,3 +33,5 @@
 rpl_ndb_relay_space : Bug 16993
 ndb_binlog_ddl_multi : Bug #17038
 rpl_ndb_log : MySQL Bugs: #17158
+subselect       : Bug#15706
+ndb_load        : Bug #17233

--- 1.18.5.1/ndb/src/kernel/blocks/dbacc/Dbacc.hpp	2006-02-07 21:56:49 +03:00
+++ 1.27/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp	2006-02-09 13:34:38 +03:00
@@ -23,7 +23,7 @@
 #include <SimulatedBlock.hpp>
 
 // primary key is stored in TUP
-#include <Dbtup.hpp>
+#include "../dbtup/Dbtup.hpp"
 
 #ifdef DBACC_C
 // Debug Macros
@@ -62,8 +62,6 @@
 }\
 */
 
-#define dbgUndoword(ptr, ind, val)
-
 // Constants
 /** ------------------------------------------------------------------------ 
  *   THESE ARE CONSTANTS THAT ARE USED FOR DEFINING THE SIZE OF BUFFERS, THE
@@ -103,46 +101,7 @@
 #define ZOVERFLOW_PAGE_TYPE 1
 #define ZDEFAULT_LIST 3
 #define ZWORDS_IN_PAGE 2048
-/* --------------------------------------------------------------------------------- */
-/*       CONSTANTS FOR THE ZERO PAGES                                                */
-/* --------------------------------------------------------------------------------- */
-#define ZPAGEZERO_PREV_UNDOP 8
-#define ZPAGEZERO_NO_OVER_PAGE 9
-#define ZPAGEZERO_TABID 10
-#define ZPAGEZERO_FRAGID0 11
-#define ZPAGEZERO_FRAGID1 12
-#define ZPAGEZERO_HASH_CHECK 13
-#define ZPAGEZERO_DIRSIZE 14
-#define ZPAGEZERO_EXPCOUNTER 15
-#define ZPAGEZERO_NEXT_UNDO_FILE 16
-#define ZPAGEZERO_SLACK 17
-#define ZPAGEZERO_NO_PAGES 18
-#define ZPAGEZERO_HASHCHECKBIT 19
-#define ZPAGEZERO_K 20
-#define ZPAGEZERO_LHFRAGBITS 21
-#define ZPAGEZERO_LHDIRBITS 22
-#define ZPAGEZERO_LOCALKEYLEN 23
-#define ZPAGEZERO_MAXP 24
-#define ZPAGEZERO_MAXLOADFACTOR 25
-#define ZPAGEZERO_MINLOADFACTOR 26
-#define ZPAGEZERO_MYFID 27
-#define ZPAGEZERO_LAST_OVER_INDEX 28
-#define ZPAGEZERO_P 29
-#define ZPAGEZERO_NO_OF_ELEMENTS 30
-#define ZPAGEZERO_ELEMENT_LENGTH 31
-#define ZPAGEZERO_KEY_LENGTH 32
-#define ZPAGEZERO_NODETYPE 33
-#define ZPAGEZERO_SLACK_CHECK 34
-/* --------------------------------------------------------------------------------- */
-/*       CONSTANTS IN ALPHABETICAL ORDER                                             */
-/* --------------------------------------------------------------------------------- */
 #define ZADDFRAG 0
-#define ZCOPY_NEXT 1
-#define ZCOPY_NEXT_COMMIT 2
-#define ZCOPY_COMMIT 3
-#define ZCOPY_REPEAT 4
-#define ZCOPY_ABORT 5
-#define ZCOPY_CLOSE 6
 #define ZDIRARRAY 68
 #define ZDIRRANGESIZE 65
 //#define ZEMPTY_FRAGMENT 0
@@ -151,17 +110,14 @@
 #define ZFS_CONNECTSIZE 300
 #define ZFS_OPSIZE 100
 #define ZKEYINKEYREQ 4
-#define ZLCP_CONNECTSIZE 30
 #define ZLEFT 1
 #define ZLOCALLOGFILE 2
 #define ZLOCKED 0
 #define ZMAXSCANSIGNALLEN 20
 #define ZMAINKEYLEN 8
-#define ZMAX_UNDO_VERSION 4
 #define ZNO_OF_DISK_VERSION 3
 #define ZNO_OF_OP_PER_SIGNAL 20
 //#define ZNOT_EMPTY_FRAGMENT 1
-#define ZNR_OF_UNDO_PAGE_GROUP 16
 #define ZOP_HEAD_INFO_LN 3
 #define ZOPRECSIZE 740
 #define ZOVERFLOWRECSIZE 5
@@ -181,35 +137,21 @@
 #define ZSCAN_LOCK_ALL 3
 #define ZSCAN_OP 5
 #define ZSCAN_REC_SIZE 256
-#define ZSR_VERSION_REC_SIZE 16
 #define ZSTAND_BY 2
 #define ZTABLESIZE 16
 #define ZTABMAXINDEX 3
 #define ZUNDEFINED_OP 6
-#define ZUNDOHEADSIZE 7
 #define ZUNLOCKED 1
-#define ZUNDOPAGE_BASE_ADD 2
-#define ZUNDOPAGEINDEXBITS 13
-#define ZUNDOPAGEINDEX_MASK 0x1fff
-#define ZWRITEPAGESIZE 8
-#define ZWRITE_UNDOPAGESIZE 2
-#define ZMIN_UNDO_PAGES_AT_COMMIT 4
-#define ZMIN_UNDO_PAGES_AT_OPERATION 10
-#define ZMIN_UNDO_PAGES_AT_EXPAND 16
 
 /* --------------------------------------------------------------------------------- */
 /* CONTINUEB CODES                                                                   */
 /* --------------------------------------------------------------------------------- */
-#define ZLOAD_BAL_LCP_TIMER 0
 #define ZINITIALISE_RECORDS 1
-#define ZSR_READ_PAGES_ALLOC 2
-#define ZSTART_UNDO 3
 #define ZSEND_SCAN_HBREP 4
 #define ZREL_ROOT_FRAG 5
 #define ZREL_FRAG 6
 #define ZREL_DIR 7
 #define ZREPORT_MEMORY_USAGE 8
-#define ZLCP_OP_WRITE_RT_BREAK 9
 
 /* ------------------------------------------------------------------------- */
 /* ERROR CODES                                                               */
@@ -235,7 +177,6 @@
 #define ZWRITE_ERROR 630
 #define ZTO_OP_STATE_ERROR 631
 #define ZTOO_EARLY_ACCESS_ERROR 632
-#define ZTEMPORARY_ACC_UNDO_FAILURE 677
 #endif
 
 class ElementHeader {
@@ -331,34 +272,9 @@
 enum State {
   FREEFRAG = 0,
   ACTIVEFRAG = 1,
-  SEND_QUE_OP = 2,
-  WAIT_ACC_LCPREQ = 3,
-  LCP_SEND_PAGES = 4,
-  LCP_SEND_OVER_PAGES = 5,
-  LCP_SEND_ZERO_PAGE = 6,
-  SR_READ_PAGES = 7,
-  SR_READ_OVER_PAGES = 8,
-  WAIT_ZERO_PAGE_STORED = 9,
+  //SEND_QUE_OP = 2,
   WAIT_NOTHING = 10,
-  WAIT_OPEN_UNDO_LCP = 11,
-  WAIT_OPEN_UNDO_LCP_NEXT = 12,
-  WAIT_OPEN_DATA_FILE_FOR_READ = 13,
-  WAIT_OPEN_DATA_FILE_FOR_WRITE = 14,
-  OPEN_UNDO_FILE_SR = 15,
-  READ_UNDO_PAGE = 16,
-  READ_UNDO_PAGE_AND_CLOSE = 17,
-  WAIT_READ_DATA = 18,
-  WAIT_READ_PAGE_ZERO = 19,
-  WAIT_WRITE_DATA = 20,
-  WAIT_WRITE_UNDO = 21,
-  WAIT_WRITE_UNDO_EXIT = 22,
-  WAIT_CLOSE_UNDO = 23,
-  LCP_CLOSE_DATA = 24,
-  SR_CLOSE_DATA = 25,
   WAIT_ONE_CONF = 26,
-  WAIT_TWO_CONF = 27,
-  LCP_FREE = 28,
-  LCP_ACTIVE = 29,
   FREE_OP = 30,
   WAIT_EXE_OP = 32,
   WAIT_IN_QUEUE = 34,
@@ -378,33 +294,12 @@
   ADDSECONDFRAG = 49,
   DELETEFIRSTFRAG = 50,
   DELETESECONDFRAG = 51,
-  ACTIVEROOT = 52,
-  LCP_CREATION = 53
+  ACTIVEROOT = 52
 };
 
 // Records
 
 /* --------------------------------------------------------------------------------- */
-/* UNDO HEADER RECORD                                                                */
-/* --------------------------------------------------------------------------------- */
-
-  struct UndoHeader {
-    enum UndoHeaderType{
-      ZPAGE_INFO = 0,
-      ZOVER_PAGE_INFO = 1,
-      ZOP_INFO = 2,
-      ZNO_UNDORECORD_TYPES = 3
-    };
-    UintR tableId;
-    UintR rootFragId;
-    UintR localFragId;
-    UintR variousInfo;
-    UintR logicalPageId;
-    UintR prevUndoAddressForThisFrag;
-    UintR prevUndoAddress;
-  };
-
-/* --------------------------------------------------------------------------------- */
 /* DIRECTORY RANGE                                                                   */
 /* --------------------------------------------------------------------------------- */
   struct DirRange {
@@ -427,19 +322,26 @@
 /*         REC  A POINTER TO FRAGMENT RECORD IS SAVED IN ROOTFRAGMENTREC FRAGMENT    */
 /* --------------------------------------------------------------------------------- */
 struct Fragmentrec {
-//-----------------------------------------------------------------------------
-// References to long key pages with free area. Some type of buddy structure
-// where references in higher index have more free space.
-//-----------------------------------------------------------------------------
-  Uint32 longKeyPageArray[4];
-
+  Uint32 scan[MAX_PARALLEL_SCANS_PER_FRAG];
+  union {
+    Uint32 mytabptr;
+    Uint32 myTableId;
+  };
+  union {
+    Uint32 fragmentid;
+    Uint32 myfid;
+  };
+  Uint32 roothashcheck;
+  Uint32 noOfElements;
+  Uint32 m_commit_count;
+  State rootState;
+  
 //-----------------------------------------------------------------------------
 // These variables keep track of allocated pages, the number of them and the
 // start file page of them. Used during local checkpoints.
 //-----------------------------------------------------------------------------
   Uint32 datapages[8];
   Uint32 activeDataPage;
-  Uint32 activeDataFilePage;
 
 //-----------------------------------------------------------------------------
 // Temporary variables used during shrink and expand process.
@@ -456,9 +358,7 @@
 // List of lock owners and list of lock waiters to support LCP handling
 //-----------------------------------------------------------------------------
   Uint32 lockOwnersList;
-  Uint32 firstWaitInQueOp;
-  Uint32 lastWaitInQueOp;
-  Uint32 sentWaitInQueOp;
+  Uint32 m_current_sequence_no;
 
 //-----------------------------------------------------------------------------
 // References to Directory Ranges (which in turn references directories, which
@@ -471,23 +371,6 @@
   Uint32 lastOverIndex;
 
 //-----------------------------------------------------------------------------
-// These variables are used to support LCP and Restore from disk.
-// lcpDirIndex: used during LCP as the frag page id currently stored.
-// lcpMaxDirIndex: The dirsize at start of LCP.
-// lcpMaxOverDirIndex: The xx at start of LCP
-// During a LCP one writes the minimum of the number of pages in the directory
-// and the number of pages at the start of the LCP.
-// noStoredPages: Number of bucket pages written in LCP used at restore
-// noOfOverStoredPages: Number of overflow pages written in LCP used at restore
-// This variable is also used during LCP to calculate this number.
-//-----------------------------------------------------------------------------
-  Uint32 lcpDirIndex;
-  Uint32 lcpMaxDirIndex;
-  Uint32 lcpMaxOverDirIndex;
-  Uint32 noStoredPages;
-  Uint32 noOfStoredOverPages;
-
-//-----------------------------------------------------------------------------
 // We have a list of overflow pages with free areas. We have a special record,
 // the overflow record representing these pages. The reason is that the
 // same record is also used to represent pages in the directory array that have
@@ -500,22 +383,10 @@
   Uint32 firstFreeDirindexRec;
 
 //-----------------------------------------------------------------------------
-// localCheckpId is used during execution of UNDO log to ensure that we only
-// apply UNDO log records from the restored LCP of the fragment.
-// lcpLqhPtr keeps track of LQH record for this fragment to checkpoint
-//-----------------------------------------------------------------------------
-  Uint32 localCheckpId;
-  Uint32 lcpLqhPtr;
-
-//-----------------------------------------------------------------------------
 // Counter keeping track of how many times we have expanded. We need to ensure
 // that we do not shrink so many times that this variable becomes negative.
 //-----------------------------------------------------------------------------
   Uint32 expandCounter;
-//-----------------------------------------------------------------------------
-// Reference to record for open file at LCP and restore
-//-----------------------------------------------------------------------------
-  Uint32 fsConnPtr;
 
 //-----------------------------------------------------------------------------
 // These variables are important for the linear hashing algorithm.
@@ -544,13 +415,8 @@
   Uint32 slackCheck;
 
 //-----------------------------------------------------------------------------
-// myfid is the fragment id of the fragment
-// myroot is the reference to the root fragment record
 // nextfreefrag is the next free fragment if linked into a free list
 //-----------------------------------------------------------------------------
-  Uint32 myfid;
-  Uint32 myroot;
-  Uint32 myTableId;
   Uint32 nextfreefrag;
 
 //-----------------------------------------------------------------------------
@@ -562,17 +428,6 @@
   Uint32 nextAllocPage;
 
 //-----------------------------------------------------------------------------
-// Keeps track of undo position for fragment during LCP and restore.
-//-----------------------------------------------------------------------------
-  Uint32 prevUndoposition;
-
-//-----------------------------------------------------------------------------
-// Page reference during LCP and restore of page zero where fragment data is
-// saved
-//-----------------------------------------------------------------------------
-  Uint32 zeroPagePtr;
-
-//-----------------------------------------------------------------------------
 // Number of pages read from file during restore
 //-----------------------------------------------------------------------------
   Uint32 noOfExpectedPages;
@@ -583,29 +438,6 @@
   State fragState;
 
 //-----------------------------------------------------------------------------
-// Keep track of number of outstanding writes of UNDO log records to ensure that
-// we have saved all UNDO info before concluding local checkpoint.
-//-----------------------------------------------------------------------------
-  Uint32 nrWaitWriteUndoExit;
-
-//-----------------------------------------------------------------------------
-// lastUndoIsStored is used to handle parallel writes of UNDO log and pages to
-// know when LCP is completed
-//-----------------------------------------------------------------------------
-  Uint8 lastUndoIsStored;
-
-//-----------------------------------------------------------------------------
-// Set to ZTRUE when local checkpoint freeze occurs and set to ZFALSE when
-// local checkpoint concludes.
-//-----------------------------------------------------------------------------
-  Uint8 createLcp;
-
-//-----------------------------------------------------------------------------
-// Flag indicating whether we are in the load phase of restore still.
-//-----------------------------------------------------------------------------
-  Uint8 loadingFlag;
-
-//-----------------------------------------------------------------------------
 // elementLength: Length of element in bucket and overflow pages
 // keyLength: Length of key
 //-----------------------------------------------------------------------------
@@ -631,11 +463,8 @@
 
 //-----------------------------------------------------------------------------
 // nodetype can only be STORED in this release. Is currently only set, never read
-// stopQueOp is indicator that locked operations will not start until LCP have
-// released the lock on the fragment
 //-----------------------------------------------------------------------------
   Uint8 nodetype;
-  Uint8 stopQueOp;
 
 //-----------------------------------------------------------------------------
 // flag to avoid accessing table record if no char attributes
@@ -646,49 +475,6 @@
   typedef Ptr<Fragmentrec> FragmentrecPtr;
 
 /* --------------------------------------------------------------------------------- */
-/* FS_CONNECTREC                                                                     */
-/* --------------------------------------------------------------------------------- */
-struct FsConnectrec {
-  Uint32 fsNext;
-  Uint32 fsPrev;
-  Uint32 fragrecPtr;
-  Uint32 fsPtr;
-  State fsState;
-  Uint8 activeFragId;
-  Uint8 fsPart;
-}; /* p2c: size = 24 bytes */
-
-  typedef Ptr<FsConnectrec> FsConnectrecPtr;
-
-/* --------------------------------------------------------------------------------- */
-/* FS_OPREC                                                                          */
-/* --------------------------------------------------------------------------------- */
-struct FsOprec {
-  Uint32 fsOpnext;
-  Uint32 fsOpfragrecPtr;
-  Uint32 fsConptr;
-  State fsOpstate;
-  Uint16 fsOpMemPage;
-}; /* p2c: size = 20 bytes */
-
-  typedef Ptr<FsOprec> FsOprecPtr;
-
-/* --------------------------------------------------------------------------------- */
-/* LCP_CONNECTREC                                                                    */
-/* --------------------------------------------------------------------------------- */
-struct LcpConnectrec {
-  Uint32 nextLcpConn;
-  Uint32 lcpUserptr;
-  Uint32 rootrecptr;
-  State syncUndopageState;
-  State lcpstate;
-  Uint32 lcpUserblockref;
-  Uint16 localCheckPid;
-  Uint8 noOfLcpConf;
-};
-  typedef Ptr<LcpConnectrec> LcpConnectrecPtr;
-
-/* --------------------------------------------------------------------------------- */
 /* OPERATIONREC                                                                      */
 /* --------------------------------------------------------------------------------- */
 struct Operationrec {
@@ -718,6 +504,7 @@
   Uint32 transId2;
   Uint32 longPagePtr;
   Uint32 longKeyPageIndex;
+  Uint32 m_sequence_no;
   State opState;
   Uint32 userptr;
   State transactionstate;
@@ -736,7 +523,6 @@
   Uint8 dirtyRead;
   Uint8 commitDeleteCheckFlag;
   Uint8 isAccLockReq;
-  Uint8 isUndoLogReq;
 }; /* p2c: size = 168 bytes */
 
   typedef Ptr<Operationrec> OperationrecPtr;
@@ -766,29 +552,6 @@
   typedef Ptr<Page8> Page8Ptr;
 
 /* --------------------------------------------------------------------------------- */
-/* ROOTFRAGMENTREC                                                                   */
-/*          DURING EXPAND FRAGMENT PROCESS, EACH FRAGMEND WILL BE EXPAND INTO TWO    */
-/*          NEW FRAGMENTS.TO MAKE THIS PROCESS EASIER, DURING ADD FRAGMENT PROCESS   */
-/*          NEXT FRAGMENT IDENTIIES WILL BE CALCULATED, AND TWO FRAGMENTS WILL BE    */
-/*          ADDED IN (NDBACC). THEREBY EXPAND OF FRAGMENT CAN BE PERFORMED QUICK AND */
-/*          EASY.THE NEW FRAGMENT ID SENDS TO TUP MANAGER FOR ALL OPERATION PROCESS. */
-/* --------------------------------------------------------------------------------- */
-struct Rootfragmentrec {
-  Uint32 scan[MAX_PARALLEL_SCANS_PER_FRAG];
-  Uint32 fragmentptr[2];
-  Uint32 fragmentid[2];
-  Uint32 lcpPtr;
-  Uint32 mytabptr;
-  Uint32 nextroot;
-  Uint32 roothashcheck;
-  Uint32 noOfElements;
-  Uint32 m_commit_count;
-  State rootState;
-}; /* p2c: size = 72 bytes */
-
-  typedef Ptr<Rootfragmentrec> RootfragmentrecPtr;
-
-/* --------------------------------------------------------------------------------- */
 /* SCAN_REC                                                                          */
 /* --------------------------------------------------------------------------------- */
 struct ScanRec {
@@ -802,7 +565,6 @@
     SCAN_COMPLETED
   };
   Uint32 activeLocalFrag;
-  Uint32 rootPtr;
   Uint32 nextBucketIndex;
   Uint32 scanNextfreerec;
   Uint32 scanFirstActiveOp;
@@ -831,17 +593,6 @@
 
   typedef Ptr<ScanRec> ScanRecPtr;
 
-/* --------------------------------------------------------------------------------- */
-/* SR_VERSION_REC                                                                    */
-/* --------------------------------------------------------------------------------- */
-struct SrVersionRec {
-  Uint32 nextFreeSr;
-  Uint32 checkPointId;
-  Uint32 prevAddress;
-  Uint32 srUnused;	/* p2c: Not used */
-}; /* p2c: size = 16 bytes */
-
-  typedef Ptr<SrVersionRec> SrVersionRecPtr;
 
 /* --------------------------------------------------------------------------------- */
 /* TABREC                                                                            */
@@ -854,15 +605,6 @@
 };
   typedef Ptr<Tabrec> TabrecPtr;
 
-/* --------------------------------------------------------------------------------- */
-/* UNDOPAGE                                                                          */
-/* --------------------------------------------------------------------------------- */
-struct Undopage {
-  Uint32 undoword[8192];
-}; /* p2c: size = 32768 bytes */
-
-  typedef Ptr<Undopage> UndopagePtr;
-
 public:
   Dbacc(const class Configuration &);
   virtual ~Dbacc();
@@ -870,6 +612,8 @@
   // pointer to TUP instance in this thread
   Dbtup* c_tup;
 
+  void execACCMINUPDATE(Signal* signal);
+
 private:
   BLOCK_DEFINES(Dbacc);
 
@@ -880,37 +624,22 @@
   void execEXPANDCHECK2(Signal* signal);
   void execSHRINKCHECK2(Signal* signal);
   void execACC_OVER_REC(Signal* signal);
-  void execACC_SAVE_PAGES(Signal* signal);
   void execNEXTOPERATION(Signal* signal);
-  void execREAD_PSUEDO_REQ(Signal* signal);
+  void execREAD_PSEUDO_REQ(Signal* signal);
 
   // Received signals
   void execSTTOR(Signal* signal);
-  void execSR_FRAGIDREQ(Signal* signal);
-  void execLCP_FRAGIDREQ(Signal* signal);
-  void execLCP_HOLDOPREQ(Signal* signal);
-  void execEND_LCPREQ(Signal* signal);
-  void execACC_LCPREQ(Signal* signal);
-  void execSTART_RECREQ(Signal* signal);
-  void execACC_CONTOPREQ(Signal* signal);
   void execACCKEYREQ(Signal* signal);
   void execACCSEIZEREQ(Signal* signal);
   void execACCFRAGREQ(Signal* signal);
-  void execACC_SRREQ(Signal* signal);
   void execNEXT_SCANREQ(Signal* signal);
   void execACC_ABORTREQ(Signal* signal);
   void execACC_SCANREQ(Signal* signal);
-  void execACCMINUPDATE(Signal* signal);
   void execACC_COMMITREQ(Signal* signal);
   void execACC_TO_REQ(Signal* signal);
   void execACC_LOCKREQ(Signal* signal);
-  void execFSOPENCONF(Signal* signal);
-  void execFSCLOSECONF(Signal* signal);
-  void execFSWRITECONF(Signal* signal);
-  void execFSREADCONF(Signal* signal);
   void execNDB_STTOR(Signal* signal);
   void execDROP_TAB_REQ(Signal* signal);
-  void execFSREMOVECONF(Signal* signal);
   void execREAD_CONFIG_REQ(Signal* signal);
   void execSET_VAR_REQ(Signal* signal);
   void execDUMP_STATE_ORD(Signal* signal);
@@ -920,14 +649,12 @@
 
   void commitDeleteCheck();
 
-  void initRootFragPageZero(RootfragmentrecPtr, Page8Ptr);
-  void initRootFragSr(RootfragmentrecPtr, Page8Ptr);
-  void initFragAdd(Signal*, Uint32 rootFragIndex, Uint32 rootIndex, FragmentrecPtr);
+  typedef void * RootfragmentrecPtr;
+  void initRootFragPageZero(FragmentrecPtr, Page8Ptr);
+  void initFragAdd(Signal*, FragmentrecPtr);
   void initFragPageZero(FragmentrecPtr, Page8Ptr);
-  void initFragSr(FragmentrecPtr, Page8Ptr);
   void initFragGeneral(FragmentrecPtr);
   void verifyFragCorrect(FragmentrecPtr regFragPtr);
-  void sendFSREMOVEREQ(Signal* signal, Uint32 tableId);
   void releaseFragResources(Signal* signal, Uint32 fragIndex);
   void releaseRootFragRecord(Signal* signal, RootfragmentrecPtr rootPtr);
   void releaseRootFragResources(Signal* signal, Uint32 tableId);
@@ -943,11 +670,6 @@
   void releaseOverflowResources(Signal* signal, FragmentrecPtr regFragPtr);
   void releaseDirIndexResources(Signal* signal, FragmentrecPtr regFragPtr);
   void releaseFragRecord(Signal* signal, FragmentrecPtr regFragPtr);
-  Uint32 remainingUndoPages();
-  void updateLastUndoPageIdWritten(Signal* signal, Uint32 aNewValue);
-  void updateUndoPositionPage(Signal* signal, Uint32 aNewValue);
-  void srCheckPage(Signal* signal);
-  void srCheckContainer(Signal* signal);
   void initScanFragmentPart(Signal* signal);
   Uint32 checkScanExpand(Signal* signal);
   Uint32 checkScanShrink(Signal* signal);
@@ -956,14 +678,11 @@
   void initialiseFragRec(Signal* signal);
   void initialiseFsConnectionRec(Signal* signal);
   void initialiseFsOpRec(Signal* signal);
-  void initialiseLcpConnectionRec(Signal* signal);
   void initialiseOperationRec(Signal* signal);
   void initialiseOverflowRec(Signal* signal);
   void initialisePageRec(Signal* signal);
-  void initialiseLcpPages(Signal* signal);
   void initialiseRootfragRec(Signal* signal);
   void initialiseScanRec(Signal* signal);
-  void initialiseSrVerRec(Signal* signal);
   void initialiseTableRec(Signal* signal);
   bool addfragtotab(Signal* signal, Uint32 rootIndex, Uint32 fragId);
   void initOpRec(Signal* signal);
@@ -979,17 +698,6 @@
   void expandcontainer(Signal* signal);
   void shrinkcontainer(Signal* signal);
   void nextcontainerinfoExp(Signal* signal);
-  void lcpCopyPage(Signal* signal);
-  void lcpUpdatePage(Signal* signal);
-  void checkUndoPages(Signal* signal);
-  void undoWritingProcess(Signal* signal);
-  void writeUndoDataInfo(Signal* signal);
-  void writeUndoHeader(Signal* signal, 
-                       Uint32 logicalPageId, 
-                       UndoHeader::UndoHeaderType pageType);
-  void writeUndoOpInfo(Signal* signal);
-  void checksumControl(Signal* signal, Uint32 checkPage);
-  void startActiveUndo(Signal* signal);
   void releaseAndCommitActiveOps(Signal* signal);
   void releaseAndCommitQueuedOps(Signal* signal);
   void releaseAndAbortLockedOps(Signal* signal);
@@ -1019,14 +727,14 @@
   Uint32 readTablePk(Uint32 localkey1);
   void getElement(Signal* signal);
   void getdirindex(Signal* signal);
-  void commitdelete(Signal* signal, bool systemRestart);
+  void commitdelete(Signal* signal);
   void deleteElement(Signal* signal);
   void getLastAndRemove(Signal* signal);
   void releaseLeftlist(Signal* signal);
   void releaseRightlist(Signal* signal);
   void checkoverfreelist(Signal* signal);
   void abortOperation(Signal* signal);
-  void accAbortReqLab(Signal* signal, bool sendConf);
+  void accAbortReqLab(Signal* signal);
   void commitOperation(Signal* signal);
   void copyOpInfo(Signal* signal);
   Uint32 executeNextOperation(Signal* signal);
@@ -1035,11 +743,11 @@
   void check_lock_upgrade(Signal* signal, OperationrecPtr lock_owner,
 			  OperationrecPtr release_op);
   void allocOverflowPage(Signal* signal);
-  bool getrootfragmentrec(Signal* signal, RootfragmentrecPtr&, Uint32 fragId);
+  bool getfragmentrec(Signal* signal, FragmentrecPtr&, Uint32 fragId);
   void insertLockOwnersList(Signal* signal, const OperationrecPtr&);
   void takeOutLockOwnersList(Signal* signal, const OperationrecPtr&);
+
   void initFsOpRec(Signal* signal);
-  void initLcpConnRec(Signal* signal);
   void initOverpage(Signal* signal);
   void initPage(Signal* signal);
   void initRootfragrec(Signal* signal);
@@ -1050,27 +758,21 @@
   void releaseDirrange(Signal* signal);
   void releaseFsConnRec(Signal* signal);
   void releaseFsOpRec(Signal* signal);
-  void releaseLcpConnectRec(Signal* signal);
   void releaseOpRec(Signal* signal);
   void releaseOverflowRec(Signal* signal);
   void releaseOverpage(Signal* signal);
   void releasePage(Signal* signal);
-  void releaseLcpPage(Signal* signal);
-  void releaseSrRec(Signal* signal);
   void releaseLogicalPage(Fragmentrec * fragP, Uint32 logicalPageId);
   void seizeDirectory(Signal* signal);
   void seizeDirrange(Signal* signal);
   void seizeFragrec(Signal* signal);
   void seizeFsConnectRec(Signal* signal);
   void seizeFsOpRec(Signal* signal);
-  void seizeLcpConnectRec(Signal* signal);
   void seizeOpRec(Signal* signal);
   void seizeOverRec(Signal* signal);
   void seizePage(Signal* signal);
-  void seizeLcpPage(Page8Ptr&);
   void seizeRootfragrec(Signal* signal);
   void seizeScanRec(Signal* signal);
-  void seizeSrVerRec(Signal* signal);
   void sendSystemerror(Signal* signal, int line);
   void takeRecOutOfFreeOverdir(Signal* signal);
   void takeRecOutOfFreeOverpage(Signal* signal);
@@ -1078,51 +780,26 @@
 
   void addFragRefuse(Signal* signal, Uint32 errorCode);
   void ndbsttorryLab(Signal* signal);
-  void srCloseDataFileLab(Signal* signal);
   void acckeyref1Lab(Signal* signal, Uint32 result_code);
   void insertelementLab(Signal* signal);
-  void startUndoLab(Signal* signal);
   void checkNextFragmentLab(Signal* signal);
   void endofexpLab(Signal* signal);
   void endofshrinkbucketLab(Signal* signal);
-  void srStartUndoLab(Signal* signal);
   void senddatapagesLab(Signal* signal);
-  void undoNext2Lab(Signal* signal);
   void sttorrysignalLab(Signal* signal);
   void sendholdconfsignalLab(Signal* signal);
   void accIsLockedLab(Signal* signal);
   void insertExistElemLab(Signal* signal);
   void refaccConnectLab(Signal* signal);
-  void srReadOverPagesLab(Signal* signal);
   void releaseScanLab(Signal* signal);
-  void lcpOpenUndofileConfLab(Signal* signal);
-  void srFsOpenConfLab(Signal* signal);
-  void checkSyncUndoPagesLab(Signal* signal);
-  void sendaccSrconfLab(Signal* signal);
-  void checkSendLcpConfLab(Signal* signal);
-  void endsaveoverpageLab(Signal* signal);
-  void lcpCloseDataFileLab(Signal* signal);
-  void srOpenDataFileLoopLab(Signal* signal);
-  void srReadPagesLab(Signal* signal);
-  void srDoUndoLab(Signal* signal);
   void ndbrestart1Lab(Signal* signal);
   void initialiseRecordsLab(Signal* signal, Uint32 ref, Uint32 data);
-  void srReadPagesAllocLab(Signal* signal);
   void checkNextBucketLab(Signal* signal);
-  void endsavepageLab(Signal* signal);
-  void saveZeroPageLab(Signal* signal);
-  void srAllocPage0011Lab(Signal* signal);
-  void sendLcpFragidconfLab(Signal* signal);
-  void savepagesLab(Signal* signal);
-  void saveOverPagesLab(Signal* signal);
-  void srReadPageZeroLab(Signal* signal);
   void storeDataPageInDirectoryLab(Signal* signal);
-  void lcpFsOpenConfLab(Signal* signal);
 
   void zpagesize_error(const char* where);
 
   void reportMemoryUsage(Signal* signal, int gth);
-  void lcp_write_op_to_undolog(Signal* signal);
   void reenable_expand_after_redo_log_exection_complete(Signal*);
 
   // charsets
@@ -1166,25 +843,6 @@
 /* --------------------------------------------------------------------------------- */
 /* FS_CONNECTREC                                                                     */
 /* --------------------------------------------------------------------------------- */
-  FsConnectrec *fsConnectrec;
-  FsConnectrecPtr fsConnectptr;
-  Uint32 cfsConnectsize;
-  Uint32 cfsFirstfreeconnect;
-/* --------------------------------------------------------------------------------- */
-/* FS_OPREC                                                                          */
-/* --------------------------------------------------------------------------------- */
-  FsOprec *fsOprec;
-  FsOprecPtr fsOpptr;
-  Uint32 cfsOpsize;
-  Uint32 cfsFirstfreeop;
-/* --------------------------------------------------------------------------------- */
-/* LCP_CONNECTREC                                                                    */
-/* --------------------------------------------------------------------------------- */
-  LcpConnectrec *lcpConnectrec;
-  LcpConnectrecPtr lcpConnectptr;
-  Uint32 clcpConnectsize;
-  Uint32 cfirstfreelcpConnect;
-/* --------------------------------------------------------------------------------- */
 /* OPERATIONREC                                                                      */
 /* --------------------------------------------------------------------------------- */
   Operationrec *operationrec;
@@ -1254,9 +912,7 @@
   Uint32 cfirstfreepage;
   Uint32 cfreepage;
   Uint32 cpagesize;
-  Uint32 cfirstfreeLcpPage;
   Uint32 cnoOfAllocatedPages;
-  Uint32 cnoLcpPages;
 /* --------------------------------------------------------------------------------- */
 /* ROOTFRAGMENTREC                                                                   */
 /*          DURING EXPAND FRAGMENT PROCESS, EACH FRAGMEND WILL BE EXPAND INTO TWO    */
@@ -1265,10 +921,6 @@
 /*          ADDED IN (NDBACC). THEREBY EXPAND OF FRAGMENT CAN BE PERFORMED QUICK AND */
 /*          EASY.THE NEW FRAGMENT ID SENDS TO TUP MANAGER FOR ALL OPERATION PROCESS. */
 /* --------------------------------------------------------------------------------- */
-  Rootfragmentrec *rootfragmentrec;
-  RootfragmentrecPtr rootfragrecptr;
-  Uint32 crootfragmentsize;
-  Uint32 cfirstfreerootfrag;
 /* --------------------------------------------------------------------------------- */
 /* SCAN_REC                                                                          */
 /* --------------------------------------------------------------------------------- */
@@ -1277,24 +929,11 @@
   Uint32 cscanRecSize;
   Uint32 cfirstFreeScanRec;
 /* --------------------------------------------------------------------------------- */
-/* SR_VERSION_REC                                                                    */
-/* --------------------------------------------------------------------------------- */
-  SrVersionRec *srVersionRec;
-  SrVersionRecPtr srVersionPtr;
-  Uint32 csrVersionRecSize;
-  Uint32 cfirstFreeSrVersionRec;
-/* --------------------------------------------------------------------------------- */
 /* TABREC                                                                            */
 /* --------------------------------------------------------------------------------- */
   Tabrec *tabrec;
   TabrecPtr tabptr;
   Uint32 ctablesize;
-/* --------------------------------------------------------------------------------- */
-/* UNDOPAGE                                                                          */
-/* --------------------------------------------------------------------------------- */
-  Undopage *undopage;
-                                                   /* 32 KB PAGE                      */
-  UndopagePtr undopageptr;
   Uint32 tpwiElementptr;
   Uint32 tpriElementptr;
   Uint32 tgseElementptr;
@@ -1335,7 +974,6 @@
   Uint32 tgeContainerptr;
   Uint32 tgeElementptr;
   Uint32 tgeForward;
-  Uint32 tundoElemIndex;
   Uint32 texpReceivedBucket;
   Uint32 texpDirInd;
   Uint32 texpDirRangeIndex;
@@ -1357,7 +995,6 @@
   Uint32 tsscElementptr;
   Uint32 tfid;
   Uint32 tscanFlag;
-  Uint32 theadundoindex;
   Uint32 tgflBufType;
   Uint32 tgseIsforward;
   Uint32 tsscIsforward;
@@ -1388,11 +1025,9 @@
   Uint32 tslUpdateHeader;
   Uint32 tuserptr;
   BlockReference tuserblockref;
-  Uint32 tundoindex;
   Uint32 tlqhPointer;
   Uint32 tholdSentOp;
   Uint32 tholdMore;
-  Uint32 tlcpLqhCheckV;
   Uint32 tgdiPageindex;
   Uint32 tiopIndex;
   Uint32 tnciTmp;
@@ -1403,35 +1038,15 @@
   Uint32 tscanTrid1;
   Uint32 tscanTrid2;
 
-  Uint16 clastUndoPageIdWritten;
-  Uint32 cactiveCheckpId;
-  Uint32 cactiveRootfrag;
-  Uint32 cactiveSrFsPtr;
-  Uint32 cactiveUndoFilePage;
-  Uint32 cactiveOpenUndoFsPtr;
-  Uint32 cactiveSrUndoPage;
-  Uint32 cprevUndoaddress;
-  Uint32 creadyUndoaddress;
   Uint32 ctest;
-  Uint32 cundoLogActive;
   Uint32 clqhPtr;
   BlockReference clqhBlockRef;
   Uint32 cminusOne;
   NodeId cmynodeid;
-  Uint32 cactiveUndoFileVersion;
   BlockReference cownBlockref;
   BlockReference cndbcntrRef;
   Uint16 csignalkey;
-  Uint32 cundopagesize;
-  Uint32 cundoposition;
-  Uint32 cundoElemIndex;
-  Uint32 cundoinfolength;
   Uint32 czero;
-  Uint32 csrVersList[16];
-  Uint32 clblPageCounter;
-  Uint32 clblPageOver;
-  Uint32 clblPagesPerTick;
-  Uint32 clblPagesPerTickAfterSr;
   Uint32 csystemRestart;
   Uint32 cexcForward;
   Uint32 cexcPageindex;
@@ -1451,7 +1066,6 @@
   };
   
   Uint32 c_errorInsert3000_TableId;
-  Uint32 cSrUndoRecords[UndoHeader::ZNO_UNDORECORD_TYPES];
 };
 
 #endif

--- 1.39.3.1/ndb/src/kernel/vm/Configuration.cpp	2006-02-07 20:09:44 +03:00
+++ 1.45/storage/ndb/src/kernel/vm/Configuration.cpp	2006-02-09 13:34:38 +03:00
@@ -603,13 +603,9 @@
     case NODE_TYPE_API:
       noOfAPINodes++; // No of API processes
       break;
-    case NODE_TYPE_REP:
-      break;
     case NODE_TYPE_MGM:
       noOfMGMNodes++; // No of MGM processes
       break;
-    case NODE_TYPE_EXT_REP:
-      break;
     default:
       BaseString::snprintf(buf, sizeof(buf), "Unknown node type: %d", nodeType);
       ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
@@ -674,14 +670,14 @@
      */
     // Can keep 65536 pages (= 0.5 GByte)
     cfg.put(CFG_ACC_DIR_RANGE, 
-	    4 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas); 
+	    2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas); 
     
     cfg.put(CFG_ACC_DIR_ARRAY,
 	    (noOfIndexPages >> 8) + 
-	    4 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
+	    2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
     
     cfg.put(CFG_ACC_FRAGMENT,
-	    2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
+	    NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
     
     /*-----------------------------------------------------------------------*/
     // The extra operation records added are used by the scan and node 
@@ -697,14 +693,11 @@
     
     cfg.put(CFG_ACC_OVERFLOW_RECS,
 	    noOfIndexPages + 
-	    2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
+	    NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
     
     cfg.put(CFG_ACC_PAGE8, 
 	    noOfIndexPages + 32);
     
-    cfg.put(CFG_ACC_ROOT_FRAG, 
-	    NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
-    
     cfg.put(CFG_ACC_TABLE, noOfAccTables);
     
     cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords);
@@ -787,7 +780,7 @@
      * Tup Size Alt values
      */
     cfg.put(CFG_TUP_FRAG, 
-	    2 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
+	    NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
     
     cfg.put(CFG_TUP_OP_RECS, 
 	    noOfLocalOperations + 50);
@@ -796,14 +789,14 @@
 	    noOfDataPages);
     
     cfg.put(CFG_TUP_PAGE_RANGE, 
-	    4 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
+	    2 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
     
     cfg.put(CFG_TUP_TABLE, 
 	    noOfMetaTables);
     
     cfg.put(CFG_TUP_TABLE_DESC, 
-	    2 * 6 * NO_OF_FRAG_PER_NODE * noOfAttributes * noOfReplicas +
-	    2 * 10 * NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas );
+	    6 * NO_OF_FRAG_PER_NODE * noOfAttributes * noOfReplicas +
+	    10 * NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas );
     
     cfg.put(CFG_TUP_STORED_PROC,
 	    noOfLocalScanRecords);
@@ -817,7 +810,7 @@
 	    noOfMetaTables /*noOfOrderedIndexes*/);
     
     cfg.put(CFG_TUX_FRAGMENT,
-	    2 * NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas);
+	    NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas);
     
     cfg.put(CFG_TUX_ATTRIBUTE, 
 	    noOfOrderedIndexes * 4);

--- 1.16.1.1/ndb/tools/delete_all.cpp	2006-02-06 00:50:58 +03:00
+++ 1.19/storage/ndb/tools/delete_all.cpp	2006-02-09 13:34:38 +03:00
@@ -142,7 +142,8 @@
       goto failed;
     }
     
-    if( pOp->readTuples(NdbOperation::LM_Exclusive,par) ) {
+    if( pOp->readTuples(NdbOperation::LM_Exclusive, 
+			NdbScanOperation::SF_TupScan, par) ) {
       goto failed;
     }
     

--- 1.263/sql/ha_ndbcluster.cc	2006-02-07 18:31:10 +03:00
+++ 1.264/sql/ha_ndbcluster.cc	2006-02-09 13:34:35 +03:00
@@ -6199,6 +6199,10 @@
 {
   return NDB_MAX_KEY_SIZE;
 }
+uint ha_ndbcluster::max_supported_key_part_length() const
+{
+  return NDB_MAX_KEY_SIZE;
+}
 bool ha_ndbcluster::low_byte_first() const
 { 
 #ifdef WORDS_BIGENDIAN

--- 1.116/sql/ha_ndbcluster.h	2006-02-01 15:04:39 +03:00
+++ 1.117/sql/ha_ndbcluster.h	2006-02-09 13:34:35 +03:00
@@ -604,6 +604,7 @@
   uint max_supported_keys() const;
   uint max_supported_key_parts() const;
   uint max_supported_key_length() const;
+  uint max_supported_key_part_length() const;
 
   int rename_table(const char *from, const char *to);
   int delete_table(const char *name);

--- 1.85/mysql-test/r/fulltext.result	2006-01-26 14:12:54 +03:00
+++ 1.86/mysql-test/r/fulltext.result	2006-02-09 13:34:34 +03:00
@@ -449,3 +449,14 @@
   FULLTEXT KEY `a` (`a`)
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 DROP TABLE t1;
+CREATE TABLE t1 (a TEXT, FULLTEXT KEY(a));
+INSERT INTO t1 VALUES('test'),('test1'),('test');
+PREPARE stmt from "SELECT a, MATCH(a) AGAINST('test1 test') FROM t1 WHERE MATCH(a)
AGAINST('test1 test')";
+EXECUTE stmt;
+a	MATCH(a) AGAINST('test1 test')
+test1	0.68526661396027
+EXECUTE stmt;
+a	MATCH(a) AGAINST('test1 test')
+test1	0.68526661396027
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;

--- 1.80/mysql-test/t/fulltext.test	2006-01-16 21:27:30 +03:00
+++ 1.81/mysql-test/t/fulltext.test	2006-02-09 13:34:34 +03:00
@@ -371,4 +371,16 @@
 SHOW CREATE TABLE t1;
 DROP TABLE t1;
 
+#
+# BUG#14496: Crash or strange results with prepared statement,
+#            MATCH and FULLTEXT
+#
+CREATE TABLE t1 (a TEXT, FULLTEXT KEY(a));
+INSERT INTO t1 VALUES('test'),('test1'),('test');
+PREPARE stmt from "SELECT a, MATCH(a) AGAINST('test1 test') FROM t1 WHERE MATCH(a)
AGAINST('test1 test')";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
 # End of 4.1 tests

--- 1.16/mysql-test/r/ndb_blob.result	2005-09-15 04:31:38 +04:00
+++ 1.17/mysql-test/r/ndb_blob.result	2006-02-09 13:34:34 +03:00
@@ -428,6 +428,13 @@
 select * from t1;
 a	b
 commit;
+replace t1 set a=2, b='y';
+select * from t1;
+a	b
+2	y
+delete from t1;
+select * from t1;
+a	b
 drop table t1;
 set autocommit=0;
 create table t1 (

--- 1.22.4.2/ndb/src/ndbapi/NdbBlob.cpp	2006-02-03 17:27:06 +03:00
+++ 1.36/storage/ndb/src/ndbapi/NdbBlob.cpp	2006-02-09 13:34:38 +03:00
@@ -23,6 +23,7 @@
 #include <NdbBlob.hpp>
 #include "NdbBlobImpl.hpp"
 #include <NdbScanOperation.hpp>
+#include <NdbEventOperationImpl.hpp>
 
 /*
  * Reading index table directly (as a table) is faster but there are
@@ -30,7 +31,21 @@
  */
 static const bool g_ndb_blob_ok_to_read_index_table = false;
 
-// state (inline)
+// get state
+
+NdbBlob::State
+NdbBlob::getState()
+{
+  return theState;
+}
+
+void
+NdbBlob::getVersion(int& version)
+{
+  version = theEventBlobVersion;
+}
+
+// set state (inline)
 
 inline void
 NdbBlob::setState(State newState)
@@ -61,17 +76,53 @@
 {
   assert(t != 0 && c != 0 && c->getBlobType());
   memset(btname, 0, NdbBlobImpl::BlobTableNameSize);
-  sprintf(btname, "NDB$BLOB_%d_%d", (int)t->m_tableId, (int)c->m_attrId);
+  sprintf(btname, "NDB$BLOB_%d_%d", (int)t->m_id, (int)c->m_column_no);
 }
 
 void
 NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl*
c)
 {
+  DBUG_ENTER("NdbBlob::getBlobTable");
   char btname[NdbBlobImpl::BlobTableNameSize];
   getBlobTableName(btname, t, c);
   bt.setName(btname);
   bt.setLogging(t->getLogging());
-  bt.setFragmentType(t->getFragmentType());
+  /*
+    BLOB tables use the same fragmentation as the original table
+    but may change the fragment type if it is UserDefined since it
+    must be hash based so that the kernel can handle it on its own.
+    It also uses the same tablespaces and it never uses any range or
+    list arrays.
+  */
+  bt.m_primaryTableId = t->m_id;
+  bt.m_fd.clear();
+  bt.m_ts.clear();
+  bt.m_range.clear();
+  bt.setFragmentCount(t->getFragmentCount());
+  bt.m_tablespace_id = t->m_tablespace_id;
+  bt.m_tablespace_version = t->m_tablespace_version;
+  switch (t->getFragmentType())
+  {
+    case NdbDictionary::Object::FragAllSmall:
+    case NdbDictionary::Object::FragAllMedium:
+    case NdbDictionary::Object::FragAllLarge:
+    case NdbDictionary::Object::FragSingle:
+      bt.setFragmentType(t->getFragmentType());
+      break;
+    case NdbDictionary::Object::DistrKeyLin:
+    case NdbDictionary::Object::DistrKeyHash:
+      bt.setFragmentType(t->getFragmentType());
+      break;
+    case NdbDictionary::Object::UserDefined:
+      bt.setFragmentType(NdbDictionary::Object::DistrKeyHash);
+      break;
+    default:
+      DBUG_ASSERT(0);
+      break;
+  }
+  DBUG_PRINT("info",
+  ("Create BLOB table with primary table = %u and Fragment Type = %u",
+    bt.m_primaryTableId, (uint)bt.getFragmentType()));
   { NdbDictionary::Column bc("PK");
     bc.setType(NdbDictionary::Column::Unsigned);
     assert(t->m_keyLenInWords != 0);
@@ -105,8 +156,66 @@
       break;
     }
     bc.setLength(c->getPartSize());
+    bc.setStorageType(c->getStorageType());
     bt.addColumn(bc);
   }
+  DBUG_VOID_RETURN;
+}
+
+int
+NdbBlob::getBlobEventName(char* bename, Ndb* anNdb, const char* eventName, const char*
columnName)
+{
+  NdbEventImpl* e = anNdb->theDictionary->m_impl.getEvent(eventName);
+  if (e == NULL)
+    return -1;
+  NdbColumnImpl* c = e->m_tableImpl->getColumn(columnName);
+  if (c == NULL)
+    return -1;
+  getBlobEventName(bename, e, c);
+  delete e; // it is from new NdbEventImpl
+  return 0;
+}
+
+void
+NdbBlob::getBlobEventName(char* bename, const NdbEventImpl* e, const NdbColumnImpl* c)
+{
+  // XXX events should have object id
+  snprintf(bename, MAX_TAB_NAME_SIZE, "NDB$BLOBEVENT_%s_%d", e->m_name.c_str(),
(int)c->m_column_no);
+}
+
+void
+NdbBlob::getBlobEvent(NdbEventImpl& be, const NdbEventImpl* e, const NdbColumnImpl*
c)
+{
+  DBUG_ENTER("NdbBlob::getBlobEvent");
+  // blob table
+  assert(c->m_blobTable != NULL);
+  const NdbTableImpl& bt = *c->m_blobTable;
+  // blob event name
+  char bename[NdbBlobImpl::BlobTableNameSize];
+  getBlobEventName(bename, e, c);
+  be.setName(bename);
+  be.setTable(bt);
+  // simple assigments
+  be.mi_type = e->mi_type;
+  be.m_dur = e->m_dur;
+  be.m_mergeEvents = e->m_mergeEvents;
+  // report unchanged data
+  // not really needed now since UPD is DEL o INS and we subscribe to all
+  be.setReport(NdbDictionary::Event::ER_ALL);
+  // columns PK - DIST - PART - DATA
+  { const NdbColumnImpl* bc = bt.getColumn((Uint32)0);
+    be.addColumn(*bc);
+  }
+  { const NdbColumnImpl* bc = bt.getColumn((Uint32)1);
+    be.addColumn(*bc);
+  }
+  { const NdbColumnImpl* bc = bt.getColumn((Uint32)2);
+    be.addColumn(*bc);
+  }
+  { const NdbColumnImpl* bc = bt.getColumn((Uint32)3);
+    be.addColumn(*bc);
+  }
+  DBUG_VOID_RETURN;
 }
 
 // initialization
@@ -120,9 +229,16 @@
 NdbBlob::init()
 {
   theState = Idle;
+  theEventBlobVersion = -1;
   theNdb = NULL;
   theNdbCon = NULL;
   theNdbOp = NULL;
+  theEventOp = NULL;
+  theBlobEventOp = NULL;
+  theBlobEventPkRecAttr = NULL;
+  theBlobEventDistRecAttr = NULL;
+  theBlobEventPartRecAttr = NULL;
+  theBlobEventDataRecAttr = NULL;
   theTable = NULL;
   theAccessTable = NULL;
   theBlobTable = NULL;
@@ -330,7 +446,7 @@
     assert(c != NULL);
     if (c->m_pk) {
       unsigned len = c->m_attrSize * c->m_arraySize;
-      if (anOp->equal_impl(c, (const char*)&data[pos], len) == -1) {
+      if (anOp->equal_impl(c, (const char*)&data[pos]) == -1) {
         setErrorCode(anOp);
         DBUG_RETURN(-1);
       }
@@ -354,7 +470,7 @@
     assert(c != NULL);
     if (c->m_pk) {
       unsigned len = c->m_attrSize * c->m_arraySize;
-      if (anOp->equal_impl(c, (const char*)&data[pos], len) == -1) {
+      if (anOp->equal_impl(c, (const char*)&data[pos]) == -1) {
         setErrorCode(anOp);
         DBUG_RETURN(-1);
       }
@@ -371,8 +487,8 @@
   DBUG_ENTER("NdbBlob::setPartKeyValue");
   DBUG_PRINT("info", ("dist=%u part=%u key=", getDistKey(part), part));
   DBUG_DUMP("info", theKeyBuf.data, 4 * theTable->m_keyLenInWords);
-  Uint32* data = (Uint32*)theKeyBuf.data;
-  unsigned size = theTable->m_keyLenInWords;
+  //Uint32* data = (Uint32*)theKeyBuf.data;
+  //unsigned size = theTable->m_keyLenInWords;
   // TODO use attr ids after compatibility with 4.1.7 not needed
   if (anOp->equal("PK", theKeyBuf.data) == -1 ||
       anOp->equal("DIST", getDistKey(part)) == -1 ||
@@ -401,7 +517,7 @@
   DBUG_ENTER("NdbBlob::getHeadFromRecAttr");
   assert(theHeadInlineRecAttr != NULL);
   theNullFlag = theHeadInlineRecAttr->isNULL();
-  assert(theNullFlag != -1);
+  assert(theEventBlobVersion >= 0 || theNullFlag != -1);
   theLength = ! theNullFlag ? theHead->length : 0;
   DBUG_VOID_RETURN;
 }
@@ -415,7 +531,7 @@
     memset(theInlineData + theLength, 0, theInlineSize - theLength);
   assert(theNullFlag != -1);
   const char* aValue = theNullFlag ? 0 : theHeadInlineBuf.data;
-  if (anOp->setValue(theColumn, aValue, theHeadInlineBuf.size) == -1) {
+  if (anOp->setValue(theColumn, aValue) == -1) {
     setErrorCode(anOp);
     DBUG_RETURN(-1);
   }
@@ -506,7 +622,19 @@
 // misc operations
 
 int
-NdbBlob::getNull(bool& isNull)
+NdbBlob::getDefined(int& isNull) // deprecated
+{
+  DBUG_ENTER("NdbBlob::getDefined");
+  if (theState == Prepared && theSetFlag) {
+    isNull = (theSetBuf == NULL);
+    DBUG_RETURN(0);
+  }
+  isNull = theNullFlag;
+  DBUG_RETURN(0);
+}
+
+int
+NdbBlob::getNull(bool& isNull) // deprecated
 {
   DBUG_ENTER("NdbBlob::getNull");
   if (theState == Prepared && theSetFlag) {
@@ -522,6 +650,23 @@
 }
 
 int
+NdbBlob::getNull(int& isNull)
+{
+  DBUG_ENTER("NdbBlob::getNull");
+  if (theState == Prepared && theSetFlag) {
+    isNull = (theSetBuf == NULL);
+    DBUG_RETURN(0);
+  }
+  isNull = theNullFlag;
+  if (isNull == -1 && theEventBlobVersion == -1) {
+    setErrorCode(NdbBlobImpl::ErrState);
+    DBUG_RETURN(-1);
+  }
+  DBUG_PRINT("info", ("isNull=%d", isNull));
+  DBUG_RETURN(0);
+}
+
+int
 NdbBlob::setNull()
 {
   DBUG_ENTER("NdbBlob::setNull");
@@ -849,6 +994,18 @@
 {
   DBUG_ENTER("NdbBlob::readParts");
   DBUG_PRINT("info", ("part=%u count=%u", part, count));
+  int ret;
+  if (theEventBlobVersion == -1)
+    ret = readTableParts(buf, part, count);
+  else
+    ret = readEventParts(buf, part, count);
+  DBUG_RETURN(ret);
+}
+
+int
+NdbBlob::readTableParts(char* buf, Uint32 part, Uint32 count)
+{
+  DBUG_ENTER("NdbBlob::readTableParts");
   Uint32 n = 0;
   while (n < count) {
     NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
@@ -869,6 +1026,18 @@
 }
 
 int
+NdbBlob::readEventParts(char* buf, Uint32 part, Uint32 count)
+{
+  DBUG_ENTER("NdbBlob::readEventParts");
+  int ret = theEventOp->readBlobParts(buf, this, part, count);
+  if (ret != 0) {
+    setErrorCode(theEventOp);
+    DBUG_RETURN(-1);
+  }
+  DBUG_RETURN(0);
+}
+
+int
 NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
 {
   DBUG_ENTER("NdbBlob::insertParts");
@@ -1058,48 +1227,12 @@
   theTable = anOp->m_currentTable;
   theAccessTable = anOp->m_accessTable;
   theColumn = aColumn;
-  NdbDictionary::Column::Type partType = NdbDictionary::Column::Undefined;
-  switch (theColumn->getType()) {
-  case NdbDictionary::Column::Blob:
-    partType = NdbDictionary::Column::Binary;
-    theFillChar = 0x0;
-    break;
-  case NdbDictionary::Column::Text:
-    partType = NdbDictionary::Column::Char;
-    theFillChar = 0x20;
-    break;
-  default:
-    setErrorCode(NdbBlobImpl::ErrUsage);
+  // prepare blob column and table
+  if (prepareColumn() == -1)
     DBUG_RETURN(-1);
-  }
-  // sizes
-  theInlineSize = theColumn->getInlineSize();
-  thePartSize = theColumn->getPartSize();
-  theStripeSize = theColumn->getStripeSize();
-  // sanity check
-  assert((NDB_BLOB_HEAD_SIZE << 2) == sizeof(Head));
-  assert(theColumn->m_attrSize * theColumn->m_arraySize == sizeof(Head) +
theInlineSize);
-  if (thePartSize > 0) {
-    const NdbDictionary::Table* bt = NULL;
-    const NdbDictionary::Column* bc = NULL;
-    if (theStripeSize == 0 ||
-        (bt = theColumn->getBlobTable()) == NULL ||
-        (bc = bt->getColumn("DATA")) == NULL ||
-        bc->getType() != partType ||
-        bc->getLength() != (int)thePartSize) {
-      setErrorCode(NdbBlobImpl::ErrTable);
-      DBUG_RETURN(-1);
-    }
-    theBlobTable = &NdbTableImpl::getImpl(*bt);
-  }
-  // buffers
-  theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+  // extra buffers
   theAccessKeyBuf.alloc(theAccessTable->m_keyLenInWords << 2);
-  theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
   theHeadInlineCopyBuf.alloc(sizeof(Head) + theInlineSize);
-  thePartBuf.alloc(thePartSize);
-  theHead = (Head*)theHeadInlineBuf.data;
-  theInlineData = theHeadInlineBuf.data + sizeof(Head);
   // handle different operation types
   bool supportedOp = false;
   if (isKeyOp()) {
@@ -1153,6 +1286,103 @@
   DBUG_RETURN(0);
 }
 
+int
+NdbBlob::atPrepare(NdbEventOperationImpl* anOp, NdbEventOperationImpl* aBlobOp, const
NdbColumnImpl* aColumn, int version)
+{
+  DBUG_ENTER("NdbBlob::atPrepare [event]");
+  DBUG_PRINT("info", ("this=%p op=%p", this, anOp));
+  assert(theState == Idle);
+  assert(version == 0 || version == 1);
+  theEventBlobVersion = version;
+  // ndb api stuff
+  theNdb = anOp->m_ndb;
+  theEventOp = anOp;
+  theBlobEventOp = aBlobOp;
+  theTable = anOp->m_eventImpl->m_tableImpl;
+  theColumn = aColumn;
+  // prepare blob column and table
+  if (prepareColumn() == -1)
+    DBUG_RETURN(-1);
+  // tinyblob sanity
+  assert((theBlobEventOp == NULL) == (theBlobTable == NULL));
+  // extra buffers
+  theBlobEventDataBuf.alloc(thePartSize);
+  // prepare receive of head+inline
+  theHeadInlineRecAttr = theEventOp->getValue(aColumn, theHeadInlineBuf.data,
version);
+  if (theHeadInlineRecAttr == NULL) {
+    setErrorCode(theEventOp);
+    DBUG_RETURN(-1);
+  }
+  // prepare receive of blob part
+  if (theBlobEventOp != NULL) {
+    if ((theBlobEventPkRecAttr =
+           theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)0),
+                                    theKeyBuf.data, version)) == NULL ||
+        (theBlobEventDistRecAttr =
+           theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)1),
+                                    (char*)0, version)) == NULL ||
+        (theBlobEventPartRecAttr =
+           theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)2),
+                                    (char*)&thePartNumber, version)) == NULL ||
+        (theBlobEventDataRecAttr =
+           theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)3),
+                                    theBlobEventDataBuf.data, version)) == NULL) {
+      setErrorCode(theBlobEventOp);
+      DBUG_RETURN(-1);
+    }
+  }
+  setState(Prepared);
+  DBUG_RETURN(0);
+}
+
+int
+NdbBlob::prepareColumn()
+{
+  DBUG_ENTER("prepareColumn");
+  NdbDictionary::Column::Type partType = NdbDictionary::Column::Undefined;
+  switch (theColumn->getType()) {
+  case NdbDictionary::Column::Blob:
+    partType = NdbDictionary::Column::Binary;
+    theFillChar = 0x0;
+    break;
+  case NdbDictionary::Column::Text:
+    partType = NdbDictionary::Column::Char;
+    theFillChar = 0x20;
+    break;
+  default:
+    setErrorCode(NdbBlobImpl::ErrUsage);
+    DBUG_RETURN(-1);
+  }
+  // sizes
+  theInlineSize = theColumn->getInlineSize();
+  thePartSize = theColumn->getPartSize();
+  theStripeSize = theColumn->getStripeSize();
+  // sanity check
+  assert((NDB_BLOB_HEAD_SIZE << 2) == sizeof(Head));
+  assert(theColumn->m_attrSize * theColumn->m_arraySize == sizeof(Head) +
theInlineSize);
+  if (thePartSize > 0) {
+    const NdbTableImpl* bt = NULL;
+    const NdbColumnImpl* bc = NULL;
+    if (theStripeSize == 0 ||
+        (bt = theColumn->m_blobTable) == NULL ||
+        (bc = bt->getColumn("DATA")) == NULL ||
+        bc->getType() != partType ||
+        bc->getLength() != (int)thePartSize) {
+      setErrorCode(NdbBlobImpl::ErrTable);
+      DBUG_RETURN(-1);
+    }
+    // blob table
+    theBlobTable = &NdbTableImpl::getImpl(*bt);
+  }
+  // these buffers are always used
+  theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+  theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+  theHead = (Head*)theHeadInlineBuf.data;
+  theInlineData = theHeadInlineBuf.data + sizeof(Head);
+  thePartBuf.alloc(thePartSize);
+  DBUG_RETURN(0);
+}
+
 /*
  * Before execute of prepared operation.  May add new operations before
  * this one.  May ask that this operation and all before it (a "batch")
@@ -1501,6 +1731,26 @@
   DBUG_RETURN(0);
 }
 
+/*
+ * After next event on main table.
+ */
+int
+NdbBlob::atNextEvent()
+{
+  DBUG_ENTER("NdbBlob::atNextEvent");
+  DBUG_PRINT("info", ("this=%p op=%p blob op=%p version=%d", this, theEventOp,
theBlobEventOp, theEventBlobVersion));
+  if (theState == Invalid)
+    DBUG_RETURN(-1);
+  assert(theEventBlobVersion >= 0);
+  getHeadFromRecAttr();
+  if (theNullFlag == -1) // value not defined
+    DBUG_RETURN(0);
+  if (setPos(0) == -1)
+    DBUG_RETURN(-1);
+  setState(Active);
+  DBUG_RETURN(0);
+}
+
 // misc
 
 const NdbDictionary::Column*
@@ -1547,6 +1797,17 @@
   if (theNdbCon != NULL && (code = theNdbCon->theError.code) != 0)
     ;
   else if ((code = theNdb->theError.code) != 0)
+    ;
+  else
+    code = NdbBlobImpl::ErrUnknown;
+  setErrorCode(code, invalidFlag);
+}
+
+void
+NdbBlob::setErrorCode(NdbEventOperationImpl* anOp, bool invalidFlag)
+{
+  int code = 0;
+  if ((code = anOp->m_error.code) != 0)
     ;
   else
     code = NdbBlobImpl::ErrUnknown;

--- 1.5/mysql-test/r/sp-code.result	2006-02-06 18:05:43 +03:00
+++ 1.6/mysql-test/r/sp-code.result	2006-02-09 13:34:34 +03:00
@@ -155,11 +155,11 @@
 0	stmt 9 "drop temporary table if exists sudoku..."
 1	stmt 1 "create temporary table sudoku_work ( ..."
 2	stmt 1 "create temporary table sudoku_schedul..."
-3	stmt 95 "call sudoku_init("
+3	stmt 94 "call sudoku_init("
 4	jump_if_not 7(8) p_naive@0
 5	stmt 4 "update sudoku_work set cnt = 0 where ..."
 6	jump 8
-7	stmt 95 "call sudoku_count("
+7	stmt 94 "call sudoku_count("
 8	stmt 6 "insert into sudoku_schedule (row,col)..."
 9	set v_scounter@2 0
 10	set v_i@3 1

--- 1.185/mysql-test/r/sp.result	2006-02-08 14:05:11 +03:00
+++ 1.186/mysql-test/r/sp.result	2006-02-09 13:34:34 +03:00
@@ -4011,8 +4011,6 @@
 call bug14643_2()|
 Handler
 boo
-2
-2
 Handler
 boo
 drop procedure bug14643_1|
@@ -4356,6 +4354,11 @@
 call bug14498_3()|
 v
 maybe
+Handler
+error
+End
+done
+call bug14498_4()|
 Handler
 error
 End

--- 1.6/mysql-test/t/sp-destruct.test	2006-01-24 15:56:46 +03:00
+++ 1.7/mysql-test/t/sp-destruct.test	2006-02-09 13:34:34 +03:00
@@ -127,6 +127,15 @@
 insert into t1 values (0);
 
 # Clean-up
-delete from mysql.proc where name like 'bug14233%';
 drop trigger t1_ai;
 drop table t1;
+
+#
+# BUG#16303: erroneus stored procedures and functions should be droppable
+#
+drop function bug14233_1;
+drop function bug14233_2;
+drop procedure bug14233_3;
+# Assert: These should show nothing.
+show procedure status;
+show function status;

--- 1.174/mysql-test/t/sp.test	2006-02-06 16:09:07 +03:00
+++ 1.175/mysql-test/t/sp.test	2006-02-09 13:34:34 +03:00
@@ -1444,11 +1444,11 @@
 call ifac(20)|
 select * from t3|
 drop table t3|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show function status like '%f%'|
 drop procedure ifac|
 drop function fac|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show function status like '%f%'|
 
 
@@ -1531,7 +1531,7 @@
   end while;
 end|
 show create procedure opp|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show procedure status like '%p%'|
 
 # This isn't the fastest way in the world to compute prime numbers, so
@@ -1549,7 +1549,7 @@
 drop table t3|
 drop procedure opp|
 drop procedure ip|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show procedure status like '%p%'|
 
 
@@ -1618,13 +1618,13 @@
 create procedure bar(x char(16), y int)
  comment "111111111111" sql security invoker
  insert into test.t1 values (x, y)|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show procedure status like 'bar'|
 alter procedure bar comment "2222222222" sql security definer|
 alter procedure bar comment "3333333333"|
 alter procedure bar|
 show create procedure bar|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show procedure status like 'bar'|
 drop procedure bar|
 
@@ -2574,7 +2574,6 @@
   show databases like 'foo';
   show errors;
   show columns from t1;
-  show grants for 'root'@'localhost';
   show keys from t1;
   show open tables like 'foo';
   show privileges;
@@ -2596,20 +2595,6 @@
 
 drop procedure bug4902|
 
-# We need separate SP for SHOW PROCESSLIST  since we want use replace_column
---disable_warnings
-drop procedure if exists bug4902_2|
---enable_warnings
-create procedure bug4902_2()
-begin
-  show processlist;
-end|
---replace_column 1 # 6 # 3 localhost
-call bug4902_2()|
---replace_column 1 # 6 # 3 localhost
-call bug4902_2()|
-drop procedure bug4902_2|
-
 #
 # BUG#4904
 #
@@ -2824,44 +2809,6 @@
 delete from t1|
 drop procedure bug4941|
 
-
-#
-# BUG#3583: query cache doesn't work for stored procedures
-#
---disable_warnings
-drop procedure if exists bug3583|
---enable_warnings
---disable_warnings
-drop procedure if exists bug3583|
---enable_warnings
-create procedure bug3583()
-begin
-  declare c int;
-
-  select * from t1;
-  select count(*) into c from t1;
-  select c;
-end|
-
-insert into t1 values ("x", 3), ("y", 5)|
-set @x = @@query_cache_size|
-set global query_cache_size = 10*1024*1024|
-
-flush status|
-flush query cache|
-show status like 'Qcache_hits'|
-call bug3583()|
-show status like 'Qcache_hits'|
-call bug3583()|
-call bug3583()|
-show status like 'Qcache_hits'|
-
-set global query_cache_size = @x|
-flush status|
-flush query cache|
-delete from t1|
-drop procedure bug3583|
-
 #
 # BUG#4905: Stored procedure doesn't clear for "Rows affected"
 #
@@ -3171,24 +3118,6 @@
 drop function bug5240|
 
 #
-# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
-#
---disable_warnings
-drop function if exists bug5278|
---enable_warnings
-create function bug5278 () returns char
-begin
-  SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
-  return 'okay';
-end|
-
---error 1133
-select bug5278()|
---error 1133
-select bug5278()|
-drop function bug5278|
-
-#
 # BUG#7992: rolling back temporary Item tree changes in SP
 #
 --disable_warnings
@@ -4209,9 +4138,13 @@
 --error 1062
 select bug12379()|
 select 1|
+# statement-based binlogging will show warning which row-based won't;
+# so we hide it (this warning is already tested in rpl_stm_sp.test)
+--disable_warnings
 call bug12379_1()|
 select 2|
 call bug12379_2()|
+--enable_warnings
 select 3|
 --error 1062
 call bug12379_3()|
@@ -4785,24 +4718,6 @@
 call bug10100t(5)|
 
 #end of the stack checking
-set @@max_sp_recursion_depth=255|
-set @var=1|
-#disable log because error about stack overrun contains numbers which
-#depend on a system
--- disable_result_log
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100p(255, @var)|
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100pt(1,255)|
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100pv(1,255)|
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100pd(1,255)|
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100pc(1,255)|
--- enable_result_log
-set @@max_sp_recursion_depth=0|
-
 deallocate prepare stmt2|
 
 drop function bug10100f|

--- 1.101/sql/sp.cc	2006-01-28 21:21:12 +03:00
+++ 1.102/sql/sp.cc	2006-02-09 13:34:35 +03:00
@@ -1003,22 +1003,26 @@
 }
 
 
+/*
+  This is used by sql_acl.cc:mysql_routine_grant() and is used to find
+  the routines in 'routines'.
+*/
 
 int
-sp_exists_routine(THD *thd, TABLE_LIST *tables, bool any, bool no_error)
+sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
 {
-  TABLE_LIST *table;
+  TABLE_LIST *routine;
   bool result= 0;
   DBUG_ENTER("sp_exists_routine");
-  for (table= tables; table; table= table->next_global)
+  for (routine= routines; routine; routine= routine->next_global)
   {
     sp_name *name;
     LEX_STRING lex_db;
     LEX_STRING lex_name;
-    lex_db.length= strlen(table->db);
-    lex_name.length= strlen(table->table_name);
-    lex_db.str= thd->strmake(table->db, lex_db.length);
-    lex_name.str= thd->strmake(table->table_name, lex_name.length);
+    lex_db.length= strlen(routine->db);
+    lex_name.length= strlen(routine->table_name);
+    lex_db.str= thd->strmake(routine->db, lex_db.length);
+    lex_name.str= thd->strmake(routine->table_name, lex_name.length);
     name= new sp_name(lex_db, lex_name);
     name->init_qname(thd);
     if (sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
@@ -1035,13 +1039,46 @@
       if (!no_error)
       {
 	my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE", 
-		 table->table_name);
+		 routine->table_name);
 	DBUG_RETURN(-1);
       }
       DBUG_RETURN(0);
     }
   }
   DBUG_RETURN(result);
+}
+
+
+/*
+  Check if a routine exists in the mysql.proc table, without actually
+  parsing the definition. (Used for dropping)
+
+  SYNOPSIS
+    sp_routine_exists_in_table()
+      thd        - thread context
+      name       - name of procedure
+
+  RETURN VALUE
+    0     - Success
+    non-0 - Error;  SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND
+*/
+
+int
+sp_routine_exists_in_table(THD *thd, int type, sp_name *name)
+{
+  TABLE *table;
+  int ret;
+  Open_tables_state open_tables_state_backup;
+
+  if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
+    ret= SP_OPEN_TABLE_FAILED;
+  else
+  {
+    if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
+      ret= SP_KEY_NOT_FOUND;
+    close_proc_table(thd, &open_tables_state_backup);
+  }
+  return ret;
 }
 
 

--- 1.33/sql/sp.h	2006-01-10 21:50:17 +03:00
+++ 1.34/sql/sp.h	2006-02-09 13:34:35 +03:00
@@ -40,7 +40,10 @@
                 sp_cache **cp, bool cache_only);
 
 int
-sp_exists_routine(THD *thd, TABLE_LIST *procs, bool any, bool no_error);
+sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any, bool no_error);
+
+int
+sp_routine_exists_in_table(THD *thd, int type, sp_name *name);
 
 int
 sp_create_procedure(THD *thd, sp_head *sp);

--- 1.200/sql/sp_head.cc	2006-02-06 16:09:07 +03:00
+++ 1.201/sql/sp_head.cc	2006-02-09 13:34:35 +03:00
@@ -180,11 +180,11 @@
   case SQLCOM_SHOW_ERRORS:
   case SQLCOM_SHOW_FIELDS:
   case SQLCOM_SHOW_GRANTS:
-  case SQLCOM_SHOW_INNODB_STATUS:
+  case SQLCOM_SHOW_ENGINE_STATUS:
+  case SQLCOM_SHOW_ENGINE_LOGS:
+  case SQLCOM_SHOW_ENGINE_MUTEX:
   case SQLCOM_SHOW_KEYS:
-  case SQLCOM_SHOW_LOGS:
   case SQLCOM_SHOW_MASTER_STAT:
-  case SQLCOM_SHOW_MUTEX_STATUS:
   case SQLCOM_SHOW_NEW_MASTER:
   case SQLCOM_SHOW_OPEN_TABLES:
   case SQLCOM_SHOW_PRIVILEGES:
@@ -314,6 +314,9 @@
 {
   DBUG_ENTER("sp_eval_expr");
 
+  if (!expr_item)
+    DBUG_RETURN(TRUE);
+
   if (!(expr_item= sp_prepare_func_item(thd, &expr_item)))
     DBUG_RETURN(TRUE);
 
@@ -497,7 +500,7 @@
 sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
 {
   DBUG_ENTER("sp_head::init_strings");
-  uchar *endp;                  /* Used to trim the end */
+  const uchar *endp;                            /* Used to trim the end */
   /* During parsing, we must use thd->mem_root */
   MEM_ROOT *root= thd->mem_root;
 
@@ -698,7 +701,8 @@
   field_length= !m_return_field_def.length ?
                 field_max_length : m_return_field_def.length;
 
-  field= ::make_field((char*) 0,                    /* field ptr */
+  field= ::make_field(table->s,                     /* TABLE_SHARE ptr */
+                      (char*) 0,                    /* field ptr */
                       field_length,                 /* field [max] length */
                       (uchar*) "",                  /* null ptr */
                       0,                            /* null bit */
@@ -708,8 +712,10 @@
                       m_return_field_def.geom_type,
                       Field::NONE,                  /* unreg check */
                       m_return_field_def.interval,
-                      field_name ? field_name : (const char *) m_name.str,
-                      table);
+                      field_name ? field_name : (const char *) m_name.str);
+
+  if (field)
+    field->init(table);
   
   DBUG_RETURN(field);
 }
@@ -723,6 +729,9 @@
 
 /*
   StoredRoutinesBinlogging
+  This paragraph applies only to statement-based binlogging. Row-based
+  binlogging does not need anything special like this.
+
   Top-down overview:
 
   1. Statements
@@ -1290,56 +1299,62 @@
 
   thd->spcont= nctx;
 
-  binlog_save_options= thd->options;
-  need_binlog_call= mysql_bin_log.is_open() && (thd->options &
OPTION_BIN_LOG);
+  /*
+    If row-based binlogging, we don't need to binlog the function's call, let
+    each substatement be binlogged its way.
+  */
+  need_binlog_call= mysql_bin_log.is_open() &&
+    (thd->options & OPTION_BIN_LOG) && !binlog_row_based;
   if (need_binlog_call)
   {
     reset_dynamic(&thd->user_var_events);
     mysql_bin_log.start_union_events(thd);
+    binlog_save_options= thd->options;
+    thd->options&= ~OPTION_BIN_LOG;
   }
-    
-  thd->options&= ~OPTION_BIN_LOG;
+
   err_status= execute(thd);
-  thd->options= binlog_save_options;
-  
-  if (need_binlog_call)
-    mysql_bin_log.stop_union_events(thd);
 
-  if (need_binlog_call && thd->binlog_evt_union.unioned_events)
+  if (need_binlog_call)
   {
-    char buf[256];
-    String bufstr(buf, sizeof(buf), &my_charset_bin);
-    bufstr.length(0);
-    bufstr.append(STRING_WITH_LEN("DO "));
-    append_identifier(thd, &bufstr, m_name.str, m_name.length);
-    bufstr.append('(');
-    for (uint i=0; i < argcount; i++)
+    mysql_bin_log.stop_union_events(thd);
+    thd->options= binlog_save_options;
+    if (thd->binlog_evt_union.unioned_events)
     {
-      String str_value_holder;
-      String *str_value;
-
-      if (i)
-        bufstr.append(',');
-
-      str_value= sp_get_item_value(param_values[i], &str_value_holder);
+      char buf[256];
+      String bufstr(buf, sizeof(buf), &my_charset_bin);
+      bufstr.length(0);
+      bufstr.append(STRING_WITH_LEN("DO "));
+      append_identifier(thd, &bufstr, m_name.str, m_name.length);
+      bufstr.append('(');
+      for (uint i=0; i < argcount; i++)
+      {
+        String str_value_holder;
+        String *str_value;
 
-      if (str_value)
-        bufstr.append(*str_value);
-      else
-        bufstr.append(STRING_WITH_LEN("NULL"));
-    }
-    bufstr.append(')');
-    
-    Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
-                          thd->binlog_evt_union.unioned_events_trans, FALSE);
-    if (mysql_bin_log.write(&qinfo) && 
-        thd->binlog_evt_union.unioned_events_trans)
-    {
-      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
-                   "Invoked ROUTINE modified a transactional table but MySQL "
-                   "failed to reflect this change in the binary log");
+        if (i)
+          bufstr.append(',');
+        
+        str_value= sp_get_item_value(param_values[i], &str_value_holder);
+
+        if (str_value)
+          bufstr.append(*str_value);
+        else
+          bufstr.append(STRING_WITH_LEN("NULL"));
+      }
+      bufstr.append(')');
+      
+      Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
+                            thd->binlog_evt_union.unioned_events_trans, FALSE);
+      if (mysql_bin_log.write(&qinfo) &&
+          thd->binlog_evt_union.unioned_events_trans)
+      {
+        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+                     "Invoked ROUTINE modified a transactional table but MySQL "
+                     "failed to reflect this change in the binary log");
+      }
+      reset_dynamic(&thd->user_var_events);
     }
-    reset_dynamic(&thd->user_var_events);
   }
 
   if (m_type == TYPE_ENUM_FUNCTION && !err_status)

--- 1.79/sql/sp_head.h	2006-02-06 16:09:07 +03:00
+++ 1.80/sql/sp_head.h	2006-02-09 13:34:35 +03:00
@@ -133,8 +133,7 @@
 
   create_field m_return_field_def; /* This is used for FUNCTIONs only. */
 
-  uchar *m_tmp_query;		// Temporary pointer to sub query string
-  uint m_old_cmq;		// Old CLIENT_MULTI_QUERIES value
+  const uchar *m_tmp_query;	// Temporary pointer to sub query string
   st_sp_chistics *m_chistics;
   ulong m_sql_mode;		// For SHOW CREATE and execution
   LEX_STRING m_qname;		// db.name
@@ -182,7 +181,7 @@
   */
   HASH m_sroutines;
   // Pointers set during parsing
-  uchar *m_param_begin, *m_param_end, *m_body_begin;
+  const uchar *m_param_begin, *m_param_end, *m_body_begin;
 
   /*
     Security context for stored routine which should be run under

--- 1.160/sql/sql_prepare.cc	2006-02-02 23:20:18 +03:00
+++ 1.161/sql/sql_prepare.cc	2006-02-09 13:34:37 +03:00
@@ -2075,14 +2075,19 @@
       sl->exclude_from_table_unique_test= FALSE;
 
       /*
-        Copy WHERE clause pointers to avoid damaging they by optimisation
+        Copy WHERE, HAVING clause pointers to avoid damaging them by optimisation
       */
-      if (sl->prep_where)
-      {
-        sl->where= sl->prep_where->copy_andor_structure(thd);
-        sl->where->cleanup();
-      }
-      DBUG_ASSERT(sl->join == 0);
+     if (sl->prep_where)
+     {
+       sl->where= sl->prep_where->copy_andor_structure(thd);
+       sl->where->cleanup();
+     }
+     if (sl->prep_having)
+     {
+       sl->having= sl->prep_having->copy_andor_structure(thd);
+       sl->having->cleanup();
+     }
+     DBUG_ASSERT(sl->join == 0);
       ORDER *order;
       /* Fix GROUP list */
       for (order= (ORDER *)sl->group_list.first; order; order= order->next)
Thread
bk commit into 5.1 tree (konstantin:1.2094)Konstantin Osipov9 Feb