Skip to content

Commit

Permalink
MDEV-29075 Changing explicit_defaults_for_timestamp within stored pro…
Browse files Browse the repository at this point in the history
…cedure works inconsistently
  • Loading branch information
vuvova committed Aug 2, 2022
1 parent b174ec1 commit 56c7d14
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 39 deletions.
48 changes: 35 additions & 13 deletions mysql-test/suite/sys_vars/inc/explicit_defaults_for_timestamp.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Original file line number Diff line number Diff line change
Expand Up @@ -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` (
Expand Down Expand Up @@ -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;
1 change: 1 addition & 0 deletions sql/field.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions sql/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -5262,7 +5262,7 @@ class Column_definition: public Sql_alloc,
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.
Expand All @@ -5284,7 +5284,7 @@ class Column_definition: public Sql_alloc,
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)
{
Expand Down
8 changes: 6 additions & 2 deletions sql/sql_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand All @@ -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;
}
}
}
Expand Down
13 changes: 0 additions & 13 deletions sql/sql_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
6 changes: 0 additions & 6 deletions sql/sql_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -6660,12 +6660,6 @@ class Type_handler_timestamp_common: public Type_handler_temporal_with_date
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;
};


Expand Down
7 changes: 5 additions & 2 deletions sql/sql_yacc.yy
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
{
Expand Down

0 comments on commit 56c7d14

Please sign in to comment.