Commit 94dfa010 authored by unknown's avatar unknown

Virtual column support for new innodb.

parent a06a844d
...@@ -2182,7 +2182,7 @@ ha_innobase::ha_innobase( ...@@ -2182,7 +2182,7 @@ ha_innobase::ha_innobase(
TABLE_SHARE* table_arg) TABLE_SHARE* table_arg)
:handler(hton, table_arg), :handler(hton, table_arg),
int_table_flags(HA_REC_NOT_IN_SEQ | int_table_flags(HA_REC_NOT_IN_SEQ |
HA_NULL_IN_KEY | HA_NULL_IN_KEY | HA_CAN_VIRTUAL_COLUMNS |
HA_CAN_INDEX_BLOBS | HA_CAN_INDEX_BLOBS |
HA_CAN_SQL_HANDLER | HA_CAN_SQL_HANDLER |
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
...@@ -4921,7 +4921,7 @@ ha_innobase::open( ...@@ -4921,7 +4921,7 @@ ha_innobase::open(
if (ib_table if (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 != dict_table_get_n_user_cols(ib_table)) && table->s->stored_fields != dict_table_get_n_user_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 && (table->s->fields
!= dict_table_get_n_user_cols(ib_table) - 1)))) { != dict_table_get_n_user_cols(ib_table) - 1)))) {
...@@ -5080,7 +5080,7 @@ ha_innobase::open( ...@@ -5080,7 +5080,7 @@ ha_innobase::open(
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
} }
prebuilt = row_create_prebuilt(ib_table, table->s->reclength); prebuilt = row_create_prebuilt(ib_table, table->s->stored_rec_length);
prebuilt->default_rec = table->s->default_values; prebuilt->default_rec = table->s->default_values;
ut_ad(prebuilt->default_rec); ut_ad(prebuilt->default_rec);
...@@ -6128,9 +6128,10 @@ build_template_needs_field( ...@@ -6128,9 +6128,10 @@ build_template_needs_field(
primary key columns */ primary key columns */
dict_index_t* index, /*!< in: InnoDB index to use */ dict_index_t* index, /*!< in: InnoDB index to use */
const TABLE* table, /*!< in: MySQL table object */ const TABLE* table, /*!< in: MySQL table object */
ulint i) /*!< in: field index in InnoDB table */ ulint i, /*!< in: field index in InnoDB table */
ulint sql_idx) /*!< in: field index in SQL table */
{ {
const Field* field = table->field[i]; const Field* field = table->field[sql_idx];
ut_ad(index_contains == dict_index_contains_col_or_prefix(index, i)); ut_ad(index_contains == dict_index_contains_col_or_prefix(index, i));
...@@ -6147,8 +6148,8 @@ build_template_needs_field( ...@@ -6147,8 +6148,8 @@ build_template_needs_field(
return(field); return(field);
} }
if (bitmap_is_set(table->read_set, i) if (bitmap_is_set(table->read_set, sql_idx)
|| bitmap_is_set(table->write_set, i)) { || bitmap_is_set(table->write_set, sql_idx)) {
/* This field is needed in the query */ /* This field is needed in the query */
return(field); return(field);
...@@ -6203,7 +6204,7 @@ build_template_field( ...@@ -6203,7 +6204,7 @@ build_template_field(
mysql_row_templ_t* templ; mysql_row_templ_t* templ;
const dict_col_t* col; const dict_col_t* col;
ut_ad(field == table->field[i]); //ut_ad(field == table->field[i]);
ut_ad(clust_index->table == index->table); ut_ad(clust_index->table == index->table);
col = dict_table_get_nth_col(index->table, i); col = dict_table_get_nth_col(index->table, i);
...@@ -6275,10 +6276,10 @@ ha_innobase::build_template( ...@@ -6275,10 +6276,10 @@ ha_innobase::build_template(
{ {
dict_index_t* index; dict_index_t* index;
dict_index_t* clust_index; dict_index_t* clust_index;
ulint n_fields; ulint n_stored_fields;
ibool fetch_all_in_key = FALSE; ibool fetch_all_in_key = FALSE;
ibool fetch_primary_key_cols = FALSE; ibool fetch_primary_key_cols = FALSE;
ulint i; ulint i, sql_idx;
if (prebuilt->select_lock_type == LOCK_X) { if (prebuilt->select_lock_type == LOCK_X) {
/* We always retrieve the whole clustered index record if we /* We always retrieve the whole clustered index record if we
...@@ -6331,11 +6332,11 @@ ha_innobase::build_template( ...@@ -6331,11 +6332,11 @@ 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_stored_fields= (ulint)table->s->stored_fields; /* number of stored columns */
if (!prebuilt->mysql_template) { if (!prebuilt->mysql_template) {
prebuilt->mysql_template = (mysql_row_templ_t*) prebuilt->mysql_template = (mysql_row_templ_t*)
mem_alloc(n_fields * sizeof(mysql_row_templ_t)); mem_alloc(n_stored_fields * sizeof(mysql_row_templ_t));
} }
prebuilt->template_type = whole_row prebuilt->template_type = whole_row
...@@ -6353,7 +6354,12 @@ ha_innobase::build_template( ...@@ -6353,7 +6354,12 @@ ha_innobase::build_template(
if (active_index != MAX_KEY && active_index == pushed_idx_cond_keyno) { if (active_index != MAX_KEY && active_index == pushed_idx_cond_keyno) {
/* Push down an index condition or an end_range check. */ /* Push down an index condition or an end_range check. */
for (i = 0; i < n_fields; i++) { for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
while (!table->field[sql_idx]->stored_in_db) {
sql_idx++;
}
const ibool index_contains const ibool index_contains
= dict_index_contains_col_or_prefix(index, i); = dict_index_contains_col_or_prefix(index, i);
...@@ -6378,14 +6384,14 @@ ha_innobase::build_template( ...@@ -6378,14 +6384,14 @@ ha_innobase::build_template(
mysql_row_templ_t* templ; mysql_row_templ_t* templ;
if (whole_row) { if (whole_row) {
field = table->field[i]; field = table->field[sql_idx];
} else { } else {
field = build_template_needs_field( field = build_template_needs_field(
index_contains, index_contains,
prebuilt->read_just_key, prebuilt->read_just_key,
fetch_all_in_key, fetch_all_in_key,
fetch_primary_key_cols, fetch_primary_key_cols,
index, table, i); index, table, i, sql_idx);
if (!field) { if (!field) {
continue; continue;
} }
...@@ -6466,7 +6472,12 @@ ha_innobase::build_template( ...@@ -6466,7 +6472,12 @@ ha_innobase::build_template(
/* Include the fields that are not needed in index condition /* Include the fields that are not needed in index condition
pushdown. */ pushdown. */
for (i = 0; i < n_fields; i++) { for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
while (!table->field[sql_idx]->stored_in_db) {
sql_idx++;
}
const ibool index_contains const ibool index_contains
= dict_index_contains_col_or_prefix(index, i); = dict_index_contains_col_or_prefix(index, i);
...@@ -6476,14 +6487,14 @@ ha_innobase::build_template( ...@@ -6476,14 +6487,14 @@ ha_innobase::build_template(
const Field* field; const Field* field;
if (whole_row) { if (whole_row) {
field = table->field[i]; field = table->field[sql_idx];
} else { } else {
field = build_template_needs_field( field = build_template_needs_field(
index_contains, index_contains,
prebuilt->read_just_key, prebuilt->read_just_key,
fetch_all_in_key, fetch_all_in_key,
fetch_primary_key_cols, fetch_primary_key_cols,
index, table, i); index, table, i, sql_idx);
if (!field) { if (!field) {
continue; continue;
} }
...@@ -6500,11 +6511,15 @@ ha_innobase::build_template( ...@@ -6500,11 +6511,15 @@ ha_innobase::build_template(
/* No index condition pushdown */ /* No index condition pushdown */
prebuilt->idx_cond = NULL; prebuilt->idx_cond = NULL;
for (i = 0; i < n_fields; i++) { for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
const Field* field; const Field* field;
while (!table->field[sql_idx]->stored_in_db) {
sql_idx++;
}
if (whole_row) { if (whole_row) {
field = table->field[i]; field = table->field[sql_idx];
} else { } else {
field = build_template_needs_field( field = build_template_needs_field(
dict_index_contains_col_or_prefix( dict_index_contains_col_or_prefix(
...@@ -6512,7 +6527,7 @@ ha_innobase::build_template( ...@@ -6512,7 +6527,7 @@ ha_innobase::build_template(
prebuilt->read_just_key, prebuilt->read_just_key,
fetch_all_in_key, fetch_all_in_key,
fetch_primary_key_cols, fetch_primary_key_cols,
index, table, i); index, table, i, sql_idx);
if (!field) { if (!field) {
continue; continue;
} }
...@@ -6946,7 +6961,7 @@ calc_row_difference( ...@@ -6946,7 +6961,7 @@ calc_row_difference(
ulint n_changed = 0; ulint n_changed = 0;
dfield_t dfield; dfield_t dfield;
dict_index_t* clust_index; dict_index_t* clust_index;
uint i; uint sql_idx, innodb_idx= 0;
ibool changes_fts_column = FALSE; ibool changes_fts_column = FALSE;
ibool changes_fts_doc_col = FALSE; ibool changes_fts_doc_col = FALSE;
trx_t* trx = thd_to_trx(thd); trx_t* trx = thd_to_trx(thd);
...@@ -6960,8 +6975,10 @@ calc_row_difference( ...@@ -6960,8 +6975,10 @@ 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 < n_fields; i++) { for (sql_idx = 0; sql_idx < n_fields; sql_idx++) {
field = table->field[i]; field = table->field[sql_idx];
if (!field->stored_in_db)
continue;
o_ptr = (const byte*) old_row + get_field_offset(table, field); o_ptr = (const byte*) old_row + get_field_offset(table, field);
n_ptr = (const byte*) new_row + get_field_offset(table, field); n_ptr = (const byte*) new_row + get_field_offset(table, field);
...@@ -6979,7 +6996,7 @@ calc_row_difference( ...@@ -6979,7 +6996,7 @@ calc_row_difference(
field_mysql_type = field->type(); field_mysql_type = field->type();
col_type = prebuilt->table->cols[i].mtype; col_type = prebuilt->table->cols[innodb_idx].mtype;
switch (col_type) { switch (col_type) {
...@@ -7046,7 +7063,8 @@ calc_row_difference( ...@@ -7046,7 +7063,8 @@ calc_row_difference(
from the MySQL column format to the InnoDB format */ from the MySQL column format to the InnoDB format */
if (n_len != UNIV_SQL_NULL) { if (n_len != UNIV_SQL_NULL) {
dict_col_copy_type(prebuilt->table->cols + i, dict_col_copy_type(prebuilt->table->cols +
innodb_idx,
dfield_get_type(&dfield)); dfield_get_type(&dfield));
buf = row_mysql_store_col_in_innobase_format( buf = row_mysql_store_col_in_innobase_format(
...@@ -7064,7 +7082,7 @@ calc_row_difference( ...@@ -7064,7 +7082,7 @@ calc_row_difference(
ufield->exp = NULL; ufield->exp = NULL;
ufield->orig_len = 0; ufield->orig_len = 0;
ufield->field_no = dict_col_get_clust_pos( ufield->field_no = dict_col_get_clust_pos(
&prebuilt->table->cols[i], clust_index); &prebuilt->table->cols[innodb_idx], clust_index);
n_changed++; n_changed++;
/* If an FTS indexed column was changed by this /* If an FTS indexed column was changed by this
...@@ -7098,6 +7116,8 @@ calc_row_difference( ...@@ -7098,6 +7116,8 @@ calc_row_difference(
} }
} }
} }
if (field->stored_in_db)
innodb_idx++;
} }
/* If the update changes a column with an FTS index on it, we /* If the update changes a column with an FTS index on it, we
...@@ -7217,13 +7237,14 @@ ha_innobase::update_row( ...@@ -7217,13 +7237,14 @@ ha_innobase::update_row(
if (upd_buf == NULL) { if (upd_buf == NULL) {
ut_ad(upd_buf_size == 0); ut_ad(upd_buf_size == 0);
/* Create a buffer for packing the fields of a record. Why /* Create a buffer for packing the fields of a record. Why
table->reclength did not work here? Obviously, because char table->stored_rec_length did not work here? Obviously,
fields when packed actually became 1 byte longer, when we also because char fields when packed actually became 1 byte
stored the string length as the first byte. */ longer, when we also stored the string length as the first
byte. */
upd_buf_size = table->s->reclength + table->s->max_key_length upd_buf_size = table->s->stored_rec_length +
+ MAX_REF_PARTS * 3; table->s->max_key_length + MAX_REF_PARTS * 3;
upd_buf = (uchar*) my_malloc(upd_buf_size, MYF(MY_WME)); upd_buf = (uchar*) my_malloc(upd_buf_size, MYF(MY_WME));
if (upd_buf == NULL) { if (upd_buf == NULL) {
upd_buf_size = 0; upd_buf_size = 0;
...@@ -8707,18 +8728,18 @@ create_table_def( ...@@ -8707,18 +8728,18 @@ create_table_def(
if (flags2 & DICT_TF2_FTS) { if (flags2 & DICT_TF2_FTS) {
/* Adjust for the FTS hidden field */ /* Adjust for the FTS hidden field */
if (!has_doc_id_col) { if (!has_doc_id_col) {
table = dict_mem_table_create(table_name, 0, n_cols + 1, table = dict_mem_table_create(table_name, 0, form->s->stored_fields + 1,
flags, flags2); flags, flags2);
/* Set the hidden doc_id column. */ /* Set the hidden doc_id column. */
table->fts->doc_col = n_cols; table->fts->doc_col = form->s->stored_fields;
} else { } else {
table = dict_mem_table_create(table_name, 0, n_cols, table = dict_mem_table_create(table_name, 0, form->s->stored_fields,
flags, flags2); flags, flags2);
table->fts->doc_col = doc_id_col; table->fts->doc_col = doc_id_col;
} }
} else { } else {
table = dict_mem_table_create(table_name, 0, n_cols, table = dict_mem_table_create(table_name, 0, form->s->stored_fields,
flags, flags2); flags, flags2);
} }
...@@ -8738,6 +8759,8 @@ create_table_def( ...@@ -8738,6 +8759,8 @@ create_table_def(
for (i = 0; i < n_cols; i++) { for (i = 0; i < n_cols; i++) {
Field* field = form->field[i]; Field* field = form->field[i];
if (!field->stored_in_db)
continue;
col_type = get_innobase_type_from_mysql_type(&unsigned_type, col_type = get_innobase_type_from_mysql_type(&unsigned_type,
field); field);
...@@ -9644,7 +9667,7 @@ ha_innobase::create( ...@@ -9644,7 +9667,7 @@ ha_innobase::create(
DBUG_ASSERT(thd != NULL); DBUG_ASSERT(thd != NULL);
DBUG_ASSERT(create_info != NULL); DBUG_ASSERT(create_info != NULL);
if (form->s->fields > REC_MAX_N_USER_FIELDS) { if (form->s->stored_fields > REC_MAX_N_USER_FIELDS) {
DBUG_RETURN(HA_ERR_TOO_MANY_FIELDS); DBUG_RETURN(HA_ERR_TOO_MANY_FIELDS);
} else if (srv_read_only_mode) { } else if (srv_read_only_mode) {
DBUG_RETURN(HA_ERR_TABLE_READONLY); DBUG_RETURN(HA_ERR_TABLE_READONLY);
......
...@@ -235,7 +235,7 @@ ha_innobase::check_if_supported_inplace_alter( ...@@ -235,7 +235,7 @@ ha_innobase::check_if_supported_inplace_alter(
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
} }
if (altered_table->s->fields > REC_MAX_N_USER_FIELDS) { if (altered_table->s->stored_fields > REC_MAX_N_USER_FIELDS) {
/* Deny the inplace ALTER TABLE. MySQL will try to /* Deny the inplace ALTER TABLE. MySQL will try to
re-create the table and ha_innobase::create() will re-create the table and ha_innobase::create() will
return an error too. This is how we effectively return an error too. This is how we effectively
...@@ -364,8 +364,7 @@ ha_innobase::check_if_supported_inplace_alter( ...@@ -364,8 +364,7 @@ ha_innobase::check_if_supported_inplace_alter(
key_part++) { key_part++) {
const Create_field* new_field; const Create_field* new_field;
DBUG_ASSERT(key_part->fieldnr DBUG_ASSERT(key_part->fieldnr < altered_table->s->fields);
< altered_table->s->fields);
cf_it.rewind(); cf_it.rewind();
for (uint fieldnr = 0; (new_field = cf_it++); for (uint fieldnr = 0; (new_field = cf_it++);
...@@ -426,7 +425,7 @@ ha_innobase::check_if_supported_inplace_alter( ...@@ -426,7 +425,7 @@ ha_innobase::check_if_supported_inplace_alter(
} }
DBUG_ASSERT(!prebuilt->table->fts || prebuilt->table->fts->doc_col DBUG_ASSERT(!prebuilt->table->fts || prebuilt->table->fts->doc_col
<= table->s->fields); <= table->s->stored_fields);
DBUG_ASSERT(!prebuilt->table->fts || prebuilt->table->fts->doc_col DBUG_ASSERT(!prebuilt->table->fts || prebuilt->table->fts->doc_col
< dict_table_get_n_user_cols(prebuilt->table)); < dict_table_get_n_user_cols(prebuilt->table));
...@@ -1135,18 +1134,22 @@ innobase_rec_to_mysql( ...@@ -1135,18 +1134,22 @@ innobase_rec_to_mysql(
const ulint* offsets)/*!< in: rec_get_offsets( const ulint* offsets)/*!< in: rec_get_offsets(
rec, index, ...) */ rec, index, ...) */
{ {
uint n_fields = table->s->fields; uint n_fields = table->s->stored_fields;
uint sql_idx = 0;
ut_ad(n_fields == dict_table_get_n_user_cols(index->table) ut_ad(n_fields == dict_table_get_n_user_cols(index->table)
- !!(DICT_TF2_FLAG_IS_SET(index->table, - !!(DICT_TF2_FLAG_IS_SET(index->table,
DICT_TF2_FTS_HAS_DOC_ID))); DICT_TF2_FTS_HAS_DOC_ID)));
for (uint i = 0; i < n_fields; i++) { for (uint i = 0; i < n_fields; i++, sql_idx++) {
Field* field = table->field[i]; Field* field;
ulint ipos; ulint ipos;
ulint ilen; ulint ilen;
const uchar* ifield; const uchar* ifield;
while (!((field= table->field[sql_idx])->stored_in_db))
sql_idx++;
field->reset(); field->reset();
ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE); ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE);
...@@ -1185,16 +1188,20 @@ innobase_fields_to_mysql( ...@@ -1185,16 +1188,20 @@ innobase_fields_to_mysql(
const dict_index_t* index, /*!< in: InnoDB index */ const dict_index_t* index, /*!< in: InnoDB index */
const dfield_t* fields) /*!< in: InnoDB index fields */ const dfield_t* fields) /*!< in: InnoDB index fields */
{ {
uint n_fields = table->s->fields; uint n_fields = table->s->stored_fields;
uint sql_idx = 0;
ut_ad(n_fields == dict_table_get_n_user_cols(index->table) ut_ad(n_fields == dict_table_get_n_user_cols(index->table)
- !!(DICT_TF2_FLAG_IS_SET(index->table, - !!(DICT_TF2_FLAG_IS_SET(index->table,
DICT_TF2_FTS_HAS_DOC_ID))); DICT_TF2_FTS_HAS_DOC_ID)));
for (uint i = 0; i < n_fields; i++) { for (uint i = 0; i < n_fields; i++, sql_idx++) {
Field* field = table->field[i]; Field* field;
ulint ipos; ulint ipos;
while (!((field= table->field[sql_idx])->stored_in_db))
sql_idx++;
field->reset(); field->reset();
ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE); ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE);
...@@ -1228,17 +1235,21 @@ innobase_row_to_mysql( ...@@ -1228,17 +1235,21 @@ innobase_row_to_mysql(
const dict_table_t* itab, /*!< in: InnoDB table */ const dict_table_t* itab, /*!< in: InnoDB table */
const dtuple_t* row) /*!< in: InnoDB row */ const dtuple_t* row) /*!< in: InnoDB row */
{ {
uint n_fields = table->s->fields; uint n_fields = table->s->stored_fields;
uint sql_idx = 0;
/* The InnoDB row may contain an extra FTS_DOC_ID column at the end. */ /* The InnoDB row may contain an extra FTS_DOC_ID column at the end. */
ut_ad(row->n_fields == dict_table_get_n_cols(itab)); ut_ad(row->n_fields == dict_table_get_n_cols(itab));
ut_ad(n_fields == row->n_fields - DATA_N_SYS_COLS ut_ad(n_fields == row->n_fields - DATA_N_SYS_COLS
- !!(DICT_TF2_FLAG_IS_SET(itab, DICT_TF2_FTS_HAS_DOC_ID))); - !!(DICT_TF2_FLAG_IS_SET(itab, DICT_TF2_FTS_HAS_DOC_ID)));
for (uint i = 0; i < n_fields; i++) { for (uint i = 0; i < n_fields; i++, sql_idx++) {
Field* field = table->field[i]; Field* field;
const dfield_t* df = dtuple_get_nth_field(row, i); const dfield_t* df = dtuple_get_nth_field(row, i);
while (!((field= table->field[sql_idx])->stored_in_db))
sql_idx++;
field->reset(); field->reset();
if (dfield_is_ext(df) || dfield_is_null(df)) { if (dfield_is_ext(df) || dfield_is_null(df)) {
...@@ -1531,12 +1542,15 @@ innobase_fts_check_doc_id_col( ...@@ -1531,12 +1542,15 @@ innobase_fts_check_doc_id_col(
{ {
*fts_doc_col_no = ULINT_UNDEFINED; *fts_doc_col_no = ULINT_UNDEFINED;
const uint n_cols = altered_table->s->fields; const uint n_cols = altered_table->s->stored_fields;
uint sql_idx = 0;
uint i; uint i;
for (i = 0; i < n_cols; i++) { for (i = 0; i < n_cols; i++, sql_idx++) {
const Field* field = altered_table->s->field[i]; const Field* field;
while (!((field= altered_table->field[sql_idx])->
stored_in_db))
sql_idx++;
if (my_strcasecmp(system_charset_info, if (my_strcasecmp(system_charset_info,
field->field_name, FTS_DOC_ID_COL_NAME)) { field->field_name, FTS_DOC_ID_COL_NAME)) {
continue; continue;
...@@ -1861,7 +1875,8 @@ innobase_create_key_defs( ...@@ -1861,7 +1875,8 @@ innobase_create_key_defs(
&& !innobase_fts_check_doc_id_col( && !innobase_fts_check_doc_id_col(
NULL, altered_table, NULL, altered_table,
&fts_doc_id_col)) { &fts_doc_id_col)) {
fts_doc_id_col = altered_table->s->fields; fts_doc_id_col =
altered_table->s->stored_fields;
add_fts_doc_id = true; add_fts_doc_id = true;
} }
...@@ -1916,7 +1931,7 @@ innobase_create_key_defs( ...@@ -1916,7 +1931,7 @@ innobase_create_key_defs(
index->name = mem_heap_strdup( index->name = mem_heap_strdup(
heap, FTS_DOC_ID_INDEX_NAME); heap, FTS_DOC_ID_INDEX_NAME);
ut_ad(!add_fts_doc_id ut_ad(!add_fts_doc_id
|| fts_doc_id_col == altered_table->s->fields); || fts_doc_id_col == altered_table->s->stored_fields);
} else { } else {
char* index_name; char* index_name;
index->name = index_name = static_cast<char*>( index->name = index_name = static_cast<char*>(
...@@ -2351,13 +2366,14 @@ innobase_build_col_map( ...@@ -2351,13 +2366,14 @@ innobase_build_col_map(
dtuple_t* add_cols, dtuple_t* add_cols,
mem_heap_t* heap) mem_heap_t* heap)
{ {
uint old_i, old_innobase_i;
DBUG_ENTER("innobase_build_col_map"); DBUG_ENTER("innobase_build_col_map");
DBUG_ASSERT(altered_table != table); DBUG_ASSERT(altered_table != table);
DBUG_ASSERT(new_table != old_table); DBUG_ASSERT(new_table != old_table);
DBUG_ASSERT(dict_table_get_n_cols(new_table) DBUG_ASSERT(dict_table_get_n_cols(new_table)
>= altered_table->s->fields + DATA_N_SYS_COLS); >= altered_table->s->stored_fields + DATA_N_SYS_COLS);
DBUG_ASSERT(dict_table_get_n_cols(old_table) DBUG_ASSERT(dict_table_get_n_cols(old_table)
>= table->s->fields + DATA_N_SYS_COLS); >= table->s->stored_fields + DATA_N_SYS_COLS);
DBUG_ASSERT(!!add_cols == !!(ha_alter_info->handler_flags DBUG_ASSERT(!!add_cols == !!(ha_alter_info->handler_flags
& Alter_inplace_info::ADD_COLUMN)); & Alter_inplace_info::ADD_COLUMN));
DBUG_ASSERT(!add_cols || dtuple_get_n_fields(add_cols) DBUG_ASSERT(!add_cols || dtuple_get_n_fields(add_cols)
...@@ -2368,34 +2384,46 @@ innobase_build_col_map( ...@@ -2368,34 +2384,46 @@ innobase_build_col_map(
List_iterator_fast<Create_field> cf_it( List_iterator_fast<Create_field> cf_it(
ha_alter_info->alter_info->create_list); ha_alter_info->alter_info->create_list);
uint i = 0; uint i = 0, sql_idx = 0;
/* Any dropped columns will map to ULINT_UNDEFINED. */ /* Any dropped columns will map to ULINT_UNDEFINED. */
for (uint old_i = 0; old_i + DATA_N_SYS_COLS < old_table->n_cols; for (old_innobase_i = 0;
old_i++) { old_innobase_i + DATA_N_SYS_COLS < old_table->n_cols;
col_map[old_i] = ULINT_UNDEFINED; old_innobase_i++) {
col_map[old_innobase_i] = ULINT_UNDEFINED;
} }
while (const Create_field* new_field = cf_it++) { while (const Create_field* new_field = cf_it++) {
for (uint old_i = 0; table->field[old_i]; old_i++) { if (!new_field->stored_in_db)
{
sql_idx++;
continue;
}
for (old_i = 0, old_innobase_i= 0;
table->field[old_i];
old_i++) {
const Field* field = table->field[old_i]; const Field* field = table->field[old_i];
if (!table->field[old_i]->stored_in_db)
continue;
if (new_field->field == field) { if (new_field->field == field) {
col_map[old_i] = i; col_map[old_innobase_i] = i;
goto found_col; goto found_col;
} }
old_innobase_i++;
} }
innobase_build_col_map_add( innobase_build_col_map_add(
heap, dtuple_get_nth_field(add_cols, i), heap, dtuple_get_nth_field(add_cols, i),
altered_table->s->field[i], altered_table->s->field[sql_idx],
dict_table_is_comp(new_table)); dict_table_is_comp(new_table));
found_col: found_col:
i++; i++;
sql_idx++;
} }
DBUG_ASSERT(i == altered_table->s->fields); DBUG_ASSERT(i == altered_table->s->stored_fields);
i = table->s->fields; i = table->s->stored_fields;
/* Add the InnoDB hidden FTS_DOC_ID column, if any. */ /* Add the InnoDB hidden FTS_DOC_ID column, if any. */
if (i + DATA_N_SYS_COLS < old_table->n_cols) { if (i + DATA_N_SYS_COLS < old_table->n_cols) {
...@@ -2405,17 +2433,17 @@ innobase_build_col_map( ...@@ -2405,17 +2433,17 @@ innobase_build_col_map(
DICT_TF2_FTS_HAS_DOC_ID)); DICT_TF2_FTS_HAS_DOC_ID));
DBUG_ASSERT(i + DATA_N_SYS_COLS + 1 == old_table->n_cols); DBUG_ASSERT(i + DATA_N_SYS_COLS + 1 == old_table->n_cols);
DBUG_ASSERT(!strcmp(dict_table_get_col_name( DBUG_ASSERT(!strcmp(dict_table_get_col_name(
old_table, table->s->fields), old_table, table->s->stored_fields),
FTS_DOC_ID_COL_NAME)); FTS_DOC_ID_COL_NAME));
if (altered_table->s->fields + DATA_N_SYS_COLS if (altered_table->s->stored_fields + DATA_N_SYS_COLS
< new_table->n_cols) { < new_table->n_cols) {
DBUG_ASSERT(DICT_TF2_FLAG_IS_SET( DBUG_ASSERT(DICT_TF2_FLAG_IS_SET(
new_table, new_table,
DICT_TF2_FTS_HAS_DOC_ID)); DICT_TF2_FTS_HAS_DOC_ID));
DBUG_ASSERT(altered_table->s->fields DBUG_ASSERT(altered_table->s->stored_fields
+ DATA_N_SYS_COLS + 1 + DATA_N_SYS_COLS + 1
== new_table->n_cols); == new_table->n_cols);
col_map[i] = altered_table->s->fields; col_map[i] = altered_table->s->stored_fields;
} else { } else {
DBUG_ASSERT(!DICT_TF2_FLAG_IS_SET( DBUG_ASSERT(!DICT_TF2_FLAG_IS_SET(
new_table, new_table,
...@@ -2533,6 +2561,7 @@ prepare_inplace_alter_table_dict( ...@@ -2533,6 +2561,7 @@ prepare_inplace_alter_table_dict(
const ulint* col_map = NULL; const ulint* col_map = NULL;
dtuple_t* add_cols = NULL; dtuple_t* add_cols = NULL;
ulint num_fts_index; ulint num_fts_index;
uint sql_idx;
DBUG_ENTER("prepare_inplace_alter_table_dict"); DBUG_ENTER("prepare_inplace_alter_table_dict");
DBUG_ASSERT((add_autoinc_col != ULINT_UNDEFINED) DBUG_ASSERT((add_autoinc_col != ULINT_UNDEFINED)
...@@ -2656,7 +2685,7 @@ prepare_inplace_alter_table_dict( ...@@ -2656,7 +2685,7 @@ prepare_inplace_alter_table_dict(
goto new_clustered_failed; goto new_clustered_failed;
} }
n_cols = altered_table->s->fields; n_cols = altered_table->s->stored_fields;
if (add_fts_doc_id) { if (add_fts_doc_id) {
n_cols++; n_cols++;
...@@ -2688,8 +2717,12 @@ prepare_inplace_alter_table_dict( ...@@ -2688,8 +2717,12 @@ prepare_inplace_alter_table_dict(
user_table->data_dir_path); user_table->data_dir_path);
} }
for (uint i = 0; i < altered_table->s->fields; i++) { sql_idx= 0;
const Field* field = altered_table->field[i]; for (uint i = 0; i < altered_table->s->stored_fields; i++, sql_idx++) {
const Field* field;
while (!((field= altered_table->field[sql_idx])->
stored_in_db))
sql_idx++;
ulint is_unsigned; ulint is_unsigned;
ulint field_type ulint field_type
= (ulint) field->type(); = (ulint) field->type();
...@@ -2766,7 +2799,7 @@ prepare_inplace_alter_table_dict( ...@@ -2766,7 +2799,7 @@ prepare_inplace_alter_table_dict(
if (add_fts_doc_id) { if (add_fts_doc_id) {
fts_add_doc_id_column(indexed_table, heap); fts_add_doc_id_column(indexed_table, heap);
indexed_table->fts->doc_col = fts_doc_id_col; indexed_table->fts->doc_col = fts_doc_id_col;
ut_ad(fts_doc_id_col == altered_table->s->fields); ut_ad(fts_doc_id_col == altered_table->s->stored_fields);
} else if (indexed_table->fts) { } else if (indexed_table->fts) {
indexed_table->fts->doc_col = fts_doc_id_col; indexed_table->fts->doc_col = fts_doc_id_col;
} }
...@@ -3674,7 +3707,7 @@ ha_innobase::prepare_inplace_alter_table( ...@@ -3674,7 +3707,7 @@ ha_innobase::prepare_inplace_alter_table(
if (!innobase_fts_check_doc_id_col( if (!innobase_fts_check_doc_id_col(
prebuilt->table, altered_table, &fts_doc_col_no)) { prebuilt->table, altered_table, &fts_doc_col_no)) {
fts_doc_col_no = altered_table->s->fields; fts_doc_col_no = altered_table->s->stored_fields;
add_fts_doc_id = true; add_fts_doc_id = true;
add_fts_doc_id_idx = true; add_fts_doc_id_idx = true;
...@@ -3708,15 +3741,22 @@ ha_innobase::prepare_inplace_alter_table( ...@@ -3708,15 +3741,22 @@ ha_innobase::prepare_inplace_alter_table(
} }
/* See if an AUTO_INCREMENT column was added. */ /* See if an AUTO_INCREMENT column was added. */
uint i = 0; uint i = 0, innodb_idx= 0;
List_iterator_fast<Create_field> cf_it( List_iterator_fast<Create_field> cf_it(
ha_alter_info->alter_info->create_list); ha_alter_info->alter_info->create_list);
while (const Create_field* new_field = cf_it++) { while (const Create_field* new_field = cf_it++) {
const Field* field; const Field* field;
if (!new_field->stored_in_db) {
i++;
continue;
}
DBUG_ASSERT(i < altered_table->s->fields); DBUG_ASSERT(i < altered_table->s->fields);
DBUG_ASSERT(innodb_idx < altered_table->s->stored_fields);
for (uint old_i = 0; table->field[old_i]; old_i++) { for (uint old_i = 0; table->field[old_i]; old_i++) {
if (!table->field[old_i]->stored_in_db)
continue;
if (new_field->field == table->field[old_i]) { if (new_field->field == table->field[old_i]) {
goto found_col; goto found_col;
} }
...@@ -3740,13 +3780,14 @@ ha_innobase::prepare_inplace_alter_table( ...@@ -3740,13 +3780,14 @@ ha_innobase::prepare_inplace_alter_table(
my_error(ER_WRONG_AUTO_KEY, MYF(0)); my_error(ER_WRONG_AUTO_KEY, MYF(0));
goto err_exit; goto err_exit;
} }
add_autoinc_col_no = i; add_autoinc_col_no = innodb_idx;
autoinc_col_max_value = innobase_get_int_col_max_value( autoinc_col_max_value = innobase_get_int_col_max_value(
field); field);
} }
found_col: found_col:
i++; i++;
innodb_idx++;
} }
DBUG_ASSERT(user_thd == prebuilt->trx->mysql_thd); DBUG_ASSERT(user_thd == prebuilt->trx->mysql_thd);
...@@ -4369,7 +4410,7 @@ innobase_rename_columns( ...@@ -4369,7 +4410,7 @@ innobase_rename_columns(
uint i = 0; uint i = 0;
for (Field** fp = table->field; *fp; fp++, i++) { for (Field** fp = table->field; *fp; fp++, i++) {
if (!((*fp)->flags & FIELD_IS_RENAMED)) { if (!((*fp)->flags & FIELD_IS_RENAMED) || !((*fp)->stored_in_db)) {
continue; continue;
} }
......
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