fix some window func bugs
This commit is contained in:
parent
ef9887b33b
commit
e067fa2e07
@ -984,7 +984,12 @@
|
||||
#define ER_WINDOW_NO_CHILD_PARTITIONING 3581
|
||||
#define ER_WINDOW_NO_INHERIT_FRAME 3582
|
||||
#define ER_WINDOW_NO_REDEFINE_ORDER_BY 3583
|
||||
#define ER_WINDOW_FRAME_ILLEGAL 3586
|
||||
#define ER_WINDOW_RANGE_FRAME_ORDER_TYPE 3587
|
||||
#define ER_WINDOW_RANGE_FRAME_TEMPORAL_TYPE 3588
|
||||
#define ER_WINDOW_RANGE_FRAME_NUMERIC_TYPE 3589
|
||||
#define ER_WINDOW_RANGE_BOUND_NOT_CONSTANT 3590
|
||||
|
||||
#define ER_WINDOW_ILLEGAL_ORDER_BY 3592
|
||||
#define ER_WINDOW_ROWS_INTERVAL_USE 3596
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -1147,6 +1147,11 @@ DEFINE_ORACLE_ERROR(OB_ERR_DEFAULT_NOT_ALLOWED, -5504, -1, "HY000", "Virtual col
|
||||
DEFINE_ORACLE_ERROR(OB_ERR_MODIFY_REALCOL_TO_GENCOL, -5505, -1, "HY000", "Real column cannot have an expression", 54026, "Real column cannot have an expression");
|
||||
DEFINE_ORACLE_ERROR(OB_ERR_MODIFY_TYPE_OF_GENCOL, -5506, -1, "HY000", "cannot modify data-type of virtual column", 54027, "cannot modify data-type of virtual column");
|
||||
|
||||
DEFINE_ERROR_EXT(OB_ERR_WINDOW_FRAME_ILLEGAL, -5507, ER_WINDOW_FRAME_ILLEGAL, "HY000", "frame start or end is negative or NULL or of non-integral type", "Window '%.*s': frame start or end is negative or NULL or of non-integral type");
|
||||
DEFINE_ERROR_EXT(OB_ERR_WINDOW_RANGE_FRAME_TEMPORAL_TYPE, -5508, ER_WINDOW_RANGE_FRAME_TEMPORAL_TYPE, "HY000", "Window with RANGE frame has ORDER BY expression of datetime type. Only INTERVAL bound value allowed.", "Window '%.*s' with RANGE frame has ORDER BY expression of datetime type. Only INTERVAL bound value allowed.");
|
||||
DEFINE_ERROR_EXT(OB_ERR_WINDOW_RANGE_FRAME_NUMERIC_TYPE, -5509, ER_WINDOW_RANGE_FRAME_NUMERIC_TYPE, "HY000", "Window with RANGE frame has ORDER BY expression of numeric type. INTERVAL bound value not allowed.", "Window '%.*s' with RANGE frame has ORDER BY expression of numeric type. INTERVAL bound value not allowed.");
|
||||
DEFINE_ERROR_EXT(OB_ERR_WINDOW_RANGE_BOUND_NOT_CONSTANT, -5510, ER_WINDOW_RANGE_BOUND_NOT_CONSTANT, "HY000", "Window has a non-constant frame bound.", "Window '%.*s' has a non-constant frame bound.");
|
||||
|
||||
DEFINE_ERROR_EXT(OB_ERR_SP_ALREADY_EXISTS, -5541, ER_SP_ALREADY_EXISTS, "42000", "procedure/function already exists", "%s %.*s already exists");
|
||||
DEFINE_ERROR_EXT(OB_ERR_SP_DOES_NOT_EXIST, -5542, ER_SP_DOES_NOT_EXIST, "42000", "procedure/function does not exist", "%s %.*s.%.*s does not exist");
|
||||
DEFINE_PLS_ERROR_EXT(OB_ERR_SP_UNDECLARED_VAR, -5543, ER_SP_UNDECLARED_VAR, "42000", "Undeclared variable", "Undeclared variable: %.*s", 201, "identifier must be declared", "identifier '%.*s' must be declared");
|
||||
|
@ -859,6 +859,10 @@ constexpr int OB_ERR_VIEW_SELECT_CONTAIN_INTO = -5503;
|
||||
constexpr int OB_ERR_DEFAULT_NOT_ALLOWED = -5504;
|
||||
constexpr int OB_ERR_MODIFY_REALCOL_TO_GENCOL = -5505;
|
||||
constexpr int OB_ERR_MODIFY_TYPE_OF_GENCOL = -5506;
|
||||
constexpr int OB_ERR_WINDOW_FRAME_ILLEGAL = -5507;
|
||||
constexpr int OB_ERR_WINDOW_RANGE_FRAME_TEMPORAL_TYPE = -5508;
|
||||
constexpr int OB_ERR_WINDOW_RANGE_FRAME_NUMERIC_TYPE = -5509;
|
||||
constexpr int OB_ERR_WINDOW_RANGE_BOUND_NOT_CONSTANT = -5510;
|
||||
constexpr int OB_ERR_SP_ALREADY_EXISTS = -5541;
|
||||
constexpr int OB_ERR_SP_DOES_NOT_EXIST = -5542;
|
||||
constexpr int OB_ERR_SP_UNDECLARED_VAR = -5543;
|
||||
@ -2805,6 +2809,10 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
|
||||
#define OB_ERR_DEFAULT_NOT_ALLOWED__USER_ERROR_MSG "Virtual column cannot have a default value"
|
||||
#define OB_ERR_MODIFY_REALCOL_TO_GENCOL__USER_ERROR_MSG "Real column cannot have an expression"
|
||||
#define OB_ERR_MODIFY_TYPE_OF_GENCOL__USER_ERROR_MSG "cannot modify data-type of virtual column"
|
||||
#define OB_ERR_WINDOW_FRAME_ILLEGAL__USER_ERROR_MSG "Window '%.*s': frame start or end is negative or NULL or of non-integral type"
|
||||
#define OB_ERR_WINDOW_RANGE_FRAME_TEMPORAL_TYPE__USER_ERROR_MSG "Window '%.*s' with RANGE frame has ORDER BY expression of datetime type. Only INTERVAL bound value allowed."
|
||||
#define OB_ERR_WINDOW_RANGE_FRAME_NUMERIC_TYPE__USER_ERROR_MSG "Window '%.*s' with RANGE frame has ORDER BY expression of numeric type. INTERVAL bound value not allowed."
|
||||
#define OB_ERR_WINDOW_RANGE_BOUND_NOT_CONSTANT__USER_ERROR_MSG "Window '%.*s' has a non-constant frame bound."
|
||||
#define OB_ERR_SP_ALREADY_EXISTS__USER_ERROR_MSG "%s %.*s already exists"
|
||||
#define OB_ERR_SP_DOES_NOT_EXIST__USER_ERROR_MSG "%s %.*s.%.*s does not exist"
|
||||
#define OB_ERR_SP_UNDECLARED_VAR__USER_ERROR_MSG "Undeclared variable: %.*s"
|
||||
@ -4920,6 +4928,10 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
|
||||
#define OB_ERR_DEFAULT_NOT_ALLOWED__ORA_USER_ERROR_MSG "ORA-54025: Virtual column cannot have a default value"
|
||||
#define OB_ERR_MODIFY_REALCOL_TO_GENCOL__ORA_USER_ERROR_MSG "ORA-54026: Real column cannot have an expression"
|
||||
#define OB_ERR_MODIFY_TYPE_OF_GENCOL__ORA_USER_ERROR_MSG "ORA-54027: cannot modify data-type of virtual column"
|
||||
#define OB_ERR_WINDOW_FRAME_ILLEGAL__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5507, Window '%.*s': frame start or end is negative or NULL or of non-integral type"
|
||||
#define OB_ERR_WINDOW_RANGE_FRAME_TEMPORAL_TYPE__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5508, Window '%.*s' with RANGE frame has ORDER BY expression of datetime type. Only INTERVAL bound value allowed."
|
||||
#define OB_ERR_WINDOW_RANGE_FRAME_NUMERIC_TYPE__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5509, Window '%.*s' with RANGE frame has ORDER BY expression of numeric type. INTERVAL bound value not allowed."
|
||||
#define OB_ERR_WINDOW_RANGE_BOUND_NOT_CONSTANT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5510, Window '%.*s' has a non-constant frame bound."
|
||||
#define OB_ERR_SP_ALREADY_EXISTS__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5541, %s %.*s already exists"
|
||||
#define OB_ERR_SP_DOES_NOT_EXIST__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5542, %s %.*s.%.*s does not exist"
|
||||
#define OB_ERR_SP_UNDECLARED_VAR__ORA_USER_ERROR_MSG "PLS-00201: identifier '%.*s' must be declared"
|
||||
@ -6005,7 +6017,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
|
||||
#define OB_ERR_DATA_TOO_LONG_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-12899: value too large for column %.*s (actual: %ld, maximum: %ld)"
|
||||
#define OB_ERR_INVALID_DATE_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-01861: Incorrect datetime value for column '%.*s' at row %ld"
|
||||
|
||||
extern int g_all_ob_errnos[2111];
|
||||
extern int g_all_ob_errnos[2115];
|
||||
|
||||
const char *ob_error_name(const int oberr);
|
||||
const char* ob_error_cause(const int oberr);
|
||||
|
@ -444,10 +444,12 @@ int ObWindowFunctionOp::get_param_int_value(ObExpr &expr,
|
||||
ObEvalCtx &eval_ctx,
|
||||
bool &is_null,
|
||||
int64_t &value,
|
||||
const bool need_number/* = false*/)
|
||||
const bool need_number/* = false*/,
|
||||
const bool need_check_valid/* = false*/)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObDatum *result = NULL;
|
||||
bool is_valid_param = true;
|
||||
is_null = false;
|
||||
value = 0;
|
||||
if (OB_FAIL(expr.eval(eval_ctx, result))) {
|
||||
@ -457,12 +459,14 @@ int ObWindowFunctionOp::get_param_int_value(ObExpr &expr,
|
||||
LOG_WARN("params is not number type", K(expr), K(ret));
|
||||
} else if (result->is_null()) {
|
||||
is_null = true;
|
||||
is_valid_param = !need_check_valid;
|
||||
} else if (need_number || expr.obj_meta_.is_number()) {
|
||||
//we restrict the bucket_num in range [0, (1<<63)-1]
|
||||
number::ObNumber result_nmb;
|
||||
number::ObCompactNumber &cnum = const_cast<number::ObCompactNumber &>(
|
||||
result->get_number());
|
||||
result_nmb.assign(cnum.desc_.desc_, cnum.digits_ + 0);
|
||||
is_valid_param = !need_check_valid || !result_nmb.is_negative();
|
||||
if (OB_FAIL(result_nmb.extract_valid_int64_with_trunc(value))) {
|
||||
LOG_WARN("extract_valid_int64_with_trunc failed", K(ret));
|
||||
}
|
||||
@ -470,11 +474,13 @@ int ObWindowFunctionOp::get_param_int_value(ObExpr &expr,
|
||||
switch (expr.obj_meta_.get_type_class()) {
|
||||
case ObIntTC: {
|
||||
value = result->get_int();
|
||||
is_valid_param = !need_check_valid || value >= 0;
|
||||
break;
|
||||
}
|
||||
case ObUIntTC: {
|
||||
const uint64_t tmp_value = result->get_uint();
|
||||
if (tmp_value > INT64_MAX) {
|
||||
is_valid_param = !need_check_valid || static_cast<int64_t>(tmp_value) >= 0;
|
||||
if (tmp_value > INT64_MAX && is_valid_param) {
|
||||
ret = OB_DATA_OUT_OF_RANGE;
|
||||
LOG_WARN("int64 out of range", K(ret), K(tmp_value), K(INT64_MAX));
|
||||
} else {
|
||||
@ -484,6 +490,7 @@ int ObWindowFunctionOp::get_param_int_value(ObExpr &expr,
|
||||
}
|
||||
case ObFloatTC: {
|
||||
const float tmp_value = result->get_float();
|
||||
is_valid_param = !need_check_valid || tmp_value >= 0;
|
||||
if (tmp_value > INT64_MAX) {
|
||||
ret = OB_DATA_OUT_OF_RANGE;
|
||||
LOG_WARN("int64 out of range", K(ret), K(tmp_value), K(INT64_MAX));
|
||||
@ -494,6 +501,7 @@ int ObWindowFunctionOp::get_param_int_value(ObExpr &expr,
|
||||
}
|
||||
case ObDoubleTC: {
|
||||
const double tmp_value = result->get_double();
|
||||
is_valid_param = !need_check_valid || tmp_value >= 0;
|
||||
if (tmp_value > INT64_MAX) {
|
||||
ret = OB_DATA_OUT_OF_RANGE;
|
||||
LOG_WARN("int64 out of range", K(ret), K(tmp_value), K(INT64_MAX));
|
||||
@ -504,7 +512,8 @@ int ObWindowFunctionOp::get_param_int_value(ObExpr &expr,
|
||||
}
|
||||
case ObBitTC: {
|
||||
const uint64_t tmp_value = result->get_bit();
|
||||
if (tmp_value > INT64_MAX) {
|
||||
is_valid_param = !need_check_valid || static_cast<int64_t>(tmp_value) >= 0;
|
||||
if (tmp_value > INT64_MAX && is_valid_param) {
|
||||
ret = OB_DATA_OUT_OF_RANGE;
|
||||
LOG_WARN("int64 out of range", K(ret), K(tmp_value), K(INT64_MAX));
|
||||
} else {
|
||||
@ -518,6 +527,10 @@ int ObWindowFunctionOp::get_param_int_value(ObExpr &expr,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !is_valid_param) {
|
||||
ret = OB_ERR_WINDOW_FRAME_ILLEGAL;
|
||||
LOG_WARN("frame start or end is negative, NULL or of non-integral type", K(ret), K(value), KPC(result));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -758,8 +771,14 @@ int ObWindowFunctionOp::NonAggrCellNtile::eval(RowsReader &row_reader,
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("argument is NULL", K(ret));
|
||||
} else if (OB_FAIL(ObWindowFunctionOp::get_param_int_value(*param,
|
||||
op_.eval_ctx_, is_null, bucket_num))) {
|
||||
LOG_WARN("get_param_int_value failed", K(ret));
|
||||
op_.eval_ctx_, is_null, bucket_num, false, lib::is_mysql_mode()))) {
|
||||
if (ret == OB_ERR_WINDOW_FRAME_ILLEGAL) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Incorrect arguments to ntile", K(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "ntile");
|
||||
} else {
|
||||
LOG_WARN("get_param_int_value failed", K(ret));
|
||||
}
|
||||
} else if (is_null) {
|
||||
// return NULL when backets_num is NULL
|
||||
val.set_null();
|
||||
@ -2818,7 +2837,10 @@ int ObWindowFunctionOp::get_pos(RowsReader &row_reader,
|
||||
if (OB_ISNULL(between_value_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("between_value_expr is unexpected", KPC(between_value_expr), K(ret));
|
||||
} else if (OB_FAIL(get_param_int_value(*between_value_expr, eval_ctx_, is_null, interval))) {
|
||||
} else if (OB_UNLIKELY(lib::is_mysql_mode() && is_rows && !between_value_expr->obj_meta_.is_integer_type())) {
|
||||
ret = OB_ERR_WINDOW_FRAME_ILLEGAL;
|
||||
LOG_WARN("frame start or end is negative, NULL or of non-integral type", K(ret), K(between_value_expr->obj_meta_));
|
||||
} else if (OB_FAIL(get_param_int_value(*between_value_expr, eval_ctx_, is_null, interval, false, lib::is_mysql_mode()))) {
|
||||
LOG_WARN("get_param_int_value failed", K(ret), KPC(between_value_expr));
|
||||
} else if (is_null) {
|
||||
got_null_val = true;
|
||||
@ -2831,7 +2853,17 @@ int ObWindowFunctionOp::get_pos(RowsReader &row_reader,
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (is_rows) {
|
||||
// range or rows with expr
|
||||
pos = is_preceding ? row_idx - interval : row_idx + interval;
|
||||
if (OB_UNLIKELY(!is_preceding && static_cast<uint64>(row_idx + interval) > INT64_MAX)) {
|
||||
if (lib::is_mysql_mode()) {
|
||||
ret = OB_ERR_WINDOW_FRAME_ILLEGAL;
|
||||
LOG_WARN("frame start or end is negative, NULL or of non-integral type", K(ret), K(row_idx + interval));
|
||||
} else {
|
||||
ret = OB_DATA_OUT_OF_RANGE;
|
||||
LOG_WARN("int64 out of range", K(ret), K(row_idx + interval));
|
||||
}
|
||||
} else {
|
||||
pos = is_preceding ? row_idx - interval : row_idx + interval;
|
||||
}
|
||||
} else if (wf_cell.wf_info_.sort_exprs_.count() == 0) {
|
||||
//Only when order by is const, sort_exprs_.count() == 0
|
||||
ObDatum *cmp_result = NULL;
|
||||
@ -2886,6 +2918,12 @@ int ObWindowFunctionOp::get_pos(RowsReader &row_reader,
|
||||
LOG_WARN("NULL ptr", K(ret), K(bound_expr));
|
||||
} else if (OB_FAIL(bound_expr->eval(eval_ctx_, cmp_val))) {
|
||||
LOG_WARN("calc compare value failed", K(ret));
|
||||
} else if (lib::is_mysql_mode() &&
|
||||
!is_nmb_literal &&
|
||||
ob_is_temporal_type(bound_expr->datum_meta_.get_type())) {
|
||||
if (OB_FAIL(check_interval_valid(*bound_expr))) {
|
||||
LOG_WARN("failed to check interval valid", K(ret));
|
||||
}
|
||||
}
|
||||
ObSortFuncs &sort_cmp_funcs = wf_cell.wf_info_.sort_cmp_funcs_;
|
||||
ObDatumCmpFuncType cmp_func = sort_cmp_funcs.at(0).cmp_func_;
|
||||
@ -3896,5 +3934,41 @@ int ObWindowFunctionOp::final_next_batch(const int64_t max_row_cnt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObWindowFunctionOp::check_interval_valid(ObExpr &expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (expr.type_ == T_FUN_SYS_DATE_ADD ||
|
||||
expr.type_ == T_FUN_SYS_DATE_SUB) {
|
||||
bool is_valid = true;
|
||||
ObDatum *date = NULL;
|
||||
ObDatum *interval = NULL;
|
||||
ObDatum *unit = NULL;
|
||||
if (OB_FAIL(expr.eval_param_value(eval_ctx_, date, interval, unit))) {
|
||||
LOG_WARN("eval param value failed");
|
||||
} else if (OB_UNLIKELY(date->is_null() || interval->is_null())) {
|
||||
is_valid = false;
|
||||
} else {
|
||||
ObString interval_val = interval->get_string();
|
||||
int64_t unit_value = unit->get_int();
|
||||
ObDateUnitType unit_val = static_cast<ObDateUnitType>(unit_value);
|
||||
ObInterval interval_time;
|
||||
if (OB_FAIL(ObTimeConverter::str_to_ob_interval(interval_val, unit_val, interval_time))) {
|
||||
if (OB_UNLIKELY(OB_INVALID_DATE_VALUE == ret)) {
|
||||
ret = OB_SUCCESS;
|
||||
} else {
|
||||
LOG_WARN("failed to convert string to ob interval", K(ret));
|
||||
}
|
||||
} else {
|
||||
is_valid = !(DT_MODE_NEG & interval_time.mode_);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !is_valid) {
|
||||
ret = OB_ERR_WINDOW_FRAME_ILLEGAL;
|
||||
LOG_WARN("frame start or end is negative, NULL or of non-integral type", K(ret), KPC(interval), KPC(unit));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
@ -822,7 +822,8 @@ protected:
|
||||
// shanting attention!
|
||||
inline int64_t get_part_end_idx() const { return input_rows_.cur_->count() - 1; }
|
||||
static int get_param_int_value(ObExpr &expr, ObEvalCtx &eval_ctx, bool &is_null, int64_t &value,
|
||||
const bool need_number_type = false);
|
||||
const bool need_number_type = false,
|
||||
const bool need_check_valid = false);
|
||||
int parallel_winbuf_process();
|
||||
int get_whole_msg(bool is_end, ObWinbufWholeMsg &whole,
|
||||
const ObRADatumStore::StoredRow *row = NULL);
|
||||
@ -897,6 +898,7 @@ protected:
|
||||
const ObChunkDatumStore::StoredRow *row_, uint64_t &hash_value);
|
||||
int detect_aggr_status();
|
||||
bool skip_calc(const int64_t wf_idx);
|
||||
int check_interval_valid(ObExpr &expr);
|
||||
|
||||
private:
|
||||
// disallow copy
|
||||
|
@ -1951,7 +1951,7 @@ COUNT '(' opt_all '*' ')' OVER new_generalized_window_clause
|
||||
$$->type_ = T_WIN_FUN_LAG;
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_WINDOW_FUNCTION, 2, $$, $4);
|
||||
}
|
||||
| NTH_VALUE '(' expr ',' expr ')' opt_from_first_or_last opt_respect_or_ignore_nulls OVER new_generalized_window_clause
|
||||
| NTH_VALUE '(' expr ',' simple_expr ')' opt_from_first_or_last opt_respect_or_ignore_nulls OVER new_generalized_window_clause
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_WIN_FUN_NTH_VALUE, 4, $3, $5, $7, $8);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_WINDOW_FUNCTION, 2, $$, $10);
|
||||
@ -2159,11 +2159,22 @@ PRECEDING
|
||||
;
|
||||
|
||||
win_interval:
|
||||
expr
|
||||
INTNUM
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_WIN_INTERVAL, 1, $1);
|
||||
$$->value_ = 1;
|
||||
}
|
||||
| DECIMAL_VAL
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_WIN_INTERVAL, 1, $1);
|
||||
$$->value_ = 1;
|
||||
}
|
||||
| UNBOUNDED
|
||||
{
|
||||
get_non_reserved_node($$, result->malloc_pool_, @1.first_column, @1.last_column);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_WIN_INTERVAL, 1, $$);
|
||||
$$->value_ = 1;
|
||||
}
|
||||
| INTERVAL expr date_unit
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_WIN_INTERVAL, 2, $2, $3);
|
||||
|
@ -4899,7 +4899,8 @@ int ObSelectResolver::resolve_column_ref_expr(
|
||||
LOG_WARN("session info is null");
|
||||
} else if (OB_FALSE_IT(const_cast<ObQualifiedName&>(q_name).current_resolve_level_ = current_level_)) {
|
||||
|
||||
} else if (q_name.parents_expr_info_.has_member(IS_AGG)) {
|
||||
} else if (q_name.parents_expr_info_.has_member(IS_AGG) &&
|
||||
!q_name.parents_expr_info_.has_member(IS_WINDOW_FUNC)) {
|
||||
const_cast<ObQualifiedName&>(q_name).parent_aggr_level_ = current_level_;
|
||||
} else {
|
||||
const_cast<ObQualifiedName&>(q_name).parent_aggr_level_ = parent_aggr_level_;
|
||||
|
@ -56,7 +56,10 @@ public:
|
||||
virtual ObSelectStmt *get_child_stmt() { return get_select_stmt(); }
|
||||
virtual bool is_select_resolver() const { return true; }
|
||||
inline bool can_produce_aggr() const
|
||||
{ return T_FIELD_LIST_SCOPE == current_scope_ || T_HAVING_SCOPE == current_scope_ || T_ORDER_SCOPE == current_scope_; }
|
||||
{ return T_FIELD_LIST_SCOPE == current_scope_ ||
|
||||
T_HAVING_SCOPE == current_scope_ ||
|
||||
T_ORDER_SCOPE == current_scope_ ||
|
||||
T_NAMED_WINDOWS_SCOPE == current_scope_; }
|
||||
int add_aggr_expr(ObAggFunRawExpr *&final_aggr_expr);
|
||||
int add_unsettled_column(ObRawExpr *column_expr);
|
||||
void set_in_set_query(bool in_set_query) { in_set_query_ = in_set_query; }
|
||||
|
@ -5087,6 +5087,9 @@ int ObWindow::assign(const ObWindow &other)
|
||||
LOG_WARN("failed to assign order items", K(ret));
|
||||
} else if (OB_FAIL(ObFrame::assign(other))) {
|
||||
LOG_WARN("failed to assign frame", K(ret));
|
||||
} else {
|
||||
win_name_ = other.win_name_;
|
||||
has_frame_orig_ = other.has_frame_orig_;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -4305,7 +4305,7 @@ public:
|
||||
ObRawExpr *date_unit_expr_;
|
||||
|
||||
ObRawExpr *exprs_[BOUND_EXPR_MAX];
|
||||
TO_STRING_KV(K_(type), K_(is_preceding), K_(is_nmb_literal), KP_(interval_expr),
|
||||
TO_STRING_KV(K_(type), K_(is_preceding), K_(is_nmb_literal), KPC_(interval_expr),
|
||||
K_(date_unit_expr));
|
||||
};
|
||||
|
||||
|
@ -2429,6 +2429,20 @@ int ObRawExprDeduceType::visit(ObWinFunRawExpr &expr)
|
||||
} else {
|
||||
func_params.at(0) = cast_expr;
|
||||
}
|
||||
} else if (OB_UNLIKELY(lib::is_mysql_mode() &&
|
||||
(!func_params.at(0)->is_const_expr() ||
|
||||
!func_params.at(0)->get_result_type().is_integer_type()))) {
|
||||
if (func_params.at(0)->get_expr_type() == T_FUN_SYS_FLOOR &&
|
||||
func_params.at(0)->get_param_count() >= 1 &&
|
||||
func_params.at(0)->get_param_expr(0) != NULL &&
|
||||
func_params.at(0)->get_param_expr(0)->get_expr_type() == T_REF_QUERY &&
|
||||
func_params.at(0)->get_param_expr(0)->get_result_type().is_integer_type()) {
|
||||
//do nothing
|
||||
} else {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Incorrect arguments to ntile", K(ret), KPC(func_params.at(0)));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "ntile");
|
||||
}
|
||||
}
|
||||
} else if (T_WIN_FUN_NTH_VALUE == expr.get_func_type()) {
|
||||
// nth_value函数的返回类型可以为null. lead和lag也是
|
||||
@ -2600,6 +2614,31 @@ int ObRawExprDeduceType::visit(ObWinFunRawExpr &expr)
|
||||
LOG_WARN("interval is not numberic", K(ret), KPC(expr.lower_.interval_expr_));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) &&
|
||||
lib::is_mysql_mode() &&
|
||||
expr.get_window_type() == WINDOW_RANGE &&
|
||||
(expr.upper_.interval_expr_ != NULL || expr.lower_.interval_expr_ != NULL)) {
|
||||
if (expr.get_order_items().empty()) {
|
||||
//do nothing
|
||||
} else if (OB_UNLIKELY(expr.get_order_items().count() != 1)) {
|
||||
ret = OB_ERR_INVALID_WINDOW_FUNC_USE;
|
||||
LOG_WARN("invalid window specification", K(ret), K(expr.get_order_items()));
|
||||
} else if (OB_UNLIKELY(((expr.upper_.interval_expr_ != NULL && !expr.upper_.is_nmb_literal_) ||
|
||||
(expr.lower_.interval_expr_ != NULL && !expr.lower_.is_nmb_literal_)) &&
|
||||
expr.get_order_items().at(0).expr_->get_result_type().is_numeric_type())) {
|
||||
ret = OB_ERR_WINDOW_RANGE_FRAME_NUMERIC_TYPE;
|
||||
LOG_WARN("Window with RANGE frame has ORDER BY expression of numeric type. INTERVAL bound value not allowed.", K(ret));
|
||||
ObString tmp_name = expr.get_win_name().empty() ? ObString("<unnamed window>") : expr.get_win_name();
|
||||
LOG_USER_ERROR(OB_ERR_WINDOW_RANGE_FRAME_NUMERIC_TYPE, tmp_name.length(), tmp_name.ptr());
|
||||
} else if (OB_UNLIKELY(((expr.upper_.interval_expr_ != NULL && expr.upper_.is_nmb_literal_) ||
|
||||
(expr.lower_.interval_expr_ != NULL && expr.lower_.is_nmb_literal_)) &&
|
||||
expr.get_order_items().at(0).expr_->get_result_type().is_temporal_type())) {
|
||||
ret = OB_ERR_WINDOW_RANGE_FRAME_TEMPORAL_TYPE;
|
||||
LOG_WARN("Window with RANGE frame has ORDER BY expression of datetime type. Only INTERVAL bound value allowed.", K(ret));
|
||||
ObString tmp_name = expr.get_win_name().empty() ? ObString("<unnamed window>") : expr.get_win_name();
|
||||
LOG_USER_ERROR(OB_ERR_WINDOW_RANGE_FRAME_TEMPORAL_TYPE, tmp_name.length(), tmp_name.ptr());
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("finish add cast for window function", K(result_number_type), K(expr.lower_), K(expr.upper_));
|
||||
}
|
||||
|
||||
|
@ -3850,7 +3850,14 @@ int ObRawExprPrinter::print_window_clause(ObWinFunRawExpr *expr)
|
||||
} else if (BoundType::BOUND_CURRENT_ROW == expr->get_upper().type_) {
|
||||
DATA_PRINTF(" CURRENT ROW ");
|
||||
} else if (BoundType::BOUND_INTERVAL == expr->get_upper().type_) {
|
||||
if (!expr->get_upper().is_nmb_literal_) {
|
||||
DATA_PRINTF(" INTERVAL ");
|
||||
}
|
||||
PRINT_EXPR(expr->get_upper().interval_expr_);
|
||||
if (!expr->get_upper().is_nmb_literal_) {
|
||||
DATA_PRINTF(" ");
|
||||
PRINT_EXPR(expr->get_upper().date_unit_expr_);
|
||||
}
|
||||
if (expr->get_upper().is_preceding_) {
|
||||
DATA_PRINTF(" PRECEDING ");
|
||||
} else {
|
||||
@ -3868,7 +3875,14 @@ int ObRawExprPrinter::print_window_clause(ObWinFunRawExpr *expr)
|
||||
} else if (BoundType::BOUND_CURRENT_ROW == expr->get_lower().type_) {
|
||||
DATA_PRINTF(" CURRENT ROW ");
|
||||
} else if (BoundType::BOUND_INTERVAL == expr->get_lower().type_) {
|
||||
if (!expr->get_lower().is_nmb_literal_) {
|
||||
DATA_PRINTF(" INTERVAL ");
|
||||
}
|
||||
PRINT_EXPR(expr->get_lower().interval_expr_);
|
||||
if (!expr->get_lower().is_nmb_literal_) {
|
||||
DATA_PRINTF(" ");
|
||||
PRINT_EXPR(expr->get_lower().date_unit_expr_);
|
||||
}
|
||||
if (expr->get_lower().is_preceding_) {
|
||||
DATA_PRINTF(" PRECEDING ");
|
||||
} else {
|
||||
|
@ -6419,6 +6419,12 @@ int ObRawExprResolverImpl::process_window_function_node(const ParseNode *node, O
|
||||
LOG_WARN("fail to add param expr", K(ret));
|
||||
} else if (OB_FAIL(func_params.push_back(n_expr))) {
|
||||
LOG_WARN("fail to add param expr", K(ret));
|
||||
} else if (OB_FAIL(n_expr->extract_info())) {
|
||||
LOG_WARN("faield to extract info", K(ret));
|
||||
} else if (OB_UNLIKELY(lib::is_mysql_mode() && !n_expr->is_const_expr())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arguments to nth_value", K(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "nth_value");
|
||||
} else {
|
||||
win_func->set_is_from_first(NULL == func_node->children_[2] || T_FIRST == func_node->children_[2]->type_);
|
||||
win_func->set_is_ignore_null(!(NULL == func_node->children_[3] || T_RESPECT == func_node->children_[3]->type_));
|
||||
@ -6535,10 +6541,16 @@ int ObRawExprResolverImpl::process_window_function_node(const ParseNode *node, O
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(OB_SUCC(ret) && NULL == named_win) {
|
||||
if (OB_SUCC(ret) && NULL == named_win) {
|
||||
ret = OB_ERR_WINDOW_NAME_IS_NOT_DEFINE;
|
||||
LOG_WARN("name win not exist", K(name), K(ret), K(named_windows));
|
||||
LOG_USER_ERROR(OB_ERR_WINDOW_NAME_IS_NOT_DEFINE, name.length(), name.ptr());
|
||||
} else if (OB_UNLIKELY(ctx_.current_scope_ == T_NAMED_WINDOWS_SCOPE &&
|
||||
named_win->has_frame_orig())) {
|
||||
ret = OB_EER_WINDOW_NO_INHERIT_FRAME;
|
||||
LOG_WARN("Named window cann't be modified by another framing property", K(ret));
|
||||
ObString tmp_name = named_win->get_win_name().empty() ? ObString("<unnamed window>") : named_win->get_win_name();
|
||||
LOG_USER_ERROR(OB_EER_WINDOW_NO_INHERIT_FRAME, tmp_name.length(), tmp_name.ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6676,6 +6688,13 @@ int ObRawExprResolverImpl::process_window_function_node(const ParseNode *node, O
|
||||
if (OB_SUCC(ret) && NULL != frame_node) {
|
||||
if (OB_FAIL(process_frame_node(frame_node, frame))) {
|
||||
LOG_WARN("process window node failed", K(ret));
|
||||
} else if (lib::is_mysql_mode() &&
|
||||
OB_UNLIKELY((frame.get_upper().interval_expr_ != NULL && !frame.get_upper().interval_expr_->is_const_expr()) ||
|
||||
(frame.get_lower().interval_expr_ != NULL && !frame.get_lower().interval_expr_->is_const_expr()))) {
|
||||
ret = OB_ERR_WINDOW_RANGE_BOUND_NOT_CONSTANT;
|
||||
LOG_WARN("Window has a non-constant frame bound.", K(ret), KPC(frame.get_upper().interval_expr_), KPC(frame.get_lower().interval_expr_));
|
||||
ObString tmp_name = named_win == NULL ? ObString("<unnamed window>") : named_win->get_win_name();
|
||||
LOG_USER_ERROR(OB_ERR_WINDOW_RANGE_BOUND_NOT_CONSTANT, tmp_name.length(), tmp_name.ptr());
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -6914,6 +6933,8 @@ int ObRawExprResolverImpl::process_interval_node(const ParseNode *node,
|
||||
} else if (OB_ISNULL(interval_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("NULL ptr", K(ret), K(interval_expr));
|
||||
} else if (OB_FAIL(interval_expr->extract_info())) {
|
||||
LOG_WARN("fail to extract info", K(interval_expr), K(ret));
|
||||
} else if (!is_nmb_literal) {
|
||||
// date type
|
||||
ParseNode *date_unit_node = node->children_[1];
|
||||
@ -6922,8 +6943,10 @@ int ObRawExprResolverImpl::process_interval_node(const ParseNode *node,
|
||||
} else if (OB_ISNULL(date_unit_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("NULL ptr", K(ret), K(date_unit_expr));
|
||||
} else if (OB_FAIL(date_unit_expr->extract_info())) {
|
||||
LOG_WARN("fail to extract info", K(interval_expr), K(ret));
|
||||
} else if (!date_unit_expr->is_const_raw_expr()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("not const expr error", K(ret), K(date_unit_expr->get_expr_type()));
|
||||
} else {/*do nothing*/}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user