Forbid creating local unique index without covering all partition columns
This commit is contained in:
parent
5efdb4800d
commit
198891e5ba
@ -14096,18 +14096,6 @@ int ObDDLService::gen_hidden_index_schema_columns(const ObTableSchema &orig_inde
|
||||
if (OB_FAIL(sql::ObResolverUtils::check_unique_index_cover_partition_column(
|
||||
new_table_schema, create_index_arg))) {
|
||||
LOG_WARN("fail to check unique key cover partition column", K(ret));
|
||||
if (INDEX_TYPE_UNIQUE_LOCAL == create_index_arg.index_type_ &&
|
||||
OB_EER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF == ret) {
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
bool allow = false;
|
||||
if (OB_SUCCESS != (tmp_ret = ObDDLResolver::check_uniq_allow(
|
||||
new_table_schema, create_index_arg, allow))) {
|
||||
LOG_WARN("fail to check uniq allow", K(ret));
|
||||
} else if (allow) {
|
||||
LOG_INFO("uniq index allowd, deduced by constraint", K(ret));
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -649,18 +649,6 @@ int ObIndexBuilder::generate_schema(
|
||||
if (OB_FAIL(sql::ObResolverUtils::check_unique_index_cover_partition_column(
|
||||
data_schema, arg))) {
|
||||
RS_LOG(WARN, "fail to check unique key cover partition column", K(ret));
|
||||
if (INDEX_TYPE_UNIQUE_LOCAL == arg.index_type_ &&
|
||||
OB_EER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF == ret) {
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
bool allow = false;
|
||||
if (OB_SUCCESS != (tmp_ret = ObDDLResolver::check_uniq_allow(data_schema,
|
||||
arg, allow))) {
|
||||
RS_LOG(WARN, "fail to check uniq allow", K(ret));
|
||||
} else if (allow) {
|
||||
RS_LOG(INFO, "uniq index allowd, deduced by constraint", K(ret));
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int64_t index_data_length = 0;
|
||||
|
@ -7123,271 +7123,6 @@ int ObDDLResolver::set_index_tablespace(const ObTableSchema &table_schema,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLResolver::check_uniq_allow(ObResolverParams ¶ms,
|
||||
ObTableSchema &table_schema,
|
||||
const ObCreateIndexArg &index_arg,
|
||||
ObRawExpr *part_func_expr,
|
||||
ObIArray<ObRawExpr *> &constraint_exprs,
|
||||
bool &allow)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
allow = false;
|
||||
|
||||
ObColumnRefRawExpr *part_col_expr = NULL;
|
||||
if (!part_func_expr->is_column_ref_expr()) {
|
||||
allow = false;
|
||||
} else if (FALSE_IT(part_col_expr = static_cast<ObColumnRefRawExpr *>(part_func_expr))) {
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < index_arg.index_columns_.count() && !allow; ++i) {
|
||||
const ObString &index_col_name = index_arg.index_columns_.at(i).column_name_;
|
||||
const ObString &part_col_name = part_col_expr->get_column_name();
|
||||
if (ObCharset::case_insensitive_equal(index_col_name, part_col_name)) {
|
||||
allow = true;
|
||||
} else {
|
||||
// concern as base-column
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < constraint_exprs.count() && !allow; ++j) {
|
||||
ObOpRawExpr *check_expr = static_cast<ObOpRawExpr *>(constraint_exprs.at(j));
|
||||
ObRawExpr *child_exprs[2] = {check_expr->get_param_expr(0), check_expr->get_param_expr(1)};
|
||||
for (int64_t k = 0; OB_SUCC(ret) && k < 2 && !allow; ++k) {
|
||||
if (child_exprs[k]->is_column_ref_expr()) {
|
||||
ObColumnRefRawExpr *col_expr = static_cast<ObColumnRefRawExpr*>(child_exprs[k]);
|
||||
if (ObCharset::case_insensitive_equal(part_col_name,
|
||||
col_expr->get_column_name())) {
|
||||
ObColumnRefRawExpr *cmp_col_expr = NULL;
|
||||
if (!child_exprs[1 - k]->is_column_ref_expr()) {
|
||||
cmp_col_expr = static_cast<ObColumnRefRawExpr*>(child_exprs[1 - k]->get_param_expr(0));
|
||||
} else {
|
||||
cmp_col_expr = static_cast<ObColumnRefRawExpr*>(child_exprs[1 - k]);
|
||||
}
|
||||
if (ObCharset::case_insensitive_equal(cmp_col_expr->get_column_name(), index_col_name)) {
|
||||
allow = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check gen column
|
||||
if (OB_SUCC(ret) && !allow) {
|
||||
ObColumnSchemaV2 *column_schema = NULL;
|
||||
if (OB_ISNULL(column_schema = table_schema.get_column_schema(part_col_expr->get_column_id()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Failed to get column schema", K(ret), K(part_col_expr->get_column_id()));
|
||||
} else if (column_schema->is_generated_column()) {
|
||||
ObString col_def;
|
||||
ObRawExpr *gen_expr = NULL;
|
||||
if (OB_FAIL(column_schema->get_orig_default_value().get_string(col_def))) {
|
||||
LOG_WARN("get generated column definition failed", K(ret));
|
||||
} else if (OB_FAIL(ObResolverUtils::resolve_generated_column_expr(params, col_def, table_schema,
|
||||
*column_schema, gen_expr))) {
|
||||
LOG_WARN("resolve generated column expr failed", K(ret));
|
||||
} else {
|
||||
ObString depend_part_col_name;
|
||||
bool is_expect = true;
|
||||
// check is substring or not
|
||||
if (OB_ISNULL(gen_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("NULL ptr", K(ret));
|
||||
} else if (T_FUN_SYS_SUBSTR != gen_expr->get_expr_type()) {
|
||||
is_expect = false;
|
||||
} else {
|
||||
ObSysFunRawExpr *sys_expr = static_cast<ObSysFunRawExpr *>(gen_expr);
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < sys_expr->get_param_count(); j++) {
|
||||
ObRawExpr *param_expr = sys_expr->get_param_expr(j);
|
||||
if (OB_ISNULL(param_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("NULL ptr", K(ret), K(param_expr));
|
||||
} else if (0 == j && !param_expr->is_column_ref_expr()) {
|
||||
is_expect = false;
|
||||
} else if (0 != j && !param_expr->is_const_raw_expr()) {
|
||||
is_expect = false;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && is_expect) {
|
||||
depend_part_col_name =
|
||||
static_cast<ObColumnRefRawExpr *>(sys_expr->get_param_expr(0))->get_column_name();
|
||||
}
|
||||
if (OB_SUCC(ret) && !is_expect) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < constraint_exprs.count() && !allow; ++j) {
|
||||
ObOpRawExpr *check_expr = static_cast<ObOpRawExpr *>(constraint_exprs.at(j));
|
||||
ObRawExpr *child_exprs[2] = {check_expr->get_param_expr(0), check_expr->get_param_expr(1)};
|
||||
ObColumnRefRawExpr *col_exprs[2] = {NULL, NULL};
|
||||
bool gen_expr_exist = false;
|
||||
bool all_col = true;
|
||||
for (int64_t k = 0; OB_SUCC(ret) && k < 2; ++k) {
|
||||
if (child_exprs[k]->is_column_ref_expr()) {
|
||||
col_exprs[k] = static_cast<ObColumnRefRawExpr*>(child_exprs[k]);
|
||||
} else {
|
||||
all_col = false;
|
||||
col_exprs[k] = static_cast<ObColumnRefRawExpr*>(child_exprs[k]->get_param_expr(0));
|
||||
if (!gen_expr_exist) {
|
||||
ret = check_same_substr_expr(*child_exprs[k], *gen_expr, gen_expr_exist);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (all_col || gen_expr_exist) {
|
||||
if (ObCharset::case_insensitive_equal(col_exprs[0]->get_column_name(),
|
||||
index_col_name) &&
|
||||
ObCharset::case_insensitive_equal(col_exprs[1]->get_column_name(),
|
||||
depend_part_col_name)) {
|
||||
allow = true;
|
||||
} else if (ObCharset::case_insensitive_equal(col_exprs[1]->get_column_name(),
|
||||
index_col_name) &&
|
||||
ObCharset::case_insensitive_equal(col_exprs[0]->get_column_name(),
|
||||
depend_part_col_name)) {
|
||||
allow = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLResolver::check_same_substr_expr(ObRawExpr &left, ObRawExpr &right, bool &same)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
same = true;
|
||||
|
||||
if (left.get_expr_type() != T_FUN_SYS_SUBSTR ||
|
||||
right.get_expr_type() != T_FUN_SYS_SUBSTR) {
|
||||
same = false;
|
||||
} else {
|
||||
ObSysFunRawExpr &sys_left = static_cast<ObSysFunRawExpr &>(left);
|
||||
ObSysFunRawExpr &sys_right = static_cast<ObSysFunRawExpr &>(right);
|
||||
if (sys_left.get_param_count() != sys_right.get_param_count()) {
|
||||
same = false;
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < sys_left.get_param_count() && same; ++i) {
|
||||
ObRawExpr *param_left = sys_left.get_param_expr(i);
|
||||
ObRawExpr *param_right = sys_right.get_param_expr(i);
|
||||
if (0 == i) {
|
||||
if (!param_left->is_column_ref_expr() ||
|
||||
!param_right->is_column_ref_expr()) {
|
||||
same = false;
|
||||
} else {
|
||||
ObColumnRefRawExpr *col_left = static_cast<ObColumnRefRawExpr *>(param_left);
|
||||
ObColumnRefRawExpr *col_right = static_cast<ObColumnRefRawExpr *>(param_right);
|
||||
if (!ObCharset::case_insensitive_equal(col_left->get_column_name(),
|
||||
col_right->get_column_name())) {
|
||||
same = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!param_left->is_const_raw_expr() ||
|
||||
!param_right->is_const_raw_expr()) {
|
||||
same = false;
|
||||
} else if (!param_left->same_as(*param_right)) {
|
||||
same = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLResolver::check_uniq_allow(ObTableSchema &table_schema,
|
||||
const ObCreateIndexArg &index_arg,
|
||||
bool &allow)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
allow = false;
|
||||
|
||||
if (table_schema.get_part_level() == PARTITION_LEVEL_ONE &&
|
||||
table_schema.get_part_option().is_list_part()) {
|
||||
ObArenaAllocator allocator(ObModIds::OB_TEMP_VARIABLES);
|
||||
ObResolverParams params;
|
||||
ObRawExprFactory expr_factory(allocator);
|
||||
SMART_VAR(sql::ObSQLSessionInfo, empty_session) {
|
||||
uint64_t tenant_id = table_schema.get_tenant_id();
|
||||
const ObTenantSchema *tenant_schema = NULL;
|
||||
ObSchemaGetterGuard guard;
|
||||
ObSchemaChecker schema_checker;
|
||||
params.expr_factory_ = &expr_factory;
|
||||
params.allocator_ = &allocator;
|
||||
params.session_info_ = &empty_session;
|
||||
if (OB_FAIL(empty_session.init(0, 0, &allocator))) {
|
||||
LOG_WARN("init empty session failed", K(ret));
|
||||
} else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(tenant_id, guard))) {
|
||||
LOG_WARN("get schema guard failed", K(ret));
|
||||
} else if (OB_FAIL(guard.get_tenant_info(tenant_id, tenant_schema))) {
|
||||
LOG_WARN("get tenant_schema failed", K(ret));
|
||||
} else if (OB_FAIL(empty_session.init_tenant(tenant_schema->get_tenant_name_str(), tenant_id))) {
|
||||
LOG_WARN("init tenant failed", K(ret));
|
||||
} else if (OB_FAIL(empty_session.load_all_sys_vars(guard))) {
|
||||
LOG_WARN("session load system variable failed", K(ret));
|
||||
LOG_WARN("session load default system variable failed", K(ret));
|
||||
} else if (OB_FAIL(empty_session.load_default_configs_in_pc())) {
|
||||
LOG_WARN("session load default configs failed", K(ret));
|
||||
} else if (OB_FAIL(schema_checker.init(guard))) {
|
||||
LOG_WARN("failed to init schema checker", K(ret));
|
||||
} else {
|
||||
params.schema_checker_ = &schema_checker;
|
||||
const share::schema::ObPartitionFuncType part_func_type = table_schema.get_part_option().get_part_func_type();
|
||||
const ParseNode *node = NULL;
|
||||
common::ObSEArray<common::ObString, 8> part_keys;
|
||||
common::ObSEArray<ObRawExpr*, 8> part_func_exprs;
|
||||
if (OB_FAIL(ObRawExprUtils::parse_expr_node_from_str(table_schema.get_part_option().get_part_func_expr_str(),
|
||||
empty_session.get_local_collation_connection(),
|
||||
*params.allocator_, node))) {
|
||||
LOG_WARN("parse expr node from string failed", K(ret));
|
||||
} else if (OB_FAIL(resolve_part_func(params,
|
||||
node,
|
||||
part_func_type,
|
||||
table_schema,
|
||||
part_func_exprs,
|
||||
part_keys
|
||||
))) {
|
||||
SQL_RESV_LOG(WARN, "resolve part func failed", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && part_func_exprs.count() == 1) {
|
||||
ObSEArray<ObRawExpr *, 8> check_exprs;
|
||||
for (ObTableSchema::const_constraint_iterator iter = table_schema.constraint_begin(); OB_SUCC(ret) &&
|
||||
iter != table_schema.constraint_end(); iter ++) {
|
||||
ObConstraint cst;
|
||||
ObRawExpr *check_expr = NULL;
|
||||
if ((*iter)->get_constraint_type() != CONSTRAINT_TYPE_CHECK) {
|
||||
continue;
|
||||
} else if (OB_FAIL(ObRawExprUtils::parse_bool_expr_node_from_str((*iter)->get_check_expr_str(),
|
||||
*params.allocator_, node))) {
|
||||
LOG_WARN("parse expr node from string failed", K(ret));
|
||||
} else if (OB_FAIL(resolve_check_constraint_expr(params, node, table_schema, cst, check_expr))) {
|
||||
LOG_WARN("resolver constraint expr failed", K(ret));
|
||||
} else {
|
||||
ret = check_exprs.push_back(check_expr);
|
||||
}
|
||||
}
|
||||
bool tmp_allow = false;
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(check_uniq_allow(params,
|
||||
table_schema,
|
||||
index_arg,
|
||||
part_func_exprs.at(0),
|
||||
check_exprs,
|
||||
tmp_allow))) {
|
||||
LOG_WARN("check_uniq_allowe failed", K(ret));
|
||||
} else if (tmp_allow) {
|
||||
allow = tmp_allow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLResolver::resolve_split_partition_range_element(const ParseNode *node,
|
||||
const share::schema::ObPartitionFuncType part_type,
|
||||
const ObIArray<ObRawExpr *> &part_func_exprs,
|
||||
|
@ -167,9 +167,6 @@ public:
|
||||
bool need_rewrite_length,
|
||||
const bool is_byte_length = false);
|
||||
static int rewrite_text_length_mysql(ObObjType &type, int32_t &length);
|
||||
static int check_uniq_allow(share::schema::ObTableSchema &table_schema,
|
||||
const obrpc::ObCreateIndexArg &index_arg,
|
||||
bool &allow);
|
||||
// check whether the column is allowed to be primary key.
|
||||
int check_add_column_as_pk_allowed(const ObColumnSchemaV2 &column_schema);
|
||||
static int get_primary_key_default_value(
|
||||
@ -421,13 +418,6 @@ public:
|
||||
bool is_oracle_mode,
|
||||
bool is_explicit_order);
|
||||
protected:
|
||||
static int check_same_substr_expr(ObRawExpr &left, ObRawExpr &right, bool &same);
|
||||
static int check_uniq_allow(ObResolverParams ¶ms,
|
||||
share::schema::ObTableSchema &table_schema,
|
||||
const obrpc:: ObCreateIndexArg &index_arg,
|
||||
ObRawExpr *part_func_expr,
|
||||
common::ObIArray<ObRawExpr *> &constraint_exprs,
|
||||
bool &allow);
|
||||
static int get_part_str_with_type(
|
||||
const bool is_oracle_mode,
|
||||
share::schema::ObPartitionFuncType part_func_type,
|
||||
|
Loading…
x
Reference in New Issue
Block a user