diff --git a/src/sql/resolver/ddl/ob_create_table_resolver.cpp b/src/sql/resolver/ddl/ob_create_table_resolver.cpp index f59622950b..5940ce83be 100644 --- a/src/sql/resolver/ddl/ob_create_table_resolver.cpp +++ b/src/sql/resolver/ddl/ob_create_table_resolver.cpp @@ -1513,6 +1513,9 @@ int ObCreateTableResolver::resolve_table_elements_from_select(const ParseNode &p ObSelectStmt *select_stmt = NULL; ObSelectResolver select_resolver(params_); select_resolver.params_.is_from_create_table_ = true; + select_resolver.params_.is_specified_col_name_ = parse_tree.num_child_ > 3 && + parse_tree.children_[3] != NULL && + T_TABLE_ELEMENT_LIST == parse_tree.children_[3]->type_; //select层不应该看到上层的insert stmt的属性,所以upper scope stmt应该为空 select_resolver.set_parent_namespace_resolver(NULL); if (lib::is_mysql_mode() @@ -1521,6 +1524,11 @@ int ObCreateTableResolver::resolve_table_elements_from_select(const ParseNode &p && !params_.is_prepare_protocol_) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("not support questionmark in normal create.", K(ret)); + } else if (OB_UNLIKELY(parse_tree.num_child_ <= 3 || + (parse_tree.children_[3] != NULL && + T_TABLE_ELEMENT_LIST != parse_tree.children_[3]->type_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument.", K(ret)); } else if (OB_ISNULL(session_info_) || OB_ISNULL(allocator_) || OB_ISNULL(params_.param_list_)) { ret = OB_NOT_INIT; SQL_RESV_LOG(WARN, "ObCreateTableResolver is not init", K(params_.param_list_), K(allocator_), diff --git a/src/sql/resolver/ddl/ob_create_view_resolver.cpp b/src/sql/resolver/ddl/ob_create_view_resolver.cpp index c98611155b..d132ff4858 100644 --- a/src/sql/resolver/ddl/ob_create_view_resolver.cpp +++ b/src/sql/resolver/ddl/ob_create_view_resolver.cpp @@ -126,6 +126,7 @@ int ObCreateViewResolver::resolve(const ParseNode &parse_tree) ObViewTableResolver view_table_resolver(params_, stmt->get_database_name(), table_schema.get_table_name()); view_table_resolver.params_.is_from_create_view_ = true; + view_table_resolver.params_.is_specified_col_name_ = parse_tree.children_[VIEW_COLUMNS_NODE] != NULL; view_table_resolver.set_current_view_level(1); view_table_resolver.set_is_create_view(true); // set ObViewSchema.materialized_ in RS diff --git a/src/sql/resolver/dml/ob_column_namespace_checker.cpp b/src/sql/resolver/dml/ob_column_namespace_checker.cpp index 11c312db4e..68c0ac4b1c 100644 --- a/src/sql/resolver/dml/ob_column_namespace_checker.cpp +++ b/src/sql/resolver/dml/ob_column_namespace_checker.cpp @@ -68,7 +68,9 @@ int ObColumnNamespaceChecker::remove_reference_table(int64_t tid) * for oracle mode, if table name is specified, we need to make sure that this column does not appear in the using columns in the joined table * for example, select t1.a from t1 inner join t2 using (a), this is not allowed in oracle mode */ -int ObColumnNamespaceChecker::check_table_column_namespace(const ObQualifiedName &q_name, const TableItem *&table_item) +int ObColumnNamespaceChecker::check_table_column_namespace(const ObQualifiedName &q_name, + const TableItem *&table_item, + bool is_from_multi_tab_insert/*default false*/) { int ret = OB_SUCCESS; table_item = NULL; @@ -76,7 +78,7 @@ int ObColumnNamespaceChecker::check_table_column_namespace(const ObQualifiedName bool need_check_unique = false; //针对multi table insert需要进行特殊检测,因为同一个sql中可能插入多次相同表,eg: //insert all into t1 values(1,1) into t1 values(2,2) select 1 from dual; - if (get_resolve_params().is_multi_table_insert_) { + if (is_from_multi_tab_insert) { if (OB_UNLIKELY(all_table_refs_.count() <= 0) || OB_ISNULL(cur_table = all_table_refs_.at(all_table_refs_.count() - 1))) { ret = OB_ERR_UNEXPECTED; @@ -540,7 +542,8 @@ int ObColumnNamespaceChecker::check_rowscn_table_column_namespace( } int ObColumnNamespaceChecker::check_rowid_table_column_namespace(const ObQualifiedName &q_name, - const TableItem *&table_item) + const TableItem *&table_item, + bool is_from_multi_tab_insert/*default false*/) { int ret = OB_SUCCESS; table_item = nullptr; @@ -548,7 +551,7 @@ int ObColumnNamespaceChecker::check_rowid_table_column_namespace(const ObQualifi bool is_match = false; //for multi table insert need extra check, because rowid must be come from generate table and the //generate table must be the last one in all_table_refs_. - if (get_resolve_params().is_multi_table_insert_) { + if (is_from_multi_tab_insert) { if (OB_UNLIKELY(all_table_refs_.count() <= 1) || OB_ISNULL(cur_table = all_table_refs_.at(all_table_refs_.count() - 1)) || OB_UNLIKELY(!cur_table->is_generated_table())) { diff --git a/src/sql/resolver/dml/ob_column_namespace_checker.h b/src/sql/resolver/dml/ob_column_namespace_checker.h index 56ec976dc1..5a817b7e36 100644 --- a/src/sql/resolver/dml/ob_column_namespace_checker.h +++ b/src/sql/resolver/dml/ob_column_namespace_checker.h @@ -56,7 +56,9 @@ public: * @param table_item, if exists, will return the table item that contain this column * @return */ - int check_table_column_namespace(const ObQualifiedName &q_name, const TableItem *&table_item); + int check_table_column_namespace(const ObQualifiedName &q_name, + const TableItem *&table_item, + bool is_from_multi_tab_insert = false); int check_using_column_namespace(const common::ObString &column_name, const TableItem *&left_table, const TableItem *&right_table); @@ -85,7 +87,8 @@ public: int check_rowid_table_column_namespace( const ObQualifiedName &q_name, - const TableItem *&table_item); + const TableItem *&table_item, + bool is_from_multi_tab_insert = false); void enable_check_unique() { check_unique_ = true; } void disable_check_unique() { check_unique_ = false; } diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index eaef9b84fb..ba69e4b6d3 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -1965,7 +1965,8 @@ int ObDMLResolver::resolve_basic_column_ref(const ObQualifiedName &q_name, ObRaw ret = OB_NOT_INIT; LOG_WARN("stmt is null", K(ret)); } else { - if (OB_FAIL(column_namespace_checker_.check_table_column_namespace(q_name, table_item))) { + if (OB_FAIL(column_namespace_checker_.check_table_column_namespace(q_name, table_item, + stmt->is_insert_all_stmt()))) { LOG_WARN_IGNORE_COL_NOTFOUND(ret, "check basic column namespace failed", K(ret), K(q_name)); } else if (OB_ISNULL(table_item)) { ret = OB_ERR_UNEXPECTED; @@ -3550,12 +3551,13 @@ int ObDMLResolver::resolve_table_column_expr(const ObQualifiedName &q_name, ObRa //1. joined table column //2. basic table column or generated table column int ret = OB_SUCCESS; - if (OB_ISNULL(session_info_)) { + if (OB_ISNULL(session_info_) || OB_ISNULL(get_stmt())) { ret = OB_NOT_INIT; - LOG_WARN("session info is null", K_(session_info)); + LOG_WARN("session info is null", K_(session_info), K(get_stmt())); } else { const TableItem *table_item = NULL; - if (OB_FAIL(column_namespace_checker_.check_table_column_namespace(q_name, table_item))) { + if (OB_FAIL(column_namespace_checker_.check_table_column_namespace(q_name, table_item, + get_stmt()->is_insert_all_stmt()))) { LOG_WARN_IGNORE_COL_NOTFOUND(ret, "column don't found in table", K(ret), K(q_name)); } else if (table_item->is_joined_table()) { const JoinedTable &joined_table = static_cast(*table_item); @@ -5803,9 +5805,6 @@ int ObDMLResolver::resolve_subquery_info(const ObIArray &subquer ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "Too many levels of subquery"); } - //resolve subquery in insert all need reset the flag. - bool is_multi_table_insert = params_.is_multi_table_insert_; - params_.is_multi_table_insert_ = false; for (int64_t i = 0; OB_SUCC(ret) && i < subquery_info.count(); i++) { const ObSubQueryInfo &info = subquery_info.at(i); ObSelectResolver subquery_resolver(params_); @@ -5827,7 +5826,6 @@ int ObDMLResolver::resolve_subquery_info(const ObIArray &subquer } set_query_ref_expr(NULL); } - params_.is_multi_table_insert_ = is_multi_table_insert; return ret; } @@ -11199,7 +11197,11 @@ int ObDMLResolver::check_rowid_table_column_in_all_namespace(const ObQualifiedNa { int ret = OB_SUCCESS; //first check current resolver - if (OB_FAIL(column_namespace_checker_.check_rowid_table_column_namespace(q_name, table_item))) { + if (OB_ISNULL(get_stmt())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("index schema should not be null", K(ret), K(get_stmt())); + } else if (OB_FAIL(column_namespace_checker_.check_rowid_table_column_namespace(q_name, table_item, + get_stmt()->is_insert_all_stmt()))) { LOG_WARN("check rowid table colum namespace failed", K(ret)); } else if (table_item != NULL) { dml_stmt = get_stmt(); 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 5e58fe1c8d..96fd1f9a18 100644 --- a/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp +++ b/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp @@ -176,7 +176,6 @@ int ObMultiTableInsertResolver::resolve_multi_table_insert(const ParseNode &node } else { //3.解析insert conditions //对于列只需要检测在subquery对应的generated table中是否存在对应的列,因此提前设置好相关标记 - params_.is_multi_table_insert_ = true; for (int64_t i = 0; OB_SUCC(ret) && i < multi_insert_cond_node.count(); ++i) { ObSEArray insert_condition_exprs; if (OB_UNLIKELY(multi_insert_cond_node.at(i).table_cnt_ <= 0) || @@ -260,7 +259,6 @@ int ObMultiTableInsertResolver::resolve_multi_insert_subquey(const ParseNode &su ObSelectStmt *select_stmt = NULL; ObSelectResolver *sub_select_resolver = nullptr; //重置状态,避免状态误判 - params_.is_multi_table_insert_ = false; params_.have_same_table_name_ = false; sub_select_resolver = new(select_buffer) ObSelectResolver(params_); sub_select_resolver->set_current_level(current_level_); @@ -363,7 +361,6 @@ int ObMultiTableInsertResolver::resolve_insert_table_node(const ParseNode &inser LOG_WARN("failed to resolve basic table"); } else { //提前设置好解析参数,对于多表插入会出现相同的表的场景,因此检查时需要提前设置好参数 - params_.is_multi_table_insert_ = true; if (OB_FAIL(generate_insert_all_table_info(*table_item, when_conds_idx, table_info))) { LOG_WARN("failed to generate insert all table info", K(ret)); } else if (OB_ISNULL(table_info)) { diff --git a/src/sql/resolver/dml/ob_select_resolver.cpp b/src/sql/resolver/dml/ob_select_resolver.cpp index 1a0e9fe6df..63a367d035 100644 --- a/src/sql/resolver/dml/ob_select_resolver.cpp +++ b/src/sql/resolver/dml/ob_select_resolver.cpp @@ -62,6 +62,7 @@ ObSelectResolver::ObSelectResolver(ObResolverParams ¶ms) { params_.is_from_create_view_ = params.is_from_create_view_; params_.is_from_create_table_ = params.is_from_create_table_; + params_.is_specified_col_name_ = params.is_specified_col_name_; auto_name_id_ = 1; } @@ -1760,6 +1761,7 @@ int ObSelectResolver::resolve_field_list(const ParseNode &node) LOG_WARN("alias name too long", K(ret), K(select_item.alias_name_)); } } else if (OB_UNLIKELY((params_.is_from_create_view_ || params_.is_from_create_table_) + && !params_.is_specified_col_name_ && 0 == select_item.expr_name_.case_compare( OB_HIDDEN_LOGICAL_ROWID_COLUMN_NAME))) { // must name alias for rowid diff --git a/src/sql/resolver/dml/ob_view_table_resolver.h b/src/sql/resolver/dml/ob_view_table_resolver.h index 3089cf5f94..d15bbab7c6 100644 --- a/src/sql/resolver/dml/ob_view_table_resolver.h +++ b/src/sql/resolver/dml/ob_view_table_resolver.h @@ -33,6 +33,7 @@ public: is_resolving_view_ = true; params_.is_from_create_view_ = params.is_from_create_view_; params_.is_from_create_table_ = params.is_from_create_table_; + params_.is_specified_col_name_ = params.is_specified_col_name_; } virtual ~ObViewTableResolver() {} diff --git a/src/sql/resolver/ob_resolver_define.h b/src/sql/resolver/ob_resolver_define.h index 5c600dbdcc..12c0100b7d 100644 --- a/src/sql/resolver/ob_resolver_define.h +++ b/src/sql/resolver/ob_resolver_define.h @@ -331,7 +331,6 @@ struct ObResolverParams new_gen_qid_(1), new_cte_tid_(common::OB_MIN_CTE_TABLE_ID + 1), new_gen_wid_(1), - is_multi_table_insert_(false), is_resolve_table_function_expr_(false), has_cte_param_list_(false), has_recursive_word_(false), @@ -342,7 +341,8 @@ struct ObResolverParams outline_parse_result_(NULL), is_execute_call_stmt_(false), enable_res_map_(false), - need_check_col_dup_(true) + need_check_col_dup_(true), + is_specified_col_name_(false) {} bool is_force_trace_log() { return force_trace_log_; } @@ -395,7 +395,6 @@ private: int64_t new_gen_wid_; // when number friend class ObStmtResolver; public: - bool is_multi_table_insert_; // used to mark is multi table insert bool is_resolve_table_function_expr_; // used to mark resolve table function expr. bool has_cte_param_list_; bool has_recursive_word_; @@ -407,6 +406,7 @@ public: bool is_execute_call_stmt_; bool enable_res_map_; bool need_check_col_dup_; + bool is_specified_col_name_;//mark if specify the column name in create view or create table as.. }; } // end namespace sql } // end namespace oceanbase