@@ -1255,6 +1255,9 @@ convert_error_code_to_mysql(
12551255 case DB_PRIMARY_KEY_IS_NULL:
12561256 return (ER_PRIMARY_CANT_HAVE_NULL);
12571257
1258+ case DB_FTS_INVALID_DOCID:
1259+ return (HA_FTS_INVALID_DOCID);
1260+
12581261 case DB_TOO_MANY_CONCURRENT_TRXS:
12591262 /* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
12601263 available in 5.1.38 and later, but the plugin should still
@@ -1372,6 +1375,16 @@ innobase_strcasecmp(
13721375 const char * a, /* !< in: first string to compare */
13731376 const char * b) /* !< in: second string to compare */
13741377{
1378+ if (!a) {
1379+ if (!b) {
1380+ return (0 );
1381+ } else {
1382+ return (-1 );
1383+ }
1384+ } else if (!b) {
1385+ return (1 );
1386+ }
1387+
13751388 return (my_strcasecmp (system_charset_info, a, b));
13761389}
13771390
@@ -5944,6 +5957,10 @@ ha_innobase::write_row(
59445957 prebuilt->table ->flags ,
59455958 user_thd);
59465959
5960+ if (error_result == HA_FTS_INVALID_DOCID) {
5961+ my_error (HA_FTS_INVALID_DOCID, MYF (0 ));
5962+ }
5963+
59475964func_exit:
59485965 innobase_active_small ();
59495966
@@ -5987,7 +6004,9 @@ calc_row_difference(
59876004 uint i;
59886005 ulint error = DB_SUCCESS;
59896006 ibool changes_fts_column = FALSE ;
6007+ ibool changes_fts_doc_col = FALSE ;
59906008 trx_t * trx = thd_to_trx (thd);
6009+ doc_id_t doc_id = 0 ;
59916010
59926011 n_fields = table->s ->fields ;
59936012 clust_index = dict_table_get_first_index (prebuilt->table );
@@ -6048,6 +6067,18 @@ calc_row_difference(
60486067 ;
60496068 }
60506069
6070+ if (field_mysql_type == MYSQL_TYPE_LONGLONG
6071+ && prebuilt->table ->fts
6072+ && innobase_strcasecmp (
6073+ field->field_name , FTS_DOC_ID_COL_NAME) == 0 ) {
6074+ doc_id = (doc_id_t ) mach_read_from_n_little_endian (
6075+ n_ptr, 8 );
6076+ if (doc_id == 0 ) {
6077+ return (DB_FTS_INVALID_DOCID);
6078+ }
6079+ }
6080+
6081+
60516082 if (field->null_ptr ) {
60526083 if (field_in_record_is_null (table, field,
60536084 (char *) old_row)) {
@@ -6100,19 +6131,25 @@ calc_row_difference(
61006131 checking only once here. Later we will need to
61016132 note which columns have been updated and do
61026133 selective processing. */
6103- if (prebuilt->table ->fts != NULL
6104- && !changes_fts_column) {
6105-
6134+ if (prebuilt->table ->fts != NULL ) {
61066135 ulint offset;
61076136 dict_table_t * innodb_table;
61086137
61096138 innodb_table = prebuilt->table ;
61106139
6111- offset = row_upd_changes_fts_column (
6112- innodb_table, ufield);
6140+ if (!changes_fts_column) {
6141+ offset = row_upd_changes_fts_column (
6142+ innodb_table, ufield);
61136143
6114- if (offset != ULINT_UNDEFINED) {
6115- changes_fts_column = TRUE ;
6144+ if (offset != ULINT_UNDEFINED) {
6145+ changes_fts_column = TRUE ;
6146+ }
6147+ }
6148+
6149+ if (!changes_fts_doc_col) {
6150+ changes_fts_doc_col =
6151+ row_upd_changes_doc_id (
6152+ innodb_table, ufield);
61166153 }
61176154 }
61186155 }
@@ -6122,11 +6159,19 @@ calc_row_difference(
61226159 then add an update column node with a new document id to the
61236160 other changes. We piggy back our changes on the normal UPDATE
61246161 to reduce processing and IO overhead. */
6125- if (prebuilt->table ->fts != NULL && changes_fts_column) {
6162+ if (prebuilt->table ->fts != NULL
6163+ && (changes_fts_column || changes_fts_doc_col)) {
61266164 dict_table_t * innodb_table = prebuilt->table ;
61276165
61286166 ufield = uvect->fields + n_changed;
61296167
6168+ if (!DICT_TF2_FLAG_IS_SET (
6169+ innodb_table, DICT_TF2_FTS_HAS_DOC_ID)) {
6170+ trx->fts_next_doc_id = doc_id;
6171+ } else {
6172+ trx->fts_next_doc_id = 0 ;
6173+ }
6174+
61306175 error = fts_update_doc_id (
61316176 innodb_table, ufield, &trx->fts_next_doc_id );
61326177
@@ -6186,10 +6231,14 @@ ha_innobase::update_row(
61866231 /* Build an update vector from the modified fields in the rows
61876232 (uses upd_buff of the handle) */
61886233
6189- calc_row_difference (uvect, (uchar*) old_row, new_row, table,
6234+ error = calc_row_difference (uvect, (uchar*) old_row, new_row, table,
61906235 upd_buff, (ulint)upd_and_key_val_buff_len,
61916236 prebuilt, user_thd);
61926237
6238+ if (error != DB_SUCCESS) {
6239+ goto func_exit;
6240+ }
6241+
61936242 /* This is not a delete */
61946243 prebuilt->upd_node ->is_delete = FALSE ;
61956244
@@ -6241,6 +6290,7 @@ ha_innobase::update_row(
62416290
62426291 innodb_srv_conc_exit_innodb (trx);
62436292
6293+ func_exit:
62446294 error = convert_error_code_to_mysql (error,
62456295 prebuilt->table ->flags , user_thd);
62466296
@@ -6252,6 +6302,8 @@ ha_innobase::update_row(
62526302 should not increase the count of updated rows.
62536303 This is fix for http://bugs.mysql.com/29157 */
62546304 error = HA_ERR_RECORD_IS_THE_SAME;
6305+ } else if (error == HA_FTS_INVALID_DOCID) {
6306+ my_error (HA_FTS_INVALID_DOCID, MYF (0 ));
62556307 }
62566308
62576309 /* Tell InnoDB server that there might be work for
@@ -9258,9 +9310,10 @@ ha_innobase::info_low(
92589310 - prebuilt->clust_index_was_generated ;
92599311
92609312 if (table->s ->keys != num_innodb_index
9261- && (innobase_fts_check_doc_id_index (ib_table, NULL )
9313+ && (innobase_fts_check_doc_id_index (ib_table, NULL )
9314+ == FTS_EXIST_DOC_ID_INDEX
92629315 && table->s ->keys != (num_innodb_index - 1 ))) {
9263- sql_print_error (" Table %s contains %lu "
9316+ sql_print_error (" InnoDB: Table %s contains %lu "
92649317 " indexes inside InnoDB, which "
92659318 " is different from the number of "
92669319 " indexes %u defined in the MySQL " ,
0 commit comments