From 73f655d57654e9ef8cd40154a0482170c10ad14c Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 25 Oct 2017 21:21:40 +0300 Subject: [PATCH] SQL: VIEW without VERS_COMMIT_TS + CTE fix [fixes #295] --- mysql-test/suite/versioning/t/view.opt | 1 - sql/item.h | 33 +++++++++++++--- sql/sql_select.cc | 53 +++----------------------- sql/sql_type.cc | 14 +++++++ sql/sql_type.h | 12 ++++++ 5 files changed, 59 insertions(+), 54 deletions(-) diff --git a/mysql-test/suite/versioning/t/view.opt b/mysql-test/suite/versioning/t/view.opt index 9baff80804d..c1a585b67eb 100644 --- a/mysql-test/suite/versioning/t/view.opt +++ b/mysql-test/suite/versioning/t/view.opt @@ -1,2 +1 @@ --versioning-hide=implicit ---plugin-load=versioning diff --git a/sql/item.h b/sql/item.h index 37cda6b8d44..70f2a65a587 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4587,6 +4587,12 @@ public: return 0; return cleanup_processor(arg); } + virtual bool vers_trx_id() const + { + DBUG_ASSERT(ref); + DBUG_ASSERT(*ref); + return (*ref)->vers_trx_id(); + } }; @@ -6047,8 +6053,10 @@ private: if (item->real_type() == Item::FIELD_ITEM) { Item_field *item_field= (Item_field *)item->real_item(); - flags|= (item_field->field->flags & + m_flags|= (item_field->field->flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG)); + // TODO: additional field flag? + m_vers_trx_id= item_field->field->vers_trx_id(); } } public: @@ -6056,7 +6064,8 @@ public: :Item(thd, item), Type_handler_hybrid_field_type(item->real_type_handler()), enum_set_typelib(0), - flags(0) + m_flags(0), + m_vers_trx_id(false) { DBUG_ASSERT(item->fixed); maybe_null= item->maybe_null; @@ -6071,7 +6080,8 @@ public: Type_handler_hybrid_field_type(handler), Type_geometry_attributes(handler, attr), enum_set_typelib(attr->get_typelib()), - flags(0) + m_flags(0), + m_vers_trx_id(false) { name= item->name; Type_std_attributes::set(*attr); @@ -6081,11 +6091,15 @@ public: const Type_handler *type_handler() const { - const Type_handler *handler= Type_handler_hybrid_field_type::type_handler(); + const Type_handler *handler= m_vers_trx_id ? + &type_handler_vers_trx_id : + Type_handler_hybrid_field_type::type_handler(); return handler->type_handler_for_item_field(); } const Type_handler *real_type_handler() const { + if (m_vers_trx_id) + return &type_handler_vers_trx_id; return Type_handler_hybrid_field_type::type_handler(); } @@ -6111,10 +6125,17 @@ public: } Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } - uint flags; +private: + uint m_flags; + bool m_vers_trx_id; +public: uint32 field_flags() const { - return flags; + return m_flags; + } + virtual bool vers_trx_id() const + { + return m_vers_trx_id; } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bd80ffd061e..2885642a2bb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -861,52 +861,11 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, if (vers_conditions) { vers_conditions.resolve_units(timestamps_only); - if (timestamps_only) + if (timestamps_only && (vers_conditions.unit_start == UNIT_TRX_ID || + vers_conditions.unit_end == UNIT_TRX_ID)) { - if (vers_conditions.unit_start == UNIT_TRX_ID || vers_conditions.unit_end == UNIT_TRX_ID) - { - my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), table->table_name); - DBUG_RETURN(-1); - } - } - else if (thd->variables.vers_innodb_algorithm_simple) - { - DBUG_ASSERT(table->table->s && table->table->s->db_plugin); - handlerton *hton= plugin_hton(table->table->s->db_plugin); - DBUG_ASSERT(hton); - bool convert_start= false; - bool convert_end= false; - switch (vers_conditions.type) - { - case FOR_SYSTEM_TIME_AS_OF: - if (vers_conditions.unit_start == UNIT_TIMESTAMP) - convert_start= convert_end= true; - break; - case FOR_SYSTEM_TIME_BEFORE: - if (vers_conditions.unit_start == UNIT_TIMESTAMP) - convert_end= true; - break; - case FOR_SYSTEM_TIME_FROM_TO: - case FOR_SYSTEM_TIME_BETWEEN: - if (vers_conditions.unit_start == UNIT_TIMESTAMP) - convert_end= true; - if (vers_conditions.unit_end == UNIT_TIMESTAMP) - convert_start= true; - default: - break; - } - if (convert_start) - row_start= newx Item_func_vtq_ts( - thd, - hton, - row_start, - VTQ_COMMIT_TS); - if (convert_end) - row_end= newx Item_func_vtq_ts( - thd, - hton, - row_end, - VTQ_COMMIT_TS); + my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), table->table_name); + DBUG_RETURN(-1); } } @@ -17481,9 +17440,9 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List &fields, if (type == Item::TYPE_HOLDER) { Item_type_holder *ith= (Item_type_holder*)item; - if (ith->flags & VERS_SYS_START_FLAG) + if (ith->field_flags() & VERS_SYS_START_FLAG) sys_trx_start= new_field; - else if (ith->flags & VERS_SYS_END_FLAG) + else if (ith->field_flags() & VERS_SYS_END_FLAG) sys_trx_end= new_field; } if (type == Item::SUM_FUNC_ITEM) diff --git a/sql/sql_type.cc b/sql/sql_type.cc index b23ee1b314d..d1e4641253c 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -32,6 +32,7 @@ Type_handler_long type_handler_long; Type_handler_int24 type_handler_int24; Type_handler_longlong type_handler_longlong; Type_handler_longlong type_handler_ulonglong; // Only used for CAST() for now +Type_handler_vers_trx_id type_handler_vers_trx_id; Type_handler_float type_handler_float; Type_handler_double type_handler_double; Type_handler_bit type_handler_bit; @@ -2065,6 +2066,19 @@ Field *Type_handler_longlong::make_table_field(const LEX_CSTRING *name, } +Field *Type_handler_vers_trx_id::make_table_field(const LEX_CSTRING *name, + const Record_addr &addr, + const Type_all_attributes &attr, + TABLE *table) const +{ + return new (table->in_use->mem_root) + Field_vers_trx_id(addr.ptr, attr.max_char_length(), + addr.null_ptr, addr.null_bit, + Field::NONE, name, + 0/*zerofill*/, attr.unsigned_flag); +} + + Field *Type_handler_float::make_table_field(const LEX_CSTRING *name, const Record_addr &addr, const Type_all_attributes &attr, diff --git a/sql/sql_type.h b/sql/sql_type.h index 1310666e667..f9a4ae2a96b 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -1875,6 +1875,17 @@ public: }; +class Type_handler_vers_trx_id: public Type_handler_longlong +{ +public: + virtual ~Type_handler_vers_trx_id() {} + Field *make_table_field(const LEX_CSTRING *name, + const Record_addr &addr, + const Type_all_attributes &attr, + TABLE *table) const; +}; + + class Type_handler_int24: public Type_handler_general_purpose_int { static const Name m_name_mediumint; @@ -2905,6 +2916,7 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_int24 type_handler_int24; extern MYSQL_PLUGIN_IMPORT Type_handler_long type_handler_long; extern MYSQL_PLUGIN_IMPORT Type_handler_longlong type_handler_longlong; extern MYSQL_PLUGIN_IMPORT Type_handler_longlong type_handler_ulonglong; +extern MYSQL_PLUGIN_IMPORT Type_handler_vers_trx_id type_handler_vers_trx_id; extern MYSQL_PLUGIN_IMPORT Type_handler_newdecimal type_handler_newdecimal; extern MYSQL_PLUGIN_IMPORT Type_handler_olddecimal type_handler_olddecimal;