Fixed bug in undo_key_delete; Caused crashed key files in recovery

Maria is now used for internal temporary tables in MySQL
Better usage of VARCHAR and long strings in temporary tables
Use packed fields if BLOCK_RECORD is used
null_bytes are not anymore stored in a separate field
New interface to remember and restore scan position
Fixed bugs in unique handling
Don't sync Maria temporary tables
Lock control file while it's used to stop several processes from using it
Changed value of MA_DONT_OVERWRITE_FILE as it collided with MY_SYNC_DIR
Split MY_DONT_WAIT into MY_NO_WAIT and MY_SHORT_WAIT (for my_lock())
Added MY_FORCE_LOCK


include/my_sys.h:
  Changed value of MA_DONT_OVERWRITE_FILE as it collided with MY_SYNC_DIR
  Split MY_DONT_WAIT into MY_NO_WAIT and MY_SHORT_WAIT (for my_lock())
  Added MY_FORCE_LOCK
include/myisam.h:
  Make MyISAM columndef compile time compatible with Maria
mysql-test/lib/mtr_process.pl:
  Removed confusing warning (It's common that there is a lot of other files than pid files)
mysql-test/mysql-test-run.pl:
  Added --sync-frm to speed up tests
mysql-test/r/maria-recovery.result:
  Updated results from wrong push
mysql-test/suite/rpl/t/rpl_innodb_bug28430.test:
  Marked test as --big
mysys/my_lock.c:
  If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
  If MY_NO_WAIT is given, return at once if lock is occupied
  If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
mysys/my_thr_init.c:
  Fix that we don't give name to thread before it's properly initied
sql/handler.cc:
  Added myisam.h
sql/handler.h:
  Changes to use Maria for internal temporary tables
  Removed not needed argument to restart_rnd_next()
  Added function remember_rnd_pos()
sql/my_lock.c:
  If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
  If MY_NO_WAIT is given, return at once if lock is occupied
  If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
sql/mysql_priv.h:
  Added maria_hton
sql/sql_class.h:
  Changes to use Maria for internal temporary tables
sql/sql_select.cc:
  Changes to use Maria for internal temporary tables
  Temporary tables didn't properly switch to dynamic row format if long strings was used
  Better usage of VARCHAR in temporary tables
  Use new interface to restart scan in duplicate removal
sql/sql_select.h:
  Changes to use Maria for internal temporary tables
sql/sql_show.cc:
  Changes to use Maria for internal temporary tables
  Removed all end space
sql/sql_table.cc:
  Set HA_OPTION_PACK_RECORD if we are not using default or static record
sql/sql_union.cc:
  If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
  If MY_NO_WAIT is given, return at once if lock is occupied
  If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
sql/sql_update.cc:
  If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
  If MY_NO_WAIT is given, return at once if lock is occupied
  If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
storage/maria/ha_maria.cc:
  Use packed fields
  null_bytes are not anymore stored in a separate field
  Changes to use Maria for internal temporary tables
  Give warning if we try to do an ALTER TABLE to a unusable row format
storage/maria/ha_maria.h:
  Allow Maria with block format to restart scanning at given position
storage/maria/ma_blockrec.c:
  Added functions to remember and restore scan position
  Allocate cur_row.extents so that we don't have to do a malloc on first read
  Fixed bug when using packed row without packed strings
  Removed unneeded calls to free_full_pages()
  Fixed unlikely bug when using old bitmap to read head page and head page had gone away
  Remember row position when doing undo of delete and update row (needed for undo of key delete)
storage/maria/ma_blockrec.h:
  Added functions to remember and restore scan position
storage/maria/ma_close.c:
  Don't sync temporary tables
storage/maria/ma_control_file.c:
  Lock control file while it's used to stop several processes from using it
storage/maria/ma_create.c:
  Fixed bug when using FIELD_NORMAL that was longer than FULL_PAGE_SIZE
  Fixed bug that casued fields to not be ordered according to offset
  Fixed bug in unique creation
storage/maria/ma_delete.c:
  Don't write record reference when deleting key.
  (Rowid is likely to be different when we undo this)
storage/maria/ma_dynrec.c:
  Fixed core dump when comparing records (happended in unique handling)
storage/maria/ma_extra.c:
  MY_DONT_WAIT -> MY_SHORT_WAIT
  Removed TODO comment. (Was not relevant as all other instances are guranteed to be closed when we the code is excecuted)
  Added DBUG_ASSERT() to prove above.
storage/maria/ma_key_recover.c:
  CLR's for UNDO_ROW_DELETE and UNDO_ROW_UPDATE now include rowid for the row.
  This was needed for undo_key_delete to work, as undo of delete row is likely to put row in a new position.
  undo_delete_key now doesn't include row position
storage/maria/ma_open.c:
  Added virtual functions for remembering and restoring scan position
  Fixed wrong key search method when using multi-byte character sets (Bug#32705)
  Store original column number in index file
  
  NOTE: Index files are now incompatible with previous versions!
  (Ok as we haven't yet made a public Maria release)
storage/maria/ma_recovery.c:
  Set info->cur_row.lastpos when reading CLR's for UNDO_ROW_DELETE or UNDO_ROW_UPDATE
storage/maria/ma_scan.c:
  Added default function to remember and restore scan position
storage/maria/maria_def.h:
  Added virtual functions & variables to remember and restore scan position
  Added MARIA_MAX_CONTROL_FILE_LOCK_RETRY
storage/myisam/ha_myisam.cc:
  Fixed compiler errors as columdef->type is now an enum, not an integer
  Added functions to remember and restore scan position
storage/myisam/ha_myisam.h:
  Added functions to remember and restore scan position
storage/myisam/mi_check.c:
  MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/mi_extra.c:
  MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/mi_open.c:
  MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/myisamdef.h:
  MY_DONT_WAIT -> MY_SHORT_WAIT
This commit is contained in:
unknown 2007-12-17 01:17:37 +02:00
parent 6b89901cdf
commit cc589bef15
40 changed files with 767 additions and 339 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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 )
{

View File

@ -1,3 +1,4 @@
set global maria_log_file_size=4294967296;
drop database if exists mysqltest;
create database mysqltest;
use mysqltest;

View File

@ -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

View File

@ -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 &&

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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))
if (!(MyFlags & MY_NO_WAIT))
{
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;
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 */

View File

@ -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;

View File

@ -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;

View File

@ -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);
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;
}
/*
* If a HEAP table gets full, create a MyISAM table and copy all rows to this
If a HEAP table gets full, create a MyISAM table 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)
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");
}
#endif /* WITH_MARIA_STORAGE_ENGINE */
/*
If a HEAP table gets full, create a internal table in MyISAM or Maria
and copy all rows to this
*/
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;
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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 */

View File

@ -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)

View File

@ -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;
}

View File

@ -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;