mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
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.
This commit is contained in:
@ -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)
|
||||
{
|
||||
|
12
sql/table.cc
12
sql/table.cc
@ -1925,8 +1925,10 @@ end:
|
||||
@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 @@ end:
|
||||
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,
|
||||
|
Reference in New Issue
Block a user