fix some bugs about NULL propagation
This commit is contained in:
parent
6f10db934c
commit
afc486e2df
@ -16,6 +16,7 @@
|
||||
#include "sql/ob_sql_context.h"
|
||||
#include "lib/oblog/ob_log_module.h"
|
||||
#include "lib/oblog/ob_log_print_kv.h"
|
||||
#include "sql/rewrite/ob_transform_utils.h"
|
||||
|
||||
using namespace oceanbase;
|
||||
using namespace oceanbase::sql;
|
||||
@ -164,10 +165,15 @@ int ObSharedExprResolver::get_shared_instance(ObRawExpr *expr,
|
||||
ObRawExpr *new_param_expr = NULL;
|
||||
bool is_param_new = false;
|
||||
bool disable_share_child = false;
|
||||
if (old_param_expr->get_expr_type() == T_QUESTIONMARK) {
|
||||
if (OB_ISNULL(old_param_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret));
|
||||
} else if (old_param_expr->get_expr_type() == T_QUESTIONMARK) {
|
||||
if (old_param_expr->has_flag(IS_STATIC_PARAM) && disable_share_const_level_ > 0) {
|
||||
disable_share_expr = true;
|
||||
}
|
||||
} else if (ObTransformUtils::is_const_null(*old_param_expr)) {
|
||||
// skip const null
|
||||
} else if (expr->get_expr_type() == T_FUN_SYS_CAST && i == 1) {
|
||||
// skip exec var and question mark
|
||||
} else if (OB_FAIL(SMART_CALL(get_shared_instance(old_param_expr,
|
||||
|
@ -1354,43 +1354,39 @@ int ObTransformConstPropagate::check_need_cast_when_replace(ObRawExpr *expr,
|
||||
bool &need_cast)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObRawExpr *parent_expr = NULL;
|
||||
bool is_in_param = false;
|
||||
UNUSED(expr);
|
||||
need_cast = true;
|
||||
if (parent_exprs.empty()) {
|
||||
need_cast = false;
|
||||
} else if (OB_ISNULL(parent_expr = parent_exprs.at(parent_exprs.count() - 1)) ||
|
||||
OB_ISNULL(const_expr) || OB_ISNULL(expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret));
|
||||
} else if (check_is_in_or_notin_param(parent_exprs, is_in_param)) {
|
||||
LOG_WARN("failed to check in or notin param", K(ret));
|
||||
} else if (is_in_param) {
|
||||
// for static engine, all params in rigth side of in or not in should have same type
|
||||
need_cast = true;
|
||||
} else {
|
||||
ObRawExpr *parent_expr = parent_exprs.at(parent_exprs.count() - 1);
|
||||
if (OB_ISNULL(parent_expr) || OB_ISNULL(const_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret));
|
||||
} else if (const_expr->get_expr_type() == T_NULL &&
|
||||
ObDatumFuncs::is_null_aware_hash_type(expr->get_result_type().get_type())) {
|
||||
// To adapt to the behavior of casting NULL values for hash compare
|
||||
// cast need to be added above NULL for null aware hash type.
|
||||
need_cast = true;
|
||||
} else if (parent_expr->is_win_func_expr()) {
|
||||
ObWinFunRawExpr *win_expr = static_cast<ObWinFunRawExpr*>(parent_expr);
|
||||
if (OB_NOT_NULL(win_expr->get_agg_expr()) &&
|
||||
ObOptimizerUtil::find_item(win_expr->get_agg_expr()->get_real_param_exprs(), expr)) {
|
||||
need_cast = true;
|
||||
} else if (ObOptimizerUtil::find_item(win_expr->get_func_params(), expr)) {
|
||||
need_cast = true;
|
||||
} else {
|
||||
bool is_parent_cmp = IS_COMPARISON_OP(parent_expr->get_expr_type());
|
||||
// To adapt to the behavior of casting NULL values for hash compare
|
||||
// cast need to be added above NULL when its' parent expr is CMP_OP.
|
||||
bool need_cast_null = false;
|
||||
if (is_parent_cmp && const_expr->get_expr_type() == T_NULL) {
|
||||
for (int64_t i = 0; !need_cast_null && OB_SUCC(ret) &&
|
||||
i < parent_expr->get_param_count(); ++i) {
|
||||
const ObRawExpr *param_expr = parent_expr->get_param_expr(i);
|
||||
if (OB_ISNULL(param_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("param expr is null");
|
||||
} else if (ObDatumFuncs::is_null_aware_hash_type(param_expr->get_result_type().get_type())) {
|
||||
need_cast_null = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
need_cast = need_cast_null || !(is_parent_cmp ||
|
||||
parent_expr->is_query_ref_expr() ||
|
||||
parent_expr->is_win_func_expr() ||
|
||||
T_OP_ROW == parent_expr->get_expr_type());
|
||||
need_cast = false;
|
||||
}
|
||||
} else {
|
||||
need_cast = !(IS_COMPARISON_OP(parent_expr->get_expr_type()) ||
|
||||
T_OP_ROW == parent_expr->get_expr_type() ||
|
||||
parent_expr->is_query_ref_expr());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1485,7 +1481,8 @@ int ObTransformConstPropagate::check_cast_const_expr(ExprConstInfo &const_info,
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (!const_info.const_expr_->is_static_scalar_const_expr()) {
|
||||
is_valid = false;
|
||||
} else if (const_info.need_add_constraint_ == PRE_CALC_RESULT_NULL) {
|
||||
} else if (const_info.need_add_constraint_ == PRE_CALC_RESULT_NULL ||
|
||||
ObTransformUtils::is_const_null(*const_info.const_expr_)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(ObRawExprUtils::check_need_cast_expr(const_info.const_expr_->get_result_type(),
|
||||
const_info.column_expr_->get_result_type(),
|
||||
|
@ -14822,5 +14822,19 @@ int ObTransformUtils::is_winfunc_topn_filter(const ObIArray<ObWinFunRawExpr *> &
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObTransformUtils::is_const_null(ObRawExpr &expr)
|
||||
{
|
||||
int bret = false;
|
||||
if (!expr.is_const_raw_expr()) {
|
||||
// do nothing
|
||||
} else if (expr.get_expr_type() == T_NULL) {
|
||||
bret = true;
|
||||
} else if (expr.get_expr_type() == T_QUESTIONMARK) {
|
||||
bret = expr.get_result_type().get_param().is_null() ||
|
||||
(lib::is_oracle_mode() && expr.get_result_type().get_param().is_null_oracle());
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
@ -1875,6 +1875,8 @@ public:
|
||||
bool &is_fetch_with_ties,
|
||||
ObWinFunRawExpr *&win_expr);
|
||||
static int pushdown_qualify_filters(ObSelectStmt *stmt);
|
||||
// check if a constant or parameterized constant is NULL.
|
||||
static bool is_const_null(ObRawExpr &expr);
|
||||
|
||||
private:
|
||||
static int inner_get_lazy_left_join(ObDMLStmt *stmt,
|
||||
|
Loading…
x
Reference in New Issue
Block a user