Skip to content

Commit 8efca72

Browse files
committed
MDEV-14792 INSERT without column list into table with explicit versioning columns produces bad data
1 parent 157150c commit 8efca72

File tree

13 files changed

+74
-146
lines changed

13 files changed

+74
-146
lines changed

include/mysql.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ typedef unsigned long long my_ulonglong;
145145
#define ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
146146
#define ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN
147147
#define ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN ER_WRONG_FK_OPTION_FOR_GENERATED_COLUMN
148-
#define ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
149148
#define ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN
150149
#define ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS ER_UNSUPPORTED_ENGINE_FOR_GENERATED_COLUMNS
151150

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,8 @@ t2 CREATE TABLE `t2` (
323323
) ENGINE=NON_DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
324324
create or replace table t1 (
325325
x26 int,
326-
st bigint unsigned as row start invisible,
327-
en bigint unsigned as row end invisible,
326+
st bigint unsigned as row start,
327+
en bigint unsigned as row end,
328328
period for system_time (st, en)
329329
) with system versioning engine innodb;
330330
create or replace table t2 with system versioning engine myisam

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

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,6 @@ emp_id name mgr salary
4747
1 bill NULL 1000
4848
20 john 1 500
4949
30 jane 1 750
50-
with recursive
51-
ancestors
52-
as
53-
(
54-
select e.emp_id, e.name, e.mgr, e.salary
55-
from emp as e
56-
where name = 'bill'
57-
union
58-
select e.emp_id, e.name, e.mgr, e.salary
59-
from emp as e,
60-
ancestors as a
61-
where e.mgr = a.emp_id
62-
)
63-
select * from ancestors
64-
for system_time as of timestamp @ts_1;
65-
emp_id name mgr salary
66-
1 bill NULL 1000
67-
30 jane 1 750
6850
/* Expected 3 rows */
6951
with recursive
7052
ancestors

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

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,38 @@ select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_ti
304304
x y current
305305
2 2 1
306306
1 1 0
307-
create or replace table t1 (i int) with system versioning engine innodb;
308-
insert into t1 values (1),(2);
307+
create or replace table t1 (x int) with system versioning engine innodb;
308+
insert into t1 values (1), (2);
309309
insert into t1 (sys_trx_start) select sys_trx_end from t1;
310-
ERROR HY000: Column 'sys_trx_start' is not updatable
310+
ERROR HY000: The value specified for generated column 'sys_trx_start' in table 't1' ignored
311311
insert into t1 (sys_trx_start, sys_trx_end) values (DEFAULT, 1);
312-
ERROR HY000: Column 'sys_trx_end' is not updatable
312+
ERROR HY000: The value specified for generated column 'sys_trx_end' in table 't1' ignored
313+
select @@sql_mode into @saved_mode;
314+
set sql_mode= '';
315+
insert into t1 (x, sys_trx_start, sys_trx_end) values (3, 4, 5);
316+
Warnings:
317+
Warning 1906 The value specified for generated column 'sys_trx_start' in table 't1' ignored
318+
Warning 1906 The value specified for generated column 'sys_trx_end' in table 't1' ignored
319+
set sql_mode= @saved_mode;
313320
insert into t1 (sys_trx_start, sys_trx_end) values (DEFAULT, DEFAULT);
321+
select * from t1;
322+
x
323+
1
324+
2
325+
3
326+
NULL
327+
# MDEV-14792 INSERT without column list into table with explicit versioning columns produces bad data
328+
create or replace table t1 (
329+
i int,
330+
s timestamp(6) as row start,
331+
e timestamp(6) as row end,
332+
c varchar(8),
333+
period for system_time(s, e))
334+
with system versioning;
335+
insert into t1 values (1, null, null, 'foo');
336+
select i, c, current_row(e) from t1;
337+
i c current_row(e)
338+
1 foo 1
314339
drop table t1;
315340
drop table t2;
316341
drop procedure test_01;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ show create table t2;
289289

290290
create or replace table t1 (
291291
x26 int,
292-
st bigint unsigned as row start invisible,
293-
en bigint unsigned as row end invisible,
292+
st bigint unsigned as row start,
293+
en bigint unsigned as row end,
294294
period for system_time (st, en)
295295
) with system versioning engine innodb;
296296
--error ER_VERS_FIELD_WRONG_TYPE

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

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,6 @@ as
5151
)
5252
select * from ancestors;
5353

