summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_sys.h6
-rw-r--r--include/myisam.h2
-rw-r--r--mysql-test/lib/mtr_process.pl6
-rwxr-xr-xmysql-test/mysql-test-run.pl2
-rw-r--r--mysql-test/r/maria-recovery.result1
-rw-r--r--mysql-test/suite/rpl/t/rpl_innodb_bug28430.test1
-rw-r--r--mysys/my_lock.c12
-rw-r--r--mysys/my_thr_init.c4
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/handler.h12
-rw-r--r--sql/my_lock.c45
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/sql_class.h9
-rw-r--r--sql/sql_select.cc303
-rw-r--r--sql/sql_select.h2
-rw-r--r--sql/sql_show.cc250
-rw-r--r--sql/sql_table.cc8
-rw-r--r--sql/sql_union.cc4
-rw-r--r--sql/sql_update.cc2
-rw-r--r--storage/maria/ha_maria.cc42
-rw-r--r--storage/maria/ha_maria.h4
-rw-r--r--storage/maria/ma_blockrec.c108
-rw-r--r--storage/maria/ma_blockrec.h4
-rw-r--r--storage/maria/ma_close.c2
-rw-r--r--storage/maria/ma_control_file.c27
-rw-r--r--storage/maria/ma_create.c24
-rw-r--r--storage/maria/ma_delete.c6
-rw-r--r--storage/maria/ma_dynrec.c3
-rw-r--r--storage/maria/ma_extra.c20
-rw-r--r--storage/maria/ma_key_recover.c21
-rw-r--r--storage/maria/ma_open.c25
-rw-r--r--storage/maria/ma_recovery.c72
-rw-r--r--storage/maria/ma_scan.c13
-rw-r--r--storage/maria/maria_def.h12
-rw-r--r--storage/myisam/ha_myisam.cc32
-rw-r--r--storage/myisam/ha_myisam.h3
-rw-r--r--storage/myisam/mi_check.c2
-rw-r--r--storage/myisam/mi_extra.c2
-rw-r--r--storage/myisam/mi_open.c2
-rw-r--r--storage/myisam/myisamdef.h2
40 files changed, 763 insertions, 335 deletions
diff --git a/include/my_sys.h b/include/my_sys.h
index f8f3411f337..77364c3fefb 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -62,12 +62,14 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */
#define MY_REDEL_MAKE_BACKUP 256
#define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */
-#define MY_DONT_WAIT 64 /* my_lock() don't wait if can't lock */
+#define MY_SHORT_WAIT 64 /* my_lock() don't wait if can't lock */
+#define MY_FORCE_LOCK 128 /* use my_lock() even if disable_locking */
+#define MY_NO_WAIT 256 /* my_lock() don't wait at all */
#define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */
#define MY_ALLOW_ZERO_PTR 64 /* my_realloc() ; zero ptr -> malloc */
#define MY_FREE_ON_ERROR 128 /* my_realloc() ; Free old ptr on error */
#define MY_HOLD_ON_ERROR 256 /* my_realloc() ; Return old ptr on error */
-#define MY_DONT_OVERWRITE_FILE 1024 /* my_copy: Don't overwrite file */
+#define MY_DONT_OVERWRITE_FILE 2048 /* my_copy: Don't overwrite file */
#define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */
diff --git a/include/myisam.h b/include/myisam.h
index ee0bf43782b..cad52380e97 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -225,7 +225,7 @@ struct st_mi_bit_buff;
typedef struct st_columndef /* column information */
{
- int16 type; /* en_fieldtype */
+ enum en_fieldtype type;
uint16 length; /* length of field */
uint32 offset; /* Offset to position in row */
uint8 null_bit; /* If column may be 0 */
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index 945a9af6d2a..566ccfe0778 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -474,12 +474,6 @@ sub mtr_kill_leftovers () {
}
}
}
- else
- {
- mtr_warning("Found non pid file $elem in $rundir")
- if -f "$rundir/$elem";
- next;
- }
}
closedir(RUNDIR);
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 234744e46d0..a4fa415caf6 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -3038,6 +3038,7 @@ sub install_db ($$) {
mtr_add_arg($args, "--datadir=%s", $data_dir);
mtr_add_arg($args, "--loose-skip-innodb");
mtr_add_arg($args, "--loose-skip-ndbcluster");
+ mtr_add_arg($args, "--sync-frm=0");
mtr_add_arg($args, "--tmpdir=.");
mtr_add_arg($args, "--core-file");
@@ -3778,6 +3779,7 @@ sub mysqld_arguments ($$$$) {
mtr_add_arg($args, "%s--datadir=%s", $prefix,
$mysqld->{'path_myddir'});
+ mtr_add_arg($args, "--sync-frm=0"); # Faster test
if ( $mysql_version_id >= 50106 )
{
diff --git a/mysql-test/r/maria-recovery.result b/mysql-test/r/maria-recovery.result
index 2cee14bffcd..4e756a9a1e5 100644
--- a/mysql-test/r/maria-recovery.result
+++ b/mysql-test/r/maria-recovery.result
@@ -1,3 +1,4 @@
+set global maria_log_file_size=4294967296;
drop database if exists mysqltest;
create database mysqltest;
use mysqltest;
diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test b/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test
index fe3881ab08f..d2be173f068 100644
--- a/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test
+++ b/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test
@@ -1,3 +1,4 @@
+--source include/big_test.inc
--source include/have_innodb.inc
--source include/have_binlog_format_mixed_or_row.inc
--source include/master-slave.inc
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index c0522ee849d..4b8c067ba0d 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -54,7 +54,7 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
#ifdef VMS
DBUG_RETURN(0);
#else
- if (my_disable_locking)
+ if (my_disable_locking && ! (MyFlags & MY_FORCE_LOCK))
DBUG_RETURN(0);
#if defined(__NETWARE__)
@@ -131,10 +131,16 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
lock.l_start= (off_t) start;
lock.l_len= (off_t) length;
- if (MyFlags & MY_DONT_WAIT)
+ if (MyFlags & (MY_NO_WAIT | MY_SHORT_WAIT))
{
if (fcntl(fd,F_SETLK,&lock) != -1) /* Check if we can lock */
- DBUG_RETURN(0); /* Ok, file locked */
+ DBUG_RETURN(0); /* Ok, file locked */
+ if (MyFlags & MY_NO_WAIT)
+ {
+ my_errno= (errno == EACCES) ? EAGAIN : errno ? errno : -1;
+ DBUG_RETURN(-1);
+ }
+
DBUG_PRINT("info",("Was locked, trying with alarm"));
ALARM_INIT;
while ((value=fcntl(fd,F_SETLKW,&lock)) && ! ALARM_TEST &&
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index c9ce6ab169f..aadb86d39ed 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -289,12 +289,12 @@ my_bool my_thread_init(void)
#endif
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&tmp->suspend, NULL);
- tmp->init= 1;
pthread_mutex_lock(&THR_LOCK_threads);
tmp->id= ++thread_id;
++THR_thread_count;
pthread_mutex_unlock(&THR_LOCK_threads);
+ tmp->init= 1;
#ifndef DBUG_OFF
/* Generate unique name for thread */
(void) my_thread_name();
@@ -392,7 +392,7 @@ extern void **my_thread_var_dbug()
{
struct st_my_thread_var *tmp=
my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
- return tmp ? &tmp->dbug : 0;
+ return tmp && tmp->init ? &tmp->dbug : 0;
}
#endif
diff --git a/sql/handler.cc b/sql/handler.cc
index 2fe04c5dba3..4a9052da7c0 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -26,7 +26,7 @@
#include "mysql_priv.h"
#include "rpl_filter.h"
#include <myisampack.h>
-#include <errno.h>
+#include "myisam.h"
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
diff --git a/sql/handler.h b/sql/handler.h
index d9533739af2..d2ff337f6f5 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1359,14 +1359,18 @@ public:
}
virtual int read_first_row(uchar *buf, uint primary_key);
/*
- The following function is only needed for tables that may be temporary
- tables during joins
+ The following 3 function is only needed for tables that may be
+ internal temporary tables during joins
*/
- virtual int restart_rnd_next(uchar *buf, uchar *pos)
+ virtual int remember_rnd_pos()
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int restart_rnd_next(uchar *buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int rnd_same(uchar *buf, uint inx)
{ return HA_ERR_WRONG_COMMAND; }
- virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
+
+ virtual ha_rows records_in_range(uint inx, key_range *min_key,
+ key_range *max_key)
{ return (ha_rows) 10; }
virtual void position(const uchar *record)=0;
virtual int info(uint)=0; // see my_base.h for full description
diff --git a/sql/my_lock.c b/sql/my_lock.c
index f66d7282f72..276259b106a 100644
--- a/sql/my_lock.c
+++ b/sql/my_lock.c
@@ -25,7 +25,15 @@
#include <thr_alarm.h>
#include <errno.h>
- /* Lock a part of a file */
+/**
+ @breif Lock a part of a file
+
+ @note
+ This works like mysys/my_lock.c, with the exception that this function
+ uses the thr_alarm() to break long lock statements.
+ (mysys can't use thr_alarm() as by default the alarm handling doesn't
+ exists)
+*/
int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
{
@@ -36,29 +44,34 @@ int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(ulong) start,(ulong) length,MyFlags));
- if (my_disable_locking)
+ if (my_disable_locking && ! (MyFlags & MY_FORCE_LOCK))
DBUG_RETURN(0); /* purecov: inspected */
+
m_lock.l_type=(short) locktype;
m_lock.l_whence=0L;
m_lock.l_start=(long) start;
m_lock.l_len=(long) length;
- wait_for_alarm=(MyFlags & MY_DONT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
- (uint) 12*60*60);
if (fcntl(fd,F_SETLK,&m_lock) != -1) /* Check if we can lock */
DBUG_RETURN(0); /* Ok, file locked */
- DBUG_PRINT("info",("Was locked, trying with alarm"));
- if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
- {
- int value;
- while ((value=fcntl(fd,F_SETLKW,&m_lock)) && !thr_got_alarm(&alarmed) &&
- errno == EINTR) ;
- thr_end_alarm(&alarmed);
- if (value != -1)
- DBUG_RETURN(0);
- }
- else
+
+ if (!(MyFlags & MY_NO_WAIT))
{
- errno=EINTR;
+ wait_for_alarm= (MyFlags & MY_SHORT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
+ (uint) 12*60*60);
+ DBUG_PRINT("info",("Was locked, trying with alarm"));
+ if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
+ {
+ int value;
+ while ((value=fcntl(fd,F_SETLKW,&m_lock)) && !thr_got_alarm(&alarmed) &&
+ errno == EINTR) ;
+ thr_end_alarm(&alarmed);
+ if (value != -1)
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ errno=EINTR;
+ }
}
if (errno == EINTR || errno == EACCES)
my_errno=EAGAIN; /* Easier to check for this */
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f7738e44404..b178f7103cb 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1888,6 +1888,7 @@ extern TYPELIB log_output_typelib;
extern SHOW_COMP_OPTION have_maria_db;
extern handlerton *partition_hton;
extern handlerton *myisam_hton;
+extern handlerton *maria_hton;
extern handlerton *heap_hton;
extern SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index d4950ec0f60..964b31cd95c 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2159,7 +2159,14 @@ public:
const HA_CREATE_INFO *get_create_info() { return create_info; };
};
+
+#ifdef WITH_MARIA_STORAGE_ENGINE
+#include <maria.h>
+#define ENGINE_COLUMNDEF MARIA_COLUMNDEF
+#else
#include <myisam.h>
+#define ENGINE_COLUMNDEF MI_COLUMNDEF
+#endif
/*
Param to create temporary tables when doing SELECT:s
@@ -2181,7 +2188,7 @@ public:
Copy_field *save_copy_field, *save_copy_field_end;
uchar *group_buff;
Item **items_to_copy; /* Fields in tmp table */
- MI_COLUMNDEF *recinfo,*start_recinfo;
+ ENGINE_COLUMNDEF *recinfo, *start_recinfo;
KEY *keyinfo;
ha_rows end_write_records;
uint field_count,sum_func_count,func_count;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 1f206e2ec17..850c15a11b8 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -27,11 +27,16 @@
#include "mysql_priv.h"
#include "sql_select.h"
#include "sql_cursor.h"
-
#include <m_ctype.h>
#include <my_bit.h>
#include <hash.h>
#include <ft_global.h>
+#ifdef WITH_MARIA_STORAGE_ENGINE
+#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",
@@ -116,8 +121,14 @@ static COND *optimize_cond(JOIN *join, COND *conds,
Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
-static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
+static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options);
+static bool create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
+ TMP_TABLE_PARAM *param,
+ int error,
+ bool ignore_last_dupp,
+ handlerton *hton,
+ const char *proc_info);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
@@ -9460,7 +9471,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
KEY *keyinfo;
KEY_PART_INFO *key_part_info;
Item **copy_func;
- MI_COLUMNDEF *recinfo;
+ ENGINE_COLUMNDEF *recinfo;
uint total_uneven_bit_length= 0;
bool force_copy_fields= param->force_copy_fields;
DBUG_ENTER("create_tmp_table");
@@ -9486,11 +9497,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/*
No need to change table name to lower case as we are only creating
- MyISAM or HEAP tables here
+ MyISAM, Maria or HEAP tables here
*/
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
-
if (group)
{
if (!param->quick_group)
@@ -9582,7 +9592,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
init_tmp_table_share(share, "", 0, tmpname, tmpname);
share->blob_field= blob_field;
share->blob_ptr_size= portable_sizeof_char_ptr;
- share->db_low_byte_first=1; // True for HEAP and MyISAM
+ share->db_low_byte_first=1; // True for HEAP, MyISAM and Maria
share->table_charset= param->table_charset;
share->primary_key= MAX_KEY; // Indicate no primary key
share->keys_for_keyread.init();
@@ -9714,6 +9724,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*blob_field++= fieldnr;
blob_count++;
}
+ if (new_field->real_type() == MYSQL_TYPE_STRING ||
+ new_field->real_type() == MYSQL_TYPE_VARCHAR)
+ {
+ string_count++;
+ string_total_length+= new_field->pack_length();
+ }
if (item->marker == 4 && item->maybe_null)
{
group_null_items++;
@@ -9750,7 +9766,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
{
- share->db_plugin= ha_lock_engine(0, myisam_hton);
+ share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
table->file= get_new_handler(share, &table->mem_root,
share->db_type());
if (group &&
@@ -9767,7 +9783,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!table->file)
goto err;
-
if (!using_unique_constraint)
reclength+= group_null_items; // null flag is stored separately
@@ -9903,13 +9918,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/* Make entry for create table */
recinfo->length=length;
if (field->flags & BLOB_FLAG)
- recinfo->type= (int) FIELD_BLOB;
+ recinfo->type= FIELD_BLOB;
else if (use_packed_rows &&
field->real_type() == MYSQL_TYPE_STRING &&
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
- recinfo->type=FIELD_SKIP_ENDSPACE;
+ recinfo->type= FIELD_SKIP_ENDSPACE;
+ else if (field->real_type() == MYSQL_TYPE_VARCHAR)
+ recinfo->type= FIELD_VARCHAR;
else
- recinfo->type=FIELD_NORMAL;
+ recinfo->type= FIELD_NORMAL;
+
if (!--hidden_field_count)
null_count=(null_count+7) & ~7; // move to next byte
@@ -10072,9 +10090,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
share->db_record_offset= 1;
- if (share->db_type() == myisam_hton)
+ if (share->db_type() == TMP_ENGINE_HTON)
{
- if (create_myisam_tmp_table(table,param,select_options))
+ if (create_internal_tmp_table(table,param,select_options))
goto err;
}
if (open_tmp_table(table))
@@ -10239,15 +10257,149 @@ static bool open_tmp_table(TABLE *table)
}
-static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- ulonglong options)
+#ifdef WITH_MARIA_STORAGE_ENGINE
+
+/* Create internal Maria temporary table */
+
+static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
+ ulonglong options)
+{
+ int error;
+ MARIA_KEYDEF keydef;
+ MARIA_UNIQUEDEF uniquedef;
+ KEY *keyinfo=param->keyinfo;
+ TABLE_SHARE *share= table->s;
+ MARIA_CREATE_INFO create_info;
+ DBUG_ENTER("create_internal_tmp_table");
+
+ if (share->keys)
+ { // Get keys for ni_create
+ bool using_unique_constraint=0;
+ HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
+ sizeof(*seg) * keyinfo->key_parts);
+ if (!seg)
+ goto err;
+
+ bzero(seg, sizeof(*seg) * keyinfo->key_parts);
+ if (keyinfo->key_length >= table->file->max_key_length() ||
+ keyinfo->key_parts > table->file->max_key_parts() ||
+ share->uniques)
+ {
+ /* Can't create a key; Make a unique constraint instead of a key */
+ share->keys= 0;
+ share->uniques= 1;
+ using_unique_constraint=1;
+ bzero((char*) &uniquedef,sizeof(uniquedef));
+ uniquedef.keysegs=keyinfo->key_parts;
+ uniquedef.seg=seg;
+ uniquedef.null_are_equal=1;
+
+ /* Create extra column for hash value */
+ bzero((uchar*) param->recinfo,sizeof(*param->recinfo));
+ param->recinfo->type= FIELD_CHECK;
+ param->recinfo->length= MARIA_UNIQUE_HASH_LENGTH;
+ param->recinfo++;
+ share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
+ }
+ else
+ {
+ /* Create an unique key */
+ bzero((char*) &keydef,sizeof(keydef));
+ keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
+ keydef.keysegs= keyinfo->key_parts;
+ keydef.seg= seg;
+ }
+ for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
+ {
+ Field *field=keyinfo->key_part[i].field;
+ seg->flag= 0;
+ seg->language= field->charset()->number;
+ seg->length= keyinfo->key_part[i].length;
+ seg->start= keyinfo->key_part[i].offset;
+ if (field->flags & BLOB_FLAG)
+ {
+ seg->type=
+ ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
+ HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
+ seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
+ seg->flag= HA_BLOB_PART;
+ seg->length=0; // Whole blob in unique constraint
+ }
+ else
+ {
+ seg->type= keyinfo->key_part[i].type;
+ /* Tell handler if it can do suffic space compression */
+ if (field->real_type() == MYSQL_TYPE_STRING &&
+ keyinfo->key_part[i].length > 4)
+ seg->flag|= HA_SPACE_PACK;
+ }
+ if (!(field->flags & NOT_NULL_FLAG))
+ {
+ seg->null_bit= field->null_bit;
+ seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
+ /*
+ We are using a GROUP BY on something that contains NULL
+ In this case we have to tell Maria that two NULL should
+ on INSERT be regarded at the same value
+ */
+ if (!using_unique_constraint)
+ keydef.flag|= HA_NULL_ARE_EQUAL;
+ }
+ }
+ }
+ bzero((char*) &create_info,sizeof(create_info));
+
+ if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
+ OPTION_BIG_TABLES)
+ 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,
+ share->keys, &keydef,
+ (uint) (param->recinfo-param->start_recinfo),
+ param->start_recinfo,
+ share->uniques, &uniquedef,
+ &create_info,
+ HA_CREATE_TMP_TABLE)))
+ {
+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
+ table->db_stat=0;
+ goto err;
+ }
+ status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
+ share->db_record_offset= 1;
+ DBUG_RETURN(0);
+ err:
+ DBUG_RETURN(1);
+}
+
+
+bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
+ TMP_TABLE_PARAM *param,
+ int error,
+ bool ignore_last_dupp_key_error)
+{
+ return create_internal_tmp_table_from_heap2(thd, table, param, error,
+ ignore_last_dupp_key_error,
+ maria_hton,
+ "converting HEAP to Maria");
+}
+
+#else
+
+/* Create internal MyISAM temporary table */
+
+static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
+ ulonglong options)
{
int error;
MI_KEYDEF keydef;
MI_UNIQUEDEF uniquedef;
KEY *keyinfo=param->keyinfo;
TABLE_SHARE *share= table->s;
- DBUG_ENTER("create_myisam_tmp_table");
+ DBUG_ENTER("create_internal_tmp_table");
if (share->keys)
{ // Get keys for ni_create
@@ -10350,54 +10502,43 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
}
-void
-free_tmp_table(THD *thd, TABLE *entry)
-{
- MEM_ROOT own_root= entry->mem_root;
- const char *save_proc_info;
- DBUG_ENTER("free_tmp_table");
- DBUG_PRINT("enter",("table: %s",entry->alias));
-
- save_proc_info=thd->proc_info;
- thd->proc_info="removing tmp table";
-
- if (entry->file)
- {
- if (entry->db_stat)
- entry->file->drop_table(entry->s->table_name.str);
- else
- entry->file->delete_table(entry->s->table_name.str);
- delete entry->file;
- }
-
- /* free blobs */
- for (Field **ptr=entry->field ; *ptr ; ptr++)
- (*ptr)->free();
- free_io_cache(entry);
-
- if (entry->temp_pool_slot != MY_BIT_NONE)
- bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
+/*
+ If a HEAP table gets full, create a MyISAM table and copy all rows to this
+*/
- plugin_unlock(0, entry->s->db_plugin);
+bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
+ TMP_TABLE_PARAM *param,
+ int error,
+ bool ignore_last_dupp_key_error)
+{
+ return create_internal_tmp_table_from_heap2(thd, table, param, error,
+ ignore_last_dupp_key_error,
+ myisam_hton,
+ "converting HEAP to MyISAM");
+}
- free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
- thd->proc_info=save_proc_info;
+#endif /* WITH_MARIA_STORAGE_ENGINE */
- DBUG_VOID_RETURN;
-}
/*
-* If a HEAP table gets full, create a MyISAM table and copy all rows to this
+ If a HEAP table gets full, create a internal table in MyISAM or Maria
+ and copy all rows to this
*/
-bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
- int error, bool ignore_last_dupp_key_error)
+
+static bool
+create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
+ TMP_TABLE_PARAM *param,
+ int error,
+ bool ignore_last_dupp_key_error,
+ handlerton *hton,
+ const char *proc_info)
{
TABLE new_table;
TABLE_SHARE share;
const char *save_proc_info;
int write_err;
- DBUG_ENTER("create_myisam_from_heap");
+ DBUG_ENTER("create_internal_tmp_table_from_heap2");
if (table->s->db_type() != heap_hton ||
error != HA_ERR_RECORD_FILE_FULL)
@@ -10408,15 +10549,15 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
new_table= *table;
share= *table->s;
new_table.s= &share;
- new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
+ new_table.s->db_plugin= ha_lock_engine(thd, hton);
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
new_table.s->db_type())))
DBUG_RETURN(1); // End of memory
save_proc_info=thd->proc_info;
- thd->proc_info="converting HEAP to MyISAM";
+ thd->proc_info= proc_info;
- if (create_myisam_tmp_table(&new_table, param,
+ if (create_internal_tmp_table(&new_table, param,
thd->lex->select_lex.options | thd->options))
goto err2;
if (open_tmp_table(&new_table))
@@ -10497,6 +10638,43 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
}
+void
+free_tmp_table(THD *thd, TABLE *entry)
+{
+ MEM_ROOT own_root= entry->mem_root;
+ const char *save_proc_info;
+ DBUG_ENTER("free_tmp_table");
+ DBUG_PRINT("enter",("table: %s",entry->alias));
+
+ save_proc_info=thd->proc_info;
+ thd->proc_info="removing tmp table";
+
+ if (entry->file)
+ {
+ if (entry->db_stat)
+ entry->file->drop_table(entry->s->table_name.str);
+ else
+ entry->file->delete_table(entry->s->table_name.str);
+ delete entry->file;
+ }
+
+ /* free blobs */
+ for (Field **ptr=entry->field ; *ptr ; ptr++)
+ (*ptr)->free();
+ free_io_cache(entry);
+
+ if (entry->temp_pool_slot != MY_BIT_NONE)
+ bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
+
+ plugin_unlock(0, entry->s->db_plugin);
+
+ free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
+ thd->proc_info=save_proc_info;
+
+ DBUG_VOID_RETURN;
+}
+
+
/*
SYNOPSIS
setup_end_select_func()
@@ -11915,7 +12093,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
goto end;
- if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
+ if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param,
error,1))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
table->s->uniques=0; // To ensure rows are the same
@@ -11999,7 +12177,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
copy_funcs(join->tmp_table_param.items_to_copy);
if ((error=table->file->write_row(table->record[0])))
{
- if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
+ if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param,
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
/* Change method to update rows */
@@ -12094,7 +12272,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->having || join->having->val_int())
{
int error= table->file->write_row(table->record[0]);
- if (error && create_myisam_from_heap(join->thd, table,
+ if (error && create_internal_tmp_table_from_heap(join->thd, table,
&join->tmp_table_param,
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR);
@@ -13348,13 +13526,14 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
else if (!found)
{
found=1;
- file->position(record); // Remember position
+ if ((error= file->remember_rnd_pos()))
+ goto err;
}
}
if (!found)
break; // End of file
- /* Restart search on next row */
- error=file->restart_rnd_next(record,file->ref);
+ /* Restart search on saved row */
+ error=file->restart_rnd_next(record);
}
file->extra(HA_EXTRA_NO_CACHE);
@@ -15444,7 +15623,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
if ((write_error= table_arg->file->write_row(table_arg->record[0])))
{
- if (create_myisam_from_heap(thd, table_arg, &tmp_table_param,
+ if (create_internal_tmp_table_from_heap(thd, table_arg, &tmp_table_param,
write_error, 0))
return 1;
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index efa92432e2b..2d9761a8364 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -542,7 +542,7 @@ bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
uint elements, List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param);
void copy_funcs(Item **func_ptr);
-bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
+bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
int error, bool ignore_last_dupp_error);
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
Field* create_tmp_field_from_field(THD *thd, Field* org_field,
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 38db2fe85a5..4280722607b 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -165,15 +165,15 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin,
switch (plug->license) {
case PLUGIN_LICENSE_GPL:
- table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
+ table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
strlen(PLUGIN_LICENSE_GPL_STRING), cs);
break;
case PLUGIN_LICENSE_BSD:
- table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
+ table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
strlen(PLUGIN_LICENSE_BSD_STRING), cs);
break;
default:
- table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
+ table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
break;
}
@@ -481,7 +481,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
file=dirp->dir_entry+i;
if (dir)
{ /* Return databases */
- if ((file->name[0] == '.' &&
+ if ((file->name[0] == '.' &&
((file->name[1] == '.' && file->name[2] == '\0') ||
file->name[1] == '\0')))
continue; /* . or .. */
@@ -507,7 +507,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
if (wild && wild_compare(uname, wild, 0))
continue;
- if (!(file_name=
+ if (!(file_name=
thd->make_lex_string(file_name, uname, file_name_len, TRUE)))
{
my_dirend(dirp);
@@ -546,7 +546,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
continue;
}
#endif
- if (!(file_name=
+ if (!(file_name=
thd->make_lex_string(file_name, uname, file_name_len, TRUE)) ||
files->push_back(file_name))
{
@@ -584,7 +584,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
/*
Clear all messages with 'error' level status and
- issue a warning with 'warning' level status in
+ issue a warning with 'warning' level status in
case of invalid view and last error is ER_VIEW_INVALID
*/
mysql_reset_errors(thd, true);
@@ -774,7 +774,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
Field **ptr,*field;
for (ptr=table->field ; (field= *ptr); ptr++)
{
- if (!wild || !wild[0] ||
+ if (!wild || !wild[0] ||
!wild_case_compare(system_charset_info, field->field_name,wild))
{
if (table_list->view)
@@ -985,13 +985,13 @@ static bool get_field_default_value(THD *thd, TABLE *table,
bool has_default;
bool has_now_default;
- /*
+ /*
We are using CURRENT_TIMESTAMP instead of NOW because it is
more standard
*/
- has_now_default= table->timestamp_field == field &&
+ has_now_default= table->timestamp_field == field &&
field->unireg_check != Field::TIMESTAMP_UN_FIELD;
-
+
has_default= (field->type() != FIELD_TYPE_BLOB &&
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
field->unireg_check != Field::NEXT_NUMBER &&
@@ -1046,11 +1046,11 @@ static bool get_field_default_value(THD *thd, TABLE *table,
to tailor the format of the statement. Can be
NULL, in which case only SQL_MODE is considered
when building the statement.
-
+
NOTE
Currently always return 0, but might return error code in the
future.
-
+
RETURN
0 OK
*/
@@ -1132,7 +1132,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
field->sql_type(type);
packet->append(type.ptr(), type.length(), system_charset_info);
- if (field->has_charset() &&
+ if (field->has_charset() &&
!(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
{
if (field->charset() != share->table_charset)
@@ -1140,8 +1140,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
packet->append(field->charset()->csname);
}
- /*
- For string types dump collation name only if
+ /*
+ For string types dump collation name only if
collation is not primary for the given charset
*/
if (!(field->charset()->state & MY_CS_PRIMARY))
@@ -1168,11 +1168,11 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
}
- if (!limited_mysql_mode && table->timestamp_field == field &&
+ if (!limited_mysql_mode && table->timestamp_field == field &&
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
- if (field->unireg_check == Field::NEXT_NUMBER &&
+ if (field->unireg_check == Field::NEXT_NUMBER &&
!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
@@ -1321,7 +1321,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(buff, (uint) (end - buff));
}
-
+
if (share->table_charset &&
!(thd->variables.sql_mode & MODE_MYSQL323) &&
!(thd->variables.sql_mode & MODE_MYSQL40))
@@ -1492,7 +1492,7 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
/*
Append DEFINER clause to the given buffer.
-
+
SYNOPSIS
append_definer()
thd [in] thread handle
@@ -1521,7 +1521,7 @@ static void append_algorithm(TABLE_LIST *table, String *buff)
/*
Append DEFINER clause to the given buffer.
-
+
SYNOPSIS
append_definer()
thd [in] thread handle
@@ -1681,8 +1681,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
"%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
}
else
- thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
- tmp_sctx->host_or_ip :
+ thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
+ tmp_sctx->host_or_ip :
tmp_sctx->host ? tmp_sctx->host : "");
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
@@ -1711,7 +1711,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thd_info->query=0;
if (tmp->query)
{
- /*
+ /*
query_length is always set to 0 when we set query = NULL; see
the comment in sql_class.h why this prevents crashes in possible
races with query_length
@@ -1958,7 +1958,7 @@ void reset_status_vars()
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
if (ptr->type == SHOW_LONG)
*(ulong*) ptr->value= 0;
- }
+ }
}
/*
@@ -2204,14 +2204,14 @@ void calc_sum_of_all_status(STATUS_VAR *to)
I_List_iterator<THD> it(threads);
THD *tmp;
-
+
/* Get global values as base */
*to= global_status_var;
-
+
/* Add to this status from existing threads */
while ((tmp= it++))
add_to_status(to, &tmp->status_var);
-
+
VOID(pthread_mutex_unlock(&LOCK_thread_count));
DBUG_VOID_RETURN;
}
@@ -2246,7 +2246,7 @@ bool schema_table_store_record(THD *thd, TABLE *table)
int error;
if ((error= table->file->ha_write_row(table->record[0])))
{
- if (create_myisam_from_heap(thd, table,
+ if (create_internal_tmp_table_from_heap(thd, table,
table->pos_in_table_list->schema_table_param,
error, 0))
return 1;
@@ -2268,23 +2268,23 @@ int make_table_list(THD *thd, SELECT_LEX *sel,
/**
- @brief Get lookup value from the part of 'WHERE' condition
+ @brief Get lookup value from the part of 'WHERE' condition
- @details This function gets lookup value from
- the part of 'WHERE' condition if it's possible and
+ @details This function gets lookup value from
+ the part of 'WHERE' condition if it's possible and
fill appropriate lookup_field_vals struct field
with this value.
@param[in] thd thread handler
@param[in] item_func part of WHERE condition
@param[in] table I_S table
- @param[in, out] lookup_field_vals Struct which holds lookup values
+ @param[in, out] lookup_field_vals Struct which holds lookup values
@return void
*/
void get_lookup_value(THD *thd, Item_func *item_func,
- TABLE_LIST *table,
+ TABLE_LIST *table,
LOOKUP_FIELD_VALUES *lookup_field_vals)
{
ST_SCHEMA_TABLE *schema_table= table->schema_table;
@@ -2346,16 +2346,16 @@ void get_lookup_value(THD *thd, Item_func *item_func,
/**
- @brief Calculates lookup values from 'WHERE' condition
+ @brief Calculates lookup values from 'WHERE' condition
@details This function calculates lookup value(database name, table name)
- from 'WHERE' condition if it's possible and
+ from 'WHERE' condition if it's possible and
fill lookup_field_vals struct fields with these values.
@param[in] thd thread handler
@param[in] cond WHERE condition
@param[in] table I_S table
- @param[in, out] lookup_field_vals Struct which holds lookup values
+ @param[in, out] lookup_field_vals Struct which holds lookup values
@return void
*/
@@ -2495,7 +2495,7 @@ static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
@param[in] thd thread handler
@param[in] cond WHERE condition
@param[in] tables I_S table
- @param[in, out] lookup_field_values Struct which holds lookup values
+ @param[in, out] lookup_field_values Struct which holds lookup values
@return void
*/
@@ -2556,7 +2556,7 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
idx_field_vals idx_field_vals->db_name contains db name or
wild string
with_i_schema returns 1 if we added 'IS' name to list
- otherwise returns 0
+ otherwise returns 0
RETURN
zero success
@@ -2580,7 +2580,7 @@ int make_db_list(THD *thd, List<LEX_STRING> *files,
LIKE clause (see also get_index_field_values() function)
*/
if (!lookup_field_vals->db_value.str ||
- !wild_case_compare(system_charset_info,
+ !wild_case_compare(system_charset_info,
INFORMATION_SCHEMA_NAME.str,
lookup_field_vals->db_value.str))
{
@@ -2624,7 +2624,7 @@ int make_db_list(THD *thd, List<LEX_STRING> *files,
}
-struct st_add_schema_table
+struct st_add_schema_table
{
List<LEX_STRING> *files;
const char *wild;
@@ -2688,7 +2688,7 @@ int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
continue;
}
- if ((file_name=
+ if ((file_name=
thd->make_lex_string(file_name, tmp_schema_table->table_name,
strlen(tmp_schema_table->table_name), TRUE)) &&
!files->push_back(file_name))
@@ -2744,7 +2744,7 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
}
}
else
- {
+ {
if (table_names->push_back(&lookup_field_vals->table_value))
return 1;
/*
@@ -2805,7 +2805,7 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
@retval 1 error
*/
-static int
+static int
fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
ST_SCHEMA_TABLE *schema_table,
Open_tables_state *open_tables_state_backup)
@@ -2832,7 +2832,7 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
Let us set fake sql_command so views won't try to merge
themselves into main statement. If we don't do this,
SELECT * from information_schema.xxxx will cause problems.
- SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
+ SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
*/
lex->sql_command= SQLCOM_SHOW_FIELDS;
res= open_normal_and_derived_tables(thd, show_table_list,
@@ -2842,11 +2842,11 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
get_all_tables() returns 1 on failure and 0 on success thus
return only these and not the result code of ::process_table()
- We should use show_table_list->alias instead of
+ We should use show_table_list->alias instead of
show_table_list->table_name because table_name
could be changed during opening of I_S tables. It's safe
- to use alias because alias contains original table name
- in this case(this part of code is used only for
+ to use alias because alias contains original table name
+ in this case(this part of code is used only for
'show columns' & 'show statistics' commands).
*/
table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
@@ -2856,7 +2856,7 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
show_table_list->db_length, FALSE);
else
db_name= &show_table_list->view_db;
-
+
error= test(schema_table->process_table(thd, show_table_list,
table, res, db_name,
@@ -2894,7 +2894,7 @@ static int fill_schema_table_names(THD *thd, TABLE *table,
{
enum legacy_db_type not_used;
char path[FN_REFLEN];
- (void) build_table_filename(path, sizeof(path), db_name->str,
+ (void) build_table_filename(path, sizeof(path), db_name->str,
table_name->str, reg_ext, 0);
switch (mysql_frm_type(thd, path, &not_used)) {
case FRMTYPE_ERROR:
@@ -2982,7 +2982,7 @@ static uint get_table_open_method(TABLE_LIST *tables,
*/
static int fill_schema_table_from_frm(THD *thd,TABLE *table,
- ST_SCHEMA_TABLE *schema_table,
+ ST_SCHEMA_TABLE *schema_table,
LEX_STRING *db_name,
LEX_STRING *table_name,
enum enum_schema_tables schema_table_idx)
@@ -3009,7 +3009,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table,
res= 0;
goto err;
}
-
+
if (share->is_view)
{
if (schema_table->i_s_requested_object & OPEN_TABLE_ONLY)
@@ -3021,7 +3021,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table,
else if (schema_table->i_s_requested_object & OPEN_VIEW_FULL)
{
/*
- tell get_all_tables() to fall back to
+ tell get_all_tables() to fall back to
open_normal_and_derived_tables()
*/
res= 1;
@@ -3090,7 +3090,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
List<LEX_STRING> db_names;
List_iterator_fast<LEX_STRING> it(db_names);
COND *partial_cond= 0;
- uint derived_tables= lex->derived_tables;
+ uint derived_tables= lex->derived_tables;
int error= 1;
Open_tables_state open_tables_state_backup;
bool save_view_prepare_mode= lex->view_prepare_mode;
@@ -3111,7 +3111,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
*/
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
- /*
+ /*
this branch processes SHOW FIELDS, SHOW INDEXES commands.
see sql_parse.cc, prepare_schema_table() function where
this values are initialized
@@ -3131,7 +3131,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
{
- /*
+ /*
if lookup value is empty string then
it's impossible table name or db name
*/
@@ -3149,7 +3149,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
!lookup_field_vals.wild_db_value)
tables->has_db_lookup_value= TRUE;
if (lookup_field_vals.table_value.length &&
- !lookup_field_vals.wild_table_value)
+ !lookup_field_vals.wild_table_value)
tables->has_table_lookup_value= TRUE;
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
@@ -3173,7 +3173,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
while ((db_name= it++))
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (!check_access(thd,SELECT_ACL, db_name->str,
+ if (!check_access(thd,SELECT_ACL, db_name->str,
&thd->col_access, 0, 1, with_i_schema) ||
sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
@@ -3203,7 +3203,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
{
/*
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
- we can skip table opening and we don't have lookup value for
+ we can skip table opening and we don't have lookup value for
table name or lookup value is wild string(table name list is
already created by make_table_name_list() function).
*/
@@ -3225,7 +3225,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
}
else
{
- if (!(table_open_method & ~OPEN_FRM_ONLY) &&
+ if (!(table_open_method & ~OPEN_FRM_ONLY) &&
!with_i_schema)
{
if (!fill_schema_table_from_frm(thd, table, schema_table, db_name,
@@ -3256,7 +3256,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
res= open_normal_and_derived_tables(thd, show_table_list,
MYSQL_LOCK_IGNORE_FLUSH);
lex->sql_command= save_sql_command;
-
+
if (thd->net.last_errno == ER_NO_SUCH_TABLE)
{
/*
@@ -3271,10 +3271,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
else
{
/*
- We should use show_table_list->alias instead of
+ We should use show_table_list->alias instead of
show_table_list->table_name because table_name
could be changed during opening of I_S tables. It's safe
- to use alias because alias contains original table name
+ to use alias because alias contains original table name
in this case.
*/
thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
@@ -3482,7 +3482,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
ptr=strmov(ptr," delay_key_write=1");
if (share->row_type != ROW_TYPE_DEFAULT)
- ptr=strxmov(ptr, " row_format=",
+ ptr=strxmov(ptr, " row_format=",
ha_row_type[(uint) share->row_type],
NullS);
if (share->transactional != HA_CHOICE_UNDEF)
@@ -3492,8 +3492,8 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
NullS);
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
- if (show_table->s->db_type() == partition_hton &&
- show_table->part_info != NULL &&
+ if (show_table->s->db_type() == partition_hton &&
+ show_table->part_info != NULL &&
show_table->part_info->no_parts > 0)
ptr= strmov(ptr, " partitioned");
#endif
@@ -3501,7 +3501,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
ptr= strxmov(ptr, " transactional=",
ha_choice_values[(uint) share->transactional], NullS);
table->field[19]->store(option_buff+1,
- (ptr == option_buff ? 0 :
+ (ptr == option_buff ? 0 :
(uint) (ptr-option_buff)-1), cs);
if (share->comment.str)
@@ -3615,7 +3615,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
/*
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
rather than in SHOW COLUMNS
- */
+ */
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
thd->net.last_errno, thd->net.last_error);
thd->clear_error();
@@ -3653,7 +3653,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
uint col_access;
check_access(thd,SELECT_ACL | EXTRA_ACL, db_name->str,
&tables->grant.privilege, 0, 0, test(tables->schema_table));
- col_access= get_column_grant(thd, &tables->grant,
+ col_access= get_column_grant(thd, &tables->grant,
db_name->str, table_name->str,
field->field_name) & COL_ACLS;
if (!tables->schema_table && !col_access)
@@ -3676,7 +3676,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
cs);
table->field[4]->store((longlong) count, TRUE);
field->sql_type(type);
- table->field[14]->store(type.ptr(), type.length(), cs);
+ table->field[14]->store(type.ptr(), type.length(), cs);
tmp_buff= strchr(type.ptr(), '(');
table->field[7]->store(type.ptr(),
(tmp_buff ? tmp_buff - type.ptr() :
@@ -3698,7 +3698,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
uint32 octet_max_length= field->max_display_length();
if (is_blob && octet_max_length != (uint32) 4294967295U)
octet_max_length /= field->charset()->mbmaxlen;
- longlong char_max_len= is_blob ?
+ longlong char_max_len= is_blob ?
(longlong) octet_max_length / field->charset()->mbminlen :
(longlong) octet_max_length / field->charset()->mbmaxlen;
table->field[8]->store(char_max_len, TRUE);
@@ -3731,7 +3731,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
field_length= field->max_display_length();
decimals= -1; // return NULL
break;
- case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
field_length= field->field_length;
if (decimals == NOT_FIXED_DEC)
@@ -3794,7 +3794,7 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
{
CHARSET_INFO *tmp_cs= cs[0];
- if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
+ if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
(tmp_cs->state & MY_CS_AVAILABLE) &&
!(tmp_cs->state & MY_CS_HIDDEN) &&
!(wild && wild[0] &&
@@ -3882,7 +3882,7 @@ int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
{
CHARSET_INFO *tmp_cl= cl[0];
- if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
+ if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
!my_charset_same(tmp_cs, tmp_cl))
continue;
if (!(wild && wild[0] &&
@@ -3916,13 +3916,13 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
{
CHARSET_INFO **cl;
CHARSET_INFO *tmp_cs= cs[0];
- if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
+ if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
!(tmp_cs->state & MY_CS_PRIMARY))
continue;
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
{
CHARSET_INFO *tmp_cl= cl[0];
- if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
+ if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
!my_charset_same(tmp_cs,tmp_cl))
continue;
restore_record(table, s->default_values);
@@ -3988,7 +3988,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
table->field[10]->store(STRING_WITH_LEN("SQL"), cs);
get_field(thd->mem_root, proc_table->field[6], &tmp_string);
table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs);
- table->field[12]->store(sp_data_access_name[enum_idx].str,
+ table->field[12]->store(sp_data_access_name[enum_idx].str,
sp_data_access_name[enum_idx].length , cs);
get_field(thd->mem_root, proc_table->field[7], &tmp_string);
table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs);
@@ -4281,10 +4281,10 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
if (res && thd->net.last_errno)
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
thd->net.last_errno, thd->net.last_error);
}
- if (res)
+ if (res)
thd->clear_error();
DBUG_RETURN(0);
}
@@ -4325,7 +4325,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
TABLE *show_table= tables->table;
KEY *key_info=show_table->key_info;
uint primary_key= show_table->s->primary_key;
- show_table->file->info(HA_STATUS_VARIABLE |
+ show_table->file->info(HA_STATUS_VARIABLE |
HA_STATUS_NO_LOCK |
HA_STATUS_TIME);
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
@@ -4354,7 +4354,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
while ((f_key_info=it++))
{
- if (store_constraints(thd, table, db_name, table_name,
+ if (store_constraints(thd, table, db_name, table_name,
f_key_info->forein_id->str,
strlen(f_key_info->forein_id->str),
"FOREIGN KEY", 11))
@@ -4513,7 +4513,7 @@ static int get_schema_key_column_usage_record(THD *thd,
TABLE *show_table= tables->table;
KEY *key_info=show_table->key_info;
uint primary_key= show_table->s->primary_key;
- show_table->file->info(HA_STATUS_VARIABLE |
+ show_table->file->info(HA_STATUS_VARIABLE |
HA_STATUS_NO_LOCK |
HA_STATUS_TIME);
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
@@ -4530,8 +4530,8 @@ static int get_schema_key_column_usage_record(THD *thd,
restore_record(table, s->default_values);
store_key_column_usage(table, db_name, table_name,
key_info->name,
- strlen(key_info->name),
- key_part->field->field_name,
+ strlen(key_info->name),
+ key_part->field->field_name,
strlen(key_part->field->field_name),
(longlong) f_idx);
if (schema_table_store_record(thd, table))
@@ -4567,7 +4567,7 @@ static int get_schema_key_column_usage_record(THD *thd,
system_charset_info);
table->field[9]->set_notnull();
table->field[10]->store(f_key_info->referenced_table->str,
- f_key_info->referenced_table->length,
+ f_key_info->referenced_table->length,
system_charset_info);
table->field[10]->set_notnull();
table->field[11]->store(r_info->str, r_info->length,
@@ -4735,7 +4735,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
tmp_res.append(partition_keywords[PKW_KEY].str,
partition_keywords[PKW_KEY].length);
else
- tmp_res.append(partition_keywords[PKW_HASH].str,
+ tmp_res.append(partition_keywords[PKW_HASH].str,
partition_keywords[PKW_HASH].length);
table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
break;
@@ -4770,7 +4770,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
tmp_res.append(partition_keywords[PKW_KEY].str,
partition_keywords[PKW_KEY].length);
else
- tmp_res.append(partition_keywords[PKW_HASH].str,
+ tmp_res.append(partition_keywords[PKW_HASH].str,
partition_keywords[PKW_HASH].length);
table->field[8]->store(tmp_res.ptr(), tmp_res.length(), cs);
table->field[8]->set_notnull();
@@ -4849,7 +4849,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
/* SUBPARTITION_ORDINAL_POSITION */
table->field[6]->store((longlong) ++subpart_pos, TRUE);
table->field[6]->set_notnull();
-
+
store_schema_partitions_record(thd, table, show_table, subpart_elem,
file, part_id);
part_id++;
@@ -5067,7 +5067,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
else
sch_table->field[ISE_ON_COMPLETION]->
store(STRING_WITH_LEN("PRESERVE"), scs);
-
+
number_to_datetime(et.created, &time, 0, &not_used);
DBUG_ASSERT(not_used==0);
sch_table->field[ISE_CREATED]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
@@ -5188,7 +5188,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
tmp1= &tmp;
}
else
- {
+ {
option_type= OPT_SESSION;
tmp1= &thd->status_var;
}
@@ -5243,7 +5243,7 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
{
List<FOREIGN_KEY_INFO> f_key_list;
TABLE *show_table= tables->table;
- show_table->file->info(HA_STATUS_VARIABLE |
+ show_table->file->info(HA_STATUS_VARIABLE |
HA_STATUS_NO_LOCK |
HA_STATUS_TIME);
@@ -5257,16 +5257,16 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
table->field[9]->store(table_name->str, table_name->length, cs);
table->field[2]->store(f_key_info->forein_id->str,
f_key_info->forein_id->length, cs);
- table->field[4]->store(f_key_info->referenced_db->str,
+ table->field[4]->store(f_key_info->referenced_db->str,
f_key_info->referenced_db->length, cs);
- table->field[10]->store(f_key_info->referenced_table->str,
+ table->field[10]->store(f_key_info->referenced_table->str,
f_key_info->referenced_table->length, cs);
- table->field[5]->store(f_key_info->referenced_key_name->str,
+ table->field[5]->store(f_key_info->referenced_key_name->str,
f_key_info->referenced_key_name->length, cs);
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
- table->field[7]->store(f_key_info->update_method->str,
+ table->field[7]->store(f_key_info->update_method->str,
f_key_info->update_method->length, cs);
- table->field[8]->store(f_key_info->delete_method->str,
+ table->field[8]->store(f_key_info->delete_method->str,
f_key_info->delete_method->length, cs);
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
@@ -5275,7 +5275,7 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
DBUG_RETURN(0);
}
-struct schema_table_ref
+struct schema_table_ref
{
const char *table_name;
ST_SCHEMA_TABLE *schema_table;
@@ -5342,7 +5342,7 @@ ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
}
schema_table_a.table_name= table_name;
- if (plugin_foreach(thd, find_schema_table_in_plugin,
+ if (plugin_foreach(thd, find_schema_table_in_plugin,
MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
DBUG_RETURN(schema_table_a.schema_table);
@@ -5409,7 +5409,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
break;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
- if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
+ if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
fields_info->field_length)) == NULL)
DBUG_RETURN(NULL);
break;
@@ -5462,7 +5462,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
tmp_table_param->schema_table= 1;
SELECT_LEX *select_lex= thd->lex->current_select;
if (!(table= create_tmp_table(thd, tmp_table_param,
- field_list, (ORDER*) 0, 0, 0,
+ field_list, (ORDER*) 0, 0, 0,
(select_lex->options | thd->options |
TMP_TABLE_ALL_COLUMNS),
HA_POS_ERROR, table_list->alias)))
@@ -5807,7 +5807,7 @@ bool get_schema_tables_result(JOIN *join,
thd->no_warnings_for_error= 1;
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
- {
+ {
if (!tab->table || !tab->table->pos_in_table_list)
break;
@@ -5926,17 +5926,17 @@ ST_FIELD_INFO tables_fields_info[]=
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
- {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
- {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
- {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
- {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
+ {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
@@ -6401,9 +6401,9 @@ ST_FIELD_INFO files_fields_info[]=
{"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
{"INITIAL_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
- {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
+ {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
- {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
+ {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
{"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
{"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
@@ -6415,20 +6415,20 @@ ST_FIELD_INFO files_fields_info[]=
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", SKIP_OPEN_TABLE},
{"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", SKIP_OPEN_TABLE},
- {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", SKIP_OPEN_TABLE},
- {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", SKIP_OPEN_TABLE},
- {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", SKIP_OPEN_TABLE},
- {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", SKIP_OPEN_TABLE},
- {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", SKIP_OPEN_TABLE},
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", SKIP_OPEN_TABLE},
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", SKIP_OPEN_TABLE},
{"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", SKIP_OPEN_TABLE},
- {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", SKIP_OPEN_TABLE},
{"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
@@ -6477,13 +6477,13 @@ ST_FIELD_INFO referential_constraints_fields_info[]=
ST_SCHEMA_TABLE schema_tables[]=
{
- {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
+ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
- {"COLLATIONS", collation_fields_info, create_schema_table,
+ {"COLLATIONS", collation_fields_info, create_schema_table,
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
- {"COLUMNS", columns_fields_info, create_schema_table,
+ {"COLUMNS", columns_fields_info, create_schema_table,
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
{"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
@@ -6512,7 +6512,7 @@ ST_SCHEMA_TABLE schema_tables[]=
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
1, 9, 0, OPEN_TABLE_ONLY},
- {"ROUTINES", proc_fields_info, create_schema_table,
+ {"ROUTINES", proc_fields_info, create_schema_table,
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
{"SCHEMATA", schema_fields_info, create_schema_table,
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
@@ -6522,12 +6522,12 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_status, make_old_format, 0, -1, -1, 0, 0},
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
fill_variables, make_old_format, 0, -1, -1, 0, 0},
- {"STATISTICS", stat_fields_info, create_schema_table,
+ {"STATISTICS", stat_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
- {"STATUS", variables_fields_info, create_schema_table, fill_status,
+ {"STATUS", variables_fields_info, create_schema_table, fill_status,
make_old_format, 0, -1, -1, 1, 0},
- {"TABLES", tables_fields_info, create_schema_table,
+ {"TABLES", tables_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
OPTIMIZE_I_S_TABLE},
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
@@ -6539,11 +6539,11 @@ ST_SCHEMA_TABLE schema_tables[]=
{"TRIGGERS", triggers_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
OPEN_TABLE_ONLY},
- {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
+ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
make_old_format, 0, -1, -1, 1, 0},
- {"VIEWS", view_fields_info, create_schema_table,
+ {"VIEWS", view_fields_info, create_schema_table,
get_all_tables, 0, get_schema_views_record, 1, 2, 0,
OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -6569,8 +6569,8 @@ int initialize_schema_table(st_plugin_int *plugin)
{
schema_table->create_table= create_schema_table;
schema_table->old_format= make_old_format;
- schema_table->idx_field1= -1,
- schema_table->idx_field2= -1;
+ schema_table->idx_field1= -1,
+ schema_table->idx_field2= -1;
/* Make the name available to the init() function. */
schema_table->table_name= plugin->name.str;
@@ -6581,7 +6581,7 @@ int initialize_schema_table(st_plugin_int *plugin)
plugin->name.str);
goto err;
}
-
+
/* Make sure the plugin name is not set inside the init() function. */
schema_table->table_name= plugin->name.str;
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 26f9833fd3d..6197d646cc1 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3137,8 +3137,9 @@ bool mysql_create_table_no_lock(THD *thd,
if (check_engine(thd, table_name, create_info))
DBUG_RETURN(TRUE);
db_options= create_info->table_options;
- if (create_info->row_type == ROW_TYPE_DYNAMIC)
- db_options|=HA_OPTION_PACK_RECORD;
+ if (create_info->row_type != ROW_TYPE_FIXED &&
+ create_info->row_type != ROW_TYPE_DEFAULT)
+ db_options|= HA_OPTION_PACK_RECORD;
alias= table_case_name(create_info, table_name);
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
create_info->db_type)))
@@ -5015,8 +5016,7 @@ compare_tables(TABLE *table,
}
/* Don't pack rows in old tables if the user has requested this. */
- if (create_info->row_type == ROW_TYPE_DYNAMIC ||
- (new_field->flags & BLOB_FLAG) ||
+ if ((new_field->flags & BLOB_FLAG) ||
new_field->sql_type == MYSQL_TYPE_VARCHAR &&
create_info->row_type != ROW_TYPE_FIXED)
create_info->table_options|= HA_OPTION_PACK_RECORD;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 5da4b97cc5d..33da9147b51 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -63,9 +63,9 @@ bool select_union::send_data(List<Item> &values)
if ((error= table->file->ha_write_row(table->record[0])))
{
- /* create_myisam_from_heap will generate error if needed */
+ /* create_internal_tmp_table_from_heap will generate error if needed */
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
- create_myisam_from_heap(thd, table, &tmp_table_param, error, 1))
+ create_internal_tmp_table_from_heap(thd, table, &tmp_table_param, error, 1))
return 1;
}
return 0;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 4071bb86c90..bb1508321f4 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1694,7 +1694,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
{
if (error &&
- create_myisam_from_heap(thd, tmp_table,
+ create_internal_tmp_table_from_heap(thd, tmp_table,
tmp_table_param + offset, error, 1))
{
do_update= 0;
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 606710f1f6c..4efa5ba1af7 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -267,8 +267,10 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type,
# error code
*/
-int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
- MARIA_COLUMNDEF **recinfo_out, uint *records_out)
+static int table2maria(TABLE *table_arg, data_file_type row_type,
+ MARIA_KEYDEF **keydef_out,
+ MARIA_COLUMNDEF **recinfo_out, uint *records_out,
+ MARIA_CREATE_INFO *create_info)
{
uint i, j, recpos, minpos, fieldpos, temp_length, length;
enum ha_base_keytype type= HA_KEYTYPE_BINARY;
@@ -281,6 +283,9 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
uint options= share->db_options_in_use;
DBUG_ENTER("table2maria");
+ if (row_type == BLOCK_RECORD)
+ options|= HA_OPTION_PACK_RECORD;
+
if (!(my_multi_malloc(MYF(MY_WME),
recinfo_out, (share->fields * 2 + 2) * sizeof(MARIA_COLUMNDEF),
keydef_out, share->keys * sizeof(MARIA_KEYDEF),
@@ -369,6 +374,8 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
record= table_arg->record[0];
recpos= 0;
recinfo_pos= recinfo;
+ create_info->null_bytes= table_arg->s->null_bytes;
+
while (recpos < (uint) share->reclength)
{
Field **field, *found= 0;
@@ -394,13 +401,6 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
}
DBUG_PRINT("loop", ("found: 0x%lx recpos: %d minpos: %d length: %d",
(long) found, recpos, minpos, length));
- if (recpos != minpos)
- {
- /* reserve space for null bits */
- bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
- recinfo_pos->type= FIELD_NORMAL;
- recinfo_pos++->length= (uint16) (minpos - recpos);
- }
if (!found)
break;
@@ -561,6 +561,7 @@ int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
}
}
}
+
for (i= 0; i < t1_recs; i++)
{
MARIA_COLUMNDEF *t1_rec= &t1_recinfo[i];
@@ -1900,13 +1901,20 @@ int ha_maria::rnd_next(uchar *buf)
}
-int ha_maria::restart_rnd_next(uchar *buf, uchar *pos)
+int ha_maria::remember_rnd_pos()
{
- return rnd_pos(buf, pos);
+ return (*file->s->scan_remember_pos)(file, &remember_pos);
}
-int ha_maria::rnd_pos(uchar * buf, uchar *pos)
+int ha_maria::restart_rnd_next(uchar *buf)
+{
+ (*file->s->scan_restore_pos)(file, remember_pos);
+ return rnd_next(buf);
+}
+
+
+int ha_maria::rnd_pos(uchar *buf, uchar *pos)
{
ha_statistic_increment(&SSV::ha_read_rnd_count);
int error= maria_rrnd(file, buf, my_get_ptr(pos, ref_length));
@@ -1915,7 +1923,7 @@ int ha_maria::rnd_pos(uchar * buf, uchar *pos)
}
-void ha_maria::position(const uchar * record)
+void ha_maria::position(const uchar *record)
{
my_off_t row_position= maria_position(file);
my_store_ptr(ref, ref_length, row_position);
@@ -2216,9 +2224,10 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
ER_ILLEGAL_HA_CREATE_OPTION,
"Row format set to PAGE because of TRANSACTIONAL=1 option");
- if ((error= table2maria(table_arg, &keydef, &recinfo, &record_count)))
- DBUG_RETURN(error); /* purecov: inspected */
bzero((char*) &create_info, sizeof(create_info));
+ if ((error= table2maria(table_arg, row_type, &keydef, &recinfo,
+ &record_count, &create_info)))
+ DBUG_RETURN(error); /* purecov: inspected */
create_info.max_rows= share->max_rows;
create_info.reloc_rows= share->min_rows;
create_info.with_auto_increment= share->next_number_key_offset == 0;
@@ -2387,7 +2396,8 @@ bool ha_maria::check_if_incompatible_data(HA_CREATE_INFO *create_info,
if (create_info->auto_increment_value != stats.auto_increment_value ||
create_info->data_file_name != data_file_name ||
create_info->index_file_name != index_file_name ||
- maria_row_type(create_info) != data_file_type ||
+ (create_info->row_type != data_file_type &&
+ create_info->row_type != ROW_TYPE_DEFAULT) ||
table_changes == IS_EQUAL_NO ||
table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
return COMPATIBLE_DATA_NO;
diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h
index 78d88cf52c6..cb4efffff5f 100644
--- a/storage/maria/ha_maria.h
+++ b/storage/maria/ha_maria.h
@@ -36,6 +36,7 @@ class ha_maria :public handler
{
MARIA_HA *file;
ulonglong int_table_flags;
+ MARIA_RECORD_POS remember_pos;
char *data_file_name, *index_file_name;
enum data_file_type data_file_type;
bool can_enable_indexes;
@@ -101,7 +102,8 @@ public:
int rnd_end(void);
int rnd_next(uchar * buf);
int rnd_pos(uchar * buf, uchar * pos);
- int restart_rnd_next(uchar * buf, uchar * pos);
+ int remember_rnd_pos();
+ int restart_rnd_next(uchar * buf);
void position(const uchar * record);
int info(uint);
int extra(enum ha_extra_function operation);
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index eb3b588b69d..e1ba7de0c3d 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -502,7 +502,8 @@ my_bool _ma_init_block_record(MARIA_HA *info)
sizeof(MARIA_BITMAP_BLOCK), default_extents,
64))
goto err;
- if (!(info->cur_row.extents= my_malloc(default_extents * ROW_EXTENT_SIZE,
+ info->cur_row.extents_buffer_length= default_extents * ROW_EXTENT_SIZE;
+ if (!(info->cur_row.extents= my_malloc(info->cur_row.extents_buffer_length,
MYF(MY_WME))))
goto err;
@@ -1921,7 +1922,7 @@ static my_bool write_block_record(MARIA_HA *info,
row_extents_first_part= data;
data+= ROW_EXTENT_SIZE;
}
- if (share->base.pack_fields)
+ if (share->base.max_field_lengths)
store_key_length_inc(data, row->field_lengths_length);
if (share->calc_checksum)
{
@@ -3292,7 +3293,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record)
delete_tails(info, info->cur_row.tail_positions))
goto err;
- if (info->cur_row.extents && free_full_pages(info, &info->cur_row))
+ if (info->cur_row.extents_count && free_full_pages(info, &info->cur_row))
goto err;
if (share->now_transactional)
@@ -4155,6 +4156,81 @@ void _ma_scan_end_block_record(MARIA_HA *info)
DBUG_ENTER("_ma_scan_end_block_record");
my_free(info->scan.bitmap_buff, MYF(MY_ALLOW_ZERO_PTR));
info->scan.bitmap_buff= 0;
+ if (info->scan_save)
+ {
+ my_free(info->scan_save, MYF(0));
+ info->scan_save= 0;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ @brief Save current scan position
+
+ @note
+ For the moment we can only remember one position, but this is
+ good enough for MySQL usage
+
+ @Warning
+ When this function is called, we assume that the thread is not deleting
+ or updating the current row before ma_scan_restore_block_record()
+ is called!
+
+ @return
+ @retval 0 ok
+ @retval HA_ERR_WRONG_IN_RECORD Could not allocate memory to hold position
+*/
+
+int _ma_scan_remember_block_record(MARIA_HA *info,
+ MARIA_RECORD_POS *lastpos)
+{
+ uchar *bitmap_buff;
+ DBUG_ENTER("_ma_scan_remember_block_record");
+ if (!(info->scan_save))
+ {
+ if (!(info->scan_save= my_malloc(ALIGN_SIZE(sizeof(*info->scan_save)) +
+ info->s->block_size * 2,
+ MYF(MY_WME))))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ info->scan_save->bitmap_buff= ((uchar*) info->scan_save +
+ ALIGN_SIZE(sizeof(*info->scan_save)));
+ }
+ /* Point to the last read row */
+ *lastpos= info->cur_row.nextpos - 1;
+ info->scan.dir+= DIR_ENTRY_SIZE;
+
+ /* Remember used bitmap and used head page */
+ bitmap_buff= info->scan_save->bitmap_buff;
+ memcpy(info->scan_save, &info->scan, sizeof(*info->scan_save));
+ info->scan_save->bitmap_buff= bitmap_buff;
+ memcpy(bitmap_buff, info->scan.bitmap_buff, info->s->block_size * 2);
+ DBUG_RETURN(0);
+}
+
+
+/**
+ @brief restore scan block it's original values
+
+ @note
+ In theory we could swap bitmap buffers instead of copy them.
+ For the moment we don't do that because there are variables pointing
+ inside the buffers and it's a bit of hassle to either make them relative
+ or repoint them.
+*/
+
+void _ma_scan_restore_block_record(MARIA_HA *info,
+ MARIA_RECORD_POS lastpos)
+{
+ uchar *bitmap_buff;
+ DBUG_ENTER("_ma_scan_restore_block_record");
+
+ info->cur_row.nextpos= lastpos;
+ bitmap_buff= info->scan.bitmap_buff;
+ memcpy(&info->scan, info->scan_save, sizeof(*info->scan_save));
+ info->scan.bitmap_buff= bitmap_buff;
+ memcpy(bitmap_buff, info->scan_save->bitmap_buff, info->s->block_size * 2);
+
DBUG_VOID_RETURN;
}
@@ -4207,7 +4283,10 @@ restart_record_read:
record_pos++;
#ifdef SANITY_CHECKS
if (info->scan.dir < info->scan.dir_end)
+ {
+ DBUG_ASSERT(0);
goto err;
+ }
#endif
}
/* found row */
@@ -4220,7 +4299,10 @@ restart_record_read:
#ifdef SANITY_CHECKS
if (end_of_data > info->scan.dir_end ||
offset < PAGE_HEADER_SIZE || length < share->base.min_block_length)
+ {
+ DBUG_ASSERT(0);
goto err;
+ }
#endif
DBUG_PRINT("info", ("rowid: %lu", (ulong) info->cur_row.lastpos));
DBUG_RETURN(_ma_read_block_record2(info, record, data, end_of_data));
@@ -4259,8 +4341,20 @@ restart_bitmap_scan:
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
DBUG_RETURN(my_errno);
if (((info->scan.page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) !=
- HEAD_PAGE) ||
- (info->scan.number_of_rows=
+ HEAD_PAGE))
+ {
+ /*
+ This may happen if someone has been deleting all rows
+ from a page since we read the bitmap, so it may be ok.
+ Print warning in debug log and continue.
+ */
+ DBUG_PRINT("warning",
+ ("Found page of type %d when expecting head page",
+ (info->scan.page_buff[PAGE_TYPE_OFFSET] &
+ PAGE_TYPE_MASK)));
+ continue;
+ }
+ if ((info->scan.number_of_rows=
(uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET]) == 0)
{
DBUG_PRINT("error", ("Wrong page header"));
@@ -5641,7 +5735,7 @@ my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
delete_tails(info, info->cur_row.tail_positions))
goto err;
- if (info->cur_row.extents && free_full_pages(info, &info->cur_row))
+ if (info->cur_row.extents_count && free_full_pages(info, &info->cur_row))
goto err;
checksum= 0;
@@ -5836,6 +5930,7 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn,
/* Row is now up to date. Time to insert the record */
res= allocate_and_write_block_record(info, record, &row, undo_lsn);
+ info->cur_row.lastpos= row.lastpos;
my_free(record, MYF(0));
DBUG_RETURN(res);
}
@@ -5871,6 +5966,7 @@ my_bool _ma_apply_undo_row_update(MARIA_HA *info, LSN undo_lsn,
rownr= dirpos_korr(header);
header+= DIRPOS_STORE_SIZE;
record_pos= ma_recordpos(page, rownr);
+ info->cur_row.lastpos= record_pos; /* For key insert */
DBUG_PRINT("enter", ("Page: %lu rownr: %u", (ulong) page, rownr));
if (share->calc_checksum)
diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h
index 89cdf088ac1..781d5f255a7 100644
--- a/storage/maria/ma_blockrec.h
+++ b/storage/maria/ma_blockrec.h
@@ -159,6 +159,10 @@ my_bool _ma_cmp_block_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
const uchar *record, MARIA_RECORD_POS pos);
my_bool _ma_scan_init_block_record(MARIA_HA *info);
void _ma_scan_end_block_record(MARIA_HA *info);
+int _ma_scan_remember_block_record(MARIA_HA *info,
+ MARIA_RECORD_POS *lastpos);
+void _ma_scan_restore_block_record(MARIA_HA *info,
+ MARIA_RECORD_POS lastpos);
MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info,
const uchar *record);
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index 87021820be5..b354b0fb79c 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -100,7 +100,7 @@ int maria_close(register MARIA_HA *info)
File must be synced as it is going out of the maria_open_list and so
becoming unknown to future Checkpoints.
*/
- if (my_sync(share->kfile.file, MYF(MY_WME)))
+ if (!share->temporary && my_sync(share->kfile.file, MYF(MY_WME)))
error= my_errno;
if (my_close(share->kfile.file, MYF(0)))
error= my_errno;
diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c
index 4510cc11b20..36efb52acec 100644
--- a/storage/maria/ma_control_file.c
+++ b/storage/maria/ma_control_file.c
@@ -214,6 +214,7 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
const char *errmsg;
MY_STAT stat_buff;
uint new_cf_create_time_size, new_cf_changeable_size, new_block_size;
+ uint retry;
int open_flags= O_BINARY | /*O_DIRECT |*/ O_RDWR;
int error= CONTROL_FILE_UNKNOWN_ERROR;
DBUG_ENTER("ma_control_file_create_or_open");
@@ -347,6 +348,29 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
CF_LSN_OFFSET);
last_logno= uint4korr(buffer + new_cf_create_time_size + CF_FILENO_OFFSET);
+ retry= 0;
+
+ /*
+ We can't here use the automatic wait in my_lock() as the alarm thread
+ may not yet exists.
+ */
+
+ while (my_lock(control_file_fd, F_WRLCK, 0L, F_TO_EOF,
+ MYF(MY_SEEK_NOT_DONE | MY_FORCE_LOCK | MY_NO_WAIT)))
+ {
+ if (retry == 0)
+ my_printf_error(HA_ERR_INITIALIZATION,
+ "Can't lock maria control file '%s' for exclusive use, "
+ "error: %d. Will retry for %d seconds", 0,
+ name, my_errno, MARIA_MAX_CONTROL_FILE_LOCK_RETRY);
+ if (retry++ > MARIA_MAX_CONTROL_FILE_LOCK_RETRY)
+ {
+ errmsg= "Could not get an exclusive lock; File is probably in use by another process";
+ goto err;
+ }
+ sleep(1);
+ }
+
DBUG_RETURN(0);
err:
@@ -463,6 +487,9 @@ int ma_control_file_end()
if (control_file_fd < 0) /* already closed */
DBUG_RETURN(0);
+ (void) my_lock(control_file_fd, F_UNLCK, 0L, F_TO_EOF,
+ MYF(MY_SEEK_NOT_DONE | MY_FORCE_LOCK));
+
close_error= my_close(control_file_fd, MYF(MY_WME));
/*
As my_close() frees structures even if close() fails, we do the same,
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 2922a91baef..913dc15999d 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -147,8 +147,17 @@ int maria_create(const char *name, enum data_file_type datafile_type,
reclength+= column->length;
type= column->type;
- if (type == FIELD_SKIP_PRESPACE && datafile_type == BLOCK_RECORD)
- type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
+ if (datafile_type == BLOCK_RECORD)
+ {
+ if (type == FIELD_SKIP_PRESPACE)
+ type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
+ if (type == FIELD_NORMAL &&
+ column->length > FULL_PAGE_SIZE(maria_block_size))
+ {
+ /* FIELD_NORMAL can't be split over many blocks, convert to a CHAR */
+ type= column->type= FIELD_SKIP_ENDSPACE;
+ }
+ }
if (type != FIELD_NORMAL && type != FIELD_CHECK)
{
@@ -623,7 +632,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
}
unique_key_parts=0;
- offset=reclength-uniques*MARIA_UNIQUE_HASH_LENGTH;
for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
{
uniquedef->key=keys+i;
@@ -868,7 +876,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
#endif
}
/* Create extra keys for unique definitions */
- offset=reclength-uniques*MARIA_UNIQUE_HASH_LENGTH;
+ offset= real_reclength - uniques*MARIA_UNIQUE_HASH_LENGTH;
bzero((char*) &tmp_keydef,sizeof(tmp_keydef));
bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg));
for (i=0; i < uniques ; i++)
@@ -1194,7 +1202,7 @@ uint maria_get_pointer_length(ulonglong file_length, uint def)
For same kind of fields, keep fields in original order
*/
-static inline int sign(longlong a)
+static inline int sign(long a)
{
return a < 0 ? -1 : (a > 0 ? 1 : 0);
}
@@ -1214,12 +1222,12 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
{
if (b_type != FIELD_NORMAL || b->null_bit)
return -1;
- return sign((long) (a->offset - b->offset));
+ return sign((long) a->offset - (long) b->offset);
}
if (b_type == FIELD_NORMAL && !b->null_bit)
return 1;
if (a_type == b_type)
- return sign((long) (a->offset - b->offset));
+ return sign((long) a->offset - (long) b->offset);
if (a_type == FIELD_NORMAL)
return -1;
if (b_type == FIELD_NORMAL)
@@ -1228,7 +1236,7 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
return 1;
if (b_type == FIELD_BLOB)
return -1;
- return sign((long) (a->offset - b->offset));
+ return sign((long) a->offset - (long) b->offset);
}
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index 1388d81df67..67d3d8d7092 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -192,7 +192,11 @@ int _ma_ck_delete(register MARIA_HA *info, uint keynr, uchar *key,
log_type= LOGREC_UNDO_KEY_DELETE_WITH_ROOT;
}
- key_length+= share->rec_reflength;
+ /*
+ Note that for delete key, we don't log the reference to the record.
+ This is because the row may be inserted at a different place when
+ we exceute the undo
+ */
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= (char*) key_buff;
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index 9f42f2beaa2..cb33160bdf6 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -1501,7 +1501,10 @@ my_bool _ma_cmp_dynamic_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
old_rec_buff_size= info->rec_buff_size;
if (info->s->base.blobs)
+ {
info->rec_buff= 0;
+ info->rec_buff_size= 0;
+ }
error= _ma_read_dynamic_record(info, old_record, pos) != 0;
if (!error)
error=_ma_unique_comp(def, record, old_record, def->null_are_equal) != 0;
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index 62e091a8928..26e129245d6 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -224,7 +224,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
info->lock_wait= 0;
break;
case HA_EXTRA_NO_WAIT_LOCK:
- info->lock_wait= MY_DONT_WAIT;
+ info->lock_wait= MY_SHORT_WAIT;
break;
case HA_EXTRA_NO_KEYS:
/* we're going to modify pieces of the state, stall Checkpoint */
@@ -273,11 +273,12 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
break;
case HA_EXTRA_FORCE_REOPEN:
/*
- Normally MySQL uses this case when it is going to close all open
- instances of the table, thus going to flush all data/index/state.
+ MySQL uses this case after it has closed all other instances
+ of this table.
We however do a flush here for additional safety.
*/
/** @todo consider porting these flush-es to MyISAM */
+ DBUG_ASSERT(share->reopen == 1);
error= _ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_FORCE_WRITE, FLUSH_FORCE_WRITE);
if (!error && share->changed)
@@ -287,19 +288,6 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
share->changed= 0;
pthread_mutex_unlock(&share->intern_lock);
}
-
- /**
- @todo RECOVERY BUG
- Though we flushed the state, IF some other thread may have the same
- table (same MARIA_SHARE) open at this time then it may have a
- more recent state to flush when it closes, thus we don't set
- share->changed to 0 here. On the other hand, this means that when our
- thread closes its table, it will flush the state again, then it would
- overwrite any state written by yet another thread which may have opened
- the table (new MARIA_SHARE) and done some updates.
- ASK_MONTY about the IF above. See also same tag in
- HA_EXTRA_PREPARE_FOR_DROP|RENAME.
- */
pthread_mutex_lock(&THR_LOCK_maria);
pthread_mutex_lock(&share->intern_lock); /* protect against Checkpoint */
/* this makes the share not be re-used next time the table is opened */
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index f929929083b..a4eb1e8cc5e 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -109,6 +109,20 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
page_store(log_pos + KEY_NR_STORE_SIZE, page);
log_pos+= KEY_NR_STORE_SIZE + PAGE_STORE_SIZE;
}
+ if (undo_type == LOGREC_UNDO_ROW_DELETE ||
+ undo_type == LOGREC_UNDO_ROW_UPDATE)
+ {
+ /*
+ We need to store position to the row that was inserted to be
+ able to regenerate keys
+ */
+ MARIA_RECORD_POS rowid= info->cur_row.lastpos;
+ ulonglong page= ma_recordpos_to_page(rowid);
+ uint dir_entry= ma_recordpos_to_dir_entry(rowid);
+ page_store(log_pos, page);
+ dirpos_store(log_pos+ PAGE_STORE_SIZE, dir_entry);
+ log_pos+= PAGE_STORE_SIZE + DIRPOS_STORE_SIZE;
+ }
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);
@@ -937,7 +951,7 @@ my_bool _ma_apply_undo_key_insert(MARIA_HA *info, LSN undo_lsn,
/**
- @brief Undo of insert of key (ie, delete the inserted key)
+ @brief Undo of delete of key (ie, insert the deleted key)
*/
my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn,
@@ -959,11 +973,12 @@ my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn,
/* We have to copy key as _ma_ck_real_write_btree() may change it */
memcpy(key, header + KEY_NR_STORE_SIZE, length);
- DBUG_DUMP("key", key, length);
+ _ma_dpointer(info, key + length, info->cur_row.lastpos);
+ DBUG_DUMP("key", key, length + share->rec_reflength);
new_root= share->state.key_root[keynr];
res= _ma_ck_real_write_btree(info, share->keyinfo+keynr, key,
- length - info->s->rec_reflength,
+ length,
&new_root,
share->keyinfo[keynr].write_comp_flag);
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 980d287468e..ffc9a613e78 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -871,6 +871,9 @@ void _ma_setup_functions(register MARIA_SHARE *share)
share->end= maria_scan_end_dummy;
share->scan_init= maria_scan_init_dummy;/* Compat. dummy function */
share->scan_end= maria_scan_end_dummy;/* Compat. dummy function */
+ share->scan_remember_pos= _ma_def_scan_remember_pos;
+ share->scan_restore_pos= _ma_def_scan_restore_pos;
+
share->write_record_init= _ma_write_init_default;
share->write_record_abort= _ma_write_abort_default;
share->keypos_to_recpos= _ma_transparent_recpos;
@@ -936,8 +939,10 @@ void _ma_setup_functions(register MARIA_SHARE *share)
share->write_record_abort= _ma_write_abort_block_record;
share->scan_init= _ma_scan_init_block_record;
share->scan_end= _ma_scan_end_block_record;
- share->read_record= _ma_read_block_record;
share->scan= _ma_scan_block_record;
+ share->scan_remember_pos= _ma_scan_remember_block_record;
+ share->scan_restore_pos= _ma_scan_restore_block_record;
+ share->read_record= _ma_read_block_record;
share->delete_record= _ma_delete_block_record;
share->compare_record= _ma_compare_block_record;
share->update_record= _ma_update_block_record;
@@ -994,7 +999,8 @@ static void setup_key_functions(register MARIA_KEYDEF *keyinfo)
if (keyinfo->seg[0].flag & HA_PACK_KEY)
{ /* Prefix compression */
if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
- (keyinfo->seg->flag & HA_NULL_PART))
+ (keyinfo->seg->flag & HA_NULL_PART) ||
+ keyinfo->seg->charset->mbminlen > 1)
keyinfo->bin_search= _ma_seq_search;
else
keyinfo->bin_search= _ma_prefix_search;
@@ -1468,12 +1474,14 @@ my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
uchar buff[MARIA_COLUMNDEF_SIZE];
uchar *ptr=buff;
- mi_int2store(ptr,(ulong) columndef->offset); ptr+= 2;
- mi_int2store(ptr,columndef->type); ptr+= 2;
- mi_int2store(ptr,columndef->length); ptr+= 2;
- mi_int2store(ptr,columndef->fill_length); ptr+= 2;
- mi_int2store(ptr,columndef->null_pos); ptr+= 2;
- mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
+ mi_int2store(ptr,(ulong) columndef->column_nr); ptr+= 2;
+ mi_int2store(ptr,(ulong) columndef->offset); ptr+= 2;
+ mi_int2store(ptr,columndef->type); ptr+= 2;
+ mi_int2store(ptr,columndef->length); ptr+= 2;
+ mi_int2store(ptr,columndef->fill_length); ptr+= 2;
+ mi_int2store(ptr,columndef->null_pos); ptr+= 2;
+ mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
+
(*ptr++)= columndef->null_bit;
(*ptr++)= columndef->empty_bit;
ptr[0]= ptr[1]= ptr[2]= ptr[3]= 0; ptr+= 4; /* For future */
@@ -1482,6 +1490,7 @@ my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
uchar *_ma_columndef_read(uchar *ptr, MARIA_COLUMNDEF *columndef)
{
+ columndef->column_nr= mi_uint2korr(ptr); ptr+= 2;
columndef->offset= mi_uint2korr(ptr); ptr+= 2;
columndef->type= mi_sint2korr(ptr); ptr+= 2;
columndef->length= mi_uint2korr(ptr); ptr+= 2;
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index f1b34e444c0..5873db8db61 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -1761,6 +1761,24 @@ prototype_redo_exec_hook(COMMIT)
}
+/*
+ Set position for next active record that will have key inserted
+*/
+
+static void set_lastpos(MARIA_HA *info, uchar *pos)
+{
+ ulonglong page;
+ uint dir_entry;
+
+ /* If we have checksum, it's before rowid */
+ if (info->s->calc_checksum)
+ pos+= HA_CHECKSUM_STORE_SIZE;
+ page= page_korr(pos);
+ dir_entry= dirpos_korr(pos + PAGE_STORE_SIZE);
+ info->cur_row.lastpos= ma_recordpos(page, dir_entry);
+}
+
+
prototype_redo_exec_hook(CLR_END)
{
MARIA_HA *info= get_MARIA_HA_from_UNDO_record(rec);
@@ -1769,6 +1787,7 @@ prototype_redo_exec_hook(CLR_END)
enum translog_record_type undone_record_type;
const LOG_DESC *log_desc;
my_bool row_entry= 0;
+ uchar *logpos;
DBUG_ENTER("exec_REDO_LOGREC_CLR_END");
if (info == NULL)
@@ -1782,6 +1801,19 @@ prototype_redo_exec_hook(CLR_END)
set_undo_lsn_for_active_trans(rec->short_trid, previous_undo_lsn);
tprint(tracef, " CLR_END was about %s, undo_lsn now LSN (%lu,0x%lx)\n",
log_desc->name, LSN_IN_PARTS(previous_undo_lsn));
+
+ enlarge_buffer(rec);
+ if (log_record_buffer.str == NULL ||
+ translog_read_record(rec->lsn, 0, rec->record_length,
+ log_record_buffer.str, NULL) !=
+ rec->record_length)
+ {
+ eprint(tracef, "Failed to read record\n");
+ return 1;
+ }
+ logpos= (log_record_buffer.str + LSN_STORE_SIZE + FILEID_STORE_SIZE +
+ CLR_TYPE_STORE_SIZE);
+
if (cmp_translog_addr(rec->lsn, share->state.is_of_horizon) >= 0)
{
tprint(tracef, " state older than record\n");
@@ -1789,6 +1821,7 @@ prototype_redo_exec_hook(CLR_END)
case LOGREC_UNDO_ROW_DELETE:
row_entry= 1;
share->state.state.records++;
+ set_lastpos(info, logpos);
break;
case LOGREC_UNDO_ROW_INSERT:
share->state.state.records--;
@@ -1796,6 +1829,7 @@ prototype_redo_exec_hook(CLR_END)
break;
case LOGREC_UNDO_ROW_UPDATE:
row_entry= 1;
+ set_lastpos(info, logpos);
break;
case LOGREC_UNDO_KEY_INSERT:
case LOGREC_UNDO_KEY_DELETE:
@@ -1805,18 +1839,8 @@ prototype_redo_exec_hook(CLR_END)
{
uint key_nr;
my_off_t page;
- uchar buff[KEY_NR_STORE_SIZE + PAGE_STORE_SIZE];
- if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
- CLR_TYPE_STORE_SIZE,
- KEY_NR_STORE_SIZE + PAGE_STORE_SIZE,
- buff, NULL) !=
- KEY_NR_STORE_SIZE + PAGE_STORE_SIZE)
- {
- eprint(tracef, "Failed to read record\n");
- DBUG_RETURN(1);
- }
- key_nr= key_nr_korr(buff);
- page= page_korr(buff + KEY_NR_STORE_SIZE);
+ key_nr= key_nr_korr(logpos);
+ page= page_korr(logpos + KEY_NR_STORE_SIZE);
share->state.key_root[key_nr]= (page == IMPOSSIBLE_PAGE_NO ?
HA_OFFSET_ERROR :
page * share->block_size);
@@ -1826,19 +1850,21 @@ prototype_redo_exec_hook(CLR_END)
DBUG_ASSERT(0);
}
if (row_entry && share->calc_checksum)
- {
- uchar buff[HA_CHECKSUM_STORE_SIZE];
- if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
- CLR_TYPE_STORE_SIZE, HA_CHECKSUM_STORE_SIZE,
- buff, NULL) != HA_CHECKSUM_STORE_SIZE)
- {
- eprint(tracef, "Failed to read record\n");
- DBUG_RETURN(1);
- }
- share->state.state.checksum+= ha_checksum_korr(buff);
- }
+ share->state.state.checksum+= ha_checksum_korr(logpos);
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
}
+ else
+ {
+ /* We must set lastpos for upcoming undo delete keys */
+ switch (undone_record_type) {
+ case LOGREC_UNDO_ROW_DELETE:
+ case LOGREC_UNDO_ROW_UPDATE:
+ set_lastpos(info, logpos);
+ break;
+ default:
+ break;
+ }
+ }
if (row_entry)
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
_ma_unpin_all_pages(info, rec->lsn);
diff --git a/storage/maria/ma_scan.c b/storage/maria/ma_scan.c
index f9657833fdd..48e9e3400ce 100644
--- a/storage/maria/ma_scan.c
+++ b/storage/maria/ma_scan.c
@@ -58,3 +58,16 @@ void maria_scan_end(MARIA_HA *info)
{
(*info->s->scan_end)(info);
}
+
+
+int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos)
+{
+ *lastpos= info->cur_row.lastpos;
+ return 0;
+}
+
+
+void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos)
+{
+ info->cur_row.nextpos= lastpos;
+}
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 6748fc23318..525cf94d660 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -40,6 +40,7 @@
#define MAX_NONMAPPED_INSERTS 1000
#define MARIA_MAX_TREE_LEVELS 32
+#define MARIA_MAX_CONTROL_FILE_LOCK_RETRY 30 /* Retry this many times */
struct st_transaction;
@@ -124,7 +125,7 @@ typedef struct st_maria_state_info
#define MARIA_KEYDEF_SIZE (2+ 5*2)
#define MARIA_UNIQUEDEF_SIZE (2+1+1)
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
-#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
+#define MARIA_COLUMNDEF_SIZE (2*7+1+1+4)
#define MARIA_BASE_INFO_SIZE (MY_UUID_SIZE + 5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16)
#define MARIA_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */
/* Internal management bytes needed to store 2 keys on an index page */
@@ -271,6 +272,8 @@ typedef struct st_maria_share
int (*scan)(MARIA_HA *, uchar *, MARIA_RECORD_POS, my_bool);
/* End scan */
void (*scan_end)(MARIA_HA *);
+ int (*scan_remember_pos)(MARIA_HA *, MARIA_RECORD_POS*);
+ void (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS);
/* Pre-write of row (some handlers may do the actual write here) */
MARIA_RECORD_POS (*write_record_init)(MARIA_HA *, const uchar *);
/* Write record (or accept write_record_init) */
@@ -424,7 +427,7 @@ struct st_maria_handler
MARIA_STATUS_INFO *state, save_state;
MARIA_ROW cur_row; /* The active row that we just read */
MARIA_ROW new_row; /* Storage for a row during update */
- MARIA_BLOCK_SCAN scan;
+ MARIA_BLOCK_SCAN scan, *scan_save;
MARIA_BLOB *blobs; /* Pointer to blobs */
MARIA_BIT_BUFF bit_buff;
DYNAMIC_ARRAY bitmap_blocks;
@@ -477,7 +480,7 @@ struct st_maria_handler
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
uint save_lastkey_length;
uint pack_key_length; /* For MARIAMRG */
- myf lock_wait; /* is 0 or MY_DONT_WAIT */
+ myf lock_wait; /* is 0 or MY_SHORT_WAIT */
int errkey; /* Got last error on this key */
int lock_type; /* How database was locked */
int tmp_lock_type; /* When locked by readinfo */
@@ -984,6 +987,9 @@ void _ma_restore_status(void *param);
void _ma_copy_status(void *to, void *from);
my_bool _ma_check_status(void *param);
void _ma_reset_status(MARIA_HA *maria);
+int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos);
+void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos);
+
#include "ma_commit.h"
extern MARIA_HA *_ma_test_if_reopen(const char *filename);
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 5e58565364c..4aea0ebee98 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -255,28 +255,28 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
{
/* reserve space for null bits */
bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
- recinfo_pos->type= (int) FIELD_NORMAL;
+ recinfo_pos->type= FIELD_NORMAL;
recinfo_pos++->length= (uint16) (minpos - recpos);
}
if (!found)
break;
if (found->flags & BLOB_FLAG)
- recinfo_pos->type= (int) FIELD_BLOB;
+ recinfo_pos->type= FIELD_BLOB;
else if (found->type() == MYSQL_TYPE_VARCHAR)
recinfo_pos->type= FIELD_VARCHAR;
else if (!(options & HA_OPTION_PACK_RECORD))
- recinfo_pos->type= (int) FIELD_NORMAL;
+ recinfo_pos->type= FIELD_NORMAL;
else if (found->zero_pack())
- recinfo_pos->type= (int) FIELD_SKIP_ZERO;
+ recinfo_pos->type= FIELD_SKIP_ZERO;
else
- recinfo_pos->type= (int) ((length <= 3 ||
- (found->flags & ZEROFILL_FLAG)) ?
- FIELD_NORMAL :
- found->type() == MYSQL_TYPE_STRING ||
- found->type() == MYSQL_TYPE_VAR_STRING ?
- FIELD_SKIP_ENDSPACE :
- FIELD_SKIP_PRESPACE);
+ recinfo_pos->type= ((length <= 3 ||
+ (found->flags & ZEROFILL_FLAG)) ?
+ FIELD_NORMAL :
+ found->type() == MYSQL_TYPE_STRING ||
+ found->type() == MYSQL_TYPE_VAR_STRING ?
+ FIELD_SKIP_ENDSPACE :
+ FIELD_SKIP_PRESPACE);
if (found->null_ptr)
{
recinfo_pos->null_bit= found->null_bit;
@@ -1675,9 +1675,15 @@ int ha_myisam::rnd_next(uchar *buf)
return error;
}
-int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos)
+int ha_myisam::remember_rnd_pos()
{
- return rnd_pos(buf,pos);
+ position((uchar*) 0);
+ return 0;
+}
+
+int ha_myisam::restart_rnd_next(uchar *buf)
+{
+ return rnd_pos(buf, ref);
}
int ha_myisam::rnd_pos(uchar *buf, uchar *pos)
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index 96440b74c9d..74780abf42b 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -94,7 +94,8 @@ class ha_myisam: public handler
int rnd_init(bool scan);
int rnd_next(uchar *buf);
int rnd_pos(uchar * buf, uchar *pos);
- int restart_rnd_next(uchar *buf, uchar *pos);
+ int remember_rnd_pos();
+ int restart_rnd_next(uchar *buf);
void position(const uchar *record);
int info(uint);
int extra(enum ha_extra_function operation);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 152ffd3bb55..c07ed3424d2 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -2028,7 +2028,7 @@ int lock_file(HA_CHECK *param, File file, my_off_t start, int lock_type,
{
if (my_lock(file,lock_type,start,F_TO_EOF,
param->testflag & T_WAIT_FOREVER ? MYF(MY_SEEK_NOT_DONE) :
- MYF(MY_SEEK_NOT_DONE | MY_DONT_WAIT)))
+ MYF(MY_SEEK_NOT_DONE | MY_SHORT_WAIT)))
{
mi_check_print_error(param," %d when locking %s '%s'",my_errno,filetype,filename);
param->error_printed=2; /* Don't give that data is crashed */
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index 33c9d1210ca..d798ef50d7e 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -216,7 +216,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
info->lock_wait=0;
break;
case HA_EXTRA_NO_WAIT_LOCK:
- info->lock_wait=MY_DONT_WAIT;
+ info->lock_wait= MY_SHORT_WAIT;
break;
case HA_EXTRA_NO_KEYS:
if (info->lock_type == F_UNLCK)
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 5ce8ec0275a..3e877513098 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -180,7 +180,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
- 0 : MY_DONT_WAIT))) &&
+ 0 : MY_SHORT_WAIT))) &&
!(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
goto err;
}
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 59d54bdc542..64c1a8214c3 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -284,7 +284,7 @@ struct st_myisam_info
LIST open_list;
IO_CACHE rec_cache; /* When cacheing records */
uint preload_buff_size; /* When preloading indexes */
- myf lock_wait; /* is 0 or MY_DONT_WAIT */
+ myf lock_wait; /* is 0 or MY_SHORT_WAIT */
my_bool was_locked; /* Was locked in panic */
my_bool append_insert_at_end; /* Set if concurrent insert */
my_bool quick_mode;