mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
SQL: optimized fields fix for NOT NULL [fixes #226]
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
create table t(
|
create table t (
|
||||||
a int,
|
a int,
|
||||||
b int without system versioning
|
b int without system versioning
|
||||||
) with system versioning;
|
) with system versioning;
|
||||||
@@ -36,12 +36,14 @@ a b
|
|||||||
3 NULL
|
3 NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
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;
|
select * from t for system_time as of timestamp now(6) order by b desc;
|
||||||
a b
|
a b
|
||||||
1 NULL
|
1 NULL
|
||||||
3 NULL
|
3 NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
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);
|
select * from t group by a having a=2 system_time as of timestamp now(6);
|
||||||
a b
|
a b
|
||||||
Warnings:
|
Warnings:
|
||||||
@@ -50,6 +52,7 @@ select * from t group by b having b=2 system_time as of timestamp now(6);
|
|||||||
a b
|
a b
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
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);
|
select a from t where b=2 system_time as of timestamp now(6);
|
||||||
a
|
a
|
||||||
Warnings:
|
Warnings:
|
||||||
@@ -68,8 +71,56 @@ select count(*), b from t group by b having b=NULL system_time as of timestamp n
|
|||||||
count(*) b
|
count(*) b
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
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;
|
select a, b from t;
|
||||||
a b
|
a b
|
||||||
1 2
|
1 2
|
||||||
3 4
|
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;
|
drop table t;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
create table t(
|
create table t (
|
||||||
a int,
|
a int,
|
||||||
b int without system versioning
|
b int without system versioning
|
||||||
) with 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 count(*), b from t group by b having b=NULL system_time as of timestamp now(6);
|
||||||
select a, b from t;
|
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;
|
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),
|
:ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0),
|
||||||
table_name(0), field_name(field_name_arg), option_list(0),
|
table_name(0), field_name(field_name_arg), option_list(0),
|
||||||
option_struct(0), key_start(0), part_of_key(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),
|
unireg_check(unireg_check_arg), field_length(length_arg),
|
||||||
null_bit(null_bit_arg), is_created_from_null_item(FALSE),
|
null_bit(null_bit_arg), is_created_from_null_item(FALSE),
|
||||||
read_stats(NULL), collected_stats(0), vcol_info(0), check_constraint(0),
|
read_stats(NULL), collected_stats(0), vcol_info(0), check_constraint(0),
|
||||||
|
@@ -703,8 +703,6 @@ public:
|
|||||||
/* Field is part of the following keys */
|
/* Field is part of the following keys */
|
||||||
key_map key_start, part_of_key, part_of_key_not_clustered;
|
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, ...
|
Bitmap of indexes that have records ordered by col1, ... this_field, ...
|
||||||
|
|
||||||
@@ -1090,8 +1088,6 @@ public:
|
|||||||
virtual uint size_of() const =0; // For new field
|
virtual uint size_of() const =0; // For new field
|
||||||
inline bool is_null(my_ptrdiff_t row_offset= 0) const
|
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
|
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
|
for all fields if it is a NULL-complemented row of an OUTER JOIN
|
||||||
|
38
sql/item.cc
38
sql/item.cc
@@ -2759,20 +2759,6 @@ void Item_field::set_field(Field *field_par)
|
|||||||
fixed= 1;
|
fixed= 1;
|
||||||
if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
|
if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
|
||||||
any_privileges= 0;
|
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;
|
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)
|
void Item::register_in(THD *thd)
|
||||||
{
|
{
|
||||||
next= thd->free_list;
|
next= thd->free_list;
|
||||||
|
@@ -1655,6 +1655,8 @@ public:
|
|||||||
|
|
||||||
virtual Item_field *field_for_view_update() { return 0; }
|
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 *neg_transformer(THD *thd) { return NULL; }
|
||||||
virtual Item *update_value_transformer(THD *thd, uchar *select_arg)
|
virtual Item *update_value_transformer(THD *thd, uchar *select_arg)
|
||||||
{ return this; }
|
{ return this; }
|
||||||
@@ -2750,6 +2752,7 @@ public:
|
|||||||
uint32 max_display_length() const { return field->max_display_length(); }
|
uint32 max_display_length() const { return field->max_display_length(); }
|
||||||
Item_field *field_for_view_update() { return this; }
|
Item_field *field_for_view_update() { return this; }
|
||||||
int fix_outer_field(THD *thd, Field **field, Item **reference);
|
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);
|
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_having(THD *thd, uchar *arg);
|
||||||
Item *derived_field_transformer_for_where(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))
|
if (!procedure && result && result->prepare(fields_list, unit_arg))
|
||||||
goto err; /* purecov: inspected */
|
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;
|
unit= unit_arg;
|
||||||
if (prepare_stage2())
|
if (prepare_stage2())
|
||||||
goto err;
|
goto err;
|
||||||
@@ -3827,6 +3867,16 @@ void JOIN::exec_inner()
|
|||||||
result->send_result_set_metadata(
|
result->send_result_set_metadata(
|
||||||
procedure ? procedure_fields_list : *fields,
|
procedure ? procedure_fields_list : *fields,
|
||||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
|
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);
|
error= do_select(this, procedure);
|
||||||
/* Accumulate the counts from all join iterations of all join parts. */
|
/* Accumulate the counts from all join iterations of all join parts. */
|
||||||
thd->inc_examined_row_count(join_examined_rows);
|
thd->inc_examined_row_count(join_examined_rows);
|
||||||
|
Reference in New Issue
Block a user