summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2017-05-08 19:23:39 +0200
committerSergei Golubchik <serg@mariadb.org>2017-05-09 00:28:43 +0200
commitfbdf18f86e3a631034800eb534f29f615ff7a1a4 (patch)
tree9bf3245f5b2c6b283453a7fd844580127f3afc9d
parentd738722eeee34df67081f8afe5ccd5d28c1e275f (diff)
downloadmariadb-git-fbdf18f86e3a631034800eb534f29f615ff7a1a4.tar.gz
MDEV-12696 Crash with LOAD XML and non-updatable VIEW column
extend the fix from 5.5 (in read_sep_field()) to apply to read_xml_field()
-rw-r--r--mysql-test/r/loadxml.result11
-rw-r--r--mysql-test/std_data/loaddata/mdev12696.xml9
-rw-r--r--mysql-test/t/loadxml.test13
-rw-r--r--sql/sql_load.cc41
4 files changed, 62 insertions, 12 deletions
diff --git a/mysql-test/r/loadxml.result b/mysql-test/r/loadxml.result
index 1128caf9122..05b3ddf5bc9 100644
--- a/mysql-test/r/loadxml.result
+++ b/mysql-test/r/loadxml.result
@@ -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;
diff --git a/mysql-test/std_data/loaddata/mdev12696.xml b/mysql-test/std_data/loaddata/mdev12696.xml
new file mode 100644
index 00000000000..a2789acbde5
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev12696.xml
@@ -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>
diff --git a/mysql-test/t/loadxml.test b/mysql-test/t/loadxml.test
index 93e6e82189f..0bd97a81649 100644
--- a/mysql-test/t/loadxml.test
+++ b/mysql-test/t/loadxml.test
@@ -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;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 625269607d6..0168f46f8ee 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -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)
@@ -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;
@@ -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)
@@ -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.
@@ -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);
}
}