Commit 909867d0 authored by Eugene Kosov's avatar Eugene Kosov Committed by GitHub

SQL: optimized fields fix for NOT NULL [fixes #226]

parent 91c8b43e
create table t(
create table t (
a int,
b int without system versioning
) with system versioning;
......@@ -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:
......@@ -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:
......@@ -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;
create table t(
create table t (
a int,
b int without system versioning
) with system versioning;
......@@ -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;
......@@ -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),
......
......@@ -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, ...
......@@ -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
......
......@@ -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);
}
}
......@@ -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;
......
......@@ -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; }
......@@ -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);
......
......@@ -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;
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment