Commit 47687eef authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-12936 upgrade to 10.2.6 failed upon tables with virtual columns

when opening 10.1- table that has virtual columns:

1. don't error out if it has vcols over autoinc columns.
   just issue a warning.
2. set vcol type properly
3. in innodb: use table->s->stored_fields instead of table->s->fields,
   because that's what was stored in innodb data dictionary
parent 75f80004
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
check table vcol_autoinc for upgrade;
Table Op Msg_type Msg_text
test.vcol_autoinc check Warning Function or expression 'AUTO_INCREMENT' cannot be used in the GENERATED ALWAYS AS clause of `pk`
test.vcol_autoinc check status OK
show create table vcol_autoinc;
Table Create Table
vcol_autoinc CREATE TABLE `vcol_autoinc` (
`pk` int(11) NOT NULL AUTO_INCREMENT,
`v3` int(11) GENERATED ALWAYS AS (`pk`) VIRTUAL,
PRIMARY KEY (`pk`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from vcol_autoinc;
pk v3
insert vcol_autoinc (pk) values (1);
select * from vcol_autoinc;
pk v3
1 1
drop table vcol_autoinc;
#
# MDEV-12936 upgrade to 10.2.6 failed upon tables with virtual columns
#
let $datadir=`select @@datadir`;
copy_file std_data/vcol_autoinc.frm $datadir/test/vcol_autoinc.frm;
copy_file std_data/vcol_autoinc.MYD $datadir/test/vcol_autoinc.MYD;
copy_file std_data/vcol_autoinc.MYI $datadir/test/vcol_autoinc.MYI;
check table vcol_autoinc for upgrade;
show create table vcol_autoinc;
select * from vcol_autoinc;
insert vcol_autoinc (pk) values (1);
select * from vcol_autoinc;
drop table vcol_autoinc;
...@@ -1860,7 +1860,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1860,7 +1860,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
interval_nr= (uint)vcol_screen_pos[3]; interval_nr= (uint)vcol_screen_pos[3];
else if ((uint)vcol_screen_pos[0] != 1) else if ((uint)vcol_screen_pos[0] != 1)
goto err; goto err;
vcol_info->stored_in_db= vcol_screen_pos[2] & 1; bool stored= vcol_screen_pos[2] & 1;
vcol_info->stored_in_db= stored;
vcol_info->set_vcol_type(stored ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL);
vcol_expr_length= vcol_info_length - vcol_expr_length= vcol_info_length -
(uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id)); (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
vcol_info->utf8= 0; // before 10.2.1 the charset was unknown vcol_info->utf8= 0; // before 10.2.1 the charset was unknown
...@@ -2862,8 +2864,10 @@ static bool fix_and_check_vcol_expr(THD *thd, TABLE *table, ...@@ -2862,8 +2864,10 @@ static bool fix_and_check_vcol_expr(THD *thd, TABLE *table,
of the statement because the field item does not have a field of the statement because the field item does not have a field
pointer at that time pointer at that time
*/ */
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), myf warn= table->s->frm_version < FRM_VER_EXPRESSSIONS ? ME_JUST_WARNING : 0;
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(warn),
"AUTO_INCREMENT", vcol->get_vcol_type_name(), res.name); "AUTO_INCREMENT", vcol->get_vcol_type_name(), res.name);
if (!warn)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
vcol->flags= res.errors; vcol->flags= res.errors;
......
...@@ -291,6 +291,11 @@ void set_my_errno(int err) ...@@ -291,6 +291,11 @@ void set_my_errno(int err)
errno = err; errno = err;
} }
static uint mysql_fields(const TABLE *table)
{
return table->s->frm_version < FRM_VER_EXPRESSSIONS
? table->s->stored_fields : table->s->fields;
}
/** Checks whether the file name belongs to a partition of a table. /** Checks whether the file name belongs to a partition of a table.
@param[in] file_name file name @param[in] file_name file name
...@@ -6495,16 +6500,17 @@ ha_innobase::open(const char* name, int, uint) ...@@ -6495,16 +6500,17 @@ ha_innobase::open(const char* name, int, uint)
ib_table = open_dict_table(name, norm_name, is_part, ignore_err); ib_table = open_dict_table(name, norm_name, is_part, ignore_err);
uint n_fields = mysql_fields(table);
if (ib_table != NULL if (ib_table != NULL
&& ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID)
&& table->s->fields != dict_table_get_n_tot_u_cols(ib_table)) && n_fields != dict_table_get_n_tot_u_cols(ib_table))
|| (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) || (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID)
&& (table->s->fields && (n_fields != dict_table_get_n_tot_u_cols(ib_table) - 1)))) {
!= dict_table_get_n_tot_u_cols(ib_table) - 1)))) {
ib::warn() << "Table " << norm_name << " contains " ib::warn() << "Table " << norm_name << " contains "
<< dict_table_get_n_user_cols(ib_table) << " user" << dict_table_get_n_tot_u_cols(ib_table) << " user"
" defined columns in InnoDB, but " << table->s->fields " defined columns in InnoDB, but " << n_fields
<< " columns in MariaDB. Please check" << " columns in MariaDB. Please check"
" INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN " INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN
"innodb-troubleshooting.html for how to resolve the" "innodb-troubleshooting.html for how to resolve the"
...@@ -8033,7 +8039,7 @@ ha_innobase::build_template( ...@@ -8033,7 +8039,7 @@ ha_innobase::build_template(
/* Below we check column by column if we need to access /* Below we check column by column if we need to access
the clustered index. */ the clustered index. */
n_fields = (ulint) table->s->fields; /* number of columns */ n_fields = (ulint) mysql_fields(table);
if (!m_prebuilt->mysql_template) { if (!m_prebuilt->mysql_template) {
m_prebuilt->mysql_template = (mysql_row_templ_t*) m_prebuilt->mysql_template = (mysql_row_templ_t*)
...@@ -8894,6 +8900,7 @@ calc_row_difference( ...@@ -8894,6 +8900,7 @@ calc_row_difference(
trx_t* const trx = prebuilt->trx; trx_t* const trx = prebuilt->trx;
doc_id_t doc_id = FTS_NULL_DOC_ID; doc_id_t doc_id = FTS_NULL_DOC_ID;
ulint num_v = 0; ulint num_v = 0;
uint n_fields = mysql_fields(table);
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
...@@ -8903,7 +8910,7 @@ calc_row_difference( ...@@ -8903,7 +8910,7 @@ calc_row_difference(
/* We use upd_buff to convert changed fields */ /* We use upd_buff to convert changed fields */
buf = (byte*) upd_buff; buf = (byte*) upd_buff;
for (i = 0; i < table->s->fields; i++) { for (i = 0; i < n_fields; i++) {
field = table->field[i]; field = table->field[i];
bool is_virtual = innobase_is_v_fld(field); bool is_virtual = innobase_is_v_fld(field);
dict_col_t* col; dict_col_t* col;
...@@ -9285,7 +9292,7 @@ wsrep_calc_row_hash( ...@@ -9285,7 +9292,7 @@ wsrep_calc_row_hash(
void *ctx = alloca(my_md5_context_size()); void *ctx = alloca(my_md5_context_size());
my_md5_init(ctx); my_md5_init(ctx);
n_fields = table->s->fields; n_fields = mysql_fields(table);
for (i = 0; i < n_fields; i++) { for (i = 0; i < n_fields; i++) {
byte null_byte=0; byte null_byte=0;
...@@ -11352,7 +11359,9 @@ create_table_check_doc_id_col( ...@@ -11352,7 +11359,9 @@ create_table_check_doc_id_col(
ULINT_UNDEFINED if column is of the ULINT_UNDEFINED if column is of the
wrong type/name/size */ wrong type/name/size */
{ {
for (ulint i = 0; i < form->s->fields; i++) { uint n_fields = mysql_fields(form);
for (ulint i = 0; i < n_fields; i++) {
const Field* field; const Field* field;
ulint col_type; ulint col_type;
ulint col_len; ulint col_len;
......
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