MDEV-29075 Changing explicit_defaults_for_timestamp within stored procedure works inconsistently

This commit is contained in:
Sergei Golubchik 2022-07-29 15:39:57 +02:00
parent b174ec169d
commit 56c7d14217
9 changed files with 147 additions and 39 deletions

View file

@ -5,19 +5,10 @@ CREATE TABLE t1 (a TIMESTAMP NULL);
SHOW CREATE TABLE t1;
DROP TABLE t1;
if (`SELECT @@explicit_defaults_for_timestamp=0`)
{
--error ER_INVALID_DEFAULT
CREATE TABLE t1 (a TIMESTAMP DEFAULT NULL);
}
if (`SELECT @@explicit_defaults_for_timestamp=1`)
{
CREATE TABLE t1 (a TIMESTAMP DEFAULT NULL);
SHOW CREATE TABLE t1;
DROP TABLE t1;
}
CREATE TABLE t1 (a TIMESTAMP DEFAULT NULL);
INSERT t1 () VALUES ();
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP DEFAULT '0000-00-00 00:00:00');
SHOW CREATE TABLE t1;
@ -110,3 +101,34 @@ SELECT * FROM t1;
DROP TABLE t1;
SET sql_mode=DEFAULT;
SET timestamp=DEFAULT;
--echo #
--echo # MDEV-29075 Changing explicit_defaults_for_timestamp within stored procedure works inconsistently
--echo #
set statement explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp for create table t1 (ts timestamp);
show create table t1;
drop table t1;
--delimiter $
create procedure pr()
begin
set explicit_defaults_for_timestamp= 1-@@explicit_defaults_for_timestamp;
create table t1 (ts timestamp);
end $
--delimiter ;
call pr();
show create table t1;
drop procedure pr;
drop table t1;
prepare stmt from 'create or replace table t1 (a timestamp)';
execute stmt;
show create table t1;
set explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp;
execute stmt;
show create table t1;
set explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp;
execute stmt;
show create table t1;
drop table t1;

View file

@ -14,7 +14,13 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP DEFAULT NULL);
ERROR 42000: Invalid default value for 'a'
INSERT t1 () VALUES ();
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP DEFAULT '0000-00-00 00:00:00');
SHOW CREATE TABLE t1;
Table Create Table
@ -187,3 +193,48 @@ a
DROP TABLE t1;
SET sql_mode=DEFAULT;
SET timestamp=DEFAULT;
#
# MDEV-29075 Changing explicit_defaults_for_timestamp within stored procedure works inconsistently
#
set statement explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp for create table t1 (ts timestamp);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`ts` timestamp NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create procedure pr()
begin
set explicit_defaults_for_timestamp= 1-@@explicit_defaults_for_timestamp;
create table t1 (ts timestamp);
end $
call pr();
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`ts` timestamp NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop procedure pr;
drop table t1;
prepare stmt from 'create or replace table t1 (a timestamp)';
execute stmt;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
set explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp;
execute stmt;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=MyISAM DEFAULT CHARSET=latin1
set explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp;
execute stmt;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;

View file

@ -14,6 +14,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP DEFAULT NULL);
INSERT t1 () VALUES ();
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@ -194,3 +195,48 @@ a
DROP TABLE t1;
SET sql_mode=DEFAULT;
SET timestamp=DEFAULT;
#
# MDEV-29075 Changing explicit_defaults_for_timestamp within stored procedure works inconsistently
#
set statement explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp for create table t1 (ts timestamp);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`ts` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create procedure pr()
begin
set explicit_defaults_for_timestamp= 1-@@explicit_defaults_for_timestamp;
create table t1 (ts timestamp);
end $
call pr();
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`ts` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop procedure pr;
drop table t1;
prepare stmt from 'create or replace table t1 (a timestamp)';
execute stmt;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=MyISAM DEFAULT CHARSET=latin1
set explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp;
execute stmt;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
set explicit_defaults_for_timestamp=1-@@explicit_defaults_for_timestamp;
execute stmt;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;

