[Commits] Rev 2875: Speed optimizations and minor bug fixes: in lp:maria/5.3

Michael Widenius monty at askmonty.org
Fri Jan 7 15:50:56 EET 2011


At lp:maria/5.3

------------------------------------------------------------
revno: 2875
revision-id: monty at askmonty.org-20110107135055-i8lk4m7sc64y1nsk
parent: igor at askmonty.org-20101230021403-ly4ku1yq675l5d6b
committer: Michael Widenius <monty at askmonty.org>
branch nick: maria-5.3
timestamp: Fri 2011-01-07 15:50:55 +0200
message:
  Speed optimizations and minor bug fixes:
  - Added new errors message for a common problem in Aria (running with different block sizes)
  - Added ha_write_tmp_row() for slightly faster write_row for internal temp tables.
  - create_tmp_table_from_heap() now uses bulk_insert + repair_by_sort when creating Aria/MyISAM tables from HEAP tables. This gave a HUGE speed boost!
  - Extended bulk_insert() for Aria and MyISAM to recreate UNIQUE keys for internal temporary tables.
  - Added support for NO_RECORD record format (don't store any row data) for Aria. This makes the keys smaller (no row pointer) and gives us proper errors if we use the table wrongly.
  - Optimize use of SEARCH_SAVE_BUFF (less not-needed copies of key pages)
  - Added to Aria better hash for packed numeric data for unique handling. This was needed as the old code caused us to have LOTS of duplicate hash values when used by optimizer.
-------------- next part --------------
=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h	2010-04-02 09:20:09 +0000
+++ b/include/m_ctype.h	2011-01-07 13:50:55 +0000
@@ -357,6 +357,9 @@ extern int  my_strnncollsp_simple(CHARSE
 extern void my_hash_sort_simple(CHARSET_INFO *cs,
                                 const uchar *key, size_t len,
                                 ulong *nr1, ulong *nr2); 
+extern void my_hash_sort_bin(CHARSET_INFO *cs,
+                             const uchar *key, size_t len, ulong *nr1,
+                             ulong *nr2);
 
 extern size_t my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, size_t length);
 

=== modified file 'include/my_base.h'
--- a/include/my_base.h	2010-11-04 14:53:10 +0000
+++ b/include/my_base.h	2011-01-07 13:50:55 +0000
@@ -445,7 +445,8 @@ enum ha_base_keytype {
 #define HA_ERR_WRONG_CRC          176    /* Wrong CRC on page */
 #define HA_ERR_ROW_NOT_VISIBLE    177
 #define HA_ERR_TOO_MANY_CONCURRENT_TRXS 178 /*Too many active concurrent transactions */
-#define HA_ERR_LAST               178    /* Copy of last error nr */
+#define HA_ERR_WRONG_BLOCKSIZE    179
+#define HA_ERR_LAST               179    /* Copy of last error nr */
 
 /* Number of different errors */
 #define HA_ERR_ERRORS            (HA_ERR_LAST - HA_ERR_FIRST + 1)
@@ -519,7 +520,7 @@ enum en_fieldtype {
 };
 
 enum data_file_type {
-  STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD
+  STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD, NO_RECORD
 };
 
 /* For key ranges */

=== modified file 'mysys/my_handler.c'
--- a/mysys/my_handler.c	2010-08-27 14:12:44 +0000
+++ b/mysys/my_handler.c	2011-01-07 13:50:55 +0000
@@ -659,7 +659,7 @@ void my_handler_error_register(void)
   /*
     If you got compilation error here about compile_time_assert array, check
     that every HA_ERR_xxx constant has a corresponding error message in
-    handler_error_messages[] list (check mysys/ma_handler_errors.h and
+    handler_error_messages[] list (check mysys/my_handler_errors.h and
     include/my_base.h).
   */
   compile_time_assert(HA_ERR_FIRST + array_elements(handler_error_messages) ==

=== modified file 'mysys/my_handler_errors.h'
--- a/mysys/my_handler_errors.h	2009-09-07 20:50:10 +0000
+++ b/mysys/my_handler_errors.h	2011-01-07 13:50:55 +0000
@@ -64,6 +64,7 @@ static const char *handler_error_message
   "File too short; Expected more data in file",
   "Read page with wrong checksum",
   "Too many active concurrent transactions",
-  "Row is not visible by the current transaction"
+  "Row is not visible by the current transaction",
+  "Incompatible blocksize"
 };
 

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2010-12-06 08:25:44 +0000
+++ b/sql/handler.cc	2011-01-07 13:50:55 +0000
@@ -2842,6 +2842,9 @@ void handler::print_error(int error, myf
   case HA_ERR_TOO_MANY_CONCURRENT_TRXS:
     textno= ER_TOO_MANY_CONCURRENT_TRXS;
     break;
+  case HA_ERR_WRONG_BLOCKSIZE:
+    textno= ER_WRONG_BLOCKSIZE;
+    break;
   default:
     {
       /* The error was "unknown" to this function.

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2010-12-13 17:01:32 +0000
+++ b/sql/handler.h	2011-01-07 13:50:55 +0000
@@ -2415,6 +2415,7 @@ class handler :public Sql_alloc
   /* XXX to be removed, see ha_partition::partition_ht() */
   virtual handlerton *partition_ht() const
   { return ht; }
+  inline int ha_write_tmp_row(uchar *buf);
 };
 
 #include "multi_range_read.h"

=== modified file 'sql/opt_subselect.cc'
--- a/sql/opt_subselect.cc	2010-11-23 22:08:48 +0000
+++ b/sql/opt_subselect.cc	2011-01-07 13:50:55 +0000
@@ -2741,9 +2741,6 @@ TABLE *create_duplicate_weedout_tmp_tabl
     field->set_table_name(&table->alias);
   }
 
-  //param->recinfo=recinfo;
-  //store_record(table,s->default_values);        // Make empty default record
-
   if (thd->variables.tmp_table_size == ~ (ulonglong) 0)         // No limit
     share->max_rows= ~(ha_rows) 0;
   else
@@ -2789,12 +2786,15 @@ TABLE *create_duplicate_weedout_tmp_tabl
     }
   }
 
