MDEV-14168 Unconditionally allow ALGORITHM=INPLACE for setting a column NOT NULL

- Allow NOT NULL constraint to replace the NULL value in the row with
explicit or implicit default value.

- If the default value is non-const value then inplace alter won't
support it.

- ALTER IGNORE will ignore the error if the concurrent DML contains
NULL value.
parent 461de7ed
...@@ -2,7 +2,7 @@ CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb; ...@@ -2,7 +2,7 @@ CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb;
INSERT INTO t1 VALUES(NULL); INSERT INTO t1 VALUES(NULL);
ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(), ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(),
ALGORITHM=INPLACE; ALGORITHM=INPLACE;
ERROR 22004: Invalid use of NULL value ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: cannot convert NULL to non-constant DEFAULT. Try ALGORITHM=COPY
ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(), ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(),
ALGORITHM=COPY; ALGORITHM=COPY;
ERROR 01000: Data truncated for column 'i1' at row 1 ERROR 01000: Data truncated for column 'i1' at row 1
...@@ -10,20 +10,20 @@ ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT, ...@@ -10,20 +10,20 @@ ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY(id), ALGORITHM=INPLACE; ADD PRIMARY KEY(id), ALGORITHM=INPLACE;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
ALTER TABLE t1 ADD PRIMARY KEY(i1), ALGORITHM=INPLACE; ALTER TABLE t1 ADD PRIMARY KEY(i1), ALGORITHM=INPLACE;
ERROR 22004: Invalid use of NULL value affected rows: 0
ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT, info: Records: 0 Duplicates: 0 Warnings: 0
ADD PRIMARY KEY(id); ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT;
affected rows: 1 affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0 info: Records: 1 Duplicates: 0 Warnings: 0
SELECT * FROM t1; SELECT * FROM t1;
id id
1 42
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 ) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (i1 INT UNSIGNED NOT NULL, d1 TIMESTAMP NULL) ENGINE=InnoDB; CREATE TABLE t1 (i1 INT UNSIGNED NOT NULL, d1 TIMESTAMP NULL) ENGINE=InnoDB;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
......
...@@ -411,9 +411,7 @@ SET @old_sql_mode = @@sql_mode; ...@@ -411,9 +411,7 @@ SET @old_sql_mode = @@sql_mode;
SET @@sql_mode = 'STRICT_TRANS_TABLES'; SET @@sql_mode = 'STRICT_TRANS_TABLES';
ALTER TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)), ALTER TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)),
ALGORITHM = INPLACE; ALGORITHM = INPLACE;
ERROR 22004: Invalid use of NULL value ERROR 23000: Duplicate entry '' for key 'PRIMARY'
ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL;
ERROR 22004: Invalid use of NULL value
SET @@sql_mode = @old_sql_mode; SET @@sql_mode = @old_sql_mode;
UPDATE t1 SET c3=LEFT(CONCAT(c1,REPEAT('foo',c1)),255) WHERE c3 IS NULL; UPDATE t1 SET c3=LEFT(CONCAT(c1,REPEAT('foo',c1)),255) WHERE c3 IS NULL;
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created0 WAIT_FOR ins_done0'; SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created0 WAIT_FOR ins_done0';
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb; CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb;
INSERT INTO t1 VALUES(NULL); INSERT INTO t1 VALUES(NULL);
--enable_info --enable_info
--error ER_INVALID_USE_OF_NULL --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(), ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(),
ALGORITHM=INPLACE; ALGORITHM=INPLACE;
--error WARN_DATA_TRUNCATED --error WARN_DATA_TRUNCATED
...@@ -12,10 +12,8 @@ ALGORITHM=COPY; ...@@ -12,10 +12,8 @@ ALGORITHM=COPY;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT, ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY(id), ALGORITHM=INPLACE; ADD PRIMARY KEY(id), ALGORITHM=INPLACE;
--error ER_INVALID_USE_OF_NULL
ALTER TABLE t1 ADD PRIMARY KEY(i1), ALGORITHM=INPLACE; ALTER TABLE t1 ADD PRIMARY KEY(i1), ALGORITHM=INPLACE;
ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT, ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT;
ADD PRIMARY KEY(id);
--disable_info --disable_info
SELECT * FROM t1; SELECT * FROM t1;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
......
...@@ -358,12 +358,10 @@ SET @old_sql_mode = @@sql_mode; ...@@ -358,12 +358,10 @@ SET @old_sql_mode = @@sql_mode;
# NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on. # NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on.
# And adding a PRIMARY KEY will also add NOT NULL implicitly! # And adding a PRIMARY KEY will also add NOT NULL implicitly!
SET @@sql_mode = 'STRICT_TRANS_TABLES'; SET @@sql_mode = 'STRICT_TRANS_TABLES';
--error ER_INVALID_USE_OF_NULL --error ER_DUP_ENTRY
ALTER TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)), ALTER TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)),
ALGORITHM = INPLACE; ALGORITHM = INPLACE;
--error ER_INVALID_USE_OF_NULL
ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL;
SET @@sql_mode = @old_sql_mode; SET @@sql_mode = @old_sql_mode;
UPDATE t1 SET c3=LEFT(CONCAT(c1,REPEAT('foo',c1)),255) WHERE c3 IS NULL; UPDATE t1 SET c3=LEFT(CONCAT(c1,REPEAT('foo',c1)),255) WHERE c3 IS NULL;
...@@ -397,6 +395,7 @@ ROLLBACK; ...@@ -397,6 +395,7 @@ ROLLBACK;
--echo # session con1 --echo # session con1
connection con1; connection con1;
ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL; ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL;
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created WAIT_FOR ins_done'; SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created WAIT_FOR ins_done';
--send --send
ALTER TABLE t1 DROP PRIMARY KEY, DROP COLUMN c22f, ALTER TABLE t1 DROP PRIMARY KEY, DROP COLUMN c22f,
......
...@@ -7089,7 +7089,7 @@ ER_IDENT_CAUSES_TOO_LONG_PATH ...@@ -7089,7 +7089,7 @@ ER_IDENT_CAUSES_TOO_LONG_PATH
eng "Long database name and identifier for object resulted in path length exceeding %d characters. Path: '%s'" eng "Long database name and identifier for object resulted in path length exceeding %d characters. Path: '%s'"
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL
eng "cannot silently convert NULL values, as required in this SQL_MODE" eng "cannot convert NULL to non-constant DEFAULT"
ER_MUST_CHANGE_PASSWORD_LOGIN ER_MUST_CHANGE_PASSWORD_LOGIN
eng "Your password has expired. To log in you must change it using a client that supports expired passwords" eng "Your password has expired. To log in you must change it using a client that supports expired passwords"
......
...@@ -127,6 +127,10 @@ static const alter_table_operations INNOBASE_ALTER_NOREBUILD ...@@ -127,6 +127,10 @@ static const alter_table_operations INNOBASE_ALTER_NOREBUILD
| ALTER_DROP_VIRTUAL_COLUMN | ALTER_DROP_VIRTUAL_COLUMN
| ALTER_VIRTUAL_COLUMN_ORDER; | ALTER_VIRTUAL_COLUMN_ORDER;
static const alter_table_operations INNOBASE_DEFAULTS
= ALTER_COLUMN_NOT_NULLABLE
| ALTER_ADD_COLUMN;
struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
{ {
/** Dummy query graph */ /** Dummy query graph */
...@@ -173,8 +177,8 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx ...@@ -173,8 +177,8 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
const char** col_names; const char** col_names;
/** added AUTO_INCREMENT column position, or ULINT_UNDEFINED */ /** added AUTO_INCREMENT column position, or ULINT_UNDEFINED */
const ulint add_autoinc; const ulint add_autoinc;
/** default values of ADD COLUMN, or NULL */ /** default values of ADD and CHANGE COLUMN, or NULL */
const dtuple_t* add_cols; const dtuple_t* defaults;
/** autoinc sequence to use */ /** autoinc sequence to use */
ib_sequence_t sequence; ib_sequence_t sequence;
/** temporary table name to use for old table when renaming tables */ /** temporary table name to use for old table when renaming tables */
...@@ -200,6 +204,9 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx ...@@ -200,6 +204,9 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
/** original column names of the table */ /** original column names of the table */
const char* const old_col_names; const char* const old_col_names;
/** Whether alter ignore issued. */
const bool ignore;
ha_innobase_inplace_ctx(row_prebuilt_t*& prebuilt_arg, ha_innobase_inplace_ctx(row_prebuilt_t*& prebuilt_arg,
dict_index_t** drop_arg, dict_index_t** drop_arg,
ulint num_to_drop_arg, ulint num_to_drop_arg,
...@@ -216,7 +223,8 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx ...@@ -216,7 +223,8 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
ulint add_autoinc_arg, ulint add_autoinc_arg,
ulonglong autoinc_col_min_value_arg, ulonglong autoinc_col_min_value_arg,
ulonglong autoinc_col_max_value_arg, ulonglong autoinc_col_max_value_arg,
ulint num_to_drop_vcol_arg) : ulint num_to_drop_vcol_arg,
bool ignore_flag) :
inplace_alter_handler_ctx(), inplace_alter_handler_ctx(),
prebuilt (prebuilt_arg), prebuilt (prebuilt_arg),
add_index (0), add_key_numbers (0), num_to_add_index (0), add_index (0), add_key_numbers (0), num_to_add_index (0),
...@@ -229,7 +237,7 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx ...@@ -229,7 +237,7 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
new_table (new_table_arg), instant_table (0), new_table (new_table_arg), instant_table (0),
col_map (0), col_names (col_names_arg), col_map (0), col_names (col_names_arg),
add_autoinc (add_autoinc_arg), add_autoinc (add_autoinc_arg),
add_cols (0), defaults (0),
sequence(prebuilt->trx->mysql_thd, sequence(prebuilt->trx->mysql_thd,
autoinc_col_min_value_arg, autoinc_col_max_value_arg), autoinc_col_min_value_arg, autoinc_col_max_value_arg),
tmp_name (0), tmp_name (0),
...@@ -243,7 +251,8 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx ...@@ -243,7 +251,8 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
m_stage(NULL), m_stage(NULL),
old_n_cols(prebuilt_arg->table->n_cols), old_n_cols(prebuilt_arg->table->n_cols),
old_cols(prebuilt_arg->table->cols), old_cols(prebuilt_arg->table->cols),
old_col_names(prebuilt_arg->table->col_names) old_col_names(prebuilt_arg->table->col_names),
ignore(ignore_flag)
{ {
ut_ad(old_n_cols >= DATA_N_SYS_COLS); ut_ad(old_n_cols >= DATA_N_SYS_COLS);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
...@@ -674,6 +683,46 @@ instant_alter_column_possible( ...@@ -674,6 +683,46 @@ instant_alter_column_possible(
|| !create_option_need_rebuild(ha_alter_info, table); || !create_option_need_rebuild(ha_alter_info, table);
} }
/** Check whether the non-const default value for the field
@param[in] field field which could be added or changed
@return true if the non-const default is present. */
static bool is_non_const_value(Field* field)
{
return field->default_value
&& field->default_value->flags & ~(VCOL_SESSION_FUNC
| VCOL_TIME_FUNC);
}
/** Set default value for the field.
@param[in] field field which could be added or changed
@return true if the default value is set. */
static bool set_default_value(Field* field)
{
/* The added/changed NOT NULL column lacks a DEFAULT value,
or the DEFAULT is the same for all rows.
(Time functions, such as CURRENT_TIMESTAMP(),
are evaluated from a timestamp that is assigned
at the start of the statement. Session
functions, such as USER(), always evaluate the
same within a statement.) */
ut_ad(!is_non_const_value(field));
/* Compute the DEFAULT values of non-constant columns
(VCOL_SESSION_FUNC | VCOL_TIME_FUNC). */
switch (field->set_default()) {
case 0: /* OK */
case 3: /* DATETIME to TIME or DATE conversion */
return true;
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;
}
return false;
}
/** Check if InnoDB supports a particular alter table in-place /** Check if InnoDB supports a particular alter table in-place
@param altered_table TABLE object for new version of table. @param altered_table TABLE object for new version of table.
@param ha_alter_info Structure describing changes to be done @param ha_alter_info Structure describing changes to be done
...@@ -1080,20 +1129,26 @@ ha_innobase::check_if_supported_inplace_alter( ...@@ -1080,20 +1129,26 @@ ha_innobase::check_if_supported_inplace_alter(
/* No DEFAULT value is /* No DEFAULT value is
specified. We can report specified. We can report
errors for any NULL values for errors for any NULL values for
the TIMESTAMP. the TIMESTAMP. */
FIXME: Allow any DEFAULT
expression whose value does
not change during ALTER TABLE.
This would require a fix in
row_merge_read_clustered_index()
to try to replace the DEFAULT
value before reporting
DB_INVALID_NULL. */
goto next_column; goto next_column;
} }
break; break;
default: default:
/* Changing from NULL to NOT NULL and
set the default constant values. */
if (f->real_maybe_null()
&& !(*af)->real_maybe_null()) {
if (is_non_const_value(*af)) {
break;
}
if (!set_default_value(*af)) {
break;
}
}
/* For any other data type, NULL /* For any other data type, NULL
values are not converted. values are not converted.
(An AUTO_INCREMENT attribute cannot (An AUTO_INCREMENT attribute cannot
...@@ -1109,32 +1164,16 @@ ha_innobase::check_if_supported_inplace_alter( ...@@ -1109,32 +1164,16 @@ ha_innobase::check_if_supported_inplace_alter(
ha_alter_info->unsupported_reason ha_alter_info->unsupported_reason
= innobase_get_err_msg( = innobase_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL); ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL);
} else if (!(*af)->default_value } else if (!is_non_const_value(*af)) {
|| !((*af)->default_value->flags
& ~(VCOL_SESSION_FUNC | VCOL_TIME_FUNC))) {
n_add_cols++; n_add_cols++;
if (af < &altered_table->field[table_share->fields]) { if (af < &altered_table->field[table_share->fields]) {
add_column_not_last = true; add_column_not_last = true;
} }
/* The added NOT NULL column lacks a DEFAULT value,
or the DEFAULT is the same for all rows. if (set_default_value(*af)) {
(Time functions, such as CURRENT_TIMESTAMP(),
are evaluated from a timestamp that is assigned
at the start of the statement. Session
functions, such as USER(), always evaluate the
same within a statement.) */
/* Compute the DEFAULT values of non-constant columns
(VCOL_SESSION_FUNC | VCOL_TIME_FUNC). */
switch ((*af)->set_default()) {
case 0: /* OK */
case 3: /* DATETIME to TIME or DATE conversion */
goto next_column; 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;
} }
} }
...@@ -3181,7 +3220,7 @@ adding columns. ...@@ -3181,7 +3220,7 @@ adding columns.
@param table MySQL table as it is before the ALTER operation @param table MySQL table as it is before the ALTER operation
@param new_table InnoDB table corresponding to MySQL altered_table @param new_table InnoDB table corresponding to MySQL altered_table
@param old_table InnoDB table corresponding to MYSQL table @param old_table InnoDB table corresponding to MYSQL table
@param add_cols Default values for ADD COLUMN, or NULL if no ADD COLUMN @param defaults Default values for ADD COLUMN, or NULL if no ADD COLUMN
@param heap Memory heap where allocated @param heap Memory heap where allocated
@return array of integers, mapping column numbers in the table @return array of integers, mapping column numbers in the table
to column numbers in altered_table */ to column numbers in altered_table */
...@@ -3194,7 +3233,7 @@ innobase_build_col_map( ...@@ -3194,7 +3233,7 @@ innobase_build_col_map(
const TABLE* table, const TABLE* table,
const dict_table_t* new_table, const dict_table_t* new_table,
const dict_table_t* old_table, const dict_table_t* old_table,
dtuple_t* add_cols, dtuple_t* defaults,
mem_heap_t* heap) mem_heap_t* heap)
{ {
DBUG_ENTER("innobase_build_col_map"); DBUG_ENTER("innobase_build_col_map");
...@@ -3206,9 +3245,10 @@ innobase_build_col_map( ...@@ -3206,9 +3245,10 @@ innobase_build_col_map(
DBUG_ASSERT(dict_table_get_n_cols(old_table) DBUG_ASSERT(dict_table_get_n_cols(old_table)
+ dict_table_get_n_v_cols(old_table) + dict_table_get_n_v_cols(old_table)
>= table->s->fields + DATA_N_SYS_COLS); >= table->s->fields + DATA_N_SYS_COLS);
DBUG_ASSERT(!!add_cols == !!(ha_alter_info->handler_flags DBUG_ASSERT(!!defaults == !!(ha_alter_info->handler_flags
& ALTER_ADD_COLUMN)); & (ALTER_ADD_COLUMN
DBUG_ASSERT(!add_cols || dtuple_get_n_fields(add_cols) | ALTER_COLUMN_NOT_NULLABLE)));
DBUG_ASSERT(!defaults || dtuple_get_n_fields(defaults)
== dict_table_get_n_cols(new_table)); == dict_table_get_n_cols(new_table));
ulint* col_map = static_cast<ulint*>( ulint* col_map = static_cast<ulint*>(
...@@ -3250,6 +3290,19 @@ innobase_build_col_map( ...@@ -3250,6 +3290,19 @@ innobase_build_col_map(
} }
if (new_field->field == field) { if (new_field->field == field) {
const Field* altered_field =
altered_table->field[i];
if (field->real_maybe_null()
&& !altered_field->real_maybe_null()) {
innobase_build_col_map_add(
heap, dtuple_get_nth_field(
defaults, i),
altered_field,
dict_table_is_comp(new_table));
}
col_map[old_i - num_old_v] = i; col_map[old_i - num_old_v] = i;
goto found_col; goto found_col;
} }
...@@ -3257,7 +3310,7 @@ innobase_build_col_map( ...@@ -3257,7 +3310,7 @@ innobase_build_col_map(
ut_ad(!is_v); ut_ad(!is_v);
innobase_build_col_map_add( innobase_build_col_map_add(
heap, dtuple_get_nth_field(add_cols, i), heap, dtuple_get_nth_field(defaults, i),
altered_table->field[i + num_v], altered_table->field[i + num_v],
dict_table_is_comp(new_table)); dict_table_is_comp(new_table));
found_col: found_col:
...@@ -4765,7 +4818,7 @@ prepare_inplace_alter_table_dict( ...@@ -4765,7 +4818,7 @@ prepare_inplace_alter_table_dict(
DBUG_ASSERT(!add_fts_doc_id || add_fts_doc_id_idx); DBUG_ASSERT(!add_fts_doc_id || add_fts_doc_id_idx);
DBUG_ASSERT(!add_fts_doc_id_idx DBUG_ASSERT(!add_fts_doc_id_idx
|| innobase_fulltext_exist(altered_table)); || innobase_fulltext_exist(altered_table));
DBUG_ASSERT(!ctx->add_cols); DBUG_ASSERT(!ctx->defaults);
DBUG_ASSERT(!ctx->add_index); DBUG_ASSERT(!ctx->add_index);
DBUG_ASSERT(!ctx->add_key_numbers); DBUG_ASSERT(!ctx->add_key_numbers);
DBUG_ASSERT(!ctx->num_to_add_index); DBUG_ASSERT(!ctx->num_to_add_index);
...@@ -4933,7 +4986,7 @@ prepare_inplace_alter_table_dict( ...@@ -4933,7 +4986,7 @@ prepare_inplace_alter_table_dict(
part ? part : "", partlen + 1); part ? part : "", partlen + 1);
ulint n_cols = 0; ulint n_cols = 0;
ulint n_v_cols = 0; ulint n_v_cols = 0;
dtuple_t* add_cols; dtuple_t* defaults;
ulint z = 0; ulint z = 0;
for (uint i = 0; i < altered_table->s->fields; i++) { for (uint i = 0; i < altered_table->s->fields; i++) {
...@@ -5101,23 +5154,21 @@ prepare_inplace_alter_table_dict( ...@@ -5101,23 +5154,21 @@ prepare_inplace_alter_table_dict(
dict_table_add_system_columns(ctx->new_table, ctx->heap); dict_table_add_system_columns(ctx->new_table, ctx->heap);
if (ha_alter_info->handler_flags if (ha_alter_info->handler_flags & INNOBASE_DEFAULTS) {
& ALTER_ADD_COLUMN) { defaults = dtuple_create_with_vcol(
add_cols = dtuple_create_with_vcol(
ctx->heap, ctx->heap,
dict_table_get_n_cols(ctx->new_table), dict_table_get_n_cols(ctx->new_table),
dict_table_get_n_v_cols(ctx->new_table)); dict_table_get_n_v_cols(ctx->new_table));
dict_table_copy_types(add_cols, ctx->new_table); dict_table_copy_types(defaults, ctx->new_table);
} else { } else {
add_cols = NULL; defaults = NULL;
} }
ctx->col_map = innobase_build_col_map( ctx->col_map = innobase_build_col_map(
ha_alter_info, altered_table, old_table, ha_alter_info, altered_table, old_table,
ctx->new_table, user_table, ctx->new_table, user_table, defaults, ctx->heap);
add_cols, ctx->heap); ctx->defaults = defaults;
ctx->add_cols = add_cols;
} else { } else {
DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info, old_table)); DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info, old_table));
DBUG_ASSERT(old_table->s->primary_key DBUG_ASSERT(old_table->s->primary_key
...@@ -5490,7 +5541,8 @@ prepare_inplace_alter_table_dict( ...@@ -5490,7 +5541,8 @@ prepare_inplace_alter_table_dict(
clust_index, ctx->new_table, clust_index, ctx->new_table,
!(ha_alter_info->handler_flags !(ha_alter_info->handler_flags
& ALTER_ADD_PK_INDEX), & ALTER_ADD_PK_INDEX),
ctx->add_cols, ctx->col_map, path); ctx->defaults, ctx->col_map, path,
ctx->ignore);
rw_lock_x_unlock(&clust_index->lock); rw_lock_x_unlock(&clust_index->lock);
if (!ok) { if (!ok) {
...@@ -5548,7 +5600,7 @@ prepare_inplace_alter_table_dict( ...@@ -5548,7 +5600,7 @@ prepare_inplace_alter_table_dict(
ctx->prebuilt->trx, ctx->prebuilt->trx,
index, index,
NULL, true, NULL, NULL, NULL, true, NULL, NULL,
path); path, ctx->ignore);
rw_lock_x_unlock(&index->lock); rw_lock_x_unlock(&index->lock);
if (!ok) { if (!ok) {
...@@ -6720,7 +6772,8 @@ ha_innobase::prepare_inplace_alter_table( ...@@ -6720,7 +6772,8 @@ ha_innobase::prepare_inplace_alter_table(
add_fk, n_add_fk, add_fk, n_add_fk,
ha_alter_info->online, ha_alter_info->online,
heap, indexed_table, heap, indexed_table,
col_names, ULINT_UNDEFINED, 0, 0, 0); col_names, ULINT_UNDEFINED, 0, 0, 0,
ha_alter_info->ignore);
} }
DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0);
...@@ -6855,7 +6908,7 @@ ha_innobase::prepare_inplace_alter_table( ...@@ -6855,7 +6908,7 @@ ha_innobase::prepare_inplace_alter_table(
heap, m_prebuilt->table, col_names, heap, m_prebuilt->table, col_names,
add_autoinc_col_no, add_autoinc_col_no,
ha_alter_info->create_info->auto_increment_value, ha_alter_info->create_info->auto_increment_value,
autoinc_col_max_value, 0); autoinc_col_max_value, 0, ha_alter_info->ignore);
DBUG_RETURN(prepare_inplace_alter_table_dict( DBUG_RETURN(prepare_inplace_alter_table_dict(
ha_alter_info, altered_table, table, ha_alter_info, altered_table, table,
...@@ -7086,7 +7139,7 @@ ha_innobase::inplace_alter_table( ...@@ -7086,7 +7139,7 @@ ha_innobase::inplace_alter_table(
m_prebuilt->table, ctx->new_table, m_prebuilt->table, ctx->new_table,
ctx->online, ctx->online,
ctx->add_index, ctx->add_key_numbers, ctx->num_to_add_index, ctx->add_index, ctx->add_key_numbers, ctx->num_to_add_index,
altered_table, ctx->add_cols, ctx->col_map, altered_table, ctx->defaults, ctx->col_map,
ctx->add_autoinc, ctx->sequence, ctx->skip_pk_sort, ctx->add_autoinc, ctx->sequence, ctx->skip_pk_sort,
ctx->m_stage, add_v, eval_table, ctx->m_stage, add_v, eval_table,
ha_alter_info->handler_flags & ALTER_DROP_HISTORICAL); ha_alter_info->handler_flags & ALTER_DROP_HISTORICAL);
......
...@@ -55,12 +55,13 @@ row_log_allocate( ...@@ -55,12 +55,13 @@ row_log_allocate(
or NULL when creating a secondary index */ or NULL when creating a secondary index */
bool same_pk,/*!< in: whether the definition of the bool same_pk,/*!< in: whether the definition of the
PRIMARY KEY has remained the same */ PRIMARY KEY has remained the same */
const dtuple_t* add_cols, const dtuple_t* defaults,
/*!< in: default values of /*!< in: default values of
added columns, or NULL */ added, changed columns, or NULL */
const ulint* col_map,/*!< in: mapping of old column const ulint* col_map,/*!< in: mapping of old column
numbers to new ones, or NULL if !table */ numbers to new ones, or NULL if !table */
const char* path) /*!< in: where to create temporary file */ const char* path, /*!< in: where to create temporary file */
bool ignore) /*!< in: Whether alter ignore issued */
MY_ATTRIBUTE((nonnull(1), warn_unused_result)); MY_ATTRIBUTE((nonnull(1), warn_unused_result));
/******************************************************//** /******************************************************//**
......
...@@ -308,7 +308,7 @@ old_table unless creating a PRIMARY KEY ...@@ -308,7 +308,7 @@ old_table unless creating a PRIMARY KEY
@param[in] n_indexes size of indexes[] @param[in] n_indexes size of indexes[]
@param[in,out] table MySQL table, for reporting erroneous key value @param[in,out] table MySQL table, for reporting erroneous key value
if applicable if applicable
@param[in] add_cols default values of added columns, or NULL @param[in] defaults default values of added, changed columns, or NULL
@param[in] col_map mapping of old column numbers to new ones, or @param[in] col_map mapping of old column numbers to new ones, or
NULL if old_table == new_table NULL if old_table == new_table
@param[in] add_autoinc number of added AUTO_INCREMENT columns, or @param[in] add_autoinc number of added AUTO_INCREMENT columns, or
...@@ -334,7 +334,7 @@ row_merge_build_indexes( ...@@ -334,7 +334,7 @@ row_merge_build_indexes(
const ulint* key_numbers, const ulint* key_numbers,
ulint n_indexes, ulint n_indexes,
struct TABLE* table, struct TABLE* table,
const dtuple_t* add_cols, const dtuple_t* defaults,
const ulint* col_map, const ulint* col_map,
ulint add_autoinc, ulint add_autoinc,
ib_sequence_t& sequence, ib_sequence_t& sequence,
......
...@@ -153,9 +153,9 @@ row_build( ...@@ -153,9 +153,9 @@ row_build(
consulted instead; the user consulted instead; the user
columns in this table should be columns in this table should be
the same columns as in index->table */ the same columns as in index->table */
const dtuple_t* add_cols, const dtuple_t* defaults,
/*!< in: default values of /*!< in: default values of
added columns, or NULL */ added, changed columns, or NULL */
const ulint* col_map,/*!< in: mapping of old column const ulint* col_map,/*!< in: mapping of old column
numbers to new ones, or NULL */ numbers to new ones, or NULL */
row_ext_t** ext, /*!< out, own: cache of row_ext_t** ext, /*!< out, own: cache of
...@@ -177,7 +177,7 @@ addition of new virtual columns. ...@@ -177,7 +177,7 @@ addition of new virtual columns.
of an index, or NULL if of an index, or NULL if
index->table should be index->table should be
consulted instead consulted instead
@param[in] add_cols default values of added columns, or NULL @param[in] defaults default values of added, changed columns, or NULL
@param[in] add_v new virtual columns added @param[in] add_v new virtual columns added
along with new indexes along with new indexes
@param[in] col_map mapping of old column @param[in] col_map mapping of old column
...@@ -194,7 +194,7 @@ row_build_w_add_vcol( ...@@ -194,7 +194,7 @@ row_build_w_add_vcol(
const rec_t* rec, const rec_t* rec,
const ulint* offsets, const ulint* offsets,
const dict_table_t* col_table, const dict_table_t* col_table,
const dtuple_t* add_cols, const dtuple_t* defaults,
const dict_add_v_col_t* add_v, const dict_add_v_col_t* add_v,
const ulint* col_map, const ulint* col_map,
row_ext_t** ext, row_ext_t** ext,
......
...@@ -183,8 +183,9 @@ struct row_log_t { ...@@ -183,8 +183,9 @@ struct row_log_t {
index that is being created online */ index that is being created online */
bool same_pk;/*!< whether the definition of the PRIMARY KEY bool same_pk;/*!< whether the definition of the PRIMARY KEY
has remained the same */ has remained the same */
const dtuple_t* add_cols; const dtuple_t* defaults;
/*!< default values of added columns, or NULL */ /*!< default values of added, changed columns,
or NULL */
const ulint* col_map;/*!< mapping of old column numbers to const ulint* col_map;/*!< mapping of old column numbers to
new ones, or NULL if !table */ new ones, or NULL if !table */
dberr_t error; /*!< error that occurred during online dberr_t error; /*!< error that occurred during online
...@@ -220,6 +221,9 @@ struct row_log_t { ...@@ -220,6 +221,9 @@ struct row_log_t {
decryption or NULL */ decryption or NULL */
const char* path; /*!< where to create temporary file during const char* path; /*!< where to create temporary file during
log operation */ log operation */
bool ignore; /*!< Whether the alter ignore is being used;
if not, NULL values will not be converted to
defaults */
}; };
/** Create the file or online log if it does not exist. /** Create the file or online log if it does not exist.
...@@ -1151,7 +1155,9 @@ row_log_table_get_pk_col( ...@@ -1151,7 +1155,9 @@ row_log_table_get_pk_col(
const ulint* offsets, const ulint* offsets,
ulint i, ulint i,
const page_size_t& page_size, const page_size_t& page_size,
ulint max_len) ulint max_len,
bool ignore,
const dtuple_t* defaults)
{ {
const byte* field; const byte* field;
ulint len; ulint len;
...@@ -1159,7 +1165,12 @@ row_log_table_get_pk_col( ...@@ -1159,7 +1165,12 @@ row_log_table_get_pk_col(
field = rec_get_nth_field(rec, offsets, i, &len); field = rec_get_nth_field(rec, offsets, i, &len);
if (len == UNIV_SQL_NULL) { if (len == UNIV_SQL_NULL) {
return(DB_INVALID_NULL); if (!ignore || !defaults->fields[i].data) {
return(DB_INVALID_NULL);
}
field = static_cast<const byte*>(defaults->fields[i].data);
len = defaults->fields[i].len;
} }
if (rec_offs_nth_extern(offsets, i)) { if (rec_offs_nth_extern(offsets, i)) {
...@@ -1323,7 +1334,8 @@ row_log_table_get_pk( ...@@ -1323,7 +1334,8 @@ row_log_table_get_pk(
log->error = row_log_table_get_pk_col( log->error = row_log_table_get_pk_col(
col, ifield, dfield, *heap, col, ifield, dfield, *heap,
rec, offsets, i, page_size, max_len); rec, offsets, i, page_size, max_len,
log->ignore, log->defaults);
if (log->error != DB_SUCCESS) { if (log->error != DB_SUCCESS) {
err_exit: err_exit:
...@@ -1338,10 +1350,10 @@ row_log_table_get_pk( ...@@ -1338,10 +1350,10 @@ row_log_table_get_pk(
/* No matching column was found in the old /* No matching column was found in the old
table, so this must be an added column. table, so this must be an added column.
Copy the default value. */ Copy the default value. */
ut_ad(log->add_cols); ut_ad(log->defaults);
dfield_copy(dfield, dtuple_get_nth_field( dfield_copy(dfield, dtuple_get_nth_field(
log->add_cols, col_no)); log->defaults, col_no));
mbminlen = dfield->type.mbminlen; mbminlen = dfield->type.mbminlen;
mbmaxlen = dfield->type.mbmaxlen; mbmaxlen = dfield->type.mbmaxlen;
prtype = dfield->type.prtype; prtype = dfield->type.prtype;
...@@ -1512,8 +1524,8 @@ row_log_table_apply_convert_mrec( ...@@ -1512,8 +1524,8 @@ row_log_table_apply_convert_mrec(
*error = DB_SUCCESS; *error = DB_SUCCESS;
/* This is based on row_build(). */ /* This is based on row_build(). */
if (log->add_cols) { if (log->defaults) {
row = dtuple_copy(log->add_cols, heap); row = dtuple_copy(log->defaults, heap);
/* dict_table_copy_types() would set the fields to NULL */ /* dict_table_copy_types() would set the fields to NULL */
for (ulint i = 0; i < dict_table_get_n_cols(log->table); i++) { for (ulint i = 0; i < dict_table_get_n_cols(log->table); i++) {
dict_col_copy_type( dict_col_copy_type(
...@@ -1634,9 +1646,17 @@ row_log_table_apply_convert_mrec( ...@@ -1634,9 +1646,17 @@ row_log_table_apply_convert_mrec(
if ((new_col->prtype & DATA_NOT_NULL) if ((new_col->prtype & DATA_NOT_NULL)
&& dfield_is_null(dfield)) { && dfield_is_null(dfield)) {
/* We got a NULL value for a NOT NULL column. */
*error = DB_INVALID_NULL; const dfield_t& default_field
return(NULL); = log->defaults->fields[col_no];
if (!log->ignore || !default_field.data) {
/* We got a NULL value for a NOT NULL column. */
*error = DB_INVALID_NULL;
return NULL;
}
*dfield = default_field;
} }
/* Adjust the DATA_NOT_NULL flag in the parsed row. */ /* Adjust the DATA_NOT_NULL flag in the parsed row. */
...@@ -3147,12 +3167,13 @@ row_log_allocate( ...@@ -3147,12 +3167,13 @@ row_log_allocate(
or NULL when creating a secondary index */ or NULL when creating a secondary index */
bool same_pk,/*!< in: whether the definition of the bool same_pk,/*!< in: whether the definition of the
PRIMARY KEY has remained the same */ PRIMARY KEY has remained the same */
const dtuple_t* add_cols, const dtuple_t* defaults,
/*!< in: default values of /*!< in: default values of
added columns, or NULL */ added, changed columns, or NULL */
const ulint* col_map,/*!< in: mapping of old column const ulint* col_map,/*!< in: mapping of old column
numbers to new ones, or NULL if !table */ numbers to new ones, or NULL if !table */
const char* path) /*!< in: where to create temporary file */ const char* path, /*!< in: where to create temporary file */
const bool ignore) /*!< in: alter ignore issued */
{ {
row_log_t* log; row_log_t* log;
DBUG_ENTER("row_log_allocate"); DBUG_ENTER("row_log_allocate");
...@@ -3162,7 +3183,7 @@ row_log_allocate( ...@@ -3162,7 +3183,7 @@ row_log_allocate(
ut_ad(!table || index->table != table); ut_ad(!table || index->table != table);
ut_ad(same_pk || table); ut_ad(same_pk || table);
ut_ad(!table || col_map); ut_ad(!table || col_map);
ut_ad(!add_cols || col_map); ut_ad(!defaults || col_map);
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X)); ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X));
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
ut_ad(trx->id); ut_ad(trx->id);
...@@ -3179,7 +3200,7 @@ row_log_allocate( ...@@ -3179,7 +3200,7 @@ row_log_allocate(
log->blobs = NULL; log->blobs = NULL;
log->table = table; log->table = table;
log->same_pk = same_pk; log->same_pk = same_pk;
log->add_cols = add_cols; log->defaults = defaults;
log->col_map = col_map; log->col_map = col_map;
log->error = DB_SUCCESS; log->error = DB_SUCCESS;
log->min_trx = trx->id; log->min_trx = trx->id;
...@@ -3191,6 +3212,7 @@ row_log_allocate( ...@@ -3191,6 +3212,7 @@ row_log_allocate(
log->head.blocks = log->head.bytes = 0; log->head.blocks = log->head.bytes = 0;
log->head.total = 0; log->head.total = 0;
log->path = path; log->path = path;
log->ignore=ignore;
dict_index_set_online_status(index, ONLINE_INDEX_CREATION); dict_index_set_online_status(index, ONLINE_INDEX_CREATION);
index->online_log = log; index->online_log = log;
......
...@@ -1656,7 +1656,7 @@ containing the index entries for the indexes to be built. ...@@ -1656,7 +1656,7 @@ containing the index entries for the indexes to be built.
@param[in] files temporary files @param[in] files temporary files
@param[in] key_numbers MySQL key numbers to create @param[in] key_numbers MySQL key numbers to create
@param[in] n_index number of indexes to create @param[in] n_index number of indexes to create
@param[in] add_cols default values of added columns, or NULL @param[in] defaults default values of added, changed columns, or NULL
@param[in] add_v newly added virtual columns along with indexes @param[in] add_v newly added virtual columns along with indexes
@param[in] col_map mapping of old column numbers to new ones, or @param[in] col_map mapping of old column numbers to new ones, or
NULL if old_table == new_table NULL if old_table == new_table
...@@ -1689,7 +1689,7 @@ row_merge_read_clustered_index( ...@@ -1689,7 +1689,7 @@ row_merge_read_clustered_index(
merge_file_t* files, merge_file_t* files,
const ulint* key_numbers, const ulint* key_numbers,
ulint n_index, ulint n_index,
const dtuple_t* add_cols, const dtuple_t* defaults,
const dict_add_v_col_t* add_v, const dict_add_v_col_t* add_v,
const ulint* col_map, const ulint* col_map,
ulint add_autoinc, ulint add_autoinc,
...@@ -1743,7 +1743,7 @@ row_merge_read_clustered_index( ...@@ -1743,7 +1743,7 @@ row_merge_read_clustered_index(
DBUG_ENTER("row_merge_read_clustered_index"); DBUG_ENTER("row_merge_read_clustered_index");
ut_ad((old_table == new_table) == !col_map); ut_ad((old_table == new_table) == !col_map);
ut_ad(!add_cols || col_map); ut_ad(!defaults || col_map);
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
ut_ad(trx->id); ut_ad(trx->id);
...@@ -2187,19 +2187,26 @@ row_merge_read_clustered_index( ...@@ -2187,19 +2187,26 @@ row_merge_read_clustered_index(
row = row_build_w_add_vcol(ROW_COPY_POINTERS, clust_index, row = row_build_w_add_vcol(ROW_COPY_POINTERS, clust_index,
rec, offsets, new_table, rec, offsets, new_table,
add_cols, add_v, col_map, &ext, defaults, add_v, col_map, &ext,
row_heap); row_heap);
ut_ad(row); ut_ad(row);
for (ulint i = 0; i < n_nonnull; i++) { for (ulint i = 0; i < n_nonnull; i++) {
const dfield_t* field = &row->fields[nonnull[i]]; dfield_t* field = &row->fields[nonnull[i]];
ut_ad(dfield_get_type(field)->prtype & DATA_NOT_NULL); ut_ad(dfield_get_type(field)->prtype & DATA_NOT_NULL);
if (dfield_is_null(field)) { if (dfield_is_null(field)) {
err = DB_INVALID_NULL; const dfield_t& default_field
trx->error_key_num = 0; = defaults->fields[nonnull[i]];
goto func_exit;
if (default_field.data == NULL) {
err = DB_INVALID_NULL;
trx->error_key_num = 0;
goto func_exit;
}
*field = default_field;
} }
} }
...@@ -4548,7 +4555,7 @@ old_table unless creating a PRIMARY KEY ...@@ -4548,7 +4555,7 @@ old_table unless creating a PRIMARY KEY
@param[in] n_indexes size of indexes[] @param[in] n_indexes size of indexes[]
@param[in,out] table MySQL table, for reporting erroneous key value @param[in,out] table MySQL table, for reporting erroneous key value
if applicable if applicable
@param[in] add_cols default values of added columns, or NULL @param[in] defaults default values of added, changed columns, or NULL
@param[in] col_map mapping of old column numbers to new ones, or @param[in] col_map mapping of old column numbers to new ones, or
NULL if old_table == new_table NULL if old_table == new_table
@param[in] add_autoinc number of added AUTO_INCREMENT columns, or @param[in] add_autoinc number of added AUTO_INCREMENT columns, or
...@@ -4574,7 +4581,7 @@ row_merge_build_indexes( ...@@ -4574,7 +4581,7 @@ row_merge_build_indexes(
const ulint* key_numbers, const ulint* key_numbers,
ulint n_indexes, ulint n_indexes,
struct TABLE* table, struct TABLE* table,
const dtuple_t* add_cols, const dtuple_t* defaults,
const ulint* col_map, const ulint* col_map,
ulint add_autoinc, ulint add_autoinc,
ib_sequence_t& sequence, ib_sequence_t& sequence,
...@@ -4610,7 +4617,7 @@ row_merge_build_indexes( ...@@ -4610,7 +4617,7 @@ row_merge_build_indexes(
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
ut_ad((old_table == new_table) == !col_map); ut_ad((old_table == new_table) == !col_map);
ut_ad(!add_cols || col_map); ut_ad(!defaults || col_map);
stage->begin_phase_read_pk(skip_pk_sort && new_table != old_table stage->begin_phase_read_pk(skip_pk_sort && new_table != old_table
? n_indexes - 1 ? n_indexes - 1
...@@ -4744,7 +4751,7 @@ row_merge_build_indexes( ...@@ -4744,7 +4751,7 @@ row_merge_build_indexes(
error = row_merge_read_clustered_index( error = row_merge_read_clustered_index(
trx, table, old_table, new_table, online, indexes, trx, table, old_table, new_table, online, indexes,
fts_sort_idx, psort_info, merge_files, key_numbers, fts_sort_idx, psort_info, merge_files, key_numbers,
n_indexes, add_cols, add_v, col_map, add_autoinc, n_indexes, defaults, add_v, col_map, add_autoinc,
sequence, block, skip_pk_sort, &tmpfd, stage, sequence, block, skip_pk_sort, &tmpfd, stage,
pct_cost, crypt_block, eval_table, drop_historical); pct_cost, crypt_block, eval_table, drop_historical);
......
...@@ -357,7 +357,7 @@ addition of new virtual columns. ...@@ -357,7 +357,7 @@ addition of new virtual columns.
of an index, or NULL if of an index, or NULL if
index->table should be index->table should be
consulted instead consulted instead
@param[in] add_cols default values of added columns, or NULL @param[in] defaults default values of added/changed columns, or NULL
@param[in] add_v new virtual columns added @param[in] add_v new virtual columns added
along with new indexes along with new indexes
@param[in] col_map mapping of old column @param[in] col_map mapping of old column
...@@ -375,7 +375,7 @@ row_build_low( ...@@ -375,7 +375,7 @@ row_build_low(
const rec_t* rec, const rec_t* rec,
const ulint* offsets, const ulint* offsets,
const dict_table_t* col_table, const dict_table_t* col_table,
const dtuple_t* add_cols, const dtuple_t* defaults,
const dict_add_v_col_t* add_v, const dict_add_v_col_t* add_v,
const ulint* col_map, const ulint* col_map,
row_ext_t** ext, row_ext_t** ext,
...@@ -441,13 +441,13 @@ row_build_low( ...@@ -441,13 +441,13 @@ row_build_low(
if (!col_table) { if (!col_table) {
ut_ad(!col_map); ut_ad(!col_map);
ut_ad(!add_cols); ut_ad(!defaults);
col_table = index->table; col_table = index->table;
} }
if (add_cols) { if (defaults) {
ut_ad(col_map); ut_ad(col_map);
row = dtuple_copy(add_cols, heap); row = dtuple_copy(defaults, heap);
/* dict_table_copy_types() would set the fields to NULL */ /* dict_table_copy_types() would set the fields to NULL */
for (ulint i = 0; i < dict_table_get_n_cols(col_table); i++) { for (ulint i = 0; i < dict_table_get_n_cols(col_table); i++) {
dict_col_copy_type( dict_col_copy_type(
...@@ -594,9 +594,9 @@ row_build( ...@@ -594,9 +594,9 @@ row_build(
of an index, or NULL if of an index, or NULL if
index->table should be index->table should be
consulted instead */ consulted instead */
const dtuple_t* add_cols, const dtuple_t* defaults,
/*!< in: default values of /*!< in: default values of
added columns, or NULL */ added and changed columns, or NULL */
const ulint* col_map,/*!< in: mapping of old column const ulint* col_map,/*!< in: mapping of old column
numbers to new ones, or NULL */ numbers to new ones, or NULL */
row_ext_t** ext, /*!< out, own: cache of row_ext_t** ext, /*!< out, own: cache of
...@@ -606,7 +606,7 @@ row_build( ...@@ -606,7 +606,7 @@ row_build(
the memory needed is allocated */ the memory needed is allocated */
{ {
return(row_build_low(type, index, rec, offsets, col_table, return(row_build_low(type, index, rec, offsets, col_table,
add_cols, NULL, col_map, ext, heap)); defaults, NULL, col_map, ext, heap));
} }
/** An inverse function to row_build_index_entry. Builds a row from a /** An inverse function to row_build_index_entry. Builds a row from a
...@@ -622,7 +622,7 @@ addition of new virtual columns. ...@@ -622,7 +622,7 @@ addition of new virtual columns.
of an index, or NULL if of an index, or NULL if
index->table should be index->table should be
consulted instead consulted instead
@param[in] add_cols default values of added columns, or NULL @param[in] defaults default values of added, changed columns, or NULL
@param[in] add_v new virtual columns added @param[in] add_v new virtual columns added
along with new indexes along with new indexes
@param[in] col_map mapping of old column @param[in] col_map mapping of old column
...@@ -639,14 +639,14 @@ row_build_w_add_vcol( ...@@ -639,14 +639,14 @@ row_build_w_add_vcol(
const rec_t* rec, const rec_t* rec,
const ulint* offsets, const ulint* offsets,
const dict_table_t* col_table, const dict_table_t* col_table,
const dtuple_t* add_cols, const dtuple_t* defaults,
const dict_add_v_col_t* add_v, const dict_add_v_col_t* add_v,
const ulint* col_map, const ulint* col_map,
row_ext_t** ext, row_ext_t** ext,
mem_heap_t* heap) mem_heap_t* heap)
{ {
return(row_build_low(type, index, rec, offsets, col_table, return(row_build_low(type, index, rec, offsets, col_table,
add_cols, add_v, col_map, ext, heap)); defaults, add_v, col_map, ext, heap));
} }
/** Convert an index record to a data tuple. /** Convert an index record to a data tuple.
......
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