summaryrefslogtreecommitdiff
path: root/sql/handler.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.h')
-rw-r--r--sql/handler.h50
1 files changed, 46 insertions, 4 deletions
diff --git a/sql/handler.h b/sql/handler.h
index 94f4519a2e7..d1ed6669037 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -906,16 +906,37 @@ public:
uint ref_length;
FT_INFO *ft_handler;
enum {NONE=0, INDEX, RND} inited;
- bool auto_increment_column_changed;
bool implicit_emptied; /* Can be !=0 only if HEAP */
const COND *pushed_cond;
+ /*
+ next_insert_id is the next value which should be inserted into the
+ auto_increment column: in a inserting-multi-row statement (like INSERT
+ SELECT), for the first row where the autoinc value is not specified by the
+ statement, get_auto_increment() called and asked to generate a value,
+ next_insert_id is set to the next value, then for all other rows
+ next_insert_id is used (and increased each time) without calling
+ get_auto_increment().
+ */
+ ulonglong next_insert_id;
+ /*
+ insert id for the current row (*autogenerated*; if not
+ autogenerated, it's 0).
+ At first successful insertion, this variable is stored into
+ THD::first_successful_insert_id_in_cur_stmt.
+ */
+ ulonglong insert_id_for_cur_row;
+ /*
+ Interval returned by get_auto_increment() and being consumed by the
+ inserter.
+ */
+ Discrete_interval auto_inc_interval_for_cur_row;
handler(const handlerton *ht_arg, TABLE_SHARE *share_arg)
:table_share(share_arg), estimation_rows_to_insert(0), ht(ht_arg),
ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE), implicit_emptied(0),
- pushed_cond(NULL)
+ pushed_cond(NULL), next_insert_id(0), insert_id_for_cur_row(0)
{}
virtual ~handler(void)
{
@@ -1227,9 +1248,30 @@ public:
ulonglong nb_desired_values,
ulonglong *first_value,
ulonglong *nb_reserved_values);
+private:
virtual void release_auto_increment() { return; };
- virtual void restore_auto_increment();
-
+public:
+ void ha_release_auto_increment();
+ void set_next_insert_id(ulonglong id)
+ {
+ DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
+ next_insert_id= id;
+ }
+ void restore_auto_increment(ulonglong prev_insert_id)
+ {
+ /*
+ Insertion of a row failed, re-use the lastly generated auto_increment
+ id, for the next row. This is achieved by resetting next_insert_id to
+ what it was before the failed insertion (that old value is provided by
+ the caller). If that value was 0, it was the first row of the INSERT;
+ then if insert_id_for_cur_row contains 0 it means no id was generated
+ for this first row, so no id was generated since the INSERT started, so
+ we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
+ is the generated id of the first and failed row, so we use it.
+ */
+ next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
+ insert_id_for_cur_row;
+ }
/*
Reset the auto-increment counter to the given value, i.e. the next row
inserted will get the given value. This is called e.g. after TRUNCATE