diff options
author | Sergei Golubchik <serg@mariadb.org> | 2017-05-08 19:23:39 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-05-09 00:28:43 +0200 |
commit | fbdf18f86e3a631034800eb534f29f615ff7a1a4 (patch) | |
tree | 9bf3245f5b2c6b283453a7fd844580127f3afc9d | |
parent | d738722eeee34df67081f8afe5ccd5d28c1e275f (diff) | |
download | mariadb-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.result | 11 | ||||
-rw-r--r-- | mysql-test/std_data/loaddata/mdev12696.xml | 9 | ||||
-rw-r--r-- | mysql-test/t/loadxml.test | 13 | ||||
-rw-r--r-- | sql/sql_load.cc | 41 |
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); } } |