-  if (thd->is_fatal_error)                              // If end of memory
+  if (thd->is_fatal_error)                      // If end of memory
     goto err;
   share->db_record_offset= 1;
+  table->no_rows= 1;                            // We don't need the data
+
+  // recinfo must point after last field
+  recinfo++;
   if (share->db_type() == TMP_ENGINE_HTON)
   {
-    recinfo++;
     if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
       goto err;
   }
@@ -2910,7 +2910,7 @@ int do_sj_dups_weedout(THD *thd, SJ_TMP_
     }
   }
 
-  error= sjtbl->tmp_table->file->ha_write_row(sjtbl->tmp_table->record[0]);
+  error= sjtbl->tmp_table->file->ha_write_tmp_row(sjtbl->tmp_table->record[0]);
   if (error)
   {
     /* create_internal_tmp_table_from_heap will generate error if needed */

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2010-09-12 12:29:54 +0000
+++ b/sql/share/errmsg.txt	2011-01-07 13:50:55 +0000
@@ -6247,3 +6247,5 @@ ER_UNKNOWN_OPTION
         eng "Unknown option '%-.64s'"
 ER_BAD_OPTION_VALUE
         eng "Incorrect value '%-.64s' for option '%-.64s'"
+ER_WRONG_BLOCKSIZE
+        eng "Can't use table `%-.64s` because it has an incompatible blocksize"

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-12-27 22:22:05 +0000
+++ b/sql/sql_class.h	2011-01-07 13:50:55 +0000
@@ -3639,5 +3639,10 @@ inline int handler::ha_read_first_row(uc
   return error;
 }
 
+inline int handler::ha_write_tmp_row(uchar *buf)
+{
+  increment_statistics(&SSV::ha_write_count);
+  return write_row(buf);
+}
 
 #endif /* MYSQL_SERVER */

=== modified file 'sql/sql_expression_cache.cc'
--- a/sql/sql_expression_cache.cc	2010-11-02 09:47:36 +0000
+++ b/sql/sql_expression_cache.cc	2011-01-07 13:50:55 +0000
@@ -123,7 +123,6 @@ void Expression_cache_tmptable::init()
     goto error;
   }
   cache_table->s->keys= 1;
-  cache_table->s->uniques= 1;
   ref.null_rejecting= 1;
   ref.disable_cache= FALSE;
   ref.has_record= 0;

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-12-27 22:22:05 +0000
+++ b/sql/sql_select.cc	2011-01-07 13:50:55 +0000
@@ -38,12 +38,6 @@
 #include <my_bit.h>
 #include <hash.h>
 #include <ft_global.h>
-//#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
-//#include "../storage/maria/ha_maria.h"
-//#define TMP_ENGINE_HTON maria_hton
-//#else
-//#define TMP_ENGINE_HTON myisam_hton
-//#endif
 
 const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
                               "MAYBE_REF","ALL","range","index","fulltext",
@@ -51,6 +45,8 @@ const char *join_type_str[]={ "UNKNOWN",
                               "index_merge"
 };
 
+const char *copy_to_tmp_table= "Copying to tmp table";
+
 struct st_sargable_param;
 
 static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
@@ -1963,7 +1959,7 @@ JOIN::exec()
     curr_tmp_table= exec_tmp_table1;
 
     /* Copy data to the temporary table */
