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);
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;
<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);
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;
......@@ -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.
*/
......@@ -5348,6 +5362,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)
{
......@@ -8699,6 +8734,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,
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*/
/****************************************************************************
......
......@@ -1143,6 +1143,8 @@ class Field: public Value_source
{ 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; }
......@@ -2482,6 +2484,7 @@ class Field_timestamp :public Field_temporal {
{
return get_equal_const_item_datetime(thd, ctx, const_item);
}
bool load_data_set_null(THD *thd);
uint size_of() const { return sizeof(*this); }
};
......@@ -3502,6 +3505,7 @@ class Field_geom :public Field_blob {
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);
......
......@@ -1053,7 +1053,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,
......@@ -1132,28 +1131,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,
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;
......@@ -1301,6 +1281,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();
......@@ -1352,21 +1333,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;
}
......@@ -1450,7 +1419,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
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);
/*
......
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