@@ -7211,8 +7211,9 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields(
72117211{
72127212 if (!(options & HA_VERSIONED_TABLE))
72137213 return false ;
7214- return vers_info.check_sys_fields (create_table.table_name , create_table.db ,
7215- alter_info);
7214+ return vers_info.check_sys_fields (
7215+ create_table.table_name , create_table.db , alter_info,
7216+ ha_check_storage_engine_flag (db_type, HTON_NATIVE_SYS_VERSIONING));
72167217}
72177218
72187219
@@ -7321,7 +7322,11 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info,
73217322
73227323 if (alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING)
73237324 {
7324- if (check_sys_fields (table_name, share->db , alter_info))
7325+ const bool can_native=
7326+ ha_check_storage_engine_flag (create_info->db_type ,
7327+ HTON_NATIVE_SYS_VERSIONING) ||
7328+ create_info->db_type ->db_type == DB_TYPE_PARTITION_DB;
7329+ if (check_sys_fields (table_name, share->db , alter_info, can_native))
73257330 return true ;
73267331 }
73277332
@@ -7426,78 +7431,83 @@ bool Vers_parse_info::check_conditions(const Lex_table_name &table_name,
74267431 return false ;
74277432}
74287433
7434+ static bool is_versioning_timestamp (const Create_field *f)
7435+ {
7436+ return (f->type_handler () == &type_handler_datetime2 ||
7437+ f->type_handler () == &type_handler_timestamp2) &&
7438+ f->length == MAX_DATETIME_FULL_WIDTH;
7439+ }
7440+
7441+ static bool is_some_bigint (const Create_field *f)
7442+ {
7443+ return f->type_handler () == &type_handler_longlong ||
7444+ f->type_handler () == &type_handler_vers_trx_id;
7445+ }
7446+
7447+ static bool is_versioning_bigint (const Create_field *f)
7448+ {
7449+ return is_some_bigint (f) && f->flags & UNSIGNED_FLAG &&
7450+ f->length == MY_INT64_NUM_DECIMAL_DIGITS - 1 ;
7451+ }
7452+
7453+ static bool require_timestamp (const Create_field *f, Lex_table_name table_name)
7454+ {
7455+ my_error (ER_VERS_FIELD_WRONG_TYPE, MYF (0 ), f->field_name .str , " TIMESTAMP(6)" ,
7456+ table_name.str );
7457+ return true ;
7458+ }
7459+ static bool require_bigint (const Create_field *f, Lex_table_name table_name)
7460+ {
7461+ my_error (ER_VERS_FIELD_WRONG_TYPE, MYF (0 ), f->field_name .str ,
7462+ " BIGINT(20) UNSIGNED" , table_name.str );
7463+ return true ;
7464+ }
7465+
74297466bool Vers_parse_info::check_sys_fields (const Lex_table_name &table_name,
74307467 const Lex_table_name &db,
7431- Alter_info *alter_info)
7468+ Alter_info *alter_info, bool can_native )
74327469{
74337470 if (check_conditions (table_name, db))
74347471 return true ;
74357472
7473+ const Create_field *row_start= NULL ;
7474+ const Create_field *row_end= NULL ;
7475+
74367476 List_iterator<Create_field> it (alter_info->create_list );
7437- uint found_flag= 0 ;
74387477 while (Create_field *f= it++)
74397478 {
7440- vers_sys_type_t f_check_unit= VERS_UNDEFINED;
7441- uint sys_flag= f->flags & VERS_SYSTEM_FIELD;
7479+ if (!row_start && f->flags & VERS_SYS_START_FLAG)
7480+ row_start= f;
7481+ else if (!row_end && f->flags & VERS_SYS_END_FLAG)
7482+ row_end= f;
7483+ }
74427484
7443- if (!sys_flag)
7444- continue ;
7485+ const bool expect_timestamp=
7486+ !can_native || ! is_some_bigint (row_start) || ! is_some_bigint (row_end) ;
74457487
7446- if (sys_flag & found_flag)
7447- {
7448- my_error (ER_VERS_DUPLICATE_ROW_START_END, MYF (0 ),
7449- found_flag & VERS_SYS_START_FLAG ? " START" : " END" ,
7450- f->field_name .str );
7451- return true ;
7452- }
7488+ if (expect_timestamp)
7489+ {
7490+ if (!is_versioning_timestamp (row_start))
7491+ return require_timestamp (row_start, table_name);
74537492
7454- sys_flag|= found_flag;
7493+ if (!is_versioning_timestamp (row_end))
7494+ return require_timestamp (row_end, table_name);
7495+ }
7496+ else
7497+ {
7498+ if (!is_versioning_bigint (row_start))
7499+ return require_bigint (row_start, table_name);
74557500
7456- if ((f->type_handler () == &type_handler_datetime2 ||
7457- f->type_handler () == &type_handler_timestamp2) &&
7458- f->length == MAX_DATETIME_FULL_WIDTH)
7459- {
7460- f_check_unit= VERS_TIMESTAMP;
7461- }
7462- else if (f->type_handler () == &type_handler_longlong
7463- && (f->flags & UNSIGNED_FLAG)
7464- && f->length == (MY_INT64_NUM_DECIMAL_DIGITS - 1 ))
7465- {
7466- f_check_unit= VERS_TRX_ID;
7467- }
7468- else
7469- {
7470- if (!check_unit)
7471- check_unit= VERS_TIMESTAMP;
7472- goto error;
7473- }
7501+ if (!is_versioning_bigint (row_end))
7502+ return require_bigint (row_end, table_name);
7503+ }
74747504
7475- if (f_check_unit)
7476- {
7477- if (check_unit)
7478- {
7479- if (check_unit == f_check_unit)
7480- {
7481- if (check_unit == VERS_TRX_ID && !TR_table::use_transaction_registry)
7482- {
7483- my_error (ER_VERS_TRT_IS_DISABLED, MYF (0 ));
7484- return true ;
7485- }
7486- return false ;
7487- }
7488- error:
7489- my_error (ER_VERS_FIELD_WRONG_TYPE, MYF (0 ), f->field_name .str ,
7490- check_unit == VERS_TIMESTAMP ?
7491- " TIMESTAMP(6)" :
7492- " BIGINT(20) UNSIGNED" ,
7493- table_name.str );
7494- return true ;
7495- }
7496- check_unit= f_check_unit;
7497- }
7505+ if (is_versioning_bigint (row_start) && is_versioning_bigint (row_end) &&
7506+ !TR_table::use_transaction_registry)
7507+ {
7508+ my_error (ER_VERS_TRT_IS_DISABLED, MYF (0 ));
7509+ return true ;
74987510 }
74997511
7500- my_error (ER_MISSING, MYF (0 ), table_name.str , found_flag & VERS_SYS_START_FLAG ?
7501- " ROW END" : found_flag ? " ROW START" : " ROW START/END" );
7502- return true ;
7512+ return false ;
75037513}
0 commit comments