1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-38726 Assertion `table->default_field != dfield_ptr' failed in bool parse_vcol_defs(THD *, MEM_ROOT *, TABLE *, bool *, vcol_init_mode)

A new assertion added by MDEV-36290 is correct in trying to identify
default_fields that weren't correctly accounted in parse_vcol_defs.
It caught a case for INSERT DELAYED on tables using TIMESTAMP and
DATETIME types with ON UPDATE default values. That is, the insert
delayed logic opens the table in one thread, and then copies the
field info to another table in the user thread. This copy loses most
flag metadata for these fields though. In this case, the flag
ON_UPDATE_NOW_FLAG was dropped, and the parse_col_defs() logic was
unable to properly account for that default field, and the assertion
fired.

This patch fixes this by restoring the ON_UPDATE_NOW_FLAG during the
field copy. Also, a comment is added to Field::make_new_field() to
explain the state of the returned field.

Reviewed-by: Monty <monty@mariadb.com>
Signed-off-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
This commit is contained in:
Brandon Nesterenko
2026-02-06 11:22:33 -07:00
parent 32980c6b94
commit f5460983d3
4 changed files with 35 additions and 1 deletions

View File

@@ -420,3 +420,11 @@ CREATE TABLE t1 (c0 INT,UNIQUE (c0) USING HASH) ENGINE=MYISAM;
INSERT DELAYED INTO t1 VALUES (0);
INSERT DELAYED INTO t1 VALUES (0);
DROP TABLE t1;
#
# MDEV-38726: Assertion `table->default_field != dfield_ptr' failed in
# bool parse_vcol_defs(THD *, MEM_ROOT *, TABLE *, bool *,
# vcol_init_mode)
#
CREATE TABLE t_38726 (a TIMESTAMP ON UPDATE CURRENT_TIMESTAMP()) ENGINE=MYISAM;
INSERT DELAYED INTO t_38726 VALUES ();
DROP TABLE t_38726;

View File

@@ -632,3 +632,13 @@ INSERT DELAYED INTO t1 VALUES (0);
DROP TABLE t1;
--enable_view_protocol
--echo #
--echo # MDEV-38726: Assertion `table->default_field != dfield_ptr' failed in
--echo # bool parse_vcol_defs(THD *, MEM_ROOT *, TABLE *, bool *,
--echo # vcol_init_mode)
--echo #
CREATE TABLE t_38726 (a TIMESTAMP ON UPDATE CURRENT_TIMESTAMP()) ENGINE=MYISAM;
INSERT DELAYED INTO t_38726 VALUES ();
DROP TABLE t_38726;

View File

@@ -1608,6 +1608,14 @@ public:
virtual void sort_string(uchar *buff,uint length)=0;
virtual bool optimize_range(uint idx, uint part) const;
virtual void free() {}
/*
Creates a copy of this field which can be added to any table, and the
returned field is reset to a state respective of this. That is, any
information which is dependent on the original table is dropped (e.g. key
info, auto increment, etc). The information that is retained is that which
defines how to store, retrieve, or compare the field.
*/
virtual Field *make_new_field(MEM_ROOT *root, TABLE *new_table,
bool keep_type);
virtual Field *new_key_field(MEM_ROOT *root, TABLE *new_table,

View File

@@ -3132,7 +3132,15 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
(*field)->invisible= (*org_field)->invisible;
(*field)->orig_table= copy; // Remove connection
(*field)->move_field_offset(adjust_ptrs); // Point at copy->record[0]
(*field)->flags|= ((*org_field)->flags & LONG_UNIQUE_HASH_FIELD);
/*
The Field* produced by Field::make_new_field is reset to a barebones
state. Flags that are dependent on the original table need to be
restored.
*/
(*field)->flags|=
((*org_field)->flags & (LONG_UNIQUE_HASH_FIELD | ON_UPDATE_NOW_FLAG));
(*field)->invisible= (*org_field)->invisible;
if (memdup_vcol(client_thd, (*field)->vcol_info))
goto error;