diff --git a/src/sql/resolver/dml/ob_del_upd_resolver.cpp b/src/sql/resolver/dml/ob_del_upd_resolver.cpp index 0d18003946..80869a9672 100644 --- a/src/sql/resolver/dml/ob_del_upd_resolver.cpp +++ b/src/sql/resolver/dml/ob_del_upd_resolver.cpp @@ -2351,11 +2351,50 @@ int ObDelUpdResolver::view_pullup_part_exprs() LOG_WARN("failed to push back pullup partition expr", K(ret)); } } + + // pull up the partition expr from view stmt to root stmt + const ObTableSchema *table_schema = NULL; + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_ISNULL(table) || OB_ISNULL(schema_checker_) || OB_ISNULL(session_info_) || OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table item is null", K(ret)); + } else if (OB_FAIL(schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), + table->get_base_table_item().ref_id_, + table_schema))) { + LOG_WARN("fail to get table schema", K(ret), K(table->get_base_table_item().ref_id_)); + } else if (OB_NOT_NULL(table_schema)) { + const common::ObIArray &foreign_key_infos = table_schema->get_foreign_key_infos(); + for (int64_t i = 0; OB_SUCC(ret) && i < sel_stmt->get_part_exprs().count(); ++i) { + ObDMLStmt::PartExprItem pei = sel_stmt->get_part_exprs().at(i); + if (!is_fk_parent_table(foreign_key_infos, pei.index_tid_)) { + continue; + } else if (OB_FAIL(copier.copy(pei.part_expr_, pei.part_expr_))) { + LOG_WARN("failed to copy part expr", K(ret)); + } else if (OB_FAIL(copier.copy(pei.subpart_expr_, pei.subpart_expr_))) { + LOG_WARN("failed to copy subpart expr", K(ret)); + } else if (OB_FAIL(stmt->get_part_exprs().push_back(pei))) { + LOG_WARN("failed to push back pullup partition expr", K(ret)); + } + } + } } } return ret; } +bool ObDelUpdResolver::is_fk_parent_table(const common::ObIArray &foreign_key_infos, const uint64_t table_id) +{ + bool is_pk_table = false; + for (int64_t i = 0; i < foreign_key_infos.count() && !is_pk_table; i++) { + const ObForeignKeyInfo &foreign_key_info = foreign_key_infos.at(i); + const uint64_t parent_table_id = foreign_key_info.parent_table_id_; + if (table_id == parent_table_id) { + is_pk_table = true; + } + } + return is_pk_table; +} int ObDelUpdResolver::expand_record_to_columns(const ParseNode &record_node, ObIArray &value_list) { diff --git a/src/sql/resolver/dml/ob_del_upd_resolver.h b/src/sql/resolver/dml/ob_del_upd_resolver.h index b4bc2d4600..5e0c9b793a 100644 --- a/src/sql/resolver/dml/ob_del_upd_resolver.h +++ b/src/sql/resolver/dml/ob_del_upd_resolver.h @@ -155,6 +155,7 @@ protected: int view_pullup_part_exprs(); int expand_record_to_columns(const ParseNode &record_node, ObIArray &value_list); + bool is_fk_parent_table(const common::ObIArray &foreign_key_infos, const uint64_t table_id); int resolve_check_constraints(const TableItem* table_item, common::ObIArray &check_exprs); int resolve_view_check_exprs(uint64_t table_id, diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 9867da95c9..00f6e0ac15 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -3305,7 +3305,7 @@ int ObDMLResolver::resolve_basic_table_without_cte(const ParseNode &parse_tree, LOG_WARN("resolve table partition expr failed", K(ret), K(table_name)); } else if (OB_FAIL(resolve_generated_column_expr_temp(table_item))) { LOG_WARN("resolve generated column expr templte failed", K(ret)); - } else if (OB_FAIL(resolve_table_check_constraint_items(table_item, table_schema))) { + } else if (OB_FAIL(resolve_table_constraint_items(table_item, table_schema))) { LOG_WARN("resolve table partition expr failed", K(ret), K(table_name)); } else if (stmt->is_select_stmt() && OB_FAIL(resolve_geo_mbr_column())) { LOG_WARN("resolve geo mbr column failed", K(ret), K(table_name)); @@ -3442,6 +3442,21 @@ int ObDMLResolver::resolve_table_check_constraint_items(const TableItem *table_i return ret; } +int ObDMLResolver::resolve_table_constraint_items(const TableItem *table_item, + const ObTableSchema *table_schema) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(table_item) || OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table item or schema is null", K(ret), K(table_item), K(table_schema)); + } else if (OB_FAIL(resolve_table_check_constraint_items(table_item, table_schema))) { + LOG_WARN("failed to resolve check constraints", K(ret)); + } else if (OB_FAIL(resolve_foreign_key_constraint(table_item))) { + LOG_WARN("failed to resolve foreign key constraint", K(ret)); + } + return ret; +} + int ObDMLResolver::check_flashback_expr_validity(ObRawExpr *expr, bool &has_column) { int ret = OB_SUCCESS; @@ -5419,7 +5434,18 @@ int ObDMLResolver::resolve_fk_table_partition_expr(const TableItem &table_item, if (OB_FAIL(ret)) { } else if (OB_FAIL(dml_stmt->set_part_expr(foreign_key_info.foreign_key_id_, fk_scan_tid, parent_part_expr, parent_subpart_expr))) { - LOG_WARN("set part expr to dml stmt failed", K(ret)); + /* + create table t17(a int, b int, c int, d int, primary key (a)) partition by hash(a) partitions 3; + create table tf17(a int, b int, c int, d int, primary key (a), foreign key (a) references t17 (a)) partition by hash(a) partitions 3; + update tf17 partition(p0) as C, tf17 as P set C.d = C.d + 100 where C.a = P.a; + In follwing cases, the partition key of t17 will be resolved twice, but it needs return success for compatibility with oracle + */ + if (ret == OB_ERR_TABLE_EXIST) { + ret = OB_SUCCESS; + LOG_INFO("Duplicate foreign key", K(lbt())); + } else { + LOG_WARN("set part expr to dml stmt failed", K(ret)); + } } else { LOG_TRACE("resolve partition expr", K(table_item), KPC(parent_part_expr), K(part_str)); } diff --git a/src/sql/resolver/dml/ob_dml_resolver.h b/src/sql/resolver/dml/ob_dml_resolver.h index a4249ee799..78e8251d5e 100644 --- a/src/sql/resolver/dml/ob_dml_resolver.h +++ b/src/sql/resolver/dml/ob_dml_resolver.h @@ -917,6 +917,8 @@ private: int resolve_table_check_constraint_items(const TableItem *table_item, const ObTableSchema *table_schema); + int resolve_table_constraint_items(const TableItem *table_item, + const ObTableSchema *table_schema); int find_table_index_infos(const ObString &index_name, const TableItem *table_item, bool &find_it, diff --git a/src/sql/resolver/dml/ob_insert_resolver.cpp b/src/sql/resolver/dml/ob_insert_resolver.cpp index 8b4c1e2f89..a38a2d78f3 100644 --- a/src/sql/resolver/dml/ob_insert_resolver.cpp +++ b/src/sql/resolver/dml/ob_insert_resolver.cpp @@ -421,9 +421,6 @@ int ObInsertResolver::resolve_insert_field(const ParseNode &insert_into, TableIt session_info_->set_table_name_hidden(old_flag); } OZ(column_namespace_checker_.add_reference_table(table_item)); - if (OB_SUCC(ret) && OB_FAIL(resolve_foreign_key_constraint(table_item))) { - LOG_WARN("failed to resolve foreign key constraint", K(ret), K(table_item->ref_id_)); - } if (OB_SUCC(ret)) { current_scope_ = T_INSERT_SCOPE; const ObTableSchema *table_schema = NULL; diff --git a/src/sql/resolver/dml/ob_merge_resolver.cpp b/src/sql/resolver/dml/ob_merge_resolver.cpp index df4aaa8464..3a5d374320 100644 --- a/src/sql/resolver/dml/ob_merge_resolver.cpp +++ b/src/sql/resolver/dml/ob_merge_resolver.cpp @@ -228,8 +228,6 @@ int ObMergeResolver::resolve_target_relation(const ParseNode *target_node) } else if (OB_ISNULL(table_item)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table_item is NULL", K(ret)); - } else if (OB_FAIL(resolve_foreign_key_constraint(table_item))) { - LOG_WARN("failed to resolve foreign key constraint", K(ret), K(table_item->ref_id_)); } else if (OB_FAIL(column_namespace_checker_.add_reference_table(table_item))) { LOG_WARN("add reference table to column namespace checker failed", K(ret)); } else if (OB_FAIL(check_need_fired_trigger(table_item))) { diff --git a/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp b/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp index e1cd4edf7d..42ad5a907a 100644 --- a/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp +++ b/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp @@ -360,8 +360,6 @@ int ObMultiTableInsertResolver::resolve_insert_table_node(const ParseNode &inser LOG_WARN("a view is not appropriate here", K(ret)); } else if (OB_FAIL(column_namespace_checker_.add_reference_table(table_item))) { LOG_WARN("failed to resolve basic table"); - } else if (OB_FAIL(resolve_foreign_key_constraint(table_item))) { - LOG_WARN("failed to resolve foreign key constraint", K(ret), K(table_item->ref_id_)); } else if (OB_FAIL(check_need_fired_trigger(table_item))) { LOG_WARN("failed to check has need fired trigger", K(ret), K(table_item->ref_id_)); } else { diff --git a/src/sql/resolver/dml/ob_update_resolver.cpp b/src/sql/resolver/dml/ob_update_resolver.cpp index 4180bbfcb8..6a9cc9a1f7 100644 --- a/src/sql/resolver/dml/ob_update_resolver.cpp +++ b/src/sql/resolver/dml/ob_update_resolver.cpp @@ -443,8 +443,6 @@ int ObUpdateResolver::resolve_table_list(const ParseNode &parse_tree) LOG_WARN("table node is null"); } else if (OB_FAIL(ObDMLResolver::resolve_table(*table_node, table_item))) { LOG_WARN("failed to resolve table", K(ret)); - } else if (OB_FAIL(resolve_foreign_key_constraint(table_item))) { - LOG_WARN("failed to resolve foreign key constraint", K(ret), K(table_item->ref_id_)); } else {/*do nothing*/} if (OB_SUCC(ret)) { if (OB_FAIL(column_namespace_checker_.add_reference_table(table_item))) {