diff --git a/src/share/system_variable/ob_system_variable_factory.h b/src/share/system_variable/ob_system_variable_factory.h index da2de06dc8..0435bffa62 100644 --- a/src/share/system_variable/ob_system_variable_factory.h +++ b/src/share/system_variable/ob_system_variable_factory.h @@ -1470,4 +1470,4 @@ private: } } -#endif //OCEANBASE_SHARE_SYSTEM_VARIABLE_OB_SYSTEM_VARIABLE_FACTORY_ \ No newline at end of file +#endif //OCEANBASE_SHARE_SYSTEM_VARIABLE_OB_SYSTEM_VARIABLE_FACTORY_ diff --git a/src/sql/engine/subquery/ob_subplan_scan_op.cpp b/src/sql/engine/subquery/ob_subplan_scan_op.cpp index 7abb4c639a..c6bb2f026e 100644 --- a/src/sql/engine/subquery/ob_subplan_scan_op.cpp +++ b/src/sql/engine/subquery/ob_subplan_scan_op.cpp @@ -55,6 +55,18 @@ int ObSubPlanScanOp::inner_get_next_row() LOG_WARN("get row from child failed", K(ret)); } } else { + // eval child's output expr + // For some expression in the subquery, we must eval, even if it not output. + // e.g. + // select 1 from (select @a=3); + for (int64_t i = 0; OB_SUCC(ret) && i < child_->get_spec().output_.count(); i++) { + ObExpr *expr = child_->get_spec().output_[i]; + ObDatum *datum = NULL; + if (OB_FAIL(expr->eval(eval_ctx_, datum))) { + LOG_WARN("expr evaluate failed", K(ret), K(*expr)); + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < MY_SPEC.projector_.count(); i += 2) { ObExpr* from = MY_SPEC.projector_[i]; ObExpr* to = MY_SPEC.projector_[i + 1]; diff --git a/src/sql/resolver/expr/ob_expr_info_flag.h b/src/sql/resolver/expr/ob_expr_info_flag.h index 6bc9627e5b..fd8c8b1375 100644 --- a/src/sql/resolver/expr/ob_expr_info_flag.h +++ b/src/sql/resolver/expr/ob_expr_info_flag.h @@ -56,6 +56,7 @@ enum ObExprInfoFlag { IS_VOLATILE_CONST, // the const expr may be altered by overwrite, non-const in execution. IS_ORA_ROWSCN_EXPR, IS_VAR_EXPR, + IS_ASSIGN_EXPR, IS_CONST_EXPR, // expression contains calculable expression CNT_CONST_EXPR, // IS_CONST_EXPR and CNT_CONST_EXPR at most one is true @@ -98,6 +99,7 @@ enum ObExprInfoFlag { CNT_VOLATILE_CONST, CNT_ORA_ROWSCN_EXPR, CNT_VAR_EXPR, + CNT_ASSIGN_EXPR, BE_USED, // expression has been applied IS_SIMPLE_COND, // column = const @@ -117,11 +119,11 @@ enum ObExprInfoFlag { }; #define IS_INFO_MASK_BEGIN IS_CONST -#define IS_INFO_MASK_END IS_VAR_EXPR +#define IS_INFO_MASK_END IS_ASSIGN_EXPR #define CNT_INFO_MASK_BEGIN CNT_CONST -#define CNT_INFO_MASK_END CNT_VAR_EXPR +#define CNT_INFO_MASK_END CNT_ASSIGN_EXPR #define INHERIT_MASK_BEGIN CNT_CONST_EXPR -#define INHERIT_MASK_END CNT_VAR_EXPR +#define INHERIT_MASK_END CNT_ASSIGN_EXPR inline const char* get_expr_info_flag_str(const ObExprInfoFlag flag) { 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 85f08cc83f..bf29c8056d 100644 --- a/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp @@ -161,7 +161,8 @@ int ObRawExprInfoExtractor::add_const(ObRawExpr& expr) T_FUN_SYS_ROWKEY_TO_ROWID == expr.get_expr_type() || T_OP_CONNECT_BY_ROOT == expr.get_expr_type() || T_FUN_SYS_CONNECT_BY_PATH == expr.get_expr_type() || T_FUN_SYS_GUID == expr.get_expr_type() || T_FUN_SYS_STMT_ID == expr.get_expr_type() || T_FUN_SYS_SLEEP == expr.get_expr_type() || - T_OP_PRIOR == expr.get_expr_type() || T_OP_GET_USER_VAR == expr.get_expr_type())) { + T_OP_ASSIGN == expr.get_expr_type() || T_OP_PRIOR == expr.get_expr_type() || + T_OP_GET_USER_VAR == expr.get_expr_type())) { is_const_expr = false; } if (is_const_expr) { @@ -233,7 +234,7 @@ bool ObRawExprInfoExtractor::not_calculable_expr(const ObRawExpr& expr) expr.has_flag(CNT_ALIAS) || expr.has_flag(CNT_ENUM_OR_SET) || 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_EXEC_PARAM) || - expr.has_flag(CNT_VOLATILE_CONST) || expr.has_flag(CNT_VAR_EXPR); + expr.has_flag(CNT_VOLATILE_CONST) || expr.has_flag(CNT_VAR_EXPR) || expr.has_flag(CNT_ASSIGN_EXPR); } int ObRawExprInfoExtractor::visit(ObOpRawExpr& expr) @@ -314,6 +315,10 @@ int ObRawExprInfoExtractor::visit(ObOpRawExpr& expr) if (OB_FAIL(expr.add_flag(IS_OR))) { LOG_WARN("failed to add flag IS_OR", K(ret)); } + } else if (expr.get_expr_type() == T_OP_ASSIGN) { + if (OB_FAIL(expr.add_flag(IS_ASSIGN_EXPR))) { + LOG_WARN("failed to add flag IS_ASSIGN_EXPR", K(ret)); + } } } else if (3 == expr.get_param_count()) { // triple operator diff --git a/unittest/sql/optimizer/test_optimizer_select.result b/unittest/sql/optimizer/test_optimizer_select.result index 579701d01c..e3c3fd6619 100644 --- a/unittest/sql/optimizer/test_optimizer_select.result +++ b/unittest/sql/optimizer/test_optimizer_select.result @@ -19310,17 +19310,19 @@ Outputs & filters: SQL: Select distinct 1, 1 + (@var:=1) from t7; -=================================== -|ID|OPERATOR |NAME|EST. ROWS|COST| ------------------------------------ -|0 |TABLE SCAN|t7 |1 |36 | -=================================== +====================================== +|ID|OPERATOR |NAME|EST. ROWS|COST| +-------------------------------------- +|0 |HASH DISTINCT| |1 |122 | +|1 | TABLE SCAN |t7 |100 |88 | +====================================== Outputs & filters: ------------------------------------- - 0 - output([?], [?]), filter(nil), + 0 - output([?], [? + (T_OP_ASSIGN, 'var', ?)]), filter(nil), + distinct([? + (T_OP_ASSIGN, 'var', ?)]) + 1 - output([? + (T_OP_ASSIGN, 'var', ?)]), filter(nil), access([t7.c1]), partitions(p0), - limit(1), offset(nil), is_index_back=false, range_key([t7.c1]), range(MIN ; MAX)always true