diff --git a/src/sql/resolver/ddl/ob_alter_table_resolver.cpp b/src/sql/resolver/ddl/ob_alter_table_resolver.cpp index 15731de35f..f8cd1c0d99 100644 --- a/src/sql/resolver/ddl/ob_alter_table_resolver.cpp +++ b/src/sql/resolver/ddl/ob_alter_table_resolver.cpp @@ -611,6 +611,8 @@ int ObAlterTableResolver::resolve_action_list(const ParseNode &node) int64_t alter_column_times = 0; int64_t alter_column_visibility_times = 0; ObReducedVisibleColSet reduced_visible_col_set; + //in mysql mode, resolve add index after resolve column actions + ObSEArray add_index_action_idxs; for (int64_t i = 0; OB_SUCC(ret) && i < node.num_child_; ++i) { ParseNode *action_node = node.children_[i]; if (OB_ISNULL(action_node)) { @@ -679,9 +681,14 @@ int ObAlterTableResolver::resolve_action_list(const ParseNode &node) //deal with add index drop index rename index case T_ALTER_INDEX_OPTION: { // mysql对应alter index + bool is_add_index = false; alter_table_stmt->set_alter_table_index(); - if (OB_FAIL(resolve_index_options(node, *action_node))) { + if (OB_FAIL(resolve_index_options(node, *action_node, is_add_index))) { SQL_RESV_LOG(WARN, "Resolve index option failed!", K(ret)); + } else if (is_add_index) { + if (OB_FAIL(add_index_action_idxs.push_back(i))) { + LOG_WARN("push back add index failed", K(ret)); + } } break; } @@ -872,6 +879,25 @@ int ObAlterTableResolver::resolve_action_list(const ParseNode &node) } } } + if (OB_SUCC(ret)) { + for (int64_t i = 0; OB_SUCC(ret) && i < add_index_action_idxs.count(); ++i) { + ParseNode *action_node = NULL; + if (add_index_action_idxs.at(i) < 0 || add_index_action_idxs.at(i) > node.num_child_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid id", K(ret), K(node.num_child_), K(add_index_action_idxs)); + } else if (OB_ISNULL(action_node = node.children_[add_index_action_idxs.at(i)])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", K(ret)); + } else if (action_node->num_child_ <= 0 + || OB_ISNULL(action_node->children_) + || OB_ISNULL(action_node->children_[0])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected action node", K(ret)); + } else if (OB_FAIL(resolve_add_index(*(action_node->children_[0])))) { + LOG_WARN("resolve add index failed", K(ret)); + } + } + } if (OB_SUCC(ret)) { if (lib::is_oracle_mode() && is_modify_column_visibility && (alter_column_times != alter_column_visibility_times)) { ret = OB_ERR_MODIFY_COL_VISIBILITY_COMBINED_WITH_OTHER_OPTION; @@ -1144,10 +1170,17 @@ int ObAlterTableResolver::resolve_index_column_list(const ParseNode &node, if (OB_FAIL(ret)) { // do nothing } else { + ObSEArray resolved_cols; + ObAlterTableStmt *alter_table_stmt = get_alter_table_stmt(); bool is_explicit_order = (NULL != sort_column_node->children_[2] && 1 != sort_column_node->children_[2]->is_empty_); - if (OB_FAIL(resolve_spatial_index_constraint(*table_schema_, sort_item.column_name_, - node.num_child_, index_name_value, is_explicit_order, sort_item.is_func_index_))) { + if (OB_ISNULL(alter_table_stmt)) { + ret = OB_ERR_UNEXPECTED; + SQL_RESV_LOG(WARN, "alter table stmt should not be null", K(ret)); + } else if (OB_FAIL(get_table_schema_all_column_schema(resolved_cols, alter_table_stmt->get_alter_table_schema()))) { + SQL_RESV_LOG(WARN, "failed to get table column schema", K(ret)); + } else if (OB_FAIL(resolve_spatial_index_constraint(*table_schema_, sort_item.column_name_, + node.num_child_, index_name_value, is_explicit_order, sort_item.is_func_index_, &resolved_cols))) { SQL_RESV_LOG(WARN, "check spatial index constraint fail",K(ret), K(sort_item.column_name_), K(node.num_child_)); } @@ -3014,7 +3047,8 @@ int ObAlterTableResolver::resolve_index_options_oracle(const ParseNode &node) // 这里不只处理 index,还会处理 oracle 模式下 alter table 时追加约束 int ObAlterTableResolver::resolve_index_options(const ParseNode &action_node_list, - const ParseNode &node) + const ParseNode &node, + bool &is_add_index) { int ret = OB_SUCCESS; if (OB_UNLIKELY(T_ALTER_INDEX_OPTION != node.type_ || @@ -3027,7 +3061,9 @@ int ObAlterTableResolver::resolve_index_options(const ParseNode &action_node_lis switch(node.children_[0]->type_) { case T_INDEX_ADD: { ParseNode *index_node = node.children_[0]; - if (OB_FAIL(resolve_add_index(*index_node))) { + if (is_mysql_mode()) { + is_add_index = true; + } else if (OB_FAIL(resolve_add_index(*index_node))) { SQL_RESV_LOG(WARN, "Resolve add index error!", K(ret)); } break; diff --git a/src/sql/resolver/ddl/ob_alter_table_resolver.h b/src/sql/resolver/ddl/ob_alter_table_resolver.h index c705eaa818..c59d09f521 100644 --- a/src/sql/resolver/ddl/ob_alter_table_resolver.h +++ b/src/sql/resolver/ddl/ob_alter_table_resolver.h @@ -50,7 +50,8 @@ public: bool &is_drop_column, ObReducedVisibleColSet &reduced_visible_col_set); int resolve_index_options_oracle(const ParseNode &node); - int resolve_index_options(const ParseNode &action_node_list, const ParseNode &node); + int resolve_index_options(const ParseNode &action_node_list, const ParseNode &node, + bool &is_add_index); int resolve_partition_options(const ParseNode &node); int resolve_constraint_options(const ParseNode &node, const bool is_multi_actions); int resolve_modify_foreign_key_state(const ParseNode *node); diff --git a/src/sql/resolver/ddl/ob_ddl_resolver.cpp b/src/sql/resolver/ddl/ob_ddl_resolver.cpp index 7460d130e9..4029ec15f5 100644 --- a/src/sql/resolver/ddl/ob_ddl_resolver.cpp +++ b/src/sql/resolver/ddl/ob_ddl_resolver.cpp @@ -6066,7 +6066,8 @@ int ObDDLResolver::resolve_spatial_index_constraint( int64_t column_num, const int64_t index_keyname_value, bool is_explicit_order, - bool is_func_index) + bool is_func_index, + ObIArray *resolved_cols) { int ret = OB_SUCCESS; const ObColumnSchemaV2 *column_schema = NULL; @@ -6089,7 +6090,8 @@ int ObDDLResolver::resolve_spatial_index_constraint( table_schema, expr, schema_checker_, - ObResolverUtils::CHECK_FOR_FUNCTION_INDEX))) { + ObResolverUtils::CHECK_FOR_FUNCTION_INDEX, + resolved_cols))) { LOG_WARN("build generated column expr failed", K(ret)); } else if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; diff --git a/src/sql/resolver/ddl/ob_ddl_resolver.h b/src/sql/resolver/ddl/ob_ddl_resolver.h index ead2020401..6bb73ab640 100644 --- a/src/sql/resolver/ddl/ob_ddl_resolver.h +++ b/src/sql/resolver/ddl/ob_ddl_resolver.h @@ -422,13 +422,15 @@ public: int resolve_subpartition_option(ObPartitionedStmt *stmt, ParseNode *subpart_node, share::schema::ObTableSchema &table_schema); + // @param [in] resolved_cols the columns which have been resolved in alter table, default null int resolve_spatial_index_constraint( const share::schema::ObTableSchema &table_schema, const common::ObString &column_name, int64_t column_num, const int64_t index_keyname_value, bool is_explicit_order, - bool is_func_index); + bool is_func_index, + ObIArray *resolved_cols = NULL); int resolve_spatial_index_constraint( const share::schema::ObColumnSchemaV2 &column_schema, int64_t column_num, diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index 3979a7fd6c..a499cd2276 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -1918,6 +1918,7 @@ int ObRawExprUtils::check_deterministic_single(const ObRawExpr *expr, * @param table_schema table_schema * @param expr 生成好的表达式 * @param schema_checker checker + * @param resolved_cols Default null. Only use in 'alter table'. Columns which have been resolved in alter table. * @return ret */ int ObRawExprUtils::build_generated_column_expr(const obrpc::ObCreateIndexArg *arg, @@ -1928,7 +1929,8 @@ int ObRawExprUtils::build_generated_column_expr(const obrpc::ObCreateIndexArg *a ObRawExpr *&expr, const ObSchemaChecker *schema_checker, const ObResolverUtils::PureFunctionCheckStatus - check_status) + check_status, + ObIArray *resolved_cols) { int ret = OB_SUCCESS; const ParseNode *node = NULL; @@ -1980,8 +1982,16 @@ int ObRawExprUtils::build_generated_column_expr(const obrpc::ObCreateIndexArg *a ret = OB_ERR_BAD_TABLE; LOG_USER_ERROR(OB_ERR_BAD_TABLE, q_name.tbl_name_.length(), q_name.tbl_name_.ptr()); } else if (OB_ISNULL(col_schema = table_schema.get_column_schema(q_name.col_name_))) { - ret = OB_ERR_KEY_COLUMN_DOES_NOT_EXITS; - LOG_USER_ERROR(OB_ERR_KEY_COLUMN_DOES_NOT_EXITS, q_name.col_name_.length(), q_name.col_name_.ptr()); + if (OB_NOT_NULL(resolved_cols)) { + col_schema = ObResolverUtils::get_column_schema_from_array(*resolved_cols, q_name.col_name_); + } + if (OB_ISNULL(col_schema)) { + ret = OB_ERR_KEY_COLUMN_DOES_NOT_EXITS; + LOG_USER_ERROR(OB_ERR_KEY_COLUMN_DOES_NOT_EXITS, q_name.col_name_.length(), q_name.col_name_.ptr()); + } + } + if (OB_FAIL(ret)) { + //do nothing } else if (OB_UNLIKELY(col_schema->is_generated_column())) { ret = OB_ERR_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN; LOG_USER_ERROR(OB_ERR_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN, diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index a304312229..f3f931fbdf 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -275,7 +275,8 @@ public: ObRawExpr *&expr, const ObSchemaChecker *schema_checker = NULL, const ObResolverUtils::PureFunctionCheckStatus - check_status = ObResolverUtils::DISABLE_CHECK); + check_status = ObResolverUtils::DISABLE_CHECK, + ObIArray *resolved_cols = NULL); static int build_generated_column_expr(const common::ObString &expr_str, ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session_info,