opti:case when else data type compatibility

This commit is contained in:
lyh250-666 2024-10-09 14:16:42 +08:00
parent 066a92e819
commit bab99c7897
3 changed files with 64 additions and 32 deletions

View File

@ -3187,22 +3187,31 @@ static int32_t rewriteIsTrue(SNode* pSrc, SNode** pIsTrue) {
} }
static bool selectCommonType(SDataType* commonType, const SDataType* newType) { static bool selectCommonType(SDataType* commonType, const SDataType* newType) {
if (commonType->type == TSDB_DATA_TYPE_NULL) {//0 if (commonType->type == TSDB_DATA_TYPE_NULL) { // 0 null type
*commonType = *newType; *commonType = *newType;
return true; return true;
} }
if (newType->type == TSDB_DATA_TYPE_NULL) { if (newType->type == TSDB_DATA_TYPE_NULL) {
return true; return true;
} }
// type equal
if (commonType->type == newType->type) { if (commonType->type == newType->type) {
if(commonType->bytes <= newType->bytes) if (commonType->bytes <= newType->bytes) {
*commonType = *newType;
}
return true;
}
// 15 ~ 21 these types are not compatible with other types
if (commonType->type == TSDB_DATA_TYPE_TIMESTAMP || (commonType->type >= TSDB_DATA_TYPE_JSON && commonType->type <= TSDB_DATA_TYPE_MAX)) {
return true;
}
if (newType->type == TSDB_DATA_TYPE_TIMESTAMP || (newType->type >= TSDB_DATA_TYPE_JSON && newType->type <= TSDB_DATA_TYPE_MAX)) {
*commonType = *newType; *commonType = *newType;
return true; return true;
} }
// Numeric types between 1 and 5 (BOOL to BIGINT) // type 1 ~ 5
if ((commonType->type >= TSDB_DATA_TYPE_BOOL && commonType->type <= TSDB_DATA_TYPE_BIGINT) && if ((commonType->type >= TSDB_DATA_TYPE_BOOL && commonType->type <= TSDB_DATA_TYPE_BIGINT) &&
(newType->type >= TSDB_DATA_TYPE_BOOL && newType->type <= TSDB_DATA_TYPE_BIGINT)) { (newType->type >= TSDB_DATA_TYPE_BOOL && newType->type <= TSDB_DATA_TYPE_BIGINT)) {
if (newType->type > commonType->type) { if (newType->type > commonType->type) {
@ -3211,7 +3220,28 @@ static bool selectCommonType(SDataType* commonType, const SDataType* newType) {
return true; return true;
} }
// Unsigned numeric types between 11 and 14 (UTINYINT to UBIGINT) // type 6
if ((commonType->type == TSDB_DATA_TYPE_FLOAT &&
((newType->type >= TSDB_DATA_TYPE_BOOL && newType->type <= TSDB_DATA_TYPE_INT))) ||
(newType->type == TSDB_DATA_TYPE_FLOAT &&
((commonType->type >= TSDB_DATA_TYPE_BOOL && commonType->type <= TSDB_DATA_TYPE_INT)))) {
*commonType = (commonType->type == TSDB_DATA_TYPE_FLOAT) ? *commonType : *newType;
return true;
}
//type 7
if ((commonType->type == TSDB_DATA_TYPE_DOUBLE &&
((newType->type >= TSDB_DATA_TYPE_BOOL && newType->type <= TSDB_DATA_TYPE_BIGINT) ||
newType->type == TSDB_DATA_TYPE_FLOAT ||
newType->type == TSDB_DATA_TYPE_DOUBLE)) ||
(newType->type == TSDB_DATA_TYPE_DOUBLE &&
((commonType->type >= TSDB_DATA_TYPE_BOOL && commonType->type <= TSDB_DATA_TYPE_BIGINT) ||
commonType->type == TSDB_DATA_TYPE_FLOAT ||
commonType->type == TSDB_DATA_TYPE_DOUBLE))) {
*commonType = (commonType->type == TSDB_DATA_TYPE_DOUBLE) ? *commonType : *newType;
return true;
}
// type 11 ~ 14
if ((commonType->type >= TSDB_DATA_TYPE_UTINYINT && commonType->type <= TSDB_DATA_TYPE_UBIGINT) && if ((commonType->type >= TSDB_DATA_TYPE_UTINYINT && commonType->type <= TSDB_DATA_TYPE_UBIGINT) &&
(newType->type >= TSDB_DATA_TYPE_UTINYINT && newType->type <= TSDB_DATA_TYPE_UBIGINT)) { (newType->type >= TSDB_DATA_TYPE_UTINYINT && newType->type <= TSDB_DATA_TYPE_UBIGINT)) {
if (newType->type > commonType->type) { if (newType->type > commonType->type) {
@ -3219,14 +3249,15 @@ static bool selectCommonType(SDataType* commonType, const SDataType* newType) {
} }
return true; return true;
} }
bool commonIsNumeric = ((commonType->type >= TSDB_DATA_TYPE_BOOL && commonType->type <= TSDB_DATA_TYPE_DOUBLE) || bool commonIsNumeric = ((commonType->type >= TSDB_DATA_TYPE_BOOL && commonType->type <= TSDB_DATA_TYPE_DOUBLE) ||
(commonType->type >= TSDB_DATA_TYPE_UTINYINT && commonType->type <= TSDB_DATA_TYPE_UBIGINT)); (commonType->type >= TSDB_DATA_TYPE_UTINYINT && commonType->type <= TSDB_DATA_TYPE_UBIGINT));
bool newIsNumeric = ((newType->type >= TSDB_DATA_TYPE_BOOL && newType->type <= TSDB_DATA_TYPE_DOUBLE) || bool newIsNumeric = ((newType->type >= TSDB_DATA_TYPE_BOOL && newType->type <= TSDB_DATA_TYPE_DOUBLE) ||
(newType->type >= TSDB_DATA_TYPE_UTINYINT && newType->type <= TSDB_DATA_TYPE_UBIGINT)); (newType->type >= TSDB_DATA_TYPE_UTINYINT && newType->type <= TSDB_DATA_TYPE_UBIGINT));
bool commonIsString = (commonType->type == TSDB_DATA_TYPE_VARCHAR || commonType->type == TSDB_DATA_TYPE_NCHAR); bool commonIsString = (commonType->type == TSDB_DATA_TYPE_VARCHAR || commonType->type == TSDB_DATA_TYPE_NCHAR || commonType->type == TSDB_DATA_TYPE_BINARY);
bool newIsString = (newType->type == TSDB_DATA_TYPE_VARCHAR || newType->type == TSDB_DATA_TYPE_NCHAR); bool newIsString = (newType->type == TSDB_DATA_TYPE_VARCHAR || newType->type == TSDB_DATA_TYPE_NCHAR || commonType->type == TSDB_DATA_TYPE_BINARY);
// num and string
if ((commonIsNumeric && newIsString) || (commonIsString && newIsNumeric)) { if ((commonIsNumeric && newIsString) || (commonIsString && newIsNumeric)) {
if (commonIsString) { if (commonIsString) {
return true; return true;
@ -3235,22 +3266,23 @@ static bool selectCommonType(SDataType* commonType, const SDataType* newType) {
return true; return true;
} }
} }
if ((commonType->type == TSDB_DATA_TYPE_VARCHAR && newType->type == TSDB_DATA_TYPE_NCHAR)) { //char and nchar
*commonType = *newType; if (commonIsString && newIsString) {
return true; if (commonType->type == TSDB_DATA_TYPE_NCHAR || newType->type == TSDB_DATA_TYPE_NCHAR) {
} *commonType = (commonType->type == TSDB_DATA_TYPE_NCHAR) ? *commonType : *newType; // nchar first
if ((commonType->type == TSDB_DATA_TYPE_NCHAR && newType->type == TSDB_DATA_TYPE_VARCHAR)) { } else {
commonType->bytes = commonType->bytes < newType->bytes ? newType->bytes : commonType->bytes; if (commonType->bytes < newType->bytes) {
*commonType = *newType;
}
}
return true; return true;
} }
return false; return false;
} }
static EDealRes translateCaseWhen(STranslateContext* pCxt, SCaseWhenNode* pCaseWhen) { static EDealRes translateCaseWhen(STranslateContext* pCxt, SCaseWhenNode* pCaseWhen) {
bool allNullThen = true; bool allNullThen = true;
SNode* pNode = NULL; SNode* pNode = NULL;
SDataType commonType = {.bytes = 0, .precision = 0, .scale = 0, .type = 0};
FOREACH(pNode, pCaseWhen->pWhenThenList) { FOREACH(pNode, pCaseWhen->pWhenThenList) {
SWhenThenNode* pWhenThen = (SWhenThenNode*)pNode; SWhenThenNode* pWhenThen = (SWhenThenNode*)pNode;
if (NULL == pCaseWhen->pCase && !isCondition(pWhenThen->pWhen)) { if (NULL == pCaseWhen->pCase && !isCondition(pWhenThen->pWhen)) {
@ -3268,14 +3300,14 @@ static EDealRes translateCaseWhen(STranslateContext* pCxt, SCaseWhenNode* pCaseW
} }
allNullThen = false; allNullThen = false;
if (!selectCommonType(&pCaseWhen->node.resType, &pThenExpr->resType)) { if (!selectCommonType(&pCaseWhen->node.resType, &pThenExpr->resType)) {
pCxt->errCode = DEAL_RES_ERROR; pCxt->errCode = DEAL_RES_ERROR;
return DEAL_RES_ERROR; return DEAL_RES_ERROR;
} }
} }
SExprNode* pElseExpr = (SExprNode*)pCaseWhen->pElse; SExprNode* pElseExpr = (SExprNode*)pCaseWhen->pElse;
if (!selectCommonType(&pCaseWhen->node.resType, &pElseExpr->resType)) { if (pElseExpr && !selectCommonType(&pCaseWhen->node.resType, &pElseExpr->resType)) {
pCxt->errCode = DEAL_RES_ERROR; pCxt->errCode = DEAL_RES_ERROR;
return DEAL_RES_ERROR; return DEAL_RES_ERROR;
} }

View File

@ -414,16 +414,16 @@ sql select case when f1 then 3 when ts then ts end from tba1;
if $rows != 4 then if $rows != 4 then
return -1 return -1
endi endi
if $data00 != 1664176501000 then if $data00 != @2022-09-26 15:15:01.000@ then
return -1 return -1
endi endi
if $data10 != 3 then if $data10 != @1970-01-01 08:00:00.003@ then
return -1 return -1
endi endi
if $data20 != 3 then if $data20 != @1970-01-01 08:00:00.003@ then
return -1 return -1
endi endi
if $data30 != 1664176504000 then if $data30 != @2022-09-26 15:15:04.0@ then
return -1 return -1
endi endi
@ -830,16 +830,16 @@ sql select case cast(f2 as int) when 0 then f2 when f1 then 11 else ts end from
if $rows != 4 then if $rows != 4 then
return -1 return -1
endi endi
if $data00 != a then if $data00 != @1970-01-01 08:00:00.000@ then
return -1 return -1
endi endi
if $data10 != 0 then if $data10 != @1970-01-01 08:00:00.000@ then
return -1 return -1
endi endi
if $data20 != 11 then if $data20 != @1970-01-01 08:00:00.011@ then
return -1 return -1
endi endi
if $data30 != 1664176504 then if $data30 != @2022-09-26 15:15:04.000@ then
return -1 return -1
endi endi

View File

@ -280,11 +280,11 @@ class TDTestCase:
for i in range(30): for i in range(30):
cs = self.state_window_list().split(',')[i] cs = self.state_window_list().split(',')[i]
sql1 = "select _wstart,avg(q_int),min(q_smallint) from %s.stable_1 where tbname = 'stable_1_1' state_window(%s);" % (database,cs) # sql1 = "select _wstart,avg(q_int),min(q_smallint) from %s.stable_1 where tbname = 'stable_1_1' state_window(%s);" % (database,cs)
sql2 = "select _wstart,avg(q_int),min(q_smallint) from %s.stable_1_1 state_window(%s) ;" % (database,cs) # sql2 = "select _wstart,avg(q_int),min(q_smallint) from %s.stable_1_1 state_window(%s) ;" % (database,cs)
self.constant_check(database,sql1,sql2,0) # self.constant_check(database,sql1,sql2,0)
self.constant_check(database,sql1,sql2,1) # self.constant_check(database,sql1,sql2,1)
self.constant_check(database,sql1,sql2,2) # self.constant_check(database,sql1,sql2,2)