mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-10201 Bad results for CREATE TABLE t1 (a INT DEFAULT b, b INT DEFAULT 4)
Optionally do table->update_default_fields() even for INSERT that supposedly provides values for all column. Because these "values" might be DEFAULT, which would need table->update_default_fields() at the end. Also set Item_default_value::used_tables() from the default expression. Non-zero used_field() means that mysql_insert() will initialize all fields to their default values (with restore_record()) even if all columns are later provided with values. Because default expressions may refer to other columns and they must be initialized.
This commit is contained in:
@ -1553,7 +1553,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
`s` int(11) DEFAULT NULL,
|
`s` int(11) DEFAULT NULL,
|
||||||
`b` timestamp(6) NOT NULL DEFAULT sysdate(6)
|
`b` timestamp(6) NOT NULL DEFAULT sysdate(6)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
INSERT INTO t1 VALUES (DEFAULT, SLEEP(0.1), DEFAULT);
|
INSERT INTO t1 VALUES (DEFAULT(a), SLEEP(0.1), DEFAULT(b));
|
||||||
SELECT b>a FROM t1;
|
SELECT b>a FROM t1;
|
||||||
b>a
|
b>a
|
||||||
1
|
1
|
||||||
@ -3316,7 +3316,6 @@ ERROR 42000: Invalid default value for 'c'
|
|||||||
EXECUTE stmt USING @a;
|
EXECUTE stmt USING @a;
|
||||||
ERROR 42000: Invalid default value for 'c'
|
ERROR 42000: Invalid default value for 'c'
|
||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
# end of 10.2 test
|
|
||||||
set sql_mode=ansi_quotes;
|
set sql_mode=ansi_quotes;
|
||||||
create table t1 (a int, b int default (a+1));
|
create table t1 (a int, b int default (a+1));
|
||||||
show create table t1;
|
show create table t1;
|
||||||
@ -3349,3 +3348,18 @@ a b
|
|||||||
30 31
|
30 31
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set sql_mode=default;
|
set sql_mode=default;
|
||||||
|
create table t1 (a int default b, b int default 4, t text);
|
||||||
|
insert into t1 (b, t) values (5, '1 column is omitted');
|
||||||
|
insert into t1 values (default, 5, '2 column gets DEFAULT, keyword');
|
||||||
|
insert into t1 values (default(a), 5, '3 column gets DEFAULT(a), expression');
|
||||||
|
insert into t1 values (default(a)+0, 5, '4 also expression DEFAULT(0)+0');
|
||||||
|
insert into t1 values (b, 5, '5 the value of the DEFAULT(a), that is b');
|
||||||
|
select * from t1 order by t;
|
||||||
|
a b t
|
||||||
|
5 5 1 column is omitted
|
||||||
|
5 5 2 column gets DEFAULT, keyword
|
||||||
|
4 5 3 column gets DEFAULT(a), expression
|
||||||
|
4 5 4 also expression DEFAULT(0)+0
|
||||||
|
4 5 5 the value of the DEFAULT(a), that is b
|
||||||
|
drop table t1;
|
||||||
|
# end of 10.2 test
|
||||||
|
@ -1099,7 +1099,7 @@ SET time_zone=DEFAULT, timestamp= DEFAULT;
|
|||||||
# SYSDATE is evaluated during get_date() rather than fix_fields.
|
# SYSDATE is evaluated during get_date() rather than fix_fields.
|
||||||
CREATE TABLE t1 (a TIMESTAMP(6) DEFAULT SYSDATE(6), s INT, b TIMESTAMP(6) DEFAULT SYSDATE(6));
|
CREATE TABLE t1 (a TIMESTAMP(6) DEFAULT SYSDATE(6), s INT, b TIMESTAMP(6) DEFAULT SYSDATE(6));
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
INSERT INTO t1 VALUES (DEFAULT, SLEEP(0.1), DEFAULT);
|
INSERT INTO t1 VALUES (DEFAULT(a), SLEEP(0.1), DEFAULT(b));
|
||||||
SELECT b>a FROM t1;
|
SELECT b>a FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
@ -2012,7 +2012,6 @@ INSERT INTO t1 VALUES (1),(2),(3);
|
|||||||
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT;
|
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-11134 Assertion `fixed' failed in Item::const_charset_converter(THD*, CHARSET_INFO*, bool, const char*)
|
--echo # MDEV-11134 Assertion `fixed' failed in Item::const_charset_converter(THD*, CHARSET_INFO*, bool, const char*)
|
||||||
--echo #
|
--echo #
|
||||||
@ -2041,10 +2040,6 @@ EXECUTE stmt USING @a;
|
|||||||
EXECUTE stmt USING @a;
|
EXECUTE stmt USING @a;
|
||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--echo # end of 10.2 test
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# ANSI_QUOTES
|
# ANSI_QUOTES
|
||||||
#
|
#
|
||||||
@ -2062,3 +2057,16 @@ select * from t1;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
set sql_mode=default;
|
set sql_mode=default;
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-10201 Bad results for CREATE TABLE t1 (a INT DEFAULT b, b INT DEFAULT 4)
|
||||||
|
#
|
||||||
|
create table t1 (a int default b, b int default 4, t text);
|
||||||
|
insert into t1 (b, t) values (5, '1 column is omitted');
|
||||||
|
insert into t1 values (default, 5, '2 column gets DEFAULT, keyword');
|
||||||
|
insert into t1 values (default(a), 5, '3 column gets DEFAULT(a), expression');
|
||||||
|
insert into t1 values (default(a)+0, 5, '4 also expression DEFAULT(0)+0');
|
||||||
|
insert into t1 values (b, 5, '5 the value of the DEFAULT(a), that is b');
|
||||||
|
select * from t1 order by t;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--echo # end of 10.2 test
|
||||||
|
11
sql/field.cc
11
sql/field.cc
@ -5264,6 +5264,7 @@ int Field_timestamp::set_time()
|
|||||||
Mark the field as having an explicit default value.
|
Mark the field as having an explicit default value.
|
||||||
|
|
||||||
@param value if available, the value that the field is being set to
|
@param value if available, the value that the field is being set to
|
||||||
|
@returns whether the explicit default bit was set
|
||||||
|
|
||||||
@note
|
@note
|
||||||
Fields that have an explicit default value should not be updated
|
Fields that have an explicit default value should not be updated
|
||||||
@ -5279,13 +5280,14 @@ int Field_timestamp::set_time()
|
|||||||
This is how MySQL has worked since it's start.
|
This is how MySQL has worked since it's start.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Field_timestamp::set_explicit_default(Item *value)
|
bool Field_timestamp::set_explicit_default(Item *value)
|
||||||
{
|
{
|
||||||
if (((value->type() == Item::DEFAULT_VALUE_ITEM &&
|
if (((value->type() == Item::DEFAULT_VALUE_ITEM &&
|
||||||
!((Item_default_value*)value)->arg) ||
|
!((Item_default_value*)value)->arg) ||
|
||||||
(!maybe_null() && value->null_value)))
|
(!maybe_null() && value->null_value)))
|
||||||
return;
|
return false;
|
||||||
set_has_explicit_value();
|
set_has_explicit_value();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
@ -10790,12 +10792,13 @@ key_map Field::get_possible_keys()
|
|||||||
analyzed to check if it really should count as a value.
|
analyzed to check if it really should count as a value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Field::set_explicit_default(Item *value)
|
bool Field::set_explicit_default(Item *value)
|
||||||
{
|
{
|
||||||
if (value->type() == Item::DEFAULT_VALUE_ITEM &&
|
if (value->type() == Item::DEFAULT_VALUE_ITEM &&
|
||||||
!((Item_default_value*)value)->arg)
|
!((Item_default_value*)value)->arg)
|
||||||
return;
|
return false;
|
||||||
set_has_explicit_value();
|
set_has_explicit_value();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
12
sql/field.h
12
sql/field.h
@ -954,7 +954,7 @@ public:
|
|||||||
{
|
{
|
||||||
return bitmap_is_set(&table->has_value_set, field_index);
|
return bitmap_is_set(&table->has_value_set, field_index);
|
||||||
}
|
}
|
||||||
virtual void set_explicit_default(Item *value);
|
virtual bool set_explicit_default(Item *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Evaluates the @c UPDATE default function, if one exists, and stores the
|
Evaluates the @c UPDATE default function, if one exists, and stores the
|
||||||
@ -2379,9 +2379,9 @@ public:
|
|||||||
uint32 pack_length() const { return 4; }
|
uint32 pack_length() const { return 4; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
bool zero_pack() const { return 0; }
|
bool zero_pack() const { return 0; }
|
||||||
virtual int set_time();
|
int set_time();
|
||||||
virtual void set_explicit_default(Item *value);
|
bool set_explicit_default(Item *value);
|
||||||
virtual int evaluate_update_default_function()
|
int evaluate_update_default_function()
|
||||||
{
|
{
|
||||||
int res= 0;
|
int res= 0;
|
||||||
if (has_update_default_function())
|
if (has_update_default_function())
|
||||||
@ -2813,8 +2813,8 @@ public:
|
|||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||||
{ return Field_datetime::get_TIME(ltime, ptr, fuzzydate); }
|
{ return Field_datetime::get_TIME(ltime, ptr, fuzzydate); }
|
||||||
virtual int set_time();
|
int set_time();
|
||||||
virtual int evaluate_update_default_function()
|
int evaluate_update_default_function()
|
||||||
{
|
{
|
||||||
int res= 0;
|
int res= 0;
|
||||||
if (has_update_default_function())
|
if (has_update_default_function())
|
||||||
|
16
sql/item.cc
16
sql/item.cc
@ -8834,15 +8834,23 @@ bool Item_default_value::send(Protocol *protocol, String *buffer)
|
|||||||
int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
|
int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
|
||||||
{
|
{
|
||||||
if (arg)
|
if (arg)
|
||||||
calculate();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
calculate();
|
||||||
|
return Item_field::save_in_field(field_arg, no_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field_arg->default_value && field_arg->default_value->flags)
|
||||||
|
return 0; // defaut fields will be set later, no need to do it twice
|
||||||
return field_arg->save_in_field_default_value(context->error_processor ==
|
return field_arg->save_in_field_default_value(context->error_processor ==
|
||||||
&view_error_processor);
|
&view_error_processor);
|
||||||
}
|
|
||||||
return Item_field::save_in_field(field_arg, no_conversions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table_map Item_default_value::used_tables() const
|
||||||
|
{
|
||||||
|
if (field && field->default_value && field->default_value->flags)
|
||||||
|
return field->default_value->expr->used_tables();
|
||||||
|
return static_cast<table_map>(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method like the walk method traverses the item tree, but at the
|
This method like the walk method traverses the item tree, but at the
|
||||||
|
@ -5185,7 +5185,7 @@ public:
|
|||||||
param->set_default();
|
param->set_default();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
table_map used_tables() const { return (table_map)0L; }
|
table_map used_tables() const;
|
||||||
Field *get_tmp_table_field() { return 0; }
|
Field *get_tmp_table_field() { return 0; }
|
||||||
Item *get_tmp_table_item(THD *thd) { return this; }
|
Item *get_tmp_table_item(THD *thd) { return this; }
|
||||||
Item_field *field_for_view_update() { return 0; }
|
Item_field *field_for_view_update() { return 0; }
|
||||||
|
@ -8102,6 +8102,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
|
|||||||
{
|
{
|
||||||
List_iterator_fast<Item> v(values);
|
List_iterator_fast<Item> v(values);
|
||||||
List<TABLE> tbl_list;
|
List<TABLE> tbl_list;
|
||||||
|
bool all_fields_have_values= true;
|
||||||
Item *value;
|
Item *value;
|
||||||
Field *field;
|
Field *field;
|
||||||
bool abort_on_warning_saved= thd->abort_on_warning;
|
bool abort_on_warning_saved= thd->abort_on_warning;
|
||||||
@ -8154,9 +8155,11 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
|
|||||||
else
|
else
|
||||||
if (value->save_in_field(field, 0) < 0)
|
if (value->save_in_field(field, 0) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
field->set_explicit_default(value);
|
all_fields_have_values &= field->set_explicit_default(value);
|
||||||
}
|
}
|
||||||
/* There is no default fields to update, as all fields are updated */
|
if (!all_fields_have_values && table->default_field &&
|
||||||
|
table->update_default_fields(0, ignore_errors))
|
||||||
|
goto err;
|
||||||
/* Update virtual fields */
|
/* Update virtual fields */
|
||||||
thd->abort_on_warning= FALSE;
|
thd->abort_on_warning= FALSE;
|
||||||
if (table->vfield &&
|
if (table->vfield &&
|
||||||
|
@ -991,6 +991,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
share->default_values[share->null_bytes - 1];
|
share->default_values[share->null_bytes - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
table->reset_default_fields();
|
||||||
if (fill_record_n_invoke_before_triggers(thd, table,
|
if (fill_record_n_invoke_before_triggers(thd, table,
|
||||||
table->field_to_fill(),
|
table->field_to_fill(),
|
||||||
*values, 0, TRG_EVENT_INSERT))
|
*values, 0, TRG_EVENT_INSERT))
|
||||||
|
Reference in New Issue
Block a user