diff options
author | unknown <anozdrin/alik@quad.opbmk> | 2008-03-28 18:59:13 +0300 |
---|---|---|
committer | unknown <anozdrin/alik@quad.opbmk> | 2008-03-28 18:59:13 +0300 |
commit | 4ec65151dc8e1b30b05a84c2f3a8bd2b9ce641c6 (patch) | |
tree | 3da9187f61f42e5a0993052dfefdd40d9f13e8a6 /sql/sql_load.cc | |
parent | 7c156537cc51c42ae58c61f6bb70a307b8216334 (diff) | |
download | mariadb-git-4ec65151dc8e1b30b05a84c2f3a8bd2b9ce641c6.tar.gz |
Fix for Bug#35469: server crash with LOAD DATA INFILE to a VIEW.
The problem was that LOAD DATA code (sql_load.cc) didn't take into
account that there may be items, representing references to other
columns. This is a usual case in views. The crash happened because
Item_direct_view_ref was casted to Item_user_var_as_out_param,
which is not a base class.
The fix is to
1) Handle references properly;
2) Ensure that an item is treated as a user variable only when
it is a user variable indeed;
3) Report an error if LOAD DATA is used to load data into
non-updatable column.
mysql-test/r/loaddata.result:
Update result file.
mysql-test/t/loaddata.test:
Add a test case form Bug#35469: server crash with
LOAD DATA INFILE to a VIEW.
sql/share/errmsg.txt:
Introduce a new error.
sql/sql_load.cc:
Handle reference-items properly.
mysql-test/std_data/bug35649.data:
Add a data file for the test case.
Diffstat (limited to 'sql/sql_load.cc')
-rw-r--r-- | sql/sql_load.cc | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 4da3c19bb3c..e9fd04dff15 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -233,9 +233,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, while ((item= it++)) { - if (item->type() == Item::FIELD_ITEM) + Item *real_item= item->real_item(); + + if (real_item->type() == Item::FIELD_ITEM) { - Field *field= ((Item_field*)item)->field; + Field *field= ((Item_field*)real_item)->field; if (field->flags & BLOB_FLAG) { use_blobs= 1; @@ -244,7 +246,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, else tot_length+= field->field_length; } - else + else if (item->type() == Item::STRING_ITEM) use_vars= 1; } if (use_blobs && !ex->line_term->length() && !field_term->length()) @@ -705,6 +707,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, { uint length; byte *pos; + Item *real_item; if (read_info.read_field()) break; @@ -716,14 +719,17 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, pos=read_info.row_start; length=(uint) (read_info.row_end-pos); + real_item= item->real_item(); + if (!read_info.enclosed && (enclosed_length && length == 4 && !memcmp(pos, STRING_WITH_LEN("NULL"))) || (length == 1 && read_info.found_null)) { - if (item->type() == Item::FIELD_ITEM) + + if (real_item->type() == Item::FIELD_ITEM) { - Field *field= ((Item_field *)item)->field; + Field *field= ((Item_field *)real_item)->field; if (field->reset()) { my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name, @@ -740,25 +746,39 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, ER_WARN_NULL_TO_NOTNULL, 1); } } - else + else if (item->type() == Item::STRING_ITEM) + { ((Item_user_var_as_out_param *)item)->set_null_value( read_info.read_charset); + } + else + { + my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name()); + DBUG_RETURN(1); + } + continue; } - if (item->type() == Item::FIELD_ITEM) + if (real_item->type() == Item::FIELD_ITEM) { - - Field *field= ((Item_field *)item)->field; + Field *field= ((Item_field *)real_item)->field; field->set_notnull(); read_info.row_end[0]=0; // Safe to change end marker if (field == table->next_number_field) table->auto_increment_field_not_null= TRUE; field->store((char*) pos, length, read_info.read_charset); } - else + else if (item->type() == Item::STRING_ITEM) + { ((Item_user_var_as_out_param *)item)->set_value((char*) pos, length, - read_info.read_charset); + read_info.read_charset); + } + else + { + my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name()); + DBUG_RETURN(1); + } } if (read_info.error) break; @@ -774,9 +794,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, break; for (; item ; item= it++) { - if (item->type() == Item::FIELD_ITEM) + Item *real_item= item->real_item(); + if (real_item->type() == Item::FIELD_ITEM) { - Field *field= ((Item_field *)item)->field; + Field *field= ((Item_field *)real_item)->field; if (field->reset()) { my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name, @@ -796,9 +817,16 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, ER_WARN_TOO_FEW_RECORDS, ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count); } - else + else if (item->type() == Item::STRING_ITEM) + { ((Item_user_var_as_out_param *)item)->set_null_value( read_info.read_charset); + } + else + { + my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name()); + DBUG_RETURN(1); + } } } |