diff options
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 125 |
1 files changed, 84 insertions, 41 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index a4a2297bd2f..4a9df5b2bf8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -41,6 +41,7 @@ #include <mysql/psi/mysql_table.h> #include "debug_sync.h" // DEBUG_SYNC #include "sql_audit.h" +#include "ha_sequence.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" @@ -75,12 +76,12 @@ ulong total_ha_2pc= 0; /* size of savepoint storage area (see ha_init) */ ulong savepoint_alloc_size= 0; -static const LEX_STRING sys_table_aliases[]= +static const LEX_CSTRING sys_table_aliases[]= { - { C_STRING_WITH_LEN("INNOBASE") }, { C_STRING_WITH_LEN("INNODB") }, - { C_STRING_WITH_LEN("HEAP") }, { C_STRING_WITH_LEN("MEMORY") }, - { C_STRING_WITH_LEN("MERGE") }, { C_STRING_WITH_LEN("MRG_MYISAM") }, - { C_STRING_WITH_LEN("Maria") }, { C_STRING_WITH_LEN("Aria") }, + { STRING_WITH_LEN("INNOBASE") }, { STRING_WITH_LEN("INNODB") }, + { STRING_WITH_LEN("HEAP") }, { STRING_WITH_LEN("MEMORY") }, + { STRING_WITH_LEN("MERGE") }, { STRING_WITH_LEN("MRG_MYISAM") }, + { STRING_WITH_LEN("Maria") }, { STRING_WITH_LEN("Aria") }, {NullS, 0} }; @@ -159,9 +160,10 @@ handlerton *ha_default_tmp_handlerton(THD *thd) RETURN pointer to storage engine plugin handle */ -plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name, bool tmp_table) +plugin_ref ha_resolve_by_name(THD *thd, const LEX_CSTRING *name, + bool tmp_table) { - const LEX_STRING *table_alias; + const LEX_CSTRING *table_alias; plugin_ref plugin; redo: @@ -291,7 +293,6 @@ handler *get_ha_partition(partition_info *part_info) } #endif - static const char **handler_errmsgs; C_MODE_START @@ -405,7 +406,7 @@ static int full_discover_for_existence(handlerton *, const char *, const char *) static int ext_based_existence(handlerton *, const char *, const char *) { return 0; } -static int hton_ext_based_table_discovery(handlerton *hton, LEX_STRING *db, +static int hton_ext_based_table_discovery(handlerton *hton, LEX_CSTRING *db, MY_DIR *dir, handlerton::discovered_list *result) { /* @@ -618,7 +619,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin) /* This is entirely for legacy. We will create a new "disk based" hton and a "memory" hton which will be configurable longterm. We should be able to - remove partition and myisammrg. + remove partition. */ switch (hton->db_type) { case DB_TYPE_HEAP: @@ -630,6 +631,9 @@ int ha_initialize_handlerton(st_plugin_int *plugin) case DB_TYPE_PARTITION_DB: partition_hton= hton; break; + case DB_TYPE_SEQUENCE: + sql_sequence_hton= hton; + break; default: break; }; @@ -2388,6 +2392,11 @@ err: return NULL; } +LEX_CSTRING *handler::engine_name() +{ + return hton_name(ht); +} + double handler::keyread_time(uint index, uint ranges, ha_rows rows) { @@ -2511,6 +2520,7 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, } reset_statistics(); internal_tmp_table= MY_TEST(test_if_locked & HA_OPEN_INTERNAL_TABLE); + DBUG_RETURN(error); } @@ -2759,10 +2769,11 @@ int handler::ha_rnd_init_with_error(bool scan) /** - Read first row (only) from a table. + Read first row (only) from a table. Used for reading tables with + only one row, either based on table statistics or if table is a SEQUENCE. - This is never called for InnoDB tables, as these table types - has the HA_STATS_RECORDS_IS_EXACT set. + This is never called for normal InnoDB tables, as these table types + does not have HA_STATS_RECORDS_IS_EXACT set. */ int handler::read_first_row(uchar * buf, uint primary_key) { @@ -3553,7 +3564,7 @@ void handler::print_error(int error, myf errflag) break; case HA_ERR_AUTOINC_ERANGE: textno= error; - my_error(textno, errflag, table->next_number_field->field_name, + my_error(textno, errflag, table->next_number_field->field_name.str, table->in_use->get_stmt_da()->current_row_for_warning()); DBUG_VOID_RETURN; break; @@ -3954,7 +3965,7 @@ void handler::mark_trx_read_write_internal() */ if (ha_info->is_started()) { - DBUG_ASSERT(has_transactions()); + DBUG_ASSERT(has_transaction_manager()); /* table_share can be NULL in ha_delete_table(). See implementation of standalone function ha_delete_table() in sql_base.cc. @@ -3994,7 +4005,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt) */ int -handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data, +handler::ha_bulk_update_row(const uchar *old_data, const uchar *new_data, uint *dup_key_found) { DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || @@ -5000,22 +5011,28 @@ private: loaded, frm is invalid), the return value will be true, but *hton will be NULL. */ + bool ha_table_exists(THD *thd, const char *db, const char *table_name, - handlerton **hton) + handlerton **hton, bool *is_sequence) { handlerton *dummy; + bool dummy2; DBUG_ENTER("ha_table_exists"); if (hton) *hton= 0; else if (engines_with_discover) hton= &dummy; + if (!is_sequence) + is_sequence= &dummy2; + *is_sequence= 0; TDC_element *element= tdc_lock_share(thd, db, table_name); if (element && element != MY_ERRPTR) { if (hton) *hton= element->share->db_type(); + *is_sequence= element->share->table_type == TABLE_TYPE_SEQUENCE; tdc_unlock_share(element); DBUG_RETURN(TRUE); } @@ -5031,11 +5048,12 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name, if (hton) { char engine_buf[NAME_CHAR_LEN + 1]; - LEX_STRING engine= { engine_buf, 0 }; + LEX_CSTRING engine= { engine_buf, 0 }; - if (dd_frm_type(thd, path, &engine) != FRMTYPE_VIEW) + if (dd_frm_type(thd, path, &engine, is_sequence) != TABLE_TYPE_VIEW) { - plugin_ref p= plugin_lock_by_name(thd, &engine, MYSQL_STORAGE_ENGINE_PLUGIN); + plugin_ref p= plugin_lock_by_name(thd, &engine, + MYSQL_STORAGE_ENGINE_PLUGIN); *hton= p ? plugin_hton(p) : NULL; if (*hton) // verify that the table really exists @@ -5056,7 +5074,6 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name, DBUG_RETURN(TRUE); } - if (need_full_discover_for_existence) { TABLE_LIST table; @@ -5098,7 +5115,7 @@ static int cmp_file_names(const void *a, const void *b) return my_strnncoll(cs, (uchar*)aa, strlen(aa), (uchar*)bb, strlen(bb)); } -static int cmp_table_names(LEX_STRING * const *a, LEX_STRING * const *b) +static int cmp_table_names(LEX_CSTRING * const *a, LEX_CSTRING * const *b) { return my_strnncoll(&my_charset_bin, (uchar*)((*a)->str), (*a)->length, (uchar*)((*b)->str), (*b)->length); @@ -5107,8 +5124,8 @@ static int cmp_table_names(LEX_STRING * const *a, LEX_STRING * const *b) } Discovered_table_list::Discovered_table_list(THD *thd_arg, - Dynamic_array<LEX_STRING*> *tables_arg, - const LEX_STRING *wild_arg) : + Dynamic_array<LEX_CSTRING*> *tables_arg, + const LEX_CSTRING *wild_arg) : thd(thd_arg), with_temps(false), tables(tables_arg) { if (wild_arg->str && wild_arg->str[0]) @@ -5132,7 +5149,7 @@ bool Discovered_table_list::add_table(const char *tname, size_t tlen) wild_prefix, wild_one, wild_many)) return 0; - LEX_STRING *name= thd->make_lex_string(tname, tlen); + LEX_CSTRING *name= thd->make_clex_string(tname, tlen); if (!name || tables->append(name)) return 1; return 0; @@ -5158,11 +5175,11 @@ void Discovered_table_list::sort() void Discovered_table_list::remove_duplicates() { - LEX_STRING **src= tables->front(); - LEX_STRING **dst= src; + LEX_CSTRING **src= tables->front(); + LEX_CSTRING **dst= src; while (++dst <= tables->back()) { - LEX_STRING *s= *src, *d= *dst; + LEX_CSTRING *s= *src, *d= *dst; DBUG_ASSERT(strncmp(s->str, d->str, MY_MIN(s->length, d->length)) <= 0); if ((s->length != d->length || strncmp(s->str, d->str, d->length))) { @@ -5176,7 +5193,7 @@ void Discovered_table_list::remove_duplicates() struct st_discover_names_args { - LEX_STRING *db; + LEX_CSTRING *db; MY_DIR *dirp; Discovered_table_list *result; uint possible_duplicates; @@ -5221,7 +5238,7 @@ static my_bool discover_names(THD *thd, plugin_ref plugin, for DROP DATABASE (as it needs to know and delete non-table files). */ -int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, +int ha_discover_table_names(THD *thd, LEX_CSTRING *db, MY_DIR *dirp, Discovered_table_list *result, bool reusable) { int error; @@ -5571,7 +5588,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) { if (db_type->state != SHOW_OPTION_YES) { - const LEX_STRING *name= hton_name(db_type); + const LEX_CSTRING *name= hton_name(db_type); result= stat_print(thd, name->str, name->length, "", 0, "DISABLED", 8) ? 1 : 0; } @@ -5759,8 +5776,6 @@ static int write_locked_table_maps(THD *thd) } -typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*); - static int check_wsrep_max_ws_rows(); static int binlog_log_row_internal(TABLE* table, @@ -5801,10 +5816,10 @@ static int binlog_log_row_internal(TABLE* table, return error ? HA_ERR_RBR_LOGGING_FAILED : 0; } -static inline int binlog_log_row(TABLE* table, - const uchar *before_record, - const uchar *after_record, - Log_func *log_func) +int binlog_log_row(TABLE* table, + const uchar *before_record, + const uchar *after_record, + Log_func *log_func) { if (!table->file->check_table_binlog_row_based(1)) return 0; @@ -5956,7 +5971,7 @@ int handler::ha_write_row(uchar *buf) { error= write_row(buf); }) MYSQL_INSERT_ROW_DONE(error); - if (likely(!error)) + if (likely(!error) && !row_already_logged) { rows_changed++; error= binlog_log_row(table, 0, buf, log_func); @@ -5966,7 +5981,7 @@ int handler::ha_write_row(uchar *buf) } -int handler::ha_update_row(const uchar *old_data, uchar *new_data) +int handler::ha_update_row(const uchar *old_data, const uchar *new_data) { int error; Log_func *log_func= Update_rows_log_event::binlog_row_logging_function; @@ -5988,7 +6003,7 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data) { error= update_row(old_data, new_data);}) MYSQL_UPDATE_ROW_DONE(error); - if (likely(!error)) + if (likely(!error) && !row_already_logged) { rows_changed++; error= binlog_log_row(table, old_data, new_data, log_func); @@ -5996,6 +6011,34 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data) return error; } +/* + Update first row. Only used by sequence tables +*/ + +int handler::update_first_row(uchar *new_data) +{ + int error; + if (!(error= ha_rnd_init(1))) + { + int end_error; + if (!(error= ha_rnd_next(table->record[1]))) + { + /* + We have to do the memcmp as otherwise we may get error 169 from InnoDB + */ + if (memcmp(table->record[0], table->record[1], table->s->reclength)) + error= update_row(table->record[1], new_data); + } + end_error= ha_rnd_end(); + if (!error) + error= end_error; + /* Logging would be wrong if update_row works but ha_rnd_end fails */ + DBUG_ASSERT(!end_error || error != 0); + } + return error; +} + + int handler::ha_delete_row(const uchar *buf) { int error; @@ -6443,7 +6486,7 @@ int del_global_index_stats_for_table(THD *thd, uchar* cache_key, uint cache_key_ /* Remove a table from global table statistics */ -int del_global_table_stat(THD *thd, LEX_STRING *db, LEX_STRING *table) +int del_global_table_stat(THD *thd, LEX_CSTRING *db, LEX_CSTRING *table) { TABLE_STATS *table_stats; int res = 0; |