Fix date/datetime comparision bug and fix failed mysqltests

This commit is contained in:
obdev
2022-11-22 08:08:55 +00:00
committed by wangzelin.wzl
parent 5f8b94eb45
commit 3772f41232
3 changed files with 58 additions and 23 deletions

View File

@ -148,7 +148,8 @@ public:
session_(NULL),
udf_meta_(NULL),
cast_mode_(CM_NONE),
raw_expr_(NULL)
raw_expr_(NULL),
cur_row_idx_(0)
{}
inline ObCollationType get_coll_type() const {
@ -196,6 +197,9 @@ public:
void set_raw_expr(sql::ObRawExpr *expr) { raw_expr_ = expr; }
sql::ObRawExpr *get_raw_expr() { return raw_expr_; }
inline void set_cur_row_idx(int64_t cur_row_idx) { cur_row_idx_ = cur_row_idx; }
inline int64_t get_cur_row_idx() { return cur_row_idx_; }
TO_STRING_KV(K_(coll_type),
K_(div_precision_increment),
K_(ob_max_allowed_packet),
@ -215,6 +219,8 @@ private:
// Usually need to override get_cast_mode() of ObExprOperator which works for non_static engine
common::ObCastMode cast_mode_;
sql::ObRawExpr *raw_expr_;
//used to switch params in subquery comparison operators
int64_t cur_row_idx_;
};
class ObISqlExpression

View File

@ -31,6 +31,7 @@
#include "sql/engine/expr/ob_expr_util.h"
#include "sql/engine/subquery/ob_subplan_filter_op.h"
#include "lib/timezone/ob_oracle_format_models.h"
#include "sql/resolver/dml/ob_select_stmt.h"
namespace oceanbase
{
@ -2127,29 +2128,55 @@ int ObRelationalExprOperator::deduce_cmp_type(const ObExprOperator &expr,
const ObRawExpr* other_expr = cmp_expr->get_param_expr(1);
ObObjType other_expr_type = ObMaxType;
bool is_date_op_other = false;
if (OB_ISNULL(cmp_expr) || OB_ISNULL(date_expr) || OB_ISNULL(other_expr)) {
if (OB_ISNULL(cmp_expr) || OB_ISNULL(date_expr) || OB_ISNULL(other_expr) ) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), K(cmp_expr));
} else if (date_expr->get_result_type().get_type() == ObDateType ||
date_expr->get_result_type().get_type() == ObDateTimeType) {
other_expr_type = other_expr->get_result_type().get_type();
is_date_op_other = true;
} else if (other_expr->get_result_type().get_type() == ObDateType ||
other_expr->get_result_type().get_type() == ObDateTimeType) {
const ObRawExpr *tmp_expr = date_expr;
date_expr = other_expr;
other_expr = tmp_expr;
other_expr_type = other_expr->get_result_type().get_type();
is_date_op_other = true;
LOG_WARN("unexpected null", K(ret), K(cmp_expr), K(date_expr), K(other_expr));
} else {
//do nothing
if (T_REF_QUERY == other_expr->get_expr_type()) {
const ObQueryRefRawExpr *ref_expr = static_cast<const ObQueryRefRawExpr*>(other_expr);
if (OB_ISNULL(ref_expr->get_ref_stmt())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret));
} else {
other_expr = ref_expr->get_ref_stmt()->get_select_item(type_ctx.get_cur_row_idx()).expr_;
}
} else if (T_OP_ROW == other_expr->get_expr_type()) {
other_expr = other_expr->get_param_expr(type_ctx.get_cur_row_idx());
}
if (OB_FAIL(ret)) {
} else if (T_REF_QUERY == date_expr->get_expr_type()) {
const ObQueryRefRawExpr *ref_expr = static_cast<const ObQueryRefRawExpr*>(date_expr);
if (OB_ISNULL(ref_expr->get_ref_stmt())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret));
} else {
date_expr = ref_expr->get_ref_stmt()->get_select_item(type_ctx.get_cur_row_idx()).expr_;
}
} else if (T_OP_ROW == date_expr->get_expr_type()) {
date_expr = date_expr->get_param_expr(type_ctx.get_cur_row_idx());
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(date_expr) || OB_ISNULL(other_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), K(date_expr), K(other_expr));
} else if (date_expr->get_result_type().get_type() == ObDateType ||
date_expr->get_result_type().get_type() == ObDateTimeType) {
other_expr_type = other_expr->get_result_type().get_type();
is_date_op_other = true;
} else if (other_expr->get_result_type().get_type() == ObDateType ||
other_expr->get_result_type().get_type() == ObDateTimeType) {
const ObRawExpr *tmp_expr = date_expr;
date_expr = other_expr;
other_expr = tmp_expr;
other_expr_type = other_expr->get_result_type().get_type();
is_date_op_other = true;
} else {
//do nothing
}
}
if (OB_SUCC(ret) &&
is_mysql_mode() &&
is_date_op_other &&
if (OB_SUCC(ret) && is_mysql_mode() && is_date_op_other &&
(ob_is_accurate_numeric_type(other_expr_type) || ob_is_real_type(other_expr_type)) &&
!(other_expr->is_const_expr() && !date_expr->is_const_expr())) {
!(other_expr->is_const_expr() && !date_expr->is_const_expr()) && !other_expr->has_flag(IS_USER_VARIABLE)) {
cmp_type.set_calc_type(ObDoubleType);
type.set_calc_collation(cmp_type);
type.set_calc_type(cmp_type.get_calc_type());
@ -2225,6 +2252,7 @@ int ObRelationalExprOperator::calc_result_typeN(ObExprResType &type,
// 1和'1.00x'会转为int然后比较,'1.00000'和'1.000000'会直接做字符串比较
ObExprResType tmp_res_type;
for (int64_t i = 0; OB_SUCC(ret) && i < row_dimension_; ++i) {
type_ctx.set_cur_row_idx(i);
if (OB_FAIL(ObRelationalExprOperator::calc_result_type2(tmp_res_type,
types[i],
types[i + row_dimension_],
@ -2751,6 +2779,7 @@ int ObSubQueryRelationalExpr::calc_result_typeN(ObExprResType &type,
if (OB_SUCC(ret)) {
for (int64_t i = 0; OB_SUCC(ret) && i < row_dimension_; i++) {
ObExprResType tmp_res_type;
type_ctx.set_cur_row_idx(i);
OZ(ObRelationalExprOperator::deduce_cmp_type(
*this, tmp_res_type, types[i], types[i + row_dimension_], type_ctx));
OZ(type.get_row_calc_cmp_types().push_back(tmp_res_type.get_calc_meta()));

View File

@ -1408,7 +1408,7 @@ Query Plan
Outputs & filters:
-------------------------------------
0 - output([t3.c1], [t3.c2], [t3.c3]), filter([cast(t3.c1, DATETIME(-1, -1)) = cast('2010-10-10 00:00:00', DATETIME(0, 0))], [cast(t3.c1, DECIMAL(20, 0)) = cast(t3.c2, DECIMAL(-1, -1))]), rowset=256,
0 - output([t3.c1], [t3.c2], [t3.c3]), filter([cast(t3.c1, DOUBLE(-1, -1)) = cast(cast('2010-10-10 00:00:00', DATETIME(0, 0)), DOUBLE(-1, -1))], [cast(t3.c1, DECIMAL(20, 0)) = cast(t3.c2, DECIMAL(-1, -1))]), rowset=256,
access([t3.c1], [t3.c2], [t3.c3]), partitions(p0)
select /*+no_rewrite*/* from t3 where c1=c2 and c1=cast('2010-10-10 00:00:00' as datetime);
@ -1427,7 +1427,7 @@ Query Plan
Outputs & filters:
-------------------------------------
0 - output([t3.c1], [t3.c2], [t3.c3]), filter([cast(t3.c1, DATETIME(-1, -1)) = cast('2010-10-10 00:00:00', DATETIME(0, 0))], [cast(t3.c1, DECIMAL(20, 0)) = cast(t3.c2, DECIMAL(-1, -1))]), rowset=256,
0 - output([t3.c1], [t3.c2], [t3.c3]), filter([cast(t3.c1, DOUBLE(-1, -1)) = cast(cast('2010-10-10 00:00:00', DATETIME(0, 0)), DOUBLE(-1, -1))], [cast(t3.c1, DECIMAL(20, 0)) = cast(t3.c2, DECIMAL(-1, -1))]), rowset=256,
access([t3.c1], [t3.c2], [t3.c3]), partitions(p0)
select * from t3 where c1=c2 and c1=cast('2010-10-10 00:00:00' as datetime);
@ -1450,7 +1450,7 @@ Outputs & filters:
-------------------------------------
0 - output(nil), filter(nil), table_columns([{t3: ({t3: (t3.__pk_increment, t3.c1, t3.c2, t3.c3)})}]),
update([t3.c1=column_conv(BIGINT,PS:(20,0),NULL,1)])
1 - output([t3.__pk_increment], [t3.c1], [t3.c2], [t3.c3]), filter([cast(t3.c1, DATETIME(-1, -1)) = cast('2010-10-10 00:00:00', DATETIME(0, 0))], [cast(t3.c1, DECIMAL(20, 0)) = cast(t3.c2, DECIMAL(-1, -1))]), rowset=256,
1 - output([t3.__pk_increment], [t3.c1], [t3.c2], [t3.c3]), filter([cast(t3.c1, DOUBLE(-1, -1)) = cast(cast('2010-10-10 00:00:00', DATETIME(0, 0)), DOUBLE(-1, -1))], [cast(t3.c1, DECIMAL(20, 0)) = cast(t3.c2, DECIMAL(-1, -1))]), rowset=256,
access([t3.__pk_increment], [t3.c1], [t3.c2], [t3.c3]), partitions(p0)
update t3 set c1 = 1 where c1=c2 and c1=cast('2010-10-10 00:00:00' as datetime);