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,6 +3,7 @@ ...@@ -3,6 +3,7 @@
/* /*
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
...@@ -17,10 +18,6 @@ ...@@ -17,10 +18,6 @@
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 */
...@@ -31,21 +28,7 @@ enum partition_keywords ...@@ -31,21 +28,7 @@ enum partition_keywords
}; };
#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 @@ private: ...@@ -148,7 +131,7 @@ private:
/* 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 @@ private: ...@@ -191,8 +174,6 @@ private:
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 @@ public: ...@@ -356,7 +337,6 @@ public:
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 @@ private: ...@@ -390,6 +370,7 @@ private:
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 @@ public: ...@@ -409,8 +390,6 @@ public:
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 @@ public: ...@@ -452,6 +431,18 @@ public:
*/ */
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 @@ public: ...@@ -502,6 +493,7 @@ public:
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
MODULE full table scan MODULE full table scan
...@@ -626,7 +618,6 @@ private: ...@@ -626,7 +618,6 @@ private:
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 @@ private: ...@@ -659,6 +650,7 @@ private:
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 @@ public: ...@@ -727,6 +719,9 @@ public:
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 @@ public: ...@@ -742,6 +737,9 @@ public:
*/ */
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 @@ public: ...@@ -903,17 +901,7 @@ public:
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
...@@ -1213,8 +1201,8 @@ public: ...@@ -1213,8 +1201,8 @@ public:
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 @@ public: ...@@ -2809,6 +2809,7 @@ public:
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,7 +312,7 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags) ...@@ -312,7 +312,7 @@ 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 +
...@@ -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 @@ public: ...@@ -2618,8 +2620,8 @@ public:
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