diff --git a/src/sql/resolver/dml/ob_stmt_expr_visitor.cpp b/src/sql/resolver/dml/ob_stmt_expr_visitor.cpp index ddfad4c49b..2e8901d6ab 100644 --- a/src/sql/resolver/dml/ob_stmt_expr_visitor.cpp +++ b/src/sql/resolver/dml/ob_stmt_expr_visitor.cpp @@ -263,3 +263,59 @@ int ObStmtExecParamFormatter::do_formalize_exec_param(ObRawExpr *&expr, bool &is } return ret; } + +int ObStmtExprChecker::do_visit(ObRawExpr *&expr) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(check_expr(expr))) { + LOG_WARN("failed to check expr", K(ret), KPC(expr)); + } + return ret; +} + +int ObStmtExprChecker::check_expr(const ObRawExpr *expr) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is null", K(ret)); + } else if (OB_FAIL(check_const_flag(expr))) { + LOG_WARN("failed to check const flag", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) { + if (OB_FAIL(SMART_CALL(check_expr(expr->get_param_expr(i))))) { + LOG_WARN("failed to check param expr", K(ret)); + } + } + return ret; +} + +int ObStmtExprChecker::check_const_flag(const ObRawExpr *expr) const +{ + int ret = OB_SUCCESS; + bool expect_is_const = true; + if (OB_ISNULL(expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is null", K(ret), K(expr)); + } + for (int64_t i = 0; OB_SUCC(ret) && expect_is_const && i < expr->get_param_count(); ++i) { + const ObRawExpr *param_expr = expr->get_param_expr(i); + if (OB_ISNULL(param_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("param expr is null", K(ret), K(param_expr)); + } else { + expect_is_const = param_expr->is_const_expr(); + } + } + if (OB_SUCC(ret) && expect_is_const) { + if (OB_FAIL(expr->is_const_inherit_expr(expect_is_const))) { + LOG_WARN("failed to check expr is const inherit", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(expr->is_const_expr() != expect_is_const)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr const flag is not match", K(ret), K(expect_is_const), KPC(expr)); + } + return ret; +} diff --git a/src/sql/resolver/dml/ob_stmt_expr_visitor.h b/src/sql/resolver/dml/ob_stmt_expr_visitor.h index 475c94108f..23a1878581 100644 --- a/src/sql/resolver/dml/ob_stmt_expr_visitor.h +++ b/src/sql/resolver/dml/ob_stmt_expr_visitor.h @@ -236,6 +236,15 @@ public: }; +class ObStmtExprChecker : public ObStmtExprVisitor +{ +public: + ObStmtExprChecker() {} + virtual int do_visit(ObRawExpr *&expr) override; + int check_expr(const ObRawExpr *expr) const; + int check_const_flag(const ObRawExpr *expr) const; +}; + } } diff --git a/src/sql/resolver/expr/ob_raw_expr.cpp b/src/sql/resolver/expr/ob_raw_expr.cpp index 0f16b09d7c..edd7addf5d 100644 --- a/src/sql/resolver/expr/ob_raw_expr.cpp +++ b/src/sql/resolver/expr/ob_raw_expr.cpp @@ -789,6 +789,17 @@ int ObRawExpr::is_const_inherit_expr(bool &is_const_inherit, || T_FUN_NORMAL_UDF == type_ || T_FUN_SYS_REMOVE_CONST == type_ || T_FUN_SYS_WRAPPER_INNER == type_ + || T_FUN_SYS_VALUES == type_ + || T_OP_GET_PACKAGE_VAR == type_ + || T_OP_GET_SUBPROGRAM_VAR == type_ + || T_FUN_SYS_JSON_VALUE == type_ + || T_FUN_SYS_JSON_QUERY == type_ + || (T_FUN_SYS_JSON_EXISTS == type_ && lib::is_oracle_mode()) + || T_FUN_SYS_JSON_EQUAL == type_ + || T_FUN_SYS_IS_JSON == type_ + || (T_FUN_SYS_JSON_MERGE_PATCH == type_ && lib::is_oracle_mode()) + || T_FUN_SYS_JSON_OBJECT == type_ + || IS_LABEL_SE_POLICY_FUNC(type_) || (T_FUN_SYS_LAST_INSERT_ID == type_ && get_param_count() > 0) || T_FUN_SYS_TO_BLOB == type_ || (T_FUN_SYS_SYSDATE == type_ && lib::is_mysql_mode()) diff --git a/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp b/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp index cea4f80c28..c14421ec2c 100644 --- a/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp @@ -567,32 +567,6 @@ int ObRawExprInfoExtractor::visit(ObSysFunRawExpr &expr) } } else {} } - - if (OB_SUCC(ret) - && (T_FUN_SYS_JSON_VALUE == expr.get_expr_type() - || T_FUN_SYS_JSON_QUERY == expr.get_expr_type() - || (T_FUN_SYS_JSON_EXISTS == expr.get_expr_type() && lib::is_oracle_mode()) - || T_FUN_SYS_JSON_EQUAL == expr.get_expr_type() - || T_FUN_SYS_IS_JSON == expr.get_expr_type() - || (T_FUN_SYS_JSON_MERGE_PATCH == expr.get_expr_type() && lib::is_oracle_mode()) - || T_FUN_SYS_JSON_OBJECT == expr.get_expr_type() - || IS_LABEL_SE_POLICY_FUNC(expr.get_expr_type())) - && OB_FAIL(expr.clear_flag(IS_CONST_EXPR))) { - LOG_WARN("failed to clear flag", K(ret)); - } - - if (OB_SUCC(ret) && T_FUN_SYS_JSON_VALUE == expr.get_expr_type()) { - if (expr.get_param_count() >= 12) { - ObRawExpr * sub_expr = expr.get_param_expr(7); - if (OB_NOT_NULL(sub_expr) - && OB_FAIL(sub_expr->clear_flag(IS_CONST_EXPR))) { - LOG_WARN("failed to clear flag", K(ret)); - } else if (OB_NOT_NULL(sub_expr = expr.get_param_expr(4)) - && OB_FAIL(sub_expr->clear_flag(IS_CONST_EXPR))) { - LOG_WARN("failed to clear flag", K(ret)); - } - } - } } return ret; } diff --git a/src/sql/rewrite/ob_transform_or_expansion.cpp b/src/sql/rewrite/ob_transform_or_expansion.cpp index c20af013fe..02f18d52d9 100644 --- a/src/sql/rewrite/ob_transform_or_expansion.cpp +++ b/src/sql/rewrite/ob_transform_or_expansion.cpp @@ -598,6 +598,10 @@ int ObTransformOrExpansion::try_do_transform_left_join(ObIArray if (OB_FAIL(ret)) { } else if (!trans_happened && OB_FAIL(try_trans_helper1.recover(stmt->get_query_ctx()))) { LOG_WARN("failed to recover params", K(ret)); + } else if (!trans_happened && OB_FAIL(remove_temp_table_select_item(ref_query, + not_null_side_table->table_id_, + right_flag_pos))) { + LOG_WARN("failed to remove temp table select item", K(ret)); } else { ctx_->src_hash_val_.pop_back(); } @@ -726,7 +730,7 @@ int ObTransformOrExpansion::add_select_item_to_ref_query(ObSelectStmt *stmt, ObSEArray right_flag_exprs; ObSEArray select_exprs; if (OB_ISNULL(stmt) || OB_ISNULL(ctx_) || OB_ISNULL(ctx_->expr_factory_) - || OB_ISNULL(ctx_->allocator_)) { + || OB_ISNULL(ctx_->allocator_) || OB_ISNULL(ctx_->session_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null", K(ret), K(stmt), K(ctx_)); } else if (OB_UNLIKELY(1 != stmt->get_from_item_size()) || @@ -758,6 +762,8 @@ int ObTransformOrExpansion::add_select_item_to_ref_query(ObSelectStmt *stmt, } else if (OB_FAIL(ObRawExprUtils::build_const_number_expr(*ctx_->expr_factory_, ObNumberType, number::ObNumber::get_positive_one(), const_expr))) { LOG_WARN("failed to build const expr", K(ret)); + } else if (OB_FAIL(const_expr->formalize(ctx_->session_info_))) { + LOG_WARN("failed to formalize const number expr", K(ret)); } else if (OB_FAIL(select_list.push_back(const_expr))) { LOG_WARN("failed to push back expr", K(ret)); } else if (OB_FAIL(ObTransformUtils::create_columns_for_view(ctx_, *flag_table, stmt, @@ -818,6 +824,33 @@ int ObTransformOrExpansion::add_select_item_to_ref_query(ObSelectStmt *stmt, return ret; } +int ObTransformOrExpansion::remove_temp_table_select_item(ObSelectStmt *stmt, + const uint64_t flag_table_id, + ObSqlBitSet<> &right_flag_pos) +{ + int ret = OB_SUCCESS; + TableItem *flag_table = NULL; + ObSelectStmt *view_stmt = NULL; + if (OB_ISNULL(stmt) || OB_ISNULL(ctx_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect null", K(ret), K(stmt)); + } else if (OB_ISNULL(flag_table = stmt->get_table_item_by_id(flag_table_id))) { + LOG_WARN("faield to get table item", K(ret), K(flag_table), K(flag_table_id)); + } else if (!flag_table->is_temp_table()) { + // do nothing + } else if (OB_UNLIKELY(right_flag_pos.num_members() != 1)) { + ret= OB_ERR_UNEXPECTED; + LOG_WARN("unexpected right flag pos count", K(ret), K(right_flag_pos)); + } else if (OB_ISNULL(view_stmt = flag_table->ref_query_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("view_stmt is null", K(ret), K(view_stmt)); + } else if (ObTransformUtils::remove_select_items(ctx_, flag_table_id, *view_stmt, + *stmt, right_flag_pos)) { + LOG_WARN("failed to remove select items", K(ret)); + } + return ret; +} + // do transform after get a union stmt: // 1. add win func level // 2. add filter level diff --git a/src/sql/rewrite/ob_transform_or_expansion.h b/src/sql/rewrite/ob_transform_or_expansion.h index 32f1509933..ef7044664b 100644 --- a/src/sql/rewrite/ob_transform_or_expansion.h +++ b/src/sql/rewrite/ob_transform_or_expansion.h @@ -169,6 +169,9 @@ private: StmtUniqueKeyProvider &unique_key_provider, ObSqlBitSet<> &left_unique_pos, ObSqlBitSet<> &right_flag_pos); + int remove_temp_table_select_item(ObSelectStmt *stmt, + const uint64_t flag_table_id, + ObSqlBitSet<> &right_flag_pos); int create_row_number_window_function(ObIArray &partition_exprs, ObIArray &order_exprs, diff --git a/src/sql/rewrite/ob_transformer_impl.cpp b/src/sql/rewrite/ob_transformer_impl.cpp index 6dd612c8b8..2df94a4fd6 100644 --- a/src/sql/rewrite/ob_transformer_impl.cpp +++ b/src/sql/rewrite/ob_transformer_impl.cpp @@ -159,6 +159,8 @@ int ObTransformerImpl::do_after_transform(ObDMLStmt *stmt) LOG_WARN("failed to add pre calc constraints", K(ret)); } else if (OB_FAIL(adjust_global_dependency_tables(stmt))) { LOG_WARN("failed to adjust global depency", K(ret)); + } else if (OB_FAIL(verify_all_stmt_exprs(stmt))) { + LOG_WARN("failed to verify all stmt exprs", K(ret)); } return ret; } @@ -649,6 +651,44 @@ int ObTransformerImpl::adjust_global_dependency_tables(ObDMLStmt *stmt) return ret; } +int ObTransformerImpl::verify_all_stmt_exprs(ObDMLStmt *stmt) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("stmt is NULL", K(ret)); + } else if (OB_FAIL(verify_stmt_exprs(stmt))) { + LOG_WARN("failed to verify stmt exprs", K(ret)); + } else { + ObArray temp_table_infos; + if (OB_FAIL(stmt->collect_temp_table_infos(temp_table_infos))) { + LOG_WARN("failed to collect temp table infos", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < temp_table_infos.count(); ++i) { + if (OB_FAIL(verify_stmt_exprs(temp_table_infos.at(i).temp_table_query_))) { + LOG_WARN("failed to verify temp table query exprs", K(ret)); + } + } + } + return ret; +} + +int ObTransformerImpl::verify_stmt_exprs(ObDMLStmt *stmt) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("stmt is NULL", K(ret)); + } else { + ObStmtExprChecker checker; + checker.set_relation_scope(); + if (OB_FAIL(stmt->iterate_stmt_expr(checker))) { + LOG_WARN("failed to check stmt expr", K(ret), KPC(stmt)); + } + } + return ret; +} + int ObTransformerImpl::add_param_and_expr_constraints(ObExecContext &exec_ctx, ObTransformerCtx &trans_ctx, ObDMLStmt &stmt) diff --git a/src/sql/rewrite/ob_transformer_impl.h b/src/sql/rewrite/ob_transformer_impl.h index 46369635f9..c0f3db0381 100644 --- a/src/sql/rewrite/ob_transformer_impl.h +++ b/src/sql/rewrite/ob_transformer_impl.h @@ -158,6 +158,8 @@ private: * 为pl收集依赖表的schema version信息 */ int adjust_global_dependency_tables(ObDMLStmt *stmt); + int verify_all_stmt_exprs(ObDMLStmt *stmt); + int verify_stmt_exprs(ObDMLStmt *stmt); template int transform_one_rule(ObDMLStmt *&stmt,