summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.h4
-rw-r--r--sql/item.h13
-rw-r--r--sql/item_create.cc122
-rw-r--r--sql/item_timefunc.cc222
-rw-r--r--sql/item_timefunc.h101
-rw-r--r--sql/sql_select.cc98
-rwxr-xr-xsql/vtq.h18
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 */