Commit 0ef88485 authored by Alexander Barkov's avatar Alexander Barkov Committed by Alexander Barkov

Backporting MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode

This is a part of "MDEV-18045 Backporting the MDEV-15497 changes to 10.2 branch"
parent 15a20367
...@@ -134,3 +134,23 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2); ...@@ -134,3 +134,23 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
ERROR HY000: Column 'c2' is not updatable ERROR HY000: Column 'c2' is not updatable
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; 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;
<list>
<row a="1" b="bbb1"/>
<row b="bbb2"/>
</list>
...@@ -143,3 +143,22 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c1); ...@@ -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); LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; 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;
...@@ -1361,6 +1361,20 @@ int Field::store_hex_hybrid(const char *str, uint length) ...@@ -1361,6 +1361,20 @@ int Field::store_hex_hybrid(const char *str, uint length)
} }
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. Numeric fields base class constructor.
*/ */
...@@ -5348,6 +5362,27 @@ int Field_timestamp::set_time() ...@@ -5348,6 +5362,27 @@ int Field_timestamp::set_time()
return 0; 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 #ifdef NOT_USED
static void store_native(ulonglong num, uchar *to, uint bytes) static void store_native(ulonglong num, uchar *to, uint bytes)
{ {
...@@ -8699,6 +8734,22 @@ bool Field_geom::can_optimize_range(const Item_bool_func *cond, ...@@ -8699,6 +8734,22 @@ bool Field_geom::can_optimize_range(const Item_bool_func *cond,
return item->cmp_type() == STRING_RESULT; 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,
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*/ #endif /*HAVE_SPATIAL*/
/**************************************************************************** /****************************************************************************
......
...@@ -1143,6 +1143,8 @@ class Field: public Value_source ...@@ -1143,6 +1143,8 @@ class Field: public Value_source
{ if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; } { if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
inline bool maybe_null(void) const inline bool maybe_null(void) const
{ return null_ptr != 0 || table->maybe_null; } { 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) */ /* @return true if this field is NULL-able (even if temporarily) */
inline bool real_maybe_null(void) const { return null_ptr != 0; } inline bool real_maybe_null(void) const { return null_ptr != 0; }
...@@ -2482,6 +2484,7 @@ class Field_timestamp :public Field_temporal { ...@@ -2482,6 +2484,7 @@ class Field_timestamp :public Field_temporal {
{ {
return get_equal_const_item_datetime(thd, ctx, const_item); return get_equal_const_item_datetime(thd, ctx, const_item);
} }
bool load_data_set_null(THD *thd);
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
}; };
...@@ -3502,6 +3505,7 @@ class Field_geom :public Field_blob { ...@@ -3502,6 +3505,7 @@ class Field_geom :public Field_blob {
but the underlying blob must still be reset. but the underlying blob must still be reset.
*/ */
int reset(void) { return Field_blob::reset() || !maybe_null(); } int reset(void) { return Field_blob::reset() || !maybe_null(); }
bool load_data_set_null(THD *thd);
geometry_type get_geometry_type() { return geom_type; }; geometry_type get_geometry_type() { return geom_type; };
static geometry_type geometry_type_merge(geometry_type, geometry_type); static geometry_type geometry_type_merge(geometry_type, geometry_type);
......
...@@ -1053,7 +1053,6 @@ continue_loop:; ...@@ -1053,7 +1053,6 @@ continue_loop:;
} }
static int static int
read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields, List<Item> &fields_vars, List<Item> &set_fields,
...@@ -1132,28 +1131,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, ...@@ -1132,28 +1131,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
} }
else else
{ {
Field *field= real_item->field; DBUG_ASSERT(real_item->field->table == table);
if (field->reset()) if (real_item->field->load_data_set_null(thd))
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
thd->get_stmt_da()->current_row_for_warning());
DBUG_RETURN(1); 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; continue;
...@@ -1301,6 +1281,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, ...@@ -1301,6 +1281,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
for ( ; ; it.rewind()) for ( ; ; it.rewind())
{ {
bool err;
if (thd->killed) if (thd->killed)
{ {
thd->send_kill_message(); thd->send_kill_message();
...@@ -1352,21 +1333,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, ...@@ -1352,21 +1333,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
} }
else else
{ {
Field *field= real_item->field; DBUG_ASSERT(real_item->field->table == table);
field->reset(); if (real_item->field->load_data_set_null(thd))
field->set_null(); DBUG_RETURN(1);
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();
} }
continue; continue;
} }
...@@ -1450,7 +1419,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, ...@@ -1450,7 +1419,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
} }
WSREP_LOAD_DATA_SPLIT(thd, table, info); WSREP_LOAD_DATA_SPLIT(thd, table, info);
if (write_record(thd, table, &info)) err= write_record(thd, table, &info);
table->auto_increment_field_not_null= false;
if (err)
DBUG_RETURN(1); DBUG_RETURN(1);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment