Commit f8f90aa7 authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-3938.

The original patch with the implementation of virtual columns
did not support INSERT DELAYED into tables with virtual columns.
This patch fixes the problem.
parent bd87fed1
...@@ -182,3 +182,13 @@ a b c ...@@ -182,3 +182,13 @@ a b c
2 3 y 2 3 y
0 1 y,n 0 1 y,n
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1 (
ts TIMESTAMP,
tsv TIMESTAMP AS (ADDDATE(ts, INTERVAL 1 DAY)) VIRTUAL
) ENGINE=MyISAM;
INSERT INTO t1 (tsv) VALUES (DEFAULT);
INSERT DELAYED INTO t1 (tsv) VALUES (DEFAULT);
SELECT COUNT(*) FROM t1;
COUNT(*)
2
DROP TABLE t1;
...@@ -178,3 +178,21 @@ insert into t2(a,b) values (7,0), (2,3), (0,1); ...@@ -178,3 +178,21 @@ insert into t2(a,b) values (7,0), (2,3), (0,1);
select * from t2; select * from t2;
drop table t1,t2; drop table t1,t2;
#
# Bug mdev-3938: INSERT DELAYED for a table with virtual columns
#
CREATE TABLE t1 (
ts TIMESTAMP,
tsv TIMESTAMP AS (ADDDATE(ts, INTERVAL 1 DAY)) VIRTUAL
) ENGINE=MyISAM;
INSERT INTO t1 (tsv) VALUES (DEFAULT);
INSERT DELAYED INTO t1 (tsv) VALUES (DEFAULT);
SELECT COUNT(*) FROM t1;
DROP TABLE t1;
...@@ -2292,6 +2292,9 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg); ...@@ -2292,6 +2292,9 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg);
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
uint db_stat, uint prgflag, uint ha_open_flags, uint db_stat, uint prgflag, uint ha_open_flags,
TABLE *outparam, bool is_create_table); TABLE *outparam, bool is_create_table);
bool unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root,
TABLE *table, Field *field,
LEX_STRING *vcol_expr, bool *error_reported);
int readfrm(const char *name, uchar **data, size_t *length); int readfrm(const char *name, uchar **data, size_t *length);
int writefrm(const char* name, const uchar* data, size_t len); int writefrm(const char* name, const uchar* data, size_t len);
int closefrm(TABLE *table, bool free_share); int closefrm(TABLE *table, bool free_share);
......
...@@ -8429,7 +8429,8 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values, ...@@ -8429,7 +8429,8 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
rfield->field_name, table->s->table_name.str); rfield->field_name, table->s->table_name.str);
thd->abort_on_warning= abort_on_warning_saved; thd->abort_on_warning= abort_on_warning_saved;
} }
if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors) if ((!rfield->vcol_info || rfield->stored_in_db) &&
(value->save_in_field(rfield, 0) < 0) && !ignore_errors)
{ {
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0)); my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
goto err; goto err;
......
...@@ -2084,6 +2084,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) ...@@ -2084,6 +2084,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
{ {
my_ptrdiff_t adjust_ptrs; my_ptrdiff_t adjust_ptrs;
Field **field,**org_field, *found_next_number_field; Field **field,**org_field, *found_next_number_field;
Field **vfield;
TABLE *copy; TABLE *copy;
TABLE_SHARE *share; TABLE_SHARE *share;
uchar *bitmap; uchar *bitmap;
...@@ -2127,12 +2128,20 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) ...@@ -2127,12 +2128,20 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
if (!copy_tmp) if (!copy_tmp)
goto error; goto error;
if (share->vfields)
{
vfield= (Field **) client_thd->alloc((share->vfields+1)*sizeof(Field*));
if (!vfield)
goto error;
}
/* Copy the TABLE object. */ /* Copy the TABLE object. */
copy= new (copy_tmp) TABLE; copy= new (copy_tmp) TABLE;
*copy= *table; *copy= *table;
/* We don't need to change the file handler here */ /* We don't need to change the file handler here */
/* Assign the pointers for the field pointers array and the record. */ /* Assign the pointers for the field pointers array and the record. */
field= copy->field= (Field**) (copy + 1); field= copy->field= (Field**) (copy + 1);
copy->vfield= vfield;
bitmap= (uchar*) (field + share->fields + 1); bitmap= (uchar*) (field + share->fields + 1);
copy->record[0]= (bitmap + share->column_bitmap_size*3); copy->record[0]= (bitmap + share->column_bitmap_size*3);
memcpy((char*) copy->record[0], (char*) table->record[0], share->reclength); memcpy((char*) copy->record[0], (char*) table->record[0], share->reclength);
...@@ -2156,6 +2165,26 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) ...@@ -2156,6 +2165,26 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
} }
*field=0; *field=0;
if (table->vfield)
{
for (field= copy->field; *field; field++)
{
if ((*field)->vcol_info)
{
bool error_reported= FALSE;
if (unpack_vcol_info_from_frm(client_thd,
client_thd->mem_root,
copy,
*field,
&(*field)->vcol_info->expr_str,
&error_reported))
goto error;
*vfield++= *field;
}
}
*vfield= 0;
}
/* Adjust timestamp */ /* Adjust timestamp */
if (table->timestamp_field) if (table->timestamp_field)
{ {
......
...@@ -1925,8 +1925,10 @@ bool fix_vcol_expr(THD *thd, ...@@ -1925,8 +1925,10 @@ bool fix_vcol_expr(THD *thd,
@brief @brief
Unpack the definition of a virtual column from its linear representation Unpack the definition of a virtual column from its linear representation
@parm @param
thd The thread object thd The thread object
@param
mem_root The mem_root object where to allocated memory
@param @param
table The table containing the virtual column table The table containing the virtual column
@param @param
...@@ -1956,6 +1958,7 @@ bool fix_vcol_expr(THD *thd, ...@@ -1956,6 +1958,7 @@ bool fix_vcol_expr(THD *thd,
TRUE Otherwise TRUE Otherwise
*/ */
bool unpack_vcol_info_from_frm(THD *thd, bool unpack_vcol_info_from_frm(THD *thd,
MEM_ROOT *mem_root,
TABLE *table, TABLE *table,
Field *field, Field *field,
LEX_STRING *vcol_expr, LEX_STRING *vcol_expr,
...@@ -1981,7 +1984,7 @@ bool unpack_vcol_info_from_frm(THD *thd, ...@@ -1981,7 +1984,7 @@ bool unpack_vcol_info_from_frm(THD *thd,
"PARSE_VCOL_EXPR (<expr_string_from_frm>)". "PARSE_VCOL_EXPR (<expr_string_from_frm>)".
*/ */
if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root, if (!(vcol_expr_str= (char*) alloc_root(mem_root,
vcol_expr->length + vcol_expr->length +
parse_vcol_keyword.length + 3))) parse_vcol_keyword.length + 3)))
{ {
...@@ -2011,8 +2014,8 @@ bool unpack_vcol_info_from_frm(THD *thd, ...@@ -2011,8 +2014,8 @@ bool unpack_vcol_info_from_frm(THD *thd,
vcol_arena= table->expr_arena; vcol_arena= table->expr_arena;
if (!vcol_arena) if (!vcol_arena)
{ {
Query_arena expr_arena(&table->mem_root, Query_arena::INITIALIZED); Query_arena expr_arena(mem_root, Query_arena::INITIALIZED);
if (!(vcol_arena= (Query_arena *) alloc_root(&table->mem_root, if (!(vcol_arena= (Query_arena *) alloc_root(mem_root,
sizeof(Query_arena)))) sizeof(Query_arena))))
goto err; goto err;
*vcol_arena= expr_arena; *vcol_arena= expr_arena;
...@@ -2265,6 +2268,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, ...@@ -2265,6 +2268,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
if ((*field_ptr)->vcol_info) if ((*field_ptr)->vcol_info)
{ {
if (unpack_vcol_info_from_frm(thd, if (unpack_vcol_info_from_frm(thd,
&outparam->mem_root,
outparam, outparam,
*field_ptr, *field_ptr,
&(*field_ptr)->vcol_info->expr_str, &(*field_ptr)->vcol_info->expr_str,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment