diff --git a/src/sql/rewrite/ob_transform_query_push_down.cpp b/src/sql/rewrite/ob_transform_query_push_down.cpp index 45236a2cdf152e3828f99857e92d23f5820b4d13..7323bc2fc574504864234a31543a11173f0e8e86 100644 --- a/src/sql/rewrite/ob_transform_query_push_down.cpp +++ b/src/sql/rewrite/ob_transform_query_push_down.cpp @@ -485,6 +485,8 @@ int ObTransformQueryPushDown::check_select_item_push_down(ObSelectStmt *select_s int ret = OB_SUCCESS; can_be = false; bool check_status = false; + bool is_select_expr_valid = false; + ObSEArray select_exprs; if (OB_ISNULL(select_stmt) || OB_ISNULL(view_stmt)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("stmt is NULL", K(select_stmt), K(view_stmt), K(ret)); @@ -494,6 +496,13 @@ int ObTransformQueryPushDown::check_select_item_push_down(ObSelectStmt *select_s can_be = false; } else if (view_stmt->is_contains_assignment() || select_stmt->is_contains_assignment()) { can_be = false; + } else if (OB_FAIL(view_stmt->get_select_exprs(select_exprs))) { + LOG_WARN("failed to get select exprs", K(ret)); + } else if (OB_FAIL(ObTransformUtils::check_expr_valid_for_stmt_merge(select_exprs, + is_select_expr_valid))) { + LOG_WARN("failed to check select expr valid", K(ret)); + } else if (!is_select_expr_valid) { + can_be = false; } else if(OB_FAIL(is_select_item_same(select_stmt, view_stmt, check_status, diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index f421b916df900bb0dcc5473d32ccde4467ae4b81..fce9a7bc3cc99d0bb3fee5315634aa18efd5e2dc 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -11504,5 +11504,36 @@ int ObTransformUtils::rebuild_win_compare_range_expr(ObRawExprFactory* expr_fact return ret; } +int ObTransformUtils::check_expr_valid_for_stmt_merge(ObIArray &select_exprs, + bool &is_valid) +{ + int ret = OB_SUCCESS; + is_valid = true; + for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < select_exprs.count(); ++i) { + ObRawExpr *expr = select_exprs.at(i); + if (OB_ISNULL(expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect null expr", K(ret)); + } else if (expr->has_flag(IS_CONST) || + expr->has_generalized_column()) { + // do nothing + } else if (expr->has_flag(CNT_STATE_FUNC) || + expr->has_flag(CNT_USER_VARIABLE) || + expr->has_flag(CNT_ALIAS) || + expr->has_flag(CNT_VALUES) || + expr->has_flag(CNT_SEQ_EXPR) || + expr->has_flag(CNT_SYS_CONNECT_BY_PATH) || + expr->has_flag(CNT_RAND_FUNC) || + expr->has_flag(CNT_SO_UDF) || + expr->has_flag(CNT_PRIOR) || + expr->has_flag(CNT_VOLATILE_CONST) || + expr->has_flag(CNT_ASSIGN_EXPR)) { + // the list is aligned with ObRawExprInfoExtractor::not_calculable_expr + is_valid = false; + } + } + return ret; +} + } // namespace sql } // namespace oceanbase diff --git a/src/sql/rewrite/ob_transform_utils.h b/src/sql/rewrite/ob_transform_utils.h index 7692d3341660874d899e3a513afc07c154341764..596fea1047af6c6bdaf58e4995b580cd8d8eb31f 100644 --- a/src/sql/rewrite/ob_transform_utils.h +++ b/src/sql/rewrite/ob_transform_utils.h @@ -1567,6 +1567,9 @@ public: static int rebuild_win_compare_range_expr(ObRawExprFactory* expr_factory, ObWinFunRawExpr &win_expr, ObRawExpr* order_expr); + + static int check_expr_valid_for_stmt_merge(ObIArray &select_exprs, + bool &is_valid); private: static int inner_get_lazy_left_join(ObDMLStmt *stmt, TableItem *table, diff --git a/src/sql/rewrite/ob_transform_view_merge.cpp b/src/sql/rewrite/ob_transform_view_merge.cpp index 295bb18b2281cdd63d4c7e1ecfd50e2f8418f895..916cdd365b7ab38e8b03059096b6681206988288 100644 --- a/src/sql/rewrite/ob_transform_view_merge.cpp +++ b/src/sql/rewrite/ob_transform_view_merge.cpp @@ -486,6 +486,8 @@ int ObTransformViewMerge::check_basic_validity(ObDMLStmt *parent_stmt, bool has_ref_assign_user_var = false; bool force_merge = false; bool force_no_merge = false; + bool is_select_expr_valid = false; + ObSEArray select_exprs; if (OB_ISNULL(parent_stmt) || OB_ISNULL(child_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); @@ -515,6 +517,13 @@ int ObTransformViewMerge::check_basic_validity(ObDMLStmt *parent_stmt, LOG_WARN("failed to check has rownum expr", K(ret)); } else if (has_rownum_expr) { can_be = false; + } else if (OB_FAIL(child_stmt->get_select_exprs(select_exprs))) { + LOG_WARN("failed to get select exprs", K(ret)); + } else if (OB_FAIL(ObTransformUtils::check_expr_valid_for_stmt_merge(select_exprs, + is_select_expr_valid))) { + LOG_WARN("failed to check select expr valid", K(ret)); + } else if (!is_select_expr_valid) { + can_be = false; } else if (0 == child_stmt->get_from_item_size()) { //当 view 为 select ... from dual, 若上层非层次查询, 允许视图合并 can_be = parent_stmt->is_single_table_stmt() diff --git a/tools/deploy/mysql_test/test_suite/static_engine/t/expr_sign.test b/tools/deploy/mysql_test/test_suite/static_engine/t/expr_sign.test index ff02b691c74a8df25d5c04473969c2250f66ea3f..a3b3c413f82762bb5b66a9ce355a3c5773ecd30a 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/t/expr_sign.test +++ b/tools/deploy/mysql_test/test_suite/static_engine/t/expr_sign.test @@ -1,3 +1,4 @@ +--source mysql_test/include/explain_init.inc # owner: dachuan.sdc # owner group: sql2 # tags: optimizer @@ -149,3 +150,4 @@ select sign( cast(a2 as char(1024)) ) , sign( cast(a4 as char(1024)) ) from t2 f --echo #https://work.aone.alibaba-inc.com/issue/32398792 select sign(1E-300) from dual; select sign(1E-400) from dual; +--source mysql_test/include/explain_end.inc