Skip to content

Commit 88ccf75

Browse files
authored
SQL: pruning, derived, view fixes [fixes #244]
1 parent c2a70c8 commit 88ccf75

File tree

14 files changed

+97
-83
lines changed

14 files changed

+97
-83
lines changed

mysql-test/suite/versioning/r/partition.result

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ x A B
175175
execute select_pn;
176176
x C D
177177
1 1 1
178+
explain partitions select * from t1;
179+
id select_type table partitions type possible_keys key key_len ref rows Extra
180+
1 SIMPLE t1 pn system NULL NULL NULL NULL 1
178181
set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
179182
prepare stmt from @str;
180183
execute stmt;

mysql-test/suite/versioning/r/view.result

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ x
8585
create or replace view vt1 as select * from t1;
8686
show create view vt1;
8787
View Create View character_set_client collation_connection
88-
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x`,`t1`.`sys_trx_start` AS `sys_trx_start`,`t1`.`sys_trx_end` AS `sys_trx_end` from `t1` FOR SYSTEM_TIME ALL where `t1`.`sys_trx_end` = TIMESTAMP'2038-01-19 03:14:07.999999' latin1 latin1_swedish_ci
88+
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x`,`t1`.`sys_trx_start` AS `sys_trx_start`,`t1`.`sys_trx_end` AS `sys_trx_end` from `t1` FOR SYSTEM_TIME ALL where `t1`.`sys_trx_end` = 18446744073709551615 latin1 latin1_swedish_ci
8989
drop view vt1;
9090
drop view vt2;
9191
create view vt1 as select * from t1 for system_time all;
@@ -178,15 +178,15 @@ create or replace table t3 (x int);
178178
create or replace view vt1 as select * from t1, t2, t3;
179179
show create view vt1;
180180
View Create View character_set_client collation_connection
181-
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,`t3`.`x` AS `x`,`t1`.`sys_trx_start` AS `sys_trx_start`,`t1`.`sys_trx_end` AS `sys_trx_end` from ((`t1` FOR SYSTEM_TIME ALL join `t2` FOR SYSTEM_TIME ALL) join `t3`) where `t1`.`sys_trx_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `t2`.`sys_trx_end` = TIMESTAMP'2038-01-19 03:14:07.999999' latin1 latin1_swedish_ci
181+
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,`t3`.`x` AS `x`,`t1`.`sys_trx_start` AS `sys_trx_start`,`t1`.`sys_trx_end` AS `sys_trx_end` from ((`t1` FOR SYSTEM_TIME ALL join `t2` FOR SYSTEM_TIME ALL) join `t3`) where `t1`.`sys_trx_end` = 18446744073709551615 and `t2`.`sys_trx_end` = 18446744073709551615 latin1 latin1_swedish_ci
182182
create or replace view vt1 as select * from t3, t2, t1;
183183
show create view vt1;
184184
View Create View character_set_client collation_connection
185-
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t3`.`x` AS `x`,`t2`.`b` AS `b`,`t1`.`a` AS `a`,`t2`.`sys_trx_start` AS `sys_trx_start`,`t2`.`sys_trx_end` AS `sys_trx_end` from ((`t3` join `t2` FOR SYSTEM_TIME ALL) join `t1` FOR SYSTEM_TIME ALL) where `t2`.`sys_trx_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `t1`.`sys_trx_end` = TIMESTAMP'2038-01-19 03:14:07.999999' latin1 latin1_swedish_ci
185+
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t3`.`x` AS `x`,`t2`.`b` AS `b`,`t1`.`a` AS `a`,`t2`.`sys_trx_start` AS `sys_trx_start`,`t2`.`sys_trx_end` AS `sys_trx_end` from ((`t3` join `t2` FOR SYSTEM_TIME ALL) join `t1` FOR SYSTEM_TIME ALL) where `t2`.`sys_trx_end` = 18446744073709551615 and `t1`.`sys_trx_end` = 18446744073709551615 latin1 latin1_swedish_ci
186186
create or replace view vt1 as select a, t2.sys_trx_end as endo from t3, t1, t2;
187187
show create view vt1;
188188
View Create View character_set_client collation_connection
189-
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`sys_trx_end` AS `endo`,`t2`.`sys_trx_start` AS `sys_trx_start` from ((`t3` join `t1` FOR SYSTEM_TIME ALL) join `t2` FOR SYSTEM_TIME ALL) where `t1`.`sys_trx_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `t2`.`sys_trx_end` = TIMESTAMP'2038-01-19 03:14:07.999999' latin1 latin1_swedish_ci
189+
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`sys_trx_end` AS `endo`,`t2`.`sys_trx_start` AS `sys_trx_start` from ((`t3` join `t1` FOR SYSTEM_TIME ALL) join `t2` FOR SYSTEM_TIME ALL) where `t1`.`sys_trx_end` = 18446744073709551615 and `t2`.`sys_trx_end` = 18446744073709551615 latin1 latin1_swedish_ci
190190
create or replace view vvt1 as select * from t1, t2, vt1;
191191
ERROR HY000: Creating VIEW `vvt1` is prohibited: versioned VIEW `vt1` in query!
192192
drop view vt1, vt12;

mysql-test/suite/versioning/t/partition.test

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ prepare select_pn from @str;
108108
execute select_p0;
109109
execute select_pn;
110110

111+
# pruning check
112+
--replace_result ALL system "Using where" ""
113+
explain partitions select * from t1;
114+
111115
set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
112116
prepare stmt from @str; execute stmt; drop prepare stmt;
113117

sql/field.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,7 @@ bool Field_num::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
19991999
}
20002000

20012001

2002-
bool Field_vers_system::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate, ulonglong trx_id)
2002+
bool Field_vers_trx_id::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate, ulonglong trx_id)
20032003
{
20042004
ASSERT_COLUMN_MARKED_FOR_READ;
20052005
DBUG_ASSERT(ltime);
@@ -10568,7 +10568,7 @@ Field *make_field(TABLE_SHARE *share,
1056810568
if (flags & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG))
1056910569
{
1057010570
return new (mem_root)
10571-
Field_vers_system(ptr, field_length, null_pos, null_bit,
10571+
Field_vers_trx_id(ptr, field_length, null_pos, null_bit,
1057210572
unireg_check, field_name,
1057310573
f_is_zerofill(pack_flag) != 0,
1057410574
f_is_dec(pack_flag) == 0);
@@ -10657,6 +10657,11 @@ Field *make_field(TABLE_SHARE *share,
1065710657
return 0;
1065810658
}
1065910659

10660+
bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) const
10661+
{
10662+
return item->type() == Item::DATE_ITEM;
10663+
}
10664+
1066010665

1066110666
/** Create a field suitable for create of table. */
1066210667

sql/field.h

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,11 @@ class Field: public Value_source
14071407
return flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG);
14081408
}
14091409

1410+
virtual bool vers_trx_id() const
1411+
{
1412+
return false;
1413+
}
1414+
14101415
/*
14111416
Validate a non-null field value stored in the given record
14121417
according to the current thread settings, e.g. sql_mode.
@@ -2130,11 +2135,11 @@ class Field_longlong :public Field_num {
21302135
};
21312136

21322137

2133-
class Field_vers_system :public Field_longlong {
2138+
class Field_vers_trx_id :public Field_longlong {
21342139
MYSQL_TIME cache;
21352140
ulonglong cached;
21362141
public:
2137-
Field_vers_system(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
2142+
Field_vers_trx_id(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
21382143
uchar null_bit_arg,
21392144
enum utype unireg_check_arg, const char *field_name_arg,
21402145
bool zero_arg, bool unsigned_arg)
@@ -2143,13 +2148,37 @@ class Field_vers_system :public Field_longlong {
21432148
cached(0)
21442149
{}
21452150
enum_field_types real_type() const { return MYSQL_TYPE_LONGLONG; }
2146-
enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
2151+
enum_field_types type() const { return MYSQL_TYPE_LONGLONG;}
21472152
uint size_of() const { return sizeof(*this); }
21482153
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate, ulonglong trx_id);
21492154
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
21502155
{
21512156
return get_date(ltime, fuzzydate, (ulonglong) val_int());
21522157
}
2158+
bool test_if_equality_guarantees_uniqueness(const Item *item) const;
2159+
bool can_optimize_keypart_ref(const Item_bool_func *cond,
2160+
const Item *item) const
2161+
{
2162+
return true;
2163+
}
2164+
2165+
bool can_optimize_group_min_max(const Item_bool_func *cond,
2166+
const Item *const_item) const
2167+
{
2168+
return true;
2169+
}
2170+
bool can_optimize_range(const Item_bool_func *cond,
2171+
const Item *item,
2172+
bool is_eq_func) const
2173+
{
2174+
return true;
2175+
}
2176+
/* cmp_type() cannot be TIME_RESULT, because we want to compare this field against
2177+
integers. But in all other cases we treat it as TIME_RESULT! */
2178+
bool vers_trx_id() const
2179+
{
2180+
return true;
2181+
}
21532182
};
21542183

21552184

sql/item.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6328,7 +6328,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table,
63286328
if (field_flags() & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG))
63296329
{
63306330
field= new (mem_root)
6331-
Field_vers_system((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
6331+
Field_vers_trx_id((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
63326332
name, 0, unsigned_flag);
63336333
}
63346334
else
@@ -6671,7 +6671,7 @@ int Item_int::save_in_field(Field *field, bool no_conversions)
66716671

66726672
Item *Item_int::clone_item(THD *thd)
66736673
{
6674-
return new (thd->mem_root) Item_int(thd, name, value, max_length);
6674+
return new (thd->mem_root) Item_int(thd, name, value, max_length, unsigned_flag);
66756675
}
66766676

66776677

@@ -10775,6 +10775,12 @@ Item *Item_field::vers_optimized_fields_transformer(THD *thd, uchar *)
1077510775
return this;
1077610776
}
1077710777

10778+
bool Item_field::vers_trx_id() const
10779+
{
10780+
DBUG_ASSERT(field);
10781+
return field->vers_trx_id();
10782+
}
10783+
1077810784
void Item::register_in(THD *thd)
1077910785
{
1078010786
next= thd->free_list;

sql/item.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,8 @@ class Item: public Value_source,
13371337
{
13381338
if (other->cmp_type() == TIME_RESULT)
13391339
return other->field_type();
1340+
if (vers_trx_id() || other->vers_trx_id())
1341+
return MYSQL_TYPE_DATETIME;
13401342
DBUG_ASSERT(0); // Two non-temporal data types, we should not get to here
13411343
return MYSQL_TYPE_DATETIME;
13421344
}
@@ -1649,6 +1651,8 @@ class Item: public Value_source,
16491651

16501652
virtual Item *vers_optimized_fields_transformer(THD *thd, uchar *)
16511653
{ return this; }
1654+
virtual bool vers_trx_id() const
1655+
{ return false; }
16521656
virtual Item *neg_transformer(THD *thd) { return NULL; }
16531657
virtual Item *update_value_transformer(THD *thd, uchar *select_arg)
16541658
{ return this; }
@@ -2751,6 +2755,7 @@ class Item_field :public Item_ident
27512755
Item_field *field_for_view_update() { return this; }
27522756
int fix_outer_field(THD *thd, Field **field, Item **reference);
27532757
virtual Item *vers_optimized_fields_transformer(THD *thd, uchar *);
2758+
virtual bool vers_trx_id() const;
27542759
virtual Item *update_value_transformer(THD *thd, uchar *select_arg);
27552760
Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
27562761
Item *derived_field_transformer_for_where(THD *thd, uchar *arg);
@@ -3188,6 +3193,9 @@ class Item_int :public Item_num
31883193
Item_int(THD *thd, const char *str_arg,longlong i,uint length):
31893194
Item_num(thd), value(i)
31903195
{ max_length=length; name=(char*) str_arg; fixed= 1; }
3196+
Item_int(THD *thd, const char *str_arg,longlong i,uint length, bool flag):
3197+
Item_num(thd), value(i)
3198+
{ max_length=length; name=(char*) str_arg; fixed= 1; unsigned_flag= flag; }
31913199
Item_int(THD *thd, const char *str_arg, uint length=64);
31923200
enum Type type() const { return INT_ITEM; }
31933201
enum Item_result result_type () const { return INT_RESULT; }

sql/item_cmpfunc.cc

Lines changed: 4 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,12 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const char *funcname,
127127
many cases.
128128
*/
129129
set_handler(items[0]->type_handler()->type_handler_for_comparison());
130+
m_vers_trx_id= items[0]->vers_trx_id();
130131
for (uint i= 1 ; i < nitems ; i++)
131132
{
132133
unsigned_count+= items[i]->unsigned_flag;
134+
if (!m_vers_trx_id)
135+
m_vers_trx_id= items[i]->vers_trx_id();
133136
if (aggregate_for_comparison(items[i]->type_handler()->
134137
type_handler_for_comparison()))
135138
{
@@ -421,7 +424,7 @@ void Item_func::convert_const_compared_to_int_field(THD *thd)
421424
args[field= 1]->real_item()->type() == FIELD_ITEM)
422425
{
423426
Item_field *field_item= (Item_field*) (args[field]->real_item());
424-
if ((field_item->field_type() == MYSQL_TYPE_LONGLONG ||
427+
if (((field_item->field_type() == MYSQL_TYPE_LONGLONG && !field_item->vers_trx_id()) ||
425428
field_item->field_type() == MYSQL_TYPE_YEAR))
426429
convert_const_to_int(thd, field_item, &args[!field]);
427430
}
@@ -5218,59 +5221,6 @@ bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str,
52185221
return FALSE;
52195222
}
52205223

5221-
bool Item_bool_func2::fix_fields(THD* thd, Item** ref)
5222-
{
5223-
if (Item_bool_func::fix_fields(thd, ref))
5224-
return true;
5225-
5226-
// System Versioning: convert TRX_ID to DATETIME
5227-
Item *trx_id= NULL;
5228-
int arg_idx= -1;
5229-
Field_vers_system *sys_field= NULL;
5230-
DBUG_ASSERT(arg_count == 2);
5231-
// find trx_id and sys_field
5232-
for (int i= 0; i < 2; ++i)
5233-
{
5234-
Item *arg= args[i];
5235-
if (arg->result_type() != INT_RESULT)
5236-
continue;
5237-
DBUG_ASSERT(arg);
5238-
if (arg->type() == Item::FIELD_ITEM)
5239-
{
5240-
Field *f= static_cast<Item_field *>(arg)->field;
5241-
DBUG_ASSERT(f);
5242-
if (f->vers_sys_field() && f->real_type() == MYSQL_TYPE_LONGLONG)
5243-
{
5244-
if (sys_field)
5245-
return false;
5246-
sys_field= static_cast<Field_vers_system *>(f);
5247-
continue;
5248-
}
5249-
}
5250-
if (trx_id)
5251-
return false;
5252-
trx_id= arg;
5253-
arg_idx= i;
5254-
}
5255-
if (!trx_id || !sys_field)
5256-
return false;
5257-
MYSQL_TIME ltime;
5258-
ulonglong trx_id_val= (ulonglong) trx_id->val_int();
5259-
if (sys_field->get_date(&ltime, false, trx_id_val))
5260-
{
5261-
my_error(ER_VERS_NO_TRX_ID, MYF(0), trx_id_val);
5262-
return true;
5263-
}
5264-
Query_arena_stmt on_stmt_arena(thd);
5265-
Item *datetime= new (thd->mem_root) Item_datetime_literal(thd, &ltime, 6);
5266-
if (!datetime)
5267-
return true;
5268-
DBUG_ASSERT(arg_idx > -1);
5269-
args[arg_idx]= datetime;
5270-
return false;
5271-
}
5272-
5273-
52745224
bool Item_func_like::fix_fields(THD *thd, Item **ref)
52755225
{
52765226
DBUG_ASSERT(fixed == 0);

sql/item_cmpfunc.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,6 @@ class Item_bool_func2 :public Item_bool_func
410410
ftree= Item_func::get_mm_tree(param, cond_ptr);
411411
DBUG_RETURN(ftree);
412412
}
413-
bool fix_fields(THD *thd, Item **ref);
414413
};
415414

416415

sql/sql_select.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
918918
switch (vers_conditions.type)
919919
{
920920
case FOR_SYSTEM_TIME_UNSPECIFIED:
921-
if (!tmp_from_ib)
921+
if (t->vers_start_field()->real_type() != MYSQL_TYPE_LONGLONG)
922922
{
923923
MYSQL_TIME max_time;
924924
thd->variables.time_zone->gmt_sec_to_TIME(&max_time, TIMESTAMP_MAX_VALUE);
@@ -25555,6 +25555,11 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
2555525555
}
2555625556
#endif /* WITH_PARTITION_STORAGE_ENGINE */
2555725557
}
25558+
if (table && table->versioned())
25559+
{
25560+
// versioning conditions are already unwrapped to WHERE clause
25561+
str->append(" FOR SYSTEM_TIME ALL");
25562+
}
2555825563
if (my_strcasecmp(table_alias_charset, cmp_name, alias))
2555925564
{
2556025565
char t_alias_buff[MAX_ALIAS_NAME];
@@ -25573,11 +25578,6 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
2557325578

2557425579
append_identifier(thd, str, t_alias, strlen(t_alias));
2557525580
}
25576-
if (table && table->versioned())
25577-
{
25578-
// versioning conditions are already unwrapped to WHERE clause
25579-
str->append(" FOR SYSTEM_TIME ALL");
25580-
}
2558125581

2558225582
if (index_hints)
2558325583
{

0 commit comments

Comments
 (0)