Skip to content

Commit

Permalink
SQL: optimized fields fix for NOT NULL [fixes #226]
Browse files Browse the repository at this point in the history
  • Loading branch information
kevgs committed Jul 13, 2017
1 parent 91c8b43 commit 909867d
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 21 deletions.
53 changes: 52 additions & 1 deletion mysql-test/suite/versioning/r/optimized_fields.result
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
create table t(
create table t (
a int,
b int without system versioning
) with system versioning;
Expand Down Expand Up @@ -36,12 +36,14 @@ a b
3 NULL
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
Warning 4075 Attempt to read unversioned field `b` in historical query
select * from t for system_time as of timestamp now(6) order by b desc;
a b
1 NULL
3 NULL
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
Warning 4075 Attempt to read unversioned field `b` in historical query
select * from t group by a having a=2 system_time as of timestamp now(6);
a b
Warnings:
Expand All @@ -50,6 +52,7 @@ select * from t group by b having b=2 system_time as of timestamp now(6);
a b
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
Warning 4075 Attempt to read unversioned field `b` in historical query
select a from t where b=2 system_time as of timestamp now(6);
a
Warnings:
Expand All @@ -68,8 +71,56 @@ select count(*), b from t group by b having b=NULL system_time as of timestamp n
count(*) b
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
Warning 4075 Attempt to read unversioned field `b` in historical query
select a, b from t;
a b
1 2
3 4
select count(*) from t for system_time as of timestamp now(6) group by b;
count(*)
2
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
select * from t for system_time as of timestamp now(6) group by b having b=2;
a b
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
Warning 4075 Attempt to read unversioned field `b` in historical query
select a from t for system_time as of timestamp now(6) where b=2;
a
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
select a from t for system_time as of timestamp now(6) where b=NULL;
a
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
select a from t for system_time as of timestamp now(6) where b is NULL;
a
1
3
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL;
count(*) b
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
Warning 4075 Attempt to read unversioned field `b` in historical query
create or replace table t (
a int,
b int not null without system versioning
) with system versioning;
insert into t values (1, 2), (3, 4);
select * from t for system_time as of timestamp now(6);
a b
1 NULL
3 NULL
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
select * from t for system_time as of timestamp now(6) where b is NULL;
a b
1 NULL
3 NULL
Warnings:
Warning 4075 Attempt to read unversioned field `b` in historical query
Warning 4075 Attempt to read unversioned field `b` in historical query
drop table t;
19 changes: 18 additions & 1 deletion mysql-test/suite/versioning/t/optimized_fields.test
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
create table t(
create table t (
a int,
b int without system versioning
) with system versioning;
Expand All @@ -20,4 +20,21 @@ select a from t where b is NULL system_time as of timestamp now(6);
select count(*), b from t group by b having b=NULL system_time as of timestamp now(6);
select a, b from t;

select count(*) from t for system_time as of timestamp now(6) group by b;
select * from t for system_time as of timestamp now(6) group by b having b=2;
select a from t for system_time as of timestamp now(6) where b=2;
select a from t for system_time as of timestamp now(6) where b=NULL;
select a from t for system_time as of timestamp now(6) where b is NULL;
select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL;

create or replace table t (
a int,
b int not null without system versioning
) with system versioning;

insert into t values (1, 2), (3, 4);

select * from t for system_time as of timestamp now(6);
select * from t for system_time as of timestamp now(6) where b is NULL;

drop table t;
2 changes: 1 addition & 1 deletion sql/field.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1631,7 +1631,7 @@ Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
:ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0),
table_name(0), field_name(field_name_arg), option_list(0),
option_struct(0), key_start(0), part_of_key(0),
part_of_key_not_clustered(0), force_null(false), part_of_sortkey(0),
part_of_key_not_clustered(0), part_of_sortkey(0),
unireg_check(unireg_check_arg), field_length(length_arg),
null_bit(null_bit_arg), is_created_from_null_item(FALSE),
read_stats(NULL), collected_stats(0), vcol_info(0), check_constraint(0),
Expand Down
4 changes: 0 additions & 4 deletions sql/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -703,8 +703,6 @@ class Field: public Value_source
/* Field is part of the following keys */
key_map key_start, part_of_key, part_of_key_not_clustered;

bool force_null;

/*
Bitmap of indexes that have records ordered by col1, ... this_field, ...
Expand Down Expand Up @@ -1090,8 +1088,6 @@ class Field: public Value_source
virtual uint size_of() const =0; // For new field
inline bool is_null(my_ptrdiff_t row_offset= 0) const
{
if (force_null)
return true;
/*
The table may have been marked as containing only NULL values
for all fields if it is a NULL-complemented row of an OUTER JOIN
Expand Down
38 changes: 24 additions & 14 deletions sql/item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2759,20 +2759,6 @@ void Item_field::set_field(Field *field_par)
fixed= 1;
if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
any_privileges= 0;

field->force_null= false;
if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG && context &&
((field->table->pos_in_table_list &&
field->table->pos_in_table_list->vers_conditions) ||
(context->select_lex && context->select_lex->vers_conditions)))
{
field->force_null= true;
push_warning_printf(
current_thd, Sql_condition::WARN_LEVEL_WARN,
ER_NON_VERSIONED_FIELD_IN_VERSIONED_QUERY,
ER_THD(current_thd, ER_NON_VERSIONED_FIELD_IN_VERSIONED_QUERY),
field_name);
}
}


Expand Down Expand Up @@ -10757,6 +10743,30 @@ bool Item_field::exclusive_dependence_on_grouping_fields_processor(void *arg)
return true;
}

Item *Item_field::vers_optimized_fields_transformer(THD *thd, uchar *)
{
if (!field)
return this;

if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG && context &&
((field->table->pos_in_table_list &&
field->table->pos_in_table_list->vers_conditions) ||
(context->select_lex && context->select_lex->vers_conditions)))
{
push_warning_printf(
current_thd, Sql_condition::WARN_LEVEL_WARN,
ER_NON_VERSIONED_FIELD_IN_VERSIONED_QUERY,
ER_THD(current_thd, ER_NON_VERSIONED_FIELD_IN_VERSIONED_QUERY),
field_name);

Item *null_item= new (thd->mem_root) Item_null(thd);
if (null_item)
return null_item;
}

return this;
}

void Item::register_in(THD *thd)
{
next= thd->free_list;
Expand Down
3 changes: 3 additions & 0 deletions sql/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,8 @@ class Item: public Value_source,

virtual Item_field *field_for_view_update() { return 0; }

virtual Item *vers_optimized_fields_transformer(THD *thd, uchar *)
{ return this; }
virtual Item *neg_transformer(THD *thd) { return NULL; }
virtual Item *update_value_transformer(THD *thd, uchar *select_arg)
{ return this; }
Expand Down Expand Up @@ -2750,6 +2752,7 @@ class Item_field :public Item_ident
uint32 max_display_length() const { return field->max_display_length(); }
Item_field *field_for_view_update() { return this; }
int fix_outer_field(THD *thd, Field **field, Item **reference);
virtual Item *vers_optimized_fields_transformer(THD *thd, uchar *);
virtual Item *update_value_transformer(THD *thd, uchar *select_arg);
Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
Item *derived_field_transformer_for_where(THD *thd, uchar *arg);
Expand Down
50 changes: 50 additions & 0 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,46 @@ JOIN::prepare(TABLE_LIST *tables_init,
if (!procedure && result && result->prepare(fields_list, unit_arg))
goto err; /* purecov: inspected */

if (!thd->stmt_arena->is_stmt_prepare())
{
bool have_versioned_tables= false;
for (TABLE_LIST *table= tables_list; table; table= table->next_local)
{
if (table->table && table->table->versioned())
{
have_versioned_tables= true;
break;
}
}

if (have_versioned_tables)
{
Item_transformer transformer= &Item::vers_optimized_fields_transformer;

if (conds)
{
conds= conds->transform(thd, transformer, NULL);
}

for (ORDER *ord= order; ord; ord= ord->next)
{
ord->item_ptr= (*ord->item)->transform(thd, transformer, NULL);
ord->item= &ord->item_ptr;
}

for (ORDER *ord= group_list; ord; ord= ord->next)
{
ord->item_ptr= (*ord->item)->transform(thd, transformer, NULL);
ord->item= &ord->item_ptr;
}

if (having)
{
having= having->transform(thd, transformer, NULL);
}
}
}

unit= unit_arg;
if (prepare_stage2())
goto err;
Expand Down Expand Up @@ -3827,6 +3867,16 @@ void JOIN::exec_inner()
result->send_result_set_metadata(
procedure ? procedure_fields_list : *fields,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);

{
List_iterator<Item> it(*columns_list);
while (Item *item= it++)
{
Item_transformer transformer= &Item::vers_optimized_fields_transformer;
it.replace(item->transform(thd, transformer, NULL));
}
}

error= do_select(this, procedure);
/* Accumulate the counts from all join iterations of all join parts. */
thd->inc_examined_row_count(join_examined_rows);
Expand Down

0 comments on commit 909867d

Please sign in to comment.