Commit 94d722b6 authored by Michael Widenius's avatar Michael Widenius

ha_partition.cc and ha_partition.h are now completely merged

Added sql_mode_t to simplify merges
parent e7606294
...@@ -280,7 +280,9 @@ static void free_memory(void *ptr) ...@@ -280,7 +280,9 @@ static void free_memory(void *ptr)
static void warn(const char *format,...) static void warn(const char *format,...)
{ {
va_list args; va_list args;
DBUG_PRINT("error", ("%s", format));
va_start(args,format); va_start(args,format);
fflush(stderr);
vfprintf(stderr, format, args); vfprintf(stderr, format, args);
va_end(args); va_end(args);
......
This diff is collapsed.
...@@ -3,49 +3,32 @@ ...@@ -3,49 +3,32 @@
/* /*
Copyright (c) 2005, 2012, Oracle and/or its affiliates. Copyright (c) 2005, 2012, Oracle and/or its affiliates.
Copyright (c) 2009-2013 Monty Program Ab & SkySQL Ab
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
#include "sql_partition.h" /* part_id_range, partition_element */ #include "sql_partition.h" /* part_id_range, partition_element */
#include "queues.h" /* QUEUE */ #include "queues.h" /* QUEUE */
enum partition_keywords enum partition_keywords
{ {
PKW_HASH= 0, PKW_RANGE, PKW_LIST, PKW_KEY, PKW_MAXVALUE, PKW_LINEAR, PKW_HASH= 0, PKW_RANGE, PKW_LIST, PKW_KEY, PKW_MAXVALUE, PKW_LINEAR,
PKW_COLUMNS PKW_COLUMNS
}; };
#define PARTITION_BYTES_IN_POS 2 #define PARTITION_BYTES_IN_POS 2
#define PARTITION_ENABLED_TABLE_FLAGS (HA_FILE_BASED | HA_REC_NOT_IN_SEQ)
#define PARTITION_DISABLED_TABLE_FLAGS (HA_CAN_GEOMETRY | \
HA_CAN_FULLTEXT | \
HA_DUPLICATE_POS | \
HA_CAN_SQL_HANDLER | \
HA_CAN_INSERT_DELAYED)
/* First 4 bytes in the .par file is the number of 32-bit words in the file */
#define PAR_WORD_SIZE 4
/* offset to the .par file checksum */
#define PAR_CHECKSUM_OFFSET 4
/* offset to the total number of partitions */
#define PAR_NUM_PARTS_OFFSET 8
/* offset to the engines array */
#define PAR_ENGINES_OFFSET 12
/** Struct used for partition_name_hash */ /** Struct used for partition_name_hash */
typedef struct st_part_name_def typedef struct st_part_name_def
...@@ -148,7 +131,7 @@ class ha_partition :public handler ...@@ -148,7 +131,7 @@ class ha_partition :public handler
/* Data for the partition handler */ /* Data for the partition handler */
int m_mode; // Open mode int m_mode; // Open mode
uint m_open_test_lock; // Open test_if_locked uint m_open_test_lock; // Open test_if_locked
char *m_file_buffer; // Content of the .par file uchar *m_file_buffer; // Content of the .par file
char *m_name_buffer_ptr; // Pointer to first partition name char *m_name_buffer_ptr; // Pointer to first partition name
MEM_ROOT m_mem_root; MEM_ROOT m_mem_root;
plugin_ref *m_engine_array; // Array of types of the handlers plugin_ref *m_engine_array; // Array of types of the handlers
...@@ -191,8 +174,6 @@ class ha_partition :public handler ...@@ -191,8 +174,6 @@ class ha_partition :public handler
uint m_tot_parts; // Total number of partitions; uint m_tot_parts; // Total number of partitions;
uint m_num_locks; // For engines like ha_blackhole, which needs no locks uint m_num_locks; // For engines like ha_blackhole, which needs no locks
uint m_last_part; // Last file that we update,write,read uint m_last_part; // Last file that we update,write,read
int m_lock_type; // Remembers type of last
// external_lock
part_id_range m_part_spec; // Which parts to scan part_id_range m_part_spec; // Which parts to scan
uint m_scan_value; // Value passed in rnd_init uint m_scan_value; // Value passed in rnd_init
// call // call
...@@ -356,7 +337,6 @@ class ha_partition :public handler ...@@ -356,7 +337,6 @@ class ha_partition :public handler
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info, virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes); uint table_changes);
private: private:
int prepare_for_rename();
int copy_partitions(ulonglong * const copied, ulonglong * const deleted); int copy_partitions(ulonglong * const copied, ulonglong * const deleted);
void cleanup_new_partition(uint part_count); void cleanup_new_partition(uint part_count);
int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info, int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info,
...@@ -390,6 +370,7 @@ class ha_partition :public handler ...@@ -390,6 +370,7 @@ class ha_partition :public handler
bool populate_partition_name_hash(); bool populate_partition_name_hash();
Partition_share *get_share(); Partition_share *get_share();
bool set_ha_share_ref(Handler_share **ha_share); bool set_ha_share_ref(Handler_share **ha_share);
void fix_data_dir(char* path);
bool init_partition_bitmaps(); bool init_partition_bitmaps();
void free_partition_bitmaps(); void free_partition_bitmaps();
...@@ -409,8 +390,6 @@ class ha_partition :public handler ...@@ -409,8 +390,6 @@ class ha_partition :public handler
If the object was opened it will also be closed before being deleted. If the object was opened it will also be closed before being deleted.
*/ */
virtual int open(const char *name, int mode, uint test_if_locked); virtual int open(const char *name, int mode, uint test_if_locked);
virtual void unbind_psi();
virtual void rebind_psi();
virtual int close(void); virtual int close(void);
/* /*
...@@ -452,6 +431,18 @@ class ha_partition :public handler ...@@ -452,6 +431,18 @@ class ha_partition :public handler
*/ */
virtual void try_semi_consistent_read(bool); virtual void try_semi_consistent_read(bool);
/*
NOTE: due to performance and resource issues with many partitions,
we only use the m_psi on the ha_partition handler, excluding all
partitions m_psi.
*/
#ifdef HAVE_M_PSI_PER_PARTITION
/*
Bind the table/handler thread to track table i/o.
*/
virtual void unbind_psi();
virtual void rebind_psi();
#endif
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
MODULE change record MODULE change record
...@@ -502,6 +493,7 @@ class ha_partition :public handler ...@@ -502,6 +493,7 @@ class ha_partition :public handler
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
MODULE full table scan MODULE full table scan
...@@ -626,7 +618,6 @@ class ha_partition :public handler ...@@ -626,7 +618,6 @@ class ha_partition :public handler
int handle_ordered_next(uchar * buf, bool next_same); int handle_ordered_next(uchar * buf, bool next_same);
int handle_ordered_prev(uchar * buf); int handle_ordered_prev(uchar * buf);
void return_top_record(uchar * buf); void return_top_record(uchar * buf);
void column_bitmaps_signal();
public: public:
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
...@@ -659,6 +650,7 @@ class ha_partition :public handler ...@@ -659,6 +650,7 @@ class ha_partition :public handler
handler *file, uint *n); handler *file, uint *n);
static const uint NO_CURRENT_PART_ID; static const uint NO_CURRENT_PART_ID;
int loop_extra(enum ha_extra_function operation); int loop_extra(enum ha_extra_function operation);
int loop_extra_alter(enum ha_extra_function operations);
void late_extra_cache(uint partition_id); void late_extra_cache(uint partition_id);
void late_extra_no_cache(uint partition_id); void late_extra_no_cache(uint partition_id);
void prepare_extra_cache(uint cachesize); void prepare_extra_cache(uint cachesize);
...@@ -727,6 +719,9 @@ class ha_partition :public handler ...@@ -727,6 +719,9 @@ class ha_partition :public handler
virtual uint8 table_cache_type(); virtual uint8 table_cache_type();
virtual ha_rows records(); virtual ha_rows records();
/* Calculate hash value for PARTITION BY KEY tables. */
uint32 calculate_key_hash_value(Field **field_array);
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
MODULE print messages MODULE print messages
...@@ -742,6 +737,9 @@ class ha_partition :public handler ...@@ -742,6 +737,9 @@ class ha_partition :public handler
*/ */
virtual const char *index_type(uint inx); virtual const char *index_type(uint inx);
/* The name of the table type that will be used for display purposes */
virtual const char *table_type() const;
/* The name of the row type used for the underlying tables. */ /* The name of the row type used for the underlying tables. */
virtual enum row_type get_row_type() const; virtual enum row_type get_row_type() const;
...@@ -903,17 +901,7 @@ class ha_partition :public handler ...@@ -903,17 +901,7 @@ class ha_partition :public handler
HA_CAN_INSERT_DELAYED, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is disabled HA_CAN_INSERT_DELAYED, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is disabled
until further investigated. until further investigated.
*/ */
virtual Table_flags table_flags() const virtual Table_flags table_flags() const;
{
DBUG_ENTER("ha_partition::table_flags");
if (m_handler_status < handler_initialized ||
m_handler_status >= handler_closed)
DBUG_RETURN(PARTITION_ENABLED_TABLE_FLAGS);
DBUG_RETURN((m_file[0]->ha_table_flags() &
~(PARTITION_DISABLED_TABLE_FLAGS)) |
(PARTITION_ENABLED_TABLE_FLAGS));
}
/* /*
This is a bitmap of flags that says how the storage engine This is a bitmap of flags that says how the storage engine
...@@ -1153,10 +1141,10 @@ class ha_partition :public handler ...@@ -1153,10 +1141,10 @@ class ha_partition :public handler
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
MODULE in-place ALTER TABLE MODULE in-place ALTER TABLE
------------------------------------------------------------------------- -------------------------------------------------------------------------
These methods are in the handler interface. (used by innodb-plugin) These methods are in the handler interface. (used by innodb-plugin)
They are used for in-place alter table: They are used for in-place alter table:
------------------------------------------------------------------------- -------------------------------------------------------------------------
*/ */
virtual enum_alter_inplace_result virtual enum_alter_inplace_result
check_if_supported_inplace_alter(TABLE *altered_table, check_if_supported_inplace_alter(TABLE *altered_table,
...@@ -1170,7 +1158,7 @@ class ha_partition :public handler ...@@ -1170,7 +1158,7 @@ class ha_partition :public handler
bool commit); bool commit);
virtual void notify_table_changed(); virtual void notify_table_changed();
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
MODULE tablespace support MODULE tablespace support
------------------------------------------------------------------------- -------------------------------------------------------------------------
...@@ -1213,8 +1201,8 @@ class ha_partition :public handler ...@@ -1213,8 +1201,8 @@ class ha_partition :public handler
virtual int restore(THD* thd, HA_CHECK_OPT *check_opt); virtual int restore(THD* thd, HA_CHECK_OPT *check_opt);
virtual int dump(THD* thd, int fd = -1); virtual int dump(THD* thd, int fd = -1);
virtual int net_read_dump(NET* net); virtual int net_read_dump(NET* net);
virtual uint checksum() const;
*/ */
virtual uint checksum() const;
/* Enabled keycache for performance reasons, WL#4571 */ /* Enabled keycache for performance reasons, WL#4571 */
virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt); virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt);
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt); virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
......
...@@ -2237,6 +2237,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, ...@@ -2237,6 +2237,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
handler *handler::clone(const char *name, MEM_ROOT *mem_root) handler *handler::clone(const char *name, MEM_ROOT *mem_root)
{ {
handler *new_handler= get_new_handler(table->s, mem_root, ht); handler *new_handler= get_new_handler(table->s, mem_root, ht);
if (!new_handler) if (!new_handler)
return NULL; return NULL;
if (new_handler->set_ha_share_ref(ha_share)) if (new_handler->set_ha_share_ref(ha_share))
...@@ -5047,14 +5048,7 @@ int handler::read_range_first(const key_range *start_key, ...@@ -5047,14 +5048,7 @@ int handler::read_range_first(const key_range *start_key,
DBUG_ENTER("handler::read_range_first"); DBUG_ENTER("handler::read_range_first");
eq_range= eq_range_arg; eq_range= eq_range_arg;
end_range= 0; set_end_range(end_key);
if (end_key)
{
end_range= &save_end_range;
save_end_range= *end_key;
key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
}
range_key_part= table->key_info[active_index].key_part; range_key_part= table->key_info[active_index].key_part;
if (!start_key) // Read first record if (!start_key) // Read first record
...@@ -5130,12 +5124,26 @@ int handler::read_range_next() ...@@ -5130,12 +5124,26 @@ int handler::read_range_next()
} }
void handler::set_end_range(const key_range *end_key)
{
end_range= 0;
if (end_key)
{
end_range= &save_end_range;
save_end_range= *end_key;
key_compare_result_on_equal=
((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
}
}
/** /**
Compare if found key (in row) is over max-value. Compare if found key (in row) is over max-value.
@param range range to compare to row. May be 0 for no range @param range range to compare to row. May be 0 for no range
@seealso @see also
key.cc::key_cmp() key.cc::key_cmp()
@return @return
......
...@@ -2809,6 +2809,7 @@ class handler :public Sql_alloc ...@@ -2809,6 +2809,7 @@ class handler :public Sql_alloc
const key_range *end_key, const key_range *end_key,
bool eq_range, bool sorted); bool eq_range, bool sorted);
virtual int read_range_next(); virtual int read_range_next();
void set_end_range(const key_range *end_key);
int compare_key(key_range *range); int compare_key(key_range *range);
int compare_key2(key_range *range); int compare_key2(key_range *range);
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; } virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
......
...@@ -312,8 +312,8 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags) ...@@ -312,8 +312,8 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags)
thd_proc_info(thd, "Table lock"); thd_proc_info(thd, "Table lock");
/* Copy the lock data array. thr_multi_lock() reorders its contents. */ /* Copy the lock data array. thr_multi_lock() reorders its contents. */
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks, memmove(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
sql_lock->lock_count * sizeof(*sql_lock->locks)); sql_lock->lock_count * sizeof(*sql_lock->locks));
/* Lock on the copied half of the lock data array. */ /* Lock on the copied half of the lock data array. */
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks + rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
sql_lock->lock_count, sql_lock->lock_count,
...@@ -692,7 +692,7 @@ static int unlock_external(THD *thd, TABLE **table,uint count) ...@@ -692,7 +692,7 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags) MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
{ {
uint i,tables,lock_count; uint i,lock_count,table_count;
MYSQL_LOCK *sql_lock; MYSQL_LOCK *sql_lock;
THR_LOCK_DATA **locks, **locks_buf; THR_LOCK_DATA **locks, **locks_buf;
TABLE **to, **table_buf; TABLE **to, **table_buf;
...@@ -701,15 +701,15 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags) ...@@ -701,15 +701,15 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS)); DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
DBUG_PRINT("info", ("count %d", count)); DBUG_PRINT("info", ("count %d", count));
for (i=tables=lock_count=0 ; i < count ; i++) for (i=lock_count=table_count=0 ; i < count ; i++)
{ {
TABLE *t= table_ptr[i]; TABLE *t= table_ptr[i];
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE && if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE &&
t->s->tmp_table != INTERNAL_TMP_TABLE) t->s->tmp_table != INTERNAL_TMP_TABLE)
{ {
tables+= t->file->lock_count(); lock_count+= t->file->lock_count();
lock_count++; table_count++;
} }
} }
...@@ -721,13 +721,13 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags) ...@@ -721,13 +721,13 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
*/ */
if (!(sql_lock= (MYSQL_LOCK*) if (!(sql_lock= (MYSQL_LOCK*)
my_malloc(sizeof(*sql_lock) + my_malloc(sizeof(*sql_lock) +
sizeof(THR_LOCK_DATA*) * tables * 2 + sizeof(THR_LOCK_DATA*) * lock_count * 2 +
sizeof(table_ptr) * lock_count, sizeof(table_ptr) * table_count,
MYF(0)))) MYF(0))))
DBUG_RETURN(0); DBUG_RETURN(0);
locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1); locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2); to= table_buf= sql_lock->table= (TABLE**) (locks + lock_count * 2);
sql_lock->table_count=lock_count; sql_lock->table_count= table_count;
for (i=0 ; i < count ; i++) for (i=0 ; i < count ; i++)
{ {
...@@ -763,7 +763,7 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags) ...@@ -763,7 +763,7 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
} }
} }
/* /*
We do not use 'tables', because there are cases where store_lock() We do not use 'lock_count', because there are cases where store_lock()
returns less locks than lock_count() claimed. This can happen when returns less locks than lock_count() claimed. This can happen when
a FLUSH TABLES tries to abort locks from a MERGE table of another a FLUSH TABLES tries to abort locks from a MERGE table of another
thread. When that thread has just opened the table, but not yet thread. When that thread has just opened the table, but not yet
...@@ -777,6 +777,7 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags) ...@@ -777,6 +777,7 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
And in the FLUSH case, the memory is released quickly anyway. And in the FLUSH case, the memory is released quickly anyway.
*/ */
sql_lock->lock_count= locks - locks_buf; sql_lock->lock_count= locks - locks_buf;
DBUG_ASSERT(sql_lock->lock_count <= lock_count);
DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d", DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d",
sql_lock->table_count, sql_lock->lock_count)); sql_lock->table_count, sql_lock->lock_count));
DBUG_RETURN(sql_lock); DBUG_RETURN(sql_lock);
......
...@@ -3972,6 +3972,12 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) ...@@ -3972,6 +3972,12 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
if (!table->file) if (!table->file)
goto err; goto err;
if (table->file->set_ha_share_ref(&share->ha_share))
{
delete table->file;
goto err;
}
null_count=1; null_count=1;
null_pack_length= 1; null_pack_length= 1;
......
...@@ -1532,7 +1532,6 @@ THD::~THD() ...@@ -1532,7 +1532,6 @@ THD::~THD()
mysql_audit_release(this); mysql_audit_release(this);
plugin_thdvar_cleanup(this); plugin_thdvar_cleanup(this);
DBUG_PRINT("info", ("freeing security context"));
main_security_ctx.destroy(); main_security_ctx.destroy();
my_free(db); my_free(db);
db= NULL; db= NULL;
...@@ -3801,6 +3800,7 @@ void Security_context::init() ...@@ -3801,6 +3800,7 @@ void Security_context::init()
void Security_context::destroy() void Security_context::destroy()
{ {
DBUG_PRINT("info", ("freeing security context"));
// If not pointer to constant // If not pointer to constant
if (host != my_localhost) if (host != my_localhost)
{ {
......
/* /*
Copyright (c) 2000, 2012, Oracle and/or its affiliates. Copyright (c) 2000, 2012, Oracle and/or its affiliates.
Copyright (c) 2009, 2012, Monty Program Ab Copyright (c) 2009-2013, Monty Program Ab & SkySQL Ab
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -465,6 +465,8 @@ class Time_zone; ...@@ -465,6 +465,8 @@ class Time_zone;
#define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC) #define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC)
typedef ulonglong sql_mode_t;
typedef struct system_variables typedef struct system_variables
{ {
/* /*
...@@ -488,7 +490,7 @@ typedef struct system_variables ...@@ -488,7 +490,7 @@ typedef struct system_variables
ulonglong tmp_table_size; ulonglong tmp_table_size;
ulonglong long_query_time; ulonglong long_query_time;
ulonglong optimizer_switch; ulonglong optimizer_switch;
ulonglong sql_mode; ///< which non-standard SQL behaviour should be enabled sql_mode_t sql_mode; ///< which non-standard SQL behaviour should be enabled
ulonglong option_bits; ///< OPTION_xxx constants, e.g. OPTION_PROFILING ulonglong option_bits; ///< OPTION_xxx constants, e.g. OPTION_PROFILING
ulonglong join_buff_space_limit; ulonglong join_buff_space_limit;
ulonglong log_slow_filter; ulonglong log_slow_filter;
...@@ -2618,8 +2620,8 @@ class THD :public Statement, ...@@ -2618,8 +2620,8 @@ class THD :public Statement,
inline bool is_strict_mode() const inline bool is_strict_mode() const
{ {
return variables.sql_mode & (MODE_STRICT_TRANS_TABLES | return (bool) (variables.sql_mode & (MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES); MODE_STRICT_ALL_TABLES));
} }
inline my_time_t query_start() { query_start_used=1; return start_time; } inline my_time_t query_start() { query_start_used=1; return start_time; }
inline ulong query_start_sec_part() inline ulong query_start_sec_part()
...@@ -3417,7 +3419,7 @@ my_eof(THD *thd) ...@@ -3417,7 +3419,7 @@ my_eof(THD *thd)
const my_bool strict_date_checking= 0; const my_bool strict_date_checking= 0;
inline ulonglong sql_mode_for_dates(THD *thd) inline sql_mode_t sql_mode_for_dates(THD *thd)
{ {
if (strict_date_checking) if (strict_date_checking)
return (thd->variables.sql_mode & return (thd->variables.sql_mode &
...@@ -3426,7 +3428,7 @@ inline ulonglong sql_mode_for_dates(THD *thd) ...@@ -3426,7 +3428,7 @@ inline ulonglong sql_mode_for_dates(THD *thd)
return (thd->variables.sql_mode & MODE_INVALID_DATES); return (thd->variables.sql_mode & MODE_INVALID_DATES);
} }
inline ulonglong sql_mode_for_dates() inline sql_mode_t sql_mode_for_dates()
{ {
return sql_mode_for_dates(current_thd); return sql_mode_for_dates(current_thd);
} }
......
...@@ -1995,6 +1995,79 @@ static int add_quoted_string(File fptr, const char *quotestr) ...@@ -1995,6 +1995,79 @@ static int add_quoted_string(File fptr, const char *quotestr)
return err + add_string(fptr, "'"); return err + add_string(fptr, "'");
} }
/**
@brief Truncate the partition file name from a path it it exists.
@note A partition file name will contian one or more '#' characters.
One of the occurances of '#' will be either "#P#" or "#p#" depending
on whether the storage engine has converted the filename to lower case.
*/
void truncate_partition_filename(char *path)
{
if (path)
{
char* last_slash= strrchr(path, FN_LIBCHAR);
if (!last_slash)
last_slash= strrchr(path, FN_LIBCHAR2);
if (last_slash)
{
/* Look for a partition-type filename */
for (char* pound= strchr(last_slash, '#');
pound; pound = strchr(pound + 1, '#'))
{
if ((pound[1] == 'P' || pound[1] == 'p') && pound[2] == '#')
{
last_slash[0] = '\0'; /* truncate the file name */
break;
}
}
}
}
}
/**
@brief Output a filepath. Similar to add_keyword_string except it
also converts \ to / on Windows and skips the partition file name at
the end if found.
@note
When Mysql sends a DATA DIRECTORY from SQL for partitions it does
not use a file name, but it does for DATA DIRECTORY on a non-partitioned
table. So when the storage engine is asked for the DATA DIRECTORY string
after a restart through Handler::update_create_options(), the storage
engine may include the filename.
*/
static int add_keyword_path(File fptr, const char *keyword,
const char *path)
{
char temp_path[FN_REFLEN];
int err= add_string(fptr, keyword);
err+= add_space(fptr);
err+= add_equal(fptr);
err+= add_space(fptr);
strmake(temp_path, path, sizeof(temp_path)-1);
/* Convert \ to / to be able to create table on unix */
to_unix_path(temp_path);
/*
If the partition file name with its "#P#" identifier
is found after the last slash, truncate that filename.
*/
truncate_partition_filename(temp_path);
err+= add_quoted_string(fptr, temp_path);
return err + add_space(fptr);
}
static int add_keyword_string(File fptr, const char *keyword, static int add_keyword_string(File fptr, const char *keyword,
bool should_use_quotes, bool should_use_quotes,
const char *keystr) const char *keystr)
...@@ -2047,11 +2120,9 @@ static int add_partition_options(File fptr, partition_element *p_elem) ...@@ -2047,11 +2120,9 @@ static int add_partition_options(File fptr, partition_element *p_elem)
if (!(current_thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)) if (!(current_thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
{ {
if (p_elem->data_file_name) if (p_elem->data_file_name)
err+= add_keyword_string(fptr, "DATA DIRECTORY", TRUE, err+= add_keyword_path(fptr, "DATA DIRECTORY", p_elem->data_file_name);
p_elem->data_file_name);
if (p_elem->index_file_name) if (p_elem->index_file_name)
err+= add_keyword_string(fptr, "INDEX DIRECTORY", TRUE, err+= add_keyword_path(fptr, "INDEX DIRECTORY", p_elem->index_file_name);
p_elem->index_file_name);
} }
if (p_elem->part_comment) if (p_elem->part_comment)
err+= add_keyword_string(fptr, "COMMENT", TRUE, p_elem->part_comment); err+= add_keyword_string(fptr, "COMMENT", TRUE, p_elem->part_comment);
......
...@@ -127,6 +127,7 @@ bool check_part_func_fields(Field **ptr, bool ok_with_charsets); ...@@ -127,6 +127,7 @@ bool check_part_func_fields(Field **ptr, bool ok_with_charsets);
bool field_is_partition_charset(Field *field); bool field_is_partition_charset(Field *field);
Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs); Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs);
void mem_alloc_error(size_t size); void mem_alloc_error(size_t size);
void truncate_partition_filename(char *path);
/* /*
A "Get next" function for partition iterator. A "Get next" function for partition iterator.
......
...@@ -14677,6 +14677,12 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, ...@@ -14677,6 +14677,12 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
if (!table->file) if (!table->file)
goto err; goto err;
if (table->file->set_ha_share_ref(&share->ha_share))
{
delete table->file;
goto err;
}
if (!using_unique_constraint) if (!using_unique_constraint)
reclength+= group_null_items; // null flag is stored separately reclength+= group_null_items; // null flag is stored separately
...@@ -15620,6 +15626,12 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, ...@@ -15620,6 +15626,12 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
new_table.s->db_type()))) new_table.s->db_type())))
DBUG_RETURN(1); // End of memory DBUG_RETURN(1); // End of memory
if (new_table.file->set_ha_share_ref(&share.ha_share))
{
delete new_table.file;
DBUG_RETURN(1);
}
save_proc_info=thd->proc_info; save_proc_info=thd->proc_info;
THD_STAGE_INFO(thd, stage_converting_heap_to_myisam); THD_STAGE_INFO(thd, stage_converting_heap_to_myisam);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment