From 397fc12ff27e2d6a2661ec897e6933a333ee6537 Mon Sep 17 00:00:00 2001 From: ChangerR Date: Fri, 26 May 2023 12:46:32 +0000 Subject: [PATCH] fix win expr order incorrect cause result error --- .../code_generator/ob_static_engine_cg.cpp | 22 +++++++++++++++++++ src/sql/code_generator/ob_static_engine_cg.h | 2 ++ src/sql/optimizer/ob_optimizer_util.cpp | 3 ++- src/sql/optimizer/ob_optimizer_util.h | 1 + src/sql/optimizer/ob_select_log_plan.cpp | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/sql/code_generator/ob_static_engine_cg.cpp b/src/sql/code_generator/ob_static_engine_cg.cpp index 6d6a2bd6d2..7a10ab6809 100644 --- a/src/sql/code_generator/ob_static_engine_cg.cpp +++ b/src/sql/code_generator/ob_static_engine_cg.cpp @@ -5813,6 +5813,8 @@ int ObStaticEngineCG::generate_spec(ObLogWindowFunction &op, ObWindowFunctionSpe } if (OB_FAIL(ret)) { + } else if (OB_FAIL(check_window_functions_order(op.get_window_exprs()))) { + LOG_WARN("failed to check window functions order", K(ret)); } else if (OB_FAIL(spec.wf_infos_.prepare_allocate(op.get_window_exprs().count()))) { LOG_WARN("failed to prepare_allocate the window function.", K(ret)); } else if (OB_FAIL(append_array_no_dup(all_expr, spec.get_child()->output_))) { @@ -7379,5 +7381,25 @@ int ObStaticEngineCG::set_batch_exec_param(const ObIArray return ret; } +int ObStaticEngineCG::check_window_functions_order(const ObIArray &winfunc_exprs) +{ + int ret = OB_SUCCESS; + int64_t partition_count = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < winfunc_exprs.count(); ++i) { + ObWinFunRawExpr * win_expr = winfunc_exprs.at(i); + if (OB_ISNULL(win_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret)); + } else if (i == 0) { + partition_count = win_expr->get_partition_exprs().count(); + } else if (partition_count < win_expr->get_partition_exprs().count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("earlier partition by exprs must be subsets of the later partition by exprs", K(ret)); + } else { + partition_count = win_expr->get_partition_exprs().count(); + } + } + return ret; +} } // end namespace sql } // end namespace oceanbase diff --git a/src/sql/code_generator/ob_static_engine_cg.h b/src/sql/code_generator/ob_static_engine_cg.h index 5f97eb958f..216aaae563 100644 --- a/src/sql/code_generator/ob_static_engine_cg.h +++ b/src/sql/code_generator/ob_static_engine_cg.h @@ -507,6 +507,8 @@ private: int set_batch_exec_param(const ObIArray &exec_params, const ObFixedArray& setters); + + int check_window_functions_order(const ObIArray &winfunc_exprs); private: struct BatchExecParamCache { BatchExecParamCache(ObExecParamRawExpr* expr, ObOpSpec* spec, bool is_left) diff --git a/src/sql/optimizer/ob_optimizer_util.cpp b/src/sql/optimizer/ob_optimizer_util.cpp index 646e0a41fe..3e39c7b64b 100644 --- a/src/sql/optimizer/ob_optimizer_util.cpp +++ b/src/sql/optimizer/ob_optimizer_util.cpp @@ -2848,13 +2848,14 @@ int ObOptimizerUtil::get_nested_exprs(ObIArray &exprs, int ObOptimizerUtil::get_non_const_expr_size(const ObIArray &exprs, const EqualSets &equal_sets, const ObIArray &const_exprs, + const ObIArray &exec_ref_exprs, int64_t &number) { int ret = OB_SUCCESS; bool is_const = false; number = 0; for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) { - if (OB_FAIL(is_const_expr(exprs.at(i), equal_sets, const_exprs, is_const))) { + if (OB_FAIL(is_const_expr(exprs.at(i), equal_sets, const_exprs, exec_ref_exprs, is_const))) { LOG_WARN("failed to check is const expr", K(ret)); } else if (!is_const) { ++number; diff --git a/src/sql/optimizer/ob_optimizer_util.h b/src/sql/optimizer/ob_optimizer_util.h index abd0240b86..2f729fc002 100644 --- a/src/sql/optimizer/ob_optimizer_util.h +++ b/src/sql/optimizer/ob_optimizer_util.h @@ -164,6 +164,7 @@ public: static int get_non_const_expr_size(const ObIArray &exprs, const EqualSets &equal_sets, const common::ObIArray &const_exprs, + const ObIArray &exec_ref_exprs, int64_t &number); static bool is_sub_expr(const ObRawExpr *sub_expr, const ObRawExpr *expr); diff --git a/src/sql/optimizer/ob_select_log_plan.cpp b/src/sql/optimizer/ob_select_log_plan.cpp index c5f42d6f81..a189670b2f 100644 --- a/src/sql/optimizer/ob_select_log_plan.cpp +++ b/src/sql/optimizer/ob_select_log_plan.cpp @@ -5883,6 +5883,7 @@ int ObSelectLogPlan::adjust_window_functions(const ObLogicalOperator *top, if (OB_FAIL(ObOptimizerUtil::get_non_const_expr_size(winfunc_exprs.at(i)->get_partition_exprs(), equal_sets, top->get_output_const_exprs(), + get_onetime_query_refs(), non_const_exprs))) { LOG_WARN("failed to get non const expr size", K(ret)); } else if (OB_FAIL(expr_entries.push_back(std::pair(-non_const_exprs, i)))) {