Skip to content

Commit

Permalink
MDEV-12696 Crash with LOAD XML and non-updatable VIEW column
Browse files Browse the repository at this point in the history
extend the fix from 5.5 (in read_sep_field()) to apply to read_xml_field()
  • Loading branch information
vuvova committed May 8, 2017
1 parent d738722 commit fbdf18f
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 12 deletions.
11 changes: 11 additions & 0 deletions mysql-test/r/loadxml.result
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,14 @@ col1 col2 col3
ABC DEF NULL
GHI NULL 123
DROP TABLE t1;
#
# MDEV-12696 Crash with LOAD XML and non-updatable VIEW column
#
CREATE TABLE t1 (c1 TEXT);
CREATE VIEW v1 AS SELECT CONCAT(c1,'') AS c1, NULL AS c2 FROM t1;
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c1);
ERROR HY000: Column 'c1' is not updatable
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
ERROR HY000: Column 'c2' is not updatable
DROP VIEW v1;
DROP TABLE t1;
9 changes: 9 additions & 0 deletions mysql-test/std_data/loaddata/mdev12696.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0"?>

<resultset statement="SELECT 'test' AS c1, NULL AS c2
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
<field name="c1">test</field>
<field name="c2" xsi:nil="true" />
</row>
</resultset>
13 changes: 13 additions & 0 deletions mysql-test/t/loadxml.test
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,16 @@ CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 INTEGER);
LOAD XML INFILE '../../std_data/bug16171518_2.dat' INTO TABLE t1;
SELECT * FROM t1 ORDER BY col1, col2, col3;
DROP TABLE t1;

--echo #
--echo # MDEV-12696 Crash with LOAD XML and non-updatable VIEW column
--echo #

CREATE TABLE t1 (c1 TEXT);
CREATE VIEW v1 AS SELECT CONCAT(c1,'') AS c1, NULL AS c2 FROM t1;
--error ER_NONUPDATEABLE_COLUMN
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c1);
--error ER_NONUPDATEABLE_COLUMN
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
DROP VIEW v1;
DROP TABLE t1;
41 changes: 29 additions & 12 deletions sql/sql_load.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1279,11 +1279,19 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
while(tag && strcmp(tag->field.c_ptr(), item->name) != 0)
tag= xmlit++;

Item_field *real_item= item->field_for_view_update();
if (!tag) // found null
{
if (item->type() == Item::FIELD_ITEM)
if (item->type() == Item::STRING_ITEM)
((Item_user_var_as_out_param *) item)->set_null_value(cs);
else if (!real_item)
{
Field *field= ((Item_field *) item)->field;
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
DBUG_RETURN(1);
}
else
{
Field *field= real_item->field;
field->reset();
field->set_null();
if (field == table->next_number_field)
Expand All @@ -1299,12 +1307,19 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
/* Do not auto-update this field. */
field->set_has_explicit_value();
}
else
((Item_user_var_as_out_param *) item)->set_null_value(cs);
continue;
}

if (item->type() == Item::FIELD_ITEM)
if (item->type() == Item::STRING_ITEM)
((Item_user_var_as_out_param *) item)->set_value(
(char *) tag->value.ptr(),
tag->value.length(), cs);
else if (!real_item)
{
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
DBUG_RETURN(1);
}
else
{

Field *field= ((Item_field *)item)->field;
Expand All @@ -1314,10 +1329,6 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
field->store((char *) tag->value.ptr(), tag->value.length(), cs);
field->set_has_explicit_value();
}
else
((Item_user_var_as_out_param *) item)->set_value(
(char *) tag->value.ptr(),
tag->value.length(), cs);
}

if (read_info.error)
Expand All @@ -1337,7 +1348,15 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,

for ( ; item; item= it++)
{
if (item->type() == Item::FIELD_ITEM)
Item_field *real_item= item->field_for_view_update();
if (item->type() == Item::STRING_ITEM)
((Item_user_var_as_out_param *)item)->set_null_value(cs);
else if (!real_item)
{
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
DBUG_RETURN(1);
}
else
{
/*
QQ: We probably should not throw warning for each field.
Expand All @@ -1351,8 +1370,6 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
ER_THD(thd, ER_WARN_TOO_FEW_RECORDS),
thd->get_stmt_da()->current_row_for_warning());
}
else
((Item_user_var_as_out_param *)item)->set_null_value(cs);
}
}

Expand Down

0 comments on commit fbdf18f

Please sign in to comment.