-    thd_proc_info(thd, "Copying to tmp table");
+    thd_proc_info(thd, copy_to_tmp_table);
     DBUG_PRINT("info", ("%s", thd->proc_info));
     if (!curr_join->sort_and_group &&
         curr_join->const_tables != curr_join->tables)
@@ -7489,7 +7485,7 @@ end_sj_materialize(JOIN *join, JOIN_TAB
     fill_record(thd, table->field, sjm->sjm_table_cols, TRUE, FALSE);
     if (thd->is_error())
       DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-    if ((error= table->file->ha_write_row(table->record[0])))
+    if ((error= table->file->ha_write_tmp_row(table->record[0])))
     {
       /* create_myisam_from_heap will generate error if needed */
       if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
@@ -12000,7 +11996,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARA
   }
 
   param->copy_field_end=copy;
-  param->recinfo=recinfo;
+  param->recinfo= recinfo;                      // Pointer to after last field
   store_record(table,s->default_values);        // Make empty default record
 
   if (thd->variables.tmp_table_size == ~ (ulonglong) 0)         // No limit
@@ -12101,7 +12097,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARA
         indexes on blobs with arbitrary length. Such indexes cannot be
         used for lookups.
       */
-      //// psergey-merge: using_unique_constraint=1;
       share->uniques= 1;
     }
     null_pack_length-=hidden_null_pack_length;
