mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 11:27:39 +02:00
MDEV-14038 ALTER TABLE does not exit on error with InnoDB + bad default function
Changing Field::set_default from void to int. It now uses the same return value notation with Field::store*() and Item::save_in_field().
This commit is contained in:
parent
f9066dc347
commit
3062445a64
7 changed files with 95 additions and 9 deletions
|
|
@ -857,3 +857,33 @@ DROP TABLE dest_db.t1;
|
|||
DROP TABLE source_db.t1;
|
||||
DROP DATABASE source_db;
|
||||
DROP DATABASE dest_db;
|
||||
USE test;
|
||||
#
|
||||
# MDEV-14038 ALTER TABLE does not exit on error with InnoDB + bad default function
|
||||
#
|
||||
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
||||
iNSERT INTO t1 VALUES (10);
|
||||
ALTER TABLE t1 ADD b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0);
|
||||
ERROR 22003: Out of range value for column 'b' at row 1
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
10
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
||||
iNSERT INTO t1 VALUES (10);
|
||||
ALTER TABLE t1 ADD b DATE NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
||||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
10 2001-01-01
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
||||
iNSERT INTO t1 VALUES (10);
|
||||
ALTER TABLE t1 ADD b TIME NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
||||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
10 10:20:30
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -37,3 +37,13 @@ Level Code Message
|
|||
show errors;
|
||||
Level Code Message
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-14038 ALTER TABLE does not exit on error with InnoDB + bad default function
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 ADD COLUMN b LINESTRING DEFAULT POINT(1,1);
|
||||
ERROR 22007: Incorrect LINESTRING value: 'POINT' for column 'b' at row 1
|
||||
DESCRIBE t1;
|
||||
Field Type Null Key Default Extra
|
||||
a int(11) YES NULL
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -494,6 +494,34 @@ eval ALTER TABLE $source_db.t1 DROP INDEX index2, algorithm=inplace;
|
|||
eval DROP TABLE $source_db.t1;
|
||||
eval DROP DATABASE $source_db;
|
||||
eval DROP DATABASE $dest_db;
|
||||
USE test;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-14038 ALTER TABLE does not exit on error with InnoDB + bad default function
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
||||
iNSERT INTO t1 VALUES (10);
|
||||
--error ER_WARN_DATA_OUT_OF_RANGE
|
||||
ALTER TABLE t1 ADD b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# DATETIME-to-DATE truncation is OK
|
||||
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
||||
iNSERT INTO t1 VALUES (10);
|
||||
--enable_info
|
||||
ALTER TABLE t1 ADD b DATE NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
||||
--disable_info
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# DATETIME-to-TIME truncation is OK
|
||||
CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
||||
iNSERT INTO t1 VALUES (10);
|
||||
--enable_info
|
||||
ALTER TABLE t1 ADD b TIME NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
||||
--disable_info
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -19,3 +19,13 @@ ALTER ONLINE TABLE t1 ADD PRIMARY KEY(a),DROP INDEX d, LOCK=SHARED;
|
|||
show warnings;
|
||||
show errors;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-14038 ALTER TABLE does not exit on error with InnoDB + bad default function
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
|
||||
ALTER TABLE t1 ADD COLUMN b LINESTRING DEFAULT POINT(1,1);
|
||||
DESCRIBE t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
11
sql/field.cc
11
sql/field.cc
|
|
@ -2335,15 +2335,15 @@ Field *Field::clone(MEM_ROOT *root, my_ptrdiff_t diff)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
void Field::set_default()
|
||||
int Field::set_default()
|
||||
{
|
||||
if (default_value)
|
||||
{
|
||||
Query_arena backup_arena;
|
||||
table->in_use->set_n_backup_active_arena(table->expr_arena, &backup_arena);
|
||||
(void) default_value->expr->save_in_field(this, 0);
|
||||
int rc= default_value->expr->save_in_field(this, 0);
|
||||
table->in_use->restore_active_arena(table->expr_arena, &backup_arena);
|
||||
return;
|
||||
return rc;
|
||||
}
|
||||
/* Copy constant value stored in s->default_values */
|
||||
my_ptrdiff_t l_offset= (my_ptrdiff_t) (table->s->default_values -
|
||||
|
|
@ -2352,6 +2352,7 @@ void Field::set_default()
|
|||
if (maybe_null_in_table())
|
||||
*null_ptr= ((*null_ptr & (uchar) ~null_bit) |
|
||||
(null_ptr[l_offset] & null_bit));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -9665,7 +9666,7 @@ Field_bit::unpack(uchar *to, const uchar *from, const uchar *from_end,
|
|||
}
|
||||
|
||||
|
||||
void Field_bit::set_default()
|
||||
int Field_bit::set_default()
|
||||
{
|
||||
if (bit_len > 0)
|
||||
{
|
||||
|
|
@ -9673,7 +9674,7 @@ void Field_bit::set_default()
|
|||
uchar bits= get_rec_bits(bit_ptr + col_offset, bit_ofs, bit_len);
|
||||
set_rec_bits(bits, bit_ptr, bit_ofs, bit_len);
|
||||
}
|
||||
Field::set_default();
|
||||
return Field::set_default();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -953,7 +953,7 @@ public:
|
|||
my_ptrdiff_t l_offset= (my_ptrdiff_t) (record - table->record[0]);
|
||||
return ptr + l_offset;
|
||||
}
|
||||
virtual void set_default();
|
||||
virtual int set_default();
|
||||
|
||||
bool has_update_default_function() const
|
||||
{
|
||||
|
|
@ -3715,7 +3715,7 @@ public:
|
|||
virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
|
||||
virtual const uchar *unpack(uchar *to, const uchar *from,
|
||||
const uchar *from_end, uint param_data);
|
||||
virtual void set_default();
|
||||
virtual int set_default();
|
||||
|
||||
Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
|
||||
uchar *new_ptr, uint32 length,
|
||||
|
|
|
|||
|
|
@ -1076,8 +1076,15 @@ ha_innobase::check_if_supported_inplace_alter(
|
|||
|
||||
/* Compute the DEFAULT values of non-constant columns
|
||||
(VCOL_SESSION_FUNC | VCOL_TIME_FUNC). */
|
||||
(*af)->set_default();
|
||||
goto next_column;
|
||||
switch ((*af)->set_default()) {
|
||||
case 0: /* OK */
|
||||
case 3: /* DATETIME to TIME or DATE conversion */
|
||||
goto next_column;
|
||||
case -1: /* OOM, or GEOMETRY type mismatch */
|
||||
case 1: /* A number adjusted to the min/max value */
|
||||
case 2: /* String truncation, or conversion problem */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue