When sql_mode='ALLOW_INVALID_DATES', the align_date4cmp remains compatible with previous versions of OB
This commit is contained in:
@ -141,6 +141,7 @@ int ObExprAlignDate4Cmp::eval_align_date4cmp(const ObExpr &expr, ObEvalCtx &ctx,
|
|||||||
const bool is_zero_on_warn = CM_IS_ZERO_ON_WARN(expr.extra_);
|
const bool is_zero_on_warn = CM_IS_ZERO_ON_WARN(expr.extra_);
|
||||||
const bool is_no_zero_date = CM_IS_NO_ZERO_DATE(expr.extra_);
|
const bool is_no_zero_date = CM_IS_NO_ZERO_DATE(expr.extra_);
|
||||||
const bool is_warn_on_fail = CM_IS_WARN_ON_FAIL(expr.extra_);
|
const bool is_warn_on_fail = CM_IS_WARN_ON_FAIL(expr.extra_);
|
||||||
|
const bool is_allow_invalid_dates = CM_IS_ALLOW_INVALID_DATES(expr.extra_);
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
switch(date_arg_type) {
|
switch(date_arg_type) {
|
||||||
case VALID_DATE: {
|
case VALID_DATE: {
|
||||||
@ -155,30 +156,28 @@ int ObExprAlignDate4Cmp::eval_align_date4cmp(const ObExpr &expr, ObEvalCtx &ctx,
|
|||||||
case INVALID_DATE: {
|
case INVALID_DATE: {
|
||||||
bool is_valid_time = false;
|
bool is_valid_time = false;
|
||||||
int cmp_type = cmp_type_datum->get_int();
|
int cmp_type = cmp_type_datum->get_int();
|
||||||
// if cmp_type == T_OP_EQ or T_OP_NSEQ or T_OP_NE,
|
|
||||||
// return null or 0 depending on is_zero_on_warn.
|
|
||||||
if (cmp_type == T_OP_EQ || cmp_type == T_OP_NSEQ || cmp_type == T_OP_NE) {
|
if (cmp_type == T_OP_EQ || cmp_type == T_OP_NSEQ || cmp_type == T_OP_NE) {
|
||||||
if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
|
// Compatible with previous versions of ob, not with mysql
|
||||||
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
|
if (is_allow_invalid_dates) {
|
||||||
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type),
|
int32_t offset = get_day_over_limit(ob_time);
|
||||||
K(date_arg_type), K(is_valid_time));
|
if (offset > 0) {
|
||||||
|
push_back_n_days(ob_time, offset);
|
||||||
|
is_valid_time = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else { // cmp_type is: >, >=, <, <=
|
||||||
if (day_over_limit(ob_time)) {
|
// Compatible with mysql, not with previous versions of ob
|
||||||
|
if (is_day_over_limit(ob_time)) {
|
||||||
offset = (cmp_type == T_OP_GT || cmp_type == T_OP_LE) ? false : true;
|
offset = (cmp_type == T_OP_GT || cmp_type == T_OP_LE) ? false : true;
|
||||||
set_valid_time_floor(ob_time);
|
set_valid_time_floor(ob_time);
|
||||||
is_valid_time = true;
|
is_valid_time = true;
|
||||||
if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
|
|
||||||
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
|
|
||||||
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type),
|
|
||||||
K(date_arg_type), K(is_valid_time));
|
|
||||||
}
|
|
||||||
} else if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
|
|
||||||
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
|
|
||||||
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type),
|
|
||||||
K(date_arg_type), K(is_valid_time));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
|
||||||
|
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
|
||||||
|
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type),
|
||||||
|
K(date_arg_type), K(is_valid_time));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NON_DATE: {
|
case NON_DATE: {
|
||||||
@ -205,6 +204,17 @@ int ObExprAlignDate4Cmp::eval_align_date4cmp(const ObExpr &expr, ObEvalCtx &ctx,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Because the date greater than 31 will be considered as NON_DATE,
|
||||||
|
// the maximum number of days to be pushed back in this case is 31-28=3.
|
||||||
|
// For year and month, the maximum pushback is limited to 1.
|
||||||
|
void ObExprAlignDate4Cmp::push_back_n_days(ObTime &ob_time, int32_t offset)
|
||||||
|
{
|
||||||
|
ob_time.parts_[DT_YEAR] += ob_time.parts_[DT_MON] / MONTHS_PER_YEAR;
|
||||||
|
ob_time.parts_[DT_MON] = (ob_time.parts_[DT_MON] + 1) % MONTHS_PER_YEAR;
|
||||||
|
ob_time.parts_[DT_MDAY] = offset;
|
||||||
|
ob_time.parts_[DT_DATE] = ObTimeConverter::ob_time_to_date(ob_time);
|
||||||
|
}
|
||||||
|
|
||||||
void ObExprAlignDate4Cmp::set_valid_time_floor(ObTime &ob_time)
|
void ObExprAlignDate4Cmp::set_valid_time_floor(ObTime &ob_time)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
@ -222,7 +232,7 @@ void ObExprAlignDate4Cmp::set_valid_time_floor(ObTime &ob_time)
|
|||||||
ob_time.parts_[DT_DATE] = ObTimeConverter::ob_time_to_date(ob_time);
|
ob_time.parts_[DT_DATE] = ObTimeConverter::ob_time_to_date(ob_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObExprAlignDate4Cmp::day_over_limit(const ObTime &ob_time)
|
bool ObExprAlignDate4Cmp::is_day_over_limit(const ObTime &ob_time)
|
||||||
{
|
{
|
||||||
bool res = true;
|
bool res = true;
|
||||||
if (ob_time.parts_[DT_MON] < 1 || ob_time.parts_[DT_MON] > 12) {
|
if (ob_time.parts_[DT_MON] < 1 || ob_time.parts_[DT_MON] > 12) {
|
||||||
@ -235,6 +245,18 @@ bool ObExprAlignDate4Cmp::day_over_limit(const ObTime &ob_time)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t ObExprAlignDate4Cmp::get_day_over_limit(const ObTime &ob_time)
|
||||||
|
{
|
||||||
|
int32_t res = 0;
|
||||||
|
if (ob_time.parts_[DT_MON] < 1 || ob_time.parts_[DT_MON] > 12) {
|
||||||
|
} else if(IS_LEAP_YEAR(ob_time.parts_[DT_YEAR])) {
|
||||||
|
res = ob_time.parts_[DT_MDAY] - DAYS_OF_MON[1][ob_time.parts_[DT_MON]];
|
||||||
|
} else {
|
||||||
|
res = ob_time.parts_[DT_MDAY] - DAYS_OF_MON[0][ob_time.parts_[DT_MON]];
|
||||||
|
}
|
||||||
|
return res > 0 ? res : 0;
|
||||||
|
}
|
||||||
|
|
||||||
ObExprAlignDate4Cmp::DateArgType ObExprAlignDate4Cmp::validate_time(ObTime &ob_time)
|
ObExprAlignDate4Cmp::DateArgType ObExprAlignDate4Cmp::validate_time(ObTime &ob_time)
|
||||||
{
|
{
|
||||||
DateArgType date_arg_type = VALID_DATE;
|
DateArgType date_arg_type = VALID_DATE;
|
||||||
|
|||||||
@ -59,8 +59,10 @@ private:
|
|||||||
//disallow copy
|
//disallow copy
|
||||||
DISALLOW_COPY_AND_ASSIGN(ObExprAlignDate4Cmp);
|
DISALLOW_COPY_AND_ASSIGN(ObExprAlignDate4Cmp);
|
||||||
|
|
||||||
static bool day_over_limit(const ObTime &ob_time);
|
static bool is_day_over_limit(const ObTime &ob_time);
|
||||||
|
static int32_t get_day_over_limit(const ObTime &ob_time);
|
||||||
static void set_valid_time_floor(ObTime &ob_time);
|
static void set_valid_time_floor(ObTime &ob_time);
|
||||||
|
static void push_back_n_days(ObTime &ob_time, int32_t offset);
|
||||||
static DateArgType validate_time(ObTime &ob_time);
|
static DateArgType validate_time(ObTime &ob_time);
|
||||||
static int integer_to_ob_time(const int64_t &date, DateArgType &date_arg_type, ObTime &ob_time);
|
static int integer_to_ob_time(const int64_t &date, DateArgType &date_arg_type, ObTime &ob_time);
|
||||||
static int double_to_ob_time(const double &date, DateArgType &date_arg_type, ObTime &ob_time);
|
static int double_to_ob_time(const double &date, DateArgType &date_arg_type, ObTime &ob_time);
|
||||||
|
|||||||
Reference in New Issue
Block a user