Merge branch 'develop' into xiaoping/add_test_case2
This commit is contained in:
commit
00ce6543a3
|
@ -56,7 +56,6 @@ typedef struct SLocalReducer {
|
|||
tFilePage * pTempBuffer;
|
||||
struct SQLFunctionCtx *pCtx;
|
||||
int32_t rowSize; // size of each intermediate result.
|
||||
int32_t finalRowSize; // final result row size
|
||||
int32_t status; // denote it is in reduce process, in reduce process, it
|
||||
bool hasPrevRow; // cannot be released
|
||||
bool hasUnprocessedRow;
|
||||
|
|
|
@ -64,13 +64,13 @@
|
|||
} \
|
||||
} while (0);
|
||||
|
||||
#define DO_UPDATE_TAG_COLUMNS_WITHOUT_TS(ctx) \
|
||||
do {\
|
||||
for (int32_t i = 0; i < (ctx)->tagInfo.numOfTagCols; ++i) { \
|
||||
SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[i]; \
|
||||
aAggs[TSDB_FUNC_TAG].xFunction(__ctx); \
|
||||
} \
|
||||
} while(0);
|
||||
#define DO_UPDATE_TAG_COLUMNS_WITHOUT_TS(ctx) \
|
||||
do { \
|
||||
for (int32_t i = 0; i < (ctx)->tagInfo.numOfTagCols; ++i) { \
|
||||
SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[i]; \
|
||||
aAggs[TSDB_FUNC_TAG].xFunction(__ctx); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
void noop1(SQLFunctionCtx *UNUSED_PARAM(pCtx)) {}
|
||||
void noop2(SQLFunctionCtx *UNUSED_PARAM(pCtx), int32_t UNUSED_PARAM(index)) {}
|
||||
|
@ -3624,52 +3624,147 @@ static bool twa_function_setup(SQLFunctionCtx *pCtx) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); //->aOutputBuf + pCtx->outputBytes;
|
||||
STwaInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
pInfo->lastKey = INT64_MIN;
|
||||
pInfo->type = pCtx->inputType;
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
pInfo->lastKey = INT64_MIN;
|
||||
pInfo->win = TSWINDOW_INITIALIZER;
|
||||
return true;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void setTWALastVal(SQLFunctionCtx *pCtx, const char *data, int32_t i, STwaInfo *pInfo) {
|
||||
switch (pCtx->inputType) {
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
pInfo->iLastValue = GET_INT32_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
pInfo->iLastValue = GET_INT8_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
pInfo->iLastValue = GET_INT16_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
pInfo->iLastValue = GET_INT64_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
pInfo->dLastValue = GET_FLOAT_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
pInfo->dLastValue = GET_DOUBLE_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t size) {
|
||||
int32_t notNullElems = 0;
|
||||
TSKEY *primaryKey = pCtx->ptsList;
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
int32_t i = index;
|
||||
|
||||
if (pCtx->start.key != INT64_MIN) {
|
||||
assert(pCtx->start.key < primaryKey[index] && pInfo->lastKey == INT64_MIN);
|
||||
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, 0));
|
||||
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->start.val) / 2) * (pInfo->lastKey - pCtx->start.key);
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pCtx->start.key;
|
||||
notNullElems++;
|
||||
i += 1;
|
||||
} else if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, 0));
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pInfo->lastKey;
|
||||
notNullElems++;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// calculate the value of
|
||||
switch(pCtx->inputType) {
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t *val = (int8_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t *val = (int16_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t *val = (int32_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t *val = (int64_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->lastValue = (double) val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float *val = (float*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double *val = (double*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
// the last interpolated time window value
|
||||
if (pCtx->end.key != INT64_MIN) {
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->end.val) / 2) * (pCtx->end.key - pInfo->lastKey);
|
||||
pInfo->lastValue = pCtx->end.val;
|
||||
pInfo->lastKey = pCtx->end.key;
|
||||
}
|
||||
|
||||
pInfo->win.ekey = pInfo->lastKey;
|
||||
return notNullElems;
|
||||
}
|
||||
|
||||
static void twa_function(SQLFunctionCtx *pCtx) {
|
||||
void * data = GET_INPUT_CHAR(pCtx);
|
||||
TSKEY *primaryKey = pCtx->ptsList;
|
||||
|
||||
int32_t notNullElems = 0;
|
||||
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
STwaInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
int32_t i = 0;
|
||||
|
||||
// skip null value
|
||||
int32_t i = 0;
|
||||
while (pCtx->hasNull && i < pCtx->size && isNull((char *)data + pCtx->inputBytes * i, pCtx->inputType)) {
|
||||
i++;
|
||||
}
|
||||
|
@ -3678,40 +3773,7 @@ static void twa_function(SQLFunctionCtx *pCtx) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = pCtx->nStartQueryTimestamp;
|
||||
setTWALastVal(pCtx, data, i, pInfo);
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
}
|
||||
|
||||
notNullElems++;
|
||||
|
||||
if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT || pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
pInfo->dOutput += pInfo->dLastValue * (primaryKey[i] - pInfo->lastKey);
|
||||
} else {
|
||||
pInfo->iOutput += pInfo->iLastValue * (primaryKey[i] - pInfo->lastKey);
|
||||
}
|
||||
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
setTWALastVal(pCtx, data, i, pInfo);
|
||||
|
||||
for (++i; i < pCtx->size; i++) {
|
||||
if (pCtx->hasNull && isNull((char *)data + pCtx->inputBytes * i, pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
notNullElems++;
|
||||
if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT || pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
pInfo->dOutput += pInfo->dLastValue * (primaryKey[i] - pInfo->lastKey);
|
||||
} else {
|
||||
pInfo->iOutput += pInfo->iLastValue * (primaryKey[i] - pInfo->lastKey);
|
||||
}
|
||||
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
setTWALastVal(pCtx, data, i, pInfo);
|
||||
}
|
||||
|
||||
int32_t notNullElems = twa_function_impl(pCtx, pCtx->startOffset, pCtx->size);
|
||||
SET_VAL(pCtx, notNullElems, 1);
|
||||
|
||||
if (notNullElems > 0) {
|
||||
|
@ -3721,8 +3783,6 @@ static void twa_function(SQLFunctionCtx *pCtx) {
|
|||
if (pCtx->stableQuery) {
|
||||
memcpy(pCtx->aOutputBuf, pInfo, sizeof(STwaInfo));
|
||||
}
|
||||
|
||||
// pCtx->numOfIteratedElems += notNullElems;
|
||||
}
|
||||
|
||||
static void twa_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||
|
@ -3730,35 +3790,12 @@ static void twa_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
if (pCtx->hasNull && isNull(pData, pCtx->inputType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SET_VAL(pCtx, 1, 1);
|
||||
|
||||
TSKEY *primaryKey = pCtx->ptsList;
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = pCtx->nStartQueryTimestamp;
|
||||
setTWALastVal(pCtx, pData, 0, pInfo);
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
}
|
||||
|
||||
if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT || pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
pInfo->dOutput += pInfo->dLastValue * (primaryKey[index] - pInfo->lastKey);
|
||||
} else {
|
||||
pInfo->iOutput += pInfo->iLastValue * (primaryKey[index] - pInfo->lastKey);
|
||||
}
|
||||
|
||||
// record the last key/value
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
setTWALastVal(pCtx, pData, 0, pInfo);
|
||||
|
||||
// pCtx->numOfIteratedElems += 1;
|
||||
pResInfo->hasResult = DATA_SET_FLAG;
|
||||
|
||||
|
||||
int32_t notNullElems = twa_function_impl(pCtx, index, 1);
|
||||
SET_VAL(pCtx, notNullElems, 1);
|
||||
|
||||
if (pCtx->stableQuery) {
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(STwaInfo));
|
||||
}
|
||||
}
|
||||
|
@ -3778,16 +3815,10 @@ static void twa_func_merge(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
numOfNotNull++;
|
||||
if (pCtx->inputType >= TSDB_DATA_TYPE_TINYINT && pCtx->inputType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
pBuf->iOutput += pInput->iOutput;
|
||||
} else {
|
||||
pBuf->dOutput += pInput->dOutput;
|
||||
}
|
||||
|
||||
pBuf->SKey = pInput->SKey;
|
||||
pBuf->EKey = pInput->EKey;
|
||||
pBuf->dOutput += pInput->dOutput;
|
||||
|
||||
pBuf->win = pInput->win;
|
||||
pBuf->lastKey = pInput->lastKey;
|
||||
pBuf->iLastValue = pInput->iLastValue;
|
||||
}
|
||||
|
||||
SET_VAL(pCtx, numOfNotNull, 1);
|
||||
|
@ -3814,21 +3845,17 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
|
|||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = (STwaInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
assert(pInfo->EKey >= pInfo->lastKey && pInfo->hasResult == pResInfo->hasResult);
|
||||
assert(pInfo->win.ekey == pInfo->lastKey && pInfo->hasResult == pResInfo->hasResult);
|
||||
|
||||
if (pInfo->hasResult != DATA_SET_FLAG) {
|
||||
setNull(pCtx->aOutputBuf, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pInfo->SKey == pInfo->EKey) {
|
||||
*(double *)pCtx->aOutputBuf = 0;
|
||||
} else if (pInfo->type >= TSDB_DATA_TYPE_TINYINT && pInfo->type <= TSDB_DATA_TYPE_BIGINT) {
|
||||
pInfo->iOutput += pInfo->iLastValue * (pInfo->EKey - pInfo->lastKey);
|
||||
*(double *)pCtx->aOutputBuf = pInfo->iOutput / (double)(pInfo->EKey - pInfo->SKey);
|
||||
if (pInfo->win.ekey == pInfo->win.skey) {
|
||||
*(double *)pCtx->aOutputBuf = pInfo->lastValue;
|
||||
} else {
|
||||
pInfo->dOutput += pInfo->dLastValue * (pInfo->EKey - pInfo->lastKey);
|
||||
*(double *)pCtx->aOutputBuf = pInfo->dOutput / (pInfo->EKey - pInfo->SKey);
|
||||
*(double *)pCtx->aOutputBuf = pInfo->dOutput / (pInfo->win.ekey - pInfo->win.skey);
|
||||
}
|
||||
|
||||
GET_RES_INFO(pCtx)->numOfRes = 1;
|
||||
|
|
|
@ -198,6 +198,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
|
||||
if (numOfFlush == 0 || numOfBuffer == 0) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty
|
||||
tscDebug("%p retrieved no data", pSql);
|
||||
return;
|
||||
}
|
||||
|
@ -330,22 +331,19 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
pReducer->nResultBufSize = pMemBuffer[0]->pageSize * 16;
|
||||
pReducer->pResultBuf = (tFilePage *)calloc(1, pReducer->nResultBufSize + sizeof(tFilePage));
|
||||
|
||||
pReducer->finalRowSize = tscGetResRowLength(pQueryInfo->exprList);
|
||||
pReducer->resColModel = finalmodel;
|
||||
pReducer->resColModel->capacity = pReducer->nResultBufSize;
|
||||
|
||||
pReducer->finalModel = pFFModel;
|
||||
|
||||
assert(pReducer->finalRowSize > 0);
|
||||
if (pReducer->finalRowSize > 0) {
|
||||
pReducer->resColModel->capacity /= pReducer->finalRowSize;
|
||||
if (finalmodel->rowSize > 0) {
|
||||
pReducer->resColModel->capacity /= finalmodel->rowSize;
|
||||
}
|
||||
assert(pReducer->finalRowSize <= pReducer->rowSize);
|
||||
|
||||
assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pReducer->rowSize);
|
||||
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity);
|
||||
|
||||
if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
||||
/*pReducer->pBufForInterpo == NULL || */pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||
pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||
tfree(pReducer->pTempBuffer);
|
||||
tfree(pReducer->discardData);
|
||||
tfree(pReducer->pResultBuf);
|
||||
|
@ -920,7 +918,7 @@ static void genFinalResWithoutFill(SSqlRes* pRes, SLocalReducer *pLocalReducer,
|
|||
savePrevRecordAndSetupFillInfo(pLocalReducer, pQueryInfo, pLocalReducer->pFillInfo);
|
||||
}
|
||||
|
||||
memcpy(pRes->data, pBeforeFillData->data, (size_t)(pRes->numOfRows * pLocalReducer->finalRowSize));
|
||||
memcpy(pRes->data, pBeforeFillData->data, (size_t)(pRes->numOfRows * pLocalReducer->finalModel->rowSize));
|
||||
|
||||
pRes->numOfClauseTotal += pRes->numOfRows;
|
||||
pBeforeFillData->num = 0;
|
||||
|
@ -1256,7 +1254,7 @@ bool genFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCur
|
|||
tColModelCompact(pModel, pResBuf, pModel->capacity);
|
||||
|
||||
if (tscIsSecondStageQuery(pQueryInfo)) {
|
||||
pLocalReducer->finalRowSize = doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalReducer->finalRowSize);
|
||||
doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalReducer->finalModel->rowSize);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
|
@ -1627,7 +1625,8 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
|
|||
}
|
||||
|
||||
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
|
||||
char* pbuf = calloc(1, pOutput->num * rowSize);
|
||||
int32_t maxRowSize = MAX(rowSize, finalRowSize);
|
||||
char* pbuf = calloc(1, pOutput->num * maxRowSize);
|
||||
|
||||
size_t size = tscNumOfFields(pQueryInfo);
|
||||
SArithmeticSupport arithSup = {0};
|
||||
|
@ -1660,7 +1659,6 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
|||
offset += pSup->field.bytes;
|
||||
}
|
||||
|
||||
assert(finalRowSize <= rowSize);
|
||||
memcpy(pOutput->data, pbuf, pOutput->num * offset);
|
||||
|
||||
tfree(pbuf);
|
||||
|
|
|
@ -4248,7 +4248,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
|
|||
tExprTreeDestroy(&p, NULL);
|
||||
|
||||
taosArrayDestroy(colList);
|
||||
if (taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table");
|
||||
}
|
||||
}
|
||||
|
@ -4256,6 +4256,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
|
|||
pCondExpr->pTagCond = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
|
||||
if (pExpr == NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -6648,7 +6649,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -63,9 +63,11 @@ typedef struct SSqlGroupbyExpr {
|
|||
|
||||
typedef struct SResultRow {
|
||||
int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer
|
||||
int32_t rowId:15;
|
||||
bool closed:1; // this result status: closed or opened
|
||||
uint16_t numOfRows; // number of rows of current time window
|
||||
int32_t rowId:29; // row index in buffer page
|
||||
bool startInterp; // the time window start timestamp has done the interpolation already.
|
||||
bool endInterp; // the time window end timestamp has done the interpolation already.
|
||||
bool closed; // this result status: closed or opened
|
||||
uint32_t numOfRows; // number of rows of current time window
|
||||
SResultRowCellInfo* pCellInfo; // For each result column, there is a resultInfo
|
||||
union {STimeWindow win; char* key;}; // start key of current time window
|
||||
} SResultRow;
|
||||
|
@ -187,6 +189,7 @@ typedef struct SQueryRuntimeEnv {
|
|||
bool topBotQuery; // false
|
||||
bool groupbyNormalCol; // denote if this is a groupby normal column query
|
||||
bool hasTagResults; // if there are tag values in final result or not
|
||||
bool timeWindowInterpo;// if the time window start/end required interpolation
|
||||
int32_t interBufSize; // intermediate buffer sizse
|
||||
int32_t prevGroupId; // previous executed group id
|
||||
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
|
@ -195,6 +198,8 @@ typedef struct SQueryRuntimeEnv {
|
|||
SResultRowPool* pool; // window result object pool
|
||||
|
||||
int32_t* rowCellInfoOffset;// offset value for each row result cell info
|
||||
char** prevRow;
|
||||
char** nextRow;
|
||||
} SQueryRuntimeEnv;
|
||||
|
||||
enum {
|
||||
|
|
|
@ -152,6 +152,11 @@ typedef struct SResultRowCellInfo {
|
|||
uint32_t numOfRes; // num of output result in current buffer
|
||||
} SResultRowCellInfo;
|
||||
|
||||
typedef struct SPoint1 {
|
||||
int64_t key;
|
||||
double val;
|
||||
} SPoint1;
|
||||
|
||||
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowCellInfo)))
|
||||
|
||||
struct SQLFunctionCtx;
|
||||
|
@ -194,6 +199,8 @@ typedef struct SQLFunctionCtx {
|
|||
SResultRowCellInfo *resultInfo;
|
||||
|
||||
SExtTagsInfo tagInfo;
|
||||
SPoint1 start;
|
||||
SPoint1 end;
|
||||
} SQLFunctionCtx;
|
||||
|
||||
typedef struct SQLAggFuncElem {
|
||||
|
@ -243,21 +250,11 @@ enum {
|
|||
};
|
||||
|
||||
typedef struct STwaInfo {
|
||||
TSKEY lastKey;
|
||||
int8_t hasResult; // flag to denote has value
|
||||
int16_t type; // source data type
|
||||
TSKEY SKey;
|
||||
TSKEY EKey;
|
||||
|
||||
union {
|
||||
double dOutput;
|
||||
int64_t iOutput;
|
||||
};
|
||||
|
||||
union {
|
||||
double dLastValue;
|
||||
int64_t iLastValue;
|
||||
};
|
||||
TSKEY lastKey;
|
||||
int8_t hasResult; // flag to denote has value
|
||||
double dOutput;
|
||||
double lastValue;
|
||||
STimeWindow win;
|
||||
} STwaInfo;
|
||||
|
||||
/* global sql function array */
|
||||
|
@ -276,8 +273,6 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, int32_t functionId, const cha
|
|||
(_r)->initialized = false; \
|
||||
} while (0)
|
||||
|
||||
//void setResultInfoBuf(SResultRowCellInfo *pResInfo, char* buf);
|
||||
|
||||
static FORCE_INLINE void initResultInfo(SResultRowCellInfo *pResInfo, uint32_t bufLen) {
|
||||
pResInfo->initialized = true; // the this struct has been initialized flag
|
||||
|
||||
|
|
|
@ -370,6 +370,66 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
|
|||
#endif
|
||||
}
|
||||
|
||||
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
|
||||
switch(type) {
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t* p = (int8_t*) dest;
|
||||
int8_t* pSrc = (int8_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t* p = (int16_t*) dest;
|
||||
int16_t* pSrc = (int16_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t* p = (int32_t*) dest;
|
||||
int32_t* pSrc = (int32_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t* p = (int64_t*) dest;
|
||||
int64_t* pSrc = (int64_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float* p = (float*) dest;
|
||||
float* pSrc = (float*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double* p = (double*) dest;
|
||||
double* pSrc = (double*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||
char *(*getSourceDataBlock)(void *, const char*, int32_t)) {
|
||||
if (pExprs == NULL) {
|
||||
|
@ -387,6 +447,8 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
|||
|
||||
/* the right output has result from the right child syntax tree */
|
||||
char *pRightOutput = malloc(sizeof(int64_t) * numOfRows);
|
||||
char *pdata = malloc(sizeof(int64_t) * numOfRows);
|
||||
|
||||
if (pRight->nodeType == TSQL_NODE_EXPR) {
|
||||
tExprTreeCalcTraverse(pRight, numOfRows, pRightOutput, param, order, getSourceDataBlock);
|
||||
}
|
||||
|
@ -398,52 +460,75 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
|||
* the type of returned value of one expression is always double float precious
|
||||
*/
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(TSDB_DATA_TYPE_DOUBLE, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
||||
fp(pLeftOutput, pRightOutput, numOfRows, numOfRows, pOutput, order);
|
||||
fp(pLeftOutput, pRightOutput, numOfRows, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||
|
||||
} else if (pRight->nodeType == TSQL_NODE_COL) { // exprLeft + columnRight
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(TSDB_DATA_TYPE_DOUBLE, pRight->pSchema->type, pExprs->_node.optr);
|
||||
|
||||
// set input buffer
|
||||
char *pInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||
fp(pLeftOutput, pInputData, numOfRows, numOfRows, pOutput, order);
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
reverseCopy(pdata, pInputData, pRight->pSchema->type, numOfRows);
|
||||
fp(pLeftOutput, pdata, numOfRows, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
fp(pLeftOutput, pInputData, numOfRows, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // exprLeft + 12
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(TSDB_DATA_TYPE_DOUBLE, pRight->pVal->nType, pExprs->_node.optr);
|
||||
fp(pLeftOutput, &pRight->pVal->i64Key, numOfRows, 1, pOutput, order);
|
||||
fp(pLeftOutput, &pRight->pVal->i64Key, numOfRows, 1, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
} else if (pLeft->nodeType == TSQL_NODE_COL) {
|
||||
// column data specified on left-hand-side
|
||||
char *pLeftInputData = getSourceDataBlock(param, pLeft->pSchema->name, pLeft->pSchema->colId);
|
||||
if (pRight->nodeType == TSQL_NODE_EXPR) { // columnLeft + expr2
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pSchema->type, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
||||
fp(pLeftInputData, pRightOutput, numOfRows, numOfRows, pOutput, order);
|
||||
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows);
|
||||
fp(pdata, pRightOutput, numOfRows, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
fp(pLeftInputData, pRightOutput, numOfRows, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
} else if (pRight->nodeType == TSQL_NODE_COL) { // columnLeft + columnRight
|
||||
// column data specified on right-hand-side
|
||||
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pSchema->type, pRight->pSchema->type, pExprs->_node.optr);
|
||||
fp(pLeftInputData, pRightInputData, numOfRows, numOfRows, pOutput, order);
|
||||
|
||||
// both columns are descending order, do not reverse the source data
|
||||
fp(pLeftInputData, pRightInputData, numOfRows, numOfRows, pOutput, order);
|
||||
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // columnLeft + 12
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pSchema->type, pRight->pVal->nType, pExprs->_node.optr);
|
||||
fp(pLeftInputData, &pRight->pVal->i64Key, numOfRows, 1, pOutput, order);
|
||||
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows);
|
||||
fp(pdata, &pRight->pVal->i64Key, numOfRows, 1, pOutput, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
fp(pLeftInputData, &pRight->pVal->i64Key, numOfRows, 1, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// column data specified on left-hand-side
|
||||
if (pRight->nodeType == TSQL_NODE_EXPR) { // 12 + expr2
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pVal->nType, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
||||
fp(&pLeft->pVal->i64Key, pRightOutput, 1, numOfRows, pOutput, order);
|
||||
fp(&pLeft->pVal->i64Key, pRightOutput, 1, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||
|
||||
} else if (pRight->nodeType == TSQL_NODE_COL) { // 12 + columnRight
|
||||
// column data specified on right-hand-side
|
||||
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pVal->nType, pRight->pSchema->type, pExprs->_node.optr);
|
||||
fp(&pLeft->pVal->i64Key, pRightInputData, 1, numOfRows, pOutput, order);
|
||||
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
reverseCopy(pdata, pRightInputData, pRight->pSchema->type, numOfRows);
|
||||
fp(&pLeft->pVal->i64Key, pdata, numOfRows, 1, pOutput, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
fp(&pLeft->pVal->i64Key, pRightInputData, 1, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // 12 + 12
|
||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pVal->nType, pRight->pVal->nType, pExprs->_node.optr);
|
||||
fp(&pLeft->pVal->i64Key, &pRight->pVal->i64Key, 1, 1, pOutput, order);
|
||||
fp(&pLeft->pVal->i64Key, &pRight->pVal->i64Key, 1, 1, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "query.h"
|
||||
#include "queryLog.h"
|
||||
#include "tlosertree.h"
|
||||
#include "ttype.h"
|
||||
|
||||
#define MAX_ROWS_PER_RESBUF_PAGE ((1u<<12) - 1)
|
||||
|
||||
|
@ -194,6 +195,7 @@ static int32_t setAdditionalInfo(SQInfo *pQInfo, void *pTable, STableQueryInfo *
|
|||
static int32_t flushFromResultBuf(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo);
|
||||
static int32_t checkForQueryBuf(size_t numOfTables);
|
||||
static void releaseQueryBuf(size_t numOfTables);
|
||||
static int32_t binarySearchForKey(char *pValue, int num, TSKEY key, int order);
|
||||
|
||||
bool doFilterData(SQuery *pQuery, int32_t elemPos) {
|
||||
for (int32_t k = 0; k < pQuery->numOfFilterCols; ++k) {
|
||||
|
@ -400,6 +402,17 @@ static bool isTopBottomQuery(SQuery *pQuery) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool timeWindowInterpoRequired(SQuery *pQuery) {
|
||||
for(int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||
int32_t functionId = pQuery->pExpr1[i].base.functionId;
|
||||
if (functionId == TSDB_FUNC_TWA) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool hasTagValOutput(SQuery* pQuery) {
|
||||
SExprInfo *pExprInfo = &pQuery->pExpr1[0];
|
||||
if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP) {
|
||||
|
@ -457,6 +470,7 @@ static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWin
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// TODO refactor
|
||||
// more than the capacity, reallocate the resources
|
||||
if (pWindowResInfo->size >= pWindowResInfo->capacity) {
|
||||
int64_t newCapacity = 0;
|
||||
|
@ -595,14 +609,17 @@ static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedResultBuf
|
|||
}
|
||||
|
||||
static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo, SDataBlockInfo* pBockInfo,
|
||||
STimeWindow *win, bool masterscan, bool* newWind) {
|
||||
STimeWindow *win, bool masterscan, bool* newWind, SResultRow** pResult) {
|
||||
assert(win->skey <= win->ekey);
|
||||
SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf;
|
||||
|
||||
SResultRow *pResultRow = doPrepareResultRowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&win->skey, TSDB_KEYSIZE, masterscan, pBockInfo->uid);
|
||||
// todo refactor
|
||||
int64_t uid = getResultInfoUId(pRuntimeEnv);
|
||||
SResultRow *pResultRow = doPrepareResultRowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&win->skey, TSDB_KEYSIZE, masterscan, uid);
|
||||
if (pResultRow == NULL) {
|
||||
*newWind = false;
|
||||
|
||||
// no master scan, no result generated means error occurs
|
||||
return masterscan? -1:0;
|
||||
}
|
||||
|
||||
|
@ -618,15 +635,40 @@ static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowRes
|
|||
|
||||
// set time window for current result
|
||||
pResultRow->win = (*win);
|
||||
*pResult = pResultRow;
|
||||
setResultRowOutputBufInitCtx(pRuntimeEnv, pResultRow);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool getTimeWindowResStatus(SWindowResInfo *pWindowResInfo, int32_t slot) {
|
||||
static bool getResultRowStatus(SWindowResInfo *pWindowResInfo, int32_t slot) {
|
||||
assert(slot >= 0 && slot < pWindowResInfo->size);
|
||||
return pWindowResInfo->pResult[slot]->closed;
|
||||
}
|
||||
|
||||
typedef enum SResultTsInterpType {
|
||||
RESULT_ROW_START_INTERP = 1,
|
||||
RESULT_ROW_END_INTERP = 2,
|
||||
} SResultTsInterpType;
|
||||
|
||||
static void setResultRowInterpo(SResultRow* pResult, SResultTsInterpType type) {
|
||||
assert(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
|
||||
if (type == RESULT_ROW_START_INTERP) {
|
||||
pResult->startInterp = true;
|
||||
} else {
|
||||
pResult->endInterp = true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isResultRowInterpo(SResultRow* pResult, SResultTsInterpType type) {
|
||||
assert(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
|
||||
if (type == RESULT_ROW_START_INTERP) {
|
||||
return pResult->startInterp == true;
|
||||
} else {
|
||||
return pResult->endInterp == true;
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey, int16_t pos,
|
||||
int16_t order, int64_t *pData) {
|
||||
int32_t forwardStep = 0;
|
||||
|
@ -990,6 +1032,113 @@ static char *getDataBlock(SQueryRuntimeEnv *pRuntimeEnv, SArithmeticSupport *sas
|
|||
return dataBlock;
|
||||
}
|
||||
|
||||
// window start key interpolation
|
||||
static bool setTimeWindowInterpolationStartTs(SQueryRuntimeEnv* pRuntimeEnv, int32_t pos, SArray* pDataBlock, TSKEY* tsCols, STimeWindow* win) {
|
||||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
|
||||
TSKEY start = tsCols[pos];
|
||||
TSKEY lastTs = *(TSKEY *) pRuntimeEnv->prevRow[0];
|
||||
TSKEY prevTs = (pos == 0)? lastTs : tsCols[pos - 1];
|
||||
|
||||
// if lastTs == INT64_MIN, it is the first block, no need to do the start time interpolation
|
||||
if (((lastTs != INT64_MIN && pos >= 0) || (lastTs == INT64_MIN && pos > 0)) && win->skey > lastTs &&
|
||||
win->skey < start) {
|
||||
|
||||
for (int32_t k = 0; k < pQuery->numOfCols; ++k) {
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, k);
|
||||
if (k == 0 && pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
assert(pColInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||
continue;
|
||||
}
|
||||
|
||||
double v1 = 0, v2 = 0, v = 0;
|
||||
|
||||
char *prevVal = pos == 0 ? pRuntimeEnv->prevRow[k] : ((char*)pColInfo->pData) + (pos - 1) * pColInfo->info.bytes;
|
||||
|
||||
GET_TYPED_DATA(v1, double, pColInfo->info.type, (char *)prevVal);
|
||||
GET_TYPED_DATA(v2, double, pColInfo->info.type, (char *)pColInfo->pData + pos * pColInfo->info.bytes);
|
||||
|
||||
SPoint point1 = (SPoint){.key = prevTs, .val = &v1};
|
||||
SPoint point2 = (SPoint){.key = start, .val = &v2};
|
||||
SPoint point = (SPoint){.key = win->skey, .val = &v};
|
||||
taosGetLinearInterpolationVal(TSDB_DATA_TYPE_DOUBLE, &point1, &point2, &point);
|
||||
pRuntimeEnv->pCtx[k].start.key = point.key;
|
||||
pRuntimeEnv->pCtx[k].start.val = v;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
for (int32_t k = 0; k < pQuery->numOfCols; ++k) {
|
||||
pRuntimeEnv->pCtx[k].start.key = INT64_MIN;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool setTimeWindowInterpolationEndTs(SQueryRuntimeEnv* pRuntimeEnv, int32_t pos, SArray* pDataBlock, TSKEY* tsCols, TSKEY ekey, STimeWindow* win) {
|
||||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
TSKEY trueEndKey = tsCols[pos];
|
||||
|
||||
if (win->ekey < ekey && win->ekey != trueEndKey) {
|
||||
int32_t nextIndex = pos + 1;
|
||||
TSKEY next = tsCols[nextIndex];
|
||||
|
||||
for (int32_t k = 0; k < pQuery->numOfCols; ++k) {
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, k);
|
||||
if (k == 0 && pColInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP &&
|
||||
pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double v1 = 0, v2 = 0, v = 0;
|
||||
GET_TYPED_DATA(v1, double, pColInfo->info.type, (char *)pColInfo->pData + pos * pColInfo->info.bytes);
|
||||
GET_TYPED_DATA(v2, double, pColInfo->info.type, (char *)pColInfo->pData + nextIndex * pColInfo->info.bytes);
|
||||
|
||||
SPoint point1 = (SPoint){.key = trueEndKey, .val = &v1};
|
||||
SPoint point2 = (SPoint){.key = next, .val = &v2};
|
||||
SPoint point = (SPoint){.key = win->ekey, .val = &v};
|
||||
taosGetLinearInterpolationVal(TSDB_DATA_TYPE_DOUBLE, &point1, &point2, &point);
|
||||
pRuntimeEnv->pCtx[k].end.key = point.key;
|
||||
pRuntimeEnv->pCtx[k].end.val = v;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else { // current time window does not ended in current data block, do nothing
|
||||
for (int32_t k = 0; k < pQuery->numOfCols; ++k) {
|
||||
pRuntimeEnv->pCtx[k].end.key = INT64_MIN;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void saveDataBlockLastRow(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pDataBlockInfo, SArray* pDataBlock) {
|
||||
if (pDataBlock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
for (int32_t k = 0; k < pQuery->numOfCols; ++k) {
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, k);
|
||||
memcpy(pRuntimeEnv->prevRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * (pDataBlockInfo->rows - 1)),
|
||||
pColInfo->info.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static TSKEY getStartTsKey(SQuery* pQuery, SDataBlockInfo* pDataBlockInfo, TSKEY* tsCols, int32_t step) {
|
||||
TSKEY ts = TSKEY_INITIAL_VAL;
|
||||
|
||||
if (tsCols == NULL) {
|
||||
ts = QUERY_IS_ASC_QUERY(pQuery) ? pDataBlockInfo->window.skey : pDataBlockInfo->window.ekey;
|
||||
} else {
|
||||
int32_t offset = GET_COL_DATA_POS(pQuery, 0, step);
|
||||
ts = tsCols[offset];
|
||||
}
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* todo set the last value for pQueryTableInfo as in rowwiseapplyfunctions
|
||||
* @param pRuntimeEnv
|
||||
|
@ -1000,16 +1149,15 @@ static char *getDataBlock(SQueryRuntimeEnv *pRuntimeEnv, SArithmeticSupport *sas
|
|||
* @return the incremental number of output value, so it maybe 0 for fixed number of query,
|
||||
* such as count/min/max etc.
|
||||
*/
|
||||
static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pStatis,
|
||||
SDataBlockInfo *pDataBlockInfo, SWindowResInfo *pWindowResInfo,
|
||||
__block_search_fn_t searchFn, SArray *pDataBlock) {
|
||||
static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pStatis, SDataBlockInfo *pDataBlockInfo,
|
||||
SWindowResInfo *pWindowResInfo, __block_search_fn_t searchFn, SArray *pDataBlock) {
|
||||
SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx;
|
||||
bool masterScan = IS_MASTER_SCAN(pRuntimeEnv);
|
||||
bool masterScan = IS_MASTER_SCAN(pRuntimeEnv);
|
||||
|
||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||
TSKEY *tsCols = NULL;
|
||||
if (pDataBlock != NULL) {
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, 0);
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, 0);
|
||||
tsCols = (TSKEY *)(pColInfo->pData);
|
||||
}
|
||||
|
||||
|
@ -1018,7 +1166,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
|
|||
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
|
||||
SQInfo *pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
|
||||
for (int32_t k = 0; k < pQuery->numOfOutput; ++k) {
|
||||
char *dataBlock = getDataBlock(pRuntimeEnv, &sasArray[k], k, pDataBlockInfo->rows, pDataBlock);
|
||||
setExecParams(pQuery, &pCtx[k], dataBlock, tsCols, pDataBlockInfo, pStatis, &sasArray[k], k, pQInfo->vgId);
|
||||
|
@ -1026,18 +1174,13 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
|
|||
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order);
|
||||
if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
||||
TSKEY ts = TSKEY_INITIAL_VAL;
|
||||
TSKEY ts = getStartTsKey(pQuery, pDataBlockInfo, tsCols, step);
|
||||
|
||||
if (tsCols == NULL) {
|
||||
ts = QUERY_IS_ASC_QUERY(pQuery)? pDataBlockInfo->window.skey:pDataBlockInfo->window.ekey;
|
||||
} else {
|
||||
int32_t offset = GET_COL_DATA_POS(pQuery, 0, step);
|
||||
ts = tsCols[offset];
|
||||
}
|
||||
|
||||
bool hasTimeWindow = false;
|
||||
bool hasTimeWindow = false;
|
||||
SResultRow* pResult = NULL;
|
||||
STimeWindow win = getActiveTimeWindow(pWindowResInfo, ts, pQuery);
|
||||
if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &win, masterScan, &hasTimeWindow) != TSDB_CODE_SUCCESS) {
|
||||
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &win, masterScan, &hasTimeWindow, &pResult);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
tfree(sasArray);
|
||||
return;
|
||||
}
|
||||
|
@ -1045,11 +1188,32 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
|
|||
int32_t forwardStep = 0;
|
||||
int32_t startPos = pQuery->pos;
|
||||
|
||||
// in case of repeat scan/reverse scan, no new time window added.
|
||||
if (hasTimeWindow) {
|
||||
TSKEY ekey = reviseWindowEkey(pQuery, &win);
|
||||
forwardStep = getNumOfRowsInTimeWindow(pQuery, pDataBlockInfo, tsCols, pQuery->pos, ekey, searchFn, true);
|
||||
|
||||
bool pStatus = getTimeWindowResStatus(pWindowResInfo, curTimeWindowIndex(pWindowResInfo));
|
||||
// window start key interpolation
|
||||
if (pRuntimeEnv->timeWindowInterpo) {
|
||||
bool alreadyInterp = isResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
if (!alreadyInterp) {
|
||||
bool interp = setTimeWindowInterpolationStartTs(pRuntimeEnv, pQuery->pos, pDataBlock, tsCols, &win);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
}
|
||||
}
|
||||
|
||||
alreadyInterp = isResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
if (!alreadyInterp) {
|
||||
bool interp = setTimeWindowInterpolationEndTs(pRuntimeEnv, pQuery->pos + forwardStep - 1, pDataBlock, tsCols,
|
||||
pDataBlockInfo->window.ekey, &win);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool pStatus = getResultRowStatus(pWindowResInfo, curTimeWindowIndex(pWindowResInfo));
|
||||
doBlockwiseApplyFunctions(pRuntimeEnv, pStatus, &win, startPos, forwardStep, tsCols, pDataBlockInfo->rows);
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1229,8 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
|
|||
|
||||
// null data, failed to allocate more memory buffer
|
||||
hasTimeWindow = false;
|
||||
if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &nextWin, masterScan, &hasTimeWindow) != TSDB_CODE_SUCCESS) {
|
||||
if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &nextWin, masterScan, &hasTimeWindow, &pResult) !=
|
||||
TSDB_CODE_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1076,7 +1241,26 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
|
|||
TSKEY ekey = reviseWindowEkey(pQuery, &nextWin);
|
||||
forwardStep = getNumOfRowsInTimeWindow(pQuery, pDataBlockInfo, tsCols, startPos, ekey, searchFn, true);
|
||||
|
||||
bool closed = getTimeWindowResStatus(pWindowResInfo, curTimeWindowIndex(pWindowResInfo));
|
||||
// window start(end) key interpolation
|
||||
if (pRuntimeEnv->timeWindowInterpo) {
|
||||
bool alreadyInterp = isResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
if (!alreadyInterp) {
|
||||
bool interp = setTimeWindowInterpolationStartTs(pRuntimeEnv, startPos, pDataBlock, tsCols, &nextWin);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
}
|
||||
}
|
||||
|
||||
alreadyInterp = isResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
if (!alreadyInterp) {
|
||||
bool interp = setTimeWindowInterpolationEndTs(pRuntimeEnv, startPos + forwardStep - 1, pDataBlock, tsCols, pDataBlockInfo->window.ekey, &nextWin);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool closed = getResultRowStatus(pWindowResInfo, curTimeWindowIndex(pWindowResInfo));
|
||||
doBlockwiseApplyFunctions(pRuntimeEnv, closed, &nextWin, startPos, forwardStep, tsCols, pDataBlockInfo->rows);
|
||||
}
|
||||
|
||||
|
@ -1090,12 +1274,17 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
|
|||
for (int32_t k = 0; k < pQuery->numOfOutput; ++k) {
|
||||
int32_t functionId = pQuery->pExpr1[k].base.functionId;
|
||||
if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) {
|
||||
pCtx[k].nStartQueryTimestamp = pDataBlockInfo->window.skey;
|
||||
aAggs[functionId].xFunction(&pCtx[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||
if (pRuntimeEnv->timeWindowInterpo) {
|
||||
saveDataBlockLastRow(pRuntimeEnv, pDataBlockInfo, pDataBlock);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||
if (pQuery->pExpr1[i].base.functionId != TSDB_FUNC_ARITHM) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1318,20 +1507,20 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
|||
pQuery->order.order, pRuntimeEnv->pTSBuf->cur.order);
|
||||
}
|
||||
|
||||
int32_t j = 0;
|
||||
int32_t offset = -1;
|
||||
// TSKEY prev = -1;
|
||||
|
||||
for (j = 0; j < pDataBlockInfo->rows; ++j) {
|
||||
for (int32_t j = 0; j < pDataBlockInfo->rows; ++j) {
|
||||
offset = GET_COL_DATA_POS(pQuery, j, step);
|
||||
|
||||
if (pRuntimeEnv->pTSBuf != NULL) {
|
||||
int32_t r = doTSJoinFilter(pRuntimeEnv, offset);
|
||||
if (r == TS_JOIN_TAG_NOT_EQUALS) {
|
||||
int32_t ret = doTSJoinFilter(pRuntimeEnv, offset);
|
||||
if (ret == TS_JOIN_TAG_NOT_EQUALS) {
|
||||
break;
|
||||
} else if (r == TS_JOIN_TS_NOT_EQUALS) {
|
||||
} else if (ret == TS_JOIN_TS_NOT_EQUALS) {
|
||||
continue;
|
||||
} else {
|
||||
assert(r == TS_JOIN_TS_EQUAL);
|
||||
assert(ret == TS_JOIN_TS_EQUAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1344,8 +1533,9 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
|||
int64_t ts = tsCols[offset];
|
||||
STimeWindow win = getActiveTimeWindow(pWindowResInfo, ts, pQuery);
|
||||
|
||||
bool hasTimeWindow = false;
|
||||
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &win, masterScan, &hasTimeWindow);
|
||||
bool hasTimeWindow = false;
|
||||
SResultRow* pResult = NULL;
|
||||
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &win, masterScan, &hasTimeWindow, &pResult);
|
||||
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||
continue;
|
||||
}
|
||||
|
@ -1353,8 +1543,28 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
|||
if (!hasTimeWindow) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
// window start key interpolation
|
||||
if (pRuntimeEnv->timeWindowInterpo) {
|
||||
bool alreadyInterp = isResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
if (!alreadyInterp) {
|
||||
bool interp = setTimeWindowInterpolationStartTs(pRuntimeEnv, pos, pDataBlock, tsCols, &win);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
}
|
||||
}
|
||||
|
||||
bool closed = getTimeWindowResStatus(pWindowResInfo, curTimeWindowIndex(pWindowResInfo));
|
||||
alreadyInterp = isResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
if (!alreadyInterp) {
|
||||
bool interp = setTimeWindowInterpolationEndTs(pRuntimeEnv, pQuery->pos + forwardStep - 1, pDataBlock, tsCols,
|
||||
pDataBlockInfo->window.ekey, &win);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
bool closed = getResultRowStatus(pWindowResInfo, curTimeWindowIndex(pWindowResInfo));
|
||||
doRowwiseApplyFunctions(pRuntimeEnv, closed, &win, offset);
|
||||
|
||||
STimeWindow nextWin = win;
|
||||
|
@ -1373,12 +1583,32 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
|||
|
||||
// null data, failed to allocate more memory buffer
|
||||
hasTimeWindow = false;
|
||||
if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &nextWin, masterScan, &hasTimeWindow) != TSDB_CODE_SUCCESS) {
|
||||
if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &nextWin, masterScan, &hasTimeWindow, &pResult) != TSDB_CODE_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasTimeWindow) {
|
||||
closed = getTimeWindowResStatus(pWindowResInfo, curTimeWindowIndex(pWindowResInfo));
|
||||
/*
|
||||
// window start(end) key interpolation
|
||||
if (pRuntimeEnv->timeWindowInterpo) {
|
||||
bool alreadyInterp = isResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
if (!alreadyInterp) {
|
||||
bool interp = setTimeWindowInterpolationStartTs(pRuntimeEnv, startPos, pDataBlock, tsCols, &nextWin);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
}
|
||||
}
|
||||
|
||||
alreadyInterp = isResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
if (!alreadyInterp) {
|
||||
bool interp = setTimeWindowInterpolationEndTs(pRuntimeEnv, startPos + forwardStep - 1, pDataBlock, tsCols, pDataBlockInfo->window.ekey, &nextWin);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
closed = getResultRowStatus(pWindowResInfo, curTimeWindowIndex(pWindowResInfo));
|
||||
doRowwiseApplyFunctions(pRuntimeEnv, closed, &nextWin, offset);
|
||||
}
|
||||
}
|
||||
|
@ -1403,6 +1633,8 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
|||
}
|
||||
}
|
||||
|
||||
// prev = tsCols[offset];
|
||||
|
||||
if (pRuntimeEnv->pTSBuf != NULL) {
|
||||
// if timestamp filter list is empty, quit current query
|
||||
if (!tsBufNextPos(pRuntimeEnv->pTSBuf)) {
|
||||
|
@ -1528,10 +1760,10 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
|
|||
* top/bottom values emerge, so does diff function
|
||||
*/
|
||||
if (functionId == TSDB_FUNC_TWA) {
|
||||
SResultRowCellInfo* pInfo = GET_RES_INFO(pCtx);
|
||||
STwaInfo *pTWAInfo = (STwaInfo*) GET_ROWCELL_INTERBUF(pInfo);
|
||||
pTWAInfo->SKey = pQuery->window.skey;
|
||||
pTWAInfo->EKey = pQuery->window.ekey;
|
||||
pCtx->param[1].i64Key = pQuery->window.skey;
|
||||
pCtx->param[1].nType = TSDB_DATA_TYPE_BIGINT;
|
||||
pCtx->param[2].i64Key = pQuery->window.ekey;
|
||||
pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT;
|
||||
}
|
||||
|
||||
} else if (functionId == TSDB_FUNC_ARITHM) {
|
||||
|
@ -1677,6 +1909,8 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
|
|||
pCtx->functionId = pSqlFuncMsg->functionId;
|
||||
pCtx->stableQuery = pRuntimeEnv->stableQuery;
|
||||
pCtx->interBufBytes = pQuery->pExpr1[i].interBytes;
|
||||
pCtx->start.key = INT64_MIN;
|
||||
pCtx->end.key = INT64_MIN;
|
||||
|
||||
pCtx->numOfParams = pSqlFuncMsg->numOfParams;
|
||||
for (int32_t j = 0; j < pCtx->numOfParams; ++j) {
|
||||
|
@ -1711,6 +1945,8 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
|
|||
|
||||
}
|
||||
|
||||
*(int64_t*) pRuntimeEnv->prevRow[0] = INT64_MIN;
|
||||
|
||||
// if it is group by normal column, do not set output buffer, the output buffer is pResult
|
||||
// fixed output query/multi-output query for normal table
|
||||
if (!pRuntimeEnv->groupbyNormalCol && !pRuntimeEnv->stableQuery && !QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQuery)) {
|
||||
|
@ -1781,6 +2017,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
|
|||
tfree(pRuntimeEnv->offset);
|
||||
tfree(pRuntimeEnv->keyBuf);
|
||||
tfree(pRuntimeEnv->rowCellInfoOffset);
|
||||
tfree(pRuntimeEnv->prevRow);
|
||||
|
||||
taosHashCleanup(pRuntimeEnv->pResultRowHashTable);
|
||||
pRuntimeEnv->pResultRowHashTable = NULL;
|
||||
|
@ -2279,12 +2516,14 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo * pW
|
|||
// the filter result may be incorrect. So in case of interval query, we need to set the correct time output buffer
|
||||
if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
||||
bool hasTimeWindow = false;
|
||||
SResultRow* pResult = NULL;
|
||||
|
||||
bool masterScan = IS_MASTER_SCAN(pRuntimeEnv);
|
||||
|
||||
TSKEY k = QUERY_IS_ASC_QUERY(pQuery)? pBlockInfo->window.skey:pBlockInfo->window.ekey;
|
||||
|
||||
STimeWindow win = getActiveTimeWindow(pWindowResInfo, k, pQuery);
|
||||
if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pBlockInfo, &win, masterScan, &hasTimeWindow) !=
|
||||
if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pBlockInfo, &win, masterScan, &hasTimeWindow, &pResult) !=
|
||||
TSDB_CODE_SUCCESS) {
|
||||
// todo handle error in set result for timewindow
|
||||
}
|
||||
|
@ -3266,7 +3505,7 @@ static void disableFuncInReverseScanImpl(SQueryRuntimeEnv* pRuntimeEnv, SWindowR
|
|||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
|
||||
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
|
||||
bool closed = getTimeWindowResStatus(pWindowResInfo, i);
|
||||
bool closed = getResultRowStatus(pWindowResInfo, i);
|
||||
if (!closed) {
|
||||
continue;
|
||||
}
|
||||
|
@ -4617,6 +4856,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
|
|||
|
||||
pRuntimeEnv->topBotQuery = isTopBottomQuery(pQuery);
|
||||
pRuntimeEnv->hasTagResults = hasTagValOutput(pQuery);
|
||||
pRuntimeEnv->timeWindowInterpo = timeWindowInterpoRequired(pQuery);
|
||||
|
||||
setScanLimitationByResultBuffer(pQuery);
|
||||
|
||||
|
@ -6447,9 +6687,11 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
|
|||
goto _cleanup;
|
||||
}
|
||||
|
||||
int32_t srcSize = 0;
|
||||
for (int16_t i = 0; i < numOfCols; ++i) {
|
||||
pQuery->colList[i] = pQueryMsg->colList[i];
|
||||
pQuery->colList[i].filters = tscFilterInfoClone(pQueryMsg->colList[i].filters, pQuery->colList[i].numOfFilters);
|
||||
srcSize += pQuery->colList[i].bytes;
|
||||
}
|
||||
|
||||
// calculate the result row size
|
||||
|
@ -6518,6 +6760,14 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
|
|||
pQInfo->runtimeEnv.pResultRowHashTable = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
||||
pQInfo->runtimeEnv.keyBuf = malloc(TSDB_MAX_BYTES_PER_ROW);
|
||||
pQInfo->runtimeEnv.pool = initResultRowPool(getWindowResultSize(&pQInfo->runtimeEnv));
|
||||
pQInfo->runtimeEnv.prevRow = malloc(POINTER_BYTES * pQuery->numOfCols + srcSize);
|
||||
|
||||
char* start = POINTER_BYTES * pQuery->numOfCols + (char*) pQInfo->runtimeEnv.prevRow;
|
||||
pQInfo->runtimeEnv.prevRow[0] = start;
|
||||
|
||||
for(int32_t i = 1; i < pQuery->numOfCols; ++i) {
|
||||
pQInfo->runtimeEnv.prevRow[i] = pQInfo->runtimeEnv.prevRow[i - 1] + pQuery->colList[i-1].bytes;
|
||||
}
|
||||
|
||||
pQInfo->pBuf = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
|
||||
if (pQInfo->pBuf == NULL) {
|
||||
|
|
|
@ -395,11 +395,10 @@ uint64_t getResultInfoUId(SQueryRuntimeEnv* pRuntimeEnv) {
|
|||
}
|
||||
|
||||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
if ((pQuery->checkBuffer == 1 && pQuery->interval.interval == 0) || isPointInterpoQuery(pQuery) ||
|
||||
pRuntimeEnv->groupbyNormalCol) {
|
||||
if (pQuery->interval.interval == 0 || isPointInterpoQuery(pQuery) || pRuntimeEnv->groupbyNormalCol) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
STableId* id = TSDB_TABLEID(pRuntimeEnv->pQuery->current);
|
||||
STableId* id = TSDB_TABLEID(pRuntimeEnv->pQuery->current->pTable);
|
||||
return id->uid;
|
||||
}
|
|
@ -117,16 +117,17 @@ run general/parser/col_arithmetic_query.sim
|
|||
# ================================================================================================
|
||||
|
||||
print ====================> crash
|
||||
# sql select spread(ts )/(1000*3600*24) from ca_stb0 interval(1y)
|
||||
sql use $db
|
||||
sql select spread(ts )/(1000*3600*24) from $stb interval(1y)
|
||||
|
||||
sql_error select first(c1, c2) - last(c1, c2) from stb interval(1y)
|
||||
sql_error select first(ts) - last(ts) from stb interval(1y)
|
||||
sql_error select top(c1, 2) - last(c1) from stb;
|
||||
sql_error select stddev(c1) - last(c1) from stb;
|
||||
sql_error select diff(c1) - last(c1) from stb;
|
||||
sql_error select first(c7) - last(c7) from stb;
|
||||
sql_error select first(c8) - last(c8) from stb;
|
||||
sql_error select first(c9) - last(c9) from stb;
|
||||
sql_error select first(c1, c2) - last(c1, c2) from $stb interval(1y)
|
||||
sql_error select first(ts) - last(ts) from $stb interval(1y)
|
||||
sql_error select top(c1, 2) - last(c1) from $stb;
|
||||
sql_error select stddev(c1) - last(c1) from $stb;
|
||||
sql_error select diff(c1) - last(c1) from $stb;
|
||||
sql_error select first(c7) - last(c7) from $stb;
|
||||
sql_error select first(c8) - last(c8) from $stb;
|
||||
sql_error select first(c9) - last(c9) from $stb;
|
||||
sql_error select max(c2*2) from $tb
|
||||
sql_error select max(c1-c2) from $tb
|
||||
|
||||
|
|
|
@ -62,24 +62,73 @@ if $data91 != 1.000000000 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
sql select (c1 * 2) % 7.9 from $tb order by ts desc;
|
||||
sql select (c1 * 2) % 7.9, c1*1, c1*1*1, c1*c1, c1*c1*c1 from $tb order by ts desc;
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.100000000 then
|
||||
print expect 0.100000000, acutal:$data00
|
||||
if $data00 != 2.200000000 then
|
||||
print expect 2.200000000, actual:$data00
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != 2.100000000 then
|
||||
if $data01 != 9.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data90 != 6.000000000 then
|
||||
if $data02 != 9.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 81.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data04 != 729.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
if $data10 != 0.200000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data11 != 8.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data12 != 8.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data13 != 64.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data14 != 512.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data90 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data91 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data92 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data93 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data94 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# [d.3]
|
||||
sql select c1 * c2 /4 from $tb where ts < 1537166000000 and ts > 1537156000000
|
||||
if $rows != 17 then
|
||||
|
@ -95,7 +144,7 @@ if $data10 != 16.000000000 then
|
|||
endi
|
||||
|
||||
if $data20 != 20.250000000 then
|
||||
print expect 20.250000000, acutal:$data21
|
||||
print expect 20.250000000, actual:$data21
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -320,7 +369,9 @@ sql_error select c7-c9 from $tb interval(2y)
|
|||
# multiple retrieve [d.20]===============================================================
|
||||
sql select c2-c2, 911 from $tb
|
||||
|
||||
#======================================= aggregation function arithmetic query cases ================
|
||||
#======================================= aggregation function arithmetic query cases ===================================
|
||||
# on $tb percentile() spread(ts) bug
|
||||
|
||||
# asc/desc order [d.2]
|
||||
sql select first(c1) * ( 2 / 3 ) from $stb order by ts asc;
|
||||
if $rows != 1 then
|
||||
|
@ -349,11 +400,11 @@ if $data00 != 1.800000000 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 100000 then
|
||||
if $data01 != 100000.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 200000 then
|
||||
if $data02 != 200000.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -374,77 +425,192 @@ if $data02 != 9.000000020 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
# all possible function in the arithmetic expressioin
|
||||
sql select min(c1) * max(c2) /4, sum(c1) * percentile(c2, 20), apercentile(c4, 33) + 52/9, spread(c5)/min(c2) from $stb where ts < and ts >
|
||||
# all possible function in the arithmetic expression, add more
|
||||
sql select min(c1) * max(c2) /4, sum(c1) * apercentile(c2, 20), apercentile(c4, 33) + 52/9, spread(c5)/min(c2), count(1)/sum(c1), avg(c2)*count(c2) from $stb where ts >= '2018-09-17 09:00:00.000' and ts <= '2018-11-25 19:30:00.000';
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# no result return [d.3]
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 225000.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 8.077777778 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != inf then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data04 != 0.444444444 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data05 != 450000.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# no result return [d.3]===============================================================
|
||||
sql select first(c1) * 91 - 7, last(c3) from $stb where ts < 1537146000000
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# no result return [d.3]
|
||||
sql select sum(c2) - avg(c2) from $tb where ts>xxx
|
||||
sql select sum(c2) - avg(c2) from $stb where ts > '2018-11-25 19:30:00.000'
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# single row result aggregation [d.4]
|
||||
sql select
|
||||
# single row result aggregation [d.4]===================================================
|
||||
# all those cases are aggregation test cases.
|
||||
|
||||
# error cases
|
||||
sql_error select first(c1, c2) - last(c1, c2) from $tb
|
||||
sql_error select first(c1, c2) - last(c1, c2) from $stb
|
||||
sql_error select top(c1, 5) - bottom(c1, 5) from $stb
|
||||
sql_error select first(*) - 99 from $stb
|
||||
|
||||
# multi row result aggregation [d.4]
|
||||
sql select top(c1, 1) - bottom(c1, 1) from $tb
|
||||
sql select top(c1, 99) - bottom(c1, 99) from $tb
|
||||
sql_error select top(c1, 1) - bottom(c1, 1) from $stb
|
||||
sql_error select top(c1, 99) - bottom(c1, 99) from $stb
|
||||
|
||||
# all data types [d.6]
|
||||
sql select c2-c1, c3/c2, c4*c3, c5%c4, c6+99%22 from $tb
|
||||
# query on super table [d.5]=============================================================
|
||||
# all cases in this part are query on super table
|
||||
|
||||
# all data types [d.6]===================================================================
|
||||
sql select c2-c1, c3/c2, c4*c3, c5%c4, c6+99%22 from $stb
|
||||
|
||||
# error case, ts/bool/binary/nchar not support arithmetic expression
|
||||
sql_error select ts+ts from $tb
|
||||
sql_error select ts+22 from $tb
|
||||
sql_error select c7*12 from $tb
|
||||
sql_error select c8/55 from $tb
|
||||
sql_error select c9+c8 from $tb
|
||||
sql_error select first(c7)*12 from $stb
|
||||
sql_error select last(c8)/55 from $stb
|
||||
sql_error select last_row(c9) + last_row(c8) from $stb
|
||||
|
||||
# arithmetic expression in join [d.7]
|
||||
# arithmetic expression in join [d.7]===============================================================
|
||||
|
||||
|
||||
# arithmetic expression in union [d.8]
|
||||
# arithmetic expression in union [d.8]===============================================================
|
||||
|
||||
|
||||
# arithmetic expression in group by [d.9]
|
||||
# arithmetic expression in group by [d.9]===============================================================
|
||||
# in group by tag
|
||||
# not support for normal table
|
||||
sql_error select c5*99 from $tb group by t1
|
||||
sql select avg(c4)*99 from $stb group by t1
|
||||
if $rows != 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 445.500000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data90 != 445.500000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data91 != 9 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# in group by column
|
||||
sql_error select c6-c6+c3*12 from $tb group by c3;
|
||||
sql select apercentile(c6, 50)-first(c6)+last(c5)*12, last(c5)*12 from ca_stb0 group by c2;
|
||||
if $rows != 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select first(c6) - last(c6) *12 / count(*) from $tb group by c3;
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# limit offset [d.10]
|
||||
sql select c6-c6+12 from $tb limit 12 offset 99;
|
||||
sql select c4/99.123 from $tb limit 1 offset 9999;
|
||||
if $data01 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# slimit/soffset not suport for normal table query. [d.11]
|
||||
sql_error select sum(c1) from $tb slimit 1 soffset 19;
|
||||
if $data10 != 12.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# fill [d.12]
|
||||
sql_error select c2-c2, c3-c4, c5%c6 from $tb fill(value, 12);
|
||||
if $data11 != 12.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# constant column. [d.13]
|
||||
if $data20 != 24.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data21 != 24.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql_error select first(c6) - last(c6) *12 / count(*) from $stb group by c3;
|
||||
|
||||
sql select first(c6) - last(c6) *12 / count(*) from $stb group by c5;
|
||||
if $rows != 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != 0.997600000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data90 != 8.978400000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# limit offset [d.10]===============================================================
|
||||
sql select first(c6) - sum(c6) + 12 from $stb limit 12 offset 0;
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != -449988.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select apercentile(c4, 21) / 99.123 from $stb limit 1 offset 1;
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select apercentile(c4, 21) / sum(c4) from $stb interval(1s) limit 1 offset 1;
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# slimit/soffset not support for normal table query. [d.11]===============================================================
|
||||
sql select sum(c1) from $stb slimit 1 soffset 19;
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select sum(c1) from $stb interval(1s) group by tbname slimit 1 soffset 1
|
||||
sql select sum(c1) from ca_stb0 interval(1s) group by tbname slimit 2 soffset 4 limit 10 offset 1
|
||||
|
||||
# fill [d.12]===============================================================
|
||||
sql_error select first(c1)-last(c1), sum(c3)*count(c3), spread(c5 ) % count(*) from $stb interval(1s) fill(prev);
|
||||
sql_error select first(c1) from $stb fill(value, 20);
|
||||
|
||||
# constant column. [d.13]===============================================================
|
||||
|
||||
|
||||
# column value filter [d.14]
|
||||
# column value filter [d.14]===============================================================
|
||||
|
||||
|
||||
# tag filter(not support for normal table). [d.15]
|
||||
sql_error select sum(c2)+99 from $tb where t1=12;
|
||||
# tag filter. [d.15]===============================================================
|
||||
sql select sum(c2)+99 from $stb where t1=12;
|
||||
|
||||
# multi-field output [d.16]
|
||||
# multi-field output [d.16]===============================================================
|
||||
sql select count(*), sum(c1)*avg(c2), avg(c3)*count(c3), sum(c3), sum(c4), first(c7), last(c8), first(c9), first(c7), last(c8) from $tb
|
||||
|
||||
sql select c4*1+1/2 from $tb
|
||||
|
@ -461,18 +627,30 @@ if $data90 != 9.500000000 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
# interval query [d.17]
|
||||
sql_error select c2*c2, c3-c3, c4+9 from $tb interval(1s)
|
||||
sql_error select c7-c9 from $tb interval(2y)
|
||||
# interval query [d.17]===============================================================
|
||||
sql select avg(c2)*count(c2), sum(c3)-first(c3), last(c4)+9 from $stb interval(1s)
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# aggregation query [d.18]
|
||||
# see test cases below
|
||||
if $data00 != @18-09-17 09:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# first/last query [d.19]
|
||||
# see test cases below
|
||||
sql_error select first(c7)- last(c1) from $tb interval(2y)
|
||||
|
||||
# multiple retrieve [d.20]
|
||||
sql select c2-c2 from $tb;
|
||||
# aggregation query [d.18]===============================================================
|
||||
# all cases in this part are aggregation query test.
|
||||
|
||||
# first/last query [d.19]===============================================================
|
||||
|
||||
|
||||
# multiple retrieve [d.20]===============================================================
|
||||
sql select c2-c2 from $tb
|
||||
|
||||
|
||||
sql select first(c1)-last(c1), spread(c2), max(c3) - min(c3), avg(c4)*count(c4) from $tb
|
||||
|
||||
|
||||
#====================================================super table query==================================================
|
||||
|
||||
|
|
|
@ -703,13 +703,13 @@ sql select twa(c1), twa(c2), twa(c3), twa(c4), twa(c5), twa(c6) from $tb where t
|
|||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 4.499549955 then
|
||||
if $data00 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data02 != 4.499549955 then
|
||||
if $data02 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data05 != 4.499549955 then
|
||||
if $data05 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -717,10 +717,12 @@ sql select first(c1), first(c2), first(c3), first(c4), first(c5), first(c6) from
|
|||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select first(c1), first(c2), first(c3), first(c4), first(c5), first(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(30m) limit 3 offset 1
|
||||
if $rows != 3 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 3 then
|
||||
return -1
|
||||
endi
|
||||
|
@ -731,7 +733,6 @@ if $data23 != 9.00000 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
|
||||
sql select last(c1), last(c2), last(c3), last(c4), last(c5), last(c6) from $tb where ts >= $ts0 and ts <= $tsu limit 5 offset 1
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
|
|
|
@ -327,22 +327,22 @@ sql select twa(c1), twa(c2), twa(c3), twa(c4), twa(c5), twa(c6) from $tb where t
|
|||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 4.000000000 then
|
||||
if $data00 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data01 != 4.000000000 then
|
||||
if $data01 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data02 != 4.000000000 then
|
||||
if $data02 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data03 != 4.000000000 then
|
||||
if $data03 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data04 != 4.000000000 then
|
||||
if $data04 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data05 != 4.000000000 then
|
||||
if $data05 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -690,13 +690,13 @@ sql select twa(c1), twa(c2), twa(c3), twa(c4), twa(c5), twa(c6) from $tb where t
|
|||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 4.000000000 then
|
||||
if $data00 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data02 != 4.000000000 then
|
||||
if $data02 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data05 != 4.000000000 then
|
||||
if $data05 != 4.500000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -131,7 +131,6 @@ if $data00 != $rowNum then
|
|||
return -1
|
||||
endi
|
||||
|
||||
|
||||
## like
|
||||
sql_error select * from $mt where c1 like 1
|
||||
#sql_error select * from $mt where t1 like 1
|
||||
|
@ -178,7 +177,8 @@ sql create table wh_mt2_tb1 using wh_mt2 tags ('wh_mt2_tb1')
|
|||
# 2019-01-01 09:00:00.000 1546304400000
|
||||
# 2019-01-01 09:10:00.000 1546305000000
|
||||
sql insert into wh_mt2_tb1 values ('2019-01-01 00:00:00.000', '2019-01-01 09:00:00.000', 'binary10', 'nchar10')
|
||||
sql insert into wh_mt2_tb1 values ('2019-01-01 00:10:00.000', '2019-01-01 09:10:00.000', 'binary10', 'nchar10')
|
||||
sql insert into wh_mt2_tb1 values ('2019-01-01 00:10:00.000', '2019-01-01 09:10:00.000', 'binary10', 'nchar10')
|
||||
|
||||
sql select * from wh_mt2_tb1 where c1 > 1546304400000
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
|
|
Loading…
Reference in New Issue