mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
SQL: optimized fields fix for NOT NULL [fixes #226]
This commit is contained in:
@@ -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;
|
||||
|
@@ -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 @@ public:
|
||||
/* 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 @@ public:
|
||||
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
|
||||
|
38
sql/item.cc
38
sql/item.cc
@@ -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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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);
|
||||
|
Reference in New Issue
Block a user