summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/loaddata.result76
-rw-r--r--mysql-test/std_data/bug35649.data3
-rw-r--r--mysql-test/t/loaddata.test82
-rw-r--r--sql/share/errmsg.txt4
-rw-r--r--sql/sql_load.cc56
5 files changed, 207 insertions, 14 deletions
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index 7fff2700779..156a78eb627 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -252,3 +252,79 @@ SELECT * FROM t1;
c1 c2 c3 c4
10 1970-02-01 01:02:03 1.1e-100 1.1e+100
DROP TABLE t1;
+
+# --
+# -- Bug#35469: server crash with LOAD DATA INFILE to a VIEW.
+# --
+
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+DROP VIEW IF EXISTS v2;
+DROP VIEW IF EXISTS v3;
+
+CREATE TABLE t1(c1 INT, c2 VARCHAR(255));
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE VIEW v2 AS SELECT 1 + 2 AS c0, c1, c2 FROM t1;
+CREATE VIEW v3 AS SELECT 1 AS d1, 2 AS d2;
+
+LOAD DATA INFILE '../std_data_ln/bug35649.data' INTO TABLE v1
+FIELDS ESCAPED BY '\\'
+ TERMINATED BY ','
+ ENCLOSED BY '"'
+ LINES TERMINATED BY '\n' (c1, c2);
+
+SELECT * FROM t1;
+c1 c2
+1 "string1"
+2 "string2"
+3 "string3"
+
+SELECT * FROM v1;
+c1 c2
+1 "string1"
+2 "string2"
+3 "string3"
+
+DELETE FROM t1;
+
+LOAD DATA INFILE '../std_data_ln/bug35649.data' INTO TABLE v2
+FIELDS ESCAPED BY '\\'
+ TERMINATED BY ','
+ ENCLOSED BY '"'
+ LINES TERMINATED BY '\n' (c1, c2);
+
+SELECT * FROM t1;
+c1 c2
+1 "string1"
+2 "string2"
+3 "string3"
+
+SELECT * FROM v2;
+c0 c1 c2
+3 1 "string1"
+3 2 "string2"
+3 3 "string3"
+
+DELETE FROM t1;
+
+LOAD DATA INFILE '../std_data_ln/bug35649.data' INTO TABLE v2
+FIELDS ESCAPED BY '\\'
+ TERMINATED BY ','
+ ENCLOSED BY '"'
+ LINES TERMINATED BY '\n' (c0, c2);
+ERROR HY000: Invalid column reference (v2.c0) in LOAD DATA
+
+LOAD DATA INFILE '../std_data_ln/bug35649.data' INTO TABLE v3
+FIELDS ESCAPED BY '\\'
+ TERMINATED BY ','
+ ENCLOSED BY '"'
+ LINES TERMINATED BY '\n' (d1, d2);
+ERROR HY000: The target table v3 of the LOAD is not updatable
+
+DROP TABLE t1;
+DROP VIEW v1;
+DROP VIEW v2;
+DROP VIEW v3;
+
+# -- End of Bug#35469.
diff --git a/mysql-test/std_data/bug35649.data b/mysql-test/std_data/bug35649.data
new file mode 100644
index 00000000000..afcd9e9cc95
--- /dev/null
+++ b/mysql-test/std_data/bug35649.data
@@ -0,0 +1,3 @@
+"1", "string1"
+"2", "string2"
+"3", "string3"
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index 9eb92015399..68cf84b7fac 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -236,4 +236,86 @@ SELECT * FROM t1;
remove_file $MYSQLTEST_VARDIR/tmp/t1;
DROP TABLE t1;
+###########################################################################
+
+--echo
+--echo # --
+--echo # -- Bug#35469: server crash with LOAD DATA INFILE to a VIEW.
+--echo # --
+
+--echo
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+DROP VIEW IF EXISTS v2;
+DROP VIEW IF EXISTS v3;
+--enable_warnings
+
+--echo
+CREATE TABLE t1(c1 INT, c2 VARCHAR(255));
+
+--echo
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE VIEW v2 AS SELECT 1 + 2 AS c0, c1, c2 FROM t1;
+CREATE VIEW v3 AS SELECT 1 AS d1, 2 AS d2;
+
+--echo
+LOAD DATA INFILE '../std_data_ln/bug35649.data' INTO TABLE v1
+ FIELDS ESCAPED BY '\\'
+ TERMINATED BY ','
+ ENCLOSED BY '"'
+ LINES TERMINATED BY '\n' (c1, c2);
+
+--echo
+SELECT * FROM t1;
+
+--echo
+SELECT * FROM v1;
+
+--echo
+DELETE FROM t1;
+
+--echo
+LOAD DATA INFILE '../std_data_ln/bug35649.data' INTO TABLE v2
+ FIELDS ESCAPED BY '\\'
+ TERMINATED BY ','
+ ENCLOSED BY '"'
+ LINES TERMINATED BY '\n' (c1, c2);
+
+--echo
+SELECT * FROM t1;
+
+--echo
+SELECT * FROM v2;
+
+--echo
+DELETE FROM t1;
+
+--echo
+--error ER_LOAD_DATA_INVALID_COLUMN
+LOAD DATA INFILE '../std_data_ln/bug35649.data' INTO TABLE v2
+ FIELDS ESCAPED BY '\\'
+ TERMINATED BY ','
+ ENCLOSED BY '"'
+ LINES TERMINATED BY '\n' (c0, c2);
+
+--echo
+--error ER_NON_UPDATABLE_TABLE
+LOAD DATA INFILE '../std_data_ln/bug35649.data' INTO TABLE v3
+ FIELDS ESCAPED BY '\\'
+ TERMINATED BY ','
+ ENCLOSED BY '"'
+ LINES TERMINATED BY '\n' (d1, d2);
+
+--echo
+DROP TABLE t1;
+DROP VIEW v1;
+DROP VIEW v2;
+DROP VIEW v3;
+
+--echo
+--echo # -- End of Bug#35469.
+
+###########################################################################
+
# End of 5.0 tests
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 9e6cf462113..a3514776d6e 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5641,3 +5641,7 @@ ER_NAME_BECOMES_EMPTY
eng "Name '%-.64s' has become ''"
ER_AMBIGUOUS_FIELD_TERM
eng "First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY"
+
+ER_LOAD_DATA_INVALID_COLUMN
+ eng "Invalid column reference (%-.64s) in LOAD DATA"
+
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);
+ }
}
}