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
2 3 y
0 1 y,n
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);
select * from 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);
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
uint db_stat, uint prgflag, uint ha_open_flags,
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 writefrm(const char* name, const uchar* data, size_t len);
int closefrm(TABLE *table, bool free_share);
......
......@@ -8429,7 +8429,8 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
rfield->field_name, table->s->table_name.str);
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));
goto err;
......
......@@ -2084,6 +2084,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
{
my_ptrdiff_t adjust_ptrs;
Field **field,**org_field, *found_next_number_field;
Field **vfield;
TABLE *copy;
TABLE_SHARE *share;
uchar *bitmap;
......@@ -2127,12 +2128,20 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
if (!copy_tmp)
goto error;
if (share->vfields)
{
vfield= (Field **) client_thd->alloc((share->vfields+1)*sizeof(Field*));
if (!vfield)
goto error;
}
/* Copy the TABLE object. */
copy= new (copy_tmp) TABLE;
*copy= *table;
/* We don't need to change the file handler here */
/* Assign the pointers for the field pointers array and the record. */
field= copy->field= (Field**) (copy + 1);
copy->vfield= vfield;
bitmap= (uchar*) (field + share->fields + 1);
copy->record[0]= (bitmap + share->column_bitmap_size*3);
memcpy((char*) copy->record[0], (char*) table->record[0], share->reclength);
......@@ -2156,6 +2165,26 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
}
*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 */
if (table->timestamp_field)
{
......
......@@ -1925,8 +1925,10 @@ bool fix_vcol_expr(THD *thd,
@brief
Unpack the definition of a virtual column from its linear representation
@parm
@param
thd The thread object
@param
mem_root The mem_root object where to allocated memory
@param
table The table containing the virtual column
@param
......@@ -1956,6 +1958,7 @@ bool fix_vcol_expr(THD *thd,
TRUE Otherwise
*/
bool unpack_vcol_info_from_frm(THD *thd,
MEM_ROOT *mem_root,
TABLE *table,
Field *field,
LEX_STRING *vcol_expr,
......@@ -1981,7 +1984,7 @@ bool unpack_vcol_info_from_frm(THD *thd,
"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 +
parse_vcol_keyword.length + 3)))
{
......@@ -2011,8 +2014,8 @@ bool unpack_vcol_info_from_frm(THD *thd,
vcol_arena= table->expr_arena;
if (!vcol_arena)
{
Query_arena expr_arena(&table->mem_root, Query_arena::INITIALIZED);
if (!(vcol_arena= (Query_arena *) alloc_root(&table->mem_root,
Query_arena expr_arena(mem_root, Query_arena::INITIALIZED);
if (!(vcol_arena= (Query_arena *) alloc_root(mem_root,
sizeof(Query_arena))))
goto err;
*vcol_arena= expr_arena;
......@@ -2265,6 +2268,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
if ((*field_ptr)->vcol_info)
{
if (unpack_vcol_info_from_frm(thd,
&outparam->mem_root,
outparam,
*field_ptr,
&(*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