View file

@ -10801,6 +10801,7 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
comment= old_field->comment;
vcol_info= old_field->vcol_info;
option_list= old_field->option_list;
explicitly_nullable= !(old_field->flags & NOT_NULL_FLAG);
compression_method_ptr= 0;
versioning= VERSIONING_NOT_SET;
invisible= old_field->invisible;

View file

@ -5262,7 +5262,7 @@ public:
uint flags, pack_length;
List<String> interval_list;
engine_option_value *option_list;
bool explicitly_nullable;
/*
This is additinal data provided for any computed(virtual) field.
@ -5284,7 +5284,7 @@ public:
comment(null_clex_str),
on_update(NULL), invisible(VISIBLE), char_length(0),
flags(0), pack_length(0),
option_list(NULL),
option_list(NULL), explicitly_nullable(false),
vcol_info(0), default_value(0), check_constraint(0),
versioning(VERSIONING_NOT_SET), period(NULL)
{

View file

@ -3133,13 +3133,17 @@ bool Column_definition::prepare_stage2(handler *file,
void promote_first_timestamp_column(List<Create_field> *column_definitions)
{
bool first= true;
for (Create_field &column_definition : *column_definitions)
{
if (column_definition.is_timestamp_type() || // TIMESTAMP
column_definition.unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
{
if (!column_definition.explicitly_nullable)
column_definition.flags|= NOT_NULL_FLAG;
DBUG_PRINT("info", ("field-ptr:%p", column_definition.field));
if ((column_definition.flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
if (first &&
(column_definition.flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
column_definition.default_value == NULL && // no constant default,
column_definition.unireg_check == Field::NONE && // no function default
column_definition.vcol_info == NULL &&
@ -3153,7 +3157,7 @@ void promote_first_timestamp_column(List<Create_field> *column_definitions)
));
column_definition.unireg_check= Field::TIMESTAMP_DNUN_FIELD;
}
return;
first= false;
}
}
}

View file

@ -4262,19 +4262,6 @@ void Type_handler_temporal_with_date::Item_update_null_value(Item *item) const
(void) item->get_date(thd, &ltime, Datetime::Options(thd));
}
bool
Type_handler_timestamp_common::
Column_definition_set_attributes(THD *thd,
Column_definition *def,
const Lex_field_type_st &attr,
CHARSET_INFO *cs,
column_definition_type_t type) const
{
Type_handler::Column_definition_set_attributes(thd, def, attr, cs, type);
if (!(thd->variables.option_bits & OPTION_EXPLICIT_DEF_TIMESTAMP))
def->flags|= NOT_NULL_FLAG;
return false;
}
void Type_handler_string_result::Item_update_null_value(Item *item) const
{

View file

@ -6660,12 +6660,6 @@ public:
bool Item_func_min_max_get_date(THD *thd, Item_func_min_max*,
MYSQL_TIME *, date_mode_t fuzzydate)
const override;
bool Column_definition_set_attributes(THD *thd,
Column_definition *def,
const Lex_field_type_st &attr,
CHARSET_INFO *cs,
column_definition_type_t type)
const override;
};

View file

@ -6091,7 +6091,6 @@ field_def:
| opt_generated_always AS virtual_column_func
{
Lex->last_field->vcol_info= $3;
Lex->last_field->flags&= ~NOT_NULL_FLAG; // undo automatic NOT NULL for timestamps
}
vcol_opt_specifier vcol_opt_attribute
| opt_generated_always AS ROW_SYM START_SYM opt_asrow_attribute
@ -6566,7 +6565,11 @@ attribute_list:
;
attribute:
NULL_SYM { Lex->last_field->flags&= ~ NOT_NULL_FLAG; }
NULL_SYM
{
Lex->last_field->flags&= ~NOT_NULL_FLAG;
Lex->last_field->explicitly_nullable= true;
}
| DEFAULT column_default_expr { Lex->last_field->default_value= $2; }
| ON UPDATE_SYM NOW_SYM opt_default_time_precision
{