summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/loadxml.result20
-rw-r--r--mysql-test/std_data/loaddata/mdev14628a.xml4
-rw-r--r--mysql-test/std_data/loaddata/mdev14628b.xml3
-rw-r--r--mysql-test/t/loadxml.test19
-rw-r--r--sql/field.cc51
-rw-r--r--sql/field.h4
-rw-r--r--sql/sql_load.cc47
7 files changed, 110 insertions, 38 deletions
diff --git a/mysql-test/r/loadxml.result b/mysql-test/r/loadxml.result
index 1d7af4f8b38..b0fb867a676 100644
--- a/mysql-test/r/loadxml.result
+++ b/mysql-test/r/loadxml.result
@@ -134,3 +134,23 @@ 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;
+#
+# MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode
+#
+SET sql_mode=NO_AUTO_VALUE_ON_ZERO;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628a.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1 ORDER BY b;
+a b
+1 bbb1
+2 bbb2
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+SET sql_mode='';
+CREATE TABLE t1 (id INT, g GEOMETRY NOT NULL);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628b.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'g' at row 1
+SELECT * FROM t1;
+id g
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
diff --git a/mysql-test/std_data/loaddata/mdev14628a.xml b/mysql-test/std_data/loaddata/mdev14628a.xml
new file mode 100644
index 00000000000..34ee7336a5a
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev14628a.xml
@@ -0,0 +1,4 @@
+<list>
+ <row a="1" b="bbb1"/>
+ <row b="bbb2"/>
+</list>
diff --git a/mysql-test/std_data/loaddata/mdev14628b.xml b/mysql-test/std_data/loaddata/mdev14628b.xml
new file mode 100644
index 00000000000..2ea02d2a35f
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev14628b.xml
@@ -0,0 +1,3 @@
+<list>
+ <row id="1"/>
+</list>
diff --git a/mysql-test/t/loadxml.test b/mysql-test/t/loadxml.test
index 0bd97a81649..623deea6ec6 100644
--- a/mysql-test/t/loadxml.test
+++ b/mysql-test/t/loadxml.test
@@ -143,3 +143,22 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c1);
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
DROP VIEW v1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode
+--echo #
+
+SET sql_mode=NO_AUTO_VALUE_ON_ZERO;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628a.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1 ORDER BY b;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+SET sql_mode='';
+CREATE TABLE t1 (id INT, g GEOMETRY NOT NULL);
+--error ER_WARN_NULL_TO_NOTNULL
+LOAD XML INFILE '../../std_data/loaddata/mdev14628b.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
diff --git a/sql/field.cc b/sql/field.cc
index cfa9623fe17..b8d19c92cda 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1253,6 +1253,20 @@ warn:
}
+bool Field::load_data_set_null(THD *thd)
+{
+ reset();
+ set_null();
+ if (!maybe_null())
+ {
+ if (this != table->next_number_field)
+ set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1);
+ }
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
/**
Numeric fields base class constructor.
*/
@@ -5152,6 +5166,27 @@ int Field_timestamp::set_time()
return 0;
}
+
+bool Field_timestamp::load_data_set_null(THD *thd)
+{
+ if (!maybe_null())
+ {
+ /*
+ Timestamp fields that are NOT NULL are autoupdated if there is no
+ corresponding value in the data file.
+ */
+ set_time();
+ }
+ else
+ {
+ reset();
+ set_null();
+ }
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
#ifdef NOT_USED
static void store_native(ulonglong num, uchar *to, uint bytes)
{
@@ -8528,6 +8563,22 @@ bool Field_geom::can_optimize_range(const Item_bool_func *cond,
return item->cmp_type() == STRING_RESULT;
}
+
+bool Field_geom::load_data_set_null(THD *thd)
+{
+ Field_blob::reset();
+ if (!maybe_null())
+ {
+ my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field_name.str,
+ thd->get_stmt_da()->current_row_for_warning());
+ return true;
+ }
+ set_null();
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
#endif /*HAVE_SPATIAL*/
/****************************************************************************
diff --git a/sql/field.h b/sql/field.h
index 3147374d496..c9df9138b19 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1146,6 +1146,8 @@ public:
{ if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
inline bool maybe_null(void) const
{ return null_ptr != 0 || table->maybe_null; }
+ // Set to NULL on LOAD DATA or LOAD XML
+ virtual bool load_data_set_null(THD *thd);
/* @return true if this field is NULL-able (even if temporarily) */
inline bool real_maybe_null(void) const { return null_ptr != 0; }
@@ -2448,6 +2450,7 @@ public:
{
return get_equal_const_item_datetime(thd, ctx, const_item);
}
+ bool load_data_set_null(THD *thd);
uint size_of() const { return sizeof(*this); }
};
@@ -3509,6 +3512,7 @@ public:
but the underlying blob must still be reset.
*/
int reset(void) { return Field_blob::reset() || !maybe_null(); }
+ bool load_data_set_null(THD *thd);
geometry_type get_geometry_type() { return geom_type; };
static geometry_type geometry_type_merge(geometry_type, geometry_type);
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 6e3396f0fcf..dfb7ede04f4 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1015,7 +1015,6 @@ continue_loop:;
}
-
static int
read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields,
@@ -1094,28 +1093,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
else
{
- Field *field= real_item->field;
- if (field->reset())
- {
- my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name.str,
- thd->get_stmt_da()->current_row_for_warning());
+ DBUG_ASSERT(real_item->field->table == table);
+ if (real_item->field->load_data_set_null(thd))
DBUG_RETURN(1);
- }
- field->set_null();
- if (!field->maybe_null())
- {
- /*
- Timestamp fields that are NOT NULL are autoupdated if there is no
- corresponding value in the data file.
- */
- if (field->type() == MYSQL_TYPE_TIMESTAMP)
- field->set_time();
- else if (field != table->next_number_field)
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_NULL_TO_NOTNULL, 1);
- }
- /* Do not auto-update this field. */
- field->set_has_explicit_value();
}
continue;
@@ -1262,6 +1242,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
for ( ; ; it.rewind())
{
+ bool err;
if (thd->killed)
{
thd->send_kill_message();
@@ -1313,21 +1294,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
else
{
- Field *field= real_item->field;
- field->reset();
- field->set_null();
- if (field == table->next_number_field)
- table->auto_increment_field_not_null= TRUE;
- if (!field->maybe_null())
- {
- if (field->type() == FIELD_TYPE_TIMESTAMP)
- field->set_time();
- else if (field != table->next_number_field)
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_NULL_TO_NOTNULL, 1);
- }
- /* Do not auto-update this field. */
- field->set_has_explicit_value();
+ DBUG_ASSERT(real_item->field->table == table);
+ if (real_item->field->load_data_set_null(thd))
+ DBUG_RETURN(1);
}
continue;
}
@@ -1410,7 +1379,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1);
}
- if (write_record(thd, table, &info))
+ err= write_record(thd, table, &info);
+ table->auto_increment_field_not_null= false;
+ if (err)
DBUG_RETURN(1);
/*