[CP] fix multiple type inferences with different result type when space expr input argument is string literal
This commit is contained in:
parent
acba5dcdcd
commit
c673714910
@ -35,25 +35,38 @@ inline int ObExprSpace::calc_result_type1(
|
||||
ObExprTypeCtx &type_ctx) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObRawExpr * raw_expr = nullptr;
|
||||
ObRawExpr * child_raw_expr = nullptr;
|
||||
// space is mysql only expr
|
||||
CK(lib::is_mysql_mode());
|
||||
ObObjType res_type = ObMaxType;
|
||||
if (type1.is_null() || (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_0_0)) {
|
||||
res_type = ObVarcharType;
|
||||
} else if (type1.is_literal()) {
|
||||
const ObObj &obj = type1.get_param();
|
||||
ObArenaAllocator alloc(ObModIds::OB_SQL_RES_TYPE);
|
||||
const ObDataTypeCastParams dtc_params = type_ctx.get_dtc_params();
|
||||
int64_t cur_time = 0;
|
||||
ObCastMode cast_mode = CM_NONE;
|
||||
if (FALSE_IT(ObSQLUtils::get_default_cast_mode(type_ctx.get_sql_mode(), cast_mode))) {
|
||||
} else {
|
||||
cast_mode |= CM_WARN_ON_FAIL;
|
||||
ObCastCtx cast_ctx(
|
||||
&alloc, &dtc_params, cur_time, cast_mode, CS_TYPE_INVALID);
|
||||
int64_t count_val = 0;
|
||||
EXPR_GET_INT64_V2(obj, count_val);
|
||||
res_type = get_result_type_mysql(count_val);
|
||||
if (OB_FAIL(calc_result_type(type_ctx, type1.get_param(), res_type))) {
|
||||
LOG_WARN("calc_result_type fail", K(ret), K(type1), K(type_ctx));
|
||||
}
|
||||
} else if (OB_ISNULL(raw_expr = type_ctx.get_raw_expr())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("raw_expr is null", K(ret), K(type_ctx));
|
||||
} else if (OB_ISNULL(child_raw_expr = raw_expr->get_param_expr(0))) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("get child expr fail", K(ret), KPC(raw_expr), K(type_ctx));
|
||||
} else if (T_FUN_SYS_CAST == child_raw_expr->get_expr_type()
|
||||
&& child_raw_expr->has_flag(IS_OP_OPERAND_IMPLICIT_CAST)
|
||||
&& child_raw_expr->get_param_expr(0)->get_result_type().is_literal()) {
|
||||
// some scenarios may have multiple type inferences
|
||||
// if the input is a string literal, the first inference will add an implicit cast to convert a string to an integer
|
||||
// this makes the input type not literal in the second type inference, resulting in an inference to longtext
|
||||
// this in turn causes multiple implicit cast to be added to the same expr
|
||||
// so need to make a special judgment here
|
||||
// eg :
|
||||
// create table space_t1(c1 char(181) default (space( '1')));
|
||||
// select c1 from space_t1;
|
||||
if (child_raw_expr->get_param_expr(0)->get_result_type().is_null()) {
|
||||
res_type = ObVarcharType;
|
||||
} else if (OB_FAIL(calc_result_type(type_ctx, child_raw_expr->get_param_expr(0)->get_result_type().get_param(), res_type))) {
|
||||
LOG_WARN("calc_result_type fail", K(ret), K(type1), K(type_ctx));
|
||||
}
|
||||
} else {
|
||||
res_type = ObLongTextType;
|
||||
@ -80,6 +93,26 @@ inline int ObExprSpace::calc_result_type1(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSpace::calc_result_type(ObExprTypeCtx &type_ctx, const ObObj &obj, ObObjType &res_type) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObArenaAllocator alloc(ObModIds::OB_SQL_RES_TYPE);
|
||||
const ObDataTypeCastParams dtc_params = type_ctx.get_dtc_params();
|
||||
int64_t cur_time = 0;
|
||||
ObCastMode cast_mode = CM_NONE;
|
||||
// void return function
|
||||
ObSQLUtils::get_default_cast_mode(type_ctx.get_sql_mode(), cast_mode);
|
||||
cast_mode |= CM_WARN_ON_FAIL;
|
||||
ObCastCtx cast_ctx(
|
||||
&alloc, &dtc_params, cur_time, cast_mode, CS_TYPE_INVALID);
|
||||
int64_t count_val = 0;
|
||||
EXPR_GET_INT64_V2(obj, count_val);
|
||||
if (OB_SUCC(ret)) {
|
||||
res_type = get_result_type_mysql(count_val);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSpace::cg_expr(ObExprCGCtx &, const ObRawExpr &, ObExpr &rt_expr) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -37,6 +37,8 @@ public:
|
||||
static int eval_space(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum);
|
||||
DECLARE_SET_LOCAL_SESSION_VARS;
|
||||
private:
|
||||
int calc_result_type(ObExprTypeCtx &type_ctx, const ObObj &obj, ObObjType &res_type) const;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ObExprSpace);
|
||||
};
|
||||
|
||||
|
@ -92,3 +92,61 @@ select * from t1 where space(c1) = '';
|
||||
drop table if exists t1;
|
||||
drop database if exists luofan;
|
||||
|
||||
drop table if exists space_t1;
|
||||
drop table if exists space_t2;
|
||||
create table space_t1(c1 char(181) default (space( '1')), c2 int);
|
||||
select * from space_t1;
|
||||
+------+------+
|
||||
| c1 | c2 |
|
||||
+------+------+
|
||||
+------+------+
|
||||
insert into space_t1(c2) values(1);
|
||||
select * from space_t1;
|
||||
+------+------+
|
||||
| c1 | c2 |
|
||||
+------+------+
|
||||
| | 1 |
|
||||
+------+------+
|
||||
|
||||
create table space_t2 as select space('1') as c1 from space_t1;
|
||||
desc space_t2;
|
||||
+-------+--------------+------+-----+---------+-------+
|
||||
| Field | Type | Null | Key | Default | Extra |
|
||||
+-------+--------------+------+-----+---------+-------+
|
||||
| c1 | varchar(512) | YES | | NULL | |
|
||||
+-------+--------------+------+-----+---------+-------+
|
||||
drop table space_t2;
|
||||
|
||||
create table space_t2 as select space('1024') as c1 from space_t1;
|
||||
desc space_t2;
|
||||
+-------+------+------+-----+---------+-------+
|
||||
| Field | Type | Null | Key | Default | Extra |
|
||||
+-------+------+------+-----+---------+-------+
|
||||
| c1 | text | YES | | NULL | |
|
||||
+-------+------+------+-----+---------+-------+
|
||||
drop table space_t2;
|
||||
|
||||
create table space_t2 as select space(NULL) as c1 from space_t1;
|
||||
desc space_t2;
|
||||
+-------+--------------+------+-----+---------+-------+
|
||||
| Field | Type | Null | Key | Default | Extra |
|
||||
+-------+--------------+------+-----+---------+-------+
|
||||
| c1 | varchar(512) | YES | | NULL | |
|
||||
+-------+--------------+------+-----+---------+-------+
|
||||
drop table space_t2;
|
||||
|
||||
drop table space_t1;
|
||||
create table space_t1(c1 char(181) default (space(NULL)), c2 int);
|
||||
select * from space_t1;
|
||||
+------+------+
|
||||
| c1 | c2 |
|
||||
+------+------+
|
||||
+------+------+
|
||||
insert into space_t1(c2) values(1);
|
||||
select * from space_t1;
|
||||
+------+------+
|
||||
| c1 | c2 |
|
||||
+------+------+
|
||||
| NULL | 1 |
|
||||
+------+------+
|
||||
drop table space_t1;
|
||||
|
@ -64,3 +64,34 @@ drop database if exists luofan;
|
||||
--enable_warnings
|
||||
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists space_t1;
|
||||
drop table if exists space_t2;
|
||||
--enable_warnings
|
||||
|
||||
create table space_t1(c1 char(181) default (space( '1')), c2 int);
|
||||
select * from space_t1;
|
||||
insert into space_t1(c2) values(1);
|
||||
select * from space_t1;
|
||||
|
||||
create table space_t2 as select space('1') as c1 from space_t1;
|
||||
# c1 is varchar type
|
||||
desc space_t2;
|
||||
drop table space_t2;
|
||||
|
||||
create table space_t2 as select space('1024') as c1 from space_t1;
|
||||
# c1 is text type
|
||||
desc space_t2;
|
||||
drop table space_t2;
|
||||
|
||||
create table space_t2 as select space(NULL) as c1 from space_t1;
|
||||
# c1 is varchar type
|
||||
desc space_t2;
|
||||
drop table space_t2;
|
||||
|
||||
drop table space_t1;
|
||||
create table space_t1(c1 char(181) default (space(NULL)), c2 int);
|
||||
select * from space_t1;
|
||||
insert into space_t1(c2) values(1);
|
||||
select * from space_t1;
|
||||
drop table space_t1;
|
Loading…
x
Reference in New Issue
Block a user