54-
with recursive
55-
ancestors
56-
as
57-
(
58-
select e.emp_id, e.name, e.mgr, e.salary
59-
from emp as e
60-
where name = 'bill'
61-
union
62-
select e.emp_id, e.name, e.mgr, e.salary
63-
from emp as e,
64-
ancestors as a
65-
where e.mgr = a.emp_id
66-
)
67-
select * from ancestors
68-
for system_time as of timestamp @ts_1;
69-
7054
/* Expected 3 rows */
7155
with recursive
7256
ancestors

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,29 @@ insert into t1 values (1, null);
206206
update t1 set x= x + 1;
207207
select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_time all;
208208

209-
create or replace table t1 (i int) with system versioning engine innodb;
210-
insert into t1 values (1),(2);
211-
--error ER_NONUPDATEABLE_COLUMN
209+
create or replace table t1 (x int) with system versioning engine innodb;
210+
insert into t1 values (1), (2);
211+
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
212212
insert into t1 (sys_trx_start) select sys_trx_end from t1;
213-
--error ER_NONUPDATEABLE_COLUMN
213+
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
214214
insert into t1 (sys_trx_start, sys_trx_end) values (DEFAULT, 1);
215+
select @@sql_mode into @saved_mode;
216+
set sql_mode= '';
217+
insert into t1 (x, sys_trx_start, sys_trx_end) values (3, 4, 5);
218+
set sql_mode= @saved_mode;
215219
insert into t1 (sys_trx_start, sys_trx_end) values (DEFAULT, DEFAULT);
220+
select * from t1;
221+
222+
--echo # MDEV-14792 INSERT without column list into table with explicit versioning columns produces bad data
223+
create or replace table t1 (
224+
i int,
225+
s timestamp(6) as row start,
226+
e timestamp(6) as row end,
227+
c varchar(8),
228+
period for system_time(s, e))
229+
with system versioning;
230+
insert into t1 values (1, null, null, 'foo');
231+
select i, c, current_row(e) from t1;
216232

217233
drop table t1;
218234
drop table t2;

sql/sql_base.cc

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7500,6 +7500,7 @@ bool Field::vers_sys_invisible(THD *thd) const
75007500
SELECT_LEX *slex= thd->lex->current_select;
75017501
ulong vers_hide= thd->variables.vers_hide;
75027502
DBUG_ASSERT(table);
7503+
DBUG_ASSERT(table->versioned());
75037504
DBUG_ASSERT(table->pos_in_table_list);
75047505
TABLE_LIST *tl= table->pos_in_table_list;
75057506
vers_system_time_t vers_type= tl->vers_conditions.type;
@@ -7508,6 +7509,7 @@ bool Field::vers_sys_invisible(THD *thd) const
75087509
slex->nest_level > 0 ||
75097510
vers_hide == VERS_HIDE_FULL ||
75107511
(invisible && (
7512+
thd->lex->sql_command != SQLCOM_SELECT ||
75117513
vers_hide == VERS_HIDE_IMPLICIT ||
75127514
(vers_hide == VERS_HIDE_AUTO && (
75137515
vers_type == SYSTEM_TIME_UNSPECIFIED ||
@@ -7649,8 +7651,6 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
76497651
field->vers_sys_invisible(thd) :
76507652
field->invisible))
76517653
{
7652-
if (thd->lex->sql_command != SQLCOM_CREATE_TABLE ||
7653-
!(thd->lex->create_info.options & HA_VERSIONED_TABLE))
76547654
continue;
76557655
}
76567656

@@ -8059,25 +8059,21 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
80598059
rfield->field_index == table->next_number_field->field_index)
80608060
table->auto_increment_field_not_null= TRUE;
80618061
Item::Type type= value->type();
8062-
if (rfield->vcol_info &&
8062+
bool vers_sys_field= table->versioned() && rfield->vers_sys_field();
8063+
if ((rfield->vcol_info || vers_sys_field) &&
80638064
type != Item::DEFAULT_VALUE_ITEM &&
80648065
type != Item::NULL_ITEM &&
80658066
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
80668067
{
80678068
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
8068-
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
8069-
ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
8069+
ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN,
8070+
ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN),
80708071
rfield->field_name.str, table->s->table_name.str);
8072+
if (vers_sys_field)
8073+
continue;
80718074
}
80728075
if (only_unvers_fields && !rfield->vers_update_unversioned())
80738076
only_unvers_fields= false;
8074-
if (table->versioned() && rfield->vers_sys_field())
8075-
{
8076-
if (type == Item::DEFAULT_VALUE_ITEM)
8077-
continue;
8078-
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), rfield->field_name.str);
8079-
goto err;
8080-
}
80818077

