Skip to content

Commit

Permalink
[CP] Change legitimacy error code for functional index
Browse files Browse the repository at this point in the history
  • Loading branch information
2149 authored and ob-robot committed Aug 11, 2023
1 parent 3059651 commit 0a266c8
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 4 deletions.
15 changes: 14 additions & 1 deletion src/share/ob_errno.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/share/ob_errno.def
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,7 @@ DEFINE_ORACLE_ERROR(OB_ERR_TABLE_NAME_NOT_IN_LIST, -5490, -1, "42000", "table na
DEFINE_ORACLE_ERROR(OB_ERR_DEFAULT_NOT_AT_LAST_IN_LIST_PART, -5491, -1, "42000", "DEFAULT partition must be last partition specified", 14318, "DEFAULT partition must be last partition specified");
DEFINE_ERROR_EXT(OB_ERR_MYSQL_CHARACTER_SET_MISMATCH, -5492, ER_CHARACTER_SET_MISMATCH, "HY000", "Character set cannot be used in conjunction with binary collations in function call", "Character set '%.*s' cannot be used in conjunction with '%.*s' in regexp function call.");

DEFINE_ERROR(OB_ERR_GENCOL_LEGIT_CHECK_FAILED, -5500, -1, "HY000", "Legitimacy check failed for generated columns.");

DEFINE_ERROR_EXT(OB_ERR_SP_ALREADY_EXISTS, -5541, ER_SP_ALREADY_EXISTS, "42000", "procedure/function already exists", "%s %.*s already exists");
DEFINE_ERROR_EXT(OB_ERR_SP_DOES_NOT_EXIST, -5542, ER_SP_DOES_NOT_EXIST, "42000", "procedure/function does not exist", "%s %.*s.%.*s does not exist");
Expand Down
7 changes: 5 additions & 2 deletions src/share/ob_errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ constexpr int OB_ERR_SCHEMA_HISTORY_EMPTY = -5489;
constexpr int OB_ERR_TABLE_NAME_NOT_IN_LIST = -5490;
constexpr int OB_ERR_DEFAULT_NOT_AT_LAST_IN_LIST_PART = -5491;
constexpr int OB_ERR_MYSQL_CHARACTER_SET_MISMATCH = -5492;
constexpr int OB_ERR_GENCOL_LEGIT_CHECK_FAILED = -5500;
constexpr int OB_ERR_SP_ALREADY_EXISTS = -5541;
constexpr int OB_ERR_SP_DOES_NOT_EXIST = -5542;
constexpr int OB_ERR_SP_UNDECLARED_VAR = -5543;
Expand Down Expand Up @@ -2719,6 +2720,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ERR_TABLE_NAME_NOT_IN_LIST__USER_ERROR_MSG "table name not in FROM list"
#define OB_ERR_DEFAULT_NOT_AT_LAST_IN_LIST_PART__USER_ERROR_MSG "DEFAULT partition must be last partition specified"
#define OB_ERR_MYSQL_CHARACTER_SET_MISMATCH__USER_ERROR_MSG "Character set '%.*s' cannot be used in conjunction with '%.*s' in regexp function call."
#define OB_ERR_GENCOL_LEGIT_CHECK_FAILED__USER_ERROR_MSG "Legitimacy check failed for generated columns."
#define OB_ERR_SP_ALREADY_EXISTS__USER_ERROR_MSG "%s %.*s already exists"
#define OB_ERR_SP_DOES_NOT_EXIST__USER_ERROR_MSG "%s %.*s.%.*s does not exist"
#define OB_ERR_SP_UNDECLARED_VAR__USER_ERROR_MSG "Undeclared variable: %.*s"
Expand Down Expand Up @@ -4125,7 +4127,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ENCODING_EST_SIZE_OVERFLOW__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4397, Encoding estimated size overflow"
#define OB_INVALID_SUB_PARTITION_TYPE__ORA_USER_ERROR_MSG "ORA-14020: this physical attribute may not be specified for a table partition"
#define OB_ERR_UNEXPECTED_UNIT_STATUS__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4399, Unit status is not expected"
#define OB_OB_AUTOINC_CACHE_NOT_EQUAL__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4400, Autoinc cache's autoinc version is not equal to request's autoinc version"
#define OB_AUTOINC_CACHE_NOT_EQUAL__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4400, Autoinc cache's autoinc version is not equal to request's autoinc version"
#define OB_IMPORT_NOT_IN_SERVER__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4505, Import not in service"
#define OB_CONVERT_ERROR__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4507, Convert error"
#define OB_BYPASS_TIMEOUT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4510, Bypass timeout"
Expand Down Expand Up @@ -4768,6 +4770,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ERR_TABLE_NAME_NOT_IN_LIST__ORA_USER_ERROR_MSG "ORA-00964: table name not in FROM list"
#define OB_ERR_DEFAULT_NOT_AT_LAST_IN_LIST_PART__ORA_USER_ERROR_MSG "ORA-14318: DEFAULT partition must be last partition specified"
#define OB_ERR_MYSQL_CHARACTER_SET_MISMATCH__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5492, Character set '%.*s' cannot be used in conjunction with '%.*s' in regexp function call."
#define OB_ERR_GENCOL_LEGIT_CHECK_FAILED__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5500, Legitimacy check failed for generated columns."
#define OB_ERR_SP_ALREADY_EXISTS__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5541, %s %.*s already exists"
#define OB_ERR_SP_DOES_NOT_EXIST__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5542, %s %.*s.%.*s does not exist"
#define OB_ERR_SP_UNDECLARED_VAR__ORA_USER_ERROR_MSG "PLS-00201: identifier '%.*s' must be declared"
Expand Down Expand Up @@ -5813,7 +5816,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ERR_DATA_TOO_LONG_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-12899: value too large for column %.*s (actual: %ld, maximum: %ld)"
#define OB_ERR_INVALID_DATE_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-01861: Incorrect datetime value for column '%.*s' at row %ld"

extern int g_all_ob_errnos[2045];
extern int g_all_ob_errnos[2046];

const char *ob_error_name(const int oberr);
const char* ob_error_cause(const int oberr);
Expand Down
74 changes: 73 additions & 1 deletion src/storage/ls/ob_ls_tablet_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3652,6 +3652,7 @@ int ObLSTabletService::check_old_row_legitimacy(
ObDatumRowkey datum_rowkey;
ObDatumRowkeyHelper rowkey_helper;
const ObIArray<uint64_t> &column_ids = *run_ctx.column_ids_;
uint64_t err_col_id = OB_INVALID_ID;
if (OB_FAIL(rowkey_helper.convert_datum_rowkey(rowkey.get_rowkey(), datum_rowkey))) {
STORAGE_LOG(WARN, "Failed to transfer datum rowkey", K(ret), K(rowkey));
} else if (OB_FAIL(init_single_row_getter(old_row_getter, run_ctx, column_ids, data_table, true))) {
Expand Down Expand Up @@ -3685,6 +3686,7 @@ int ObLSTabletService::check_old_row_legitimacy(
if (OB_FAIL(data_table.is_nop_default_value(column_ids.at(i), is_nop))) {
LOG_WARN("check column whether has nop default value failed", K(ret), K(column_ids.at(i)));
} else if (!is_nop) {
err_col_id = column_ids.at(i);
ret = OB_ERR_DEFENSIVE_CHECK;
LOG_WARN("storage old row is not matched with sql old row", K(ret),
K(i), K(column_ids.at(i)), K(storage_val), K(sql_val));
Expand All @@ -3693,6 +3695,7 @@ int ObLSTabletService::check_old_row_legitimacy(
//this column is nop val, means that this column does not be touched by DML
//just ignore it
} else if (OB_FAIL(storage_val.compare(sql_val, cmp)) || 0 != cmp) {
err_col_id = column_ids.at(i);
LOG_WARN("storage_val is not equal with sql_val, maybe catch a bug", K(ret),
K(storage_val), K(sql_val), K(cmp), K(column_ids.at(i)));
ret = OB_ERR_DEFENSIVE_CHECK;
Expand All @@ -3712,13 +3715,21 @@ int ObLSTabletService::check_old_row_legitimacy(
}
if (OB_ERR_DEFENSIVE_CHECK == ret) {
int tmp_ret = OB_SUCCESS;
bool is_virtual_gen_col = false;
if (is_udf) {
ret = OB_ERR_INDEX_KEY_NOT_FOUND;
LOG_WARN("index key not found on udf column", K(ret), K(old_row));
} else if (OB_TMP_FAIL(check_real_leader_for_4377_(run_ctx.store_ctx_.ls_id_))) {
ret = tmp_ret;
LOG_WARN("check real leader for 4377 found exception", K(ret), K(old_row), K(data_table));
} else {
} else if (data_table.is_index_table() && OB_TMP_FAIL(check_is_gencol_check_failed(data_table, err_col_id, is_virtual_gen_col))) {
//don't change ret if gencol check failed
LOG_WARN("check is functional index failed", K(ret), K(tmp_ret), K(data_table));
} else if (is_virtual_gen_col) {
ret = OB_ERR_GENCOL_LEGIT_CHECK_FAILED;
LOG_WARN("Legitimacy check failed for functional index.", K(ret), K(old_row), KPC(storage_old_row));
}
if (OB_ERR_DEFENSIVE_CHECK == ret) {
ObString func_name = ObString::make_string("check_old_row_legitimacy");
LOG_USER_ERROR(OB_ERR_DEFENSIVE_CHECK, func_name.length(), func_name.ptr());
LOG_DBA_ERROR(OB_ERR_DEFENSIVE_CHECK, "msg", "Fatal Error!!! Catch a defensive error!", K(ret),
Expand All @@ -3737,6 +3748,67 @@ int ObLSTabletService::check_old_row_legitimacy(
return ret;
}

int ObLSTabletService::check_is_gencol_check_failed(const ObRelativeTable &data_table, uint64_t error_col_id, bool &is_virtual_gen_col)
{
int ret = OB_SUCCESS;
is_virtual_gen_col = false;
if (data_table.is_index_table()) {
const ObColumnParam *param = nullptr;
const uint64_t tenant_id = MTL_ID();
uint64_t index_table_id = data_table.get_table_id();
const ObTableSchema *index_table_schema = NULL;
const ObTableSchema *data_table_schema = NULL;
ObMultiVersionSchemaService *schema_service = MTL(ObTenantSchemaService*)->get_schema_service();
ObSchemaGetterGuard schema_guard;
if (OB_ISNULL(schema_service)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), KP(schema_service));
} else if (OB_FAIL(schema_service->get_tenant_schema_guard(tenant_id, schema_guard))) {
LOG_WARN("failed to get schema manager", K(ret), K(tenant_id));
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, index_table_id, index_table_schema))) {
LOG_WARN("get index table schema failed", K(ret));
} else if (OB_ISNULL(index_table_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("index table schema is unexpected null", K(ret));
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, index_table_schema->get_data_table_id(), data_table_schema))) {
LOG_WARN("get data table schema failed", K(ret));
} else if (OB_ISNULL(data_table_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("data table schema is unexpected null", K(ret));
} else if (OB_INVALID_ID != error_col_id) {
//check specified column
const ObColumnSchemaV2 *column = NULL;
if (is_shadow_column(error_col_id)) {
//shadow column does not exists in basic table, do nothing
} else if (OB_ISNULL(column = data_table_schema->get_column_schema(error_col_id))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), KP(column));
} else if (column->is_virtual_generated_column()) {
is_virtual_gen_col = true;
}
} else {
//check all columns
for (ObTableSchema::const_column_iterator iter = index_table_schema->column_begin();
OB_SUCC(ret) && iter != index_table_schema->column_end() && !is_virtual_gen_col; iter++) {
const ObColumnSchemaV2 *column = *iter;
//the column id in the data table is the same with that in the index table
if (OB_ISNULL(column)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), KP(column));
} else if (is_shadow_column(column->get_column_id())) {
//shadow column does not exists in basic table, do nothing
} else if (OB_ISNULL(column = data_table_schema->get_column_schema(column->get_column_id()))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), KP(column));
} else if (column->is_virtual_generated_column()) {
is_virtual_gen_col = true;
}
}
}
}
return ret;
}

int ObLSTabletService::check_new_row_legitimacy(
ObDMLRunningCtx &run_ctx,
const common::ObNewRow &new_row)
Expand Down
3 changes: 3 additions & 0 deletions src/storage/ls/ob_ls_tablet_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,9 @@ class ObLSTabletService : public logservice::ObIReplaySubHandler,
const bool is_heap_table,
common::ObNewRowIterator *row_iter,
int64_t &affected_rows);
static int check_is_gencol_check_failed(const ObRelativeTable &data_table,
uint64_t error_col_id,
bool &is_virtual_gencol);

private:
friend class ObLSTabletIterator;
Expand Down

0 comments on commit 0a266c8

Please sign in to comment.