fix: type overflow
This commit is contained in:
parent
20f4eda56d
commit
163b31a4ee
|
@ -415,7 +415,7 @@ typedef struct SSelectStmt {
|
|||
int32_t returnRows; // EFuncReturnRows
|
||||
ETimeLineMode timeLineCurMode;
|
||||
ETimeLineMode timeLineResMode;
|
||||
bool hasProcessByRowFunc;
|
||||
int32_t lastProcessByRowFuncId;
|
||||
bool timeLineFromOrderBy;
|
||||
bool isEmptyResult;
|
||||
bool isSubquery;
|
||||
|
|
|
@ -831,6 +831,7 @@ int32_t taosGetErrSize();
|
|||
#define TSDB_CODE_PAR_TBNAME_ERROR TAOS_DEF_ERROR_CODE(0, 0x267D)
|
||||
#define TSDB_CODE_PAR_TBNAME_DUPLICATED TAOS_DEF_ERROR_CODE(0, 0x267E)
|
||||
#define TSDB_CODE_PAR_TAG_NAME_DUPLICATED TAOS_DEF_ERROR_CODE(0, 0x267F)
|
||||
#define TSDB_CODE_PAR_NOT_ALLOWED_DIFFERENT_BY_ROW_FUNC TAOS_DEF_ERROR_CODE(0, 0x2680)
|
||||
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF)
|
||||
|
||||
//planner
|
||||
|
|
|
@ -3183,10 +3183,13 @@ static int32_t diffIsNegtive(SDiffInfo* pDiffInfo, int32_t type, const char* pv)
|
|||
return v < pDiffInfo->prev.i64;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:{
|
||||
uint64_t v = *(uint64_t*)pv;
|
||||
return v < (uint64_t)pDiffInfo->prev.i64;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t v = *(int64_t*)pv;
|
||||
return v - pDiffInfo->prev.i64 < 0;
|
||||
return v < pDiffInfo->prev.i64;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float v = *(float*)pv;
|
||||
|
@ -3203,9 +3206,13 @@ static int32_t diffIsNegtive(SDiffInfo* pDiffInfo, int32_t type, const char* pv)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void tryToSetInt64(SDiffInfo* pDiffInfo, SColumnInfoData* pOutput, int64_t v, int32_t pos) {
|
||||
int64_t delta = v - pDiffInfo->prev.i64; // direct previous may be null
|
||||
if (delta < 0 && ignoreNegative(pDiffInfo->ignoreOption)) {
|
||||
static void tryToSetInt64(SDiffInfo* pDiffInfo, int32_t type, SColumnInfoData* pOutput, int64_t v, int32_t pos) {
|
||||
bool isNegative = v < pDiffInfo->prev.i64;
|
||||
if(type == TSDB_DATA_TYPE_UBIGINT || type == TSDB_DATA_TYPE_TIMESTAMP){
|
||||
isNegative = (uint64_t)v < (uint64_t)pDiffInfo->prev.i64;
|
||||
}
|
||||
int64_t delta = v - pDiffInfo->prev.i64;
|
||||
if (isNegative && ignoreNegative(pDiffInfo->ignoreOption)) {
|
||||
colDataSetNull_f_s(pOutput, pos);
|
||||
pOutput->hasNull = true;
|
||||
} else {
|
||||
|
@ -3214,6 +3221,16 @@ static void tryToSetInt64(SDiffInfo* pDiffInfo, SColumnInfoData* pOutput, int64_
|
|||
pDiffInfo->prev.i64 = v;
|
||||
}
|
||||
|
||||
static void tryToSetDouble(SDiffInfo* pDiffInfo, SColumnInfoData* pOutput, double v, int32_t pos) {
|
||||
double delta = v - pDiffInfo->prev.d64;
|
||||
if (delta < 0 && ignoreNegative(pDiffInfo->ignoreOption)) {
|
||||
colDataSetNull_f_s(pOutput, pos);
|
||||
} else {
|
||||
colDataSetDouble(pOutput, pos, &delta);
|
||||
}
|
||||
pDiffInfo->prev.d64 = v;
|
||||
}
|
||||
|
||||
static int32_t doHandleDiff(SDiffInfo* pDiffInfo, int32_t type, const char* pv, SColumnInfoData* pOutput, int32_t pos,
|
||||
int64_t ts) {
|
||||
if (!pDiffInfo->hasPrev) {
|
||||
|
@ -3224,74 +3241,54 @@ static int32_t doHandleDiff(SDiffInfo* pDiffInfo, int32_t type, const char* pv,
|
|||
switch (type) {
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
int64_t v = *(uint32_t*)pv;
|
||||
tryToSetInt64(pDiffInfo, pOutput, v, pos);
|
||||
tryToSetInt64(pDiffInfo, type, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int64_t v = *(int32_t*)pv;
|
||||
tryToSetInt64(pDiffInfo, pOutput, v, pos);
|
||||
tryToSetInt64(pDiffInfo, type, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BOOL: {
|
||||
int64_t v = *(bool*)pv;
|
||||
tryToSetInt64(pDiffInfo, pOutput, v, pos);
|
||||
tryToSetInt64(pDiffInfo, type, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
int64_t v = *(uint8_t*)pv;
|
||||
tryToSetInt64(pDiffInfo, pOutput, v, pos);
|
||||
tryToSetInt64(pDiffInfo, type, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int64_t v = *(int8_t*)pv;
|
||||
tryToSetInt64(pDiffInfo, pOutput, v, pos);
|
||||
tryToSetInt64(pDiffInfo, type, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_USMALLINT:{
|
||||
int64_t v = *(uint16_t*)pv;
|
||||
tryToSetInt64(pDiffInfo, pOutput, v, pos);
|
||||
tryToSetInt64(pDiffInfo, type, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int64_t v = *(int16_t*)pv;
|
||||
tryToSetInt64(pDiffInfo, pOutput, v, pos);
|
||||
tryToSetInt64(pDiffInfo, type, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t v = *(int64_t*)pv;
|
||||
int64_t delta = v - pDiffInfo->prev.i64; // direct previous may be null
|
||||
if (delta < 0 && ignoreNegative(pDiffInfo->ignoreOption)) {
|
||||
colDataSetNull_f_s(pOutput, pos);
|
||||
} else {
|
||||
colDataSetInt64(pOutput, pos, &delta);
|
||||
}
|
||||
pDiffInfo->prev.i64 = v;
|
||||
tryToSetInt64(pDiffInfo, type, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
double v = *(float*)pv;
|
||||
double delta = v - pDiffInfo->prev.d64; // direct previous may be null
|
||||
if ((delta < 0 && ignoreNegative(pDiffInfo->ignoreOption)) || isinf(delta) ||
|
||||
isnan(delta)) { // check for overflow
|
||||
colDataSetNull_f_s(pOutput, pos);
|
||||
} else {
|
||||
colDataSetDouble(pOutput, pos, &delta);
|
||||
}
|
||||
pDiffInfo->prev.d64 = v;
|
||||
tryToSetDouble(pDiffInfo, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double v = *(double*)pv;
|
||||
double delta = v - pDiffInfo->prev.d64; // direct previous may be null
|
||||
if ((delta < 0 && ignoreNegative(pDiffInfo->ignoreOption)) || isinf(delta) ||
|
||||
isnan(delta)) { // check for overflow
|
||||
colDataSetNull_f_s(pOutput, pos);
|
||||
} else {
|
||||
colDataSetDouble(pOutput, pos, &delta);
|
||||
}
|
||||
pDiffInfo->prev.d64 = v;
|
||||
tryToSetDouble(pDiffInfo, pOutput, v, pos);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -2199,9 +2199,12 @@ static int32_t translateIndefiniteRowsFunc(STranslateContext* pCxt, SFunctionNod
|
|||
}
|
||||
if (pSelect->hasIndefiniteRowsFunc &&
|
||||
(FUNC_RETURN_ROWS_INDEFINITE == pSelect->returnRows || pSelect->returnRows != fmGetFuncReturnRows(pFunc)) &&
|
||||
(!pSelect->hasProcessByRowFunc || !fmIsProcessByRowFunc(pFunc->funcId))) {
|
||||
(pSelect->lastProcessByRowFuncId == -1 || !fmIsProcessByRowFunc(pFunc->funcId))) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||
}
|
||||
if (pSelect->lastProcessByRowFuncId != -1 && pSelect->lastProcessByRowFuncId != pFunc->funcId) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_DIFFERENT_BY_ROW_FUNC);
|
||||
}
|
||||
if (NULL != pSelect->pWindow || NULL != pSelect->pGroupByList) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||
"%s function is not supported in window query or group query", pFunc->functionName);
|
||||
|
@ -2466,7 +2469,7 @@ static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) {
|
|||
pSelect->returnRows = fmGetFuncReturnRows(pFunc);
|
||||
}
|
||||
if (fmIsProcessByRowFunc(pFunc->funcId)) {
|
||||
pSelect->hasProcessByRowFunc = true;
|
||||
pSelect->lastProcessByRowFuncId = pFunc->funcId;
|
||||
}
|
||||
|
||||
pSelect->hasMultiRowsFunc = pSelect->hasMultiRowsFunc ? true : fmIsMultiRowsFunc(pFunc->funcId);
|
||||
|
@ -3404,6 +3407,7 @@ static int32_t checkIsEmptyResult(STranslateContext* pCxt, SSelectStmt* pSelect)
|
|||
static int32_t resetSelectFuncNumWithoutDup(SSelectStmt* pSelect) {
|
||||
if (pSelect->selectFuncNum <= 1) return TSDB_CODE_SUCCESS;
|
||||
pSelect->selectFuncNum = 0;
|
||||
pSelect->lastProcessByRowFuncId = -1;
|
||||
SNodeList* pNodeList = nodesMakeList();
|
||||
int32_t code = nodesCollectSelectFuncs(pSelect, SQL_CLAUSE_FROM, NULL, fmIsSelectFunc, pNodeList);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
|
|
|
@ -221,6 +221,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
|||
return "Table name:%s duplicated";
|
||||
case TSDB_CODE_PAR_TAG_NAME_DUPLICATED:
|
||||
return "Tag name:%s duplicated";
|
||||
case TSDB_CODE_PAR_NOT_ALLOWED_DIFFERENT_BY_ROW_FUNC:
|
||||
return "Some functions cannot appear in the select list at the same time";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
@ -772,6 +774,7 @@ SNode* createSelectStmtImpl(bool isDistinct, SNodeList* pProjectionList, SNode*
|
|||
select->onlyHasKeepOrderFunc = true;
|
||||
select->timeRange = TSWINDOW_INITIALIZER;
|
||||
select->pHint = pHint;
|
||||
select->lastProcessByRowFuncId = -1;
|
||||
return (SNode*)select;
|
||||
}
|
||||
|
||||
|
|
|
@ -678,6 +678,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_PRIMARY_KEY_IS_NONE, "Primary key column
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TBNAME_ERROR, "Pseudo tag tbname not set")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TBNAME_DUPLICATED, "Table name duplicated")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TAG_NAME_DUPLICATED, "Tag name duplicated")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_ALLOWED_DIFFERENT_BY_ROW_FUNC, "Some functions cannot appear in the select list at the same time")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INTERNAL_ERROR, "Parser internal error")
|
||||
|
||||
//planner
|
||||
|
|
|
@ -275,7 +275,7 @@ class TDTestCase:
|
|||
tdSql.checkRows(2)
|
||||
|
||||
|
||||
def typeOverflowTest(self):
|
||||
def intOverflowTest(self):
|
||||
dbname = "db"
|
||||
|
||||
ts1 = 1694912400000
|
||||
|
@ -284,7 +284,7 @@ class TDTestCase:
|
|||
|
||||
tdSql.execute(f"insert into {dbname}.stb6_1 values(%d, -2147483648, -32768, 0, 9223372036854775806, 9223372036854775806)" % (ts1 + 1))
|
||||
tdSql.execute(f"insert into {dbname}.stb6_1 values(%d, 2147483647, 32767, 4294967295, 0, 0)" % (ts1 + 2))
|
||||
tdSql.execute(f"insert into {dbname}.stb6_1 values(%d, -10, -10, 0, -9223372036854775806, 9223372036854775806)" % (ts1 + 3))
|
||||
tdSql.execute(f"insert into {dbname}.stb6_1 values(%d, -10, -10, 0, -9223372036854775806, 16223372036854775806)" % (ts1 + 3))
|
||||
|
||||
tdSql.query(f"select ts, diff(c1), diff(c2), diff(c3), diff(c4), diff(c5) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(2)
|
||||
|
@ -299,7 +299,6 @@ class TDTestCase:
|
|||
tdSql.checkData(1, 2, -32777)
|
||||
tdSql.checkData(1, 3, -4294967295)
|
||||
tdSql.checkData(1, 4, -9223372036854775806)
|
||||
tdSql.checkData(1, 5, 9223372036854775806)
|
||||
|
||||
tdSql.query(f"select ts, diff(c1, 1), diff(c2) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(2)
|
||||
|
@ -326,6 +325,65 @@ class TDTestCase:
|
|||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 1, 4294967295)
|
||||
tdSql.checkData(0, 2, 65535)
|
||||
|
||||
tdSql.execute(f"insert into {dbname}.stb6_1 values(%d, -10, -10, 0, 9223372036854775800, 0)" % (ts1 + 4))
|
||||
tdSql.execute(f"insert into {dbname}.stb6_1 values(%d, -10, -10, 0, 9223372036854775800, 16223372036854775806)" % (ts1 + 5))
|
||||
|
||||
tdSql.query(f"select ts, diff(c4, 0) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query(f"select ts, diff(c4, 1) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(4)
|
||||
tdSql.checkData(2, 1, -10)
|
||||
|
||||
tdSql.query(f"select ts, diff(c4, 2) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query(f"select ts, diff(c4, 3) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, -10)
|
||||
tdSql.checkData(1, 1, 0)
|
||||
|
||||
tdSql.query(f"select ts, diff(c5, 0) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query(f"select ts, diff(c5, 1) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(4)
|
||||
tdSql.checkData(0, 1, None)
|
||||
tdSql.checkData(1, 0, '2023-09-17 09:00:00.003')
|
||||
tdSql.checkData(2, 1, None)
|
||||
tdSql.checkData(3, 0, '2023-09-17 09:00:00.005')
|
||||
|
||||
tdSql.query(f"select ts, diff(c5, 2) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query(f"select ts, diff(c5, 3) from {dbname}.stb6_1")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 0, '2023-09-17 09:00:00.003')
|
||||
tdSql.checkData(1, 0, '2023-09-17 09:00:00.005')
|
||||
|
||||
def doubleOverflowTest(self):
|
||||
dbname = "db"
|
||||
|
||||
ts1 = 1694912400000
|
||||
tdSql.execute(f'''create table {dbname}.stb7(ts timestamp, c1 float, c2 double) tags(loc nchar(20))''')
|
||||
tdSql.execute(f"create table {dbname}.stb7_1 using {dbname}.stb7 tags('shanghai')")
|
||||
|
||||
tdSql.execute(f"insert into {dbname}.stb7_1 values(%d, 334567777777777777777343434343333333733, 334567777777777777777343434343333333733)" % (ts1 + 1))
|
||||
tdSql.execute(f"insert into {dbname}.stb7_1 values(%d, -334567777777777777777343434343333333733, -334567777777777777777343434343333333733)" % (ts1 + 2))
|
||||
tdSql.execute(f"insert into {dbname}.stb7_1 values(%d, 334567777777777777777343434343333333733, 334567777777777777777343434343333333733)" % (ts1 + 3))
|
||||
|
||||
tdSql.query(f"select ts, diff(c1), diff(c2) from {dbname}.stb7_1")
|
||||
tdSql.checkRows(2)
|
||||
|
||||
tdSql.query(f"select ts, diff(c1, 1), diff(c2, 1) from {dbname}.stb7_1")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, None)
|
||||
tdSql.checkData(0, 2, None)
|
||||
|
||||
tdSql.query(f"select ts, diff(c1, 3), diff(c2, 3) from {dbname}.stb7_1")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, '2023-09-17 09:00:00.003')
|
||||
|
||||
def run(self):
|
||||
tdSql.prepare()
|
||||
|
@ -336,7 +394,8 @@ class TDTestCase:
|
|||
|
||||
self.ignoreTest()
|
||||
self.withPkTest()
|
||||
self.typeOverflowTest()
|
||||
self.intOverflowTest()
|
||||
self.doubleOverflowTest()
|
||||
|
||||
tdSql.execute(
|
||||
f"create table {dbname}.ntb(ts timestamp,c1 int,c2 double,c3 float)")
|
||||
|
|
Loading…
Reference in New Issue