diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.h | 4 | ||||
-rw-r--r-- | sql/item.h | 13 | ||||
-rw-r--r-- | sql/item_create.cc | 122 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 222 | ||||
-rw-r--r-- | sql/item_timefunc.h | 101 | ||||
-rw-r--r-- | sql/sql_select.cc | 98 | ||||
-rwxr-xr-x | sql/vtq.h | 18 |
7 files changed, 481 insertions, 97 deletions
diff --git a/sql/handler.h b/sql/handler.h index 11b71a6f03d..964880b0b62 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1391,7 +1391,9 @@ struct handlerton System Versioning */ bool versioned() const; - bool (*vers_get_vtq_ts)(THD* thd, MYSQL_TIME *out, ulonglong trx_id, vtq_field_t field); + bool (*vers_query_trx_id)(THD* thd, void *out, ulonglong trx_id, vtq_field_t field); + bool (*vers_query_commit_ts)(THD* thd, void *out, const MYSQL_TIME &commit_ts, vtq_field_t field, bool backwards); + bool (*vers_trx_sees)(THD *thd, bool &result, ulonglong trx_id1, ulonglong trx_id0, ulonglong commit_id1, uchar iso_level1, ulonglong commit_id0); }; diff --git a/sql/item.h b/sql/item.h index 35b76a3278e..b7381bde260 100644 --- a/sql/item.h +++ b/sql/item.h @@ -480,9 +480,20 @@ public: String_copier_for_item(THD *thd): m_thd(thd) { } }; +/* System versioning */ +class Vers_extended_item +{ +public: + virtual vtq_record_t* vtq_cached_result() + { + return NULL; + } +}; + class Item: public Value_source, - public Type_std_attributes + public Type_std_attributes, + public Vers_extended_item { void operator=(Item &); /** diff --git a/sql/item_create.cc b/sql/item_create.cc index 48055ccb11e..7e8c60591e6 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -6678,24 +6678,26 @@ Create_func_year_week::create_native(THD *thd, LEX_STRING name, } -/* System Versioning: BEGIN_TS(), COMMIT_TS() */ - -class Create_func_begin_ts : public Create_native_func +/* System Versioning: VTQ_TRX_ID(), VTQ_COMMIT_ID(), VTQ_BEGIN_TS(), VTQ_COMMIT_TS(), VTQ_ISO_LEVEL() */ +template <vtq_field_t VTQ_FIELD> +class Create_func_vtq : public Create_native_func { public: virtual Item *create_native(THD *thd, LEX_STRING name, List<Item> *item_list); - static Create_func_begin_ts s_singleton; + static Create_func_vtq<VTQ_FIELD> s_singleton; protected: - Create_func_begin_ts() {} - virtual ~Create_func_begin_ts() {} + Create_func_vtq<VTQ_FIELD>() {} + virtual ~Create_func_vtq<VTQ_FIELD>() {} }; -Create_func_begin_ts Create_func_begin_ts::s_singleton; +template<vtq_field_t VTQ_FIELD> +Create_func_vtq<VTQ_FIELD> Create_func_vtq<VTQ_FIELD>::s_singleton; +template <vtq_field_t VTQ_FIELD> Item* -Create_func_begin_ts::create_native(THD *thd, LEX_STRING name, +Create_func_vtq<VTQ_FIELD>::create_native(THD *thd, LEX_STRING name, List<Item> *item_list) { Item *func= NULL; @@ -6708,9 +6710,38 @@ Create_func_begin_ts::create_native(THD *thd, LEX_STRING name, case 1: { Item *param_1= item_list->pop(); - func= new (thd->mem_root) Item_func_vtq_ts(thd, param_1, VTQ_BEGIN_TS); + switch (VTQ_FIELD) + { + case VTQ_BEGIN_TS: + case VTQ_COMMIT_TS: + func= new (thd->mem_root) Item_func_vtq_ts(thd, param_1, VTQ_FIELD); + break; + case VTQ_TRX_ID: + case VTQ_COMMIT_ID: + case VTQ_ISO_LEVEL: + func= new (thd->mem_root) Item_func_vtq_id(thd, param_1, VTQ_FIELD); + break; + default: + DBUG_ASSERT(0); + } + break; + } + case 2: + { + Item *param_1= item_list->pop(); + Item *param_2= item_list->pop(); + switch (VTQ_FIELD) + { + case VTQ_TRX_ID: + case VTQ_COMMIT_ID: + func= new (thd->mem_root) Item_func_vtq_id(thd, param_1, param_2, VTQ_FIELD); + break; + default: + goto error; + } break; } + error: default: { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str); @@ -6719,49 +6750,45 @@ Create_func_begin_ts::create_native(THD *thd, LEX_STRING name, } return func; -} +}; -class Create_func_commit_ts : public Create_native_func +template <class Item_func_vtq_trx_seesX> +class Create_func_vtq_trx_sees : public Create_native_func { public: - virtual Item *create_native(THD *thd, LEX_STRING name, List<Item> *item_list); - - static Create_func_commit_ts s_singleton; - -protected: - Create_func_commit_ts() {} - virtual ~Create_func_commit_ts() {} -}; - -Create_func_commit_ts Create_func_commit_ts::s_singleton; + virtual Item *create_native(THD *thd, LEX_STRING name, List<Item> *item_list) + { + Item *func= NULL; + int arg_count= 0; -Item* -Create_func_commit_ts::create_native(THD *thd, LEX_STRING name, - List<Item> *item_list) -{ - Item *func= NULL; - int arg_count= 0; + if (item_list != NULL) + arg_count= item_list->elements; - if (item_list != NULL) - arg_count= item_list->elements; + switch (arg_count) { + case 2: + { + Item *param_1= item_list->pop(); + Item *param_2= item_list->pop(); + func= new (thd->mem_root) Item_func_vtq_trx_seesX(thd, param_1, param_2); + break; + } + default: + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str); + break; + } - switch (arg_count) { - case 1: - { - Item *param_1= item_list->pop(); - func= new (thd->mem_root) Item_func_vtq_ts(thd, param_1, VTQ_COMMIT_TS); - break; - } - default: - { - my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str); - break; - } + return func; } - return func; -} + static Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX> s_singleton; + +protected: + Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX>() {} + virtual ~Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX>() {} +}; +template<class X> +Create_func_vtq_trx_sees<X> Create_func_vtq_trx_sees<X>::s_singleton; struct Native_func_registry @@ -6804,7 +6831,6 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)}, { { C_STRING_WITH_LEN("ATAN") }, BUILDER(Create_func_atan)}, { { C_STRING_WITH_LEN("ATAN2") }, BUILDER(Create_func_atan)}, - { { C_STRING_WITH_LEN("BEGIN_TS") }, BUILDER(Create_func_begin_ts)}, { { C_STRING_WITH_LEN("BENCHMARK") }, BUILDER(Create_func_benchmark)}, { { C_STRING_WITH_LEN("BIN") }, BUILDER(Create_func_bin)}, { { C_STRING_WITH_LEN("BINLOG_GTID_POS") }, BUILDER(Create_func_binlog_gtid_pos)}, @@ -6822,7 +6848,6 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("COLUMN_EXISTS") }, BUILDER(Create_func_dyncol_exists)}, { { C_STRING_WITH_LEN("COLUMN_LIST") }, BUILDER(Create_func_dyncol_list)}, { { C_STRING_WITH_LEN("COLUMN_JSON") }, BUILDER(Create_func_dyncol_json)}, - { { C_STRING_WITH_LEN("COMMIT_TS") }, BUILDER(Create_func_commit_ts)}, { { C_STRING_WITH_LEN("COMPRESS") }, BUILDER(Create_func_compress)}, { { C_STRING_WITH_LEN("CONCAT") }, BUILDER(Create_func_concat)}, { { C_STRING_WITH_LEN("CONCAT_WS") }, BUILDER(Create_func_concat_ws)}, @@ -7121,6 +7146,13 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("UUID") }, BUILDER(Create_func_uuid)}, { { C_STRING_WITH_LEN("UUID_SHORT") }, BUILDER(Create_func_uuid_short)}, { { C_STRING_WITH_LEN("VERSION") }, BUILDER(Create_func_version)}, + { { C_STRING_WITH_LEN("VTQ_BEGIN_TS") }, BUILDER(Create_func_vtq<VTQ_BEGIN_TS>)}, + { { C_STRING_WITH_LEN("VTQ_COMMIT_ID") }, BUILDER(Create_func_vtq<VTQ_COMMIT_ID>)}, + { { C_STRING_WITH_LEN("VTQ_COMMIT_TS") }, BUILDER(Create_func_vtq<VTQ_COMMIT_TS>)}, + { { C_STRING_WITH_LEN("VTQ_ISO_LEVEL") }, BUILDER(Create_func_vtq<VTQ_ISO_LEVEL>)}, + { { C_STRING_WITH_LEN("VTQ_TRX_ID") }, BUILDER(Create_func_vtq<VTQ_TRX_ID>)}, + { { C_STRING_WITH_LEN("VTQ_TRX_SEES") }, BUILDER(Create_func_vtq_trx_sees<Item_func_vtq_trx_sees>)}, + { { C_STRING_WITH_LEN("VTQ_TRX_SEES_EQ") }, BUILDER(Create_func_vtq_trx_sees<Item_func_vtq_trx_sees_eq>)}, { { C_STRING_WITH_LEN("WEEKDAY") }, BUILDER(Create_func_weekday)}, { { C_STRING_WITH_LEN("WEEKOFYEAR") }, BUILDER(Create_func_weekofyear)}, { { C_STRING_WITH_LEN("WITHIN") }, GEOM_BUILDER(Create_func_within)}, diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 3ceb87246ce..1f9d1076060 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -3278,10 +3278,9 @@ Item_func_vtq_ts::Item_func_vtq_ts( THD *thd, Item* a, vtq_field_t _vtq_field, - handlerton* _hton) : - Item_datetimefunc(thd, a), - vtq_field(_vtq_field), - hton(_hton) + handlerton* hton) : + VTQ_common<Item_datetimefunc>(thd, a, hton), + vtq_field(_vtq_field) { decimals= 6; null_value= true; @@ -3292,33 +3291,24 @@ Item_func_vtq_ts::Item_func_vtq_ts( THD *thd, Item* a, vtq_field_t _vtq_field) : - Item_datetimefunc(thd, a), - vtq_field(_vtq_field), - hton(NULL) + VTQ_common<Item_datetimefunc>(thd, a), + vtq_field(_vtq_field) { decimals= 6; null_value= true; DBUG_ASSERT(arg_count == 1 && args[0]); } -bool Item_func_vtq_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date) +template <class Item_func_X> +void +VTQ_common<Item_func_X>::init_hton() { - THD *thd= current_thd; // can it differ from constructor's? - DBUG_ASSERT(thd); - ulonglong trx_id= args[0]->val_uint(); - if (trx_id == ULONGLONG_MAX) - { - null_value= false; - thd->variables.time_zone->gmt_sec_to_TIME(res, TIMESTAMP_MAX_VALUE); - return false; - } - if (!hton) { - if (args[0]->type() == Item::FIELD_ITEM) + if (Item_func_X::args[0]->type() == Item::FIELD_ITEM) { Item_field *f= - static_cast<Item_field *>(args[0]); + static_cast<Item_field *>(Item_func_X::args[0]); DBUG_ASSERT( f->field && f->field->table && @@ -3333,11 +3323,201 @@ bool Item_func_vtq_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date) DBUG_ASSERT(hton); } } +} + +bool +Item_func_vtq_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date) +{ + THD *thd= current_thd; // can it differ from constructor's? + DBUG_ASSERT(thd); + ulonglong trx_id= args[0]->val_uint(); + if (trx_id == ULONGLONG_MAX) + { + null_value= false; + thd->variables.time_zone->gmt_sec_to_TIME(res, TIMESTAMP_MAX_VALUE); + return false; + } + + init_hton(); if (!hton) return true; - null_value= !hton->vers_get_vtq_ts(thd, res, trx_id, vtq_field); + null_value= !hton->vers_query_trx_id(thd, res, trx_id, vtq_field); return false; } + + +Item_func_vtq_id::Item_func_vtq_id( + THD *thd, + Item* a, + vtq_field_t _vtq_field, + bool _backwards) : + VTQ_common<Item_int_func>(thd, a), + vtq_field(_vtq_field), + backwards(_backwards) +{ + memset(&cached_result, 0, sizeof(cached_result)); + decimals= 0; + unsigned_flag= 1; + null_value= true; + DBUG_ASSERT(arg_count == 1 && args[0]); +} + +Item_func_vtq_id::Item_func_vtq_id( + THD *thd, + Item* a, + Item* b, + vtq_field_t _vtq_field) : + VTQ_common<Item_int_func>(thd, a, b), + vtq_field(_vtq_field), + backwards(false) +{ + memset(&cached_result, 0, sizeof(cached_result)); + decimals= 0; + unsigned_flag= 1; + null_value= true; + DBUG_ASSERT(arg_count == 2 && args[0] && args[1]); +} + +longlong +Item_func_vtq_id::get_by_trx_id(ulonglong trx_id) +{ + ulonglong res; + THD *thd= current_thd; // can it differ from constructor's? + DBUG_ASSERT(thd); + + if (trx_id == ULONGLONG_MAX) + { + null_value= true; + return 0; + } + + null_value= !hton->vers_query_trx_id(thd, &res, trx_id, vtq_field); + return res; +} + +longlong +Item_func_vtq_id::get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards) +{ + THD *thd= current_thd; // can it differ from constructor's? + DBUG_ASSERT(thd); + + null_value= !hton->vers_query_commit_ts(thd, &cached_result, commit_ts, VTQ_ALL, backwards); + if (null_value) + { + return 0; + } + + switch (vtq_field) + { + case VTQ_COMMIT_ID: + return cached_result.commit_id; + case VTQ_ISO_LEVEL: + return cached_result.iso_level; + case VTQ_TRX_ID: + return cached_result.trx_id; + default: + DBUG_ASSERT(0); + null_value= true; + } + + return 0; +} + +longlong +Item_func_vtq_id::val_int() +{ + init_hton(); + + if (!hton) + { + null_value= true; + return 0; + } + + if (args[0]->is_null()) + { + if (arg_count < 2 || vtq_field == VTQ_TRX_ID) + { + null_value= true; + return 0; + } + return get_by_trx_id(args[1]->val_uint()); + } + else + { + MYSQL_TIME commit_ts; + if (args[0]->get_date(&commit_ts, 0)) + { + null_value= true; + return 0; + } + if (arg_count > 1) + { + backwards= args[1]->val_bool(); + DBUG_ASSERT(arg_count == 2); + } + return get_by_commit_ts(commit_ts, backwards); + } +} + +Item_func_vtq_trx_sees::Item_func_vtq_trx_sees( + THD *thd, + Item* a, + Item* b) : + VTQ_common<Item_bool_func>(thd, a, b), + accept_eq(false) +{ + null_value= true; + DBUG_ASSERT(arg_count == 2 && args[0] && args[1]); +} + +longlong +Item_func_vtq_trx_sees::val_int() +{ + THD *thd= current_thd; + DBUG_ASSERT(thd); + + init_hton(); + + if (!hton) + { + null_value= true; + return 0; + } + + ulonglong trx_id1, trx_id0; + ulonglong commit_id1= 0; + ulonglong commit_id0= 0; + uchar iso_level1= 0; + + DBUG_ASSERT(arg_count > 1); + trx_id1= args[0]->val_uint(); + trx_id0= args[1]->val_uint(); + + vtq_record_t *cached= args[0]->vtq_cached_result(); + if (cached && cached->commit_id) + { + commit_id1= cached->commit_id; + iso_level1= cached->iso_level; + } + + cached= args[1]->vtq_cached_result(); + if (cached && cached->commit_id) + { + commit_id0= cached->commit_id; + } + + if (accept_eq && trx_id1 && trx_id1 == trx_id0) + { + null_value= false; + return true; + } + + bool result= false; + null_value= !hton->vers_trx_sees(thd, result, trx_id1, trx_id0, commit_id1, iso_level1, commit_id0); + return result; +} + diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index a8281124b38..4d7935b8506 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -1288,10 +1288,28 @@ public: #include "vtq.h" -class Item_func_vtq_ts :public Item_datetimefunc +template <class Item_func_X> +class VTQ_common : public Item_func_X { - vtq_field_t vtq_field; +protected: handlerton *hton; + void init_hton(); +public: + VTQ_common(THD *thd, Item* a) : + Item_func_X(thd, a), + hton(NULL) {} + VTQ_common(THD *thd, Item* a, Item* b) : + Item_func_X(thd, a, b), + hton(NULL) {} + VTQ_common(THD *thd, Item* a, handlerton* _hton) : + Item_func_X(thd, a), + hton(_hton) {} +}; + +class Item_func_vtq_ts : + public VTQ_common<Item_datetimefunc> +{ + vtq_field_t vtq_field; public: Item_func_vtq_ts(THD *thd, Item* a, vtq_field_t _vtq_field, handlerton *hton); Item_func_vtq_ts(THD *thd, Item* a, vtq_field_t _vtq_field); @@ -1299,13 +1317,88 @@ public: { if (vtq_field == VTQ_BEGIN_TS) { - return "begin_ts"; + return "vtq_begin_ts"; } - return "commit_ts"; + return "vtq_commit_ts"; } bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_vtq_ts>(thd, mem_root, this); } }; +class Item_func_vtq_id : + public VTQ_common<Item_int_func> +{ + vtq_field_t vtq_field; + vtq_record_t cached_result; + bool backwards; + + longlong get_by_trx_id(ulonglong trx_id); + longlong get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards); + +public: + Item_func_vtq_id(THD *thd, Item* a, vtq_field_t _vtq_field, bool _backwards= false); + Item_func_vtq_id(THD *thd, Item* a, Item* b, vtq_field_t _vtq_field); + + vtq_record_t *vtq_cached_result() { return &cached_result; } + + const char *func_name() const + { + switch (vtq_field) + { + case VTQ_TRX_ID: + return "vtq_trx_id"; + case VTQ_COMMIT_ID: + return "vtq_commit_id"; + case VTQ_ISO_LEVEL: + return "vtq_iso_level"; + default: + DBUG_ASSERT(0); + } + return NULL; + } + + void fix_length_and_dec() + { + Item_int_func::fix_length_and_dec(); + max_length= 20; + } + + longlong val_int(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_vtq_id>(thd, mem_root, this); } +}; + +class Item_func_vtq_trx_sees : + public VTQ_common<Item_bool_func> +{ +protected: + bool accept_eq; + +public: + Item_func_vtq_trx_sees(THD *thd, Item* a, Item* b); + const char *func_name() const + { + return "vtq_trx_sees"; + } + longlong val_int(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_vtq_trx_sees>(thd, mem_root, this); } +}; + +class Item_func_vtq_trx_sees_eq : + public Item_func_vtq_trx_sees +{ +public: + Item_func_vtq_trx_sees_eq(THD *thd, Item* a, Item* b) : + Item_func_vtq_trx_sees(thd, a, b) + { + accept_eq= true; + } + const char *func_name() const + { + return "vtq_trx_sees_eq"; + } +}; + #endif /* ITEM_TIMEFUNC_INCLUDED */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 81ff9b7246a..4c2ba3caa02 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -671,6 +671,7 @@ static int setup_for_system_time(THD *thd, TABLE_LIST *tables, COND **where_expr, SELECT_LEX *slex) { DBUG_ENTER("setup_for_system_time"); +#define newx new (thd->mem_root) TABLE_LIST *table; int versioned_tables= 0; @@ -741,6 +742,8 @@ setup_for_system_time(THD *thd, TABLE_LIST *tables, COND **where_expr, SELECT_LE } } + const static bool vers_simple_select= false; + for (table= tables; table; table= table->next_local) { if (table->table && table->table->versioned()) @@ -758,8 +761,8 @@ setup_for_system_time(THD *thd, TABLE_LIST *tables, COND **where_expr, SELECT_LE Name_resolution_context *context= slex->parent_lex->current_context(); DBUG_ASSERT(context); - Item *row_start= new (thd->mem_root) Item_field(thd, context, fstart); - Item *row_end= new (thd->mem_root) Item_field(thd, context, fend); + Item *row_start= newx Item_field(thd, context, fstart); + Item *row_end= newx Item_field(thd, context, fend); Item *row_end2= row_end; if (table->table->versioned_by_sql()) @@ -770,58 +773,108 @@ setup_for_system_time(THD *thd, TABLE_LIST *tables, COND **where_expr, SELECT_LE DBUG_RETURN(-1); } } - else if (slex->vers_conditions.unit == UNIT_TIMESTAMP) + else if (vers_simple_select && slex->vers_conditions.unit == UNIT_TIMESTAMP + && slex->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED) { DBUG_ASSERT(table->table->s && table->table->s->db_plugin); - row_start= new (thd->mem_root) Item_func_vtq_ts( + handlerton *hton= plugin_hton(table->table->s->db_plugin); + DBUG_ASSERT(hton); + row_start= newx Item_func_vtq_ts( thd, row_start, VTQ_COMMIT_TS, - plugin_hton(table->table->s->db_plugin)); - row_end= new (thd->mem_root) Item_func_vtq_ts( + // FIXME: is it needed to pass hton or it can be deduced from arg 'a'? + hton); + row_end= newx Item_func_vtq_ts( thd, row_end, VTQ_COMMIT_TS, - plugin_hton(table->table->s->db_plugin)); + hton); } Item *cond1= 0, *cond2= 0, *curr= 0; - switch (slex->vers_conditions.type) + if (table->table->versioned_by_sql() || vers_simple_select) { + switch (slex->vers_conditions.type) + { case FOR_SYSTEM_TIME_UNSPECIFIED: if (table->table->versioned_by_sql()) { MYSQL_TIME max_time; thd->variables.time_zone->gmt_sec_to_TIME(&max_time, TIMESTAMP_MAX_VALUE); - curr= new (thd->mem_root) Item_datetime_literal(thd, &max_time); - cond1= new (thd->mem_root) Item_func_eq(thd, row_end, curr); + curr= newx Item_datetime_literal(thd, &max_time); + cond1= newx Item_func_eq(thd, row_end, curr); } else { - curr= new (thd->mem_root) Item_int(thd, ULONGLONG_MAX); - cond1= new (thd->mem_root) Item_func_eq(thd, row_end2, curr); + curr= newx Item_int(thd, ULONGLONG_MAX); + cond1= newx Item_func_eq(thd, row_end2, curr); } break; case FOR_SYSTEM_TIME_AS_OF: - cond1= new (thd->mem_root) Item_func_le(thd, row_start, + cond1= newx Item_func_le(thd, row_start, slex->vers_conditions.start); - cond2= new (thd->mem_root) Item_func_gt(thd, row_end, + cond2= newx Item_func_gt(thd, row_end, slex->vers_conditions.start); break; case FOR_SYSTEM_TIME_FROM_TO: - cond1= new (thd->mem_root) Item_func_lt(thd, row_start, - slex->vers_conditions.end); - cond2= new (thd->mem_root) Item_func_ge(thd, row_end, - slex->vers_conditions.start); + cond1= newx Item_func_lt(thd, row_start, + slex->vers_conditions.end); + cond2= newx Item_func_ge(thd, row_end, + slex->vers_conditions.start); + break; + case FOR_SYSTEM_TIME_BETWEEN: + cond1= newx Item_func_le(thd, row_start, + slex->vers_conditions.end); + cond2= newx Item_func_ge(thd, row_end, + slex->vers_conditions.start); + break; + default: + DBUG_ASSERT(0); + } + } + else + { + DBUG_ASSERT(table->table->s && table->table->s->db_plugin); + handlerton *hton= plugin_hton(table->table->s->db_plugin); + DBUG_ASSERT(hton); + + Item *trx_id0, *trx_id1; + + switch (slex->vers_conditions.type) + { + case FOR_SYSTEM_TIME_UNSPECIFIED: + curr= newx Item_int(thd, ULONGLONG_MAX); + cond1= newx Item_func_eq(thd, row_end2, curr); break; + case FOR_SYSTEM_TIME_AS_OF: + trx_id0= slex->vers_conditions.unit == UNIT_TIMESTAMP ? + newx Item_func_vtq_id(thd, slex->vers_conditions.start, VTQ_TRX_ID) : + slex->vers_conditions.start; + cond1= newx Item_func_vtq_trx_sees_eq(thd, trx_id0, row_start); + cond2= newx Item_func_vtq_trx_sees(thd, row_end, trx_id0); + break; + case FOR_SYSTEM_TIME_FROM_TO: case FOR_SYSTEM_TIME_BETWEEN: - cond1= new (thd->mem_root) Item_func_le(thd, row_start, - slex->vers_conditions.end); - cond2= new (thd->mem_root) Item_func_ge(thd, row_end, - slex->vers_conditions.start); + if (slex->vers_conditions.unit == UNIT_TIMESTAMP) + { + trx_id0= newx Item_func_vtq_id(thd, slex->vers_conditions.start, VTQ_TRX_ID, true); + trx_id1= newx Item_func_vtq_id(thd, slex->vers_conditions.end, VTQ_TRX_ID, false); + } + else + { + trx_id0= slex->vers_conditions.start; + trx_id1= slex->vers_conditions.end; + } + + cond1= slex->vers_conditions.type == FOR_SYSTEM_TIME_FROM_TO ? + newx Item_func_vtq_trx_sees(thd, trx_id1, row_start) : + newx Item_func_vtq_trx_sees_eq(thd, trx_id1, row_start); + cond2= newx Item_func_vtq_trx_sees_eq(thd, row_end, trx_id0); break; default: DBUG_ASSERT(0); + } } if (cond1) @@ -848,6 +901,7 @@ setup_for_system_time(THD *thd, TABLE_LIST *tables, COND **where_expr, SELECT_LE } DBUG_RETURN(0); +#undef newx } /***************************************************************************** diff --git a/sql/vtq.h b/sql/vtq.h index 3a235352853..68c01990b04 100755 --- a/sql/vtq.h +++ b/sql/vtq.h @@ -17,9 +17,21 @@ enum vtq_field_t { - VTQ_BEGIN_TS = 0, - VTQ_COMMIT_TS + VTQ_ALL = 0, + VTQ_TRX_ID, + VTQ_COMMIT_ID, + VTQ_BEGIN_TS, + VTQ_COMMIT_TS, + VTQ_ISO_LEVEL }; -#endif /* VTQ_INCLUDED */ +struct vtq_record_t +{ + ulonglong trx_id; + ulonglong commit_id; + timeval begin_ts; + timeval commit_ts; + uchar iso_level; +}; +#endif /* VTQ_INCLUDED */ |