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)
static void warn(const char *format,...)
{
va_list args;
DBUG_PRINT("error", ("%s", format));
va_start(args,format);
fflush(stderr);
vfprintf(stderr, format, args);
va_end(args);
......
This diff is collapsed.
......@@ -3,49 +3,32 @@
/*
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
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
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
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "sql_partition.h" /* part_id_range, partition_element */
#include "queues.h" /* QUEUE */
enum partition_keywords
{
{
PKW_HASH= 0, PKW_RANGE, PKW_LIST, PKW_KEY, PKW_MAXVALUE, PKW_LINEAR,
PKW_COLUMNS
};
#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 */
typedef struct st_part_name_def
......@@ -148,7 +131,7 @@ private:
/* Data for the partition handler */
int m_mode; // Open mode
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
MEM_ROOT m_mem_root;
plugin_ref *m_engine_array; // Array of types of the handlers
......@@ -191,8 +174,6 @@ private:
uint m_tot_parts; // Total number of partitions;
uint m_num_locks; // For engines like ha_blackhole, which needs no locks
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
uint m_scan_value; // Value passed in rnd_init
// call
......@@ -356,7 +337,6 @@ public:
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes);
private:
int prepare_for_rename();
int copy_partitions(ulonglong * const copied, ulonglong * const deleted);
void cleanup_new_partition(uint part_count);
int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info,
......@@ -390,6 +370,7 @@ private:
bool populate_partition_name_hash();
Partition_share *get_share();
bool set_ha_share_ref(Handler_share **ha_share);
void fix_data_dir(char* path);
bool init_partition_bitmaps();
void free_partition_bitmaps();
......@@ -409,8 +390,6 @@ public:
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 void unbind_psi();
virtual void rebind_psi();
virtual int close(void);
/*
......@@ -452,6 +431,18 @@ public:
*/
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
......@@ -502,6 +493,7 @@ public:
return FALSE;
return TRUE;
}
/*
-------------------------------------------------------------------------
MODULE full table scan
......@@ -626,7 +618,6 @@ private:
int handle_ordered_next(uchar * buf, bool next_same);
int handle_ordered_prev(uchar * buf);
void return_top_record(uchar * buf);
void column_bitmaps_signal();
public:
/*
-------------------------------------------------------------------------
......@@ -659,6 +650,7 @@ private:
handler *file, uint *n);
static const uint NO_CURRENT_PART_ID;
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_no_cache(uint partition_id);
void prepare_extra_cache(uint cachesize);
......@@ -727,6 +719,9 @@ public:
virtual uint8 table_cache_type();
virtual ha_rows records();
/* Calculate hash value for PARTITION BY KEY tables. */
uint32 calculate_key_hash_value(Field **field_array);
/*
-------------------------------------------------------------------------
MODULE print messages
......@@ -742,6 +737,9 @@ public:
*/
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. */
virtual enum row_type get_row_type() const;
......@@ -903,17 +901,7 @@ public:
HA_CAN_INSERT_DELAYED, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is disabled
until further investigated.
*/
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));
}
virtual Table_flags table_flags() const;
/*
This is a bitmap of flags that says how the storage engine
......@@ -1153,10 +1141,10 @@ public:
/*
-------------------------------------------------------------------------
MODULE in-place ALTER TABLE
-------------------------------------------------------------------------
-------------------------------------------------------------------------
These methods are in the handler interface. (used by innodb-plugin)
They are used for in-place alter table:
-------------------------------------------------------------------------
-------------------------------------------------------------------------
*/
virtual enum_alter_inplace_result
check_if_supported_inplace_alter(TABLE *altered_table,
......@@ -1170,7 +1158,7 @@ public:
bool commit);
virtual void notify_table_changed();
/*
/*
-------------------------------------------------------------------------
MODULE tablespace support
-------------------------------------------------------------------------
......@@ -1213,8 +1201,8 @@ public:
virtual int restore(THD* thd, HA_CHECK_OPT *check_opt);
virtual int dump(THD* thd, int fd = -1);
virtual int net_read_dump(NET* net);
virtual uint checksum() const;
*/
virtual uint checksum() const;
/* Enabled keycache for performance reasons, WL#4571 */
virtual int assign_to_keycache(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,
handler *handler::clone(const char *name, MEM_ROOT *mem_root)
{
handler *new_handler= get_new_handler(table->s, mem_root, ht);
if (!new_handler)
return NULL;
if (new_handler->set_ha_share_ref(ha_share))
......@@ -5047,14 +5048,7 @@ int handler::read_range_first(const key_range *start_key,
DBUG_ENTER("handler::read_range_first");
eq_range= eq_range_arg;
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);
}
set_end_range(end_key);
range_key_part= table->key_info[active_index].key_part;
if (!start_key) // Read first record
......@@ -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.
@param range range to compare to row. May be 0 for no range
@seealso
@see also
key.cc::key_cmp()
@return
......
......@@ -2809,6 +2809,7 @@ public:
const key_range *end_key,
bool eq_range, bool sorted);
virtual int read_range_next();
void set_end_range(const key_range *end_key);
int compare_key(key_range *range);
int compare_key2(key_range *range);
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)
thd_proc_info(thd, "Table lock");
/* Copy the lock data array. thr_multi_lock() reorders its contents. */
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
sql_lock->lock_count * sizeof(*sql_lock->locks));
memmove(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
sql_lock->lock_count * sizeof(*sql_lock->locks));
/* Lock on the copied half of the lock data array. */
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
sql_lock->lock_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)
{
uint i,tables,lock_count;
uint i,lock_count,table_count;
MYSQL_LOCK *sql_lock;
THR_LOCK_DATA **locks, **locks_buf;
TABLE **to, **table_buf;
......@@ -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_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];
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE &&
t->s->tmp_table != INTERNAL_TMP_TABLE)
{
tables+= t->file->lock_count();
lock_count++;
lock_count+= t->file->lock_count();
table_count++;
}
}
......@@ -721,13 +721,13 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
*/
if (!(sql_lock= (MYSQL_LOCK*)
my_malloc(sizeof(*sql_lock) +
sizeof(THR_LOCK_DATA*) * tables * 2 +
sizeof(table_ptr) * lock_count,
sizeof(THR_LOCK_DATA*) * lock_count * 2 +
sizeof(table_ptr) * table_count,
MYF(0))))
DBUG_RETURN(0);
locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
sql_lock->table_count=lock_count;
to= table_buf= sql_lock->table= (TABLE**) (locks + lock_count * 2);
sql_lock->table_count= table_count;
for (i=0 ; i < count ; i++)
{
......@@ -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
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
......@@ -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.
*/
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",
sql_lock->table_count, sql_lock->lock_count));
DBUG_RETURN(sql_lock);
......
......@@ -3972,6 +3972,12 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
if (!table->file)
goto err;
if (table->file->set_ha_share_ref(&share->ha_share))
{
delete table->file;
goto err;
}
null_count=1;
null_pack_length= 1;
......
......@@ -1532,7 +1532,6 @@ THD::~THD()
mysql_audit_release(this);
plugin_thdvar_cleanup(this);
DBUG_PRINT("info", ("freeing security context"));
main_security_ctx.destroy();
my_free(db);
db= NULL;
......@@ -3801,6 +3800,7 @@ void Security_context::init()
void Security_context::destroy()
{
DBUG_PRINT("info", ("freeing security context"));
// If not pointer to constant
if (host != my_localhost)
{
......
/*
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
it under the terms of the GNU General Public License as published by
......@@ -465,6 +465,8 @@ class Time_zone;
#define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC)
typedef ulonglong sql_mode_t;
typedef struct system_variables
{
/*
......@@ -488,7 +490,7 @@ typedef struct system_variables
ulonglong tmp_table_size;
ulonglong long_query_time;
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 join_buff_space_limit;
ulonglong log_slow_filter;
......@@ -2618,8 +2620,8 @@ public:
inline bool is_strict_mode() const
{
return variables.sql_mode & (MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES);
return (bool) (variables.sql_mode & (MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES));
}
inline my_time_t query_start() { query_start_used=1; return start_time; }
inline ulong query_start_sec_part()
......@@ -3417,7 +3419,7 @@ my_eof(THD *thd)
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)
return (thd->variables.sql_mode &
......@@ -3426,7 +3428,7 @@ inline ulonglong sql_mode_for_dates(THD *thd)
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);
}
......
......@@ -1995,6 +1995,79 @@ static int add_quoted_string(File fptr, const char *quotestr)
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,
bool should_use_quotes,
const char *keystr)
......@@ -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 (p_elem->data_file_name)
err+= add_keyword_string(fptr, "DATA DIRECTORY", TRUE,
p_elem->data_file_name);
err+= add_keyword_path(fptr, "DATA DIRECTORY", p_elem->data_file_name);
if (p_elem->index_file_name)
err+= add_keyword_string(fptr, "INDEX DIRECTORY", TRUE,
p_elem->index_file_name);
err+= add_keyword_path(fptr, "INDEX DIRECTORY", p_elem->index_file_name);
}
if (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);
bool field_is_partition_charset(Field *field);
Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs);
void mem_alloc_error(size_t size);
void truncate_partition_filename(char *path);
/*
A "Get next" function for partition iterator.
......
......@@ -14677,6 +14677,12 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
if (!table->file)
goto err;
if (table->file->set_ha_share_ref(&share->ha_share))
{
delete table->file;
goto err;
}
if (!using_unique_constraint)
reclength+= group_null_items; // null flag is stored separately
......@@ -15620,6 +15626,12 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
new_table.s->db_type())))
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;
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