summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc125
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;