Merge pull request #18212 from taosdata/fix/TD-20456
fix(query): [ASAN] fix time precision conversion overflow
This commit is contained in:
commit
5ae3eeeed9
|
@ -436,21 +436,24 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre
|
||||||
ASSERT(toPrecision == TSDB_TIME_PRECISION_MILLI || toPrecision == TSDB_TIME_PRECISION_MICRO ||
|
ASSERT(toPrecision == TSDB_TIME_PRECISION_MILLI || toPrecision == TSDB_TIME_PRECISION_MICRO ||
|
||||||
toPrecision == TSDB_TIME_PRECISION_NANO);
|
toPrecision == TSDB_TIME_PRECISION_NANO);
|
||||||
|
|
||||||
double tempResult = (double)utime;
|
|
||||||
|
|
||||||
switch (fromPrecision) {
|
switch (fromPrecision) {
|
||||||
case TSDB_TIME_PRECISION_MILLI: {
|
case TSDB_TIME_PRECISION_MILLI: {
|
||||||
switch (toPrecision) {
|
switch (toPrecision) {
|
||||||
case TSDB_TIME_PRECISION_MILLI:
|
case TSDB_TIME_PRECISION_MILLI:
|
||||||
return utime;
|
return utime;
|
||||||
case TSDB_TIME_PRECISION_MICRO:
|
case TSDB_TIME_PRECISION_MICRO:
|
||||||
tempResult *= 1000;
|
if (utime > INT64_MAX / 1000) {
|
||||||
utime *= 1000;
|
return INT64_MAX;
|
||||||
goto end_;
|
}
|
||||||
|
return utime * 1000;
|
||||||
case TSDB_TIME_PRECISION_NANO:
|
case TSDB_TIME_PRECISION_NANO:
|
||||||
tempResult *= 1000000;
|
if (utime > INT64_MAX / 1000000) {
|
||||||
utime *= 1000000;
|
return INT64_MAX;
|
||||||
goto end_;
|
}
|
||||||
|
return utime * 1000000;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return utime;
|
||||||
}
|
}
|
||||||
} // end from milli
|
} // end from milli
|
||||||
case TSDB_TIME_PRECISION_MICRO: {
|
case TSDB_TIME_PRECISION_MICRO: {
|
||||||
|
@ -460,9 +463,13 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre
|
||||||
case TSDB_TIME_PRECISION_MICRO:
|
case TSDB_TIME_PRECISION_MICRO:
|
||||||
return utime;
|
return utime;
|
||||||
case TSDB_TIME_PRECISION_NANO:
|
case TSDB_TIME_PRECISION_NANO:
|
||||||
tempResult *= 1000;
|
if (utime > INT64_MAX / 1000) {
|
||||||
utime *= 1000;
|
return INT64_MAX;
|
||||||
goto end_;
|
}
|
||||||
|
return utime * 1000;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return utime;
|
||||||
}
|
}
|
||||||
} // end from micro
|
} // end from micro
|
||||||
case TSDB_TIME_PRECISION_NANO: {
|
case TSDB_TIME_PRECISION_NANO: {
|
||||||
|
@ -473,17 +480,17 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre
|
||||||
return utime / 1000;
|
return utime / 1000;
|
||||||
case TSDB_TIME_PRECISION_NANO:
|
case TSDB_TIME_PRECISION_NANO:
|
||||||
return utime;
|
return utime;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return utime;
|
||||||
}
|
}
|
||||||
} // end from nano
|
} // end from nano
|
||||||
default: {
|
default: {
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
return utime; // only to pass windows compilation
|
return utime; // only to pass windows compilation
|
||||||
}
|
}
|
||||||
} // end switch fromPrecision
|
} // end switch fromPrecision
|
||||||
|
|
||||||
end_:
|
|
||||||
if (tempResult >= (double)INT64_MAX) return INT64_MAX;
|
|
||||||
if (tempResult <= (double)INT64_MIN) return INT64_MIN; // INT64_MIN means NULL
|
|
||||||
return utime;
|
return utime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,18 +606,33 @@ int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec
|
||||||
static int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t timePrecision) {
|
static int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t timePrecision) {
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case 's':
|
case 's':
|
||||||
|
if (val > INT64_MAX / MILLISECOND_PER_SECOND) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
(*result) = convertTimePrecision(val * MILLISECOND_PER_SECOND, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
(*result) = convertTimePrecision(val * MILLISECOND_PER_SECOND, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
|
if (val > INT64_MAX / MILLISECOND_PER_MINUTE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
(*result) = convertTimePrecision(val * MILLISECOND_PER_MINUTE, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
(*result) = convertTimePrecision(val * MILLISECOND_PER_MINUTE, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
|
if (val > INT64_MAX / MILLISECOND_PER_MINUTE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
(*result) = convertTimePrecision(val * MILLISECOND_PER_HOUR, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
(*result) = convertTimePrecision(val * MILLISECOND_PER_HOUR, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
|
if (val > INT64_MAX / MILLISECOND_PER_DAY) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
(*result) = convertTimePrecision(val * MILLISECOND_PER_DAY, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
(*result) = convertTimePrecision(val * MILLISECOND_PER_DAY, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
|
if (val > INT64_MAX / MILLISECOND_PER_WEEK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
(*result) = convertTimePrecision(val * MILLISECOND_PER_WEEK, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
(*result) = convertTimePrecision(val * MILLISECOND_PER_WEEK, TSDB_TIME_PRECISION_MILLI, timePrecision);
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
|
@ -650,7 +672,7 @@ int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* dura
|
||||||
|
|
||||||
/* get the basic numeric value */
|
/* get the basic numeric value */
|
||||||
int64_t timestamp = taosStr2Int64(token, &endPtr, 10);
|
int64_t timestamp = taosStr2Int64(token, &endPtr, 10);
|
||||||
if (errno != 0) {
|
if (timestamp < 0 || errno != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,7 +690,7 @@ int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* durati
|
||||||
|
|
||||||
/* get the basic numeric value */
|
/* get the basic numeric value */
|
||||||
*duration = taosStr2Int64(token, NULL, 10);
|
*duration = taosStr2Int64(token, NULL, 10);
|
||||||
if (errno != 0) {
|
if (*duration < 0 || errno != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -917,6 +917,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
int32_t startIndex;
|
int32_t startIndex;
|
||||||
if (numOfParams != 4) {
|
if (numOfParams != 4) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg1);
|
snprintf(errMsg, msgLen, "%s", msg1);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -928,17 +929,20 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
|
|
||||||
if (!cJSON_IsNumber(start) || !cJSON_IsNumber(count) || !cJSON_IsBool(infinity)) {
|
if (!cJSON_IsNumber(start) || !cJSON_IsNumber(count) || !cJSON_IsBool(infinity)) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg3);
|
snprintf(errMsg, msgLen, "%s", msg3);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count->valueint <= 0 || count->valueint > 1000) { // limit count to 1000
|
if (count->valueint <= 0 || count->valueint > 1000) { // limit count to 1000
|
||||||
snprintf(errMsg, msgLen, "%s", msg4);
|
snprintf(errMsg, msgLen, "%s", msg4);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isinf(start->valuedouble) || (width != NULL && isinf(width->valuedouble)) ||
|
if (isinf(start->valuedouble) || (width != NULL && isinf(width->valuedouble)) ||
|
||||||
(factor != NULL && isinf(factor->valuedouble)) || (count != NULL && isinf(count->valuedouble))) {
|
(factor != NULL && isinf(factor->valuedouble)) || (count != NULL && isinf(count->valuedouble))) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg5);
|
snprintf(errMsg, msgLen, "%s", msg5);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -957,6 +961,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
if (width->valuedouble == 0) {
|
if (width->valuedouble == 0) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg6);
|
snprintf(errMsg, msgLen, "%s", msg6);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < counter + 1; ++i) {
|
for (int i = 0; i < counter + 1; ++i) {
|
||||||
|
@ -964,6 +969,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
if (isinf(intervals[startIndex])) {
|
if (isinf(intervals[startIndex])) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg5);
|
snprintf(errMsg, msgLen, "%s", msg5);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
startIndex++;
|
startIndex++;
|
||||||
|
@ -973,11 +979,13 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
if (start->valuedouble == 0) {
|
if (start->valuedouble == 0) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg7);
|
snprintf(errMsg, msgLen, "%s", msg7);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (factor->valuedouble < 0 || factor->valuedouble == 0 || factor->valuedouble == 1) {
|
if (factor->valuedouble < 0 || factor->valuedouble == 0 || factor->valuedouble == 1) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg8);
|
snprintf(errMsg, msgLen, "%s", msg8);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < counter + 1; ++i) {
|
for (int i = 0; i < counter + 1; ++i) {
|
||||||
|
@ -985,6 +993,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
if (isinf(intervals[startIndex])) {
|
if (isinf(intervals[startIndex])) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg5);
|
snprintf(errMsg, msgLen, "%s", msg5);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
startIndex++;
|
startIndex++;
|
||||||
|
@ -992,6 +1001,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
} else {
|
} else {
|
||||||
snprintf(errMsg, msgLen, "%s", msg3);
|
snprintf(errMsg, msgLen, "%s", msg3);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,6 +1017,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
} else if (cJSON_IsArray(binDesc)) { /* user input bins */
|
} else if (cJSON_IsArray(binDesc)) { /* user input bins */
|
||||||
if (binType != USER_INPUT_BIN) {
|
if (binType != USER_INPUT_BIN) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg3);
|
snprintf(errMsg, msgLen, "%s", msg3);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
numOfBins = cJSON_GetArraySize(binDesc);
|
numOfBins = cJSON_GetArraySize(binDesc);
|
||||||
|
@ -1015,6 +1026,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
if (bin == NULL) {
|
if (bin == NULL) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg3);
|
snprintf(errMsg, msgLen, "%s", msg3);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -1023,11 +1035,13 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
if (!cJSON_IsNumber(bin)) {
|
if (!cJSON_IsNumber(bin)) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg3);
|
snprintf(errMsg, msgLen, "%s", msg3);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (i != 0 && intervals[i] <= intervals[i - 1]) {
|
if (i != 0 && intervals[i] <= intervals[i - 1]) {
|
||||||
snprintf(errMsg, msgLen, "%s", msg3);
|
snprintf(errMsg, msgLen, "%s", msg3);
|
||||||
taosMemoryFree(intervals);
|
taosMemoryFree(intervals);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bin = bin->next;
|
bin = bin->next;
|
||||||
|
@ -1035,6 +1049,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snprintf(errMsg, msgLen, "%s", msg3);
|
snprintf(errMsg, msgLen, "%s", msg3);
|
||||||
|
cJSON_Delete(binDesc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1464,11 +1479,16 @@ static int32_t translateDerivative(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
||||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||||
|
|
||||||
// param1
|
// param1
|
||||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||||
|
SValueNode* pValue1 = (SValueNode*)pParamNode1;
|
||||||
if (QUERY_NODE_VALUE != nodeType(pParamNode1)) {
|
if (QUERY_NODE_VALUE != nodeType(pParamNode1)) {
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pValue1->datum.i <= 0) {
|
||||||
|
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
SValueNode* pValue = (SValueNode*)pParamNode1;
|
SValueNode* pValue = (SValueNode*)pParamNode1;
|
||||||
pValue->notReserved = true;
|
pValue->notReserved = true;
|
||||||
|
|
||||||
|
|
|
@ -821,10 +821,10 @@ sql insert into tm0 values('2015-08-18T00:18:00Z', 2.126) ('2015-08-18T00:24:00Z
|
||||||
|
|
||||||
sql_error select derivative(ts) from tm0;
|
sql_error select derivative(ts) from tm0;
|
||||||
sql_error select derivative(k) from tm0;
|
sql_error select derivative(k) from tm0;
|
||||||
sql select derivative(k, 0, 0) from tm0;
|
sql_error select derivative(k, 0, 0) from tm0;
|
||||||
sql_error select derivative(k, 1, 911) from tm0;
|
sql_error select derivative(k, 1, 911) from tm0;
|
||||||
sql_error select derivative(kx, 1s, 1) from tm0;
|
sql_error select derivative(kx, 1s, 1) from tm0;
|
||||||
sql select derivative(k, -20s, 1) from tm0;
|
sql_error select derivative(k, -20s, 1) from tm0;
|
||||||
sql select derivative(k, 20a, 0) from tm0;
|
sql select derivative(k, 20a, 0) from tm0;
|
||||||
sql select derivative(k, 200a, 0) from tm0;
|
sql select derivative(k, 200a, 0) from tm0;
|
||||||
sql select derivative(k, 999a, 0) from tm0;
|
sql select derivative(k, 999a, 0) from tm0;
|
||||||
|
@ -932,10 +932,10 @@ sql insert into t0 values('2020-1-1 1:4:10', 10);
|
||||||
|
|
||||||
sql insert into t1 values('2020-1-1 1:1:2', 2);
|
sql insert into t1 values('2020-1-1 1:1:2', 2);
|
||||||
print ===========================>td-4739
|
print ===========================>td-4739
|
||||||
#sql select diff(val) from (select derivative(k, 1s, 0) val from t1);
|
sql select diff(val) from (select ts, derivative(k, 1s, 0) val from t1);
|
||||||
#if $rows != 0 then
|
if $rows != 0 then
|
||||||
# return -1
|
return -1
|
||||||
#endi
|
endi
|
||||||
|
|
||||||
sql insert into t1 values('2020-1-1 1:1:4', 20);
|
sql insert into t1 values('2020-1-1 1:1:4', 20);
|
||||||
sql insert into t1 values('2020-1-1 1:1:6', 200);
|
sql insert into t1 values('2020-1-1 1:1:6', 200);
|
||||||
|
|
Loading…
Reference in New Issue