Skip to content

Commit 909867d

Browse files
authored
SQL: optimized fields fix for NOT NULL [fixes #226]
1 parent 91c8b43 commit 909867d

File tree

7 files changed

+148
-21
lines changed

7 files changed

+148
-21
lines changed

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

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
create table t(
1+
create table t (
22
a int,
33
b int without system versioning
44
) with system versioning;
@@ -36,12 +36,14 @@ a b
3636
3 NULL
3737
Warnings:
3838
Warning 4075 Attempt to read unversioned field `b` in historical query
39+
Warning 4075 Attempt to read unversioned field `b` in historical query
3940
select * from t for system_time as of timestamp now(6) order by b desc;
4041
a b
4142
1 NULL
4243
3 NULL
4344
Warnings:
4445
Warning 4075 Attempt to read unversioned field `b` in historical query
46+
Warning 4075 Attempt to read unversioned field `b` in historical query
4547
select * from t group by a having a=2 system_time as of timestamp now(6);
4648
a b
4749
Warnings:
@@ -50,6 +52,7 @@ select * from t group by b having b=2 system_time as of timestamp now(6);
5052
a b
5153
Warnings:
5254
Warning 4075 Attempt to read unversioned field `b` in historical query
55+
Warning 4075 Attempt to read unversioned field `b` in historical query
5356
select a from t where b=2 system_time as of timestamp now(6);
5457
a
5558
Warnings:
@@ -68,8 +71,56 @@ select count(*), b from t group by b having b=NULL system_time as of timestamp n
6871
count(*) b
6972
Warnings:
7073
Warning 4075 Attempt to read unversioned field `b` in historical query
74+
Warning 4075 Attempt to read unversioned field `b` in historical query
7175
select a, b from t;
7276
a b
7377
1 2
7478
3 4
79+
select count(*) from t for system_time as of timestamp now(6) group by b;
80+
count(*)
81+
2
82+
Warnings:
83+
Warning 4075 Attempt to read unversioned field `b` in historical query
84+
select * from t for system_time as of timestamp now(6) group by b having b=2;
85+
a b
86+
Warnings:
87+
Warning 4075 Attempt to read unversioned field `b` in historical query
88+
Warning 4075 Attempt to read unversioned field `b` in historical query
89+
select a from t for system_time as of timestamp now(6) where b=2;
90+
a
91+
Warnings:
92+
Warning 4075 Attempt to read unversioned field `b` in historical query
93+
select a from t for system_time as of timestamp now(6) where b=NULL;
94+
a
95+
Warnings:
96+
Warning 4075 Attempt to read unversioned field `b` in historical query
97+
select a from t for system_time as of timestamp now(6) where b is NULL;
98+
a
99+
1
100+
3
101+
Warnings:
102+
Warning 4075 Attempt to read unversioned field `b` in historical query
103+
select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL;
104+
count(*) b
105+
Warnings:
106+
Warning 4075 Attempt to read unversioned field `b` in historical query
107+
Warning 4075 Attempt to read unversioned field `b` in historical query
108+
create or replace table t (
109+
a int,
110+
b int not null without system versioning
111+
) with system versioning;
112+
insert into t values (1, 2), (3, 4);
113+
select * from t for system_time as of timestamp now(6);
114+
a b
115+
1 NULL
116+
3 NULL
117+
Warnings:
118+
Warning 4075 Attempt to read unversioned field `b` in historical query
119+
select * from t for system_time as of timestamp now(6) where b is NULL;
120+
a b
121+
1 NULL
122+
3 NULL
123+
Warnings:
124+
Warning 4075 Attempt to read unversioned field `b` in historical query
125+
Warning 4075 Attempt to read unversioned field `b` in historical query
75126
drop table t;

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
create table t(
1+
create table t (
22
a int,
33
b int without system versioning
44
) with system versioning;
@@ -20,4 +20,21 @@ select a from t where b is NULL system_time as of timestamp now(6);
2020
select count(*), b from t group by b having b=NULL system_time as of timestamp now(6);
2121
select a, b from t;
2222

23+
select count(*) from t for system_time as of timestamp now(6) group by b;
24+
select * from t for system_time as of timestamp now(6) group by b having b=2;
25+
select a from t for system_time as of timestamp now(6) where b=2;
26+
select a from t for system_time as of timestamp now(6) where b=NULL;
27+
select a from t for system_time as of timestamp now(6) where b is NULL;
28+
select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL;
29+
30+
create or replace table t (
31+
a int,
32+
b int not null without system versioning
33+
) with system versioning;
34+
35+
insert into t values (1, 2), (3, 4);
36+
37+
select * from t for system_time as of timestamp now(6);
38+
select * from t for system_time as of timestamp now(6) where b is NULL;
39+
2340
drop table t;

sql/field.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1631,7 +1631,7 @@ Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
16311631
:ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0),
16321632
table_name(0), field_name(field_name_arg), option_list(0),
16331633
option_struct(0), key_start(0), part_of_key(0),
1634-
part_of_key_not_clustered(0), force_null(false), part_of_sortkey(0),
1634+
part_of_key_not_clustered(0), part_of_sortkey(0),
16351635
unireg_check(unireg_check_arg), field_length(length_arg),
16361636
null_bit(null_bit_arg), is_created_from_null_item(FALSE),
16371637
read_stats(NULL), collected_stats(0), vcol_info(0), check_constraint(0),

sql/field.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -703,8 +703,6 @@ class Field: public Value_source
703703
/* Field is part of the following keys */
704704
key_map key_start, part_of_key, part_of_key_not_clustered;
705705

706-
bool force_null;
707-
708706
/*
709707
Bitmap of indexes that have records ordered by col1, ... this_field, ...
710708
@@ -1090,8 +1088,6 @@ class Field: public Value_source
10901088
virtual uint size_of() const =0; // For new field
10911089
inline bool is_null(my_ptrdiff_t row_offset= 0) const
10921090
{
1093-
if (force_null)
1094-
return true;
10951091
/*
10961092
The table may have been marked as containing only NULL values
10971093
for all fields if it is a NULL-complemented row of an OUTER JOIN

sql/item.cc

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,20 +2759,6 @@ void Item_field::set_field(Field *field_par)
27592759
fixed= 1;
27602760
if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
27612761
any_privileges= 0;
2762-
2763-
field->force_null= false;
2764-
if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG && context &&
2765-
((field->table->pos_in_table_list &&
2766-
field->table->pos_in_table_list->vers_conditions) ||
2767-
(context->select_lex && context->select_lex->vers_conditions)))
2768-
{
2769-
field->force_null= true;
2770-
push_warning_printf(
2771-
current_thd, Sql_condition::WARN_LEVEL_WARN,
2772-
ER_NON_VERSIONED_FIELD_IN_VERSIONED_QUERY,
2773-
ER_THD(current_thd, ER_NON_VERSIONED_FIELD_IN_VERSIONED_QUERY),
2774-
field_name);
2775-
}
27762762
}
27772763

27782764

@@ -10757,6 +10743,30 @@ bool Item_field::exclusive_dependence_on_grouping_fields_processor(void *arg)
1075710743
return true;
1075810744
}
1075910745

10746+
Item *Item_field::vers_optimized_fields_transformer(THD *thd, uchar *)
10747+
{
10748+
if (!field)
10749+
return this;
10750+
10751+
if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG && context &&
10752+
((field->table->pos_in_table_list &&
10753+
field->table->pos_in_table_list->vers_conditions) ||
10754+
(context->select_lex && context->select_lex->vers_conditions)))
10755+
{
10756+
push_warning_printf(
10757+
current_thd, Sql_condition::WARN_LEVEL_WARN,
10758+
ER_NON_VERSIONED_FIELD_IN_VERSIONED_QUERY,
10759+
ER_THD(current_thd, ER_NON_VERSIONED_FIELD_IN_VERSIONED_QUERY),
10760+
field_name);
10761+
10762+
Item *null_item= new (thd->mem_root) Item_null(thd);
10763+
if (null_item)
10764+
return null_item;
10765+
}
10766+
10767+
return this;
10768+
}
10769+
1076010770
void Item::register_in(THD *thd)
1076110771
{
1076210772
next= thd->free_list;

sql/item.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,6 +1655,8 @@ class Item: public Value_source,
16551655

16561656
virtual Item_field *field_for_view_update() { return 0; }
16571657

1658+
virtual Item *vers_optimized_fields_transformer(THD *thd, uchar *)
1659+
{ return this; }
16581660
virtual Item *neg_transformer(THD *thd) { return NULL; }
16591661
virtual Item *update_value_transformer(THD *thd, uchar *select_arg)
16601662
{ return this; }
@@ -2750,6 +2752,7 @@ class Item_field :public Item_ident
27502752
uint32 max_display_length() const { return field->max_display_length(); }
27512753
Item_field *field_for_view_update() { return this; }
27522754
int fix_outer_field(THD *thd, Field **field, Item **reference);
2755+
virtual Item *vers_optimized_fields_transformer(THD *thd, uchar *);
27532756
virtual Item *update_value_transformer(THD *thd, uchar *select_arg);
27542757
Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
27552758
Item *derived_field_transformer_for_where(THD *thd, uchar *arg);

sql/sql_select.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,46 @@ JOIN::prepare(TABLE_LIST *tables_init,
13801380
if (!procedure && result && result->prepare(fields_list, unit_arg))
13811381
goto err; /* purecov: inspected */
13821382

1383+
if (!thd->stmt_arena->is_stmt_prepare())
1384+
{
1385+
bool have_versioned_tables= false;
1386+
for (TABLE_LIST *table= tables_list; table; table= table->next_local)
1387+
{
1388+
if (table->table && table->table->versioned())
1389+
{
1390+
have_versioned_tables= true;
1391+
break;
1392+
}
1393+
}
1394+
1395+
if (have_versioned_tables)
1396+
{
1397+
Item_transformer transformer= &Item::vers_optimized_fields_transformer;
1398+
1399+
if (conds)
1400+
{
1401+
conds= conds->transform(thd, transformer, NULL);
1402+
}
1403+
1404+
for (ORDER *ord= order; ord; ord= ord->next)
1405+
{
1406+
ord->item_ptr= (*ord->item)->transform(thd, transformer, NULL);
1407+
ord->item= &ord->item_ptr;
1408+
}
1409+
1410+
for (ORDER *ord= group_list; ord; ord= ord->next)
1411+
{
1412+
ord->item_ptr= (*ord->item)->transform(thd, transformer, NULL);
1413+
ord->item= &ord->item_ptr;
1414+
}
1415+
1416+
if (having)
1417+
{
1418+
having= having->transform(thd, transformer, NULL);
1419+
}
1420+
}
1421+
}
1422+
13831423
unit= unit_arg;
13841424
if (prepare_stage2())
13851425
goto err;
@@ -3827,6 +3867,16 @@ void JOIN::exec_inner()
38273867
result->send_result_set_metadata(
38283868
procedure ? procedure_fields_list : *fields,
38293869
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
3870+
3871+
{
3872+
List_iterator<Item> it(*columns_list);
3873+
while (Item *item= it++)
3874+
{
3875+
Item_transformer transformer= &Item::vers_optimized_fields_transformer;
3876+
it.replace(item->transform(thd, transformer, NULL));
3877+
}
3878+
}
3879+
38303880
error= do_select(this, procedure);
38313881
/* Accumulate the counts from all join iterations of all join parts. */
38323882
thd->inc_examined_row_count(join_examined_rows);

0 commit comments

Comments
 (0)