@@ -12479,9 +12474,10 @@ bool create_internal_tmp_table(TABLE *ta
     create_info.data_file_length= ~(ulonglong) 0;
 
   if ((error= maria_create(share->table_name.str,
-                           share->reclength < 64 &&
-                           !share->blob_fields ? STATIC_RECORD :
-                           BLOCK_RECORD,
+                           table->no_rows ? NO_RECORD :
+                           (share->reclength < 64 &&
+                            !share->blob_fields ? STATIC_RECORD :
+                            BLOCK_RECORD),
                            share->keys, &keydef,
                            (uint) (*recinfo-start_recinfo),
                            start_recinfo,
@@ -12724,6 +12720,7 @@ create_internal_tmp_table_from_heap2(THD
   save_proc_info=thd->proc_info;
   thd_proc_info(thd, proc_info);
 
+  new_table.no_rows= table->no_rows;
   if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo,
                                 recinfo, thd->lex->select_lex.options | 
                                 thd->options))
@@ -12735,24 +12732,15 @@ create_internal_tmp_table_from_heap2(THD
   table->file->ha_index_or_rnd_end();
   if (table->file->ha_rnd_init_with_error(1))
     DBUG_RETURN(1);
-  if (table->no_rows)
-  {
+  if (new_table.no_rows)
     new_table.file->extra(HA_EXTRA_NO_ROWS);
-    new_table.no_rows=1;
+  else
+  {
+    /* update table->file->stats.records */
+    table->file->info(HA_STATUS_VARIABLE);
+    new_table.file->ha_start_bulk_insert(table->file->stats.records);
   }
 
-#ifdef TO_BE_DONE_LATER_IN_4_1
-  /*
-    To use start_bulk_insert() (which is new in 4.1) we need to find
-    all places where a corresponding end_bulk_insert() should be put.
-  */
-  table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
-  new_table.file->ha_start_bulk_insert(table->file->stats.records);
-#else
-  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
-  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
-#endif
-
   /*
     copy all old rows from heap table to MyISAM table
     This is the only code that uses record[1] to read/write but this
@@ -12761,13 +12749,15 @@ create_internal_tmp_table_from_heap2(THD
   */
   while (!table->file->ha_rnd_next(new_table.record[1]))
   {
-    write_err= new_table.file->ha_write_row(new_table.record[1]);
+    write_err= new_table.file->ha_write_tmp_row(new_table.record[1]);
     DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
     if (write_err)
       goto err;
   }
+  if (!new_table.no_rows && new_table.file->ha_end_bulk_insert())
+    goto err;
   /* copy row that filled HEAP table */
-  if ((write_err=new_table.file->ha_write_row(table->record[0])))
+  if ((write_err=new_table.file->ha_write_tmp_row(table->record[0])))
   {
     if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
         !ignore_last_dupp_key_error)
@@ -12788,8 +12778,8 @@ create_internal_tmp_table_from_heap2(THD
   table->file->change_table_ptr(table, table->s);
   table->use_all_columns();
   if (save_proc_info)
-    thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
-                     "Copying to tmp table on disk" : save_proc_info));
+    thd_proc_info(thd, save_proc_info == copy_to_tmp_table ?
+                  "Copying to tmp table on disk" : save_proc_info);
   DBUG_RETURN(0);
 
  err:
@@ -14644,7 +14634,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab
     {
       int error;
       join->found_records++;
-      if ((error= table->file->ha_write_row(table->record[0])))
+      if ((error= table->file->ha_write_tmp_row(table->record[0])))
       {
         if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
           goto end;
@@ -14733,7 +14723,7 @@ end_update(JOIN *join, JOIN_TAB *join_ta
   init_tmptable_sum_functions(join->sum_funcs);
   if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
     DBUG_RETURN(NESTED_LOOP_ERROR);           /* purecov: inspected */
-  if ((error= table->file->ha_write_row(table->record[0])))
+  if ((error= table->file->ha_write_tmp_row(table->record[0])))
   {
     if (create_internal_tmp_table_from_heap(join->thd, table,
                                             join->tmp_table_param.start_recinfo,
@@ -14776,7 +14766,7 @@ end_unique_update(JOIN *join, JOIN_TAB *
   if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
     DBUG_RETURN(NESTED_LOOP_ERROR);           /* purecov: inspected */
 
-  if (!(error= table->file->ha_write_row(table->record[0])))
+  if (!(error= table->file->ha_write_tmp_row(table->record[0])))
     join->send_records++;                       // New group
   else
   {
@@ -14836,7 +14826,7 @@ end_write_group(JOIN *join, JOIN_TAB *jo
                        join->sum_funcs_end[send_group_parts]);
         if (!join->having || join->having->val_int())
         {
-          int error= table->file->ha_write_row(table->record[0]);
+          int error= table->file->ha_write_tmp_row(table->record[0]);
           if (error && 
               create_internal_tmp_table_from_heap(join->thd, table,
                                                   join->tmp_table_param.start_recinfo,
@@ -18511,7 +18501,7 @@ int JOIN::rollup_write_data(uint idx, TA
           item->save_in_result_field(1);
       }
       copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
-      if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
+      if ((write_error= table_arg->file->ha_write_tmp_row(table_arg->record[0])))
       {
         if (create_internal_tmp_table_from_heap(thd, table_arg, 
                                                 tmp_table_param.start_recinfo,

=== modified file 'storage/maria/Makefile.am'
--- a/storage/maria/Makefile.am	2010-11-30 21:11:03 +0000
+++ b/storage/maria/Makefile.am	2011-01-07 13:50:55 +0000
@@ -124,7 +124,7 @@ libaria_la_SOURCES =	ma_init.c ma_open.c
                         ma_search.c ma_page.c ma_key_recover.c ma_key.c \
                         ma_locking.c ma_state.c \
                         ma_rrnd.c ma_scan.c ma_cache.c \
-                        ma_statrec.c ma_packrec.c ma_dynrec.c \
+                        ma_statrec.c ma_packrec.c ma_dynrec.c ma_norec.c \
                         ma_blockrec.c ma_bitmap.c \
                         ma_update.c ma_write.c ma_unique.c \
                         ma_delete.c \

=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc	2010-12-13 10:42:40 +0000
+++ b/storage/maria/ha_maria.cc	2011-01-07 13:50:55 +0000
@@ -1998,7 +1998,14 @@ void ha_maria::start_bulk_insert(ha_rows
          @todo for a single-row INSERT SELECT, we will go into repair, which
          is more costly (flushes, syncs) than a row write.
       */
-      maria_disable_non_unique_index(file, rows);
+      if (file->open_flags & HA_OPEN_INTERNAL_TABLE)
+      {
+        /* Internal table; If we get a duplicate something is very wrong */
+        file->update|= HA_STATE_CHANGED;
+        maria_clear_all_keys_active(file->s->state.key_map);
+      }
+      else
+        maria_disable_non_unique_index(file, rows);
       if (share->now_transactional)
       {
         bulk_insert_single_undo= BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR;

=== modified file 'storage/maria/ma_check.c'
--- a/storage/maria/ma_check.c	2010-12-13 13:51:47 +0000
+++ b/storage/maria/ma_check.c	2011-01-07 13:50:55 +0000
@@ -993,10 +993,12 @@ static int chk_index(HA_CHECK *param, MA
       /* fall through */
     }
     if ((share->data_file_type != BLOCK_RECORD &&
+         share->data_file_type != NO_RECORD &&
          record >= share->state.state.data_file_length) ||
         (share->data_file_type == BLOCK_RECORD &&
          ma_recordpos_to_page(record) * share->base.min_block_length >=
-         share->state.state.data_file_length))
+         share->state.state.data_file_length) ||
+        (share->data_file_type == NO_RECORD && record != 0))
     {
 #ifndef DBUG_OFF
       char llbuff2[22], llbuff3[22];
@@ -2047,6 +2049,12 @@ int maria_chk_data_link(HA_CHECK *param,
   case COMPRESSED_RECORD:
     error= check_compressed_record(param, info, extend, record);
     break;
+  case NO_RECORD:
+    param->records= share->state.state.records;
+    param->record_checksum= 0;
+    extend= 1;                                  /* No row checksums */
+    /* no data, nothing to do */
+    break;
   } /* switch */
 
   if (error)
@@ -2277,7 +2285,14 @@ static int initialize_variables_for_repa
 {
   MARIA_SHARE *share= info->s;
 
-  /* Ro allow us to restore state and check how state changed */
+  if (share->data_file_type == NO_RECORD)
+  {
+    _ma_check_print_error(param,
+                          "Can't repair tables with record type NO_DATA");
+    return 1;
+  }
+
+  /* Allow us to restore state and check how state changed */
   memcpy(org_share, share, sizeof(*share));
 
   /* Repair code relies on share->state.state so we have to update it here */
@@ -5184,8 +5199,10 @@ static int sort_get_next_record(MARIA_SO
       }
       DBUG_RETURN(0);
     }
+  case NO_RECORD:
+    DBUG_RETURN(1);                             /* Impossible */
   }
-  DBUG_RETURN(1);               /* Impossible */
+  DBUG_RETURN(1);                               /* Impossible */
 }
 
 
@@ -5305,6 +5322,8 @@ int _ma_sort_write_record(MARIA_SORT_PAR
       sort_param->filepos+=reclength+length;
       share->state.split++;
       break;
+    case NO_RECORD:
+      DBUG_RETURN(1);                           /* Impossible */
     }
   }
   if (sort_param->master)

=== modified file 'storage/maria/ma_create.c'
--- a/storage/maria/ma_create.c	2010-09-12 16:40:01 +0000
+++ b/storage/maria/ma_create.c	2011-01-07 13:50:55 +0000
@@ -250,10 +250,16 @@ int maria_create(const char *name, enum
     datafile_type= BLOCK_RECORD;
   }
 
+  if (datafile_type == NO_RECORD && uniques)
+  {
+    /* Can't do unique without data, revert to block records */
+    datafile_type= BLOCK_RECORD;
+  }
+
   if (datafile_type == DYNAMIC_RECORD)
     options|= HA_OPTION_PACK_RECORD;    /* Must use packed records */
 
-  if (datafile_type == STATIC_RECORD)
+  if (datafile_type == STATIC_RECORD || datafile_type == NO_RECORD)
   {
     /* We can't use checksum with static length rows */
     flags&= ~HA_CREATE_CHECKSUM;
@@ -366,7 +372,9 @@ int maria_create(const char *name, enum
                                       }
   else
   {
-    if (datafile_type != STATIC_RECORD)
+    if (datafile_type == NO_RECORD)
+      pointer= 0;
+    else if (datafile_type != STATIC_RECORD)
       pointer= maria_get_pointer_length(ci->data_file_length,
                                         maria_data_pointer_size);
     else

=== added file 'storage/maria/ma_norec.c'
--- a/storage/maria/ma_norec.c	1970-01-01 00:00:00 +0000
+++ b/storage/maria/ma_norec.c	2011-01-07 13:50:55 +0000
@@ -0,0 +1,66 @@
+/* Copyright (C) 2010 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/*
+  Functions to handle tables with no row data (only index)
+  This is useful when you just want to do key reads or want to use
+  the index to check against duplicates.
+*/
+
+#include "maria_def.h"
+
+my_bool _ma_write_no_record(MARIA_HA *info __attribute__((unused)),
+                            const uchar *record __attribute__((unused)))
+{
+  return 0;
+}
+
+my_bool _ma_update_no_record(MARIA_HA *info __attribute__((unused)),
+                             MARIA_RECORD_POS pos __attribute__((unused)),
+                             const uchar *oldrec __attribute__((unused)),
+                             const uchar *record __attribute__((unused)))
+{
+  return HA_ERR_WRONG_COMMAND;
+}
+
+
+my_bool _ma_delete_no_record(MARIA_HA *info __attribute__((unused)),
+                             const uchar *record __attribute__((unused)))
+{
+  return HA_ERR_WRONG_COMMAND;
+}
+
+
+int _ma_read_no_record(MARIA_HA *info  __attribute__((unused)),
+                       uchar *record  __attribute__((unused)),
+                       MARIA_RECORD_POS pos __attribute__((unused)))
+{
+  return HA_ERR_WRONG_COMMAND;
+}
+
+
+int _ma_read_rnd_no_record(MARIA_HA *info __attribute__((unused)),
+                           uchar *buf  __attribute__((unused)),
+                           MARIA_RECORD_POS filepos __attribute__((unused)),
+                           my_bool skip_deleted_blocks __attribute__((unused)))
+{
+  return HA_ERR_WRONG_COMMAND;
+}
+
+my_off_t _ma_no_keypos_to_recpos(MARIA_SHARE *share __attribute__ ((unused)),
+                                 my_off_t pos __attribute__ ((unused)))
+{
+  return 0;
+}

=== modified file 'storage/maria/ma_open.c'
--- a/storage/maria/ma_open.c	2010-11-27 15:29:52 +0000
+++ b/storage/maria/ma_open.c	2011-01-07 13:50:55 +0000
@@ -203,6 +204,9 @@ static MARIA_HA *maria_clone_internal(MA
 #ifdef THREAD
   thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
 #endif
+  if (share->options & HA_OPTION_TMP_TABLE)
+    m_info->lock.type= TL_WRITE;
+
   m_info->open_list.data=(void*) m_info;
   maria_open_list=list_add(maria_open_list,&m_info->open_list);
 
@@ -484,7 +488,7 @@ MARIA_HA *maria_open(const char *name, i
       DBUG_PRINT("error", ("Wrong block size %u; Expected %u",
                            (uint) share->base.block_size,
                            (uint) maria_block_size));
-      my_errno=HA_ERR_UNSUPPORTED;
+      my_errno= HA_ERR_WRONG_BLOCKSIZE;
       goto err;
     }
 
@@ -935,6 +939,8 @@ MARIA_HA *maria_open(const char *name, i
                            share->state.changed));
 
   pthread_mutex_unlock(&THR_LOCK_maria);
+
+  m_info->open_flags= open_flags;
   DBUG_RETURN(m_info);
 
 err:
@@ -1076,6 +1082,20 @@ void _ma_setup_functions(register MARIA_
     else
       share->calc_checksum= _ma_checksum;
     break;
+  case NO_RECORD:
+    share->read_record=      _ma_read_no_record;
+    share->scan=             _ma_read_rnd_no_record;
+    share->delete_record=    _ma_delete_no_record;
+    share->update_record=    _ma_update_no_record;
+    share->write_record=     _ma_write_no_record;
+    share->recpos_to_keypos= _ma_no_keypos_to_recpos;
+    share->keypos_to_recpos= _ma_no_keypos_to_recpos;
+
+    /* Abort if following functions are called */
+    share->compare_record=   0;
+    share->compare_unique=   0;
+    share->calc_checksum= 0;
+    break;
   case BLOCK_RECORD:
     share->once_init= _ma_once_init_block_record;
     share->once_end=  _ma_once_end_block_record;

=== modified file 'storage/maria/ma_rkey.c'
--- a/storage/maria/ma_rkey.c	2010-03-20 12:01:47 +0000
+++ b/storage/maria/ma_rkey.c	2011-01-07 13:50:55 +0000
@@ -83,10 +83,11 @@ int maria_rkey(MARIA_HA *info, uchar *bu
     rw_rdlock(&keyinfo->root_lock);
 
   nextflag= maria_read_vec[search_flag] | key.flag;
-  if (search_flag != HA_READ_KEY_EXACT ||
-      ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME))
+  if (search_flag != HA_READ_KEY_EXACT)
+  {
+    /* Assume we will get a read next/previous call after this one */
     nextflag|= SEARCH_SAVE_BUFF;
-
+  }
   switch (keyinfo->key_alg) {
 #ifdef HAVE_RTREE_KEYS
   case HA_KEY_ALG_RTREE:
@@ -103,8 +104,6 @@ int maria_rkey(MARIA_HA *info, uchar *bu
     if (!_ma_search(info, &key, nextflag, info->s->state.key_root[inx]))
     {      
       MARIA_KEY lastkey;
-      lastkey.keyinfo= keyinfo;
-      lastkey.data= info->lastkey_buff;
       /*
         Found a key, but it might not be usable. We cannot use rows that
         are inserted by other threads after we got our table lock
@@ -129,6 +128,8 @@ int maria_rkey(MARIA_HA *info, uchar *bu
         break;
       }
       
+      lastkey.keyinfo= keyinfo;
+      lastkey.data= info->lastkey_buff;
       do
       {
         uint not_used[2];

=== modified file 'storage/maria/ma_search.c'
--- a/storage/maria/ma_search.c	2010-10-14 22:46:20 +0000
+++ b/storage/maria/ma_search.c	2011-01-07 13:50:55 +0000
@@ -785,6 +785,7 @@ MARIA_RECORD_POS _ma_row_pos_from_key(co
   case 4:  pos= (my_off_t) mi_uint4korr(after_key);  break;
   case 3:  pos= (my_off_t) mi_uint3korr(after_key);  break;
   case 2:  pos= (my_off_t) mi_uint2korr(after_key);  break;
+  case 0:                                       /* NO_RECORD */
   default:
     pos=0L;                                     /* Shut compiler up */
   }
@@ -894,6 +895,7 @@ void _ma_dpointer(MARIA_SHARE *share, uc
   case 4: mi_int4store(buff,pos); break;
   case 3: mi_int3store(buff,pos); break;
   case 2: mi_int2store(buff,(uint) pos); break;
+  case 0: break;                                /* For NO_RECORD */
   default: abort();                             /* Impossible */
   }
 } /* _ma_dpointer */

=== modified file 'storage/maria/ma_test1.c'
--- a/storage/maria/ma_test1.c	2008-12-02 22:02:52 +0000
+++ b/storage/maria/ma_test1.c	2011-01-07 13:50:55 +0000
@@ -409,6 +409,10 @@ static int run_test(const char *filename
   if (!silent)
     printf("- Reading rows with key\n");
   record[1]= 0;                                 /* For nicer printf */
+
+  if (record_type == NO_RECORD)
+    maria_extra(file, HA_EXTRA_KEYREAD, 0);
+
   for (i=0 ; i <= 25 ; i++)
   {
     create_key(key,i);
@@ -422,6 +426,11 @@ static int run_test(const char *filename
              (int) key_length,key+offset_to_key,error,my_errno,record+1);
     }
   }
+  if (record_type == NO_RECORD)
+  {
+    maria_extra(file, HA_EXTRA_NO_KEYREAD, 0);
+    goto end;
+  }
 
   if (!silent)
     printf("- Reading rows with position\n");
@@ -757,6 +767,8 @@ static struct my_option my_long_options[
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"rows-in-block", 'M', "Store rows in block format",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"rows-no-data", 'n', "Don't store any data, only keys",
+   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"row-pointer-size", 'R', "Undocumented", (uchar**) &rec_pointer_size,
    (uchar**) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"silent", 's', "Undocumented",
@@ -816,6 +828,9 @@ get_one_option(int optid, const struct m
   case 'M':
     record_type= BLOCK_RECORD;
     break;
+  case 'n':
+    record_type= NO_RECORD;
+    break;
   case 'S':
     if (key_field == FIELD_VARCHAR)
     {
@@ -887,6 +902,10 @@ static void get_options(int argc, char *
     exit(ho_error);
   if (transactional)
     record_type= BLOCK_RECORD;
+  if (record_type == NO_RECORD)
+    skip_update= skip_delete= 1;
+
+
   return;
 } /* get options */
 

=== modified file 'storage/maria/ma_unique.c'
--- a/storage/maria/ma_unique.c	2010-09-07 20:57:00 +0000
+++ b/storage/maria/ma_unique.c	2011-01-07 13:50:55 +0000
@@ -45,7 +45,8 @@ my_bool _ma_check_unique(MARIA_HA *info,
   info->update&= ~HA_STATE_RNEXT_SAME;
 
   DBUG_ASSERT(key.data_length == MARIA_UNIQUE_HASH_LENGTH);
-  if (_ma_search(info, &key, SEARCH_FIND, info->s->state.key_root[def->key]))
+  if (_ma_search(info, &key, SEARCH_FIND | SEARCH_SAVE_BUFF,
+                 info->s->state.key_root[def->key]))
   {
     info->page_changed=1;                       /* Can't optimize read next */
     info->cur_row.lastpos= lastpos;
@@ -134,13 +135,14 @@ ha_checksum _ma_unique_hash(MARIA_UNIQUE
       keyseg->charset->coll->hash_sort(keyseg->charset,
                                        (const uchar*) pos, length, &seed1,
                                        &seed2);
-      crc^= seed1;
+      crc+= seed1;
     }
     else
-      while (pos != end)
-        crc=((crc << 8) +
-             (((uchar)  *pos++))) +
-          (crc >> (8*sizeof(ha_checksum)-8));
+    {
+      my_hash_sort_bin((CHARSET_INFO*) 0, pos, (size_t) (end-pos),
+                       &seed1, &seed2);
+      crc+= seed1;
+    }
   }
   return crc;
 }

=== modified file 'storage/maria/ma_write.c'
--- a/storage/maria/ma_write.c	2010-12-10 15:15:18 +0000
+++ b/storage/maria/ma_write.c	2011-01-07 13:50:55 +0000
@@ -124,12 +124,23 @@ int maria_write(MARIA_HA *info, uchar *r
     goto err2;
 
   /* Calculate and check all unique constraints */
-  for (i=0 ; i < share->state.header.uniques ; i++)
+
+  if (share->state.header.uniques)
   {
-    if (_ma_check_unique(info,share->uniqueinfo+i,record,
-                         _ma_unique_hash(share->uniqueinfo+i,record),
-                         HA_OFFSET_ERROR))
-      goto err2;
+    for (i=0 ; i < share->state.header.uniques ; i++)
+    {
+      MARIA_UNIQUEDEF *def= share->uniqueinfo + i;
+      ha_checksum unique_hash= _ma_unique_hash(share->uniqueinfo+i,record);
+      if (maria_is_key_active(share->state.key_map, def->key))
+      {
+        if (_ma_check_unique(info, def, record,
+                             unique_hash, HA_OFFSET_ERROR))
+          goto err2;
+      }
+      else
+        maria_unique_store(record+ share->keyinfo[def->key].seg->start,
+                           unique_hash);
+    }
   }
 
   /* Ensure we don't try to restore auto_increment if it doesn't change */

=== modified file 'storage/maria/maria_chk.c'
--- a/storage/maria/maria_chk.c	2010-12-05 13:10:12 +0000
+++ b/storage/maria/maria_chk.c	2011-01-07 13:50:55 +0000
@@ -68,7 +68,7 @@ static const char *field_pack[]=
 
 static const char *record_formats[]=
 {
-  "Fixed length", "Packed", "Compressed", "Block", "?"
+  "Fixed length", "Packed", "Compressed", "Block", "No data", "?", "?"
 };
 
 static const char *bitmap_description[]=

=== modified file 'storage/maria/maria_def.h'
--- a/storage/maria/maria_def.h	2010-12-27 22:22:05 +0000
+++ b/storage/maria/maria_def.h	2011-01-07 13:50:55 +0000
@@ -97,6 +97,7 @@ typedef struct st_maria_state_info
   ulong sec_index_changed;              /* Updated when new sec_index */
   ulong sec_index_used;                 /* which extra index are in use */
   ulonglong key_map;                    /* Which keys are in use */
+  my_bool uniques_enabled;              /* If uniques are enabled */
   ulong version;                        /* timestamp of create */
   time_t create_time;                   /* Time when created database */
   time_t recover_time;                  /* Time for last recover */
@@ -550,6 +551,7 @@ struct st_maria_handler
   ulong row_base_length;                /* Length of row header */
   uint row_flag;                        /* Flag to store in row header */
   uint opt_flag;                        /* Optim. for space/speed */
+  uint open_flags;                      /* Flags used in open() */
   uint update;                          /* If file changed since open */
   int lastinx;                          /* Last used index */
   uint last_rkey_length;                /* Last length in maria_rkey() */
@@ -871,6 +873,18 @@ extern my_bool _ma_update_static_record(
                                         const uchar *, const uchar *);
 extern my_bool _ma_delete_static_record(MARIA_HA *info, const uchar *record);
 extern my_bool _ma_cmp_static_record(MARIA_HA *info, const uchar *record);
+
+extern my_bool _ma_write_no_record(MARIA_HA *info, const uchar *record);
+extern my_bool _ma_update_no_record(MARIA_HA *info, MARIA_RECORD_POS pos,
+                                    const uchar *oldrec, const uchar *record);
+extern my_bool _ma_delete_no_record(MARIA_HA *info, const uchar *record);
+extern int _ma_read_no_record(MARIA_HA *info, uchar *record,
+                              MARIA_RECORD_POS pos);
+extern int _ma_read_rnd_no_record(MARIA_HA *info, uchar *buf,
+                                  MARIA_RECORD_POS filepos,
+                                  my_bool skip_deleted_blocks);
+my_off_t _ma_no_keypos_to_recpos(MARIA_SHARE *share, my_off_t pos);
+
 extern my_bool _ma_ck_write(MARIA_HA *info, MARIA_KEY *key);
 extern my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key,
                                 MARIA_RECORD_POS *root);

=== modified file 'storage/maria/unittest/ma_test_all-t'
--- a/storage/maria/unittest/ma_test_all-t	2010-09-12 16:40:01 +0000
+++ b/storage/maria/unittest/ma_test_all-t	2011-01-07 13:50:55 +0000
@@ -250,6 +250,7 @@ sub run_check_tests
                       ["-p -B --key_length=480","-sm"],
                       ["--checksum --unique","-se"],
                       ["--unique","-se"],
+                      ["--rows-no-data", "-s"],
                       ["--key_multiple -N -S","-sm"],
                       ["--key_multiple -a -p --key_length=480","-sm"],
                       ["--key_multiple -a -B --key_length=480","-sm"],

=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc	2010-12-13 10:42:40 +0000
+++ b/storage/myisam/ha_myisam.cc	2011-01-07 13:50:55 +0000
@@ -1596,7 +1596,15 @@ void ha_myisam::start_bulk_insert(ha_row
     */
     if (file->state->records == 0 && can_enable_indexes &&
         (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
-      mi_disable_non_unique_index(file,rows);
+    {
+      if (file->open_flag & HA_OPEN_INTERNAL_TABLE)
+      {
+        file->update|= HA_STATE_CHANGED;
+        mi_clear_all_keys_active(file->s->state.key_map);
+      }
+      else
+        mi_disable_non_unique_index(file,rows);
+    }
     else
     if (!file->bulk_insert &&
         (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))



More information about the commits mailing list