implement of any value expr in mysql mode
This commit is contained in:
1
deps/oblib/src/lib/ob_name_def.h
vendored
1
deps/oblib/src/lib/ob_name_def.h
vendored
@ -335,6 +335,7 @@
|
||||
#define N_INDEX_FILTER_EXPRS "index_filter_exprs"
|
||||
#define N_OPERATOR_MONITOR_INFO "op_info"
|
||||
#define N_PLAN_MONITOR_INFO "plan_info"
|
||||
#define N_ANY_VAL "any_value"
|
||||
// common comparison operator
|
||||
#define N_LESS_THAN "<"
|
||||
#define N_GREATER_THAN ">"
|
||||
|
||||
@ -164,6 +164,8 @@ ob_set_subtarget(ob_sql engine
|
||||
engine/expr/ob_expr.cpp
|
||||
engine/expr/ob_expr_frame_info.cpp
|
||||
engine/expr/ob_expr_user_can_access_obj.cpp
|
||||
engine/expr/ob_expr_any_value.h
|
||||
engine/expr/ob_expr_any_value.cpp
|
||||
engine/pdml/ob_batch_row_cache.cpp
|
||||
engine/pdml/ob_pdml_data_driver.cpp
|
||||
engine/pdml/ob_px_multi_part_modify.cpp
|
||||
@ -950,6 +952,8 @@ ob_set_subtarget(ob_sql resolver
|
||||
resolver/dml/ob_update_stmt.cpp
|
||||
resolver/dml/ob_view_table_resolver.cpp
|
||||
resolver/dml/ob_multi_table_insert_resolver.cpp
|
||||
resolver/dml/ob_any_value_checker.h
|
||||
resolver/dml/ob_any_value_checker.cpp
|
||||
resolver/expr/ob_expr_relation_analyzer.cpp
|
||||
resolver/expr/ob_raw_expr.cpp
|
||||
resolver/expr/ob_expr.cpp
|
||||
|
||||
67
src/sql/engine/expr/ob_expr_any_value.cpp
Normal file
67
src/sql/engine/expr/ob_expr_any_value.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2014-2021 Alibaba Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* ob_expr_any_value.cpp is for any_value function
|
||||
*
|
||||
* Date: 2021/7/9
|
||||
*
|
||||
* Authors:
|
||||
* ailing.lcq<ailing.lcq@alibaba-inc.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sql/engine/expr/ob_expr_any_value.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
|
||||
ObExprAnyValue::ObExprAnyValue(ObIAllocator &alloc)
|
||||
: ObFuncExprOperator(alloc, T_FUN_SYS_ANY_VALUE, N_ANY_VAL, 1, NOT_ROW_DIMENSION)
|
||||
{}
|
||||
|
||||
ObExprAnyValue::~ObExprAnyValue()
|
||||
{}
|
||||
|
||||
int ObExprAnyValue::calc_result_type1(ObExprResType &type, ObExprResType &arg, common::ObExprTypeCtx &) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
type = arg;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprAnyValue::calc_result1(common::ObObj &result, const common::ObObj &arg, common::ObExprCtx &expr_ctx) const
|
||||
{
|
||||
UNUSED(expr_ctx);
|
||||
int ret = OB_SUCCESS;
|
||||
result = arg;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprAnyValue::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const
|
||||
{
|
||||
UNUSED(raw_expr);
|
||||
UNUSED(expr_cg_ctx);
|
||||
rt_expr.eval_func_ = ObExprAnyValue::eval_any_value;
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObExprAnyValue::eval_any_value(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObDatum *arg = NULL;
|
||||
if (OB_FAIL(expr.eval_param_value(ctx, arg))) {
|
||||
SERVER_LOG(WARN, "expr evaluate parameter failed", K(ret));
|
||||
} else {
|
||||
expr_datum.set_datum(*arg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
44
src/sql/engine/expr/ob_expr_any_value.h
Normal file
44
src/sql/engine/expr/ob_expr_any_value.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2014-2021 Alibaba Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* ob_expr_any_value.h is for any_value function
|
||||
*
|
||||
* Date: 2021/7/9
|
||||
*
|
||||
* Authors:
|
||||
* ailing.lcq<ailing.lcq@alibaba-inc.com>
|
||||
*
|
||||
*/
|
||||
#ifndef _OB_EXPR_ANY_VALUE_H_
|
||||
#define _OB_EXPR_ANY_VALUE_H_
|
||||
|
||||
#include "sql/engine/expr/ob_expr_operator.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExprAnyValue : public ObFuncExprOperator {
|
||||
public:
|
||||
explicit ObExprAnyValue(common::ObIAllocator &alloc);
|
||||
virtual ~ObExprAnyValue();
|
||||
|
||||
virtual int calc_result_type1(
|
||||
ObExprResType &type, ObExprResType &arg, common::ObExprTypeCtx &type_ctx) const override;
|
||||
|
||||
virtual int calc_result1(common::ObObj &result, const common::ObObj &arg, common::ObExprCtx &expr_ctx) const override;
|
||||
|
||||
virtual int cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const override;
|
||||
|
||||
static int eval_any_value(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObExprAnyValue) const;
|
||||
};
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* _OB_EXPR_ANY_VALUE_H_ */
|
||||
|
||||
// select any_value();
|
||||
@ -186,6 +186,7 @@
|
||||
#include "ob_expr_convert_tz.h"
|
||||
#include "ob_expr_degrees.h"
|
||||
#include "ob_expr_weight_string.h"
|
||||
#include "ob_expr_any_value.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
@ -671,7 +672,7 @@ static ObExpr::EvalFunc g_expr_eval_functions[] = {
|
||||
ObExprPeriodAdd::calc_periodadd, /* 409 */
|
||||
NULL, /* 410 */
|
||||
NULL, /* 411 */
|
||||
NULL, /* 412 */
|
||||
ObExprAnyValue::eval_any_value, /* 412 */
|
||||
NULL, /* 413 */
|
||||
ObExprDegrees::calc_degrees_expr, /* 414 */
|
||||
NULL, /* 415 */
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
#include "sql/engine/expr/ob_expr_convert_tz.h"
|
||||
#include "sql/engine/expr/ob_expr_degrees.h"
|
||||
#include "sql/engine/expr/ob_expr_weight_string.h"
|
||||
#include "sql/engine/expr/ob_expr_any_value.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
namespace oceanbase {
|
||||
@ -610,6 +611,7 @@ void ObExprOperatorFactory::register_expr_operators()
|
||||
REG_OP(ObExprTruncate);
|
||||
REG_OP(ObExprDllUdf);
|
||||
REG_OP(ObExprExp);
|
||||
REG_OP(ObExprAnyValue);
|
||||
/* subquery comparison experator */
|
||||
REG_OP(ObExprSubQueryRef);
|
||||
REG_OP(ObExprSubQueryEqual);
|
||||
|
||||
@ -426,6 +426,7 @@ typedef enum ObItemType {
|
||||
T_FUN_SYS_QUARTER = 711,
|
||||
T_FUN_SYS_BIT_LENGTH = 712,
|
||||
T_FUN_SYS_PI = 713,
|
||||
T_FUN_SYS_ANY_VALUE = 714,
|
||||
T_FUN_SYS_DEGREES = 715,
|
||||
T_FUN_SYS_EXPORT_SET = 721,
|
||||
|
||||
|
||||
@ -371,6 +371,7 @@ const char* get_type_name(int type)
|
||||
case T_FUN_SYS_QUARTER : return "T_FUN_SYS_QUARTER";
|
||||
case T_FUN_SYS_BIT_LENGTH : return "T_FUN_SYS_BIT_LENGTH";
|
||||
case T_FUN_SYS_PI : return "T_FUN_SYS_PI";
|
||||
case T_FUN_SYS_ANY_VALUE : return "T_FUN_SYS_ANY_VALUE";
|
||||
case T_FUN_SYS_DEGREES : return "T_FUN_SYS_DEGREES";
|
||||
case T_FUN_SYS_EXPORT_SET : return "T_FUN_SYS_EXPORT_SET";
|
||||
case T_FUN_SYS_INET6NTOA : return "T_FUN_SYS_INET6NTOA";
|
||||
|
||||
175
src/sql/resolver/dml/ob_any_value_checker.cpp
Normal file
175
src/sql/resolver/dml/ob_any_value_checker.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Copyright 2014-2021 Alibaba Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* Date: 2021/07/14
|
||||
*
|
||||
* ob_any_value_checker.h is for checking any_value expr in mysql's only_full_group_by mode compatible
|
||||
*
|
||||
* Authors:
|
||||
* ailing.lcq<ailing.lcq@alibaba-inc.com>
|
||||
*/
|
||||
#define USING_LOG_PREFIX SQL_RESV
|
||||
#include "sql/resolver/dml/ob_any_value_checker.h"
|
||||
#include "sql/rewrite/ob_transform_utils.h"
|
||||
#include "lib/oblog/ob_log_module.h"
|
||||
//#include "lib/utility/ob_macro_utils.h"
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
|
||||
int ObAnyValueChecker::visit(ObSysFunRawExpr &expr)
|
||||
{
|
||||
if (T_FUN_SYS_ANY_VALUE == expr.get_expr_type()) {
|
||||
set_skip_expr(&expr);
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObColumnRefRawExpr &expr)
|
||||
{
|
||||
if (undefined_column_ == &expr) {
|
||||
is_pass_ = false;
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObConstRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObVarRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObQueryRefRawExpr &expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObSelectStmt *ref_stmt = expr.get_ref_stmt();
|
||||
if (OB_FAIL(check_select_stmt(ref_stmt))) {
|
||||
LOG_WARN("failed to check select stmt", K(ret));
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObOpRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObCaseOpRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObAggFunRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObSetOpRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObAliasRefRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObFunMatchAgainst &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObWinFunRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::visit(ObPseudoColumnRawExpr &expr)
|
||||
{
|
||||
UNUSED(expr);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::check_select_stmt(const ObSelectStmt *ref_stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool ref_query = false;
|
||||
LOG_DEBUG("check any value start stmt", K(ret));
|
||||
|
||||
if (OB_ISNULL(ref_stmt)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("ref_stmt should not be NULL", K(ret));
|
||||
} else if (OB_FAIL(
|
||||
ObTransformUtils::is_ref_outer_block_relation(ref_stmt, ref_stmt->get_current_level(), ref_query))) {
|
||||
LOG_WARN("failed to get ref stmt", K(ret));
|
||||
} else if (!ref_query) {
|
||||
// non ref query
|
||||
} else {
|
||||
int32_t ignore_scope = 0;
|
||||
if (ref_stmt->is_order_siblings()) {
|
||||
ignore_scope |= RelExprCheckerBase::ORDER_SCOPE;
|
||||
}
|
||||
ObArray<ObRawExpr *> relation_expr_pointers;
|
||||
if (OB_FAIL(ref_stmt->get_relation_exprs(relation_expr_pointers, ignore_scope))) {
|
||||
LOG_WARN("get stmt relation exprs fail", K(ret));
|
||||
}
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < relation_expr_pointers.count(); ++i) {
|
||||
ObRawExpr *expr = relation_expr_pointers.at(i);
|
||||
if (OB_ISNULL(expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("expr in relation_expr_pointers is null", K(i), K(relation_expr_pointers));
|
||||
} else if (OB_FAIL(expr->preorder_accept(*this))) {
|
||||
LOG_WARN("fail to check group by", K(i), K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
const ObIArray<ObSelectStmt *> &child_stmts = ref_stmt->get_set_query();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < child_stmts.count(); ++i) {
|
||||
ret = check_select_stmt(child_stmts.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("check any value end stmt", K(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAnyValueChecker::check_any_value(const ObRawExpr *expr, const ObColumnRefRawExpr *undefined_column)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
undefined_column_ = undefined_column;
|
||||
ObRawExpr *expr_ = const_cast<ObRawExpr *>(expr);
|
||||
if (OB_ISNULL(expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("expr is null");
|
||||
} else if (OB_FAIL(expr_->preorder_accept(*this))) {
|
||||
LOG_WARN("check any value expr fail", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObAnyValueChecker::is_pass_after_check()
|
||||
{
|
||||
return is_pass_;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
70
src/sql/resolver/dml/ob_any_value_checker.h
Normal file
70
src/sql/resolver/dml/ob_any_value_checker.h
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright 2014-2021 Alibaba Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* Date: 2021/07/14
|
||||
*
|
||||
* ob_any_value_checker.h is for checking any_value expr in mysql's only_full_group_by mode compatible
|
||||
*
|
||||
* Authors:
|
||||
* ailing.lcq<ailing.lcq@alibaba-inc.com>
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SRC_SQL_RESOLVER_DML_OB_ANY_VALUE_CHECKER_H_
|
||||
#define OCEANBASE_SRC_SQL_RESOLVER_DML_OB_ANY_VALUE_CHECKER_H_
|
||||
#include "sql/resolver/expr/ob_raw_expr.h"
|
||||
#include "sql/resolver/dml/ob_select_stmt.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
|
||||
class ObAnyValueChecker : public ObRawExprVisitor {
|
||||
public:
|
||||
ObAnyValueChecker() : ObRawExprVisitor(), skip_expr_(nullptr), is_pass_(true)
|
||||
{}
|
||||
virtual ~ObAnyValueChecker()
|
||||
{}
|
||||
/// interface of ObRawExprVisitor
|
||||
virtual int visit(ObConstRawExpr &expr);
|
||||
virtual int visit(ObVarRawExpr &expr);
|
||||
virtual int visit(ObQueryRefRawExpr &expr);
|
||||
virtual int visit(ObColumnRefRawExpr &expr);
|
||||
virtual int visit(ObOpRawExpr &expr);
|
||||
virtual int visit(ObCaseOpRawExpr &expr);
|
||||
virtual int visit(ObAggFunRawExpr &expr);
|
||||
virtual int visit(ObSysFunRawExpr &expr);
|
||||
virtual int visit(ObSetOpRawExpr &expr);
|
||||
virtual int visit(ObAliasRefRawExpr &expr);
|
||||
virtual int visit(ObFunMatchAgainst &expr);
|
||||
virtual int visit(ObWinFunRawExpr &expr);
|
||||
virtual int visit(ObPseudoColumnRawExpr &expr);
|
||||
|
||||
// set expr skip
|
||||
virtual bool skip_child(ObRawExpr &expr)
|
||||
{
|
||||
return skip_expr_ == &expr;
|
||||
}
|
||||
|
||||
int check_select_stmt(const ObSelectStmt *ref_stmt);
|
||||
int check_any_value(const ObRawExpr *expr, const ObColumnRefRawExpr *undefined_column);
|
||||
bool is_pass_after_check();
|
||||
|
||||
private:
|
||||
void set_skip_expr(ObRawExpr *expr)
|
||||
{
|
||||
skip_expr_ = expr;
|
||||
}
|
||||
const ObColumnRefRawExpr *undefined_column_;
|
||||
ObRawExpr *skip_expr_;
|
||||
bool is_pass_;
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObAnyValueChecker);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_SRC_SQL_RESOLVER_DML_OB_ANY_VALUE_CHECKER_H_
|
||||
@ -13,6 +13,7 @@
|
||||
#define USING_LOG_PREFIX SQL_RESV
|
||||
#include "sql/resolver/dml/ob_standard_group_checker.h"
|
||||
#include "sql/resolver/expr/ob_raw_expr.h"
|
||||
#include "sql/resolver/dml/ob_any_value_checker.h"
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
@ -96,7 +97,8 @@ int ObStandardGroupChecker::check_only_full_group_by()
|
||||
// not check aggregate function or column in aggregate function, such as select count(c1) from t1 group by c2;
|
||||
// but if expr has column outside of aggregate function, we only check the column not in aggregate function
|
||||
// such as: select c1+count(c2) from t1 group by c1;
|
||||
const ObUnsettledExprItem& unsettled_expr = unsettled_exprs_.at(i);
|
||||
const ObUnsettledExprItem &unsettled_expr = unsettled_exprs_.at(i);
|
||||
common::ObArray<const ObColumnRefRawExpr *> undefined_columns;
|
||||
for (int64_t j = unsettled_expr.start_idx_;
|
||||
OB_SUCC(ret) && j < unsettled_expr.start_idx_ + unsettled_expr.dependent_column_cnt_;
|
||||
++j) {
|
||||
@ -110,14 +112,23 @@ int ObStandardGroupChecker::check_only_full_group_by()
|
||||
} else if (OB_FAIL(check_unsettled_column(unsettled_column, undefined_column))) {
|
||||
LOG_WARN("check unsettled column failed", K(ret));
|
||||
} else if (undefined_column != NULL) {
|
||||
//当前stmt中存在undefined的列,根据only full group
|
||||
//by语义,如果一个表达式中所有列都是defined,那么该表达式是defined
|
||||
//如果所有列不能保证defined,需要看看表达式本身是否是defined
|
||||
//例如:select c1+c2 from t1 group by c1, c1+c2
|
||||
// c1是defined列,c2不是,c1+c2整体是defined,所以这条语句满足only full group by
|
||||
undefined_columns.push_back(undefined_column);
|
||||
undefined_column = NULL;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && 0 != undefined_columns.size()) {
|
||||
// has undefined column, must check expr whether defined in group by or in any_value
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < undefined_columns.size(); ++i) {
|
||||
if (OB_FAIL(check_unsettled_expr(unsettled_expr.expr_, *(undefined_columns.at(i))))) {
|
||||
LOG_WARN("check unsettled expr failed", K(ret));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && undefined_column != NULL) {
|
||||
// has undefined column, must check expr whether defined in group by
|
||||
if (OB_FAIL(check_unsettled_expr(unsettled_expr.expr_, *undefined_column))) {
|
||||
LOG_WARN("check unsettled expr failed", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !unsettled_expr.expr_->has_flag(CNT_AGG)) {
|
||||
// The current expression satisfies the semantics of only full group by,
|
||||
@ -180,9 +191,6 @@ int ObStandardGroupChecker::check_unsettled_expr(
|
||||
// but if expr has column outside of aggregate function, we only check the column not in aggregate function
|
||||
// such as: select c1+count(c2) from t1 group by c1;
|
||||
ret = OB_ERR_WRONG_FIELD_WITH_GROUP;
|
||||
ObString column_name = concat_qualified_name(
|
||||
undefined_column.get_database_name(), undefined_column.get_table_name(), undefined_column.get_column_name());
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_FIELD_WITH_GROUP, column_name.length(), column_name.ptr());
|
||||
LOG_DEBUG("column not in group by", K(*unsettled_expr), K(undefined_column));
|
||||
} else if (OB_HASH_EXIST == (ret = settled_columns_.exist_refactored(reinterpret_cast<int64_t>(unsettled_expr)))) {
|
||||
// this expr satisfy the only full group by semantic constraints
|
||||
@ -201,13 +209,30 @@ int ObStandardGroupChecker::check_unsettled_expr(
|
||||
}
|
||||
if (OB_SUCC(ret) && !is_defined) {
|
||||
ret = OB_ERR_WRONG_FIELD_WITH_GROUP;
|
||||
ObString column_name = concat_qualified_name(
|
||||
undefined_column.get_database_name(), undefined_column.get_table_name(), undefined_column.get_column_name());
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_FIELD_WITH_GROUP, column_name.length(), column_name.ptr());
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("check unsettled expr failed", K(ret));
|
||||
}
|
||||
|
||||
if (OB_ERR_WRONG_FIELD_WITH_GROUP == ret || OB_ERR_MIX_OF_GROUP_FUNC_AND_FIELDS == ret) {
|
||||
int tmp_ret = ret;
|
||||
ObAnyValueChecker any_value_checker;
|
||||
if (OB_FAIL(any_value_checker.check_any_value(unsettled_expr, &undefined_column))) {
|
||||
LOG_WARN("check any value expr fail", K(ret));
|
||||
} else {
|
||||
if (any_value_checker.is_pass_after_check()) {
|
||||
ret = OB_SUCCESS;
|
||||
} else {
|
||||
ret = tmp_ret;
|
||||
if (OB_ERR_WRONG_FIELD_WITH_GROUP == ret) {
|
||||
ObString column_name = concat_qualified_name(undefined_column.get_database_name(),
|
||||
undefined_column.get_table_name(),
|
||||
undefined_column.get_column_name());
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_FIELD_WITH_GROUP, column_name.length(), column_name.ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // namespace sql
|
||||
|
||||
Reference in New Issue
Block a user