80828078
if (rfield->stored_in_db() &&
80838079
(value->save_in_field(rfield, 0)) < 0 && !ignore_errors)
@@ -8310,33 +8306,30 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
83108306
/* Ensure that all fields are from the same table */
83118307
DBUG_ASSERT(field->table == table);
83128308

8313-
bool vers_sys_field= table->versioned() && field->vers_sys_field();
8314-
8315-
if (vers_sys_field && !ignore_errors)
8316-
{
8317-
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), field->field_name.str);
8318-
goto err;
8319-
}
8320-
8321-
if (field->invisible && !vers_sys_field)
8309+
if (field->invisible)
83228310
{
83238311
continue;
83248312
}
83258313
else
83268314
value=v++;
8315+
8316+
bool vers_sys_field= table->versioned() && field->vers_sys_field();
8317+
83278318
if (field->field_index == autoinc_index)
83288319
table->auto_increment_field_not_null= TRUE;
8329-
if (field->vcol_info)
8320+
if (field->vcol_info || (vers_sys_field && !ignore_errors))
83308321
{
83318322
Item::Type type= value->type();
83328323
if (type != Item::DEFAULT_VALUE_ITEM &&
83338324
type != Item::NULL_ITEM &&
83348325
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
83358326
{
83368327
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
8337-
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
8338-
ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
8328+
ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN,
8329+
ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN),
83398330
field->field_name.str, table->s->table_name.str);
8331+
if (vers_sys_field)
8332+
continue;
83408333
}
83418334
}
83428335

sql/sql_insert.cc

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -682,17 +682,6 @@ Field **TABLE::field_to_fill()
682682
}
683683

684684

685-
inline
686-
Field **TABLE::vers_user_field_to_fill()
687-
{
688-
if (versioned())
689-
{
690-
return triggers && triggers->vers_user_fields() ? triggers->vers_user_fields() : vers_user_field;
691-
}
692-
return field_to_fill();
693-
}
694-
695-
696685
/**
697686
INSERT statement implementation
698687
@@ -1020,7 +1009,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
10201009
}
10211010
table->reset_default_fields();
10221011
if (fill_record_n_invoke_before_triggers(thd, table,
1023-
table->vers_user_field_to_fill(),
1012+
table->field_to_fill(),
10241013
*values, 0, TRG_EVENT_INSERT))
10251014
{
10261015
if (values_list.elements != 1 && ! thd->is_error())
@@ -2612,9 +2601,6 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
26122601
}
26132602
*field=0;
26142603

2615-
if (copy->versioned() && copy->vers_update_user_field(client_thd->mem_root))
2616-
goto error;
2617-
26182604
if (share->virtual_fields || share->default_expressions ||
26192605
share->default_fields)
26202606
{
@@ -3913,7 +3899,7 @@ void select_insert::store_values(List<Item> &values)
39133899
fill_record_n_invoke_before_triggers(thd, table, *fields, values, 1,
39143900
TRG_EVENT_INSERT);
39153901
else
3916-
fill_record_n_invoke_before_triggers(thd, table, table->vers_user_field_to_fill(),
3902+
fill_record_n_invoke_before_triggers(thd, table, table->field_to_fill(),
39173903
values, 1, TRG_EVENT_INSERT);
39183904

39193905
DBUG_VOID_RETURN;

sql/sql_trigger.cc

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,28 +1249,10 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table)
12491249
*trg_fld= 0;
12501250
DBUG_ASSERT(null_ptr <= extra_null_bitmap + null_bytes);
12511251
bzero(extra_null_bitmap, null_bytes);
1252-
1253-
if (table->versioned())
1254-
{
1255-
vers_user_field= (Field **)alloc_root(&table->mem_root,
1256-
(table->s->fields - VERSIONING_FIELDS + 1) *
1257-
sizeof(Field*));
1258-
if (!vers_user_field)
1259-
return 1;
1260-
Field **dst= vers_user_field;
1261-
for (Field **src= record0_field; *src; src++)
1262-
{
1263-
if ((*src)->vers_sys_field())
1264-
continue;
1265-
*dst++= *src;
1266-
}
1267-
*dst= NULL;
1268-
}
12691252
}
12701253
else
12711254
{
12721255
record0_field= table->field;
1273-
vers_user_field= table->vers_user_field;
12741256
}
12751257

12761258
if (has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_BEFORE) ||

0 commit comments

Comments
 (0)