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:
parent
6b89901cdf
commit
cc589bef15
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -1,3 +1,4 @@
|
||||
set global maria_log_file_size=4294967296;
|
||||
drop database if exists mysqltest;
|
||||
create database mysqltest;
|
||||
use mysqltest;
|
||||
|
@ -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
|
||||
|
@ -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 &&
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
250
sql/sql_show.cc
250
sql/sql_show.cc
@ -165,15 +165,15 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin,
|
||||
|
||||
switch (plug->license) {
|
||||
case PLUGIN_LICENSE_GPL:
|
||||
table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
|
||||
table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
|
||||
strlen(PLUGIN_LICENSE_GPL_STRING), cs);
|
||||
break;
|
||||
case PLUGIN_LICENSE_BSD:
|
||||
table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
|
||||
table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
|
||||
strlen(PLUGIN_LICENSE_BSD_STRING), cs);
|
||||
break;
|
||||
default:
|
||||
table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
|
||||
table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
|
||||
strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
|
||||
break;
|
||||
}
|
||||
@ -481,7 +481,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
|
||||
file=dirp->dir_entry+i;
|
||||
if (dir)
|
||||
{ /* Return databases */
|
||||
if ((file->name[0] == '.' &&
|
||||
if ((file->name[0] == '.' &&
|
||||
((file->name[1] == '.' && file->name[2] == '\0') ||
|
||||
file->name[1] == '\0')))
|
||||
continue; /* . or .. */
|
||||
@ -507,7 +507,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
|
||||
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
|
||||
if (wild && wild_compare(uname, wild, 0))
|
||||
continue;
|
||||
if (!(file_name=
|
||||
if (!(file_name=
|
||||
thd->make_lex_string(file_name, uname, file_name_len, TRUE)))
|
||||
{
|
||||
my_dirend(dirp);
|
||||
@ -546,7 +546,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!(file_name=
|
||||
if (!(file_name=
|
||||
thd->make_lex_string(file_name, uname, file_name_len, TRUE)) ||
|
||||
files->push_back(file_name))
|
||||
{
|
||||
@ -584,7 +584,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
|
||||
|
||||
/*
|
||||
Clear all messages with 'error' level status and
|
||||
issue a warning with 'warning' level status in
|
||||
issue a warning with 'warning' level status in
|
||||
case of invalid view and last error is ER_VIEW_INVALID
|
||||
*/
|
||||
mysql_reset_errors(thd, true);
|
||||
@ -774,7 +774,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
|
||||
Field **ptr,*field;
|
||||
for (ptr=table->field ; (field= *ptr); ptr++)
|
||||
{
|
||||
if (!wild || !wild[0] ||
|
||||
if (!wild || !wild[0] ||
|
||||
!wild_case_compare(system_charset_info, field->field_name,wild))
|
||||
{
|
||||
if (table_list->view)
|
||||
@ -985,13 +985,13 @@ static bool get_field_default_value(THD *thd, TABLE *table,
|
||||
bool has_default;
|
||||
bool has_now_default;
|
||||
|
||||
/*
|
||||
/*
|
||||
We are using CURRENT_TIMESTAMP instead of NOW because it is
|
||||
more standard
|
||||
*/
|
||||
has_now_default= table->timestamp_field == field &&
|
||||
has_now_default= table->timestamp_field == field &&
|
||||
field->unireg_check != Field::TIMESTAMP_UN_FIELD;
|
||||
|
||||
|
||||
has_default= (field->type() != FIELD_TYPE_BLOB &&
|
||||
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
|
||||
field->unireg_check != Field::NEXT_NUMBER &&
|
||||
@ -1046,11 +1046,11 @@ static bool get_field_default_value(THD *thd, TABLE *table,
|
||||
to tailor the format of the statement. Can be
|
||||
NULL, in which case only SQL_MODE is considered
|
||||
when building the statement.
|
||||
|
||||
|
||||
NOTE
|
||||
Currently always return 0, but might return error code in the
|
||||
future.
|
||||
|
||||
|
||||
RETURN
|
||||
0 OK
|
||||
*/
|
||||
@ -1132,7 +1132,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
||||
field->sql_type(type);
|
||||
packet->append(type.ptr(), type.length(), system_charset_info);
|
||||
|
||||
if (field->has_charset() &&
|
||||
if (field->has_charset() &&
|
||||
!(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
|
||||
{
|
||||
if (field->charset() != share->table_charset)
|
||||
@ -1140,8 +1140,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
||||
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
|
||||
packet->append(field->charset()->csname);
|
||||
}
|
||||
/*
|
||||
For string types dump collation name only if
|
||||
/*
|
||||
For string types dump collation name only if
|
||||
collation is not primary for the given charset
|
||||
*/
|
||||
if (!(field->charset()->state & MY_CS_PRIMARY))
|
||||
@ -1168,11 +1168,11 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
||||
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
|
||||
}
|
||||
|
||||
if (!limited_mysql_mode && table->timestamp_field == field &&
|
||||
if (!limited_mysql_mode && table->timestamp_field == field &&
|
||||
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
|
||||
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
|
||||
|
||||
if (field->unireg_check == Field::NEXT_NUMBER &&
|
||||
if (field->unireg_check == Field::NEXT_NUMBER &&
|
||||
!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
|
||||
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
|
||||
|
||||
@ -1321,7 +1321,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
||||
packet->append(buff, (uint) (end - buff));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (share->table_charset &&
|
||||
!(thd->variables.sql_mode & MODE_MYSQL323) &&
|
||||
!(thd->variables.sql_mode & MODE_MYSQL40))
|
||||
@ -1492,7 +1492,7 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
|
||||
|
||||
/*
|
||||
Append DEFINER clause to the given buffer.
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
append_definer()
|
||||
thd [in] thread handle
|
||||
@ -1521,7 +1521,7 @@ static void append_algorithm(TABLE_LIST *table, String *buff)
|
||||
|
||||
/*
|
||||
Append DEFINER clause to the given buffer.
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
append_definer()
|
||||
thd [in] thread handle
|
||||
@ -1681,8 +1681,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
||||
"%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
|
||||
}
|
||||
else
|
||||
thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
|
||||
tmp_sctx->host_or_ip :
|
||||
thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
|
||||
tmp_sctx->host_or_ip :
|
||||
tmp_sctx->host ? tmp_sctx->host : "");
|
||||
if ((thd_info->db=tmp->db)) // Safe test
|
||||
thd_info->db=thd->strdup(thd_info->db);
|
||||
@ -1711,7 +1711,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
||||
thd_info->query=0;
|
||||
if (tmp->query)
|
||||
{
|
||||
/*
|
||||
/*
|
||||
query_length is always set to 0 when we set query = NULL; see
|
||||
the comment in sql_class.h why this prevents crashes in possible
|
||||
races with query_length
|
||||
@ -1958,7 +1958,7 @@ void reset_status_vars()
|
||||
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
|
||||
if (ptr->type == SHOW_LONG)
|
||||
*(ulong*) ptr->value= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2204,14 +2204,14 @@ void calc_sum_of_all_status(STATUS_VAR *to)
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
THD *tmp;
|
||||
|
||||
|
||||
/* Get global values as base */
|
||||
*to= global_status_var;
|
||||
|
||||
|
||||
/* Add to this status from existing threads */
|
||||
while ((tmp= it++))
|
||||
add_to_status(to, &tmp->status_var);
|
||||
|
||||
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -2246,7 +2246,7 @@ bool schema_table_store_record(THD *thd, TABLE *table)
|
||||
int error;
|
||||
if ((error= table->file->ha_write_row(table->record[0])))
|
||||
{
|
||||
if (create_myisam_from_heap(thd, table,
|
||||
if (create_internal_tmp_table_from_heap(thd, table,
|
||||
table->pos_in_table_list->schema_table_param,
|
||||
error, 0))
|
||||
return 1;
|
||||
@ -2268,23 +2268,23 @@ int make_table_list(THD *thd, SELECT_LEX *sel,
|
||||
|
||||
|
||||
/**
|
||||
@brief Get lookup value from the part of 'WHERE' condition
|
||||
@brief Get lookup value from the part of 'WHERE' condition
|
||||
|
||||
@details This function gets lookup value from
|
||||
the part of 'WHERE' condition if it's possible and
|
||||
@details This function gets lookup value from
|
||||
the part of 'WHERE' condition if it's possible and
|
||||
fill appropriate lookup_field_vals struct field
|
||||
with this value.
|
||||
|
||||
@param[in] thd thread handler
|
||||
@param[in] item_func part of WHERE condition
|
||||
@param[in] table I_S table
|
||||
@param[in, out] lookup_field_vals Struct which holds lookup values
|
||||
@param[in, out] lookup_field_vals Struct which holds lookup values
|
||||
|
||||
@return void
|
||||
*/
|
||||
|
||||
void get_lookup_value(THD *thd, Item_func *item_func,
|
||||
TABLE_LIST *table,
|
||||
TABLE_LIST *table,
|
||||
LOOKUP_FIELD_VALUES *lookup_field_vals)
|
||||
{
|
||||
ST_SCHEMA_TABLE *schema_table= table->schema_table;
|
||||
@ -2346,16 +2346,16 @@ void get_lookup_value(THD *thd, Item_func *item_func,
|
||||
|
||||
|
||||
/**
|
||||
@brief Calculates lookup values from 'WHERE' condition
|
||||
@brief Calculates lookup values from 'WHERE' condition
|
||||
|
||||
@details This function calculates lookup value(database name, table name)
|
||||
from 'WHERE' condition if it's possible and
|
||||
from 'WHERE' condition if it's possible and
|
||||
fill lookup_field_vals struct fields with these values.
|
||||
|
||||
@param[in] thd thread handler
|
||||
@param[in] cond WHERE condition
|
||||
@param[in] table I_S table
|
||||
@param[in, out] lookup_field_vals Struct which holds lookup values
|
||||
@param[in, out] lookup_field_vals Struct which holds lookup values
|
||||
|
||||
@return void
|
||||
*/
|
||||
@ -2495,7 +2495,7 @@ static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
|
||||
@param[in] thd thread handler
|
||||
@param[in] cond WHERE condition
|
||||
@param[in] tables I_S table
|
||||
@param[in, out] lookup_field_values Struct which holds lookup values
|
||||
@param[in, out] lookup_field_values Struct which holds lookup values
|
||||
|
||||
@return void
|
||||
*/
|
||||
@ -2556,7 +2556,7 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
|
||||
idx_field_vals idx_field_vals->db_name contains db name or
|
||||
wild string
|
||||
with_i_schema returns 1 if we added 'IS' name to list
|
||||
otherwise returns 0
|
||||
otherwise returns 0
|
||||
|
||||
RETURN
|
||||
zero success
|
||||
@ -2580,7 +2580,7 @@ int make_db_list(THD *thd, List<LEX_STRING> *files,
|
||||
LIKE clause (see also get_index_field_values() function)
|
||||
*/
|
||||
if (!lookup_field_vals->db_value.str ||
|
||||
!wild_case_compare(system_charset_info,
|
||||
!wild_case_compare(system_charset_info,
|
||||
INFORMATION_SCHEMA_NAME.str,
|
||||
lookup_field_vals->db_value.str))
|
||||
{
|
||||
@ -2624,7 +2624,7 @@ int make_db_list(THD *thd, List<LEX_STRING> *files,
|
||||
}
|
||||
|
||||
|
||||
struct st_add_schema_table
|
||||
struct st_add_schema_table
|
||||
{
|
||||
List<LEX_STRING> *files;
|
||||
const char *wild;
|
||||
@ -2688,7 +2688,7 @@ int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
|
||||
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
|
||||
continue;
|
||||
}
|
||||
if ((file_name=
|
||||
if ((file_name=
|
||||
thd->make_lex_string(file_name, tmp_schema_table->table_name,
|
||||
strlen(tmp_schema_table->table_name), TRUE)) &&
|
||||
!files->push_back(file_name))
|
||||
@ -2744,7 +2744,7 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (table_names->push_back(&lookup_field_vals->table_value))
|
||||
return 1;
|
||||
/*
|
||||
@ -2805,7 +2805,7 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
|
||||
@retval 1 error
|
||||
*/
|
||||
|
||||
static int
|
||||
static int
|
||||
fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
|
||||
ST_SCHEMA_TABLE *schema_table,
|
||||
Open_tables_state *open_tables_state_backup)
|
||||
@ -2832,7 +2832,7 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
|
||||
Let us set fake sql_command so views won't try to merge
|
||||
themselves into main statement. If we don't do this,
|
||||
SELECT * from information_schema.xxxx will cause problems.
|
||||
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
|
||||
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
|
||||
*/
|
||||
lex->sql_command= SQLCOM_SHOW_FIELDS;
|
||||
res= open_normal_and_derived_tables(thd, show_table_list,
|
||||
@ -2842,11 +2842,11 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
|
||||
get_all_tables() returns 1 on failure and 0 on success thus
|
||||
return only these and not the result code of ::process_table()
|
||||
|
||||
We should use show_table_list->alias instead of
|
||||
We should use show_table_list->alias instead of
|
||||
show_table_list->table_name because table_name
|
||||
could be changed during opening of I_S tables. It's safe
|
||||
to use alias because alias contains original table name
|
||||
in this case(this part of code is used only for
|
||||
to use alias because alias contains original table name
|
||||
in this case(this part of code is used only for
|
||||
'show columns' & 'show statistics' commands).
|
||||
*/
|
||||
table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
|
||||
@ -2856,7 +2856,7 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
|
||||
show_table_list->db_length, FALSE);
|
||||
else
|
||||
db_name= &show_table_list->view_db;
|
||||
|
||||
|
||||
|
||||
error= test(schema_table->process_table(thd, show_table_list,
|
||||
table, res, db_name,
|
||||
@ -2894,7 +2894,7 @@ static int fill_schema_table_names(THD *thd, TABLE *table,
|
||||
{
|
||||
enum legacy_db_type not_used;
|
||||
char path[FN_REFLEN];
|
||||
(void) build_table_filename(path, sizeof(path), db_name->str,
|
||||
(void) build_table_filename(path, sizeof(path), db_name->str,
|
||||
table_name->str, reg_ext, 0);
|
||||
switch (mysql_frm_type(thd, path, ¬_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, ¬_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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1694,7 +1694,7 @@ bool multi_update::send_data(List<Item> ¬_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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user