diff --git a/deps/MsvcLibX/include/msvcUnistd.h b/deps/MsvcLibX/include/msvcUnistd.h
index 9ad60625e0..9b59bae7f0 100644
--- a/deps/MsvcLibX/include/msvcUnistd.h
+++ b/deps/MsvcLibX/include/msvcUnistd.h
@@ -89,11 +89,12 @@ pid_t getppid(void); /* Get parent PID */
/* Path management */
#if defined(_WIN32)
-#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
#define realpath realpathU
+#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+// #define realpath realpathU
#define CompactPath CompactPathU
#else /* _ANSI_SOURCE */
-#define realpath realpathA
+// #define realpath realpathA
#define CompactPath CompactPathA
#endif
#endif /* defined(_WIN32) */
diff --git a/deps/rmonotonic/src/monotonic.c b/deps/rmonotonic/src/monotonic.c
index 622ac1b075..1470f91b56 100644
--- a/deps/rmonotonic/src/monotonic.c
+++ b/deps/rmonotonic/src/monotonic.c
@@ -84,11 +84,11 @@ static void monotonicInit_x86linux() {
regfree(&constTscRegex);
if (mono_ticksPerMicrosecond == 0) {
- fprintf(stderr, "monotonic: x86 linux, unable to determine clock rate");
+ //fprintf(stderr, "monotonic: x86 linux, unable to determine clock rate");
return;
}
if (!constantTsc) {
- fprintf(stderr, "monotonic: x86 linux, 'constant_tsc' flag not present");
+ //fprintf(stderr, "monotonic: x86 linux, 'constant_tsc' flag not present");
return;
}
diff --git a/documentation20/webdocs/markdowndocs/connector-ch.md b/documentation20/webdocs/markdowndocs/connector-ch.md
index bcaabe3c0a..6736eea7c7 100644
--- a/documentation20/webdocs/markdowndocs/connector-ch.md
+++ b/documentation20/webdocs/markdowndocs/connector-ch.md
@@ -852,7 +852,7 @@ npm install td2.0-connector
### Linux
- `python` (建议`v2.7` , `v3.x.x` 目前还不支持)
-- `node` 必须采用v10.x版本,其他版本存在包兼容性的问题。
+- `node` 2.0.6支持v12.x和v10.x,2.0.5及更早版本支持v10.x版本,其他版本可能存在包兼容性的问题。
- `make`
- c语言编译器比如GCC
diff --git a/src/client/inc/tscSubquery.h b/src/client/inc/tscSubquery.h
index e1370513ef..15ef54b7b1 100644
--- a/src/client/inc/tscSubquery.h
+++ b/src/client/inc/tscSubquery.h
@@ -33,6 +33,7 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index);
void tscHandleMasterJoinQuery(SSqlObj* pSql);
int32_t tscHandleMasterSTableQuery(SSqlObj *pSql);
+int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql);
int32_t tscHandleMultivnodeInsert(SSqlObj *pSql);
diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h
index ce623cdc03..e78e259eb2 100644
--- a/src/client/inc/tscUtil.h
+++ b/src/client/inc/tscUtil.h
@@ -132,8 +132,9 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo);
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
bool tscQueryTags(SQueryInfo* pQueryInfo);
+bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
-SSqlExpr* tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
+SSqlExpr* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType);
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql);
@@ -174,6 +175,7 @@ SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIn
SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
int16_t size);
size_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo);
+void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index);
int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h
index c9702ad1fc..bdb0173e9c 100644
--- a/src/client/inc/tsclient.h
+++ b/src/client/inc/tsclient.h
@@ -224,7 +224,9 @@ typedef struct SQueryInfo {
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
int16_t resColumnId; // result column id
bool distinctTag; // distinct tag or not
-
+ int32_t round; // 0/1/....
+ int32_t bufLen;
+ char* buf;
} SQueryInfo;
typedef struct {
@@ -412,10 +414,9 @@ void tscQueueAsyncError(void(*fp), void *param, int32_t code);
int tscProcessLocalCmd(SSqlObj *pSql);
int tscCfgDynamicOptions(char *msg);
-int taos_retrieve(TAOS_RES *res);
-int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo *pQueryInfo);
-void tscRestoreSQLFuncForSTableQuery(SQueryInfo *pQueryInfo);
+int32_t tscTansformFuncForSTableQuery(SQueryInfo *pQueryInfo);
+void tscRestoreFuncForSTableQuery(SQueryInfo *pQueryInfo);
int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c
index 97426b2dd1..da350197d4 100644
--- a/src/client/src/tscLocalMerge.c
+++ b/src/client/src/tscLocalMerge.c
@@ -68,7 +68,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescr
SQLFunctionCtx *pCtx = &pReducer->pCtx[i];
SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i);
- pCtx->aOutputBuf = pReducer->pResultBuf->data + pExpr->offset * pReducer->resColModel->capacity;
+ pCtx->pOutput = pReducer->pResultBuf->data + pExpr->offset * pReducer->resColModel->capacity;
pCtx->order = pQueryInfo->order.order;
pCtx->functionId = pExpr->functionId;
@@ -76,7 +76,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescr
int16_t offset = getColumnModelOffset(pDesc->pColumnModel, i);
SSchema *pSchema = getColumnModelSchema(pDesc->pColumnModel, i);
- pCtx->aInputElemBuf = pReducer->pTempBuffer->data + offset;
+ pCtx->pInput = pReducer->pTempBuffer->data + offset;
// input data format comes from pModel
pCtx->inputType = pSchema->type;
@@ -94,7 +94,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescr
// for top/bottom function, the output of timestamp is the first column
int32_t functionId = pExpr->functionId;
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
- pCtx->ptsOutputBuf = pReducer->pCtx[0].aOutputBuf;
+ pCtx->ptsOutputBuf = pReducer->pCtx[0].pOutput;
pCtx->param[2].i64 = pQueryInfo->order.order;
pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT;
pCtx->param[1].i64 = pQueryInfo->order.orderColId;
@@ -118,7 +118,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescr
if (pExpr->functionId == TSDB_FUNC_TAG_DUMMY || pExpr->functionId == TSDB_FUNC_TS_DUMMY) {
tagLen += pExpr->resBytes;
pTagCtx[n++] = &pReducer->pCtx[i];
- } else if ((aAggs[pExpr->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
+ } else if ((aAggs[pExpr->functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
pCtx = &pReducer->pCtx[i];
}
}
@@ -311,7 +311,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
pReducer->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx));
pReducer->rowSize = pMemBuffer[0]->nElemSize;
- tscRestoreSQLFuncForSTableQuery(pQueryInfo);
+ tscRestoreFuncForSTableQuery(pQueryInfo);
tscFieldInfoUpdateOffset(pQueryInfo);
if (pReducer->rowSize > pMemBuffer[0]->pageSize) {
@@ -383,7 +383,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
if (pQueryInfo->fillType != TSDB_FILL_NONE) {
SFillColInfo* pFillCol = createFillColInfo(pQueryInfo);
- pReducer->pFillInfo = taosInitFillInfo(pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols,
+ pReducer->pFillInfo = taosCreateFillInfo(pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols,
4096, (int32_t)pQueryInfo->fieldsInfo.numOfOutput, pQueryInfo->interval.sliding, pQueryInfo->interval.slidingUnit,
tinfo.precision, pQueryInfo->fillType, pFillCol, pSql);
}
@@ -720,7 +720,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
SSchema p1 = {0};
if (pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
- p1 = tGetTableNameColumnSchema();
+ p1 = *tGetTbnameColumnSchema();
} else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) {
p1.bytes = pExpr->resBytes;
p1.type = (uint8_t) pExpr->resType;
@@ -744,6 +744,8 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
functionId = TSDB_FUNC_FIRST;
} else if (functionId == TSDB_FUNC_LAST_DST) {
functionId = TSDB_FUNC_LAST;
+ } else if (functionId == TSDB_FUNC_STDDEV_DST) {
+ functionId = TSDB_FUNC_STDDEV;
}
int32_t ret = getResultDataInfo(p1.type, p1.bytes, functionId, 0, &type, &bytes, &inter, 0, false);
@@ -1041,7 +1043,7 @@ static void savePreviousRow(SLocalMerger *pLocalMerge, tFilePage *tmpBuffer) {
pLocalMerge->hasPrevRow = true;
}
-static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, bool needInit) {
+static void doExecuteFinalMerge(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, bool needInit) {
// the tag columns need to be set before all functions execution
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
@@ -1053,7 +1055,7 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, bo
int32_t functionId = pCtx->functionId;
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS_DUMMY) {
tVariantDestroy(&pCtx->tag);
- char* input = pCtx->aInputElemBuf;
+ char* input = pCtx->pInput;
if (pCtx->inputType == TSDB_DATA_TYPE_BINARY || pCtx->inputType == TSDB_DATA_TYPE_NCHAR) {
assert(varDataLen(input) <= pCtx->inputBytes);
@@ -1061,6 +1063,7 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, bo
} else {
tVariantCreateFromBinary(&pCtx->tag, input, pCtx->inputBytes, pCtx->inputType);
}
+
} else if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) {
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, j);
pCtx->param[0].i64 = pExpr->param[0].i64;
@@ -1086,7 +1089,7 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, bo
static void handleUnprocessedRow(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, tFilePage *tmpBuffer) {
if (pLocalMerge->hasUnprocessedRow) {
pLocalMerge->hasUnprocessedRow = false;
- doExecuteSecondaryMerge(pCmd, pLocalMerge, true);
+ doExecuteFinalMerge(pCmd, pLocalMerge, true);
savePreviousRow(pLocalMerge, tmpBuffer);
}
}
@@ -1142,11 +1145,11 @@ static void fillMultiRowsOfTagsVal(SQueryInfo *pQueryInfo, int32_t numOfRes, SLo
int32_t inc = numOfRes - 1; // tsdb_func_tag function only produce one row of result
memset(buf, 0, (size_t)maxBufSize);
- memcpy(buf, pCtx->aOutputBuf, (size_t)pCtx->outputBytes);
+ memcpy(buf, pCtx->pOutput, (size_t)pCtx->outputBytes);
for (int32_t i = 0; i < inc; ++i) {
- pCtx->aOutputBuf += pCtx->outputBytes;
- memcpy(pCtx->aOutputBuf, buf, (size_t)pCtx->outputBytes);
+ pCtx->pOutput += pCtx->outputBytes;
+ memcpy(pCtx->pOutput, buf, (size_t)pCtx->outputBytes);
}
}
@@ -1289,10 +1292,10 @@ void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalMerger *pLocalMerge) {// reset
size_t t = tscSqlExprNumOfExprs(pQueryInfo);
for (int32_t i = 0; i < t; ++i) {
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
- pLocalMerge->pCtx[i].aOutputBuf = pLocalMerge->pResultBuf->data + pExpr->offset * pLocalMerge->resColModel->capacity;
+ pLocalMerge->pCtx[i].pOutput = pLocalMerge->pResultBuf->data + pExpr->offset * pLocalMerge->resColModel->capacity;
if (pExpr->functionId == TSDB_FUNC_TOP || pExpr->functionId == TSDB_FUNC_BOTTOM || pExpr->functionId == TSDB_FUNC_DIFF) {
- pLocalMerge->pCtx[i].ptsOutputBuf = pLocalMerge->pCtx[0].aOutputBuf;
+ pLocalMerge->pCtx[i].ptsOutputBuf = pLocalMerge->pCtx[0].pOutput;
}
}
@@ -1404,7 +1407,7 @@ static void doProcessResultInNextWindow(SSqlObj *pSql, int32_t numOfRes) {
for (int32_t k = 0; k < size; ++k) {
SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[k];
- pCtx->aOutputBuf += pCtx->outputBytes * numOfRes;
+ pCtx->pOutput += pCtx->outputBytes * numOfRes;
// set the correct output timestamp column position
if (pCtx->functionId == TSDB_FUNC_TOP || pCtx->functionId == TSDB_FUNC_BOTTOM) {
@@ -1412,7 +1415,7 @@ static void doProcessResultInNextWindow(SSqlObj *pSql, int32_t numOfRes) {
}
}
- doExecuteSecondaryMerge(pCmd, pLocalMerge, true);
+ doExecuteFinalMerge(pCmd, pLocalMerge, true);
}
int32_t tscDoLocalMerge(SSqlObj *pSql) {
@@ -1504,7 +1507,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
if (pLocalMerge->hasPrevRow) {
if (needToMerge(pQueryInfo, pLocalMerge, tmpBuffer)) {
// belong to the group of the previous row, continue process it
- doExecuteSecondaryMerge(pCmd, pLocalMerge, false);
+ doExecuteFinalMerge(pCmd, pLocalMerge, false);
// copy to buffer
savePreviousRow(pLocalMerge, tmpBuffer);
@@ -1576,7 +1579,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
}
}
} else {
- doExecuteSecondaryMerge(pCmd, pLocalMerge, true);
+ doExecuteFinalMerge(pCmd, pLocalMerge, true);
savePreviousRow(pLocalMerge, tmpBuffer); // copy the processed row to buffer
}
diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c
index 34e96869e3..9e8c6bb163 100644
--- a/src/client/src/tscSQLParser.c
+++ b/src/client/src/tscSQLParser.c
@@ -787,10 +787,10 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQ
}
SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
- tstrncpy(s.name, aAggs[TSDB_FUNC_TS].aName, sizeof(s.name));
+ tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
- tscAddSpecialColumnForSelect(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL);
+ tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL);
if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
@@ -1319,7 +1319,7 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr
return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
}
-static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
+void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
tscColumnListInsert(pQueryInfo->colList, &tsCol);
}
@@ -1401,7 +1401,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
// add ts column
- tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
+ tscInsertPrimaryTsSourceColumn(pQueryInfo, &index);
tbufCloseWriter(&bw);
taosArrayDestroy(colList);
@@ -1506,7 +1506,7 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) {
// add the timestamp column into the output columns
SColumnIndex index = {0}; // primary timestamp column info
int32_t numOfCols = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
- tscAddSpecialColumnForSelect(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL);
+ tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL);
SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols);
pSupInfo->visible = false;
@@ -1602,7 +1602,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
* in dealing with super table queries such as: count/first/last
*/
if (isSTable) {
- tscTansformSQLFuncForSTableQuery(pQueryInfo);
+ tscTansformFuncForSTableQuery(pQueryInfo);
if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
return TSDB_CODE_TSC_INVALID_SQL;
@@ -1656,7 +1656,7 @@ SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tabl
(functionId == TSDB_FUNC_TAGPRJ));
}
-SSqlExpr* tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
+SSqlExpr* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
int16_t colId = getNewResColId(pQueryInfo);
@@ -1738,7 +1738,7 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
}
// add the primary timestamp column even though it is not required by user
- tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
+ tscInsertPrimaryTsSourceColumn(pQueryInfo, &index);
} else if (optr == TK_STRING || optr == TK_INTEGER || optr == TK_FLOAT) { // simple column projection query
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
@@ -1748,7 +1748,7 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->val, &pItem->pNode->token, pItem->aliasName);
SSqlExpr* pExpr =
- tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC);
+ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC);
// NOTE: the first parameter is reserved for the tag column id during join query process.
pExpr->numOfParams = 2;
@@ -1761,11 +1761,11 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
}
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
- SSchema colSchema = tGetTableNameColumnSchema();
- tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG);
+ SSchema* colSchema = tGetTbnameColumnSchema();
+ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, colSchema, TSDB_COL_TAG);
} else if (index.columnIndex == TSDB_BLOCK_DIST_COLUMN_INDEX) {
SSchema colSchema = tGetBlockDistColumnSchema();
- tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_TAG);
+ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_TAG);
} else {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
@@ -1779,7 +1779,7 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
}
// add the primary timestamp column even though it is not required by user
- tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
+ tscInsertPrimaryTsSourceColumn(pQueryInfo, &index);
} else {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -1849,9 +1849,9 @@ void setResultColName(char* name, tSqlExprItem* pItem, int32_t functionId, SStrT
if (tsKeepOriginalColumnName) { // keep the original column name
tstrncpy(name, uname, TSDB_COL_NAME_LEN);
} else {
- int32_t size = TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].aName) + 2 + 1;
- char tmp[TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].aName) + 2 + 1] = {0};
- snprintf(tmp, size, "%s(%s)", aAggs[functionId].aName, uname);
+ int32_t size = TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].name) + 2 + 1;
+ char tmp[TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].name) + 2 + 1] = {0};
+ snprintf(tmp, size, "%s(%s)", aAggs[functionId].name, uname);
tstrncpy(name, tmp, TSDB_COL_NAME_LEN);
}
@@ -1966,7 +1966,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
// the time stamp may be always needed
if (index.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
- tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
+ tscInsertPrimaryTsSourceColumn(pQueryInfo, &index);
}
return TSDB_CODE_SUCCESS;
@@ -2036,7 +2036,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
getNewResColId(pQueryInfo), TSDB_KEYSIZE, false);
SColumnList ids = getColumnList(1, 0, 0);
- insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
+ insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].name, pExpr);
}
// functions can not be applied to tags
@@ -2079,7 +2079,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
}
}
- tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
+ tscInsertPrimaryTsSourceColumn(pQueryInfo, &index);
return TSDB_CODE_SUCCESS;
}
case TK_FIRST:
@@ -2285,7 +2285,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
- tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
+ tscInsertPrimaryTsSourceColumn(pQueryInfo, &index);
colIndex += 1; // the first column is ts
pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false);
@@ -2308,12 +2308,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pQueryInfo),
TSDB_KEYSIZE, false);
- tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
+ tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->aliasName));
const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
SColumnList ids = getColumnList(1, 0, TS_COLUMN_INDEX);
insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
- aAggs[TSDB_FUNC_TS].aName, pExpr);
+ aAggs[TSDB_FUNC_TS].name, pExpr);
colIndex += 1; // the first column is ts
@@ -2384,7 +2384,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
SSchema s = {0};
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
- s = tGetTableNameColumnSchema();
+ s = *tGetTbnameColumnSchema();
} else {
s = pTagSchema[index.columnIndex];
}
@@ -2400,7 +2400,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
s.bytes = bytes;
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
- tscAddSpecialColumnForSelect(pQueryInfo, 0, TSDB_FUNC_TID_TAG, &index, &s, TSDB_COL_TAG);
+ tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TID_TAG, &index, &s, TSDB_COL_TAG);
return TSDB_CODE_SUCCESS;
}
@@ -2778,7 +2778,7 @@ bool validateIpAddress(const char* ip, size_t size) {
return epAddr != INADDR_NONE;
}
-int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
+int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
@@ -2800,7 +2800,7 @@ int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
- (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
+ (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_STDDEV_DST) ||
(functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64, &type, &bytes,
&interBytes, 0, true) != TSDB_CODE_SUCCESS) {
@@ -2818,7 +2818,7 @@ int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
}
/* transfer the field-info back to original input format */
-void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
+void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
return;
@@ -2842,6 +2842,8 @@ void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
functionId = TSDB_FUNC_FIRST;
} else if (functionId == TSDB_FUNC_LAST_DST) {
functionId = TSDB_FUNC_LAST;
+ } else if (functionId == TSDB_FUNC_STDDEV_DST) {
+ functionId = TSDB_FUNC_STDDEV;
}
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->resType, &pExpr->resBytes,
@@ -2858,7 +2860,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
for (int32_t i = 0; i < size; ++i) {
int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
- if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
+ if ((aAggs[functionId].status & TSDB_FUNCSTATE_STABLE) == 0) {
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
return true;
}
@@ -2968,7 +2970,7 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd)
STableMeta* pTableMeta = NULL;
SSchema* pSchema = NULL;
- SSchema s = tGetTbnameColumnSchema();
+// SSchema s = tGetTbnameColumnSchema();
int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
@@ -2995,7 +2997,7 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd)
int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
- pSchema = &s;
+ pSchema = tGetTbnameColumnSchema();
} else {
pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
}
@@ -3552,38 +3554,6 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
return TSDB_CODE_SUCCESS;
}
-// todo error handle / such as and /or mixed with +/-/*/
-int32_t doArithmeticExprToString(tSQLExpr* pExpr, char** exprString) {
- tSQLExpr* pLeft = pExpr->pLeft;
- tSQLExpr* pRight = pExpr->pRight;
-
- *(*exprString)++ = '(';
-
- if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
- doArithmeticExprToString(pLeft, exprString);
- } else {
- int32_t ret = tSQLExprNodeToString(pLeft, exprString);
- if (ret != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
- }
-
- optrToString(pExpr, exprString);
-
- if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
- doArithmeticExprToString(pRight, exprString);
- } else {
- int32_t ret = tSQLExprNodeToString(pRight, exprString);
- if (ret != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
- }
-
- *(*exprString)++ = ')';
-
- return TSDB_CODE_SUCCESS;
-}
-
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList,
int32_t* type, uint64_t* uid) {
if (pExpr->nSQLOptr == TK_ID) {
@@ -5233,7 +5203,7 @@ int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
size_t size = taosArrayGetSize(pQueryInfo->exprList);
for (int32_t i = 0; i < size; ++i) {
int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
- if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
+ if (!IS_STREAM_QUERY_VALID(aAggs[functId].status)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
}
@@ -5256,7 +5226,7 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu
bool hasSelectivity = false;
for (int32_t j = 0; j < size; ++j) {
SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
- if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
+ if ((aAggs[pEx->functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
hasSelectivity = true;
break;
}
@@ -5710,7 +5680,7 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->colIndex);
SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pColIndex->colIndex};
- tscAddSpecialColumnForSelect(pQueryInfo, (int32_t)size, TSDB_FUNC_PRJ, &colIndex, pSchema, TSDB_COL_NORMAL);
+ tscAddFuncInSelectClause(pQueryInfo, (int32_t)size, TSDB_FUNC_PRJ, &colIndex, pSchema, TSDB_COL_NORMAL);
int32_t numOfFields = tscNumOfFields(pQueryInfo);
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfFields - 1);
@@ -5874,7 +5844,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd)
continue;
}
- if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
+ if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
numOfSelectivity++;
} else {
numOfAggregation++;
@@ -5906,7 +5876,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd)
for (int32_t i = 0; i < numOfExprs; ++i) {
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
int16_t functionId = pExpr->functionId;
- if (functionId == TSDB_FUNC_TAGPRJ || (aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == 0) {
+ if (functionId == TSDB_FUNC_TAGPRJ || (aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == 0) {
continue;
}
@@ -5949,7 +5919,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
- SSchema s = tGetTableNameColumnSchema();
+ SSchema s = *tGetTbnameColumnSchema();
SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
int16_t bytes = 0;
int16_t type = 0;
@@ -6093,7 +6063,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
}
}
- if (IS_MULTIOUTPUT(aAggs[functId].nStatus) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM &&
+ if (IS_MULTIOUTPUT(aAggs[functId].status) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM &&
functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
@@ -6283,7 +6253,7 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) {
char tmpBuf[1024] = {0};
int32_t tmpLen = 0;
tmpLen =
- sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
+ sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].name, pExpr->uid, pExpr->colInfo.colId);
if (tmpLen + offset >= totalBufSize - 1) break;
@@ -6984,3 +6954,4 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) {
return false;
}
+
diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c
index bcffbde658..b10b040c7b 100644
--- a/src/client/src/tscServer.c
+++ b/src/client/src/tscServer.c
@@ -752,6 +752,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pQueryMsg->queryType = htonl(pQueryInfo->type);
pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit);
pQueryMsg->sqlstrLen = htonl(sqlLen);
+ pQueryMsg->prevResultLen = htonl(pQueryInfo->bufLen);
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
@@ -989,6 +990,11 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
}
}
+ if (pQueryInfo->bufLen > 0) {
+ memcpy(pMsg, pQueryInfo->buf, pQueryInfo->bufLen);
+ pMsg += pQueryInfo->bufLen;
+ }
+
SCond* pCond = &pQueryInfo->tagCond.tbnameCond;
if (pCond->len > 0) {
strncpy(pMsg, pCond->cond, pCond->len);
diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c
index 448eea16bf..8a240accec 100644
--- a/src/client/src/tscSql.c
+++ b/src/client/src/tscSql.c
@@ -443,24 +443,6 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
return pFieldInfo->final;
}
-int taos_retrieve(TAOS_RES *res) {
- if (res == NULL) return 0;
- SSqlObj *pSql = (SSqlObj *)res;
- SSqlCmd *pCmd = &pSql->cmd;
- SSqlRes *pRes = &pSql->res;
- if (pSql == NULL || pSql->signature != pSql) return 0;
- if (pRes->qhandle == 0) return 0;
-
- tscResetForNextRetrieve(pRes);
-
- if (pCmd->command < TSDB_SQL_LOCAL) {
- pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
- }
-
- tscProcessSql(pSql);
- return pRes->numOfRows;
-}
-
static bool needToFetchNewBlock(SSqlObj* pSql) {
SSqlRes *pRes = &pSql->res;
SSqlCmd *pCmd = &pSql->cmd;
diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c
index d787f5b515..a9cd1965e8 100644
--- a/src/client/src/tscStream.c
+++ b/src/client/src/tscStream.c
@@ -103,7 +103,7 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) {
// failed to get table Meta or vgroup list, retry in 10sec.
if (code == TSDB_CODE_SUCCESS) {
- tscTansformSQLFuncForSTableQuery(pQueryInfo);
+ tscTansformFuncForSTableQuery(pQueryInfo);
tscDebug("%p stream:%p, start stream query on:%s", pSql, pStream, tNameGetTableName(&pTableMetaInfo->name));
pSql->fp = tscProcessStreamQueryCallback;
diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c
index ec7f9d8b4f..96aae423d5 100644
--- a/src/client/src/tscSubquery.c
+++ b/src/client/src/tscSubquery.c
@@ -13,7 +13,7 @@
* along with this program. If not, see .
*/
#define _GNU_SOURCE
-
+
#include "os.h"
#include "texpr.h"
@@ -23,6 +23,7 @@
#include "tscSubquery.h"
#include "tschemautil.h"
#include "tsclient.h"
+#include "qUtil.h"
typedef struct SInsertSupporter {
SSqlObj* pSql;
@@ -501,7 +502,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
int16_t functionId = tscIsProjectionQuery(pQueryInfo)? TSDB_FUNC_PRJ : TSDB_FUNC_TS;
- tscAddSpecialColumnForSelect(pQueryInfo, 0, functionId, &index, s, TSDB_COL_NORMAL);
+ tscAddFuncInSelectClause(pQueryInfo, 0, functionId, &index, s, TSDB_COL_NORMAL);
tscPrintSelectClause(pNew, 0);
tscFieldInfoUpdateOffset(pQueryInfo);
@@ -681,7 +682,7 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr
}
}
-static void issueTSCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* pParent) {
+static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* pParent) {
SSqlCmd* pCmd = &pSql->cmd;
tscClearSubqueryInfo(pCmd);
tscFreeSqlResult(pSql);
@@ -701,7 +702,7 @@ static void issueTSCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj*
SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1};
SColumnIndex index = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
- tscAddSpecialColumnForSelect(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL);
+ tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL);
// set the tags value for ts_comp function
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
@@ -970,7 +971,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
for (int32_t m = 0; m < pParentSql->subState.numOfSub; ++m) {
SSqlObj* sub = pParentSql->pSubs[m];
- issueTSCompQuery(sub, sub->param, pParentSql);
+ issueTsCompQuery(sub, sub->param, pParentSql);
}
}
@@ -1470,7 +1471,7 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
}
// restore the offset value for super table query in case of final result.
- tscRestoreSQLFuncForSTableQuery(pQueryInfo);
+ tscRestoreFuncForSTableQuery(pQueryInfo);
tscFieldInfoUpdateOffset(pQueryInfo);
}
@@ -1651,7 +1652,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
// set get tags query type
TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
- tscAddSpecialColumnForSelect(pNewQueryInfo, 0, TSDB_FUNC_TID_TAG, &colIndex, &s1, TSDB_COL_TAG);
+ tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TID_TAG, &colIndex, &s1, TSDB_COL_TAG);
size_t numOfCols = taosArrayGetSize(pNewQueryInfo->colList);
tscDebug(
@@ -1662,7 +1663,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
} else {
SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1};
SColumnIndex colIndex = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
- tscAddSpecialColumnForSelect(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &colIndex, &colSchema, TSDB_COL_NORMAL);
+ tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &colIndex, &colSchema, TSDB_COL_NORMAL);
// set the tags value for ts_comp function
SSqlExpr *pExpr = tscSqlExprGet(pNewQueryInfo, 0);
@@ -1821,7 +1822,262 @@ void tscUnlockByThread(int64_t *lockedBy) {
}
}
+typedef struct SFirstRoundQuerySup {
+ SSqlObj *pParent;
+ int32_t numOfRows;
+ SArray *pColsInfo;
+ int32_t tagLen;
+ STColumn *pTagCols;
+ SArray *pResult; // SArray
+ int64_t interval;
+ char* buf;
+ int32_t bufLen;
+} SFirstRoundQuerySup;
+void doAppendData(SInterResult* pInterResult, TAOS_ROW row, int32_t numOfCols, SQueryInfo* pQueryInfo) {
+ TSKEY key = INT64_MIN;
+ for(int32_t i = 0; i < numOfCols; ++i) {
+ SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
+ if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
+ continue;
+ }
+
+ if (pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
+ key = *(TSKEY*) row[i];
+ continue;
+ }
+
+ double v = 0;
+ if (row[i] != NULL) {
+ v = *(double*) row[i];
+ } else {
+ SET_DOUBLE_NULL(&v);
+ }
+
+ int32_t id = pExpr->colInfo.colId;
+ int32_t numOfQueriedCols = (int32_t) taosArrayGetSize(pInterResult->pResult);
+
+ SArray* p = NULL;
+ for(int32_t j = 0; j < numOfQueriedCols; ++j) {
+ SStddevInterResult* pColRes = taosArrayGet(pInterResult->pResult, j);
+ if (pColRes->colId == id) {
+ p = pColRes->pResult;
+ break;
+ }
+ }
+
+ //append a new column
+ if (p == NULL) {
+ SStddevInterResult t = {.colId = id, .pResult = taosArrayInit(10, sizeof(SResPair)),};
+ taosArrayPush(pInterResult->pResult, &t);
+ p = t.pResult;
+ }
+
+ SResPair pair = {.avg = v, .key = key};
+ taosArrayPush(p, &pair);
+ }
+}
+
+void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
+ SSqlObj* pSql = (SSqlObj*)tres;
+ SSqlRes* pRes = &pSql->res;
+
+ SFirstRoundQuerySup* pSup = param;
+ SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
+
+ if (numOfRows > 0) {
+ TAOS_ROW row = NULL;
+ int32_t numOfCols = taos_field_count(tres);
+
+ if (pSup->tagLen == 0) { // no tags, all rows belong to one group
+ SInterResult interResult = {.tags = NULL, .pResult = taosArrayInit(4, sizeof(SStddevInterResult))};
+ taosArrayPush(pSup->pResult, &interResult);
+
+ while ((row = taos_fetch_row(tres)) != NULL) {
+ doAppendData(&interResult, row, numOfCols, pQueryInfo);
+ }
+ } else { // tagLen > 0
+ char* p = calloc(1, pSup->tagLen);
+
+ while ((row = taos_fetch_row(tres)) != NULL) {
+ int32_t* length = taos_fetch_lengths(tres);
+ memset(p, 0, pSup->tagLen);
+
+ int32_t offset = 0;
+ for (int32_t i = 0; i < numOfCols && offset < pSup->tagLen; ++i) {
+ SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
+ if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
+ memcpy(p + offset, row[i], length[i]);
+ offset += pExpr->resBytes;
+ }
+ }
+
+ assert(offset == pSup->tagLen);
+ size_t size = taosArrayGetSize(pSup->pResult);
+
+ if (size > 0) {
+ SInterResult* pInterResult = taosArrayGetLast(pSup->pResult);
+ if (memcmp(pInterResult->tags, p, pSup->tagLen) == 0) { // belongs to the same group
+ doAppendData(pInterResult, row, numOfCols, pQueryInfo);
+ } else {
+ char* tags = malloc( pSup->tagLen);
+ memcpy(tags, p, pSup->tagLen);
+
+ SInterResult interResult = {.tags = tags, .pResult = taosArrayInit(4, sizeof(SStddevInterResult))};
+ taosArrayPush(pSup->pResult, &interResult);
+ doAppendData(&interResult, row, numOfCols, pQueryInfo);
+ }
+ } else {
+ char* tags = malloc(pSup->tagLen);
+ memcpy(tags, p, pSup->tagLen);
+
+ SInterResult interResult = {.tags = tags, .pResult = taosArrayInit(4, sizeof(SStddevInterResult))};
+ taosArrayPush(pSup->pResult, &interResult);
+ doAppendData(&interResult, row, numOfCols, pQueryInfo);
+ }
+ }
+
+ tfree(p);
+ }
+ }
+
+ pSup->numOfRows += numOfRows;
+ if (!pRes->completed) {
+ taos_fetch_rows_a(tres, tscFirstRoundRetrieveCallback, param);
+ return;
+ }
+
+ // set the parameters for the second round query process
+ SSqlObj *pParent = pSup->pParent;
+ SSqlCmd *pPCmd = &pParent->cmd;
+ SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(pPCmd, 0);
+
+ if (pSup->numOfRows > 0) {
+ SBufferWriter bw = tbufInitWriter(NULL, false);
+ interResToBinary(&bw, pSup->pResult, pSup->tagLen);
+
+ pQueryInfo1->bufLen = (int32_t) tbufTell(&bw);
+ pQueryInfo1->buf = tbufGetData(&bw, true);
+
+ // set the serialized binary string as the parameter of arithmetic expression
+ tbufCloseWriter(&bw);
+ }
+
+ taosArrayDestroyEx(pSup->pResult, freeInterResult);
+ taosArrayDestroy(pSup->pColsInfo);
+ tfree(pSup);
+
+ taos_free_result(pSql);
+
+ pQueryInfo1->round = 1;
+ tscDoQuery(pParent);
+}
+
+void tscFirstRoundCallback(void* param, TAOS_RES* tres, int code) {
+ int32_t c = taos_errno(tres);
+ if (c != TSDB_CODE_SUCCESS) {
+ // TODO HANDLE ERROR
+ }
+
+ taos_fetch_rows_a(tres, tscFirstRoundRetrieveCallback, param);
+}
+
+int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) {
+ SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
+ STableMetaInfo* pTableMetaInfo1 = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
+
+ SFirstRoundQuerySup *pSup = calloc(1, sizeof(SFirstRoundQuerySup));
+
+ pSup->pParent = pSql;
+ pSup->interval = pQueryInfo->interval.interval;
+ pSup->pResult = taosArrayInit(6, sizeof(SStddevInterResult));
+ pSup->pColsInfo = taosArrayInit(6, sizeof(int16_t)); // result column id
+
+ SSqlObj *pNew = createSubqueryObj(pSql, 0, tscFirstRoundCallback, pSup, TSDB_SQL_SELECT, NULL);
+ SSqlCmd *pCmd = &pNew->cmd;
+
+ tscClearSubqueryInfo(pCmd);
+ tscFreeSqlResult(pSql);
+
+ SQueryInfo* pNewQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
+ assert(pQueryInfo->numOfTables == 1);
+
+ STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0);
+
+ tscInitQueryInfo(pNewQueryInfo);
+ pNewQueryInfo->groupbyExpr = pQueryInfo->groupbyExpr;
+ if (pQueryInfo->groupbyExpr.columnInfo != NULL) {
+ pNewQueryInfo->groupbyExpr.columnInfo = taosArrayDup(pQueryInfo->groupbyExpr.columnInfo);
+ if (pNewQueryInfo->groupbyExpr.columnInfo == NULL) {
+ terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
+// goto _error;
+ }
+ }
+
+ if (tscTagCondCopy(&pNewQueryInfo->tagCond, &pQueryInfo->tagCond) != 0) {
+ terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
+// goto _error;
+ }
+
+ pNewQueryInfo->interval = pQueryInfo->interval;
+
+ pCmd->command = TSDB_SQL_SELECT;
+ pNew->fp = tscFirstRoundCallback;
+
+ int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
+
+ int32_t index = 0;
+ int32_t numOfTags = 0;
+ for(int32_t i = 0; i < numOfExprs; ++i) {
+ SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
+ if (pExpr->functionId == TSDB_FUNC_TS && pQueryInfo->interval.interval > 0) {
+ taosArrayPush(pSup->pColsInfo, &pExpr->resColId);
+
+ SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
+ SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->colInfo.colId);
+
+ SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL);
+ p->resColId = pExpr->resColId; // update the result column id
+ } else if (pExpr->functionId == TSDB_FUNC_STDDEV_DST) {
+ taosArrayPush(pSup->pColsInfo, &pExpr->resColId);
+
+ SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->colInfo.colIndex};
+ SSchema schema = {.type = TSDB_DATA_TYPE_DOUBLE, .bytes = sizeof(double)};
+ tstrncpy(schema.name, pExpr->aliasName, tListLen(schema.name));
+
+ SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL);
+ p->resColId = pExpr->resColId; // update the result column id
+ } else if (pExpr->functionId == TSDB_FUNC_TAG) {
+ pSup->tagLen += pExpr->resBytes;
+ SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->colInfo.colIndex};
+
+ SSchema* schema = NULL;
+ if (pExpr->colInfo.colId != TSDB_TBNAME_COLUMN_INDEX) {
+ schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->colInfo.colId);
+ } else {
+ schema = tGetTbnameColumnSchema();
+ }
+
+ SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG);
+ p->resColId = pExpr->resColId;
+ numOfTags += 1;
+ }
+ }
+
+ SColumnIndex columnIndex = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
+ tscInsertPrimaryTsSourceColumn(pNewQueryInfo, &columnIndex);
+
+ tscTansformFuncForSTableQuery(pNewQueryInfo);
+
+ tscDebug(
+ "%p first round subquery:%p tableIndex:%d, vgroupIndex:%d, numOfVgroups:%d, type:%d, query to retrieve timestamps, "
+ "numOfExpr:%" PRIzu ", colList:%d, numOfOutputFields:%d, name:%s",
+ pSql, pNew, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pNewQueryInfo->type,
+ tscSqlExprNumOfExprs(pNewQueryInfo), index+1, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name));
+
+ tscHandleMasterSTableQuery(pNew);
+ return TSDB_CODE_SUCCESS;
+}
int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res;
@@ -1833,7 +2089,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
return pRes->code;
}
- tExtMemBuffer ** pMemoryBuf = NULL;
+ tExtMemBuffer **pMemoryBuf = NULL;
tOrderDescriptor *pDesc = NULL;
SColumnModel *pModel = NULL;
SColumnModel *pFinalModel = NULL;
@@ -1863,10 +2119,8 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
return ret;
}
- pSql->pSubs = calloc(pState->numOfSub, POINTER_BYTES);
-
tscDebug("%p retrieved query data from %d vnode(s)", pSql, pState->numOfSub);
-
+ pSql->pSubs = calloc(pState->numOfSub, POINTER_BYTES);
if (pSql->pSubs == NULL) {
tfree(pSql->pSubs);
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
@@ -2739,7 +2993,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
return;
}
- tscRestoreSQLFuncForSTableQuery(pQueryInfo);
+ tscRestoreFuncForSTableQuery(pQueryInfo);
}
assert (pRes->row >= pRes->numOfRows);
diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c
index 83d9dd805c..95cf28ec49 100644
--- a/src/client/src/tscUtil.c
+++ b/src/client/src/tscUtil.c
@@ -107,11 +107,6 @@ bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex) {
return false;
}
- // for select query super table, the super table vgroup list can not be null in any cases.
- // if (pQueryInfo->command == TSDB_SQL_SELECT && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
- // assert(pTableMetaInfo->vgroupList != NULL);
- // }
-
if ((pQueryInfo->type & TSDB_QUERY_TYPE_FREE_RESOURCE) == TSDB_QUERY_TYPE_FREE_RESOURCE) {
return false;
}
@@ -1074,7 +1069,7 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo) {
memset(pFieldInfo, 0, sizeof(SFieldInfo));
}
-static SSqlExpr* doBuildSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
+static SSqlExpr* doCreateSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
int16_t size, int16_t resColId, int16_t interSize, int32_t colType) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pColIndex->tableIndex);
@@ -1127,14 +1122,14 @@ SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
return tscSqlExprAppend(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol);
}
- SSqlExpr* pExpr = doBuildSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol);
+ SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol);
taosArrayInsert(pQueryInfo->exprList, index, &pExpr);
return pExpr;
}
SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) {
- SSqlExpr* pExpr = doBuildSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol);
+ SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol);
taosArrayPush(pQueryInfo->exprList, &pExpr);
return pExpr;
}
@@ -1158,6 +1153,22 @@ SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
return pExpr;
}
+bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t index) {
+ if (!UTIL_TABLE_IS_SUPER_TABLE(pQueryInfo->pTableMetaInfo[index])) {
+ return false;
+ }
+
+ int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
+ for(int32_t i = 0; i < numOfExprs; ++i) {
+ SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
+ if (pExpr->functionId == TSDB_FUNC_STDDEV_DST) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
size_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo) {
return taosArrayGetSize(pQueryInfo->exprList);
}
@@ -1422,9 +1433,9 @@ int32_t tscValidateName(SStrToken* pToken) {
if (sep == NULL) { // single part
if (pToken->type == TK_STRING) {
- strdequote(pToken->z);
+ tscDequoteAndTrimToken(pToken);
tscStrToLower(pToken->z, pToken->n);
- pToken->n = (uint32_t)strtrim(pToken->z);
+ //pToken->n = (uint32_t)strtrim(pToken->z);
int len = tSQLGetToken(pToken->z, &pToken->type);
@@ -1762,6 +1773,7 @@ static void freeQueryInfoImpl(SQueryInfo* pQueryInfo) {
pQueryInfo->tsBuf = tsBufDestroy(pQueryInfo->tsBuf);
tfree(pQueryInfo->fillVal);
+ tfree(pQueryInfo->buf);
}
void tscClearSubqueryInfo(SSqlCmd* pCmd) {
@@ -2029,7 +2041,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t
pNew->signature = pNew;
pNew->sqlstr = strdup(pSql->sqlstr);
- SSqlCmd* pnCmd = &pNew->cmd;
+ SSqlCmd* pnCmd = &pNew->cmd;
memcpy(pnCmd, pCmd, sizeof(SSqlCmd));
pnCmd->command = cmd;
@@ -2068,7 +2080,18 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t
pNewQueryInfo->clauseLimit = pQueryInfo->clauseLimit;
pNewQueryInfo->numOfTables = 0;
pNewQueryInfo->pTableMetaInfo = NULL;
-
+ pNewQueryInfo->bufLen = pQueryInfo->bufLen;
+
+ pNewQueryInfo->buf = malloc(pQueryInfo->bufLen);
+ if (pNewQueryInfo->buf == NULL) {
+ terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
+ goto _error;
+ }
+
+ if (pQueryInfo->bufLen > 0) {
+ memcpy(pNewQueryInfo->buf, pQueryInfo->buf, pQueryInfo->bufLen);
+ }
+
pNewQueryInfo->groupbyExpr = pQueryInfo->groupbyExpr;
if (pQueryInfo->groupbyExpr.columnInfo != NULL) {
pNewQueryInfo->groupbyExpr.columnInfo = taosArrayDup(pQueryInfo->groupbyExpr.columnInfo);
@@ -2234,6 +2257,9 @@ void tscDoQuery(SSqlObj* pSql) {
}
}
+ return;
+ } else if (tscMultiRoundQuery(pQueryInfo, 0) && pQueryInfo->round == 0) {
+ tscHandleFirstRoundStableQuery(pSql); // todo lock?
return;
} else if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query
tscLockByThread(&pSql->squeryLock);
diff --git a/src/common/inc/tname.h b/src/common/inc/tname.h
index 892d682756..b651913d73 100644
--- a/src/common/inc/tname.h
+++ b/src/common/inc/tname.h
@@ -36,6 +36,11 @@ typedef struct SColumnInfoData {
void* pData; // the corresponding block data in memory
} SColumnInfoData;
+typedef struct SResPair {
+ TSKEY key;
+ double avg;
+} SResPair;
+
#define TSDB_DB_NAME_T 1
#define TSDB_TABLE_NAME_T 2
@@ -58,7 +63,7 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len);
void extractTableNameFromToken(SStrToken *pToken, SStrToken* pTable);
-SSchema tGetTableNameColumnSchema();
+//SSchema tGetTbnameColumnSchema();
SSchema tGetBlockDistColumnSchema();
@@ -68,7 +73,7 @@ bool tscValidateTableNameLength(size_t len);
SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFilters);
-SSchema tGetTbnameColumnSchema();
+SSchema* tGetTbnameColumnSchema();
/**
* check if the schema is valid or not, including following aspects:
diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c
index f941fc4501..f50b829baa 100644
--- a/src/common/src/texpr.c
+++ b/src/common/src/texpr.c
@@ -407,7 +407,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
SSchema* pSchema = exception_calloc(1, sizeof(SSchema));
left->pSchema = pSchema;
- *pSchema = tGetTbnameColumnSchema();
+ *pSchema = *tGetTbnameColumnSchema();
tExprNode* right = exception_calloc(1, sizeof(tExprNode));
expr->_node.pRight = right;
diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c
index 980524be96..3d88cf8312 100644
--- a/src/common/src/tglobal.c
+++ b/src/common/src/tglobal.c
@@ -59,7 +59,6 @@ char tsLocale[TSDB_LOCALE_LEN] = {0};
char tsCharset[TSDB_LOCALE_LEN] = {0}; // default encode string
int8_t tsEnableCoreFile = 0;
int32_t tsMaxBinaryDisplayWidth = 30;
-char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/";
/*
* denote if the server needs to compress response message at the application layer to client, including query rsp,
@@ -182,6 +181,7 @@ char tsDnodeDir[TSDB_FILENAME_LEN] = {0};
char tsMnodeDir[TSDB_FILENAME_LEN] = {0};
char tsDataDir[TSDB_FILENAME_LEN] = {0};
char tsScriptDir[TSDB_FILENAME_LEN] = {0};
+char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/";
int32_t tsDiskCfgNum = 0;
diff --git a/src/common/src/tname.c b/src/common/src/tname.c
index 178ed09123..787aa1e95b 100644
--- a/src/common/src/tname.c
+++ b/src/common/src/tname.c
@@ -10,6 +10,7 @@
#define VALID_NAME_TYPE(x) ((x) == TSDB_DB_NAME_T || (x) == TSDB_TABLE_NAME_T)
+//TODO remove it
void extractTableName(const char* tableId, char* name) {
size_t s1 = strcspn(tableId, &TS_PATH_DELIMITER[0]);
size_t s2 = strcspn(&tableId[s1 + 1], &TS_PATH_DELIMITER[0]);
@@ -24,6 +25,7 @@ char* extractDBName(const char* tableId, char* name) {
return strncpy(name, &tableId[offset1 + 1], len);
}
+// todo remove it
size_t tableIdPrefix(const char* name, char* prefix, int32_t len) {
tstrncpy(prefix, name, len);
strcat(prefix, TS_PATH_DELIMITER);
@@ -31,14 +33,6 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len) {
return strlen(prefix);
}
-SSchema tGetTableNameColumnSchema() {
- SSchema s = {0};
- s.bytes = TSDB_TABLE_NAME_LEN - 1 + VARSTR_HEADER_SIZE;
- s.type = TSDB_DATA_TYPE_BINARY;
- s.colId = TSDB_TBNAME_COLUMN_INDEX;
- tstrncpy(s.name, TSQL_TBNAME_L, TSDB_COL_NAME_LEN);
- return s;
-}
SSchema tGetBlockDistColumnSchema() {
SSchema s = {0};
s.bytes = TSDB_MAX_BINARY_LEN;;
@@ -189,15 +183,15 @@ void extractTableNameFromToken(SStrToken* pToken, SStrToken* pTable) {
}
}
-SSchema tGetTbnameColumnSchema() {
- struct SSchema s = {
- .colId = TSDB_TBNAME_COLUMN_INDEX,
- .type = TSDB_DATA_TYPE_BINARY,
- .bytes = TSDB_TABLE_NAME_LEN
- };
+static struct SSchema _s = {
+ .colId = TSDB_TBNAME_COLUMN_INDEX,
+ .type = TSDB_DATA_TYPE_BINARY,
+ .bytes = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE,
+ .name = TSQL_TBNAME_L,
+};
- strcpy(s.name, TSQL_TBNAME_L);
- return s;
+SSchema* tGetTbnameColumnSchema() {
+ return &_s;
}
static bool doValidateSchema(SSchema* pSchema, int32_t numOfCols, int32_t maxLen) {
diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c
index cfad85be60..7009c4d5c3 100644
--- a/src/common/src/tvariant.c
+++ b/src/common/src/tvariant.c
@@ -86,43 +86,53 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32
switch (type) {
case TSDB_DATA_TYPE_BOOL:
case TSDB_DATA_TYPE_TINYINT: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->i64 = GET_INT8_VAL(pz);
break;
}
case TSDB_DATA_TYPE_UTINYINT: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->u64 = GET_UINT8_VAL(pz);
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->i64 = GET_INT16_VAL(pz);
break;
}
case TSDB_DATA_TYPE_USMALLINT: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->u64 = GET_UINT16_VAL(pz);
break;
}
case TSDB_DATA_TYPE_INT: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->i64 = GET_INT32_VAL(pz);
break;
}
case TSDB_DATA_TYPE_UINT: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->u64 = GET_UINT32_VAL(pz);
break;
}
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->i64 = GET_INT64_VAL(pz);
break;
}
case TSDB_DATA_TYPE_UBIGINT: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->u64 = GET_UINT64_VAL(pz);
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->dKey = GET_DOUBLE_VAL(pz);
break;
}
case TSDB_DATA_TYPE_FLOAT: {
+ pVar->nLen = tDataTypes[type].bytes;
pVar->dKey = GET_FLOAT_VAL(pz);
break;
}
@@ -144,6 +154,7 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32
default:
pVar->i64 = GET_INT32_VAL(pz);
+ pVar->nLen = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
}
pVar->nType = type;
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java
index 94abe39655..547fe6a9e9 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java
@@ -34,44 +34,37 @@ import java.util.*;
import java.util.concurrent.Executor;
public class TSDBConnection implements Connection {
- protected Properties props = null;
private TSDBJNIConnector connector = null;
private String catalog = null;
- private TSDBDatabaseMetaData dbMetaData = null;
+ private TSDBDatabaseMetaData dbMetaData;
private Properties clientInfoProps = new Properties();
private int timeoutMilliseconds = 0;
-
+
private boolean batchFetch = false;
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
this.dbMetaData = meta;
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")),
- info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME),
+ info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME),
info.getProperty(TSDBDriver.PROPERTY_KEY_USER),
info.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD));
-
+
String batchLoad = info.getProperty(TSDBDriver.PROPERTY_KEY_BATCH_LOAD);
if (batchLoad != null) {
- this.batchFetch = Boolean.parseBoolean(batchLoad);
+ this.batchFetch = Boolean.parseBoolean(batchLoad);
}
}
private void connect(String host, int port, String dbName, String user, String password) throws SQLException {
this.connector = new TSDBJNIConnector();
this.connector.connect(host, port, dbName, user, password);
-
- try {
- this.setCatalog(dbName);
- } catch (SQLException e) {
- e.printStackTrace();
- }
-
+ this.setCatalog(dbName);
this.dbMetaData.setConnection(this);
}
@@ -80,68 +73,86 @@ public class TSDBConnection implements Connection {
}
public Statement createStatement() throws SQLException {
- if (!this.connector.isClosed()) {
- TSDBStatement statement = new TSDBStatement(this, this.connector);
- statement.setConnection(this);
- return statement;
- } else {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
+
+ TSDBStatement statement = new TSDBStatement(this, this.connector);
+ statement.setConnection(this);
+ return statement;
}
public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException {
- if (this.connector.isClosed()) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
long id = this.connector.subscribe(topic, sql, restart, 0);
if (id == 0) {
- throw new SQLException(TSDBConstants.WrapErrMsg("failed to create subscription"));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SUBSCRIBE_FAILED);
}
-
return new TSDBSubscribe(this.connector, id);
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
- if (!this.connector.isClosed()) {
- return new TSDBPreparedStatement(this, this.connector, sql);
- } else {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
+
+ return new TSDBPreparedStatement(this, this.connector, sql);
}
public CallableStatement prepareCall(String sql) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public String nativeSQL(String sql) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+
}
public boolean getAutoCommit() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+
return true;
}
public void commit() throws SQLException {
- }
-
- public void rollback() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
- }
-
- public void close() throws SQLException {
- if (this.connector != null && !this.connector.isClosed()) {
- this.connector.closeConnection();
- } else {
- throw new SQLException(TSDBConstants.WrapErrMsg("connection is already closed!"));
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
}
+ public void rollback() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ public void close() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ this.connector.closeConnection();
+ }
+
public boolean isClosed() throws SQLException {
- return this.connector.isClosed();
+ return this.connector != null && this.connector.isClosed();
}
/**
@@ -154,6 +165,9 @@ public class TSDBConnection implements Connection {
* @throws SQLException if a database access error occurs
*/
public DatabaseMetaData getMetaData() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
return this.dbMetaData;
}
@@ -165,17 +179,29 @@ public class TSDBConnection implements Connection {
* @throws SQLException
*/
public void setReadOnly(boolean readOnly) throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
}
public boolean isReadOnly() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
return true;
}
public void setCatalog(String catalog) throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
this.catalog = catalog;
}
public String getCatalog() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
return this.catalog;
}
@@ -187,6 +213,19 @@ public class TSDBConnection implements Connection {
* @throws SQLException
*/
public void setTransactionIsolation(int level) throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ switch (level) {
+ case Connection.TRANSACTION_NONE:
+ case Connection.TRANSACTION_READ_COMMITTED:
+ case Connection.TRANSACTION_READ_UNCOMMITTED:
+ case Connection.TRANSACTION_REPEATABLE_READ:
+ case Connection.TRANSACTION_SERIALIZABLE:
+ break;
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+ }
}
/**
@@ -196,60 +235,81 @@ public class TSDBConnection implements Connection {
* @throws SQLException
*/
public int getTransactionIsolation() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
return Connection.TRANSACTION_NONE;
}
public SQLWarning getWarnings() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
//todo: implement getWarnings according to the warning messages returned from TDengine
return null;
-// throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
public void clearWarnings() throws SQLException {
- // left blank to support HikariCP connection
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
//todo: implement clearWarnings according to the warning messages returned from TDengine
}
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
// This method is implemented in the current way to support Spark
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
- throw new SQLException(TSDBConstants.INVALID_VARIABLES);
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) {
- throw new SQLException(TSDBConstants.INVALID_VARIABLES);
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
return this.prepareStatement(sql);
}
-
+
public Boolean getBatchFetch() {
- return this.batchFetch;
+ return this.batchFetch;
}
-
+
public void setBatchFetch(Boolean batchFetch) {
- this.batchFetch = batchFetch;
+ this.batchFetch = batchFetch;
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Map> getTypeMap() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setTypeMap(Map> map) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setHoldability(int holdability) throws SQLException {
- // intentionally left empty to support druid connection pool.
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
}
/**
@@ -259,67 +319,111 @@ public class TSDBConnection implements Connection {
* @throws SQLException
*/
public int getHoldability() throws SQLException {
- //intentionally left empty to support HikariCP connection.
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
public Savepoint setSavepoint() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Savepoint setSavepoint(String name) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void rollback(Savepoint savepoint) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
- return this.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Clob createClob() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Blob createBlob() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public NClob createNClob() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public SQLXML createSQLXML() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public boolean isValid(int timeout) throws SQLException {
@@ -338,31 +442,52 @@ public class TSDBConnection implements Connection {
}
public String getClientInfo(String name) throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
return clientInfoProps.getProperty(name);
}
public Properties getClientInfo() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
return clientInfoProps;
}
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setSchema(String schema) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public String getSchema() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void abort(Executor executor) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
@@ -370,14 +495,21 @@ public class TSDBConnection implements Connection {
}
public int getNetworkTimeout() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ }
return this.timeoutMilliseconds;
}
public T unwrap(Class iface) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ try {
+ return iface.cast(this);
+ } catch (ClassCastException cce) {
+ throw new SQLException("Unable to unwrap to " + iface.toString());
+ }
}
public boolean isWrapperFor(Class> iface) throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ return iface.isInstance(this);
}
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
index 4fb172ceb5..0cf33692b0 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
@@ -19,12 +19,12 @@ import java.util.Map;
public abstract class TSDBConstants {
- public static final String STATEMENT_CLOSED = "Statement already closed.";
- public static final String DEFAULT_PORT = "6200";
+ public static final String STATEMENT_CLOSED = "statement is closed";
public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
public static final String INVALID_VARIABLES = "invalid variables";
- public static final String RESULT_SET_IS_CLOSED = "resultSet is closed.";
+ public static final String RESULT_SET_IS_CLOSED = "resultSet is closed";
+ public static final String DEFAULT_PORT = "6200";
public static Map DATATYPE_MAP = null;
public static final long JNI_NULL_POINTER = 0L;
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java
new file mode 100644
index 0000000000..ede0b4e4e8
--- /dev/null
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java
@@ -0,0 +1,31 @@
+package com.taosdata.jdbc;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class TSDBError {
+ private static Map TSDBErrorMap = new HashMap<>();
+
+ static {
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED, "connection already closed");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD, "this operation is NOT supported currently!");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_VARIABLE, "invalid variables");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED, "statement is closed");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED, "resultSet is closed");
+ /**************************************************/
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SUBSCRIBE_FAILED, "failed to create subscription");
+ }
+
+ public static String wrapErrMsg(String msg) {
+ return "TDengine Error: " + msg;
+ }
+
+ public static SQLException createSQLException(int errorNumber) {
+ // JDBC exception code is less than 0x2350
+ if (errorNumber <= 0x2350)
+ return new SQLException(TSDBErrorMap.get(errorNumber));
+ // JNI exception code is
+ return new SQLException(wrapErrMsg(TSDBErrorMap.get(errorNumber)));
+ }
+}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
new file mode 100644
index 0000000000..74dbb8ab9a
--- /dev/null
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
@@ -0,0 +1,15 @@
+package com.taosdata.jdbc;
+
+public class TSDBErrorNumbers {
+
+ public static final int ERROR_CONNECTION_CLOSED = 0x2301; // connection already closed
+ public static final int ERROR_UNSUPPORTED_METHOD = 0x2302; //this operation is NOT supported currently!
+ public static final int ERROR_INVALID_VARIABLE = 0x2303; //invalid variables
+ public static final int ERROR_STATEMENT_CLOSED = 0x2304; //statement already closed
+ public static final int ERROR_RESULTSET_CLOSED = 0x2305; //resultSet is closed
+
+ public static final int ERROR_SUBSCRIBE_FAILED = 0x2350; //failed to create subscription
+
+ private TSDBErrorNumbers() {
+ }
+}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
index 402d114215..82a6b4a3ff 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
@@ -22,7 +22,6 @@ import java.util.List;
public class TSDBStatement implements Statement {
private TSDBJNIConnector connector;
- private TaosInfo taosInfo = TaosInfo.getInstance();
/**
* To store batched commands
@@ -69,13 +68,12 @@ public class TSDBStatement implements Statement {
}
public ResultSet executeQuery(String sql) throws SQLException {
- if (isClosed) {
- throw new SQLException("Invalid method call on a closed statement.");
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
}
// TODO make sure it is not a update query
pSql = this.connector.executeQuery(sql);
-
long resultSetPointer = this.connector.getResultSet();
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
this.connector.freeResultSet(pSql);
@@ -100,8 +98,8 @@ public class TSDBStatement implements Statement {
}
public int executeUpdate(String sql) throws SQLException {
- if (isClosed) {
- throw new SQLException("Invalid method call on a closed statement.");
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
}
// TODO check if current query is update query
@@ -133,25 +131,33 @@ public class TSDBStatement implements Statement {
}
public int getMaxFieldSize() throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
+ }
+
return 0;
-// throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
public void setMaxFieldSize(int max) throws SQLException {
- if (isClosed())
- throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
+ }
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
public int getMaxRows() throws SQLException {
- if (isClosed())
- throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
+ }
// always set maxRows to zero, meaning unlimitted rows in a resultSet
return 0;
}
public void setMaxRows(int max) throws SQLException {
+ if (isClosed()) {
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
+ }
// always set maxRows to zero, meaning unlimited rows in a resultSet
}
diff --git a/src/connector/python/linux/python2/setup.py b/src/connector/python/linux/python2/setup.py
index 2cad664307..dba234d7a4 100644
--- a/src/connector/python/linux/python2/setup.py
+++ b/src/connector/python/linux/python2/setup.py
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="taos",
- version="2.0.4",
+ version="2.0.5",
author="Taosdata Inc.",
author_email="support@taosdata.com",
description="TDengine python client package",
diff --git a/src/connector/python/linux/python2/taos/cursor.py b/src/connector/python/linux/python2/taos/cursor.py
index ada83d72c5..bc3b6c65d8 100644
--- a/src/connector/python/linux/python2/taos/cursor.py
+++ b/src/connector/python/linux/python2/taos/cursor.py
@@ -1,7 +1,6 @@
from .cinterface import CTaosInterface
from .error import *
from .constants import FieldType
-import threading
class TDengineCursor(object):
@@ -36,7 +35,6 @@ class TDengineCursor(object):
self._block_iter = 0
self._affected_rows = 0
self._logfile = ""
- self._threadId = threading.get_ident()
if connection is not None:
self._connection = connection
diff --git a/src/cq/src/cqMain.c b/src/cq/src/cqMain.c
index c2df0d36b2..0dc3300911 100644
--- a/src/cq/src/cqMain.c
+++ b/src/cq/src/cqMain.c
@@ -91,6 +91,20 @@ void cqRmFromList(SCqObj *pObj) {
}
+static void freeSCqContext(void *handle) {
+ if (handle == NULL) {
+ return;
+ }
+ SCqContext *pContext = handle;
+ pthread_mutex_destroy(&pContext->mutex);
+
+ taosTmrCleanUp(pContext->tmrCtrl);
+ pContext->tmrCtrl = NULL;
+ cDebug("vgId:%d, CQ is closed", pContext->vgId);
+ free(pContext);
+}
+
+
void cqFree(void *handle) {
if (tsEnableStream == 0) {
return;
@@ -125,13 +139,7 @@ void cqFree(void *handle) {
pthread_mutex_unlock(&pContext->mutex);
if (delete) {
- pthread_mutex_destroy(&pContext->mutex);
-
- taosTmrCleanUp(pContext->tmrCtrl);
- pContext->tmrCtrl = NULL;
-
- cDebug("vgId:%d, CQ is closed", pContext->vgId);
- free(pContext);
+ freeSCqContext(pContext);
}
}
@@ -184,18 +192,7 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
return pContext;
}
-static void freeSCqContext(void *handle) {
- if (handle == NULL) {
- return;
- }
- SCqContext *pContext = handle;
- pthread_mutex_destroy(&pContext->mutex);
-
- taosTmrCleanUp(pContext->tmrCtrl);
- pContext->tmrCtrl = NULL;
- cDebug("vgId:%d, CQ is closed", pContext->vgId);
- free(pContext);
-}
+
void cqClose(void *handle) {
if (tsEnableStream == 0) {
return;
@@ -204,6 +201,8 @@ void cqClose(void *handle) {
if (handle == NULL) return;
pContext->delete = 1;
+ int32_t hasCq = 0;
+ int32_t existLoop = 0;
// stop all CQs
cqStop(pContext);
@@ -218,6 +217,12 @@ void cqClose(void *handle) {
cqRmFromList(pObj);
rid = pObj->rid;
+
+ hasCq = 1;
+
+ if (pContext->pHead == NULL) {
+ existLoop = 1;
+ }
} else {
pthread_mutex_unlock(&pContext->mutex);
break;
@@ -226,9 +231,15 @@ void cqClose(void *handle) {
pthread_mutex_unlock(&pContext->mutex);
taosRemoveRef(cqObjRef, rid);
+
+ if (existLoop) {
+ break;
+ }
}
- freeSCqContext(pContext);
+ if (hasCq == 0) {
+ freeSCqContext(pContext);
+ }
}
void cqStart(void *handle) {
diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c
index a40df626e2..9a226b81e8 100644
--- a/src/dnode/src/dnodeShell.c
+++ b/src/dnode/src/dnodeShell.c
@@ -36,12 +36,12 @@ int32_t dnodeInitShell() {
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_QUERY] = dnodeDispatchToVReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_FETCH] = dnodeDispatchToVReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = dnodeDispatchToVWriteQueue;
-
+
// the following message shall be treated as mnode write
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_ACCT] = dnodeDispatchToMWriteQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_ALTER_ACCT] = dnodeDispatchToMWriteQueue;
- dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_ACCT] = dnodeDispatchToMWriteQueue;
- dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_USER] = dnodeDispatchToMWriteQueue;
+ dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_ACCT] = dnodeDispatchToMWriteQueue;
+ dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_USER] = dnodeDispatchToMWriteQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_ALTER_USER] = dnodeDispatchToMWriteQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_USER] = dnodeDispatchToMWriteQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_DNODE]= dnodeDispatchToMWriteQueue;
@@ -57,13 +57,13 @@ int32_t dnodeInitShell() {
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_KILL_STREAM] = dnodeDispatchToMWriteQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_KILL_CONN] = dnodeDispatchToMWriteQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CONFIG_DNODE]= dnodeDispatchToMWriteQueue;
-
- // the following message shall be treated as mnode query
+
+ // the following message shall be treated as mnode query
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_HEARTBEAT] = dnodeDispatchToMReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CONNECT] = dnodeDispatchToMReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_USE_DB] = dnodeDispatchToMReadQueue;
- dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_TABLE_META] = dnodeDispatchToMReadQueue;
- dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_STABLE_VGROUP]= dnodeDispatchToMReadQueue;
+ dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_TABLE_META] = dnodeDispatchToMReadQueue;
+ dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_STABLE_VGROUP]= dnodeDispatchToMReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_TABLES_META] = dnodeDispatchToMReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_SHOW] = dnodeDispatchToMReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_RETRIEVE] = dnodeDispatchToMReadQueue;
@@ -153,7 +153,7 @@ static int32_t dnodeAuthNettestUser(char *user, char *spi, char *encrypt, char *
}
static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
- if (dnodeAuthNettestUser(user, spi, encrypt, secret, ckey) == 0) return 0;
+ if (dnodeAuthNettestUser(user, spi, encrypt, secret, ckey) == 0) return 0;
int code = mnodeRetriveAuth(user, spi, encrypt, secret, ckey);
if (code != TSDB_CODE_APP_NOT_READY) return code;
@@ -164,7 +164,7 @@ static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char
rpcMsg.pCont = pMsg;
rpcMsg.contLen = sizeof(SAuthMsg);
rpcMsg.msgType = TSDB_MSG_TYPE_DM_AUTH;
-
+
dDebug("user:%s, send auth msg to mnodes", user);
SRpcMsg rpcRsp = {0};
dnodeSendMsgToMnodeRecv(&rpcMsg, &rpcRsp);
@@ -202,14 +202,14 @@ void *dnodeSendCfgTableToRecv(int32_t vgId, int32_t tid) {
SRpcMsg rpcRsp = {0};
dnodeSendMsgToMnodeRecv(&rpcMsg, &rpcRsp);
terrno = rpcRsp.code;
-
+
if (rpcRsp.code != 0) {
rpcFreeCont(rpcRsp.pCont);
dError("vgId:%d, tid:%d failed to config table from mnode", vgId, tid);
return NULL;
} else {
dInfo("vgId:%d, tid:%d config table msg is received", vgId, tid);
-
+
// delete this after debug finished
SMDCreateTableMsg *pTable = rpcRsp.pCont;
int16_t numOfColumns = htons(pTable->numOfColumns);
@@ -231,4 +231,4 @@ SStatisInfo dnodeGetStatisInfo() {
}
return info;
-}
\ No newline at end of file
+}
diff --git a/src/dnode/src/dnodeStep.c b/src/dnode/src/dnodeStep.c
index 8878299d94..eda6fb227d 100644
--- a/src/dnode/src/dnodeStep.c
+++ b/src/dnode/src/dnodeStep.c
@@ -69,6 +69,6 @@ int32_t dnodeStepInit(SStep *pSteps, int32_t stepSize) {
return 0;
}
-void dnodeStepCleanup(SStep *pSteps, int32_t stepSize) {
+void dnodeStepCleanup(SStep *pSteps, int32_t stepSize) {
taosStepCleanupImp(pSteps, stepSize - 1);
-}
\ No newline at end of file
+}
diff --git a/src/dnode/src/dnodeSystem.c b/src/dnode/src/dnodeSystem.c
index 33ebc8b64f..e49b3eba99 100644
--- a/src/dnode/src/dnodeSystem.c
+++ b/src/dnode/src/dnodeSystem.c
@@ -181,4 +181,4 @@ static void sigintHandler(int32_t signum, void *sigInfo, void *context) {
#ifdef WINDOWS
tsem_wait(&exitSem);
#endif
-}
\ No newline at end of file
+}
diff --git a/src/dnode/src/dnodeVWrite.c b/src/dnode/src/dnodeVWrite.c
index 93d1611ebc..a3ff459396 100644
--- a/src/dnode/src/dnodeVWrite.c
+++ b/src/dnode/src/dnodeVWrite.c
@@ -53,7 +53,7 @@ void dnodeCleanupVWrite() {
for (int32_t i = 0; i < tsVWriteWP.max; ++i) {
SVWriteWorker *pWorker = tsVWriteWP.worker + i;
if (taosCheckPthreadValid(pWorker->thread)) {
- taosQsetThreadResume(pWorker->qset);
+ if (pWorker->qset) taosQsetThreadResume(pWorker->qset);
}
}
diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h
index 5b31fbf292..721b9ca605 100644
--- a/src/inc/taosmsg.h
+++ b/src/inc/taosmsg.h
@@ -496,6 +496,7 @@ typedef struct {
int32_t tsOrder; // ts comp block order
int32_t numOfTags; // number of tags columns involved
int32_t sqlstrLen; // sql query string
+ int32_t prevResultLen; // previous result length
SColumnInfo colList[];
} SQueryTableMsg;
diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c
index 1d77a6bb63..4d8c64d8b3 100644
--- a/src/kit/taosdemo/taosdemo.c
+++ b/src/kit/taosdemo/taosdemo.c
@@ -908,6 +908,7 @@ int main(int argc, char *argv[]) {
}
pthread_join(read_id, NULL);
taos_close(rInfo->taos);
+ free(rInfo);
}
taos_cleanup();
diff --git a/src/kit/taosdemox/taosdemox.c b/src/kit/taosdemox/taosdemox.c
index f2f7aaaf5d..40ca232327 100644
--- a/src/kit/taosdemox/taosdemox.c
+++ b/src/kit/taosdemox/taosdemox.c
@@ -93,6 +93,8 @@ extern char configDir[];
#define MAX_QUERY_SQL_COUNT 10
#define MAX_QUERY_SQL_LENGTH 256
+#define MAX_DATABASE_COUNT 256
+
typedef enum CREATE_SUB_TALBE_MOD_EN {
PRE_CREATE_SUBTBL,
AUTO_CREATE_SUBTBL,
@@ -116,7 +118,41 @@ enum QUERY_TYPE {
INSERT_TYPE,
QUERY_TYPE_BUT
} ;
-
+
+enum _show_db_index {
+ TSDB_SHOW_DB_NAME_INDEX,
+ TSDB_SHOW_DB_CREATED_TIME_INDEX,
+ TSDB_SHOW_DB_NTABLES_INDEX,
+ TSDB_SHOW_DB_VGROUPS_INDEX,
+ TSDB_SHOW_DB_REPLICA_INDEX,
+ TSDB_SHOW_DB_QUORUM_INDEX,
+ TSDB_SHOW_DB_DAYS_INDEX,
+ TSDB_SHOW_DB_KEEP_INDEX,
+ TSDB_SHOW_DB_CACHE_INDEX,
+ TSDB_SHOW_DB_BLOCKS_INDEX,
+ TSDB_SHOW_DB_MINROWS_INDEX,
+ TSDB_SHOW_DB_MAXROWS_INDEX,
+ TSDB_SHOW_DB_WALLEVEL_INDEX,
+ TSDB_SHOW_DB_FSYNC_INDEX,
+ TSDB_SHOW_DB_COMP_INDEX,
+ TSDB_SHOW_DB_CACHELAST_INDEX,
+ TSDB_SHOW_DB_PRECISION_INDEX,
+ TSDB_SHOW_DB_UPDATE_INDEX,
+ TSDB_SHOW_DB_STATUS_INDEX,
+ TSDB_MAX_SHOW_DB
+};
+
+// -----------------------------------------SHOW TABLES CONFIGURE -------------------------------------
+enum _show_stables_index {
+ TSDB_SHOW_STABLES_NAME_INDEX,
+ TSDB_SHOW_STABLES_CREATED_TIME_INDEX,
+ TSDB_SHOW_STABLES_COLUMNS_INDEX,
+ TSDB_SHOW_STABLES_METRIC_INDEX,
+ TSDB_SHOW_STABLES_UID_INDEX,
+ TSDB_SHOW_STABLES_TID_INDEX,
+ TSDB_SHOW_STABLES_VGID_INDEX,
+ TSDB_MAX_SHOW_STABLES
+};
enum _describe_table_index {
TSDB_DESCRIBE_METRIC_FIELD_INDEX,
TSDB_DESCRIBE_METRIC_TYPE_INDEX,
@@ -219,6 +255,28 @@ typedef struct SSuperTable_S {
int64_t totalAffectedRows;
} SSuperTable;
+typedef struct {
+ char name[TSDB_DB_NAME_LEN + 1];
+ char create_time[32];
+ int32_t ntables;
+ int32_t vgroups;
+ int16_t replica;
+ int16_t quorum;
+ int16_t days;
+ char keeplist[32];
+ int32_t cache; //MB
+ int32_t blocks;
+ int32_t minrows;
+ int32_t maxrows;
+ int8_t wallevel;
+ int32_t fsync;
+ int8_t comp;
+ int8_t cachelast;
+ char precision[8]; // time resolution
+ int8_t update;
+ char status[16];
+} SDbInfo;
+
typedef struct SDbCfg_S {
// int maxtablesPerVnode;
int minRows;
@@ -1126,6 +1184,272 @@ static void printfQueryMeta() {
printf("\033[1m\033[40;32m================ query.json parse result ================\033[0m\n");
}
+
+static char* xFormatTimestamp(char* buf, int64_t val, int precision) {
+ time_t tt;
+ if (precision == TSDB_TIME_PRECISION_MICRO) {
+ tt = (time_t)(val / 1000000);
+ } else {
+ tt = (time_t)(val / 1000);
+ }
+
+/* comment out as it make testcases like select_with_tags.sim fail.
+ but in windows, this may cause the call to localtime crash if tt < 0,
+ need to find a better solution.
+ if (tt < 0) {
+ tt = 0;
+ }
+ */
+
+#ifdef WINDOWS
+ if (tt < 0) tt = 0;
+#endif
+
+ struct tm* ptm = localtime(&tt);
+ size_t pos = strftime(buf, 32, "%Y-%m-%d %H:%M:%S", ptm);
+
+ if (precision == TSDB_TIME_PRECISION_MICRO) {
+ sprintf(buf + pos, ".%06d", (int)(val % 1000000));
+ } else {
+ sprintf(buf + pos, ".%03d", (int)(val % 1000));
+ }
+
+ return buf;
+}
+
+static void xDumpFieldToFile(FILE* fp, const char* val, TAOS_FIELD* field, int32_t length, int precision) {
+ if (val == NULL) {
+ fprintf(fp, "%s", TSDB_DATA_NULL_STR);
+ return;
+ }
+
+ char buf[TSDB_MAX_BYTES_PER_ROW];
+ switch (field->type) {
+ case TSDB_DATA_TYPE_BOOL:
+ fprintf(fp, "%d", ((((int32_t)(*((char *)val))) == 1) ? 1 : 0));
+ break;
+ case TSDB_DATA_TYPE_TINYINT:
+ fprintf(fp, "%d", *((int8_t *)val));
+ break;
+ case TSDB_DATA_TYPE_SMALLINT:
+ fprintf(fp, "%d", *((int16_t *)val));
+ break;
+ case TSDB_DATA_TYPE_INT:
+ fprintf(fp, "%d", *((int32_t *)val));
+ break;
+ case TSDB_DATA_TYPE_BIGINT:
+ fprintf(fp, "%" PRId64, *((int64_t *)val));
+ break;
+ case TSDB_DATA_TYPE_FLOAT:
+ fprintf(fp, "%.5f", GET_FLOAT_VAL(val));
+ break;
+ case TSDB_DATA_TYPE_DOUBLE:
+ fprintf(fp, "%.9f", GET_DOUBLE_VAL(val));
+ break;
+ case TSDB_DATA_TYPE_BINARY:
+ case TSDB_DATA_TYPE_NCHAR:
+ memcpy(buf, val, length);
+ buf[length] = 0;
+ fprintf(fp, "\'%s\'", buf);
+ break;
+ case TSDB_DATA_TYPE_TIMESTAMP:
+ xFormatTimestamp(buf, *(int64_t*)val, precision);
+ fprintf(fp, "'%s'", buf);
+ break;
+ default:
+ break;
+ }
+}
+
+static int xDumpResultToFile(const char* fname, TAOS_RES* tres) {
+ TAOS_ROW row = taos_fetch_row(tres);
+ if (row == NULL) {
+ return 0;
+ }
+
+ FILE* fp = fopen(fname, "at");
+ if (fp == NULL) {
+ fprintf(stderr, "ERROR: failed to open file: %s\n", fname);
+ return -1;
+ }
+
+ int num_fields = taos_num_fields(tres);
+ TAOS_FIELD *fields = taos_fetch_fields(tres);
+ int precision = taos_result_precision(tres);
+
+ for (int col = 0; col < num_fields; col++) {
+ if (col > 0) {
+ fprintf(fp, ",");
+ }
+ fprintf(fp, "%s", fields[col].name);
+ }
+ fputc('\n', fp);
+
+ int numOfRows = 0;
+ do {
+ int32_t* length = taos_fetch_lengths(tres);
+ for (int i = 0; i < num_fields; i++) {
+ if (i > 0) {
+ fputc(',', fp);
+ }
+ xDumpFieldToFile(fp, (const char*)row[i], fields +i, length[i], precision);
+ }
+ fputc('\n', fp);
+
+ numOfRows++;
+ row = taos_fetch_row(tres);
+ } while( row != NULL);
+
+ fclose(fp);
+
+ return numOfRows;
+}
+
+static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) {
+ TAOS_RES * res;
+ TAOS_ROW row = NULL;
+ int count = 0;
+
+ res = taos_query(taos, "show databases;");
+ int32_t code = taos_errno(res);
+
+ if (code != 0) {
+ fprintf(stderr, "failed to run , reason: %s\n", taos_errstr(res));
+ return -1;
+ }
+
+ TAOS_FIELD *fields = taos_fetch_fields(res);
+
+ while ((row = taos_fetch_row(res)) != NULL) {
+ // sys database name : 'log'
+ if (strncasecmp(row[TSDB_SHOW_DB_NAME_INDEX], "log", fields[TSDB_SHOW_DB_NAME_INDEX].bytes) == 0) continue;
+
+ dbInfos[count] = (SDbInfo *)calloc(1, sizeof(SDbInfo));
+ if (dbInfos[count] == NULL) {
+ fprintf(stderr, "failed to allocate memory for some dbInfo[%d]\n", count);
+ return -1;
+ }
+
+ strncpy(dbInfos[count]->name, (char *)row[TSDB_SHOW_DB_NAME_INDEX], fields[TSDB_SHOW_DB_NAME_INDEX].bytes);
+ xFormatTimestamp(dbInfos[count]->create_time, *(int64_t*)row[TSDB_SHOW_DB_CREATED_TIME_INDEX], TSDB_TIME_PRECISION_MILLI);
+ dbInfos[count]->ntables = *((int32_t *)row[TSDB_SHOW_DB_NTABLES_INDEX]);
+ dbInfos[count]->vgroups = *((int32_t *)row[TSDB_SHOW_DB_VGROUPS_INDEX]);
+ dbInfos[count]->replica = *((int16_t *)row[TSDB_SHOW_DB_REPLICA_INDEX]);
+ dbInfos[count]->quorum = *((int16_t *)row[TSDB_SHOW_DB_QUORUM_INDEX]);
+ dbInfos[count]->days = *((int16_t *)row[TSDB_SHOW_DB_DAYS_INDEX]);
+
+ strncpy(dbInfos[count]->keeplist, (char *)row[TSDB_SHOW_DB_KEEP_INDEX], fields[TSDB_SHOW_DB_KEEP_INDEX].bytes);
+ dbInfos[count]->cache = *((int32_t *)row[TSDB_SHOW_DB_CACHE_INDEX]);
+ dbInfos[count]->blocks = *((int32_t *)row[TSDB_SHOW_DB_BLOCKS_INDEX]);
+ dbInfos[count]->minrows = *((int32_t *)row[TSDB_SHOW_DB_MINROWS_INDEX]);
+ dbInfos[count]->maxrows = *((int32_t *)row[TSDB_SHOW_DB_MAXROWS_INDEX]);
+ dbInfos[count]->wallevel = *((int8_t *)row[TSDB_SHOW_DB_WALLEVEL_INDEX]);
+ dbInfos[count]->fsync = *((int32_t *)row[TSDB_SHOW_DB_FSYNC_INDEX]);
+ dbInfos[count]->comp = (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_COMP_INDEX]));
+ dbInfos[count]->cachelast = (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_CACHELAST_INDEX]));
+
+ strncpy(dbInfos[count]->precision, (char *)row[TSDB_SHOW_DB_PRECISION_INDEX], fields[TSDB_SHOW_DB_PRECISION_INDEX].bytes);
+ dbInfos[count]->update = *((int8_t *)row[TSDB_SHOW_DB_UPDATE_INDEX]);
+ strncpy(dbInfos[count]->status, (char *)row[TSDB_SHOW_DB_STATUS_INDEX], fields[TSDB_SHOW_DB_STATUS_INDEX].bytes);
+
+ count++;
+ if (count > MAX_DATABASE_COUNT) {
+ fprintf(stderr, "The database count overflow than %d\n", MAX_DATABASE_COUNT);
+ break;
+ }
+ }
+
+ return count;
+}
+
+static void printfDbInfoForQueryToFile(char* filename, SDbInfo* dbInfos, int index) {
+ FILE *fp = NULL;
+ if (filename[0] != 0) {
+ fp = fopen(filename, "at");
+ if (fp == NULL) {
+ fprintf(stderr, "failed to open file: %s\n", filename);
+ return;
+ }
+ }
+
+ fprintf(fp, "================ database[%d] ================\n", index);
+ fprintf(fp, "name: %s\n", dbInfos->name);
+ fprintf(fp, "created_time: %s\n", dbInfos->create_time);
+ fprintf(fp, "ntables: %d\n", dbInfos->ntables);
+ fprintf(fp, "vgroups: %d\n", dbInfos->vgroups);
+ fprintf(fp, "replica: %d\n", dbInfos->replica);
+ fprintf(fp, "quorum: %d\n", dbInfos->quorum);
+ fprintf(fp, "days: %d\n", dbInfos->days);
+ fprintf(fp, "keep1,keep2,keep(D): %s\n", dbInfos->keeplist);
+ fprintf(fp, "cache(MB): %d\n", dbInfos->cache);
+ fprintf(fp, "blocks: %d\n", dbInfos->blocks);
+ fprintf(fp, "minrows: %d\n", dbInfos->minrows);
+ fprintf(fp, "maxrows: %d\n", dbInfos->maxrows);
+ fprintf(fp, "wallevel: %d\n", dbInfos->wallevel);
+ fprintf(fp, "fsync: %d\n", dbInfos->fsync);
+ fprintf(fp, "comp: %d\n", dbInfos->comp);
+ fprintf(fp, "cachelast: %d\n", dbInfos->cachelast);
+ fprintf(fp, "precision: %s\n", dbInfos->precision);
+ fprintf(fp, "update: %d\n", dbInfos->update);
+ fprintf(fp, "status: %s\n", dbInfos->status);
+ fprintf(fp, "\n");
+
+ fclose(fp);
+}
+
+static void printfQuerySystemInfo(TAOS * taos) {
+ char filename[MAX_QUERY_SQL_LENGTH+1] = {0};
+ char buffer[MAX_QUERY_SQL_LENGTH+1] = {0};
+ TAOS_RES* res;
+
+ time_t t;
+ struct tm* lt;
+ time(&t);
+ lt = localtime(&t);
+ snprintf(filename, MAX_QUERY_SQL_LENGTH, "querySystemInfo-%d-%d-%d %d:%d:%d", lt->tm_year+1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
+
+ // show variables
+ res = taos_query(taos, "show variables;");
+ //getResult(res, filename);
+ xDumpResultToFile(filename, res);
+
+ // show dnodes
+ res = taos_query(taos, "show dnodes;");
+ xDumpResultToFile(filename, res);
+ //getResult(res, filename);
+
+ // show databases
+ res = taos_query(taos, "show databases;");
+ SDbInfo** dbInfos = (SDbInfo **)calloc(MAX_DATABASE_COUNT, sizeof(SDbInfo *));
+ if (dbInfos == NULL) {
+ fprintf(stderr, "failed to allocate memory\n");
+ return;
+ }
+ int dbCount = getDbFromServer(taos, dbInfos);
+ if (dbCount <= 0) return;
+
+ for (int i = 0; i < dbCount; i++) {
+ // printf database info
+ printfDbInfoForQueryToFile(filename, dbInfos[i], i);
+
+ // show db.vgroups
+ snprintf(buffer, MAX_QUERY_SQL_LENGTH, "show %s.vgroups;", dbInfos[i]->name);
+ res = taos_query(taos, buffer);
+ xDumpResultToFile(filename, res);
+
+ // show db.stables
+ snprintf(buffer, MAX_QUERY_SQL_LENGTH, "show %s.stables;", dbInfos[i]->name);
+ res = taos_query(taos, buffer);
+ xDumpResultToFile(filename, res);
+
+ free(dbInfos[i]);
+ }
+
+ free(dbInfos);
+
+}
+
+
#ifdef TD_LOWA_CURL
static size_t responseCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
@@ -4134,7 +4458,7 @@ void *subQueryProcess(void *sarg) {
int queryTestProcess() {
TAOS * taos = NULL;
taos_init();
- taos = taos_connect(g_queryInfo.host, g_queryInfo.user, g_queryInfo.password, g_queryInfo.dbName, g_queryInfo.port);
+ taos = taos_connect(g_queryInfo.host, g_queryInfo.user, g_queryInfo.password, NULL, g_queryInfo.port);
if (taos == NULL) {
fprintf(stderr, "Failed to connect to TDengine, reason:%s\n", taos_errstr(NULL));
exit(-1);
@@ -4147,6 +4471,8 @@ int queryTestProcess() {
printfQueryMeta();
printf("Press enter key to continue\n\n");
(void)getchar();
+
+ printfQuerySystemInfo(taos);
pthread_t *pids = NULL;
threadInfo *infos = NULL;
diff --git a/src/mnode/src/mnodeDb.c b/src/mnode/src/mnodeDb.c
index a853342ab3..dbb5f56692 100644
--- a/src/mnode/src/mnodeDb.c
+++ b/src/mnode/src/mnodeDb.c
@@ -679,7 +679,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
pShow->pIter = mnodeGetNextDb(pShow->pIter, &pDb);
if (pDb == NULL) break;
- if (pDb->pAcct != pUser->pAcct) {
+ if (pDb->pAcct != pUser->pAcct || pDb->status != TSDB_DB_STATUS_READY) {
mnodeDecDbRef(pDb);
continue;
}
diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c
index 8928bf0aac..7f463899ce 100644
--- a/src/mnode/src/mnodeTable.c
+++ b/src/mnode/src/mnodeTable.c
@@ -1081,20 +1081,13 @@ static int32_t mnodeDropSuperTableCb(SMnodeMsg *pMsg, int32_t code) {
SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
if (code != TSDB_CODE_SUCCESS) {
mError("msg:%p, app:%p stable:%s, failed to drop, sdb error", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId);
- } else {
- mLInfo("msg:%p, app:%p stable:%s, is dropped from sdb", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId);
+
+ return code;
}
- return code;
-}
-
-static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) {
- if (pMsg == NULL) return TSDB_CODE_MND_APP_ERROR;
+ mLInfo("msg:%p, app:%p stable:%s, is dropped from sdb", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId);
SSTableObj *pStable = (SSTableObj *)pMsg->pTable;
- mInfo("msg:%p, app:%p stable:%s will be dropped, hash:%p sizeOfVgList:%d", pMsg, pMsg->rpcMsg.ahandle,
- pStable->info.tableId, pStable->vgHash, taosHashGetSize(pStable->vgHash));
-
if (pStable->vgHash != NULL /*pStable->numOfTables != 0*/) {
int32_t *pVgId = taosHashIterate(pStable->vgHash, NULL);
while (pVgId) {
@@ -1122,6 +1115,16 @@ static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) {
mnodeDropAllChildTablesInStable(pStable);
}
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) {
+ if (pMsg == NULL) return TSDB_CODE_MND_APP_ERROR;
+
+ SSTableObj *pStable = (SSTableObj *)pMsg->pTable;
+ mInfo("msg:%p, app:%p stable:%s will be dropped, hash:%p sizeOfVgList:%d", pMsg, pMsg->rpcMsg.ahandle,
+ pStable->info.tableId, pStable->vgHash, taosHashGetSize(pStable->vgHash));
+
SSdbRow row = {
.type = SDB_OPER_GLOBAL,
.pTable = tsSuperTableSdb,
@@ -1461,9 +1464,9 @@ static int32_t mnodeGetShowSuperTableMeta(STableMetaMsg *pMeta, SShowObj *pShow,
int32_t cols = 0;
SSchema *pSchema = pMeta->schema;
- SSchema tbnameSchema = tGetTableNameColumnSchema();
- pShow->bytes[cols] = tbnameSchema.bytes;
- pSchema[cols].type = tbnameSchema.type;
+ SSchema* tbnameSchema = tGetTbnameColumnSchema();
+ pShow->bytes[cols] = tbnameSchema->bytes;
+ pSchema[cols].type = tbnameSchema->type;
strcpy(pSchema[cols].name, "name");
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
@@ -2821,9 +2824,9 @@ static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void
int32_t cols = 0;
SSchema *pSchema = pMeta->schema;
- SSchema s = tGetTableNameColumnSchema();
- pShow->bytes[cols] = s.bytes;
- pSchema[cols].type = s.type;
+ SSchema* s = tGetTbnameColumnSchema();
+ pShow->bytes[cols] = s->bytes;
+ pSchema[cols].type = s->type;
strcpy(pSchema[cols].name, "table_name");
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
@@ -2840,9 +2843,9 @@ static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
- SSchema tbCol = tGetTableNameColumnSchema();
- pShow->bytes[cols] = tbCol.bytes + VARSTR_HEADER_SIZE;
- pSchema[cols].type = tbCol.type;
+ SSchema* tbCol = tGetTbnameColumnSchema();
+ pShow->bytes[cols] = tbCol->bytes + VARSTR_HEADER_SIZE;
+ pSchema[cols].type = tbCol->type;
strcpy(pSchema[cols].name, "stable_name");
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
@@ -3076,9 +3079,9 @@ static int32_t mnodeGetStreamTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, vo
int32_t cols = 0;
SSchema *pSchema = pMeta->schema;
- SSchema tbnameColSchema = tGetTableNameColumnSchema();
- pShow->bytes[cols] = tbnameColSchema.bytes;
- pSchema[cols].type = tbnameColSchema.type;
+ SSchema* tbnameColSchema = tGetTbnameColumnSchema();
+ pShow->bytes[cols] = tbnameColSchema->bytes;
+ pSchema[cols].type = tbnameColSchema->type;
strcpy(pSchema[cols].name, "table_name");
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
diff --git a/src/os/inc/osDarwin.h b/src/os/inc/osDarwin.h
index 2a05d5682e..7c206afe7a 100644
--- a/src/os/inc/osDarwin.h
+++ b/src/os/inc/osDarwin.h
@@ -85,6 +85,7 @@ extern "C" {
#define TAOS_OS_FUNC_STRING_STR2INT64
#define TAOS_OS_FUNC_SYSINFO
#define TAOS_OS_FUNC_TIMER
+#define TAOS_OS_FUNC_SEMPHONE_PTHREAD
// specific
#define htobe64 htonll
@@ -114,7 +115,7 @@ int64_t tsosStr2int64(char *str);
void taos_block_sigalrm(void);
#define TAOS_OS_DEF_EPOLL
- #define TAOS_EPOLL_WAIT_TIME 500
+ #define TAOS_EPOLL_WAIT_TIME 500
typedef int32_t SOCKET;
typedef SOCKET EpollFd;
#define EpollClose(pollFd) epoll_close(pollFd)
diff --git a/src/os/inc/osDef.h b/src/os/inc/osDef.h
index 04cb8b6e74..cb91b0526b 100644
--- a/src/os/inc/osDef.h
+++ b/src/os/inc/osDef.h
@@ -26,10 +26,6 @@ extern "C" {
#endif
#endif
-#ifndef STDERR_FILENO
-#define STDERR_FILENO (2)
-#endif
-
#define FD_VALID(x) ((x) > STDERR_FILENO)
#define FD_INITIALIZER ((int32_t)-1)
diff --git a/src/os/inc/osWindows.h b/src/os/inc/osWindows.h
index 6f96e4d1c8..d54d519cc3 100644
--- a/src/os/inc/osWindows.h
+++ b/src/os/inc/osWindows.h
@@ -46,6 +46,8 @@
#include "msvcFcntl.h"
#include "msvcLibgen.h"
#include "msvcStdio.h"
+#include "msvcUnistd.h"
+#include "msvcLibgen.h"
#include "sys/msvcStat.h"
#include "sys/msvcTypes.h"
@@ -144,7 +146,6 @@ typedef int (*__compar_fn_t)(const void *, const void *);
#define in_addr_t unsigned long
#define socklen_t int
#define htobe64 htonll
-#define getpid _getpid
struct tm *localtime_r(const time_t *timep, struct tm *result);
char * strptime(const char *buf, const char *fmt, struct tm *tm);
@@ -153,15 +154,8 @@ char * getpass(const char *prefix);
int flock(int fd, int option);
int fsync(int filedes);
char * strndup(const char *s, size_t n);
-char * dirname(char *pszPathname);
int gettimeofday(struct timeval *ptv, void *pTimeZone);
-// for access function in io.h
-#define F_OK 00 //Existence only
-#define W_OK 02 //Write - only
-#define R_OK 04 //Read - only
-#define X_OK 06 //Read and write
-
// for send function in tsocket.c
#define MSG_NOSIGNAL 0
#define SO_NO_CHECK 0x1234
@@ -208,8 +202,6 @@ typedef struct {
int wordexp(char *words, wordexp_t *pwordexp, int flags);
void wordfree(wordexp_t *pwordexp);
-char *realpath(char *path, char *resolved_path);
-
#define openlog(a, b, c)
#define closelog()
#define LOG_ERR 0
diff --git a/src/os/src/darwin/darwinEnv.c b/src/os/src/darwin/darwinEnv.c
index da4b32139e..83344df221 100644
--- a/src/os/src/darwin/darwinEnv.c
+++ b/src/os/src/darwin/darwinEnv.c
@@ -17,17 +17,29 @@
#include "os.h"
#include "tglobal.h"
+static const char* expand_like_shell(const char *path) {
+ static __thread char buf[TSDB_FILENAME_LEN];
+ buf[0] = '\0';
+ wordexp_t we;
+ if (wordexp(path, &we, 0)) return "/tmp/taosd";
+ if (sizeof(buf)<=snprintf(buf, sizeof(buf), "%s", we.we_wordv[0])) return "/tmp/taosd";
+ wordfree(&we);
+ return buf;
+}
+
void osInit() {
if (configDir[0] == 0) {
- strcpy(configDir, "~/TDengine/cfg");
+ strcpy(configDir, expand_like_shell("~/TDengine/cfg"));
}
strcpy(tsVnodeDir, "");
strcpy(tsDnodeDir, "");
strcpy(tsMnodeDir, "");
- strcpy(tsDataDir, "~/TDengine/data");
- strcpy(tsLogDir, "~/TDengine/log");
- strcpy(tsScriptDir, "~/TDengine/cfg");
+
+ strcpy(tsDataDir, expand_like_shell("~/TDengine/data"));
+ strcpy(tsLogDir, expand_like_shell("~/TDengine/log"));
+ strcpy(tsScriptDir, expand_like_shell("~/TDengine/cfg"));
+
strcpy(tsOsName, "Darwin");
}
diff --git a/src/os/src/darwin/darwinFile.c b/src/os/src/darwin/darwinFile.c
index 1e77cd68d8..4236ea1c5f 100644
--- a/src/os/src/darwin/darwinFile.c
+++ b/src/os/src/darwin/darwinFile.c
@@ -17,71 +17,49 @@
#include "os.h"
#include "tulog.h"
-#define _SEND_FILE_STEP_ 1000
-
int64_t taosFSendFile(FILE *out_file, FILE *in_file, int64_t *offset, int64_t count) {
- fseek(in_file, (int32_t)(*offset), 0);
- int writeLen = 0;
- uint8_t buffer[_SEND_FILE_STEP_] = {0};
-
- for (int len = 0; len < (count - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) {
- size_t rlen = fread(buffer, 1, _SEND_FILE_STEP_, in_file);
- if (rlen <= 0) {
- return writeLen;
- } else if (rlen < _SEND_FILE_STEP_) {
- fwrite(buffer, 1, rlen, out_file);
- return (int)(writeLen + rlen);
- } else {
- fwrite(buffer, 1, _SEND_FILE_STEP_, in_file);
- writeLen += _SEND_FILE_STEP_;
- }
+ int r = 0;
+ if (offset) {
+ r = fseek(in_file, *offset, SEEK_SET);
+ if (r==-1) return -1;
}
-
- int remain = count - writeLen;
- if (remain > 0) {
- size_t rlen = fread(buffer, 1, remain, in_file);
- if (rlen <= 0) {
- return writeLen;
- } else {
- fwrite(buffer, 1, remain, out_file);
- writeLen += remain;
+ off_t len = count;
+ while (len>0) {
+ char buf[1024*16];
+ off_t n = sizeof(buf);
+ if (len 0) {
- int32_t rlen = read(sfd, buffer, (int32_t)remain);
- if (rlen <= 0) {
- return writeLen;
- }
- else {
- taosWriteSocket(sfd, buffer, (int32_t)remain);
- writeLen += remain;
- }
+ off_t len = count;
+ while (len>0) {
+ char buf[1024*16];
+ off_t n = sizeof(buf);
+ if (len
+
// #define SEM_USE_PTHREAD
// #define SEM_USE_POSIX
#define SEM_USE_SEM
@@ -279,3 +281,41 @@ int tsem_destroy(tsem_t *sem) {
return 0;
}
+bool taosCheckPthreadValid(pthread_t thread) {
+ uint64_t id = 0;
+ int r = pthread_threadid_np(thread, &id);
+ return r ? false : true;
+}
+
+int64_t taosGetSelfPthreadId() {
+ return (int64_t)pthread_self();
+}
+
+int64_t taosGetPthreadId(pthread_t thread) {
+ return (int64_t)thread;
+}
+
+void taosResetPthread(pthread_t* thread) {
+ *thread = NULL;
+}
+
+bool taosComparePthread(pthread_t first, pthread_t second) {
+ return pthread_equal(first, second) ? true : false;
+}
+
+int32_t taosGetPId() {
+ return (int32_t)getpid();
+}
+
+int32_t taosGetCurrentAPPName(char* name, int32_t* len) {
+ char buf[PATH_MAX+1];
+ buf[0] = '\0';
+ proc_name(getpid(), buf, sizeof(buf)-1);
+ buf[PATH_MAX] = '\0';
+ size_t n = strlen(buf);
+ if (len) *len = n;
+ if (name) strcpy(name, buf);
+ return 0;
+}
+
+
diff --git a/src/os/src/darwin/darwinSysInfo.c b/src/os/src/darwin/darwinSysInfo.c
index bce60429c5..6af6285f56 100644
--- a/src/os/src/darwin/darwinSysInfo.c
+++ b/src/os/src/darwin/darwinSysInfo.c
@@ -24,42 +24,134 @@
static void taosGetSystemTimezone() {
- // get and set default timezone
SGlobalCfg *cfg_timezone = taosGetConfigOption("timezone");
- if (cfg_timezone && cfg_timezone->cfgStatus < TAOS_CFG_CSTATUS_DEFAULT) {
- char *tz = getenv("TZ");
- if (tz == NULL || strlen(tz) == 0) {
- strcpy(tsTimezone, "not configured");
- }
- else {
- strcpy(tsTimezone, tz);
- }
- cfg_timezone->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT;
- uInfo("timezone not configured, use default");
+ if (cfg_timezone == NULL) return;
+ if (cfg_timezone->cfgStatus >= TAOS_CFG_CSTATUS_DEFAULT) {
+ return;
}
+
+ /* load time zone string from /etc/localtime */
+ char buf[4096];
+ char *tz = NULL; {
+ int n = readlink("/etc/localtime", buf, sizeof(buf));
+ if (n<0) {
+ uError("read /etc/localtime error, reason:%s", strerror(errno));
+ return;
+ }
+ buf[n] = '\0';
+ for(int i=n-1; i>=0; --i) {
+ if (buf[i]=='/') {
+ if (tz) {
+ tz = buf + i + 1;
+ break;
+ }
+ tz = buf + i + 1;
+ }
+ }
+ if (!tz || 0==strchr(tz, '/')) {
+ uError("parsing /etc/localtime failed");
+ return;
+ }
+
+ setenv("TZ", tz, 1);
+ tzset();
+ }
+
+ /*
+ * NOTE: do not remove it.
+ * Enforce set the correct daylight saving time(DST) flag according
+ * to current time
+ */
+ time_t tx1 = time(NULL);
+ struct tm tm1;
+ localtime_r(&tx1, &tm1);
+
+ /*
+ * format example:
+ *
+ * Asia/Shanghai (CST, +0800)
+ * Europe/London (BST, +0100)
+ */
+ snprintf(tsTimezone, TSDB_TIMEZONE_LEN, "%s (%s, %+03ld00)",
+ tz, tm1.tm_isdst ? tzname[daylight] : tzname[0], -timezone/3600);
+
+ // cfg_timezone->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT;
+ uWarn("timezone not configured, set to system default:%s", tsTimezone);
}
-static void taosGetSystemLocale() {
- // get and set default locale
+/*
+ * originally from src/os/src/detail/osSysinfo.c
+ * POSIX format locale string:
+ * (Language Strings)_(Country/Region Strings).(code_page)
+ *
+ * example: en_US.UTF-8, zh_CN.GB18030, zh_CN.UTF-8,
+ *
+ * if user does not specify the locale in taos.cfg the program use default LC_CTYPE as system locale.
+ *
+ * In case of some CentOS systems, their default locale is "en_US.utf8", which is not valid code_page
+ * for libiconv that is employed to convert string in this system. This program will automatically use
+ * UTF-8 instead as the charset.
+ *
+ * In case of windows client, the locale string is not valid POSIX format, user needs to set the
+ * correct code_page for libiconv. Usually, the code_page of windows system with simple chinese is
+ * CP936, CP437 for English charset.
+ *
+ */
+static void taosGetSystemLocale() { // get and set default locale
+ char sep = '.';
+ char *locale = NULL;
+
SGlobalCfg *cfg_locale = taosGetConfigOption("locale");
if (cfg_locale && cfg_locale->cfgStatus < TAOS_CFG_CSTATUS_DEFAULT) {
- char *locale = setlocale(LC_CTYPE, "chs");
- if (locale != NULL) {
+ locale = setlocale(LC_CTYPE, "");
+ if (locale == NULL) {
+ uError("can't get locale from system, set it to en_US.UTF-8 since error:%d:%s", errno, strerror(errno));
+ strcpy(tsLocale, "en_US.UTF-8");
+ } else {
tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN);
- cfg_locale->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT;
- uInfo("locale not configured, set to default:%s", tsLocale);
+ uWarn("locale not configured, set to system default:%s", tsLocale);
}
}
+ /* if user does not specify the charset, extract it from locale */
SGlobalCfg *cfg_charset = taosGetConfigOption("charset");
if (cfg_charset && cfg_charset->cfgStatus < TAOS_CFG_CSTATUS_DEFAULT) {
- strcpy(tsCharset, "cp936");
- cfg_charset->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT;
- uInfo("charset not configured, set to default:%s", tsCharset);
+ char *str = strrchr(tsLocale, sep);
+ if (str != NULL) {
+ str++;
+
+ char *revisedCharset = taosCharsetReplace(str);
+ tstrncpy(tsCharset, revisedCharset, TSDB_LOCALE_LEN);
+
+ free(revisedCharset);
+ uWarn("charset not configured, set to system default:%s", tsCharset);
+ } else {
+ strcpy(tsCharset, "UTF-8");
+ uWarn("can't get locale and charset from system, set it to UTF-8");
+ }
}
}
-void taosPrintOsInfo() {}
+void taosPrintOsInfo() {
+ uInfo(" os pageSize: %" PRId64 "(KB)", tsPageSize / 1024);
+ // uInfo(" os openMax: %" PRId64, tsOpenMax);
+ // uInfo(" os streamMax: %" PRId64, tsStreamMax);
+ uInfo(" os numOfCores: %d", tsNumOfCores);
+ uInfo(" os totalDisk: %f(GB)", tsTotalDataDirGB);
+ uInfo(" os totalMemory: %d(MB)", tsTotalMemoryMB);
+
+ struct utsname buf;
+ if (uname(&buf)) {
+ uInfo(" can't fetch os info");
+ return;
+ }
+ uInfo(" os sysname: %s", buf.sysname);
+ uInfo(" os nodename: %s", buf.nodename);
+ uInfo(" os release: %s", buf.release);
+ uInfo(" os version: %s", buf.version);
+ uInfo(" os machine: %s", buf.machine);
+ uInfo("==================================");
+}
void taosKillSystem() {
uError("function taosKillSystem, exit!");
@@ -67,6 +159,22 @@ void taosKillSystem() {
}
void taosGetSystemInfo() {
+ // taosGetProcInfos();
+
+ tsNumOfCores = sysconf(_SC_NPROCESSORS_ONLN);
+ long physical_pages = sysconf(_SC_PHYS_PAGES);
+ long page_size = sysconf(_SC_PAGESIZE);
+ tsTotalMemoryMB = physical_pages * page_size / (1024 * 1024);
+ tsPageSize = page_size;
+
+ // float tmp1, tmp2;
+ // taosGetSysMemory(&tmp1);
+ // taosGetProcMemory(&tmp2);
+ // taosGetDisk();
+ // taosGetBandSpeed(&tmp1);
+ // taosGetCpuUsage(&tmp1, &tmp2);
+ // taosGetProcIO(&tmp1, &tmp2);
+
taosGetSystemTimezone();
taosGetSystemLocale();
}
@@ -121,7 +229,6 @@ int32_t taosGetDiskSize(char *dataDir, SysDiskSize *diskSize) {
char cmdline[1024];
char *taosGetCmdlineByPID(int pid) {
-
errno = 0;
if (proc_pidpath(pid, cmdline, sizeof(cmdline)) <= 0) {
@@ -136,6 +243,7 @@ bool taosGetSystemUid(char *uid) {
uuid_t uuid = {0};
uuid_generate(uuid);
// it's caller's responsibility to make enough space for `uid`, that's 36-char + 1-null
- uuid_unparse(uuid, uid);
+ uuid_unparse_lower(uuid, uid);
return true;
}
+
diff --git a/src/os/src/detail/osFile.c b/src/os/src/detail/osFile.c
index 42f2ff3afe..0b7b5ca487 100644
--- a/src/os/src/detail/osFile.c
+++ b/src/os/src/detail/osFile.c
@@ -142,6 +142,8 @@ int64_t taosCopy(char *from, char *to) {
if (bytes < sizeof(buffer)) break;
}
+ fsync(fidto);
+
close(fidfrom);
close(fidto);
return size;
diff --git a/src/os/src/detail/osSemphone.c b/src/os/src/detail/osSemphone.c
index d379e56ed8..1d05ce20a5 100644
--- a/src/os/src/detail/osSemphone.c
+++ b/src/os/src/detail/osSemphone.c
@@ -62,4 +62,4 @@ int32_t taosGetCurrentAPPName(char *name, int32_t* len) {
return 0;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/os/src/windows/wString.c b/src/os/src/windows/wString.c
index 1fb235a005..67237e655c 100644
--- a/src/os/src/windows/wString.c
+++ b/src/os/src/windows/wString.c
@@ -75,18 +75,6 @@ char *getpass(const char *prefix) {
return passwd;
}
-char *strndup(const char *s, size_t n) {
- size_t len = strlen(s);
- if (len >= n) {
- len = n;
- }
-
- char *r = calloc(len + 1, 1);
- memcpy(r, s, len);
- r[len] = 0;
- return r;
-}
-
int twcslen(const wchar_t *wcs) {
int *wstr = (int *)wcs;
if (NULL == wstr) {
diff --git a/src/os/src/windows/wWordexp.c b/src/os/src/windows/wWordexp.c
index 929505516d..febe22ac8f 100644
--- a/src/os/src/windows/wWordexp.c
+++ b/src/os/src/windows/wWordexp.c
@@ -38,7 +38,3 @@ int wordexp(char *words, wordexp_t *pwordexp, int flags) {
}
void wordfree(wordexp_t *pwordexp) {}
-
-char *realpath(char *path, char *resolved_path) {
- return _fullpath(path, resolved_path, TSDB_FILENAME_LEN - 1);
-}
\ No newline at end of file
diff --git a/src/plugins/http/src/httpSystem.c b/src/plugins/http/src/httpSystem.c
index 4721451529..203db21895 100644
--- a/src/plugins/http/src/httpSystem.c
+++ b/src/plugins/http/src/httpSystem.c
@@ -92,6 +92,11 @@ void httpStopSystem() {
tsHttpServer.stop = 1;
#ifdef WINDOWS
closesocket(tsHttpServer.fd);
+#elif __APPLE__
+ if (tsHttpServer.fd!=-1) {
+ close(tsHttpServer.fd);
+ tsHttpServer.fd = -1;
+ }
#else
shutdown(tsHttpServer.fd, SHUT_RD);
#endif
diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h
index 53af502e27..dbdada8952 100644
--- a/src/query/inc/qAggMain.h
+++ b/src/query/inc/qAggMain.h
@@ -59,25 +59,27 @@ extern "C" {
#define TSDB_FUNC_FIRST_DST 25
#define TSDB_FUNC_LAST_DST 26
-#define TSDB_FUNC_INTERP 27
+#define TSDB_FUNC_STDDEV_DST 27
+#define TSDB_FUNC_INTERP 28
-#define TSDB_FUNC_RATE 28
-#define TSDB_FUNC_IRATE 29
-#define TSDB_FUNC_SUM_RATE 30
-#define TSDB_FUNC_SUM_IRATE 31
-#define TSDB_FUNC_AVG_RATE 32
-#define TSDB_FUNC_AVG_IRATE 33
+#define TSDB_FUNC_RATE 29
+#define TSDB_FUNC_IRATE 30
+#define TSDB_FUNC_SUM_RATE 31
+#define TSDB_FUNC_SUM_IRATE 32
+#define TSDB_FUNC_AVG_RATE 33
+#define TSDB_FUNC_AVG_IRATE 34
+
+#define TSDB_FUNC_TID_TAG 35
+#define TSDB_FUNC_HISTOGRAM 36
+#define TSDB_FUNC_HLL 37
+#define TSDB_FUNC_MODE 38
+#define TSDB_FUNC_SAMPLE 39
+#define TSDB_FUNC_CEIL 40
+#define TSDB_FUNC_FLOOR 41
+#define TSDB_FUNC_ROUND 42
+#define TSDB_FUNC_MAVG 43
+#define TSDB_FUNC_CSUM 44
-#define TSDB_FUNC_TID_TAG 34
-#define TSDB_FUNC_HISTOGRAM 35
-#define TSDB_FUNC_HLL 36
-#define TSDB_FUNC_MODE 37
-#define TSDB_FUNC_SAMPLE 38
-#define TSDB_FUNC_CEIL 39
-#define TSDB_FUNC_FLOOR 40
-#define TSDB_FUNC_ROUND 41
-#define TSDB_FUNC_MAVG 42
-#define TSDB_FUNC_CSUM 43
#define TSDB_FUNCSTATE_SO 0x1u // single output
#define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
@@ -90,15 +92,12 @@ extern "C" {
#define TSDB_BASE_FUNC_SO TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_OF
#define TSDB_BASE_FUNC_MO TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_OF
-
#define TSDB_FUNCTIONS_NAME_MAX_LENGTH 16
#define TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE 50
#define DATA_SET_FLAG ',' // to denote the output area has data, not null value
#define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG)
-
-
#define QUERY_ASC_FORWARD_STEP 1
#define QUERY_DESC_FORWARD_STEP -1
@@ -167,8 +166,9 @@ typedef struct SExtTagsInfo {
// sql function runtime context
typedef struct SQLFunctionCtx {
- int32_t startOffset;
+ int32_t startOffset; // todo remove it
int32_t size; // number of rows
+ void * pInput; //
uint32_t order; // asc|desc
int16_t inputType;
int16_t inputBytes;
@@ -177,13 +177,12 @@ typedef struct SQLFunctionCtx {
int16_t outputBytes; // size of results, determined by function and input column data type
int32_t interBufBytes; // internal buffer size
bool hasNull; // null value exist in current block
- bool requireNull; // require null in some function
+ bool requireNull; // require null in some function
bool stableQuery;
- int16_t functionId; // function id
- void * aInputElemBuf;
- char * aOutputBuf; // final result output buffer, point to sdata->data
- uint8_t currentStage; // record current running step, default: 0
- int64_t nStartQueryTimestamp; // timestamp range of current query when function is executed on a specific data block
+ int16_t functionId; // function id
+ char * pOutput; // final result output buffer, point to sdata->data
+ uint8_t currentStage; // record current running step, default: 0
+ int64_t startTs; // timestamp range of current query when function is executed on a specific data block
int32_t numOfParams;
tVariant param[4]; // input parameter, e.g., top(k, 20), the number of results for top query is kept in param */
int64_t *ptsList; // corresponding timestamp array list
@@ -198,17 +197,16 @@ typedef struct SQLFunctionCtx {
SPoint1 end;
} SQLFunctionCtx;
-typedef struct SQLAggFuncElem {
- char aName[TSDB_FUNCTIONS_NAME_MAX_LENGTH];
-
- uint8_t nAggIdx; // index of function in aAggs
+typedef struct SAggFunctionInfo {
+ char name[TSDB_FUNCTIONS_NAME_MAX_LENGTH];
+ uint8_t index; // index of function in aAggs
int8_t stableFuncId; // transfer function for super table query
- uint16_t nStatus;
+ uint16_t status;
bool (*init)(SQLFunctionCtx *pCtx); // setup the execute environment
void (*xFunction)(SQLFunctionCtx *pCtx); // blocks version function
- void (*xFunctionF)(SQLFunctionCtx *pCtx, int32_t position); // single-row function version
+ void (*xFunctionF)(SQLFunctionCtx *pCtx, int32_t position); // single-row function version, todo merge with blockwise function
// some sql function require scan data twice or more, e.g.,stddev, percentile
void (*xNextStep)(SQLFunctionCtx *pCtx);
@@ -218,7 +216,7 @@ typedef struct SQLAggFuncElem {
void (*mergeFunc)(SQLFunctionCtx *pCtx);
int32_t (*dataReqFunc)(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId);
-} SQLAggFuncElem;
+} SAggFunctionInfo;
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
@@ -246,7 +244,7 @@ typedef struct STwaInfo {
} STwaInfo;
/* global sql function array */
-extern struct SQLAggFuncElem aAggs[];
+extern struct SAggFunctionInfo aAggs[];
extern int32_t functionCompatList[]; // compatible check array list
diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h
index 87c16f2ee4..80068588f7 100644
--- a/src/query/inc/qExecutor.h
+++ b/src/query/inc/qExecutor.h
@@ -143,6 +143,11 @@ typedef struct {
int64_t ts;
} SOrderedPrjQueryInfo;
+typedef struct {
+ char* tags;
+ SArray* pResult; // SArray
+} SInterResult;
+
typedef struct SQuery {
int16_t numOfCols;
int16_t numOfTags;
@@ -152,9 +157,14 @@ typedef struct SQuery {
int16_t precision;
int16_t numOfOutput;
int16_t fillType;
- int16_t checkResultBuf; // check if the buffer is full during scan each block
+ int16_t checkResultBuf; // check if the buffer is full during scan each block
SLimitVal limit;
- int32_t rowSize;
+
+ int32_t srcRowSize; // todo extract struct
+ int32_t resultRowSize;
+ int32_t maxSrcColumnSize;
+ int32_t tagLen; // tag value length of current query
+
SSqlGroupbyExpr* pGroupbyExpr;
SExprInfo* pExpr1;
SExprInfo* pExpr2;
@@ -184,14 +194,13 @@ typedef struct SQueryRuntimeEnv {
uint16_t scanFlag; // denotes reversed scan of data or not
SFillInfo* pFillInfo;
SResultRowInfo windowResInfo;
- STSBuf* pTsBuf;
- STSCursor cur;
+
SQueryCostInfo summary;
void* pQueryHandle;
void* pSecQueryHandle; // another thread for
bool stableQuery; // super table query or not
bool topBotQuery; // TODO used bitwise flag
- bool groupbyColumn; // denote if this is a groupby normal column query
+ bool groupbyColumn; // 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
bool queryWindowIdentical; // all query time windows are identical for all tables in one group
@@ -205,8 +214,12 @@ typedef struct SQueryRuntimeEnv {
int32_t* rowCellInfoOffset;// offset value for each row result cell info
char** prevRow;
- char** nextRow;
+ SArray* prevResult; // intermediate result, SArray
+ STSBuf* pTsBuf; // timestamp filter list
+ STSCursor cur;
+
+ char* tagVal; // tag value of current data block
SArithmeticSupport *sasArray;
} SQueryRuntimeEnv;
diff --git a/src/query/inc/qFill.h b/src/query/inc/qFill.h
index 9b7f0fb529..aa6df9279a 100644
--- a/src/query/inc/qFill.h
+++ b/src/query/inc/qFill.h
@@ -68,7 +68,7 @@ typedef struct SPoint {
void * val;
} SPoint;
-SFillInfo* taosInitFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
+SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
int64_t slidingTime, int8_t slidingUnit, int8_t precision, int32_t fillType,
SFillColInfo* pFillCol, void* handle);
@@ -78,7 +78,7 @@ void* taosDestroyFillInfo(SFillInfo *pFillInfo);
void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey);
-void taosFillCopyInputDataFromFilePage(SFillInfo* pFillInfo, const tFilePage** pInput);
+void taosFillSetDataBlockFromFilePage(SFillInfo* pFillInfo, const tFilePage** pInput);
void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* pInput);
diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h
index 27bf7f2d96..55311f5694 100644
--- a/src/query/inc/qUtil.h
+++ b/src/query/inc/qUtil.h
@@ -15,6 +15,8 @@
#ifndef TDENGINE_QUERYUTIL_H
#define TDENGINE_QUERYUTIL_H
+#include "tbuffer.h"
+
#define SET_RES_WINDOW_KEY(_k, _ori, _len, _uid) \
do { \
assert(sizeof(_uid) == sizeof(uint64_t)); \
@@ -74,5 +76,13 @@ int32_t getNumOfUsedResultRows(SResultRowPool* p);
bool isPointInterpoQuery(SQuery *pQuery);
+typedef struct {
+ SArray* pResult; // SArray
+ int32_t colId;
+} SStddevInterResult;
+
+void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen);
+SArray* interResFromBinary(const char* data, int32_t len);
+void freeInterResult(void* param);
#endif // TDENGINE_QUERYUTIL_H
diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c
index 12c8a16f1f..d43b5f45e8 100644
--- a/src/query/src/qAggMain.c
+++ b/src/query/src/qAggMain.c
@@ -26,7 +26,7 @@
#include "qTsbuf.h"
#include "queryLog.h"
-#define GET_INPUT_DATA_LIST(x) (((char *)((x)->aInputElemBuf)) + ((x)->startOffset) * ((x)->inputBytes))
+#define GET_INPUT_DATA_LIST(x) (((char *)((x)->pInput)) + ((x)->startOffset) * ((x)->inputBytes))
#define GET_INPUT_DATA(x, y) (GET_INPUT_DATA_LIST(x) + (y) * (x)->inputBytes)
#define GET_TS_LIST(x) ((TSKEY*)&((x)->ptsList[(x)->startOffset]))
@@ -109,6 +109,11 @@ typedef struct SStddevInfo {
int8_t stage;
} SStddevInfo;
+typedef struct SStddevdstInfo {
+ int64_t num;
+ double res;
+} SStddevdstInfo;
+
typedef struct SFirstLastInfo {
int8_t hasResult;
TSKEY ts;
@@ -335,6 +340,11 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*type = (int16_t)dataType;
*bytes = (int16_t)dataBytes;
*interBytes = dataBytes;
+ } else if (functionId == TSDB_FUNC_STDDEV_DST) {
+ *type = TSDB_DATA_TYPE_BINARY;
+ *bytes = sizeof(SStddevdstInfo);
+ *interBytes = (*bytes);
+
} else {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -354,7 +364,7 @@ static bool function_setup(SQLFunctionCtx *pCtx) {
return false;
}
- memset(pCtx->aOutputBuf, 0, (size_t)pCtx->outputBytes);
+ memset(pCtx->pOutput, 0, (size_t)pCtx->outputBytes);
initResultInfo(pResInfo, pCtx->interBufBytes);
return true;
}
@@ -370,9 +380,9 @@ static void function_finalizer(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult != DATA_SET_FLAG) {
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
- setVardataNull(pCtx->aOutputBuf, pCtx->outputType);
+ setVardataNull(pCtx->pOutput, pCtx->outputType);
} else {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
}
}
@@ -416,7 +426,7 @@ static void count_function(SQLFunctionCtx *pCtx) {
GET_RES_INFO(pCtx)->hasResult = DATA_SET_FLAG;
}
- *((int64_t *)pCtx->aOutputBuf) += numOfElem;
+ *((int64_t *)pCtx->pOutput) += numOfElem;
SET_VAL(pCtx, numOfElem, 1);
}
@@ -427,7 +437,7 @@ static void count_function_f(SQLFunctionCtx *pCtx, int32_t index) {
}
SET_VAL(pCtx, 1, 1);
- *((int64_t *)pCtx->aOutputBuf) += pCtx->size;
+ *((int64_t *)pCtx->pOutput) += pCtx->size;
// do not need it actually
SResultRowCellInfo *pInfo = GET_RES_INFO(pCtx);
@@ -437,7 +447,7 @@ static void count_function_f(SQLFunctionCtx *pCtx, int32_t index) {
static void count_func_merge(SQLFunctionCtx *pCtx) {
int64_t *pData = (int64_t *)GET_INPUT_DATA_LIST(pCtx);
for (int32_t i = 0; i < pCtx->size; ++i) {
- *((int64_t *)pCtx->aOutputBuf) += pData[i];
+ *((int64_t *)pCtx->pOutput) += pData[i];
}
SET_VAL(pCtx, pCtx->size, 1);
@@ -519,13 +529,13 @@ static void do_sum(SQLFunctionCtx *pCtx) {
assert(pCtx->size >= pCtx->preAggVals.statis.numOfNull);
if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) {
- int64_t *retVal = (int64_t *)pCtx->aOutputBuf;
+ int64_t *retVal = (int64_t *)pCtx->pOutput;
*retVal += pCtx->preAggVals.statis.sum;
} else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) {
- uint64_t *retVal = (uint64_t *)pCtx->aOutputBuf;
+ uint64_t *retVal = (uint64_t *)pCtx->pOutput;
*retVal += (uint64_t)pCtx->preAggVals.statis.sum;
} else if (pCtx->inputType == TSDB_DATA_TYPE_DOUBLE || pCtx->inputType == TSDB_DATA_TYPE_FLOAT) {
- double *retVal = (double*) pCtx->aOutputBuf;
+ double *retVal = (double*) pCtx->pOutput;
*retVal += GET_DOUBLE_VAL((const char*)&(pCtx->preAggVals.statis.sum));
}
} else { // computing based on the true data block
@@ -533,7 +543,7 @@ static void do_sum(SQLFunctionCtx *pCtx) {
notNullElems = 0;
if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) {
- int64_t *retVal = (int64_t *)pCtx->aOutputBuf;
+ int64_t *retVal = (int64_t *)pCtx->pOutput;
if (pCtx->inputType == TSDB_DATA_TYPE_TINYINT) {
LIST_ADD_N(*retVal, pCtx, pData, int8_t, notNullElems, pCtx->inputType);
@@ -545,7 +555,7 @@ static void do_sum(SQLFunctionCtx *pCtx) {
LIST_ADD_N(*retVal, pCtx, pData, int64_t, notNullElems, pCtx->inputType);
}
} else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) {
- uint64_t *retVal = (uint64_t *)pCtx->aOutputBuf;
+ uint64_t *retVal = (uint64_t *)pCtx->pOutput;
if (pCtx->inputType == TSDB_DATA_TYPE_TINYINT) {
LIST_ADD_N(*retVal, pCtx, pData, uint8_t, notNullElems, pCtx->inputType);
@@ -557,10 +567,10 @@ static void do_sum(SQLFunctionCtx *pCtx) {
LIST_ADD_N(*retVal, pCtx, pData, uint64_t, notNullElems, pCtx->inputType);
}
} else if (pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
- double *retVal = (double *)pCtx->aOutputBuf;
+ double *retVal = (double *)pCtx->pOutput;
LIST_ADD_N(*retVal, pCtx, pData, double, notNullElems, pCtx->inputType);
} else if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT) {
- double *retVal = (double *)pCtx->aOutputBuf;
+ double *retVal = (double *)pCtx->pOutput;
LIST_ADD_N(*retVal, pCtx, pData, float, notNullElems, pCtx->inputType);
}
}
@@ -580,7 +590,7 @@ static void do_sum_f(SQLFunctionCtx *pCtx, int32_t index) {
}
SET_VAL(pCtx, 1, 1);
- int64_t *res = (int64_t*) pCtx->aOutputBuf;
+ int64_t *res = (int64_t*) pCtx->pOutput;
if (pCtx->inputType == TSDB_DATA_TYPE_TINYINT) {
*res += GET_INT8_VAL(pData);
@@ -591,10 +601,10 @@ static void do_sum_f(SQLFunctionCtx *pCtx, int32_t index) {
} else if (pCtx->inputType == TSDB_DATA_TYPE_BIGINT) {
*res += GET_INT64_VAL(pData);
} else if (pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
- double *retVal = (double*) pCtx->aOutputBuf;
+ double *retVal = (double*) pCtx->pOutput;
*retVal += GET_DOUBLE_VAL(pData);
} else if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT) {
- double *retVal = (double*) pCtx->aOutputBuf;
+ double *retVal = (double*) pCtx->pOutput;
*retVal += GET_FLOAT_VAL(pData);
}
@@ -608,7 +618,7 @@ static void sum_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
// set the flag for super table query
- SSumInfo *pSum = (SSumInfo *)pCtx->aOutputBuf;
+ SSumInfo *pSum = (SSumInfo *)pCtx->pOutput;
pSum->hasResult = DATA_SET_FLAG;
}
}
@@ -619,7 +629,7 @@ static void sum_function_f(SQLFunctionCtx *pCtx, int32_t index) {
// keep the result data in output buffer, not in the intermediate buffer
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
- SSumInfo *pSum = (SSumInfo *)pCtx->aOutputBuf;
+ SSumInfo *pSum = (SSumInfo *)pCtx->pOutput;
pSum->hasResult = DATA_SET_FLAG;
}
}
@@ -644,12 +654,12 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) {
case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_BIGINT: {
- *(int64_t *)pCtx->aOutputBuf += pInput->isum;
+ *(int64_t *)pCtx->pOutput += pInput->isum;
break;
};
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE: {
- *(double *)pCtx->aOutputBuf += pInput->dsum;
+ *(double *)pCtx->pOutput += pInput->dsum;
}
}
}
@@ -702,13 +712,13 @@ static int32_t firstDistFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY en
}
// not initialized yet, it is the first block, load it.
- if (pCtx->aOutputBuf == NULL) {
+ if (pCtx->pOutput == NULL) {
return BLK_DATA_ALL_NEEDED;
}
- // the pCtx should be set to current Ctx and output buffer before call this function. Otherwise, pCtx->aOutputBuf is
+ // the pCtx should be set to current Ctx and output buffer before call this function. Otherwise, pCtx->pOutput is
// the previous windowRes output buffer, not current unloaded block. In this case, the following filter is invalid
- SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes);
+ SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->pOutput + pCtx->inputBytes);
if (pInfo->hasResult != DATA_SET_FLAG) {
return BLK_DATA_ALL_NEEDED;
} else { // data in current block is not earlier than current result
@@ -722,13 +732,13 @@ static int32_t lastDistFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end
}
// not initialized yet, it is the first block, load it.
- if (pCtx->aOutputBuf == NULL) {
+ if (pCtx->pOutput == NULL) {
return BLK_DATA_ALL_NEEDED;
}
- // the pCtx should be set to current Ctx and output buffer before call this function. Otherwise, pCtx->aOutputBuf is
+ // the pCtx should be set to current Ctx and output buffer before call this function. Otherwise, pCtx->pOutput is
// the previous windowRes output buffer, not current unloaded block. In this case, the following filter is invalid
- SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes);
+ SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->pOutput + pCtx->inputBytes);
if (pInfo->hasResult != DATA_SET_FLAG) {
return BLK_DATA_ALL_NEEDED;
} else {
@@ -801,7 +811,7 @@ static void avg_function(SQLFunctionCtx *pCtx) {
// keep the data into the final output buffer for super table query since this execution may be the last one
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SAvgInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SAvgInfo));
}
}
@@ -848,14 +858,14 @@ static void avg_function_f(SQLFunctionCtx *pCtx, int32_t index) {
// keep the data into the final output buffer for super table query since this execution may be the last one
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SAvgInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SAvgInfo));
}
}
static void avg_func_merge(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- double *sum = (double*) pCtx->aOutputBuf;
+ double *sum = (double*) pCtx->pOutput;
char *input = GET_INPUT_DATA_LIST(pCtx);
for (int32_t i = 0; i < pCtx->size; ++i, input += pCtx->inputBytes) {
@@ -881,21 +891,21 @@ static void avg_finalizer(SQLFunctionCtx *pCtx) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
if (GET_INT64_VAL(GET_ROWCELL_INTERBUF(pResInfo)) <= 0) {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
return;
}
- *(double *)pCtx->aOutputBuf = (*(double *)pCtx->aOutputBuf) / *(int64_t *)GET_ROWCELL_INTERBUF(pResInfo);
+ *(double *)pCtx->pOutput = (*(double *)pCtx->pOutput) / *(int64_t *)GET_ROWCELL_INTERBUF(pResInfo);
} else { // this is the secondary merge, only in the secondary merge, the input type is TSDB_DATA_TYPE_BINARY
assert(IS_NUMERIC_TYPE(pCtx->inputType));
SAvgInfo *pAvgInfo = (SAvgInfo *)GET_ROWCELL_INTERBUF(pResInfo);
if (pAvgInfo->num == 0) { // all data are NULL or empty table
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
return;
}
- *(double *)pCtx->aOutputBuf = pAvgInfo->sum / pAvgInfo->num;
+ *(double *)pCtx->pOutput = pAvgInfo->sum / pAvgInfo->num;
}
// cannot set the numOfIteratedElems again since it is set during previous iteration
@@ -1065,34 +1075,34 @@ static bool min_func_setup(SQLFunctionCtx *pCtx) {
switch (type) {
case TSDB_DATA_TYPE_TINYINT:
- *((int8_t *)pCtx->aOutputBuf) = INT8_MAX;
+ *((int8_t *)pCtx->pOutput) = INT8_MAX;
break;
case TSDB_DATA_TYPE_UTINYINT:
- *(uint8_t *) pCtx->aOutputBuf = UINT8_MAX;
+ *(uint8_t *) pCtx->pOutput = UINT8_MAX;
break;
case TSDB_DATA_TYPE_SMALLINT:
- *((int16_t *)pCtx->aOutputBuf) = INT16_MAX;
+ *((int16_t *)pCtx->pOutput) = INT16_MAX;
break;
case TSDB_DATA_TYPE_USMALLINT:
- *((uint16_t *)pCtx->aOutputBuf) = UINT16_MAX;
+ *((uint16_t *)pCtx->pOutput) = UINT16_MAX;
break;
case TSDB_DATA_TYPE_INT:
- *((int32_t *)pCtx->aOutputBuf) = INT32_MAX;
+ *((int32_t *)pCtx->pOutput) = INT32_MAX;
break;
case TSDB_DATA_TYPE_UINT:
- *((uint32_t *)pCtx->aOutputBuf) = UINT32_MAX;
+ *((uint32_t *)pCtx->pOutput) = UINT32_MAX;
break;
case TSDB_DATA_TYPE_BIGINT:
- *((int64_t *)pCtx->aOutputBuf) = INT64_MAX;
+ *((int64_t *)pCtx->pOutput) = INT64_MAX;
break;
case TSDB_DATA_TYPE_UBIGINT:
- *((uint64_t *)pCtx->aOutputBuf) = UINT64_MAX;
+ *((uint64_t *)pCtx->pOutput) = UINT64_MAX;
break;
case TSDB_DATA_TYPE_FLOAT:
- *((float *)pCtx->aOutputBuf) = FLT_MAX;
+ *((float *)pCtx->pOutput) = FLT_MAX;
break;
case TSDB_DATA_TYPE_DOUBLE:
- *((double *)pCtx->aOutputBuf) = DBL_MAX;
+ *((double *)pCtx->pOutput) = DBL_MAX;
break;
default:
qError("illegal data type:%d in min/max query", pCtx->inputType);
@@ -1110,34 +1120,34 @@ static bool max_func_setup(SQLFunctionCtx *pCtx) {
switch (type) {
case TSDB_DATA_TYPE_INT:
- *((int32_t *)pCtx->aOutputBuf) = INT32_MIN;
+ *((int32_t *)pCtx->pOutput) = INT32_MIN;
break;
case TSDB_DATA_TYPE_UINT:
- *((uint32_t *)pCtx->aOutputBuf) = 0;
+ *((uint32_t *)pCtx->pOutput) = 0;
break;
case TSDB_DATA_TYPE_FLOAT:
- *((float *)pCtx->aOutputBuf) = -FLT_MAX;
+ *((float *)pCtx->pOutput) = -FLT_MAX;
break;
case TSDB_DATA_TYPE_DOUBLE:
- *((double *)pCtx->aOutputBuf) = -DBL_MAX;
+ *((double *)pCtx->pOutput) = -DBL_MAX;
break;
case TSDB_DATA_TYPE_BIGINT:
- *((int64_t *)pCtx->aOutputBuf) = INT64_MIN;
+ *((int64_t *)pCtx->pOutput) = INT64_MIN;
break;
case TSDB_DATA_TYPE_UBIGINT:
- *((uint64_t *)pCtx->aOutputBuf) = 0;
+ *((uint64_t *)pCtx->pOutput) = 0;
break;
case TSDB_DATA_TYPE_SMALLINT:
- *((int16_t *)pCtx->aOutputBuf) = INT16_MIN;
+ *((int16_t *)pCtx->pOutput) = INT16_MIN;
break;
case TSDB_DATA_TYPE_USMALLINT:
- *((uint16_t *)pCtx->aOutputBuf) = 0;
+ *((uint16_t *)pCtx->pOutput) = 0;
break;
case TSDB_DATA_TYPE_TINYINT:
- *((int8_t *)pCtx->aOutputBuf) = INT8_MIN;
+ *((int8_t *)pCtx->pOutput) = INT8_MIN;
break;
case TSDB_DATA_TYPE_UTINYINT:
- *((uint8_t *)pCtx->aOutputBuf) = 0;
+ *((uint8_t *)pCtx->pOutput) = 0;
break;
default:
qError("illegal data type:%d in min/max query", pCtx->inputType);
@@ -1151,7 +1161,7 @@ static bool max_func_setup(SQLFunctionCtx *pCtx) {
*/
static void min_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
- minMax_function(pCtx, pCtx->aOutputBuf, 1, ¬NullElems);
+ minMax_function(pCtx, pCtx->pOutput, 1, ¬NullElems);
SET_VAL(pCtx, notNullElems, 1);
@@ -1161,14 +1171,14 @@ static void min_function(SQLFunctionCtx *pCtx) {
// set the flag for super table query
if (pCtx->stableQuery) {
- *(pCtx->aOutputBuf + pCtx->inputBytes) = DATA_SET_FLAG;
+ *(pCtx->pOutput + pCtx->inputBytes) = DATA_SET_FLAG;
}
}
}
static void max_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
- minMax_function(pCtx, pCtx->aOutputBuf, 0, ¬NullElems);
+ minMax_function(pCtx, pCtx->pOutput, 0, ¬NullElems);
SET_VAL(pCtx, notNullElems, 1);
@@ -1178,7 +1188,7 @@ static void max_function(SQLFunctionCtx *pCtx) {
// set the flag for super table query
if (pCtx->stableQuery) {
- *(pCtx->aOutputBuf + pCtx->inputBytes) = DATA_SET_FLAG;
+ *(pCtx->pOutput + pCtx->inputBytes) = DATA_SET_FLAG;
}
}
}
@@ -1244,7 +1254,7 @@ static int32_t minmax_merge_impl(SQLFunctionCtx *pCtx, int32_t bytes, char *outp
}
static void min_func_merge(SQLFunctionCtx *pCtx) {
- int32_t notNullElems = minmax_merge_impl(pCtx, pCtx->outputBytes, pCtx->aOutputBuf, 1);
+ int32_t notNullElems = minmax_merge_impl(pCtx, pCtx->outputBytes, pCtx->pOutput, 1);
SET_VAL(pCtx, notNullElems, 1);
@@ -1255,7 +1265,7 @@ static void min_func_merge(SQLFunctionCtx *pCtx) {
}
static void max_func_merge(SQLFunctionCtx *pCtx) {
- int32_t numOfElem = minmax_merge_impl(pCtx, pCtx->outputBytes, pCtx->aOutputBuf, 0);
+ int32_t numOfElem = minmax_merge_impl(pCtx, pCtx->outputBytes, pCtx->pOutput, 0);
SET_VAL(pCtx, numOfElem, 1);
@@ -1271,32 +1281,32 @@ static void minMax_function_f(SQLFunctionCtx *pCtx, int32_t index, int32_t isMin
int32_t num = 0;
if (pCtx->inputType == TSDB_DATA_TYPE_TINYINT) {
- int8_t *output = (int8_t *)pCtx->aOutputBuf;
+ int8_t *output = (int8_t *)pCtx->pOutput;
int8_t i = GET_INT8_VAL(pData);
UPDATE_DATA(pCtx, *output, i, num, isMin, key);
} else if (pCtx->inputType == TSDB_DATA_TYPE_SMALLINT) {
- int16_t *output = (int16_t*) pCtx->aOutputBuf;
+ int16_t *output = (int16_t*) pCtx->pOutput;
int16_t i = GET_INT16_VAL(pData);
UPDATE_DATA(pCtx, *output, i, num, isMin, key);
} else if (pCtx->inputType == TSDB_DATA_TYPE_INT) {
- int32_t *output = (int32_t*) pCtx->aOutputBuf;
+ int32_t *output = (int32_t*) pCtx->pOutput;
int32_t i = GET_INT32_VAL(pData);
UPDATE_DATA(pCtx, *output, i, num, isMin, key);
} else if (pCtx->inputType == TSDB_DATA_TYPE_BIGINT) {
- int64_t *output = (int64_t*) pCtx->aOutputBuf;
+ int64_t *output = (int64_t*) pCtx->pOutput;
int64_t i = GET_INT64_VAL(pData);
UPDATE_DATA(pCtx, *output, i, num, isMin, key);
} else if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT) {
- float *output = (float*) pCtx->aOutputBuf;
+ float *output = (float*) pCtx->pOutput;
float i = GET_FLOAT_VAL(pData);
UPDATE_DATA(pCtx, *output, i, num, isMin, key);
} else if (pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
- double *output = (double*) pCtx->aOutputBuf;
+ double *output = (double*) pCtx->pOutput;
double i = GET_DOUBLE_VAL(pData);
UPDATE_DATA(pCtx, *output, i, num, isMin, key);
@@ -1316,7 +1326,7 @@ static void max_function_f(SQLFunctionCtx *pCtx, int32_t index) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
- char *flag = pCtx->aOutputBuf + pCtx->inputBytes;
+ char *flag = pCtx->pOutput + pCtx->inputBytes;
*flag = DATA_SET_FLAG;
}
}
@@ -1332,17 +1342,18 @@ static void min_function_f(SQLFunctionCtx *pCtx, int32_t index) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
- char *flag = pCtx->aOutputBuf + pCtx->inputBytes;
+ char *flag = pCtx->pOutput + pCtx->inputBytes;
*flag = DATA_SET_FLAG;
}
}
-#define LOOP_STDDEV_IMPL(type, r, d, ctx, delta, tsdbType) \
- for (int32_t i = 0; i < (ctx)->size; ++i) { \
- if ((ctx)->hasNull && isNull((char *)&((type *)d)[i], tsdbType)) { \
- continue; \
- } \
- (r) += POW2(((type *)d)[i] - (delta)); \
+#define LOOP_STDDEV_IMPL(type, r, d, ctx, delta, _type, num) \
+ for (int32_t i = 0; i < (ctx)->size; ++i) { \
+ if ((ctx)->hasNull && isNull((char *)&((type *)d)[i], (_type))) { \
+ continue; \
+ } \
+ (num) += 1; \
+ (r) += POW2(((type *)d)[i] - (delta)); \
}
static void stddev_function(SQLFunctionCtx *pCtx) {
@@ -1358,35 +1369,53 @@ static void stddev_function(SQLFunctionCtx *pCtx) {
double avg = pStd->avg;
void *pData = GET_INPUT_DATA_LIST(pCtx);
-
+ int32_t num = 0;
+
switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: {
for (int32_t i = 0; i < pCtx->size; ++i) {
if (pCtx->hasNull && isNull((const char*) (&((int32_t *)pData)[i]), pCtx->inputType)) {
continue;
}
+ num += 1;
*retVal += POW2(((int32_t *)pData)[i] - avg);
}
break;
}
case TSDB_DATA_TYPE_FLOAT: {
- LOOP_STDDEV_IMPL(float, *retVal, pData, pCtx, avg, pCtx->inputType);
+ LOOP_STDDEV_IMPL(float, *retVal, pData, pCtx, avg, pCtx->inputType, num);
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
- LOOP_STDDEV_IMPL(double, *retVal, pData, pCtx, avg, pCtx->inputType);
+ LOOP_STDDEV_IMPL(double, *retVal, pData, pCtx, avg, pCtx->inputType, num);
break;
}
case TSDB_DATA_TYPE_BIGINT: {
- LOOP_STDDEV_IMPL(int64_t, *retVal, pData, pCtx, avg, pCtx->inputType);
+ LOOP_STDDEV_IMPL(int64_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
- LOOP_STDDEV_IMPL(int16_t, *retVal, pData, pCtx, avg, pCtx->inputType);
+ LOOP_STDDEV_IMPL(int16_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
break;
}
case TSDB_DATA_TYPE_TINYINT: {
- LOOP_STDDEV_IMPL(int8_t, *retVal, pData, pCtx, avg, pCtx->inputType);
+ LOOP_STDDEV_IMPL(int8_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_UBIGINT: {
+ LOOP_STDDEV_IMPL(uint64_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_USMALLINT: {
+ LOOP_STDDEV_IMPL(uint16_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_UTINYINT: {
+ LOOP_STDDEV_IMPL(uint8_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_UINT: {
+ LOOP_STDDEV_IMPL(uint32_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
break;
}
default:
@@ -1438,6 +1467,22 @@ static void stddev_function_f(SQLFunctionCtx *pCtx, int32_t index) {
pStd->res += POW2(GET_INT8_VAL(pData) - avg);
break;
}
+ case TSDB_DATA_TYPE_UINT: {
+ pStd->res += POW2(GET_UINT32_VAL(pData) - avg);
+ break;
+ }
+ case TSDB_DATA_TYPE_UBIGINT: {
+ pStd->res += POW2(GET_UINT64_VAL(pData) - avg);
+ break;
+ }
+ case TSDB_DATA_TYPE_USMALLINT: {
+ pStd->res += POW2(GET_UINT16_VAL(pData) - avg);
+ break;
+ }
+ case TSDB_DATA_TYPE_UTINYINT: {
+ pStd->res += POW2(GET_UINT8_VAL(pData) - avg);
+ break;
+ }
default:
qError("stddev function not support data type:%d", pCtx->inputType);
}
@@ -1469,7 +1514,7 @@ static void stddev_next_step(SQLFunctionCtx *pCtx) {
// save average value into tmpBuf, for second stage scan
SAvgInfo *pAvg = GET_ROWCELL_INTERBUF(pResInfo);
- pStd->avg = GET_DOUBLE_VAL(pCtx->aOutputBuf);
+ pStd->avg = GET_DOUBLE_VAL(pCtx->pOutput);
assert((isnan(pAvg->sum) && pAvg->num == 0) || (pStd->num == pAvg->num && pStd->avg == pAvg->sum));
} else {
pResInfo->complete = true;
@@ -1480,9 +1525,9 @@ static void stddev_finalizer(SQLFunctionCtx *pCtx) {
SStddevInfo *pStd = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
if (pStd->num <= 0) {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
} else {
- double *retValue = (double *)pCtx->aOutputBuf;
+ double *retValue = (double *)pCtx->pOutput;
*retValue = sqrt(pStd->res / pStd->num);
SET_VAL(pCtx, 1, 1);
}
@@ -1490,6 +1535,137 @@ static void stddev_finalizer(SQLFunctionCtx *pCtx) {
doFinalizer(pCtx);
}
+//////////////////////////////////////////////////////////////////////////////////////
+int32_t tsCompare(const void* p1, const void* p2) {
+ TSKEY k = *(TSKEY*)p1;
+ SResPair* pair = (SResPair*)p2;
+
+ if (k == pair->key) {
+ return 0;
+ } else {
+ return k < pair->key? -1:1;
+ }
+}
+
+static void stddev_dst_function(SQLFunctionCtx *pCtx) {
+ SStddevdstInfo *pStd = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
+
+ // the second stage to calculate standard deviation
+ double *retVal = &pStd->res;
+
+ // all data are null, no need to proceed
+ SArray* resList = (SArray*) pCtx->param[0].pz;
+ if (resList == NULL) {
+ return;
+ }
+
+ // find the correct group average results according to the tag value
+ int32_t len = (int32_t) taosArrayGetSize(resList);
+ assert(len > 0);
+
+ double avg = 0;
+ if (len == 1) {
+ SResPair* p = taosArrayGet(resList, 0);
+ avg = p->avg;
+ } else { // todo opt performance by using iterator since the timestamp lsit is matched with the output result
+ SResPair* p = bsearch(&pCtx->startTs, resList->pData, len, sizeof(SResPair), tsCompare);
+ assert(p != NULL);
+
+ avg = p->avg;
+ }
+
+ void *pData = GET_INPUT_DATA_LIST(pCtx);
+ int32_t num = 0;
+
+ switch (pCtx->inputType) {
+ case TSDB_DATA_TYPE_INT: {
+ for (int32_t i = 0; i < pCtx->size; ++i) {
+ if (pCtx->hasNull && isNull((const char*) (&((int32_t *)pData)[i]), pCtx->inputType)) {
+ continue;
+ }
+ num += 1;
+ *retVal += POW2(((int32_t *)pData)[i] - avg);
+ }
+ break;
+ }
+ case TSDB_DATA_TYPE_FLOAT: {
+ LOOP_STDDEV_IMPL(float, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_DOUBLE: {
+ LOOP_STDDEV_IMPL(double, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_TINYINT: {
+ LOOP_STDDEV_IMPL(int8_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_UTINYINT: {
+ LOOP_STDDEV_IMPL(int8_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_SMALLINT: {
+ LOOP_STDDEV_IMPL(int16_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_USMALLINT: {
+ LOOP_STDDEV_IMPL(uint16_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_UINT: {
+ LOOP_STDDEV_IMPL(uint32_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_BIGINT: {
+ LOOP_STDDEV_IMPL(int64_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ case TSDB_DATA_TYPE_UBIGINT: {
+ LOOP_STDDEV_IMPL(uint64_t, *retVal, pData, pCtx, avg, pCtx->inputType, num);
+ break;
+ }
+ default:
+ qError("stddev function not support data type:%d", pCtx->inputType);
+ }
+
+ pStd->num += num;
+ SET_VAL(pCtx, num, 1);
+
+ // copy to the final output buffer for super table
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)), sizeof(SAvgInfo));
+}
+
+static void stddev_dst_merge(SQLFunctionCtx *pCtx) {
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SStddevdstInfo* pRes = GET_ROWCELL_INTERBUF(pResInfo);
+
+ char *input = GET_INPUT_DATA_LIST(pCtx);
+
+ for (int32_t i = 0; i < pCtx->size; ++i, input += pCtx->inputBytes) {
+ SStddevdstInfo *pInput = (SStddevdstInfo *)input;
+ if (pInput->num == 0) { // current input is null
+ continue;
+ }
+
+ pRes->num += pInput->num;
+ pRes->res += pInput->res;
+ }
+}
+
+static void stddev_dst_finalizer(SQLFunctionCtx *pCtx) {
+ SStddevdstInfo *pStd = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
+
+ if (pStd->num <= 0) {
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
+ } else {
+ double *retValue = (double *)pCtx->pOutput;
+ *retValue = sqrt(pStd->res / pStd->num);
+ SET_VAL(pCtx, 1, 1);
+ }
+
+ doFinalizer(pCtx);
+}
+
//////////////////////////////////////////////////////////////////////////////////////
static bool first_last_function_setup(SQLFunctionCtx *pCtx) {
if (!function_setup(pCtx)) {
@@ -1518,7 +1694,7 @@ static void first_function(SQLFunctionCtx *pCtx) {
continue;
}
- memcpy(pCtx->aOutputBuf, data, pCtx->inputBytes);
+ memcpy(pCtx->pOutput, data, pCtx->inputBytes);
TSKEY k = GET_TS_DATA(pCtx, i);
DO_UPDATE_TAG_COLUMNS(pCtx, k);
@@ -1545,7 +1721,7 @@ static void first_function_f(SQLFunctionCtx *pCtx, int32_t index) {
}
SET_VAL(pCtx, 1, 1);
- memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
+ memcpy(pCtx->pOutput, pData, pCtx->inputBytes);
TSKEY ts = GET_TS_DATA(pCtx, index);
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
@@ -1558,10 +1734,10 @@ static void first_function_f(SQLFunctionCtx *pCtx, int32_t index) {
static void first_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t index) {
int64_t *timestamp = GET_TS_LIST(pCtx);
- SFirstLastInfo *pInfo = (SFirstLastInfo *)(pCtx->aOutputBuf + pCtx->inputBytes);
+ SFirstLastInfo *pInfo = (SFirstLastInfo *)(pCtx->pOutput + pCtx->inputBytes);
if (pInfo->hasResult != DATA_SET_FLAG || timestamp[index] < pInfo->ts) {
- memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
+ memcpy(pCtx->pOutput, pData, pCtx->inputBytes);
pInfo->hasResult = DATA_SET_FLAG;
pInfo->ts = timestamp[index];
@@ -1630,7 +1806,7 @@ static void first_dist_func_merge(SQLFunctionCtx *pCtx) {
// The param[1] is used to keep the initial value of max ts value
if (pCtx->param[1].nType != pCtx->outputType || pCtx->param[1].i64 > pInput->ts) {
- memcpy(pCtx->aOutputBuf, pData, pCtx->outputBytes);
+ memcpy(pCtx->pOutput, pData, pCtx->outputBytes);
pCtx->param[1].i64 = pInput->ts;
pCtx->param[1].nType = pCtx->outputType;
@@ -1663,7 +1839,7 @@ static void last_function(SQLFunctionCtx *pCtx) {
continue;
}
}
- memcpy(pCtx->aOutputBuf, data, pCtx->inputBytes);
+ memcpy(pCtx->pOutput, data, pCtx->inputBytes);
TSKEY ts = GET_TS_DATA(pCtx, i);
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
@@ -1692,7 +1868,7 @@ static void last_function_f(SQLFunctionCtx *pCtx, int32_t index) {
if (pCtx->order == TSDB_ORDER_DESC) {
SET_VAL(pCtx, 1, 1);
- memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
+ memcpy(pCtx->pOutput, pData, pCtx->inputBytes);
TSKEY ts = GET_TS_DATA(pCtx, index);
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
@@ -1707,7 +1883,7 @@ static void last_function_f(SQLFunctionCtx *pCtx, int32_t index) {
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
if (pResInfo->hasResult != DATA_SET_FLAG || (*(TSKEY*)buf) < ts) {
pResInfo->hasResult = DATA_SET_FLAG;
- memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
+ memcpy(pCtx->pOutput, pData, pCtx->inputBytes);
*(TSKEY*)buf = ts;
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
@@ -1718,14 +1894,14 @@ static void last_function_f(SQLFunctionCtx *pCtx, int32_t index) {
static void last_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t index) {
int64_t *timestamp = GET_TS_LIST(pCtx);
- SFirstLastInfo *pInfo = (SFirstLastInfo *)(pCtx->aOutputBuf + pCtx->inputBytes);
+ SFirstLastInfo *pInfo = (SFirstLastInfo *)(pCtx->pOutput + pCtx->inputBytes);
if (pInfo->hasResult != DATA_SET_FLAG || pInfo->ts < timestamp[index]) {
#if defined(_DEBUG_VIEW)
qDebug("assign index:%d, ts:%" PRId64 ", val:%d, ", index, timestamp[index], *(int32_t *)pData);
#endif
- memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
+ memcpy(pCtx->pOutput, pData, pCtx->inputBytes);
pInfo->hasResult = DATA_SET_FLAG;
pInfo->ts = timestamp[index];
@@ -1810,7 +1986,7 @@ static void last_dist_func_merge(SQLFunctionCtx *pCtx) {
* the true last result
*/
if (pCtx->param[1].nType != pCtx->outputType || pCtx->param[1].i64 < pInput->ts) {
- memcpy(pCtx->aOutputBuf, pData, pCtx->outputBytes);
+ memcpy(pCtx->pOutput, pData, pCtx->outputBytes);
pCtx->param[1].i64 = pInput->ts;
pCtx->param[1].nType = pCtx->outputType;
@@ -1830,14 +2006,14 @@ static void last_row_function(SQLFunctionCtx *pCtx) {
char *pData = GET_INPUT_DATA_LIST(pCtx);
// assign the last element in current data block
- assignVal(pCtx->aOutputBuf, pData + (pCtx->size - 1) * pCtx->inputBytes, pCtx->inputBytes, pCtx->inputType);
+ assignVal(pCtx->pOutput, pData + (pCtx->size - 1) * pCtx->inputBytes, pCtx->inputBytes, pCtx->inputType);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
// set the result to final result buffer in case of super table query
if (pCtx->stableQuery) {
- SLastrowInfo *pInfo1 = (SLastrowInfo *)(pCtx->aOutputBuf + pCtx->inputBytes);
+ SLastrowInfo *pInfo1 = (SLastrowInfo *)(pCtx->pOutput + pCtx->inputBytes);
pInfo1->ts = GET_TS_DATA(pCtx, pCtx->size - 1);
pInfo1->hasResult = DATA_SET_FLAG;
@@ -1855,9 +2031,9 @@ static void last_row_finalizer(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult != DATA_SET_FLAG) {
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
- setVardataNull(pCtx->aOutputBuf, pCtx->outputType);
+ setVardataNull(pCtx->pOutput, pCtx->outputType);
} else {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
}
return;
@@ -2055,7 +2231,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
switch (type) {
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_INT: {
- int32_t *output = (int32_t *)pCtx->aOutputBuf;
+ int32_t *output = (int32_t *)pCtx->pOutput;
for (int32_t i = 0; i < len; ++i, output += step) {
*output = (int32_t)tvp[i]->v.i64;
}
@@ -2063,21 +2239,21 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
}
case TSDB_DATA_TYPE_UBIGINT:
case TSDB_DATA_TYPE_BIGINT: {
- int64_t *output = (int64_t *)pCtx->aOutputBuf;
+ int64_t *output = (int64_t *)pCtx->pOutput;
for (int32_t i = 0; i < len; ++i, output += step) {
*output = tvp[i]->v.i64;
}
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
- double *output = (double *)pCtx->aOutputBuf;
+ double *output = (double *)pCtx->pOutput;
for (int32_t i = 0; i < len; ++i, output += step) {
*output = tvp[i]->v.dKey;
}
break;
}
case TSDB_DATA_TYPE_FLOAT: {
- float *output = (float *)pCtx->aOutputBuf;
+ float *output = (float *)pCtx->pOutput;
for (int32_t i = 0; i < len; ++i, output += step) {
*output = (float)tvp[i]->v.dKey;
}
@@ -2085,7 +2261,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
}
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_SMALLINT: {
- int16_t *output = (int16_t *)pCtx->aOutputBuf;
+ int16_t *output = (int16_t *)pCtx->pOutput;
for (int32_t i = 0; i < len; ++i, output += step) {
*output = (int16_t)tvp[i]->v.i64;
}
@@ -2093,7 +2269,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
}
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_TINYINT: {
- int8_t *output = (int8_t *)pCtx->aOutputBuf;
+ int8_t *output = (int8_t *)pCtx->pOutput;
for (int32_t i = 0; i < len; ++i, output += step) {
*output = (int8_t)tvp[i]->v.i64;
}
@@ -2115,7 +2291,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
// todo check malloc failure
char **pData = calloc(pCtx->tagInfo.numOfTagCols, POINTER_BYTES);
for (int32_t i = 0; i < pCtx->tagInfo.numOfTagCols; ++i) {
- pData[i] = pCtx->tagInfo.pTagCtxList[i]->aOutputBuf;
+ pData[i] = pCtx->tagInfo.pTagCtxList[i]->pOutput;
}
for (int32_t i = 0; i < len; ++i, output += step) {
@@ -2143,7 +2319,7 @@ static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) {
// only the first_stage_merge is directly written data into final output buffer
if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) {
- return (STopBotInfo*) pCtx->aOutputBuf;
+ return (STopBotInfo*) pCtx->pOutput;
} else { // during normal table query and super table at the secondary_stage, result is written to intermediate buffer
return GET_ROWCELL_INTERBUF(pResInfo);
}
@@ -2527,9 +2703,9 @@ static void percentile_finalizer(SQLFunctionCtx *pCtx) {
tMemBucket * pMemBucket = ppInfo->pMemBucket;
if (pMemBucket == NULL || pMemBucket->total == 0) { // check for null
assert(ppInfo->numOfElems == 0);
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
} else {
- *(double *)pCtx->aOutputBuf = getPercentile(pMemBucket, v);
+ *(double *)pCtx->pOutput = getPercentile(pMemBucket, v);
}
tMemBucketDestroy(pMemBucket);
@@ -2565,7 +2741,7 @@ static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) {
SAPercentileInfo* pInfo = NULL;
if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) {
- pInfo = (SAPercentileInfo*) pCtx->aOutputBuf;
+ pInfo = (SAPercentileInfo*) pCtx->pOutput;
} else {
pInfo = GET_ROWCELL_INTERBUF(pResInfo);
}
@@ -2679,10 +2855,10 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
double ratio[] = {v};
double *res = tHistogramUniform(pOutput->pHisto, ratio, 1);
- memcpy(pCtx->aOutputBuf, res, sizeof(double));
+ memcpy(pCtx->pOutput, res, sizeof(double));
free(res);
} else {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
return;
}
} else {
@@ -2690,10 +2866,10 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
double ratio[] = {v};
double *res = tHistogramUniform(pOutput->pHisto, ratio, 1);
- memcpy(pCtx->aOutputBuf, res, sizeof(double));
+ memcpy(pCtx->pOutput, res, sizeof(double));
free(res);
} else { // no need to free
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
return;
}
}
@@ -2859,7 +3035,7 @@ static void leastsquares_finalizer(SQLFunctionCtx *pCtx) {
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
if (pInfo->num == 0) {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
return;
}
@@ -2878,16 +3054,16 @@ static void leastsquares_finalizer(SQLFunctionCtx *pCtx) {
param[1][2] /= param[1][1];
int32_t maxOutputSize = TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE - VARSTR_HEADER_SIZE;
- size_t n = snprintf(varDataVal(pCtx->aOutputBuf), maxOutputSize, "{slop:%.6lf, intercept:%.6lf}",
+ size_t n = snprintf(varDataVal(pCtx->pOutput), maxOutputSize, "{slop:%.6lf, intercept:%.6lf}",
param[0][2], param[1][2]);
- varDataSetLen(pCtx->aOutputBuf, n);
+ varDataSetLen(pCtx->pOutput, n);
doFinalizer(pCtx);
}
static void date_col_output_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, pCtx->size, 1);
- *(int64_t *)(pCtx->aOutputBuf) = pCtx->nStartQueryTimestamp;
+ *(int64_t *)(pCtx->pOutput) = pCtx->startTs;
}
static FORCE_INLINE void date_col_output_function_f(SQLFunctionCtx *pCtx, int32_t index) {
@@ -2904,15 +3080,15 @@ static void col_project_function(SQLFunctionCtx *pCtx) {
char *pData = GET_INPUT_DATA_LIST(pCtx);
if (pCtx->order == TSDB_ORDER_ASC) {
- memcpy(pCtx->aOutputBuf, pData, (size_t) pCtx->size * pCtx->inputBytes);
+ memcpy(pCtx->pOutput, pData, (size_t) pCtx->size * pCtx->inputBytes);
} else {
for(int32_t i = 0; i < pCtx->size; ++i) {
- memcpy(pCtx->aOutputBuf + (pCtx->size - 1 - i) * pCtx->inputBytes, pData + i * pCtx->inputBytes,
+ memcpy(pCtx->pOutput + (pCtx->size - 1 - i) * pCtx->inputBytes, pData + i * pCtx->inputBytes,
pCtx->inputBytes);
}
}
- pCtx->aOutputBuf += pCtx->size * pCtx->outputBytes;
+ pCtx->pOutput += pCtx->size * pCtx->outputBytes;
}
static void col_project_function_f(SQLFunctionCtx *pCtx, int32_t index) {
@@ -2928,9 +3104,9 @@ static void col_project_function_f(SQLFunctionCtx *pCtx, int32_t index) {
INC_INIT_VAL(pCtx, 1);
char *pData = GET_INPUT_DATA(pCtx, index);
- memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
+ memcpy(pCtx->pOutput, pData, pCtx->inputBytes);
- pCtx->aOutputBuf += pCtx->inputBytes;
+ pCtx->pOutput += pCtx->inputBytes;
}
/**
@@ -2943,22 +3119,22 @@ static void tag_project_function(SQLFunctionCtx *pCtx) {
assert(pCtx->inputBytes == pCtx->outputBytes);
- tVariantDump(&pCtx->tag, pCtx->aOutputBuf, pCtx->outputType, true);
- char* data = pCtx->aOutputBuf;
- pCtx->aOutputBuf += pCtx->outputBytes;
+ tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->outputType, true);
+ char* data = pCtx->pOutput;
+ pCtx->pOutput += pCtx->outputBytes;
// directly copy from the first one
for (int32_t i = 1; i < pCtx->size; ++i) {
- memmove(pCtx->aOutputBuf, data, pCtx->outputBytes);
- pCtx->aOutputBuf += pCtx->outputBytes;
+ memmove(pCtx->pOutput, data, pCtx->outputBytes);
+ pCtx->pOutput += pCtx->outputBytes;
}
}
static void tag_project_function_f(SQLFunctionCtx *pCtx, int32_t index) {
INC_INIT_VAL(pCtx, 1);
- tVariantDump(&pCtx->tag, pCtx->aOutputBuf, pCtx->tag.nType, true);
- pCtx->aOutputBuf += pCtx->outputBytes;
+ tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->tag.nType, true);
+ pCtx->pOutput += pCtx->outputBytes;
}
/**
@@ -2970,19 +3146,19 @@ static void tag_project_function_f(SQLFunctionCtx *pCtx, int32_t index) {
*/
static void tag_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, 1, 1);
- tVariantDump(&pCtx->tag, pCtx->aOutputBuf, pCtx->outputType, true);
+ tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->outputType, true);
}
static void tag_function_f(SQLFunctionCtx *pCtx, int32_t index) {
SET_VAL(pCtx, 1, 1);
- tVariantDump(&pCtx->tag, pCtx->aOutputBuf, pCtx->outputType, true);
+ tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->outputType, true);
}
static void copy_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, pCtx->size, 1);
char *pData = GET_INPUT_DATA_LIST(pCtx);
- assignVal(pCtx->aOutputBuf, pData, pCtx->inputBytes, pCtx->inputType);
+ assignVal(pCtx->pOutput, pData, pCtx->inputBytes, pCtx->inputType);
}
enum {
@@ -3015,7 +3191,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: {
int32_t *pData = (int32_t *)data;
- int32_t *pOutput = (int32_t *)pCtx->aOutputBuf;
+ int32_t *pOutput = (int32_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
@@ -3047,7 +3223,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
};
case TSDB_DATA_TYPE_BIGINT: {
int64_t *pData = (int64_t *)data;
- int64_t *pOutput = (int64_t *)pCtx->aOutputBuf;
+ int64_t *pOutput = (int64_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
@@ -3079,7 +3255,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
}
case TSDB_DATA_TYPE_DOUBLE: {
double *pData = (double *)data;
- double *pOutput = (double *)pCtx->aOutputBuf;
+ double *pOutput = (double *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
@@ -3109,7 +3285,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
}
case TSDB_DATA_TYPE_FLOAT: {
float *pData = (float *)data;
- float *pOutput = (float *)pCtx->aOutputBuf;
+ float *pOutput = (float *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
@@ -3142,7 +3318,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
}
case TSDB_DATA_TYPE_SMALLINT: {
int16_t *pData = (int16_t *)data;
- int16_t *pOutput = (int16_t *)pCtx->aOutputBuf;
+ int16_t *pOutput = (int16_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
@@ -3173,7 +3349,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
}
case TSDB_DATA_TYPE_TINYINT: {
int8_t *pData = (int8_t *)data;
- int8_t *pOutput = (int8_t *)pCtx->aOutputBuf;
+ int8_t *pOutput = (int8_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) {
@@ -3219,7 +3395,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
GET_RES_INFO(pCtx)->numOfRes += forwardStep;
- pCtx->aOutputBuf += forwardStep * pCtx->outputBytes;
+ pCtx->pOutput += forwardStep * pCtx->outputBytes;
pCtx->ptsOutputBuf = (char*)pCtx->ptsOutputBuf + forwardStep * TSDB_KEYSIZE;
}
}
@@ -3230,7 +3406,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
(ctx)->param[1].nType = (ctx)->inputType; \
*(type *)&(ctx)->param[1].i64 = *(type *)(d); \
} else { \
- *(type *)(ctx)->aOutputBuf = *(type *)(d) - (*(type *)(&(ctx)->param[1].i64)); \
+ *(type *)(ctx)->pOutput = *(type *)(d) - (*(type *)(&(ctx)->param[1].i64)); \
*(type *)(&(ctx)->param[1].i64) = *(type *)(d); \
*(int64_t *)(ctx)->ptsOutputBuf = GET_TS_DATA(ctx, index); \
} \
@@ -3255,7 +3431,7 @@ static void diff_function_f(SQLFunctionCtx *pCtx, int32_t index) {
pCtx->param[1].nType = pCtx->inputType;
pCtx->param[1].i64 = *(int32_t *)pData;
} else {
- *(int32_t *)pCtx->aOutputBuf = *(int32_t *)pData - (int32_t)pCtx->param[1].i64;
+ *(int32_t *)pCtx->pOutput = *(int32_t *)pData - (int32_t)pCtx->param[1].i64;
pCtx->param[1].i64 = *(int32_t *)pData;
*(int64_t *)pCtx->ptsOutputBuf = GET_TS_DATA(pCtx, index);
}
@@ -3286,7 +3462,7 @@ static void diff_function_f(SQLFunctionCtx *pCtx, int32_t index) {
}
if (GET_RES_INFO(pCtx)->numOfRes > 0) {
- pCtx->aOutputBuf += pCtx->outputBytes * step;
+ pCtx->pOutput += pCtx->outputBytes * step;
pCtx->ptsOutputBuf = (char *)pCtx->ptsOutputBuf + TSDB_KEYSIZE * step;
}
}
@@ -3310,9 +3486,9 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) {
GET_RES_INFO(pCtx)->numOfRes += pCtx->size;
SArithmeticSupport *sas = (SArithmeticSupport *)pCtx->param[1].pz;
- arithmeticTreeTraverse(sas->pArithExpr->pExpr, pCtx->size, pCtx->aOutputBuf, sas, pCtx->order, getArithColumnData);
+ arithmeticTreeTraverse(sas->pArithExpr->pExpr, pCtx->size, pCtx->pOutput, sas, pCtx->order, getArithColumnData);
- pCtx->aOutputBuf += pCtx->outputBytes * pCtx->size;
+ pCtx->pOutput += pCtx->outputBytes * pCtx->size;
pCtx->param[1].pz = NULL;
}
@@ -3321,9 +3497,9 @@ static void arithmetic_function_f(SQLFunctionCtx *pCtx, int32_t index) {
SArithmeticSupport *sas = (SArithmeticSupport *)pCtx->param[1].pz;
sas->offset = index;
- arithmeticTreeTraverse(sas->pArithExpr->pExpr, 1, pCtx->aOutputBuf, sas, pCtx->order, getArithColumnData);
+ arithmeticTreeTraverse(sas->pArithExpr->pExpr, 1, pCtx->pOutput, sas, pCtx->order, getArithColumnData);
- pCtx->aOutputBuf += pCtx->outputBytes;
+ pCtx->pOutput += pCtx->outputBytes;
}
#define LIST_MINMAX_N(ctx, minOutput, maxOutput, elemCnt, data, type, tsdbType, numOfNotNullElem) \
@@ -3432,7 +3608,7 @@ static void spread_function(SQLFunctionCtx *pCtx) {
// keep the data into the final output buffer for super table query since this execution may be the last one
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SSpreadInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SSpreadInfo));
}
}
@@ -3475,7 +3651,7 @@ static void spread_function_f(SQLFunctionCtx *pCtx, int32_t index) {
pInfo->hasResult = DATA_SET_FLAG;
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SSpreadInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SSpreadInfo));
}
}
@@ -3511,21 +3687,21 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
if (pResInfo->hasResult != DATA_SET_FLAG) {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
return;
}
- *(double *)pCtx->aOutputBuf = pCtx->param[3].dKey - pCtx->param[0].dKey;
+ *(double *)pCtx->pOutput = pCtx->param[3].dKey - pCtx->param[0].dKey;
} else {
assert(IS_NUMERIC_TYPE(pCtx->inputType) || (pCtx->inputType == TSDB_DATA_TYPE_TIMESTAMP));
SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
if (pInfo->hasResult != DATA_SET_FLAG) {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
return;
}
- *(double *)pCtx->aOutputBuf = pInfo->max - pInfo->min;
+ *(double *)pCtx->pOutput = pInfo->max - pInfo->min;
}
GET_RES_INFO(pCtx)->numOfRes = 1; // todo add test case
@@ -3715,7 +3891,7 @@ static void twa_function(SQLFunctionCtx *pCtx) {
}
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, pInfo, sizeof(STwaInfo));
+ memcpy(pCtx->pOutput, pInfo, sizeof(STwaInfo));
}
}
@@ -3735,7 +3911,7 @@ static void twa_function_f(SQLFunctionCtx *pCtx, int32_t index) {
}
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(STwaInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(STwaInfo));
}
}
@@ -3748,8 +3924,8 @@ void twa_function_copy(SQLFunctionCtx *pCtx) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->aInputElemBuf, (size_t)pCtx->inputBytes);
- pResInfo->hasResult = ((STwaInfo *)pCtx->aInputElemBuf)->hasResult;
+ memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes);
+ pResInfo->hasResult = ((STwaInfo *)pCtx->pInput)->hasResult;
}
void twa_function_finalizer(SQLFunctionCtx *pCtx) {
@@ -3757,15 +3933,15 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
STwaInfo *pInfo = (STwaInfo *)GET_ROWCELL_INTERBUF(pResInfo);
if (pInfo->hasResult != DATA_SET_FLAG) {
- setNull(pCtx->aOutputBuf, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
+ setNull(pCtx->pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
return;
}
assert(pInfo->win.ekey == pInfo->p.key && pInfo->hasResult == pResInfo->hasResult);
if (pInfo->win.ekey == pInfo->win.skey) {
- *(double *)pCtx->aOutputBuf = pInfo->p.val;
+ *(double *)pCtx->pOutput = pInfo->p.val;
} else {
- *(double *)pCtx->aOutputBuf = pInfo->dOutput / (pInfo->win.ekey - pInfo->win.skey);
+ *(double *)pCtx->pOutput = pInfo->dOutput / (pInfo->win.ekey - pInfo->win.skey);
}
GET_RES_INFO(pCtx)->numOfRes = 1;
@@ -3784,7 +3960,7 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
}
if (pCtx->inputType == TSDB_DATA_TYPE_TIMESTAMP) {
- *(TSKEY *) pCtx->aOutputBuf = pCtx->nStartQueryTimestamp;
+ *(TSKEY *) pCtx->pOutput = pCtx->startTs;
} else {
if (pCtx->start.key == INT64_MIN) {
assert(pCtx->end.key == INT64_MIN);
@@ -3792,29 +3968,29 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
}
if (type == TSDB_FILL_NULL) {
- setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
+ setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
} else if (type == TSDB_FILL_SET_VALUE) {
- tVariantDump(&pCtx->param[1], pCtx->aOutputBuf, pCtx->inputType, true);
+ tVariantDump(&pCtx->param[1], pCtx->pOutput, pCtx->inputType, true);
} else if (type == TSDB_FILL_PREV) {
if (IS_NUMERIC_TYPE(pCtx->inputType) || pCtx->inputType == TSDB_DATA_TYPE_BOOL) {
- SET_TYPED_DATA(pCtx->aOutputBuf, pCtx->inputType, pCtx->start.val);
+ SET_TYPED_DATA(pCtx->pOutput, pCtx->inputType, pCtx->start.val);
} else {
- assignVal(pCtx->aOutputBuf, pCtx->start.ptr, pCtx->outputBytes, pCtx->inputType);
+ assignVal(pCtx->pOutput, pCtx->start.ptr, pCtx->outputBytes, pCtx->inputType);
}
} else if (type == TSDB_FILL_LINEAR) {
SPoint point1 = {.key = pCtx->start.key, .val = &pCtx->start.val};
SPoint point2 = {.key = pCtx->end.key, .val = &pCtx->end.val};
- SPoint point = {.key = pCtx->nStartQueryTimestamp, .val = pCtx->aOutputBuf};
+ SPoint point = {.key = pCtx->startTs, .val = pCtx->pOutput};
int32_t srcType = pCtx->inputType;
if (IS_NUMERIC_TYPE(srcType)) { // TODO should find the not null data?
if (isNull((char *)&pCtx->start.val, srcType) || isNull((char *)&pCtx->end.val, srcType)) {
- setNull(pCtx->aOutputBuf, srcType, pCtx->inputBytes);
+ setNull(pCtx->pOutput, srcType, pCtx->inputBytes);
} else {
taosGetLinearInterpolationVal(&point, pCtx->outputType, &point1, &point2, TSDB_DATA_TYPE_DOUBLE);
}
} else {
- setNull(pCtx->aOutputBuf, srcType, pCtx->inputBytes);
+ setNull(pCtx->pOutput, srcType, pCtx->inputBytes);
}
}
}
@@ -3827,9 +4003,9 @@ static void interp_function(SQLFunctionCtx *pCtx) {
if (pCtx->size > 0) {
// impose the timestamp check
TSKEY key = GET_TS_DATA(pCtx, 0);
- if (key == pCtx->nStartQueryTimestamp) {
+ if (key == pCtx->startTs) {
char *pData = GET_INPUT_DATA(pCtx, 0);
- assignVal(pCtx->aOutputBuf, pData, pCtx->inputBytes, pCtx->inputType);
+ assignVal(pCtx->pOutput, pData, pCtx->inputBytes, pCtx->inputType);
SET_VAL(pCtx, 1, 1);
} else {
interp_function_impl(pCtx);
@@ -3897,7 +4073,7 @@ static void ts_comp_finalize(SQLFunctionCtx *pCtx) {
tsBufFlush(pTSbuf);
- *(FILE **)pCtx->aOutputBuf = pTSbuf->f;
+ *(FILE **)pCtx->pOutput = pTSbuf->f;
pTSbuf->remainOpen = true;
tsBufDestroy(pTSbuf);
@@ -3942,7 +4118,7 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx) {
return false;
}
- SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); //->aOutputBuf + pCtx->outputBytes;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); //->pOutput + pCtx->outputBytes;
SRateInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
pInfo->CorrectionValue = 0;
@@ -4011,7 +4187,7 @@ static void rate_function(SQLFunctionCtx *pCtx) {
// keep the data into the final output buffer for super table query since this execution may be the last one
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
@@ -4053,7 +4229,7 @@ static void rate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
// keep the data into the final output buffer for super table query since this execution may be the last one
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
@@ -4061,10 +4237,10 @@ static void rate_func_copy(SQLFunctionCtx *pCtx) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->aInputElemBuf, (size_t)pCtx->inputBytes);
- pResInfo->hasResult = ((SRateInfo*)pCtx->aInputElemBuf)->hasResult;
+ memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes);
+ pResInfo->hasResult = ((SRateInfo*)pCtx->pInput)->hasResult;
- SRateInfo* pRateInfo = (SRateInfo*)pCtx->aInputElemBuf;
+ SRateInfo* pRateInfo = (SRateInfo*)pCtx->pInput;
qDebug("%p rate_func_merge() firstKey:%" PRId64 " lastKey:%" PRId64 " firstValue:%" PRId64 " lastValue:%" PRId64 " CorrectionValue:%" PRId64 " hasResult:%d",
pCtx, pRateInfo->firstKey, pRateInfo->lastKey, pRateInfo->firstValue, pRateInfo->lastValue, pRateInfo->CorrectionValue, pRateInfo->hasResult);
}
@@ -4077,13 +4253,13 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) {
pCtx, pRateInfo->isIRate, pRateInfo->firstKey, pRateInfo->lastKey, pRateInfo->firstValue, pRateInfo->lastValue, pRateInfo->CorrectionValue, pRateInfo->hasResult);
if (pRateInfo->hasResult != DATA_SET_FLAG) {
- setNull(pCtx->aOutputBuf, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
+ setNull(pCtx->pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
return;
}
- *(double*)pCtx->aOutputBuf = do_calc_rate(pRateInfo);
+ *(double*)pCtx->pOutput = do_calc_rate(pRateInfo);
- qDebug("rate_finalizer() output result:%f", *(double *)pCtx->aOutputBuf);
+ qDebug("rate_finalizer() output result:%f", *(double *)pCtx->pOutput);
// cannot set the numOfIteratedElems again since it is set during previous iteration
pResInfo->numOfRes = 1;
@@ -4144,7 +4320,7 @@ static void irate_function(SQLFunctionCtx *pCtx) {
// keep the data into the final output buffer for super table query since this execution may be the last one
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
@@ -4178,7 +4354,7 @@ static void irate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
// keep the data into the final output buffer for super table query since this execution may be the last one
if (pCtx->stableQuery) {
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
@@ -4210,7 +4386,7 @@ static void do_sumrate_merge(SQLFunctionCtx *pCtx) {
if (DATA_SET_FLAG == pRateInfo->hasResult) {
pResInfo->hasResult = DATA_SET_FLAG;
SET_VAL(pCtx, pRateInfo->num, 1);
- memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
+ memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
@@ -4226,17 +4402,17 @@ static void sumrate_finalizer(SQLFunctionCtx *pCtx) {
qDebug("%p sumrate_finalizer() superTableQ:%d num:%" PRId64 " sum:%f hasResult:%d", pCtx, pCtx->stableQuery, pRateInfo->num, pRateInfo->sum, pRateInfo->hasResult);
if (pRateInfo->hasResult != DATA_SET_FLAG) {
- setNull(pCtx->aOutputBuf, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
+ setNull(pCtx->pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
return;
}
if (pRateInfo->num == 0) {
// from meter
- *(double*)pCtx->aOutputBuf = do_calc_rate(pRateInfo);
+ *(double*)pCtx->pOutput = do_calc_rate(pRateInfo);
} else if (pCtx->functionId == TSDB_FUNC_SUM_RATE || pCtx->functionId == TSDB_FUNC_SUM_IRATE) {
- *(double*)pCtx->aOutputBuf = pRateInfo->sum;
+ *(double*)pCtx->pOutput = pRateInfo->sum;
} else {
- *(double*)pCtx->aOutputBuf = pRateInfo->sum / pRateInfo->num;
+ *(double*)pCtx->pOutput = pRateInfo->sum / pRateInfo->num;
}
pResInfo->numOfRes = 1;
@@ -4270,7 +4446,7 @@ int32_t functionCompatList[] = {
1, 1, 1, 1,
};
-SQLAggFuncElem aAggs[] = {{
+SAggFunctionInfo aAggs[] = {{
// 0, count function does not invoke the finalize function
"count",
TSDB_FUNC_COUNT,
@@ -4344,7 +4520,7 @@ SQLAggFuncElem aAggs[] = {{
// 5
"stddev",
TSDB_FUNC_STDDEV,
- TSDB_FUNC_INVALID_ID,
+ TSDB_FUNC_STDDEV_DST,
TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_OF,
function_setup,
stddev_function,
@@ -4654,6 +4830,20 @@ SQLAggFuncElem aAggs[] = {{
},
{
// 27
+ "stddev", // return table id and the corresponding tags for join match and subscribe
+ TSDB_FUNC_STDDEV_DST,
+ TSDB_FUNC_AVG,
+ TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STABLE,
+ function_setup,
+ stddev_dst_function,
+ noop2,
+ no_next_step,
+ stddev_dst_finalizer,
+ stddev_dst_merge,
+ dataBlockRequired,
+ },
+ {
+ // 28
"interp",
TSDB_FUNC_INTERP,
TSDB_FUNC_INTERP,
@@ -4667,7 +4857,7 @@ SQLAggFuncElem aAggs[] = {{
dataBlockRequired,
},
{
- // 28
+ // 29
"rate",
TSDB_FUNC_RATE,
TSDB_FUNC_RATE,
@@ -4681,7 +4871,7 @@ SQLAggFuncElem aAggs[] = {{
dataBlockRequired,
},
{
- // 29
+ // 30
"irate",
TSDB_FUNC_IRATE,
TSDB_FUNC_IRATE,
@@ -4695,7 +4885,7 @@ SQLAggFuncElem aAggs[] = {{
dataBlockRequired,
},
{
- // 30
+ // 31
"sum_rate",
TSDB_FUNC_SUM_RATE,
TSDB_FUNC_SUM_RATE,
@@ -4709,7 +4899,7 @@ SQLAggFuncElem aAggs[] = {{
dataBlockRequired,
},
{
- // 31
+ // 32
"sum_irate",
TSDB_FUNC_SUM_IRATE,
TSDB_FUNC_SUM_IRATE,
@@ -4723,7 +4913,7 @@ SQLAggFuncElem aAggs[] = {{
dataBlockRequired,
},
{
- // 32
+ // 33
"avg_rate",
TSDB_FUNC_AVG_RATE,
TSDB_FUNC_AVG_RATE,
@@ -4737,7 +4927,7 @@ SQLAggFuncElem aAggs[] = {{
dataBlockRequired,
},
{
- // 33
+ // 34
"avg_irate",
TSDB_FUNC_AVG_IRATE,
TSDB_FUNC_AVG_IRATE,
@@ -4751,7 +4941,7 @@ SQLAggFuncElem aAggs[] = {{
dataBlockRequired,
},
{
- // 34
+ // 35
"tid_tag", // return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_TID_TAG,
TSDB_FUNC_TID_TAG,
@@ -4763,4 +4953,4 @@ SQLAggFuncElem aAggs[] = {{
noop1,
noop1,
dataBlockRequired,
- }};
+ } };
diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c
index 5bb9531d31..0e78289111 100644
--- a/src/query/src/qExecutor.c
+++ b/src/query/src/qExecutor.c
@@ -200,7 +200,7 @@ static void resetDefaultResInfoOutputBuf(SQueryRuntimeEnv *pRuntimeEnv);
static bool hasMainOutput(SQuery *pQuery);
static void buildTagQueryResult(SQInfo *pQInfo);
-static int32_t setAdditionalInfo(SQInfo *pQInfo, void *pTable, STableQueryInfo *pTableQueryInfo);
+static int32_t setTimestampListJoinInfo(SQInfo *pQInfo, STableQueryInfo *pTableQueryInfo);
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);
@@ -301,7 +301,7 @@ static UNUSED_FUNC int32_t getMergeResultGroupId(int32_t groupIndex) {
return base + (groupIndex * 10000);
}
-bool isGroupbyNormalCol(SSqlGroupbyExpr *pGroupbyExpr) {
+bool isGroupbyColumn(SSqlGroupbyExpr *pGroupbyExpr) {
if (pGroupbyExpr == NULL || pGroupbyExpr->numOfGroupCols == 0) {
return false;
}
@@ -356,7 +356,7 @@ bool isSelectivityWithTagsQuery(SQuery *pQuery) {
continue;
}
- if ((aAggs[functId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
+ if ((aAggs[functId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
numOfSelectivity++;
}
}
@@ -379,9 +379,9 @@ bool isProjQuery(SQuery *pQuery) {
return true;
}
-bool isTSCompQuery(SQuery *pQuery) { return pQuery->pExpr1[0].base.functionId == TSDB_FUNC_TS_COMP; }
+bool isTsCompQuery(SQuery *pQuery) { return pQuery->pExpr1[0].base.functionId == TSDB_FUNC_TS_COMP; }
-static bool limitResults(SQueryRuntimeEnv* pRuntimeEnv) {
+static bool limitOperator(SQueryRuntimeEnv* pRuntimeEnv) {
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
SQuery* pQuery = pRuntimeEnv->pQuery;
@@ -835,7 +835,7 @@ static void doBlockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow
for (int32_t k = 0; k < pQuery->numOfOutput; ++k) {
pCtx[k].size = forwardStep;
- pCtx[k].nStartQueryTimestamp = pWin->skey;
+ pCtx[k].startTs = pWin->skey;
pCtx[k].startOffset = (QUERY_IS_ASC_QUERY(pQuery)) ? offset : offset - (forwardStep - 1);
int32_t functionId = pQuery->pExpr1[k].base.functionId;
@@ -860,7 +860,7 @@ static void doRowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow *
SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx;
for (int32_t k = 0; k < pQuery->numOfOutput; ++k) {
- pCtx[k].nStartQueryTimestamp = pWin->skey;
+ pCtx[k].startTs = pWin->skey;
int32_t functionId = pQuery->pExpr1[k].base.functionId;
if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) {
@@ -1277,7 +1277,7 @@ 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 = pQuery->window.skey;
+ pCtx[k].startTs = pQuery->window.skey;
aAggs[functionId].xFunction(&pCtx[k]);
}
}
@@ -1386,7 +1386,7 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, int32_t offset) {
return TS_JOIN_TAG_NOT_EQUALS;
}
- TSKEY key = *(TSKEY *)((char*)pCtx[0].aInputElemBuf + TSDB_KEYSIZE * offset);
+ TSKEY key = *(TSKEY *)((char*)pCtx[0].pInput + TSDB_KEYSIZE * offset);
#if defined(_DEBUG_VIEW)
printf("elem in comp ts file:%" PRId64 ", key:%" PRId64 ", tag:%"PRIu64", query order:%d, ts order:%d, traverse:%d, index:%d\n",
@@ -1774,7 +1774,7 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
SDataStatis *tpField = NULL;
pCtx->hasNull = hasNullValue(&pQuery->pExpr1[colIndex].base.colInfo, pStatis, &tpField);
- pCtx->aInputElemBuf = inputData;
+ pCtx->pInput = inputData;
if (tpField != NULL) {
pCtx->preAggVals.isSet = true;
@@ -1793,7 +1793,7 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
pCtx->startOffset = QUERY_IS_ASC_QUERY(pQuery) ? pQuery->pos: (pQuery->pos - pCtx->size + 1);
assert(pCtx->startOffset >= 0);
- uint32_t status = aAggs[functionId].nStatus;
+ uint32_t status = aAggs[functionId].status;
if (((status & (TSDB_FUNCSTATE_SELECTIVITY | TSDB_FUNCSTATE_NEED_TS)) != 0) && (tsCol != NULL)) {
pCtx->ptsList = tsCol;
}
@@ -1878,7 +1878,7 @@ static int32_t setCtxTagColumnInfo(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
if (pSqlFuncMsg->functionId == TSDB_FUNC_TAG_DUMMY || pSqlFuncMsg->functionId == TSDB_FUNC_TS_DUMMY) {
tagLen += pCtx[i].outputBytes;
pTagCtx[num++] = &pCtx[i];
- } else if ((aAggs[pSqlFuncMsg->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
+ } else if ((aAggs[pSqlFuncMsg->functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
p = &pCtx[i];
} else if (pSqlFuncMsg->functionId == TSDB_FUNC_TS || pSqlFuncMsg->functionId == TSDB_FUNC_TAG) {
// tag function may be the group by tag column
@@ -1900,16 +1900,32 @@ static int32_t setCtxTagColumnInfo(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
return TSDB_CODE_SUCCESS;
}
-// todo refactor
-static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order) {
+static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfTables, int16_t order) {
qDebug("QInfo:%p setup runtime env", GET_QINFO_ADDR(pRuntimeEnv));
SQuery *pQuery = pRuntimeEnv->pQuery;
+ pRuntimeEnv->interBufSize = getOutputInterResultBufSize(pQuery);
+ pRuntimeEnv->summary.tableInfoSize += (numOfTables * sizeof(STableQueryInfo));
+
+ pRuntimeEnv->pResultRowHashTable = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
+ pRuntimeEnv->keyBuf = malloc(pQuery->maxSrcColumnSize + sizeof(int64_t));
+ pRuntimeEnv->pool = initResultRowPool(getResultRowSize(pRuntimeEnv));
+ pRuntimeEnv->prevRow = malloc(POINTER_BYTES * pQuery->numOfCols + pQuery->srcRowSize);
+ pRuntimeEnv->tagVal = malloc(pQuery->tagLen);
+
+ char* start = POINTER_BYTES * pQuery->numOfCols + (char*) pRuntimeEnv->prevRow;
+ pRuntimeEnv->prevRow[0] = start;
+
+ for(int32_t i = 1; i < pQuery->numOfCols; ++i) {
+ pRuntimeEnv->prevRow[i] = pRuntimeEnv->prevRow[i - 1] + pQuery->colList[i-1].bytes;
+ }
+
pRuntimeEnv->pCtx = (SQLFunctionCtx *)calloc(pQuery->numOfOutput, sizeof(SQLFunctionCtx));
pRuntimeEnv->offset = calloc(pQuery->numOfOutput, sizeof(int16_t));
pRuntimeEnv->rowCellInfoOffset = calloc(pQuery->numOfOutput, sizeof(int32_t));
pRuntimeEnv->sasArray = calloc(pQuery->numOfOutput, sizeof(SArithmeticSupport));
+ // TODO check malloc failure
if (pRuntimeEnv->offset == NULL || pRuntimeEnv->pCtx == NULL || pRuntimeEnv->rowCellInfoOffset == NULL || pRuntimeEnv->sasArray == NULL) {
goto _clean;
}
@@ -1931,10 +1947,10 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
int32_t index = pSqlFuncMsg->colInfo.colIndex;
if (TSDB_COL_IS_TAG(pIndex->flag)) {
if (pIndex->colId == TSDB_TBNAME_COLUMN_INDEX) { // todo refactor
- SSchema s = tGetTableNameColumnSchema();
+ SSchema* s = tGetTbnameColumnSchema();
- pCtx->inputBytes = s.bytes;
- pCtx->inputType = s.type;
+ pCtx->inputBytes = s->bytes;
+ pCtx->inputType = s->type;
} else if (pIndex->colId == TSDB_BLOCK_DIST_COLUMN_INDEX) {
SSchema s = tGetBlockDistColumnSchema();
pCtx->inputBytes = s.bytes;
@@ -1968,6 +1984,10 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
for (int32_t j = 0; j < pCtx->numOfParams; ++j) {
int16_t type = pSqlFuncMsg->arg[j].argType;
int16_t bytes = pSqlFuncMsg->arg[j].argBytes;
+ if (pSqlFuncMsg->functionId == TSDB_FUNC_STDDEV_DST) {
+ continue;
+ }
+
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
tVariantCreateFromBinary(&pCtx->param[j], pSqlFuncMsg->arg[j].argValue.pz, bytes, type);
} else {
@@ -2052,7 +2072,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
qDebug("QInfo:%p teardown runtime env", pQInfo);
cleanupResultRowInfo(&pRuntimeEnv->windowResInfo);
- if (isTSCompQuery(pQuery)) {
+ if (isTsCompQuery(pQuery)) {
FILE *f = *(FILE **)pQuery->sdata[0]->data;
if (f) {
@@ -2096,11 +2116,15 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
tfree(pRuntimeEnv->keyBuf);
tfree(pRuntimeEnv->rowCellInfoOffset);
tfree(pRuntimeEnv->prevRow);
+ tfree(pRuntimeEnv->tagVal);
+
taosHashCleanup(pRuntimeEnv->pResultRowHashTable);
pRuntimeEnv->pResultRowHashTable = NULL;
pRuntimeEnv->pool = destroyResultRowPool(pRuntimeEnv->pool);
+ taosArrayDestroyEx(pRuntimeEnv->prevResult, freeInterResult);
+ pRuntimeEnv->prevResult = NULL;
}
static bool needBuildResAfterQueryComplete(SQInfo* pQInfo) {
@@ -2154,7 +2178,7 @@ static bool isFixedOutputQuery(SQueryRuntimeEnv* pRuntimeEnv) {
continue;
}
- if (!IS_MULTIOUTPUT(aAggs[pExprMsg->functionId].nStatus)) {
+ if (!IS_MULTIOUTPUT(aAggs[pExprMsg->functionId].status)) {
return true;
}
}
@@ -2269,7 +2293,7 @@ void getAlignQueryTimeWindow(SQuery *pQuery, int64_t key, int64_t keyFirst, int6
static void setScanLimitationByResultBuffer(SQuery *pQuery) {
if (isTopBottomQuery(pQuery)) {
pQuery->checkResultBuf = 0;
- } else if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) {
+ } else if (isGroupbyColumn(pQuery->pGroupbyExpr)) {
pQuery->checkResultBuf = 0;
} else {
bool hasMultioutput = false;
@@ -2279,7 +2303,7 @@ static void setScanLimitationByResultBuffer(SQuery *pQuery) {
continue;
}
- hasMultioutput = IS_MULTIOUTPUT(aAggs[pExprMsg->functionId].nStatus);
+ hasMultioutput = IS_MULTIOUTPUT(aAggs[pExprMsg->functionId].status);
if (!hasMultioutput) {
break;
}
@@ -2365,7 +2389,7 @@ static void changeExecuteScanOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bo
return;
}
- if (isGroupbyNormalCol(pQuery->pGroupbyExpr) && pQuery->order.order == TSDB_ORDER_DESC) {
+ if (isGroupbyColumn(pQuery->pGroupbyExpr) && pQuery->order.order == TSDB_ORDER_DESC) {
pQuery->order.order = TSDB_ORDER_ASC;
if (pQuery->window.skey > pQuery->window.ekey) {
SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY);
@@ -2442,7 +2466,7 @@ static int32_t getInitialPageNum(SQInfo *pQInfo) {
int32_t num = 0;
- if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) {
+ if (isGroupbyColumn(pQuery->pGroupbyExpr)) {
num = 128;
} else if (QUERY_IS_INTERVAL_QUERY(pQuery)) { // time window query, allocate one page for each table
size_t s = pQInfo->tableqinfoGroupInfo.numOfTables;
@@ -2459,7 +2483,7 @@ static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, i
SQuery* pQuery = pRuntimeEnv->pQuery;
int32_t MIN_ROWS_PER_PAGE = 4;
- *rowsize = (int32_t)(pQuery->rowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pRuntimeEnv->topBotQuery, pRuntimeEnv->stableQuery));
+ *rowsize = (int32_t)(pQuery->resultRowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pRuntimeEnv->topBotQuery, pRuntimeEnv->stableQuery));
int32_t overhead = sizeof(tFilePage);
// one page contains at least two rows
@@ -2764,7 +2788,7 @@ static void ensureOutputBufferSimple(SQueryRuntimeEnv* pRuntimeEnv, int32_t capa
}
// set the pCtx output buffer position
- pRuntimeEnv->pCtx[i].aOutputBuf = pQuery->sdata[i]->data;
+ pRuntimeEnv->pCtx[i].pOutput = pQuery->sdata[i]->data;
}
qDebug("QInfo:%p realloc output buffer to inc output buffer from: %" PRId64 " rows to:%d rows", GET_QINFO_ADDR(pRuntimeEnv),
@@ -2777,7 +2801,7 @@ static void ensureOutputBufferSimple(SQueryRuntimeEnv* pRuntimeEnv, int32_t capa
static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pBlockInfo) {
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
SQuery* pQuery = pRuntimeEnv->pQuery;
- if (!QUERY_IS_INTERVAL_QUERY(pQuery) && !pRuntimeEnv->groupbyColumn && !isFixedOutputQuery(pRuntimeEnv) && !isTSCompQuery(pQuery)) {
+ if (!QUERY_IS_INTERVAL_QUERY(pQuery) && !pRuntimeEnv->groupbyColumn && !isFixedOutputQuery(pRuntimeEnv) && !isTsCompQuery(pQuery)) {
SResultRec *pRec = &pQuery->rec;
if (pQuery->rec.capacity - pQuery->rec.rows < pBlockInfo->rows) {
@@ -2797,11 +2821,11 @@ static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pB
}
// set the pCtx output buffer position
- pRuntimeEnv->pCtx[i].aOutputBuf = pQuery->sdata[i]->data + pRec->rows * bytes;
+ pRuntimeEnv->pCtx[i].pOutput = pQuery->sdata[i]->data + pRec->rows * bytes;
int32_t functionId = pQuery->pExpr1[i].base.functionId;
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
- pRuntimeEnv->pCtx[i].ptsOutputBuf = pRuntimeEnv->pCtx[0].aOutputBuf;
+ pRuntimeEnv->pCtx[i].ptsOutputBuf = pRuntimeEnv->pCtx[0].pOutput;
}
}
@@ -2910,7 +2934,7 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
* set tag value in SQLFunctionCtx
* e.g.,tag information into input buffer
*/
-static void doSetTagValueInParam(void *tsdb, void* pTable, int32_t tagColId, tVariant *tag, int16_t type, int16_t bytes) {
+static void doSetTagValueInParam(void* pTable, int32_t tagColId, tVariant *tag, int16_t type, int16_t bytes) {
tVariantDestroy(tag);
if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
@@ -2955,7 +2979,7 @@ static SColumnInfo* doGetTagColumnInfoById(SColumnInfo* pTagColList, int32_t num
return NULL;
}
-void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
+void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable) {
SQuery *pQuery = pRuntimeEnv->pQuery;
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
@@ -2966,9 +2990,11 @@ void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
int16_t tagColId = (int16_t)pExprInfo->base.arg->argValue.i64;
SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagColId);
- doSetTagValueInParam(tsdb, pTable, tagColId, &pRuntimeEnv->pCtx[0].tag, pColInfo->type, pColInfo->bytes);
+ doSetTagValueInParam(pTable, tagColId, &pRuntimeEnv->pCtx[0].tag, pColInfo->type, pColInfo->bytes);
} else {
// set tag value, by which the results are aggregated.
+ int32_t offset = 0;
+ memset(pRuntimeEnv->tagVal, 0, pQuery->tagLen);
for (int32_t idx = 0; idx < pQuery->numOfOutput; ++idx) {
SExprInfo* pLocalExprInfo = &pQuery->pExpr1[idx];
@@ -2978,8 +3004,16 @@ void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
}
// todo use tag column index to optimize performance
- doSetTagValueInParam(tsdb, pTable, pLocalExprInfo->base.colInfo.colId, &pRuntimeEnv->pCtx[idx].tag,
+ doSetTagValueInParam(pTable, pLocalExprInfo->base.colInfo.colId, &pRuntimeEnv->pCtx[idx].tag,
pLocalExprInfo->type, pLocalExprInfo->bytes);
+
+ if (IS_NUMERIC_TYPE(pLocalExprInfo->type) || pLocalExprInfo->type == TSDB_DATA_TYPE_BOOL) {
+ memcpy(pRuntimeEnv->tagVal + offset, &pRuntimeEnv->pCtx[idx].tag.i64, pLocalExprInfo->bytes);
+ } else {
+ memcpy(pRuntimeEnv->tagVal + offset, pRuntimeEnv->pCtx[idx].tag.pz, pRuntimeEnv->pCtx[idx].tag.nLen);
+ }
+
+ offset += pLocalExprInfo->bytes;
}
// set the join tag for first column
@@ -2991,7 +3025,7 @@ void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
int16_t tagColId = (int16_t)pExprInfo->base.arg->argValue.i64;
SColumnInfo *pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagColId);
- doSetTagValueInParam(tsdb, pTable, tagColId, &pRuntimeEnv->pCtx[0].tag, pColInfo->type, pColInfo->bytes);
+ doSetTagValueInParam(pTable, tagColId, &pRuntimeEnv->pCtx[0].tag, pColInfo->type, pColInfo->bytes);
int16_t tagType = pRuntimeEnv->pCtx[0].tag.nType;
if (tagType == TSDB_DATA_TYPE_BINARY || tagType == TSDB_DATA_TYPE_NCHAR) {
@@ -3218,7 +3252,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
}
int32_t size = (int32_t) taosArrayGetSize(pGroupResInfo->pRows);
- pQuery->rec.rows = doCopyToSData(pQInfo, pGroupResInfo->pRows->pData, (int32_t) size, &pGroupResInfo->index, TSDB_ORDER_ASC);
+ pQuery->rec.rows = doCopyToSData(pQInfo, pGroupResInfo->pRows->pData, size, &pGroupResInfo->index, TSDB_ORDER_ASC);
}
int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow *pResultRow) {
@@ -3472,7 +3506,7 @@ void resetDefaultResInfoOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
- pCtx->aOutputBuf = pQuery->sdata[i]->data;
+ pCtx->pOutput = pQuery->sdata[i]->data;
/*
* set the output buffer information and intermediate buffer
@@ -3485,7 +3519,7 @@ void resetDefaultResInfoOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
// set the timestamp output buffer for top/bottom/diff query
int32_t functionId = pQuery->pExpr1[i].base.functionId;
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
- pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].aOutputBuf;
+ pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].pOutput;
}
memset(pQuery->sdata[i]->data, 0, (size_t)(pQuery->pExpr1[i].bytes * pQuery->rec.capacity));
@@ -3503,8 +3537,8 @@ void forwardCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, int64_t output) {
assert(functionId != TSDB_FUNC_DIFF);
// set next output position
- if (IS_OUTER_FORWARD(aAggs[functionId].nStatus)) {
- pRuntimeEnv->pCtx[j].aOutputBuf += pRuntimeEnv->pCtx[j].outputBytes * output;
+ if (IS_OUTER_FORWARD(aAggs[functionId].status)) {
+ pRuntimeEnv->pCtx[j].pOutput += pRuntimeEnv->pCtx[j].outputBytes * output;
}
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) {
@@ -3568,10 +3602,10 @@ void skipResults(SQueryRuntimeEnv *pRuntimeEnv) {
int32_t bytes = pRuntimeEnv->pCtx[i].outputBytes;
memmove(pQuery->sdata[i]->data, (char*)pQuery->sdata[i]->data + bytes * numOfSkip, (size_t)(pQuery->rec.rows * bytes));
- pRuntimeEnv->pCtx[i].aOutputBuf = ((char*) pQuery->sdata[i]->data) + pQuery->rec.rows * bytes;
+ pRuntimeEnv->pCtx[i].pOutput = ((char*) pQuery->sdata[i]->data) + pQuery->rec.rows * bytes;
if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) {
- pRuntimeEnv->pCtx[i].ptsOutputBuf = pRuntimeEnv->pCtx[0].aOutputBuf;
+ pRuntimeEnv->pCtx[i].ptsOutputBuf = pRuntimeEnv->pCtx[0].pOutput;
}
}
@@ -3762,7 +3796,7 @@ static void handleInterpolationQuery(SQInfo* pQInfo) {
}
pCtx->param[2].i64 = (int8_t)pQuery->fillType;
- pCtx->nStartQueryTimestamp = pQuery->window.skey;
+ pCtx->startTs = pQuery->window.skey;
if (pQuery->fillVal != NULL) {
if (isNull((const char *)&pQuery->fillVal[i], pCtx->inputType)) {
pCtx->param[1].nType = TSDB_DATA_TYPE_NULL;
@@ -3789,7 +3823,7 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
SET_MASTER_SCAN_FLAG(pRuntimeEnv);
if (!pRuntimeEnv->groupbyColumn && pRuntimeEnv->hasTagResults) {
- setTagVal(pRuntimeEnv, pTableQueryInfo->pTable, pQInfo->tsdb);
+ setTagVal(pRuntimeEnv, pTableQueryInfo->pTable);
}
while (1) {
@@ -3898,9 +3932,7 @@ static bool hasMainOutput(SQuery *pQuery) {
return false;
}
-static STableQueryInfo *createTableQueryInfo(SQueryRuntimeEnv *pRuntimeEnv, void* pTable, STimeWindow win, void* buf) {
- SQuery *pQuery = pRuntimeEnv->pQuery;
-
+static STableQueryInfo *createTableQueryInfo(SQuery* pQuery, void* pTable, bool groupbyColumn, STimeWindow win, void* buf) {
STableQueryInfo *pTableQueryInfo = buf;
pTableQueryInfo->win = win;
@@ -3910,7 +3942,7 @@ static STableQueryInfo *createTableQueryInfo(SQueryRuntimeEnv *pRuntimeEnv, void
pTableQueryInfo->cur.vgroupIndex = -1;
// set more initial size of interval/groupby query
- if (QUERY_IS_INTERVAL_QUERY(pQuery) || pRuntimeEnv->groupbyColumn) {
+ if (QUERY_IS_INTERVAL_QUERY(pQuery) || groupbyColumn) {
int32_t initialSize = 128;
int32_t code = initResultRowInfo(&pTableQueryInfo->windowResInfo, initialSize, TSDB_DATA_TYPE_INT);
if (code != TSDB_CODE_SUCCESS) {
@@ -3977,11 +4009,11 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult) {
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
- pCtx->aOutputBuf = getPosInResultPage(pRuntimeEnv, i, pResult, page);
+ pCtx->pOutput = getPosInResultPage(pRuntimeEnv, i, pResult, page);
int32_t functionId = pQuery->pExpr1[i].base.functionId;
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
- pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].aOutputBuf;
+ pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].pOutput;
}
/*
@@ -4006,12 +4038,12 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe
continue;
}
- pCtx->aOutputBuf = getPosInResultPage(pRuntimeEnv, i, pResult, bufPage);
+ pCtx->pOutput = getPosInResultPage(pRuntimeEnv, i, pResult, bufPage);
pCtx->currentStage = 0;
int32_t functionId = pCtx->functionId;
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
- pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].aOutputBuf;
+ pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].pOutput;
}
if (!pCtx->resultInfo->initialized) {
@@ -4020,46 +4052,82 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe
}
}
-int32_t setAdditionalInfo(SQInfo *pQInfo, void* pTable, STableQueryInfo *pTableQueryInfo) {
+int32_t setTimestampListJoinInfo(SQInfo *pQInfo, STableQueryInfo *pTableQueryInfo) {
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
-
- setTagVal(pRuntimeEnv, pTable, pQInfo->tsdb);
+ assert(pRuntimeEnv->pTsBuf != NULL);
// both the master and supplement scan needs to set the correct ts comp start position
- if (pRuntimeEnv->pTsBuf != NULL) {
- tVariant* pTag = &pRuntimeEnv->pCtx[0].tag;
+ tVariant* pTag = &pRuntimeEnv->pCtx[0].tag;
- if (pTableQueryInfo->cur.vgroupIndex == -1) {
- tVariantAssign(&pTableQueryInfo->tag, pTag);
+ if (pTableQueryInfo->cur.vgroupIndex == -1) {
+ tVariantAssign(&pTableQueryInfo->tag, pTag);
- STSElem elem = tsBufGetElemStartPos(pRuntimeEnv->pTsBuf, pQInfo->vgId, &pTableQueryInfo->tag);
+ STSElem elem = tsBufGetElemStartPos(pRuntimeEnv->pTsBuf, pQInfo->vgId, &pTableQueryInfo->tag);
- // failed to find data with the specified tag value and vnodeId
- if (!tsBufIsValidElem(&elem)) {
- if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) {
- qError("QInfo:%p failed to find tag:%s in ts_comp", pQInfo, pTag->pz);
- } else {
- qError("QInfo:%p failed to find tag:%" PRId64 " in ts_comp", pQInfo, pTag->i64);
- }
-
- return false;
- }
-
- // keep the cursor info of current meter
- pTableQueryInfo->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf);
+ // failed to find data with the specified tag value and vnodeId
+ if (!tsBufIsValidElem(&elem)) {
if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) {
- qDebug("QInfo:%p find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", pQInfo, pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
+ qError("QInfo:%p failed to find tag:%s in ts_comp", pQInfo, pTag->pz);
} else {
- qDebug("QInfo:%p find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", pQInfo, pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
+ qError("QInfo:%p failed to find tag:%" PRId64 " in ts_comp", pQInfo, pTag->i64);
}
+ return false;
+ }
+
+ // keep the cursor info of current meter
+ pTableQueryInfo->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf);
+ if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) {
+ qDebug("QInfo:%p find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", pQInfo, pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
} else {
- tsBufSetCursor(pRuntimeEnv->pTsBuf, &pTableQueryInfo->cur);
+ qDebug("QInfo:%p find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", pQInfo, pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
+ }
- if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) {
- qDebug("QInfo:%p find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", pQInfo, pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
- } else {
- qDebug("QInfo:%p find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", pQInfo, pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
+ } else {
+ tsBufSetCursor(pRuntimeEnv->pTsBuf, &pTableQueryInfo->cur);
+
+ if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) {
+ qDebug("QInfo:%p find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", pQInfo, pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
+ } else {
+ qDebug("QInfo:%p find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", pQInfo, pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
+ }
+ }
+
+ return 0;
+}
+
+int32_t setParamValue(SQueryRuntimeEnv* pRuntimeEnv) {
+ SQuery* pQuery = pRuntimeEnv->pQuery;
+
+ if (pRuntimeEnv->prevResult == NULL) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ int32_t numOfExprs = pQuery->numOfOutput;
+ for(int32_t i = 0; i < numOfExprs; ++i) {
+ SExprInfo* pExprInfo = &(pQuery->pExpr1[i]);
+ if(pExprInfo->base.functionId != TSDB_FUNC_STDDEV_DST) {
+ continue;
+ }
+
+ SSqlFuncMsg* pFuncMsg = &pExprInfo->base;
+
+ pRuntimeEnv->pCtx[i].param[0].arr = NULL;
+ pRuntimeEnv->pCtx[i].param[0].nType = TSDB_DATA_TYPE_INT; // avoid freeing the memory by setting the type to be int
+
+ int32_t numOfGroup = (int32_t) taosArrayGetSize(pRuntimeEnv->prevResult);
+ for(int32_t j = 0; j < numOfGroup; ++j) {
+ SInterResult *p = taosArrayGet(pRuntimeEnv->prevResult, j);
+ if (pQuery->tagLen == 0 || memcmp(p->tags, pRuntimeEnv->tagVal, pQuery->tagLen) == 0) {
+
+ int32_t numOfCols = (int32_t) taosArrayGetSize(p->pResult);
+ for(int32_t k = 0; k < numOfCols; ++k) {
+ SStddevInterResult* pres = taosArrayGet(p->pResult, k);
+ if (pres->colId == pFuncMsg->colInfo.colId) {
+ pRuntimeEnv->pCtx[i].param[0].arr = pres->pResult;
+ break;
+ }
+ }
}
}
}
@@ -4122,7 +4190,7 @@ void setIntervalQueryRange(SQInfo *pQInfo, TSKEY key) {
bool requireTimestamp(SQuery *pQuery) {
for (int32_t i = 0; i < pQuery->numOfOutput; i++) {
int32_t functionId = pQuery->pExpr1[i].base.functionId;
- if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_NEED_TS) != 0) {
+ if ((aAggs[functionId].status & TSDB_FUNCSTATE_NEED_TS) != 0) {
return true;
}
}
@@ -4423,8 +4491,13 @@ static void queryCostStatis(SQInfo *pQInfo) {
pSummary->elapsedTime += pSummary->firstStageMergeTime;
SResultRowPool* p = pQInfo->runtimeEnv.pool;
- pSummary->winInfoSize = getResultRowPoolMemSize(p);
- pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
+ if (p != NULL) {
+ pSummary->winInfoSize = getResultRowPoolMemSize(p);
+ pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
+ } else {
+ pSummary->winInfoSize = 0;
+ pSummary->numOfTimeWindows = 0;
+ }
qDebug("QInfo:%p :cost summary: elapsed time:%"PRId64" us, first merge:%"PRId64" us, total blocks:%d, "
"load block statis:%d, load data block:%d, total rows:%"PRId64 ", check rows:%"PRId64,
@@ -4743,7 +4816,7 @@ static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery)
&& (pQInfo->tableqinfoGroupInfo.numOfTables == 1)
&& (cond.order == TSDB_ORDER_ASC)
&& (!QUERY_IS_INTERVAL_QUERY(pQuery))
- && (!isGroupbyNormalCol(pQuery->pGroupbyExpr))
+ && (!isGroupbyColumn(pQuery->pGroupbyExpr))
&& (!isFixedOutputQuery(pRuntimeEnv))
) {
SArray* pa = GET_TABLEGROUP(pQInfo, 0);
@@ -4809,7 +4882,7 @@ static SFillColInfo* createFillColInfo(SQuery* pQuery) {
return pFillCol;
}
-int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bool isSTableQuery) {
+int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *tsdb, int32_t vgId, bool isSTableQuery) {
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
@@ -4818,6 +4891,8 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
pRuntimeEnv->hasTagResults = hasTagValOutput(pQuery);
pRuntimeEnv->timeWindowInterpo = timeWindowInterpoRequired(pQuery);
+ pRuntimeEnv->prevResult = prevResult;
+
setScanLimitationByResultBuffer(pQuery);
int32_t code = setupQueryHandle(tsdb, pQInfo, isSTableQuery);
@@ -4833,7 +4908,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
pRuntimeEnv->cur.vgroupIndex = -1;
pRuntimeEnv->stableQuery = isSTableQuery;
pRuntimeEnv->prevGroupId = INT32_MIN;
- pRuntimeEnv->groupbyColumn = isGroupbyNormalCol(pQuery->pGroupbyExpr);
+ pRuntimeEnv->groupbyColumn = isGroupbyColumn(pQuery->pGroupbyExpr);
if (pTsBuf != NULL) {
int16_t order = (pQuery->order.order == pRuntimeEnv->pTsBuf->tsOrder) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
@@ -4886,7 +4961,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
}
// create runtime environment
- code = setupQueryRuntimeEnv(pRuntimeEnv, pQuery->order.order);
+ code = setupQueryRuntimeEnv(pRuntimeEnv, (int32_t) pQInfo->tableGroupInfo.numOfTables, pQuery->order.order);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
@@ -4900,7 +4975,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
getAlignQueryTimeWindow(pQuery, pQuery->window.skey, sk, ek, &w);
int32_t numOfCols = getNumOfFinalResCol(pQuery);
- pRuntimeEnv->pFillInfo = taosInitFillInfo(pQuery->order.order, w.skey, 0, (int32_t)pQuery->rec.capacity, numOfCols,
+ pRuntimeEnv->pFillInfo = taosCreateFillInfo(pQuery->order.order, w.skey, 0, (int32_t)pQuery->rec.capacity, numOfCols,
pQuery->interval.sliding, pQuery->interval.slidingUnit, (int8_t)pQuery->precision,
pQuery->fillType, pColInfo, pQInfo);
}
@@ -4926,7 +5001,18 @@ static FORCE_INLINE void setEnvForEachBlock(SQInfo* pQInfo, STableQueryInfo* pTa
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order);
if (pRuntimeEnv->hasTagResults || pRuntimeEnv->pTsBuf != NULL) {
- setAdditionalInfo(pQInfo, pTableQueryInfo->pTable, pTableQueryInfo);
+ setTagVal(pRuntimeEnv, pTableQueryInfo->pTable);
+ }
+
+ if (pRuntimeEnv->pTsBuf != NULL) {
+ setTimestampListJoinInfo(pQInfo, pTableQueryInfo);
+ }
+
+ for(int32_t i = 0; i < pQuery->numOfOutput; ++i) {
+ if (pQuery->pExpr1[i].base.functionId == TSDB_FUNC_STDDEV_DST) {
+ setParamValue(pRuntimeEnv);
+ break;
+ }
}
if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
@@ -5024,7 +5110,7 @@ static bool multiTableMultioutputHelper(SQInfo *pQInfo, int32_t index) {
STableQueryInfo* pCheckInfo = taosArrayGetP(group, index);
if (pRuntimeEnv->hasTagResults || pRuntimeEnv->pTsBuf != NULL) {
- setTagVal(pRuntimeEnv, pCheckInfo->pTable, pQInfo->tsdb);
+ setTagVal(pRuntimeEnv, pCheckInfo->pTable);
}
STableId* id = TSDB_TABLEID(pCheckInfo->pTable);
@@ -5212,7 +5298,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
SArray *s = tsdbGetQueriedTableList(pRuntimeEnv->pQueryHandle);
assert(taosArrayGetSize(s) >= 1);
- setTagVal(pRuntimeEnv, taosArrayGetP(s, 0), pQInfo->tsdb);
+ setTagVal(pRuntimeEnv, taosArrayGetP(s, 0));
taosArrayDestroy(s);
// here we simply set the first table as current table
@@ -5271,7 +5357,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
SArray *s = tsdbGetQueriedTableList(pRuntimeEnv->pQueryHandle);
assert(taosArrayGetSize(s) >= 1);
- setTagVal(pRuntimeEnv, taosArrayGetP(s, 0), pQInfo->tsdb);
+ setTagVal(pRuntimeEnv, taosArrayGetP(s, 0));
// here we simply set the first table as current table
scanMultiTableDataBlocks(pQInfo);
@@ -5310,7 +5396,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
resetResultRowInfo(pRuntimeEnv, &pRuntimeEnv->windowResInfo);
break;
}
- } else if (pRuntimeEnv->queryWindowIdentical && pRuntimeEnv->pTsBuf == NULL && !isTSCompQuery(pQuery)) {
+ } else if (pRuntimeEnv->queryWindowIdentical && pRuntimeEnv->pTsBuf == NULL && !isTsCompQuery(pQuery)) {
//super table projection query with identical query time range for all tables.
SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
resetDefaultResInfoOutputBuf(pRuntimeEnv);
@@ -5360,7 +5446,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
doTableQueryInfoTimeWindowCheck(pQuery, *pTableQueryInfo);
if (pRuntimeEnv->hasTagResults) {
- setTagVal(pRuntimeEnv, pQuery->current->pTable, pQInfo->tsdb);
+ setTagVal(pRuntimeEnv, pQuery->current->pTable);
}
if (pQuery->prjInfo.vgroupLimit > 0 && pQuery->current->windowResInfo.size > pQuery->prjInfo.vgroupLimit) {
@@ -5430,7 +5516,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
} else {
// the limitation of output result is reached, set the query completed
skipResults(pRuntimeEnv);
- if (limitResults(pRuntimeEnv)) {
+ if (limitOperator(pRuntimeEnv)) {
setQueryStatus(pQuery, QUERY_COMPLETED);
SET_STABLE_QUERY_OVER(pQInfo);
break;
@@ -5498,7 +5584,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
skipResults(pRuntimeEnv);
// the limitation of output result is reached, set the query completed
- if (limitResults(pRuntimeEnv)) {
+ if (limitOperator(pRuntimeEnv)) {
SET_STABLE_QUERY_OVER(pQInfo);
break;
}
@@ -5553,7 +5639,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
*
* Only the ts-comp query requires the finalizer function to be executed here.
*/
- if (isTSCompQuery(pQuery)) {
+ if (isTsCompQuery(pQuery)) {
finalizeQueryResult(pRuntimeEnv);
}
@@ -5801,8 +5887,9 @@ static void tableAggregationProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
}
+ // TODO limit/offset refactor to be one operator
skipResults(pRuntimeEnv);
- limitResults(pRuntimeEnv);
+ limitOperator(pRuntimeEnv);
}
static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
@@ -5810,7 +5897,7 @@ static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
// for ts_comp query, re-initialized is not allowed
SQuery *pQuery = pRuntimeEnv->pQuery;
- if (!isTSCompQuery(pQuery)) {
+ if (!isTsCompQuery(pQuery)) {
resetDefaultResInfoOutputBuf(pRuntimeEnv);
}
@@ -5844,7 +5931,7 @@ static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
resetDefaultResInfoOutputBuf(pRuntimeEnv);
}
- limitResults(pRuntimeEnv);
+ limitOperator(pRuntimeEnv);
if (Q_STATUS_EQUAL(pQuery->status, QUERY_RESBUF_FULL)) {
qDebug("QInfo:%p query paused due to output limitation, next qrange:%" PRId64 "-%" PRId64, pQInfo,
pQuery->current->lastKey, pQuery->window.ekey);
@@ -5853,7 +5940,7 @@ static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
taosHashPut(pQInfo->arrTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid), &tidInfo, sizeof(STableIdInfo));
}
- if (!isTSCompQuery(pQuery)) {
+ if (!isTsCompQuery(pQuery)) {
assert(pQuery->rec.rows <= pQuery->rec.capacity);
}
}
@@ -5893,20 +5980,20 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
copyFromWindowResToSData(pQInfo, &pRuntimeEnv->windowResInfo);
doSecondaryArithmeticProcess(pQuery);
- limitResults(pRuntimeEnv);
+ limitOperator(pRuntimeEnv);
} else {
copyFromWindowResToSData(pQInfo, &pRuntimeEnv->windowResInfo);
doSecondaryArithmeticProcess(pQuery);
taosFillSetStartInfo(pRuntimeEnv->pFillInfo, (int32_t)pQuery->rec.rows, pQuery->window.ekey);
- taosFillCopyInputDataFromFilePage(pRuntimeEnv->pFillInfo, (const tFilePage **)pQuery->sdata);
+ taosFillSetDataBlockFromFilePage(pRuntimeEnv->pFillInfo, (const tFilePage **)pQuery->sdata);
int32_t numOfFilled = 0;
pQuery->rec.rows = doFillGapsInResults(pRuntimeEnv, (tFilePage **)pQuery->sdata, &numOfFilled);
if (pQuery->rec.rows > 0 || Q_STATUS_EQUAL(pQuery->status, QUERY_COMPLETED)) {
- limitResults(pRuntimeEnv);
+ limitOperator(pRuntimeEnv);
}
}
}
@@ -5925,7 +6012,7 @@ static void tableQueryImpl(SQInfo *pQInfo) {
pQuery->rec.rows = doFillGapsInResults(pRuntimeEnv, (tFilePage **)pQuery->sdata, &numOfFilled);
if (pQuery->rec.rows > 0) {
- limitResults(pRuntimeEnv);
+ limitOperator(pRuntimeEnv);
}
qDebug("QInfo:%p current:%" PRId64 " returned, total:%" PRId64, pQInfo, pQuery->rec.rows, pQuery->rec.total);
@@ -6160,6 +6247,37 @@ static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **p
return pMsg;
}
+typedef struct SQueryParam {
+ char *sql;
+ char *tagCond;
+ char *tbnameCond;
+ char *prevResult;
+ SArray *pTableIdList;
+ SSqlFuncMsg **pExprMsg;
+ SSqlFuncMsg **pSecExprMsg;
+ SExprInfo *pExprs;
+ SExprInfo *pSecExprs;
+
+ SColIndex *pGroupColIndex;
+ SColumnInfo *pTagColumnInfo;
+ SSqlGroupbyExpr *pGroupbyExpr;
+} SQueryParam;
+
+static void freeParam(SQueryParam *param) {
+ tfree(param->sql);
+ tfree(param->tagCond);
+ tfree(param->tbnameCond);
+ tfree(param->pTableIdList);
+ tfree(param->pExprMsg);
+ tfree(param->pSecExprMsg);
+ tfree(param->pExprs);
+ tfree(param->pSecExprs);
+ tfree(param->pGroupColIndex);
+ tfree(param->pTagColumnInfo);
+ tfree(param->pGroupbyExpr);
+ tfree(param->prevResult);
+}
+
/**
* pQueryMsg->head has been converted before this function is called.
*
@@ -6168,8 +6286,7 @@ static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **p
* @param pExpr
* @return
*/
-static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList, SSqlFuncMsg ***pExpr, SSqlFuncMsg ***pSecStageExpr,
- char **tagCond, char** tbnameCond, SColIndex **groupbyCols, SColumnInfo** tagCols, char** sql) {
+static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
int32_t code = TSDB_CODE_SUCCESS;
if (taosCheckVersion(pQueryMsg->version, version, 3) != 0) {
@@ -6204,6 +6321,7 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
pQueryMsg->tbnameCondLen = htonl(pQueryMsg->tbnameCondLen);
pQueryMsg->secondStageOutput = htonl(pQueryMsg->secondStageOutput);
pQueryMsg->sqlstrLen = htonl(pQueryMsg->sqlstrLen);
+ pQueryMsg->prevResultLen = htonl(pQueryMsg->prevResultLen);
// query msg safety check
if (!validateQueryMsg(pQueryMsg)) {
@@ -6264,8 +6382,8 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
}
}
- *pExpr = calloc(pQueryMsg->numOfOutput, POINTER_BYTES);
- if (*pExpr == NULL) {
+ param->pExprMsg = calloc(pQueryMsg->numOfOutput, POINTER_BYTES);
+ if (param->pExprMsg == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _cleanup;
}
@@ -6273,7 +6391,7 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
SSqlFuncMsg *pExprMsg = (SSqlFuncMsg *)pMsg;
for (int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) {
- (*pExpr)[i] = pExprMsg;
+ param->pExprMsg[i] = pExprMsg;
pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex);
pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId);
@@ -6309,10 +6427,10 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
if (pQueryMsg->secondStageOutput) {
pExprMsg = (SSqlFuncMsg *)pMsg;
- *pSecStageExpr = calloc(pQueryMsg->secondStageOutput, POINTER_BYTES);
+ param->pSecExprMsg = calloc(pQueryMsg->secondStageOutput, POINTER_BYTES);
for (int32_t i = 0; i < pQueryMsg->secondStageOutput; ++i) {
- (*pSecStageExpr)[i] = pExprMsg;
+ param->pSecExprMsg[i] = pExprMsg;
pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex);
pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId);
@@ -6346,27 +6464,27 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
}
}
- pMsg = createTableIdList(pQueryMsg, pMsg, pTableIdList);
+ pMsg = createTableIdList(pQueryMsg, pMsg, &(param->pTableIdList));
if (pQueryMsg->numOfGroupCols > 0) { // group by tag columns
- *groupbyCols = malloc(pQueryMsg->numOfGroupCols * sizeof(SColIndex));
- if (*groupbyCols == NULL) {
+ param->pGroupColIndex = malloc(pQueryMsg->numOfGroupCols * sizeof(SColIndex));
+ if (param->pGroupColIndex == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _cleanup;
}
for (int32_t i = 0; i < pQueryMsg->numOfGroupCols; ++i) {
- (*groupbyCols)[i].colId = htons(*(int16_t *)pMsg);
- pMsg += sizeof((*groupbyCols)[i].colId);
+ param->pGroupColIndex[i].colId = htons(*(int16_t *)pMsg);
+ pMsg += sizeof(param->pGroupColIndex[i].colId);
- (*groupbyCols)[i].colIndex = htons(*(int16_t *)pMsg);
- pMsg += sizeof((*groupbyCols)[i].colIndex);
+ param->pGroupColIndex[i].colIndex = htons(*(int16_t *)pMsg);
+ pMsg += sizeof(param->pGroupColIndex[i].colIndex);
- (*groupbyCols)[i].flag = htons(*(int16_t *)pMsg);
- pMsg += sizeof((*groupbyCols)[i].flag);
+ param->pGroupColIndex[i].flag = htons(*(int16_t *)pMsg);
+ pMsg += sizeof(param->pGroupColIndex[i].flag);
- memcpy((*groupbyCols)[i].name, pMsg, tListLen(groupbyCols[i]->name));
- pMsg += tListLen((*groupbyCols)[i].name);
+ memcpy(param->pGroupColIndex[i].name, pMsg, tListLen(param->pGroupColIndex[i].name));
+ pMsg += tListLen(param->pGroupColIndex[i].name);
}
pQueryMsg->orderByIdx = htons(pQueryMsg->orderByIdx);
@@ -6386,8 +6504,8 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
}
if (pQueryMsg->numOfTags > 0) {
- (*tagCols) = calloc(1, sizeof(SColumnInfo) * pQueryMsg->numOfTags);
- if (*tagCols == NULL) {
+ param->pTagColumnInfo = calloc(1, sizeof(SColumnInfo) * pQueryMsg->numOfTags);
+ if (param->pTagColumnInfo == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _cleanup;
}
@@ -6400,32 +6518,42 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
pTagCol->type = htons(pTagCol->type);
pTagCol->numOfFilters = 0;
- (*tagCols)[i] = *pTagCol;
+ param->pTagColumnInfo[i] = *pTagCol;
pMsg += sizeof(SColumnInfo);
}
}
// the tag query condition expression string is located at the end of query msg
if (pQueryMsg->tagCondLen > 0) {
- *tagCond = calloc(1, pQueryMsg->tagCondLen);
-
- if (*tagCond == NULL) {
+ param->tagCond = calloc(1, pQueryMsg->tagCondLen);
+ if (param->tagCond == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _cleanup;
-
}
- memcpy(*tagCond, pMsg, pQueryMsg->tagCondLen);
+
+ memcpy(param->tagCond, pMsg, pQueryMsg->tagCondLen);
pMsg += pQueryMsg->tagCondLen;
}
- if (pQueryMsg->tbnameCondLen > 0) {
- *tbnameCond = calloc(1, pQueryMsg->tbnameCondLen + 1);
- if (*tbnameCond == NULL) {
+ if (pQueryMsg->prevResultLen > 0) {
+ param->prevResult = calloc(1, pQueryMsg->prevResultLen);
+ if (param->prevResult == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _cleanup;
}
- strncpy(*tbnameCond, pMsg, pQueryMsg->tbnameCondLen);
+ memcpy(param->prevResult, pMsg, pQueryMsg->prevResultLen);
+ pMsg += pQueryMsg->prevResultLen;
+ }
+
+ if (pQueryMsg->tbnameCondLen > 0) {
+ param->tbnameCond = calloc(1, pQueryMsg->tbnameCondLen + 1);
+ if (param->tbnameCond == NULL) {
+ code = TSDB_CODE_QRY_OUT_OF_MEMORY;
+ goto _cleanup;
+ }
+
+ strncpy(param->tbnameCond, pMsg, pQueryMsg->tbnameCondLen);
pMsg += pQueryMsg->tbnameCondLen;
}
@@ -6434,9 +6562,9 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
pMsg = (char *)pQueryMsg + pQueryMsg->tsOffset + pQueryMsg->tsLen;
}
- *sql = strndup(pMsg, pQueryMsg->sqlstrLen);
+ param->sql = strndup(pMsg, pQueryMsg->sqlstrLen);
- if (!validateQuerySourceCols(pQueryMsg, *pExpr, *tagCols)) {
+ if (!validateQuerySourceCols(pQueryMsg, param->pExprMsg, param->pTagColumnInfo)) {
code = TSDB_CODE_QRY_INVALID_MSG;
goto _cleanup;
}
@@ -6447,19 +6575,11 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
pQueryMsg->order, pQueryMsg->numOfOutput, pQueryMsg->numOfCols, pQueryMsg->interval.interval,
pQueryMsg->fillType, pQueryMsg->tsLen, pQueryMsg->tsNumOfBlocks, pQueryMsg->limit, pQueryMsg->offset);
- qDebug("qmsg:%p, sql:%s", pQueryMsg, *sql);
+ qDebug("qmsg:%p, sql:%s", pQueryMsg, param->sql);
return TSDB_CODE_SUCCESS;
_cleanup:
- tfree(*pExpr);
- taosArrayDestroy(*pTableIdList);
- *pTableIdList = NULL;
- tfree(*tbnameCond);
- tfree(*groupbyCols);
- tfree(*tagCols);
- tfree(*tagCond);
- tfree(*sql);
-
+ freeParam(param);
return code;
}
@@ -6516,9 +6636,9 @@ static int32_t createQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t num
type = TSDB_DATA_TYPE_DOUBLE;
bytes = tDataTypes[type].bytes;
} else if (pExprs[i].base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX && pExprs[i].base.functionId == TSDB_FUNC_TAGPRJ) { // parse the normal column
- SSchema s = tGetTableNameColumnSchema();
- type = s.type;
- bytes = s.bytes;
+ SSchema* s = tGetTbnameColumnSchema();
+ type = s->type;
+ bytes = s->bytes;
} else if (pExprs[i].base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) {
SSchema s = tGetBlockDistColumnSchema();
type = s.type;
@@ -6550,10 +6670,10 @@ static int32_t createQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t num
type = pCol->type;
bytes = pCol->bytes;
} else {
- SSchema s = tGetTableNameColumnSchema();
+ SSchema* s = tGetTbnameColumnSchema();
- type = s.type;
- bytes = s.bytes;
+ type = s->type;
+ bytes = s->bytes;
}
}
@@ -6719,7 +6839,7 @@ static void calResultBufSize(SQuery* pQuery) {
const float RESULT_THRESHOLD_RATIO = 0.85f;
if (isProjQuery(pQuery)) {
- int32_t numOfRes = RESULT_MSG_MIN_SIZE / pQuery->rowSize;
+ int32_t numOfRes = RESULT_MSG_MIN_SIZE / pQuery->resultRowSize;
if (numOfRes < RESULT_MSG_MIN_ROWS) {
numOfRes = RESULT_MSG_MIN_ROWS;
}
@@ -6775,17 +6895,27 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
goto _cleanup;
}
- int32_t srcSize = 0;
+ pQuery->srcRowSize = 0;
+ pQuery->maxSrcColumnSize = 0;
for (int16_t i = 0; i < numOfCols; ++i) {
pQuery->colList[i] = pQueryMsg->colList[i];
pQuery->colList[i].filters = tFilterInfoDup(pQueryMsg->colList[i].filters, pQuery->colList[i].numOfFilters);
- srcSize += pQuery->colList[i].bytes;
+
+ pQuery->srcRowSize += pQuery->colList[i].bytes;
+ if (pQuery->maxSrcColumnSize < pQuery->colList[i].bytes) {
+ pQuery->maxSrcColumnSize = pQuery->colList[i].bytes;
+ }
}
// calculate the result row size
for (int16_t col = 0; col < numOfOutput; ++col) {
assert(pExprs[col].bytes > 0);
- pQuery->rowSize += pExprs[col].bytes;
+ pQuery->resultRowSize += pExprs[col].bytes;
+
+ // keep the tag length
+ if (TSDB_COL_IS_TAG(pExprs[col].base.colInfo.flag)) {
+ pQuery->tagLen += pExprs[col].bytes;
+ }
}
doUpdateExprColumnIndex(pQuery);
@@ -6833,26 +6963,11 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
size_t numOfGroups = 0;
if (pTableGroupInfo->pGroupList != NULL) {
numOfGroups = taosArrayGetSize(pTableGroupInfo->pGroupList);
+ STableGroupInfo* pTableqinfo = &pQInfo->tableqinfoGroupInfo;
- pQInfo->tableqinfoGroupInfo.pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES);
- pQInfo->tableqinfoGroupInfo.numOfTables = pTableGroupInfo->numOfTables;
- pQInfo->tableqinfoGroupInfo.map = taosHashInit(pTableGroupInfo->numOfTables,
- taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
- }
-
- pQInfo->runtimeEnv.interBufSize = getOutputInterResultBufSize(pQuery);
- pQInfo->runtimeEnv.summary.tableInfoSize += (pTableGroupInfo->numOfTables * sizeof(STableQueryInfo));
-
- pQInfo->runtimeEnv.pResultRowHashTable = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
- pQInfo->runtimeEnv.keyBuf = malloc(TSDB_MAX_BYTES_PER_ROW); // todo opt size
- pQInfo->runtimeEnv.pool = initResultRowPool(getResultRowSize(&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;
+ pTableqinfo->pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES);
+ pTableqinfo->numOfTables = pTableGroupInfo->numOfTables;
+ pTableqinfo->map = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
}
pQInfo->pBuf = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
@@ -6873,6 +6988,8 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
changeExecuteScanOrder(pQInfo, pQueryMsg, stableQuery);
pQInfo->runtimeEnv.queryWindowIdentical = true;
+ bool groupByCol = isGroupbyColumn(pQuery->pGroupbyExpr);
+
STimeWindow window = pQuery->window;
int32_t index = 0;
@@ -6896,7 +7013,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
}
void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo);
- STableQueryInfo* item = createTableQueryInfo(&pQInfo->runtimeEnv, info->pTable, window, buf);
+ STableQueryInfo* item = createTableQueryInfo(pQuery, info->pTable, groupByCol, window, buf);
if (item == NULL) {
goto _cleanup;
}
@@ -6909,8 +7026,10 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
index += 1;
}
}
+
colIdCheck(pQuery);
+ // todo refactor
pQInfo->runtimeEnv.queryBlockDist = (numOfOutput == 1 && pExprs[0].base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX);
qDebug("qmsg:%p QInfo:%p created", pQueryMsg, pQInfo);
@@ -6955,21 +7074,26 @@ static bool isValidQInfo(void *param) {
return (sig == (uint64_t)pQInfo);
}
-static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *pQInfo, bool isSTable) {
+static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *pQInfo, SQueryParam* param, bool isSTable) {
int32_t code = TSDB_CODE_SUCCESS;
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
- STSBuf *pTSBuf = NULL;
+ STSBuf *pTsBuf = NULL;
if (pQueryMsg->tsLen > 0) { // open new file to save the result
char *tsBlock = (char *) pQueryMsg + pQueryMsg->tsOffset;
- pTSBuf = tsBufCreateFromCompBlocks(tsBlock, pQueryMsg->tsNumOfBlocks, pQueryMsg->tsLen, pQueryMsg->tsOrder, vgId);
+ pTsBuf = tsBufCreateFromCompBlocks(tsBlock, pQueryMsg->tsNumOfBlocks, pQueryMsg->tsLen, pQueryMsg->tsOrder, vgId);
- tsBufResetPos(pTSBuf);
- bool ret = tsBufNextPos(pTSBuf);
+ tsBufResetPos(pTsBuf);
+ bool ret = tsBufNextPos(pTsBuf);
UNUSED(ret);
}
+ SArray* prevResult = NULL;
+ if (pQueryMsg->prevResultLen > 0) {
+ prevResult = interResFromBinary(param->prevResult, pQueryMsg->prevResultLen);
+ }
+
pQuery->precision = tsdbGetCfg(tsdb)->precision;
if ((QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.skey > pQuery->window.ekey)) ||
@@ -6978,6 +7102,7 @@ static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQ
pQuery->window.ekey, pQuery->order.order);
setQueryStatus(pQuery, QUERY_COMPLETED);
pQInfo->tableqinfoGroupInfo.numOfTables = 0;
+ // todo free memory
return TSDB_CODE_SUCCESS;
}
@@ -6988,7 +7113,7 @@ static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQ
}
// filter the qualified
- if ((code = doInitQInfo(pQInfo, pTSBuf, tsdb, vgId, isSTable)) != TSDB_CODE_SUCCESS) {
+ if ((code = doInitQInfo(pQInfo, pTsBuf, prevResult, tsdb, vgId, isSTable)) != TSDB_CODE_SUCCESS) {
goto _error;
}
@@ -7062,7 +7187,6 @@ static void freeQInfo(SQInfo *pQInfo) {
qDebug("QInfo:%p start to free QInfo", pQInfo);
releaseQueryBuf(pQInfo->tableqinfoGroupInfo.numOfTables);
-
teardownQueryRuntimeEnv(&pQInfo->runtimeEnv);
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
@@ -7132,7 +7256,7 @@ static size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows) {
* the returned row size is equalled to 1
* TODO handle the case that the file is too large to send back one time
*/
- if (isTSCompQuery(pQuery) && (*numOfRows) > 0) {
+ if (isTsCompQuery(pQuery) && (*numOfRows) > 0) {
struct stat fStat;
FILE *f = *(FILE **)pQuery->sdata[0]->data;
if ((f != NULL) && (fstat(fileno(f), &fStat) == 0)) {
@@ -7143,7 +7267,7 @@ static size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows) {
return 0;
}
} else {
- return (size_t)(pQuery->rowSize * (*numOfRows));
+ return (size_t)(pQuery->resultRowSize * (*numOfRows));
}
}
@@ -7152,7 +7276,7 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
// load data from file to msg buffer
- if (isTSCompQuery(pQuery)) {
+ if (isTsCompQuery(pQuery)) {
FILE *f = *(FILE **)pQuery->sdata[0]->data; // TODO refactor
@@ -7203,10 +7327,10 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
}
typedef struct SQueryMgmt {
+ pthread_mutex_t lock;
SCacheObj *qinfoPool; // query handle pool
int32_t vgId;
bool closed;
- pthread_mutex_t lock;
} SQueryMgmt;
int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qinfo_t* pQInfo) {
@@ -7214,20 +7338,8 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
int32_t code = TSDB_CODE_SUCCESS;
- char *sql = NULL;
- char *tagCond = NULL;
- char *tbnameCond = NULL;
- SArray *pTableIdList = NULL;
- SSqlFuncMsg **pExprMsg = NULL;
- SSqlFuncMsg **pSecExprMsg = NULL;
- SExprInfo *pExprs = NULL;
- SExprInfo *pSecExprs = NULL;
-
- SColIndex *pGroupColIndex = NULL;
- SColumnInfo *pTagColumnInfo = NULL;
- SSqlGroupbyExpr *pGroupbyExpr = NULL;
-
- code = convertQueryMsg(pQueryMsg, &pTableIdList, &pExprMsg, &pSecExprMsg, &tagCond, &tbnameCond, &pGroupColIndex, &pTagColumnInfo, &sql);
+ SQueryParam param = {0};
+ code = convertQueryMsg(pQueryMsg, ¶m);
if (code != TSDB_CODE_SUCCESS) {
goto _over;
}
@@ -7238,24 +7350,24 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
goto _over;
}
- if (pTableIdList == NULL || taosArrayGetSize(pTableIdList) == 0) {
+ if (param.pTableIdList == NULL || taosArrayGetSize(param.pTableIdList) == 0) {
qError("qmsg:%p, SQueryTableMsg wrong format", pQueryMsg);
code = TSDB_CODE_QRY_INVALID_MSG;
goto _over;
}
- if ((code = createQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->numOfOutput, &pExprs, pExprMsg, pTagColumnInfo)) != TSDB_CODE_SUCCESS) {
+ if ((code = createQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExprMsg, param.pTagColumnInfo)) != TSDB_CODE_SUCCESS) {
goto _over;
}
- if (pSecExprMsg != NULL) {
- if ((code = createQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, &pSecExprs, pSecExprMsg, pTagColumnInfo)) != TSDB_CODE_SUCCESS) {
+ if (param.pSecExprMsg != NULL) {
+ if ((code = createQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExprMsg, param.pTagColumnInfo)) != TSDB_CODE_SUCCESS) {
goto _over;
}
}
- pGroupbyExpr = createGroupbyExprFromMsg(pQueryMsg, pGroupColIndex, &code);
- if ((pGroupbyExpr == NULL && pQueryMsg->numOfGroupCols != 0) || code != TSDB_CODE_SUCCESS) {
+ param.pGroupbyExpr = createGroupbyExprFromMsg(pQueryMsg, param.pGroupColIndex, &code);
+ if ((param.pGroupbyExpr == NULL && pQueryMsg->numOfGroupCols != 0) || code != TSDB_CODE_SUCCESS) {
goto _over;
}
@@ -7264,7 +7376,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
int64_t st = taosGetTimestampUs();
if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_TABLE_QUERY)) {
- STableIdInfo *id = taosArrayGet(pTableIdList, 0);
+ STableIdInfo *id = taosArrayGet(param.pTableIdList, 0);
qDebug("qmsg:%p query normal table, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid);
if ((code = tsdbGetOneTableGroup(tsdb, id->uid, pQueryMsg->window.skey, &tableGroupInfo)) != TSDB_CODE_SUCCESS) {
@@ -7275,24 +7387,24 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
// also note there's possibility that only one table in the super table
if (!TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY)) {
- STableIdInfo *id = taosArrayGet(pTableIdList, 0);
+ STableIdInfo *id = taosArrayGet(param.pTableIdList, 0);
// group by normal column, do not pass the group by condition to tsdb to group table into different group
int32_t numOfGroupByCols = pQueryMsg->numOfGroupCols;
- if (pQueryMsg->numOfGroupCols == 1 && !TSDB_COL_IS_TAG(pGroupColIndex->flag)) {
+ if (pQueryMsg->numOfGroupCols == 1 && !TSDB_COL_IS_TAG(param.pGroupColIndex->flag)) {
numOfGroupByCols = 0;
}
qDebug("qmsg:%p query stable, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid);
- code = tsdbQuerySTableByTagCond(tsdb, id->uid, pQueryMsg->window.skey, tagCond, pQueryMsg->tagCondLen,
- pQueryMsg->tagNameRelType, tbnameCond, &tableGroupInfo, pGroupColIndex, numOfGroupByCols);
+ code = tsdbQuerySTableByTagCond(tsdb, id->uid, pQueryMsg->window.skey, param.tagCond, pQueryMsg->tagCondLen,
+ pQueryMsg->tagNameRelType, param.tbnameCond, &tableGroupInfo, param.pGroupColIndex, numOfGroupByCols);
if (code != TSDB_CODE_SUCCESS) {
qError("qmsg:%p failed to query stable, reason: %s", pQueryMsg, tstrerror(code));
goto _over;
}
} else {
- code = tsdbGetTableGroupFromIdList(tsdb, pTableIdList, &tableGroupInfo);
+ code = tsdbGetTableGroupFromIdList(tsdb, param.pTableIdList, &tableGroupInfo);
if (code != TSDB_CODE_SUCCESS) {
goto _over;
}
@@ -7311,40 +7423,30 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
goto _over;
}
- (*pQInfo) = createQInfoImpl(pQueryMsg, pGroupbyExpr, pExprs, pSecExprs, &tableGroupInfo, pTagColumnInfo, isSTableQuery, sql);
+ (*pQInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo, param.pTagColumnInfo, isSTableQuery, param.sql);
- sql = NULL;
- pExprs = NULL;
- pSecExprs = NULL;
- pGroupbyExpr = NULL;
- pTagColumnInfo = NULL;
+ param.sql = NULL;
+ param.pExprs = NULL;
+ param.pSecExprs = NULL;
+ param.pGroupbyExpr = NULL;
+ param.pTagColumnInfo = NULL;
if ((*pQInfo) == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _over;
}
- code = initQInfo(pQueryMsg, tsdb, vgId, *pQInfo, isSTableQuery);
+ code = initQInfo(pQueryMsg, tsdb, vgId, *pQInfo, ¶m, isSTableQuery);
_over:
- free(tagCond);
- free(tbnameCond);
- free(pGroupColIndex);
-
- if (pGroupbyExpr != NULL) {
- taosArrayDestroy(pGroupbyExpr->columnInfo);
- free(pGroupbyExpr);
+ if (param.pGroupbyExpr != NULL) {
+ taosArrayDestroy(param.pGroupbyExpr->columnInfo);
}
- free(pTagColumnInfo);
- free(sql);
- free(pExprs);
- free(pSecExprs);
+ taosArrayDestroy(param.pTableIdList);
+ param.pTableIdList = NULL;
- free(pExprMsg);
- free(pSecExprMsg);
-
- taosArrayDestroy(pTableIdList);
+ freeParam(¶m);
for (int32_t i = 0; i < pQueryMsg->numOfCols; i++) {
SColumnInfo* column = pQueryMsg->colList + i;
@@ -7480,7 +7582,7 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex
assert(pQInfo->rspContext == NULL);
if (pQInfo->dataReady == QUERY_RESULT_READY) {
*buildRes = true;
- qDebug("QInfo:%p retrieve result info, rowsize:%d, rows:%" PRId64 ", code:%s", pQInfo, pQuery->rowSize,
+ qDebug("QInfo:%p retrieve result info, rowsize:%d, rows:%" PRId64 ", code:%s", pQInfo, pQuery->resultRowSize,
pQuery->rec.rows, tstrerror(pQInfo->code));
} else {
*buildRes = false;
@@ -7675,7 +7777,7 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
qDebug("QInfo:%p create count(tbname) query, res:%d rows:1", pQInfo, count);
} else { // return only the tags|table name etc.
count = 0;
- SSchema tbnameSchema = tGetTableNameColumnSchema();
+ SSchema* tbnameSchema = tGetTbnameColumnSchema();
int32_t maxNumOfTables = (int32_t)pQuery->rec.capacity;
if (pQuery->limit.limit >= 0 && pQuery->limit.limit < pQuery->rec.capacity) {
@@ -7703,11 +7805,11 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
}
if (pExprInfo[j].base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) {
- bytes = tbnameSchema.bytes;
- type = tbnameSchema.type;
+ bytes = tbnameSchema->bytes;
+ type = tbnameSchema->type;
data = tsdbGetTableName(item->pTable);
- dst = pQuery->sdata[j]->data + count * tbnameSchema.bytes;
+ dst = pQuery->sdata[j]->data + count * tbnameSchema->bytes;
} else {
type = pExprInfo[j].type;
bytes = pExprInfo[j].bytes;
diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c
index c82f8f632d..bc6376b807 100644
--- a/src/query/src/qFill.c
+++ b/src/query/src/qFill.c
@@ -321,7 +321,7 @@ static int32_t taosNumOfRemainRows(SFillInfo* pFillInfo) {
return pFillInfo->numOfRows - pFillInfo->index;
}
-SFillInfo* taosInitFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
+SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
int64_t slidingTime, int8_t slidingUnit, int8_t precision, int32_t fillType,
SFillColInfo* pCol, void* handle) {
if (fillType == TSDB_FILL_NONE) {
@@ -414,7 +414,7 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
}
// copy the data into source data buffer
-void taosFillCopyInputDataFromFilePage(SFillInfo* pFillInfo, const tFilePage** pInput) {
+void taosFillSetDataBlockFromFilePage(SFillInfo* pFillInfo, const tFilePage** pInput) {
for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
memcpy(pFillInfo->pData[i], pInput[i]->data, pFillInfo->numOfRows * pFillInfo->pFillCol[i].col.bytes);
}
diff --git a/src/query/src/qParserImpl.c b/src/query/src/qParserImpl.c
index d0839b3dc4..2efd4f76ea 100644
--- a/src/query/src/qParserImpl.c
+++ b/src/query/src/qParserImpl.c
@@ -279,7 +279,7 @@ tSQLExpr *tSqlExprCreate(tSQLExpr *pLeft, tSQLExpr *pRight, int32_t optrType) {
pExpr->nSQLOptr = optrType;
pExpr->pLeft = pLeft;
- if (pRight == NULL) {
+ if (pLeft != NULL && pRight == NULL) {
pRight = calloc(1, sizeof(tSQLExpr));
}
diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c
index dc01de0f92..46079e6830 100644
--- a/src/query/src/qUtil.c
+++ b/src/query/src/qUtil.c
@@ -19,6 +19,7 @@
#include "qExecutor.h"
#include "qUtil.h"
+#include "tbuffer.h"
int32_t getOutputInterResultBufSize(SQuery* pQuery) {
int32_t size = 0;
@@ -228,4 +229,97 @@ void* destroyResultRowPool(SResultRowPool* p) {
tfree(p);
return NULL;
+}
+
+void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen) {
+ uint32_t numOfGroup = (uint32_t) taosArrayGetSize(pRes);
+ tbufWriteUint32(bw, numOfGroup);
+ tbufWriteUint16(bw, tagLen);
+
+ for(int32_t i = 0; i < numOfGroup; ++i) {
+ SInterResult* pOne = taosArrayGet(pRes, i);
+ if (tagLen > 0) {
+ tbufWriteBinary(bw, pOne->tags, tagLen);
+ }
+
+ uint32_t numOfCols = (uint32_t) taosArrayGetSize(pOne->pResult);
+ tbufWriteUint32(bw, numOfCols);
+ for(int32_t j = 0; j < numOfCols; ++j) {
+ SStddevInterResult* p = taosArrayGet(pOne->pResult, j);
+ uint32_t numOfRows = (uint32_t) taosArrayGetSize(p->pResult);
+
+ tbufWriteUint16(bw, p->colId);
+ tbufWriteUint32(bw, numOfRows);
+
+ for(int32_t k = 0; k < numOfRows; ++k) {
+ SResPair v = *(SResPair*) taosArrayGet(p->pResult, k);
+ tbufWriteDouble(bw, v.avg);
+ tbufWriteInt64(bw, v.key);
+ }
+ }
+ }
+}
+
+SArray* interResFromBinary(const char* data, int32_t len) {
+ SBufferReader br = tbufInitReader(data, len, false);
+ uint32_t numOfGroup = tbufReadUint32(&br);
+ uint16_t tagLen = tbufReadUint16(&br);
+
+ char* tag = NULL;
+ if (tagLen > 0) {
+ tag = calloc(1, tagLen);
+ }
+
+ SArray* pResult = taosArrayInit(4, sizeof(SInterResult));
+
+ for(int32_t i = 0; i < numOfGroup; ++i) {
+ if (tagLen > 0) {
+ memset(tag, 0, tagLen);
+ tbufReadToBinary(&br, tag, tagLen);
+ }
+
+ uint32_t numOfCols = tbufReadUint32(&br);
+
+ SArray* p = taosArrayInit(numOfCols, sizeof(SStddevInterResult));
+ for(int32_t j = 0; j < numOfCols; ++j) {
+ int16_t colId = tbufReadUint16(&br);
+ int32_t numOfRows = tbufReadUint32(&br);
+
+ SStddevInterResult interRes = {.colId = colId, .pResult = taosArrayInit(4, sizeof(struct SResPair)),};
+ for(int32_t k = 0; k < numOfRows; ++k) {
+ SResPair px = {0};
+ px.avg = tbufReadDouble(&br);
+ px.key = tbufReadInt64(&br);
+
+ taosArrayPush(interRes.pResult, &px);
+ }
+
+ taosArrayPush(p, &interRes);
+ }
+
+ char* p1 = NULL;
+ if (tagLen > 0) {
+ p1 = malloc(tagLen);
+ memcpy(p1, tag, tagLen);
+ }
+
+ SInterResult d = {.pResult = p, .tags = p1,};
+ taosArrayPush(pResult, &d);
+ }
+
+ tfree(tag);
+ return pResult;
+}
+
+void freeInterResult(void* param) {
+ SInterResult* pResult = (SInterResult*) param;
+ tfree(pResult->tags);
+
+ int32_t numOfCols = (int32_t) taosArrayGetSize(pResult->pResult);
+ for(int32_t i = 0; i < numOfCols; ++i) {
+ SStddevInterResult *p = taosArrayGet(pResult->pResult, i);
+ taosArrayDestroy(p->pResult);
+ }
+
+ taosArrayDestroy(pResult->pResult);
}
\ No newline at end of file
diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c
index 3295c130dd..3162ab2e4c 100644
--- a/src/rpc/src/rpcTcp.c
+++ b/src/rpc/src/rpcTcp.c
@@ -17,7 +17,7 @@
#include "tsocket.h"
#include "tutil.h"
#include "taosdef.h"
-#include "taoserror.h"
+#include "taoserror.h"
#include "rpcLog.h"
#include "rpcHead.h"
#include "rpcTcp.h"
@@ -81,7 +81,7 @@ void *taosInitTcpServer(uint32_t ip, uint16_t port, char *label, int numOfThread
pServerObj = (SServerObj *)calloc(sizeof(SServerObj), 1);
if (pServerObj == NULL) {
tError("TCP:%s no enough memory", label);
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
return NULL;
}
@@ -95,7 +95,7 @@ void *taosInitTcpServer(uint32_t ip, uint16_t port, char *label, int numOfThread
pServerObj->pThreadObj = (SThreadObj **)calloc(sizeof(SThreadObj *), numOfThreads);
if (pServerObj->pThreadObj == NULL) {
tError("TCP:%s no enough memory", label);
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
free(pServerObj);
return NULL;
}
@@ -105,18 +105,18 @@ void *taosInitTcpServer(uint32_t ip, uint16_t port, char *label, int numOfThread
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
- // initialize parameters in case it may encounter error later
+ // initialize parameters in case it may encounter error later
for (int i = 0; i < numOfThreads; ++i) {
pThreadObj = (SThreadObj *)calloc(sizeof(SThreadObj), 1);
if (pThreadObj == NULL) {
tError("TCP:%s no enough memory", label);
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
for (int j=0; jpThreadObj[j]);
free(pServerObj->pThreadObj);
free(pServerObj);
return NULL;
}
-
+
pServerObj->pThreadObj[i] = pThreadObj;
pThreadObj->pollFd = -1;
taosResetPthread(&pThreadObj->thread);
@@ -152,9 +152,9 @@ void *taosInitTcpServer(uint32_t ip, uint16_t port, char *label, int numOfThread
}
pServerObj->fd = taosOpenTcpServerSocket(pServerObj->ip, pServerObj->port);
- if (pServerObj->fd < 0) code = -1;
+ if (pServerObj->fd < 0) code = -1;
- if (code == 0) {
+ if (code == 0) {
code = pthread_create(&pServerObj->thread, &thattr, taosAcceptTcpConnection, (void *)pServerObj);
if (code != 0) {
tError("%s failed to create TCP accept thread(%s)", label, strerror(code));
@@ -162,7 +162,7 @@ void *taosInitTcpServer(uint32_t ip, uint16_t port, char *label, int numOfThread
}
if (code != 0) {
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
taosCleanUpTcpServer(pServerObj);
pServerObj = NULL;
} else {
@@ -175,8 +175,8 @@ void *taosInitTcpServer(uint32_t ip, uint16_t port, char *label, int numOfThread
static void taosStopTcpThread(SThreadObj* pThreadObj) {
if (pThreadObj == NULL) { return;}
- // save thread into local variable and signal thread to stop
- pthread_t thread = pThreadObj->thread;
+ // save thread into local variable and signal thread to stop
+ pthread_t thread = pThreadObj->thread;
if (!taosCheckPthreadValid(thread)) {
return;
}
@@ -197,6 +197,11 @@ void taosStopTcpServer(void *handle) {
if (pServerObj->fd >= 0) {
#ifdef WINDOWS
closesocket(pServerObj->fd);
+#elif defined(__APPLE__)
+ if (pServerObj->fd!=-1) {
+ close(pServerObj->fd);
+ pServerObj->fd = -1;
+ }
#else
shutdown(pServerObj->fd, SHUT_RD);
#endif
@@ -265,7 +270,7 @@ static void *taosAcceptTcpConnection(void *arg) {
taosInetNtoa(caddr.sin_addr), htons(caddr.sin_port));
continue;
}
-
+
// pick up the thread to handle this connection
pThreadObj = pServerObj->pThreadObj[threadId];
@@ -274,13 +279,13 @@ static void *taosAcceptTcpConnection(void *arg) {
if (pFdObj) {
pFdObj->ip = caddr.sin_addr.s_addr;
pFdObj->port = htons(caddr.sin_port);
- tDebug("%s new TCP connection from %s:%hu, fd:%d FD:%p numOfFds:%d", pServerObj->label,
+ tDebug("%s new TCP connection from %s:%hu, fd:%d FD:%p numOfFds:%d", pServerObj->label,
taosInetNtoa(caddr.sin_addr), pFdObj->port, connFd, pFdObj, pThreadObj->numOfFds);
} else {
taosCloseSocket(connFd);
tError("%s failed to malloc FdObj(%s) for connection from:%s:%hu", pServerObj->label, strerror(errno),
taosInetNtoa(caddr.sin_addr), htons(caddr.sin_port));
- }
+ }
// pick up next thread for next connection
threadId++;
@@ -295,17 +300,17 @@ void *taosInitTcpClient(uint32_t ip, uint16_t port, char *label, int numOfThread
SClientObj *pClientObj = (SClientObj *)calloc(1, sizeof(SClientObj));
if (pClientObj == NULL) {
tError("TCP:%s no enough memory", label);
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
return NULL;
- }
+ }
tstrncpy(pClientObj->label, label, sizeof(pClientObj->label));
pClientObj->numOfThreads = numOfThreads;
- pClientObj->pThreadObj = (SThreadObj **)calloc(numOfThreads, sizeof(SThreadObj*));
+ pClientObj->pThreadObj = (SThreadObj **)calloc(numOfThreads, sizeof(SThreadObj*));
if (pClientObj->pThreadObj == NULL) {
tError("TCP:%s no enough memory", label);
tfree(pClientObj);
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
}
int code = 0;
@@ -317,7 +322,7 @@ void *taosInitTcpClient(uint32_t ip, uint16_t port, char *label, int numOfThread
SThreadObj *pThreadObj = (SThreadObj *)calloc(1, sizeof(SThreadObj));
if (pThreadObj == NULL) {
tError("TCP:%s no enough memory", label);
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
for (int j=0; jpThreadObj[j]);
free(pClientObj);
pthread_attr_destroy(&thattr);
@@ -356,11 +361,11 @@ void *taosInitTcpClient(uint32_t ip, uint16_t port, char *label, int numOfThread
pThreadObj->threadId = i;
}
if (code != 0) {
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
taosCleanUpTcpClient(pClientObj);
pClientObj = NULL;
- }
- return pClientObj;
+ }
+ return pClientObj;
}
void taosStopTcpClient(void *chandle) {
@@ -374,20 +379,20 @@ void taosStopTcpClient(void *chandle) {
void taosCleanUpTcpClient(void *chandle) {
SClientObj *pClientObj = chandle;
if (pClientObj == NULL) return;
- for (int i = 0; i < pClientObj->numOfThreads; ++i) {
+ for (int i = 0; i < pClientObj->numOfThreads; ++i) {
SThreadObj *pThreadObj= pClientObj->pThreadObj[i];
- taosStopTcpThread(pThreadObj);
+ taosStopTcpThread(pThreadObj);
}
-
+
tDebug("%s TCP client is cleaned up", pClientObj->label);
tfree(pClientObj->pThreadObj);
- tfree(pClientObj);
+ tfree(pClientObj);
}
void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uint16_t port) {
SClientObj * pClientObj = shandle;
int32_t index = atomic_load_32(&pClientObj->index) % pClientObj->numOfThreads;
- atomic_store_32(&pClientObj->index, index + 1);
+ atomic_store_32(&pClientObj->index, index + 1);
SThreadObj *pThreadObj = pClientObj->pThreadObj[index];
SOCKET fd = taosOpenTcpClientSocket(ip, port, pThreadObj->ip);
@@ -402,12 +407,12 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin
}
SFdObj *pFdObj = taosMallocFdObj(pThreadObj, fd);
-
+
if (pFdObj) {
pFdObj->thandle = thandle;
pFdObj->port = port;
pFdObj->ip = ip;
- tDebug("%s %p TCP connection to 0x%x:%hu is created, localPort:%hu FD:%p numOfFds:%d",
+ tDebug("%s %p TCP connection to 0x%x:%hu is created, localPort:%hu FD:%p numOfFds:%d",
pThreadObj->label, thandle, ip, port, localPort, pFdObj, pThreadObj->numOfFds);
} else {
tError("%s failed to malloc client FdObj(%s)", pThreadObj->label, strerror(errno));
@@ -422,7 +427,7 @@ void taosCloseTcpConnection(void *chandle) {
if (pFdObj == NULL || pFdObj->signature != pFdObj) return;
SThreadObj *pThreadObj = pFdObj->pThreadObj;
- tDebug("%s %p TCP connection will be closed, FD:%p", pThreadObj->label, pFdObj->thandle, pFdObj);
+ tDebug("%s %p TCP connection will be closed, FD:%p", pThreadObj->label, pFdObj->thandle, pFdObj);
// pFdObj->thandle = NULL;
pFdObj->closedByApp = 1;
@@ -435,7 +440,7 @@ int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chand
SThreadObj *pThreadObj = pFdObj->pThreadObj;
int ret = taosWriteMsg(pFdObj->fd, data, len);
- tTrace("%s %p TCP data is sent, FD:%p fd:%d bytes:%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, ret);
+ tTrace("%s %p TCP data is sent, FD:%p fd:%d bytes:%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, ret);
return ret;
}
@@ -458,7 +463,7 @@ static void taosReportBrokenLink(SFdObj *pFdObj) {
recvInfo.chandle = NULL;
recvInfo.connType = RPC_CONN_TCP;
(*(pThreadObj->processData))(&recvInfo);
- }
+ }
taosFreeFdObj(pFdObj);
}
@@ -473,7 +478,7 @@ static int taosReadTcpData(SFdObj *pFdObj, SRecvInfo *pInfo) {
headLen = taosReadMsg(pFdObj->fd, &rpcHead, sizeof(SRpcHead));
if (headLen != sizeof(SRpcHead)) {
tDebug("%s %p read error, FD:%p headLen:%d", pThreadObj->label, pFdObj->thandle, pFdObj, headLen);
- return -1;
+ return -1;
}
msgLen = (int32_t)htonl((uint32_t)rpcHead.msgLen);
@@ -491,14 +496,14 @@ static int taosReadTcpData(SFdObj *pFdObj, SRecvInfo *pInfo) {
retLen = taosReadMsg(pFdObj->fd, msg + headLen, leftLen);
if (leftLen != retLen) {
- tError("%s %p read error, leftLen:%d retLen:%d FD:%p",
+ tError("%s %p read error, leftLen:%d retLen:%d FD:%p",
pThreadObj->label, pFdObj->thandle, leftLen, retLen, pFdObj);
free(buffer);
return -1;
}
memcpy(msg, &rpcHead, sizeof(SRpcHead));
-
+
pInfo->msg = msg;
pInfo->msgLen = msgLen;
pInfo->ip = pFdObj->ip;
@@ -509,7 +514,7 @@ static int taosReadTcpData(SFdObj *pFdObj, SRecvInfo *pInfo) {
pInfo->connType = RPC_CONN_TCP;
if (pFdObj->closedByApp) {
- free(buffer);
+ free(buffer);
return -1;
}
@@ -557,7 +562,7 @@ static void *taosProcessTcpData(void *param) {
}
if (taosReadTcpData(pFdObj, &recvInfo) < 0) {
- shutdown(pFdObj->fd, SHUT_WR);
+ shutdown(pFdObj->fd, SHUT_WR);
continue;
}
@@ -565,7 +570,7 @@ static void *taosProcessTcpData(void *param) {
if (pFdObj->thandle == NULL) taosFreeFdObj(pFdObj);
}
- if (pThreadObj->stop) break;
+ if (pThreadObj->stop) break;
}
if (pThreadObj->pollFd >=0) {
@@ -603,7 +608,7 @@ static SFdObj *taosMallocFdObj(SThreadObj *pThreadObj, SOCKET fd) {
event.data.ptr = pFdObj;
if (epoll_ctl(pThreadObj->pollFd, EPOLL_CTL_ADD, fd, &event) < 0) {
tfree(pFdObj);
- terrno = TAOS_SYSTEM_ERROR(errno);
+ terrno = TAOS_SYSTEM_ERROR(errno);
return NULL;
}
@@ -637,7 +642,7 @@ static void taosFreeFdObj(SFdObj *pFdObj) {
pThreadObj->numOfFds--;
if (pThreadObj->numOfFds < 0)
- tError("%s %p TCP thread:%d, number of FDs is negative!!!",
+ tError("%s %p TCP thread:%d, number of FDs is negative!!!",
pThreadObj->label, pFdObj->thandle, pThreadObj->threadId);
if (pFdObj->prev) {
@@ -652,7 +657,7 @@ static void taosFreeFdObj(SFdObj *pFdObj) {
pthread_mutex_unlock(&pThreadObj->mutex);
- tDebug("%s %p TCP connection is closed, FD:%p fd:%d numOfFds:%d",
+ tDebug("%s %p TCP connection is closed, FD:%p fd:%d numOfFds:%d",
pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, pThreadObj->numOfFds);
tfree(pFdObj);
diff --git a/src/sync/src/syncTcp.c b/src/sync/src/syncTcp.c
index 22bdc7e74e..3ad9e9bba0 100644
--- a/src/sync/src/syncTcp.c
+++ b/src/sync/src/syncTcp.c
@@ -103,6 +103,11 @@ void syncCloseTcpThreadPool(void *param) {
#ifdef WINDOWS
closesocket(pPool->acceptFd);
+#elif defined(__APPLE__)
+ if (pPool->acceptFd!=-1) {
+ close(pPool->acceptFd);
+ pPool->acceptFd = -1;
+ }
#else
shutdown(pPool->acceptFd, SHUT_RD);
#endif
diff --git a/src/tfs/src/tfs.c b/src/tfs/src/tfs.c
index d942151843..7b7c9b6127 100644
--- a/src/tfs/src/tfs.c
+++ b/src/tfs/src/tfs.c
@@ -593,7 +593,7 @@ void taosGetDisk() {
tsAvailLogDirGB = (float)(diskSize.avail / unit);
}
- if (taosGetDiskSize("/tmp", &diskSize) == 0) {
+ if (taosGetDiskSize(tsTempDir, &diskSize) == 0) {
tsTotalTmpDirGB = (float)(diskSize.tsize / unit);
tsAvailTmpDirectorySpace = (float)(diskSize.avail / unit);
}
diff --git a/src/tsdb/inc/tsdbFile.h b/src/tsdb/inc/tsdbFile.h
index 132e90f8d1..f1e2422e45 100644
--- a/src/tsdb/inc/tsdbFile.h
+++ b/src/tsdb/inc/tsdbFile.h
@@ -20,6 +20,8 @@
#define TSDB_FILE_DELIMITER 0xF00AFA0F
#define TSDB_FILE_INIT_MAGIC 0xFFFFFFFF
#define TSDB_IVLD_FID INT_MIN
+#define TSDB_FILE_STATE_OK 0
+#define TSDB_FILE_STATE_BAD 1
#define TSDB_FILE_INFO(tf) (&((tf)->info))
#define TSDB_FILE_F(tf) (&((tf)->f))
@@ -31,6 +33,10 @@
#define TSDB_FILE_LEVEL(tf) TFILE_LEVEL(TSDB_FILE_F(tf))
#define TSDB_FILE_ID(tf) TFILE_ID(TSDB_FILE_F(tf))
#define TSDB_FILE_FSYNC(tf) fsync(TSDB_FILE_FD(tf))
+#define TSDB_FILE_STATE(tf) ((tf)->state)
+#define TSDB_FILE_SET_STATE(tf, s) ((tf)->state = (s))
+#define TSDB_FILE_IS_OK(tf) (TSDB_FILE_STATE(tf) == TSDB_FILE_STATE_OK)
+#define TSDB_FILE_IS_BAD(tf) (TSDB_FILE_STATE(tf) == TSDB_FILE_STATE_BAD)
typedef enum { TSDB_FILE_HEAD = 0, TSDB_FILE_DATA, TSDB_FILE_LAST, TSDB_FILE_MAX, TSDB_FILE_META } TSDB_FILE_T;
@@ -47,10 +53,11 @@ typedef struct {
SMFInfo info;
TFILE f;
int fd;
+ uint8_t state;
} SMFile;
void tsdbInitMFile(SMFile* pMFile, SDiskID did, int vid, uint32_t ver);
-void tsdbInitMFileEx(SMFile* pMFile, SMFile* pOMFile);
+void tsdbInitMFileEx(SMFile* pMFile, const SMFile* pOMFile);
int tsdbEncodeSMFile(void** buf, SMFile* pMFile);
void* tsdbDecodeSMFile(void* buf, SMFile* pMFile);
int tsdbEncodeSMFileEx(void** buf, SMFile* pMFile);
@@ -165,6 +172,7 @@ typedef struct {
SDFInfo info;
TFILE f;
int fd;
+ uint8_t state;
} SDFile;
void tsdbInitDFile(SDFile* pDFile, SDiskID did, int vid, int fid, uint32_t ver, TSDB_FILE_T ftype);
@@ -346,4 +354,14 @@ static FORCE_INLINE void tsdbGetFidKeyRange(int days, int8_t precision, int fid,
*maxKey = *minKey + days * tsMsPerDay[precision] - 1;
}
+static FORCE_INLINE bool tsdbFSetIsOk(SDFileSet* pSet) {
+ for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
+ if (TSDB_FILE_IS_BAD(TSDB_DFILE_IN_SET(pSet, ftype))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
#endif /* _TS_TSDB_FILE_H_ */
\ No newline at end of file
diff --git a/src/tsdb/src/tsdbCommit.c b/src/tsdb/src/tsdbCommit.c
index 3216b18459..a777b11186 100644
--- a/src/tsdb/src/tsdbCommit.c
+++ b/src/tsdb/src/tsdbCommit.c
@@ -52,7 +52,7 @@ static int tsdbCommitMeta(STsdbRepo *pRepo);
static int tsdbUpdateMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid, void *cont, int contLen);
static int tsdbDropMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid);
static int tsdbCommitTSData(STsdbRepo *pRepo);
-static int tsdbStartCommit(STsdbRepo *pRepo);
+static void tsdbStartCommit(STsdbRepo *pRepo);
static void tsdbEndCommit(STsdbRepo *pRepo, int eno);
static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid);
static int tsdbCreateCommitIters(SCommitH *pCommith);
@@ -84,10 +84,7 @@ static int tsdbApplyRtn(STsdbRepo *pRepo);
static int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn);
void *tsdbCommitData(STsdbRepo *pRepo) {
- if (tsdbStartCommit(pRepo) < 0) {
- tsdbError("vgId:%d failed to commit data while startting to commit since %s", REPO_ID(pRepo), tstrerror(terrno));
- goto _err;
- }
+ tsdbStartCommit(pRepo);
// Commit to update meta file
if (tsdbCommitMeta(pRepo) < 0) {
@@ -138,11 +135,15 @@ static int tsdbCommitMeta(STsdbRepo *pRepo) {
tsdbInitMFile(&mf, did, REPO_ID(pRepo), FS_TXN_VERSION(REPO_FS(pRepo)));
if (tsdbCreateMFile(&mf, true) < 0) {
+ tsdbError("vgId:%d failed to create META file since %s", REPO_ID(pRepo), tstrerror(terrno));
return -1;
}
+
+ tsdbInfo("vgId:%d meta file %s is created to commit", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(&mf));
} else {
tsdbInitMFileEx(&mf, pOMFile);
if (tsdbOpenMFile(&mf, O_WRONLY) < 0) {
+ tsdbError("vgId:%d failed to open META file since %s", REPO_ID(pRepo), tstrerror(terrno));
return -1;
}
}
@@ -154,12 +155,20 @@ static int tsdbCommitMeta(STsdbRepo *pRepo) {
if (pAct->act == TSDB_UPDATE_META) {
pCont = (SActCont *)POINTER_SHIFT(pAct, sizeof(SActObj));
if (tsdbUpdateMetaRecord(pfs, &mf, pAct->uid, (void *)(pCont->cont), pCont->len) < 0) {
+ tsdbError("vgId:%d failed to update META record, uid %" PRIu64 " since %s", REPO_ID(pRepo), pAct->uid,
+ tstrerror(terrno));
tsdbCloseMFile(&mf);
+ tsdbApplyMFileChange(&mf, pOMFile);
+ // TODO: need to reload metaCache
return -1;
}
} else if (pAct->act == TSDB_DROP_META) {
if (tsdbDropMetaRecord(pfs, &mf, pAct->uid) < 0) {
+ tsdbError("vgId:%d failed to drop META record, uid %" PRIu64 " since %s", REPO_ID(pRepo), pAct->uid,
+ tstrerror(terrno));
tsdbCloseMFile(&mf);
+ tsdbApplyMFileChange(&mf, pOMFile);
+ // TODO: need to reload metaCache
return -1;
}
} else {
@@ -168,6 +177,9 @@ static int tsdbCommitMeta(STsdbRepo *pRepo) {
}
if (tsdbUpdateMFileHeader(&mf) < 0) {
+ tsdbError("vgId:%d failed to update META file header since %s, revert it", REPO_ID(pRepo), tstrerror(terrno));
+ tsdbApplyMFileChange(&mf, pOMFile);
+ // TODO: need to reload metaCache
return -1;
}
@@ -208,6 +220,8 @@ void tsdbGetRtnSnap(STsdbRepo *pRepo, SRtn *pRtn) {
pRtn->minFid = (int)(TSDB_KEY_FID(minKey, pCfg->daysPerFile, pCfg->precision));
pRtn->midFid = (int)(TSDB_KEY_FID(midKey, pCfg->daysPerFile, pCfg->precision));
pRtn->maxFid = (int)(TSDB_KEY_FID(maxKey, pCfg->daysPerFile, pCfg->precision));
+ tsdbDebug("vgId:%d now:%" PRId64 " minKey:%" PRId64 " minFid:%d, midFid:%d, maxFid:%d", REPO_ID(pRepo), now, minKey,
+ pRtn->minFid, pRtn->midFid, pRtn->maxFid);
}
static int tsdbUpdateMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid, void *cont, int contLen) {
@@ -238,7 +252,7 @@ static int tsdbUpdateMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid, void
tsdbUpdateMFileMagic(pMFile, POINTER_SHIFT(cont, contLen - sizeof(TSCKSUM)));
SKVRecord *pRecord = taosHashGet(pfs->metaCache, (void *)&uid, sizeof(uid));
if (pRecord != NULL) {
- pMFile->info.tombSize += pRecord->size;
+ pMFile->info.tombSize += (pRecord->size + sizeof(SKVRecord));
} else {
pMFile->info.nRecords++;
}
@@ -253,7 +267,7 @@ static int tsdbDropMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid) {
SKVRecord *pRecord = taosHashGet(pfs->metaCache, (void *)(&uid), sizeof(uid));
if (pRecord == NULL) {
- tsdbError("failed to drop KV store record with key %" PRIu64 " since not find", uid);
+ tsdbError("failed to drop META record with key %" PRIu64 " since not find", uid);
return -1;
}
@@ -264,11 +278,11 @@ static int tsdbDropMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid) {
void *pBuf = buf;
tsdbEncodeKVRecord(&pBuf, &rInfo);
- if (tsdbAppendMFile(pMFile, buf, POINTER_DISTANCE(pBuf, buf), NULL) < 0) {
+ if (tsdbAppendMFile(pMFile, buf, sizeof(SKVRecord), NULL) < 0) {
return -1;
}
- pMFile->info.magic = taosCalcChecksum(pMFile->info.magic, (uint8_t *)buf, (uint32_t)POINTER_DISTANCE(pBuf, buf));
+ pMFile->info.magic = taosCalcChecksum(pMFile->info.magic, (uint8_t *)buf, sizeof(SKVRecord));
pMFile->info.nDels++;
pMFile->info.nRecords--;
pMFile->info.tombSize += (rInfo.size + sizeof(SKVRecord) * 2);
@@ -302,7 +316,12 @@ static int tsdbCommitTSData(STsdbRepo *pRepo) {
// Skip expired memory data and expired FSET
tsdbSeekCommitIter(&commith, commith.rtn.minKey);
while ((pSet = tsdbFSIterNext(&(commith.fsIter)))) {
- if (pSet->fid >= commith.rtn.minFid) break;
+ if (pSet->fid < commith.rtn.minFid) {
+ tsdbInfo("vgId:%d FSET %d on level %d disk id %d expires, remove it", REPO_ID(pRepo), pSet->fid,
+ TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet));
+ } else {
+ break;
+ }
}
// Loop to commit to each file
@@ -349,7 +368,7 @@ static int tsdbCommitTSData(STsdbRepo *pRepo) {
return 0;
}
-static int tsdbStartCommit(STsdbRepo *pRepo) {
+static void tsdbStartCommit(STsdbRepo *pRepo) {
SMemTable *pMem = pRepo->imem;
ASSERT(pMem->numOfRows > 0 || listNEles(pMem->actList) > 0);
@@ -360,7 +379,6 @@ static int tsdbStartCommit(STsdbRepo *pRepo) {
tsdbStartFSTxn(pRepo, pMem->pointsAdd, pMem->storageAdd);
pRepo->code = TSDB_CODE_SUCCESS;
- return 0;
}
static void tsdbEndCommit(STsdbRepo *pRepo, int eno) {
@@ -413,14 +431,18 @@ static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
if (pIter->pTable == NULL) continue;
if (tsdbCommitToTable(pCommith, tid) < 0) {
- // TODO: revert the file change
tsdbCloseCommitFile(pCommith, true);
+ // revert the file change
+ tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet);
return -1;
}
}
if (tsdbWriteBlockIdx(pCommith) < 0) {
+ tsdbError("vgId:%d failed to write SBlockIdx part to FSET %d since %s", REPO_ID(pRepo), fid, tstrerror(terrno));
tsdbCloseCommitFile(pCommith, true);
+ // revert the file change
+ tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet);
return -1;
}
@@ -674,7 +696,11 @@ static int tsdbCommitToTable(SCommitH *pCommith, int tid) {
TSDB_RUNLOCK_TABLE(pIter->pTable);
- if (tsdbWriteBlockInfo(pCommith) < 0) return -1;
+ if (tsdbWriteBlockInfo(pCommith) < 0) {
+ tsdbError("vgId:%d failed to write SBlockInfo part into file %s since %s", TSDB_COMMIT_REPO_ID(pCommith),
+ TSDB_FILE_FULL_NAME(TSDB_COMMIT_HEAD_FILE(pCommith)), tstrerror(terrno));
+ return -1;
+ }
return 0;
}
@@ -926,6 +952,8 @@ static int tsdbWriteBlockIdx(SCommitH *pCommih) {
if (nidx <= 0) {
// All data are deleted
+ pHeadf->info.offset = 0;
+ pHeadf->info.len = 0;
return 0;
}
@@ -1227,7 +1255,6 @@ static void tsdbResetCommitFile(SCommitH *pCommith) {
}
static void tsdbResetCommitTable(SCommitH *pCommith) {
- tdResetDataCols(pCommith->pDataCols);
taosArrayClear(pCommith->aSubBlk);
taosArrayClear(pCommith->aSupBlk);
pCommith->pTable = NULL;
@@ -1256,6 +1283,9 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid
tsdbCloseAndUnsetFSet(&(pCommith->readh));
return -1;
}
+
+ tsdbDebug("vgId:%d FSET %d at level %d disk id %d is opened to read to commit", REPO_ID(pRepo), TSDB_FSET_FID(pSet),
+ TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet));
} else {
pCommith->isRFileSet = false;
}
@@ -1266,6 +1296,8 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid
tsdbInitDFileSet(pWSet, did, REPO_ID(pRepo), fid, FS_TXN_VERSION(REPO_FS(pRepo)));
if (tsdbCreateDFileSet(pWSet, true) < 0) {
+ tsdbError("vgId:%d failed to create FSET %d at level %d disk id %d since %s", REPO_ID(pRepo),
+ TSDB_FSET_FID(pWSet), TSDB_FSET_LEVEL(pWSet), TSDB_FSET_ID(pWSet), tstrerror(terrno));
if (pCommith->isRFileSet) {
tsdbCloseAndUnsetFSet(&(pCommith->readh));
}
@@ -1274,6 +1306,9 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid
pCommith->isDFileSame = false;
pCommith->isLFileSame = false;
+
+ tsdbDebug("vgId:%d FSET %d at level %d disk id %d is created to commit", REPO_ID(pRepo), TSDB_FSET_FID(pWSet),
+ TSDB_FSET_LEVEL(pWSet), TSDB_FSET_ID(pWSet));
} else {
did.level = TSDB_FSET_LEVEL(pSet);
did.id = TSDB_FSET_ID(pSet);
@@ -1285,6 +1320,9 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid
SDFile *pWHeadf = TSDB_COMMIT_HEAD_FILE(pCommith);
tsdbInitDFile(pWHeadf, did, REPO_ID(pRepo), fid, FS_TXN_VERSION(REPO_FS(pRepo)), TSDB_FILE_HEAD);
if (tsdbCreateDFile(pWHeadf, true) < 0) {
+ tsdbError("vgId:%d failed to create file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWHeadf),
+ tstrerror(terrno));
+
if (pCommith->isRFileSet) {
tsdbCloseAndUnsetFSet(&(pCommith->readh));
return -1;
@@ -1296,7 +1334,10 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid
SDFile *pWDataf = TSDB_COMMIT_DATA_FILE(pCommith);
tsdbInitDFileEx(pWDataf, pRDataf);
if (tsdbOpenDFile(pWDataf, O_WRONLY) < 0) {
- tsdbCloseDFile(pWHeadf);
+ tsdbError("vgId:%d failed to open file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWDataf),
+ tstrerror(terrno));
+
+ tsdbCloseDFileSet(pWSet);
tsdbRemoveDFile(pWHeadf);
if (pCommith->isRFileSet) {
tsdbCloseAndUnsetFSet(&(pCommith->readh));
@@ -1313,6 +1354,9 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid
pCommith->isLFileSame = true;
if (tsdbOpenDFile(pWLastf, O_WRONLY) < 0) {
+ tsdbError("vgId:%d failed to open file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWLastf),
+ tstrerror(terrno));
+
tsdbCloseDFileSet(pWSet);
tsdbRemoveDFile(pWHeadf);
if (pCommith->isRFileSet) {
@@ -1325,6 +1369,9 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid
pCommith->isLFileSame = false;
if (tsdbCreateDFile(pWLastf, true) < 0) {
+ tsdbError("vgId:%d failed to create file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWLastf),
+ tstrerror(terrno));
+
tsdbCloseDFileSet(pWSet);
tsdbRemoveDFile(pWHeadf);
if (pCommith->isRFileSet) {
@@ -1360,7 +1407,7 @@ static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *p
if (pBlock->last) {
if (pCommith->isLFileSame && mergeRows < pCfg->minRowsPerFileBlock) return true;
} else {
- if (mergeRows < pCfg->maxRowsPerFileBlock) return true;
+ if (pCommith->isDFileSame && mergeRows <= pCfg->maxRowsPerFileBlock) return true;
}
}
@@ -1373,12 +1420,16 @@ static int tsdbApplyRtn(STsdbRepo *pRepo) {
STsdbFS * pfs = REPO_FS(pRepo);
SDFileSet *pSet;
- // Get retentioni snapshot
+ // Get retention snapshot
tsdbGetRtnSnap(pRepo, &rtn);
tsdbFSIterInit(&fsiter, pfs, TSDB_FS_ITER_FORWARD);
while ((pSet = tsdbFSIterNext(&fsiter))) {
- if (pSet->fid < rtn.minFid) continue;
+ if (pSet->fid < rtn.minFid) {
+ tsdbInfo("vgId:%d FSET %d at level %d disk id %d expires, remove it", REPO_ID(pRepo), pSet->fid,
+ TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet));
+ continue;
+ }
if (tsdbApplyRtnOnFSet(pRepo, pSet, &rtn) < 0) {
return -1;
@@ -1392,10 +1443,13 @@ static int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn) {
SDiskID did;
SDFileSet nSet;
STsdbFS * pfs = REPO_FS(pRepo);
+ int level;
ASSERT(pSet->fid >= pRtn->minFid);
- tfsAllocDisk(tsdbGetFidLevel(pSet->fid, pRtn), &(did.level), &(did.id));
+ level = tsdbGetFidLevel(pSet->fid, pRtn);
+
+ tfsAllocDisk(level, &(did.level), &(did.id));
if (did.level == TFS_UNDECIDED_LEVEL) {
terrno = TSDB_CODE_TDB_NO_AVAIL_DISK;
return -1;
@@ -1406,12 +1460,17 @@ static int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn) {
tsdbInitDFileSet(&nSet, did, REPO_ID(pRepo), pSet->fid, FS_TXN_VERSION(pfs));
if (tsdbCopyDFileSet(pSet, &nSet) < 0) {
+ tsdbError("vgId:%d failed to copy FSET %d from level %d to level %d since %s", REPO_ID(pRepo), pSet->fid,
+ TSDB_FSET_LEVEL(pSet), did.level, tstrerror(terrno));
return -1;
}
if (tsdbUpdateDFileSet(pfs, &nSet) < 0) {
return -1;
}
+
+ tsdbInfo("vgId:%d FSET %d is copied from level %d disk id %d to level %d disk id %d", REPO_ID(pRepo), pSet->fid,
+ TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet), did.level, did.id);
} else {
// On a correct level
if (tsdbUpdateDFileSet(pfs, pSet) < 0) {
diff --git a/src/tsdb/src/tsdbFS.c b/src/tsdb/src/tsdbFS.c
index b3b26bcf1f..e681508337 100644
--- a/src/tsdb/src/tsdbFS.c
+++ b/src/tsdb/src/tsdbFS.c
@@ -701,6 +701,8 @@ int tsdbLoadMetaCache(STsdbRepo *pRepo, bool recoverMeta) {
int64_t maxBufSize = 0;
SMFInfo minfo;
+ taosHashEmpty(pfs->metaCache);
+
// No meta file, just return
if (pfs->cstatus->pmf == NULL) return 0;
@@ -718,6 +720,12 @@ int tsdbLoadMetaCache(STsdbRepo *pRepo, bool recoverMeta) {
while (true) {
int64_t tsize = tsdbReadMFile(pMFile, tbuf, sizeof(SKVRecord));
if (tsize == 0) break;
+
+ if (tsize < 0) {
+ tsdbError("vgId:%d failed to read META file since %s", REPO_ID(pRepo), tstrerror(terrno));
+ return -1;
+ }
+
if (tsize < sizeof(SKVRecord)) {
tsdbError("vgId:%d failed to read %" PRIzu " bytes from file %s", REPO_ID(pRepo), sizeof(SKVRecord),
TSDB_FILE_FULL_NAME(pMFile));
@@ -840,7 +848,7 @@ static int tsdbScanRootDir(STsdbRepo *pRepo) {
continue;
}
- if (tfsIsSameFile(pf, &(pfs->cstatus->pmf->f))) {
+ if (pfs->cstatus->pmf && tfsIsSameFile(pf, &(pfs->cstatus->pmf->f))) {
continue;
}
diff --git a/src/tsdb/src/tsdbFile.c b/src/tsdb/src/tsdbFile.c
index 9a53bf4577..8124a0e3b5 100644
--- a/src/tsdb/src/tsdbFile.c
+++ b/src/tsdb/src/tsdbFile.c
@@ -33,7 +33,7 @@ static int tsdbRollBackDFile(SDFile *pDFile);
void tsdbInitMFile(SMFile *pMFile, SDiskID did, int vid, uint32_t ver) {
char fname[TSDB_FILENAME_LEN];
- TSDB_FILE_SET_CLOSED(pMFile);
+ TSDB_FILE_SET_STATE(pMFile, TSDB_FILE_STATE_OK);
memset(&(pMFile->info), 0, sizeof(pMFile->info));
pMFile->info.magic = TSDB_FILE_INIT_MAGIC;
@@ -42,7 +42,7 @@ void tsdbInitMFile(SMFile *pMFile, SDiskID did, int vid, uint32_t ver) {
tfsInitFile(TSDB_FILE_F(pMFile), did.level, did.id, fname);
}
-void tsdbInitMFileEx(SMFile *pMFile, SMFile *pOMFile) {
+void tsdbInitMFileEx(SMFile *pMFile, const SMFile *pOMFile) {
*pMFile = *pOMFile;
TSDB_FILE_SET_CLOSED(pMFile);
}
@@ -201,6 +201,7 @@ int tsdbScanAndTryFixMFile(STsdbRepo *pRepo) {
tsdbError("vgId:%d meta file %s not exit, report to upper layer to fix it", REPO_ID(pRepo),
TSDB_FILE_FULL_NAME(pMFile));
pRepo->state |= TSDB_STATE_BAD_META;
+ TSDB_FILE_SET_STATE(pMFile, TSDB_FILE_STATE_BAD);
return 0;
}
@@ -232,6 +233,7 @@ int tsdbScanAndTryFixMFile(STsdbRepo *pRepo) {
tsdbError("vgId:%d meta file %s has wrong size %" PRId64 " expected %" PRId64 ", report to upper layer to fix it",
REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile), mfstat.st_size, pMFile->info.size);
pRepo->state |= TSDB_STATE_BAD_META;
+ TSDB_FILE_SET_STATE(pMFile, TSDB_FILE_STATE_BAD);
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
return 0;
} else {
@@ -293,6 +295,8 @@ static int tsdbRollBackMFile(SMFile *pMFile) {
void tsdbInitDFile(SDFile *pDFile, SDiskID did, int vid, int fid, uint32_t ver, TSDB_FILE_T ftype) {
char fname[TSDB_FILENAME_LEN];
+ TSDB_FILE_SET_STATE(pDFile, TSDB_FILE_STATE_OK);
+
TSDB_FILE_SET_CLOSED(pDFile);
memset(&(pDFile->info), 0, sizeof(pDFile->info));
@@ -439,6 +443,7 @@ static int tsdbScanAndTryFixDFile(STsdbRepo *pRepo, SDFile *pDFile) {
tsdbError("vgId:%d data file %s not exit, report to upper layer to fix it", REPO_ID(pRepo),
TSDB_FILE_FULL_NAME(pDFile));
pRepo->state |= TSDB_STATE_BAD_DATA;
+ TSDB_FILE_SET_STATE(pDFile, TSDB_FILE_STATE_BAD);
return 0;
}
@@ -470,6 +475,7 @@ static int tsdbScanAndTryFixDFile(STsdbRepo *pRepo, SDFile *pDFile) {
tsdbError("vgId:%d data file %s has wrong size %" PRId64 " expected %" PRId64 ", report to upper layer to fix it",
REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile), dfstat.st_size, pDFile->info.size);
pRepo->state |= TSDB_STATE_BAD_DATA;
+ TSDB_FILE_SET_STATE(pDFile, TSDB_FILE_STATE_BAD);
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
return 0;
} else {
diff --git a/src/tsdb/src/tsdbMemTable.c b/src/tsdb/src/tsdbMemTable.c
index 0931b6281b..73a1270799 100644
--- a/src/tsdb/src/tsdbMemTable.c
+++ b/src/tsdb/src/tsdbMemTable.c
@@ -216,11 +216,13 @@ void *tsdbAllocBytes(STsdbRepo *pRepo, int bytes) {
}
int tsdbAsyncCommit(STsdbRepo *pRepo) {
- if (pRepo->mem == NULL) return 0;
-
tsem_wait(&(pRepo->readyToCommit));
ASSERT(pRepo->imem == NULL);
+ if (pRepo->mem == NULL) {
+ tsem_post(&(pRepo->readyToCommit));
+ return 0;
+ }
if (pRepo->code != TSDB_CODE_SUCCESS) {
tsdbWarn("vgId:%d try to commit when TSDB not in good state: %s", REPO_ID(pRepo), tstrerror(terrno));
diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c
index 40a4d5e612..17b9f8fe78 100644
--- a/src/tsdb/src/tsdbRead.c
+++ b/src/tsdb/src/tsdbRead.c
@@ -2681,7 +2681,7 @@ static int32_t tableGroupComparFn(const void *p1, const void *p2, const void *pa
f1 = (char*) TABLE_NAME(pTable1);
f2 = (char*) TABLE_NAME(pTable2);
type = TSDB_DATA_TYPE_BINARY;
- bytes = tGetTableNameColumnSchema().bytes;
+ bytes = tGetTbnameColumnSchema()->bytes;
} else {
STColumn* pCol = schemaColAt(pTableGroupSupp->pTagSchema, colIndex);
bytes = pCol->bytes;
diff --git a/src/tsdb/src/tsdbSync.c b/src/tsdb/src/tsdbSync.c
index bae4637d77..88ab973f5e 100644
--- a/src/tsdb/src/tsdbSync.c
+++ b/src/tsdb/src/tsdbSync.c
@@ -85,6 +85,7 @@ int32_t tsdbSyncRecv(void *tsdb, SOCKET socketFd) {
pRepo->state = TSDB_STATE_OK;
tsdbInitSyncH(&synch, pRepo, socketFd);
+ tsem_wait(&(pRepo->readyToCommit));
tsdbStartFSTxn(pRepo, 0, 0);
if (tsdbSyncRecvMeta(&synch) < 0) {
@@ -98,6 +99,7 @@ int32_t tsdbSyncRecv(void *tsdb, SOCKET socketFd) {
}
tsdbEndFSTxn(pRepo);
+ tsem_post(&(pRepo->readyToCommit));
tsdbDestroySyncH(&synch);
// Reload file change
@@ -107,6 +109,7 @@ int32_t tsdbSyncRecv(void *tsdb, SOCKET socketFd) {
_err:
tsdbEndFSTxnWithError(REPO_FS(pRepo));
+ tsem_post(&(pRepo->readyToCommit));
tsdbDestroySyncH(&synch);
return -1;
}
@@ -191,7 +194,8 @@ static int32_t tsdbSyncRecvMeta(SSyncH *pSynch) {
return 0;
}
- if (pLMFile == NULL || memcmp(&(pSynch->pmf->info), &(pLMFile->info), sizeof(SMFInfo)) != 0) {
+ if (pLMFile == NULL || memcmp(&(pSynch->pmf->info), &(pLMFile->info), sizeof(SMFInfo)) != 0 ||
+ TSDB_FILE_IS_BAD(pLMFile)) {
// Local has no meta file or has a different meta file, need to copy from remote
pSynch->mfChanged = true;
@@ -409,7 +413,8 @@ static int32_t tsdbSyncRecvDFileSetArray(SSyncH *pSynch) {
pSynch->pdf != NULL ? pSynch->pdf->fid : -1);
pLSet = tsdbFSIterNext(&fsiter);
} else {
- if (pLSet && pSynch->pdf && pLSet->fid == pSynch->pdf->fid && tsdbIsTowFSetSame(pLSet, pSynch->pdf)) {
+ if (pLSet && pSynch->pdf && pLSet->fid == pSynch->pdf->fid && tsdbIsTowFSetSame(pLSet, pSynch->pdf) &&
+ tsdbFSetIsOk(pLSet)) {
// Just keep local files and notify remote not to send
tsdbInfo("vgId:%d, fileset:%d is same and no need to recv", REPO_ID(pRepo), pLSet->fid);
diff --git a/src/util/inc/tarray.h b/src/util/inc/tarray.h
index c40343c557..9c3fa70b35 100644
--- a/src/util/inc/tarray.h
+++ b/src/util/inc/tarray.h
@@ -157,7 +157,7 @@ void taosArrayDestroyEx(SArray* pArray, void (*fp)(void*));
* @param pArray
* @param compar
*/
-void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*));
+void taosArraySort(SArray* pArray, __compar_fn_t comparFn);
/**
* sort string array
diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c
index dd3807797a..2752782376 100644
--- a/src/util/src/tarray.c
+++ b/src/util/src/tarray.c
@@ -220,7 +220,7 @@ void taosArrayDestroyEx(SArray* pArray, void (*fp)(void*)) {
taosArrayDestroy(pArray);
}
-void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*)) {
+void taosArraySort(SArray* pArray, __compar_fn_t compar) {
assert(pArray != NULL);
assert(compar != NULL);
diff --git a/src/util/src/tbuffer.c b/src/util/src/tbuffer.c
index 240f744ea3..a2cb32c1f4 100644
--- a/src/util/src/tbuffer.c
+++ b/src/util/src/tbuffer.c
@@ -191,7 +191,8 @@ double tbufReadDouble(SBufferReader* buf) {
// writer functions
void tbufCloseWriter( SBufferWriter* buf ) {
- (*buf->allocator)( buf->data, 0 );
+ tfree(buf->data);
+// (*buf->allocator)( buf->data, 0 ); // potential memory leak.
buf->data = NULL;
buf->pos = 0;
buf->size = 0;
diff --git a/src/util/src/tconfig.c b/src/util/src/tconfig.c
index eb96f81b33..7a92750f8f 100644
--- a/src/util/src/tconfig.c
+++ b/src/util/src/tconfig.c
@@ -134,6 +134,11 @@ static bool taosReadDirectoryConfig(SGlobalCfg *cfg, char *input_value) {
wordfree(&full_path);
+ char tmp[1025] = {0};
+ if (realpath(option, tmp) != NULL) {
+ strcpy(option, tmp);
+ }
+
int code = taosMkDir(option, 0755);
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
diff --git a/src/util/src/tref.c b/src/util/src/tref.c
index 5c7bdec01e..7d64bd1f83 100644
--- a/src/util/src/tref.c
+++ b/src/util/src/tref.c
@@ -204,7 +204,7 @@ void *taosAcquireRef(int rsetId, int64_t rid)
void *p = NULL;
if (rsetId < 0 || rsetId >= TSDB_REF_OBJECTS) {
- uTrace("rsetId:%d rid:%" PRId64 " failed to acquire, rsetId not valid", rsetId, rid);
+ //uTrace("rsetId:%d rid:%" PRId64 " failed to acquire, rsetId not valid", rsetId, rid);
terrno = TSDB_CODE_REF_INVALID_ID;
return NULL;
}
diff --git a/src/util/src/tsocket.c b/src/util/src/tsocket.c
index 7ccdca0fb1..e075876867 100644
--- a/src/util/src/tsocket.c
+++ b/src/util/src/tsocket.c
@@ -32,14 +32,27 @@ int32_t taosGetFqdn(char *fqdn) {
struct addrinfo hints = {0};
struct addrinfo *result = NULL;
+#ifdef __APPLE__
+ // on macosx, hostname -f has the form of xxx.local
+ // which will block getaddrinfo for a few seconds if AI_CANONNAME is set
+ // thus, we choose AF_INET (ipv4 for the moment) to make getaddrinfo return
+ // immediately
+ hints.ai_family = AF_INET;
+#else // __APPLE__
hints.ai_flags = AI_CANONNAME;
+#endif // __APPLE__
int32_t ret = getaddrinfo(hostname, NULL, &hints, &result);
if (!result) {
uError("failed to get fqdn, code:%d, reason:%s", ret, gai_strerror(ret));
return -1;
}
+#ifdef __APPLE__
+ // refer to comments above
+ strcpy(fqdn, hostname);
+#else // __APPLE__
strcpy(fqdn, result->ai_canonname);
+#endif // __APPLE__
freeaddrinfo(result);
return 0;
}
@@ -286,7 +299,7 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie
int32_t bufSize = 1024 * 1024;
sockFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-
+
if (sockFd <= 2) {
uError("failed to open the socket: %d (%s)", errno, strerror(errno));
taosCloseSocketNoCheck(sockFd);
diff --git a/src/util/src/ttimer.c b/src/util/src/ttimer.c
index 809b69e8ad..9833449777 100644
--- a/src/util/src/ttimer.c
+++ b/src/util/src/ttimer.c
@@ -188,11 +188,7 @@ static void removeTimer(uintptr_t id) {
}
static int64_t getMonotonicMs(void) {
-#ifdef WINDOWS
return (int64_t) getMonotonicUs() / 1000;
-#else
- return taosGetTimestampMs();
-#endif
}
static void addToWheel(tmr_obj_t* timer, uint32_t delay) {
diff --git a/src/vnode/src/vnodeCfg.c b/src/vnode/src/vnodeCfg.c
index 9b7916c8bd..03f2b11eec 100644
--- a/src/vnode/src/vnodeCfg.c
+++ b/src/vnode/src/vnodeCfg.c
@@ -34,6 +34,7 @@ static void vnodeLoadCfg(SVnodeObj *pVnode, SCreateVnodeMsg* vnodeMsg) {
pVnode->tsdbCfg.maxRowsPerFileBlock = vnodeMsg->cfg.maxRowsPerFileBlock;
pVnode->tsdbCfg.precision = vnodeMsg->cfg.precision;
pVnode->tsdbCfg.compression = vnodeMsg->cfg.compression;
+ pVnode->tsdbCfg.update = vnodeMsg->cfg.update;
pVnode->tsdbCfg.cacheLastRow = vnodeMsg->cfg.cacheLastRow;
pVnode->walCfg.walLevel = vnodeMsg->cfg.walLevel;
pVnode->walCfg.fsyncPeriod = vnodeMsg->cfg.fsyncPeriod;
@@ -227,6 +228,15 @@ int32_t vnodeReadCfg(SVnodeObj *pVnode) {
}
vnodeMsg.cfg.quorum = (int8_t)quorum->valueint;
+ cJSON *update = cJSON_GetObjectItem(root, "update");
+ if (!update || update->type != cJSON_Number) {
+ vError("vgId: %d, failed to read %s, update not found", pVnode->vgId, file);
+ vnodeMsg.cfg.update = 0;
+ vnodeMsg.cfg.vgCfgVersion = 0;
+ } else {
+ vnodeMsg.cfg.update = (int8_t)update->valueint;
+ }
+
cJSON *cacheLastRow = cJSON_GetObjectItem(root, "cacheLastRow");
if (!cacheLastRow || cacheLastRow->type != cJSON_Number) {
vError("vgId: %d, failed to read %s, cacheLastRow not found", pVnode->vgId, file);
@@ -325,6 +335,7 @@ int32_t vnodeWriteCfg(SCreateVnodeMsg *pMsg) {
len += snprintf(content + len, maxLen - len, " \"dbReplica\": %d,\n", pMsg->cfg.dbReplica);
len += snprintf(content + len, maxLen - len, " \"wals\": %d,\n", pMsg->cfg.wals);
len += snprintf(content + len, maxLen - len, " \"quorum\": %d,\n", pMsg->cfg.quorum);
+ len += snprintf(content + len, maxLen - len, " \"update\": %d,\n", pMsg->cfg.update);
len += snprintf(content + len, maxLen - len, " \"cacheLastRow\": %d,\n", pMsg->cfg.cacheLastRow);
len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
for (int32_t i = 0; i < pMsg->cfg.vgReplica; i++) {
diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c
index cd487105b8..ac9536d243 100644
--- a/src/vnode/src/vnodeMain.c
+++ b/src/vnode/src/vnodeMain.c
@@ -194,12 +194,14 @@ int32_t vnodeOpen(int32_t vgId) {
int32_t code = vnodeReadCfg(pVnode);
if (code != TSDB_CODE_SUCCESS) {
+ vError("vgId:%d, failed to read config file, set cfgVersion to 0", pVnode->vgId);
vnodeCleanUp(pVnode);
- return code;
+ return 0;
}
code = vnodeReadVersion(pVnode);
if (code != TSDB_CODE_SUCCESS) {
+ pVnode->version = 0;
vError("vgId:%d, failed to read file version, generate it from data file", pVnode->vgId);
// Allow vnode start even when read file version fails, set file version as wal version or zero
// vnodeCleanUp(pVnode);
diff --git a/tests/examples/c/epoll.c b/tests/examples/c/epoll.c
index 20ab395158..de7c5989d1 100644
--- a/tests/examples/c/epoll.c
+++ b/tests/examples/c/epoll.c
@@ -38,6 +38,8 @@
#include
#include
#include
+#include
+#include
#define D(fmt, ...) fprintf(stderr, "%s[%d]%s(): " fmt "\n", basename(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
#define A(statement, fmt, ...) do { \
@@ -56,6 +58,8 @@
##__VA_ARGS__); \
} while (0)
+#include "os.h"
+
typedef struct ep_s ep_t;
struct ep_s {
int ep;
@@ -214,7 +218,6 @@ static void* routine(void* arg) {
A(0==pthread_mutex_lock(&ep->lock), "");
ep->wakenup = 0;
A(0==pthread_mutex_unlock(&ep->lock), "");
- D("........");
continue;
}
A(ev->data.ptr, "internal logic error");
diff --git a/tests/pytest/functions/function_stddev.py b/tests/pytest/functions/function_stddev.py
index 23df415aa3..a5b2d31dd1 100644
--- a/tests/pytest/functions/function_stddev.py
+++ b/tests/pytest/functions/function_stddev.py
@@ -44,12 +44,14 @@ class TDTestCase:
# stddev verifacation
tdSql.error("select stddev(ts) from test1")
- tdSql.error("select stddev(col1) from test")
- tdSql.error("select stddev(col2) from test")
- tdSql.error("select stddev(col3) from test")
- tdSql.error("select stddev(col4) from test")
- tdSql.error("select stddev(col5) from test")
- tdSql.error("select stddev(col6) from test")
+
+ # stddev support super table now
+ # tdSql.error("select stddev(col1) from test")
+ # tdSql.error("select stddev(col2) from test")
+ # tdSql.error("select stddev(col3) from test")
+ # tdSql.error("select stddev(col4) from test")
+ # tdSql.error("select stddev(col5) from test")
+ # tdSql.error("select stddev(col6) from test")
tdSql.error("select stddev(col7) from test1")
tdSql.error("select stddev(col8) from test1")
tdSql.error("select stddev(col9) from test1")
diff --git a/tests/pytest/functions/function_stddev_restart.py b/tests/pytest/functions/function_stddev_restart.py
index ec413b94b2..837f8bb406 100644
--- a/tests/pytest/functions/function_stddev_restart.py
+++ b/tests/pytest/functions/function_stddev_restart.py
@@ -39,12 +39,6 @@ class TDTestCase:
# stddev verifacation
tdSql.error("select stddev(ts) from test1")
- tdSql.error("select stddev(col1) from test")
- tdSql.error("select stddev(col2) from test")
- tdSql.error("select stddev(col3) from test")
- tdSql.error("select stddev(col4) from test")
- tdSql.error("select stddev(col5) from test")
- tdSql.error("select stddev(col6) from test")
tdSql.error("select stddev(col7) from test1")
tdSql.error("select stddev(col8) from test1")
tdSql.error("select stddev(col9) from test1")
diff --git a/tests/pytest/functions/function_stddev_td2555.py b/tests/pytest/functions/function_stddev_td2555.py
new file mode 100644
index 0000000000..a4da7d5e29
--- /dev/null
+++ b/tests/pytest/functions/function_stddev_td2555.py
@@ -0,0 +1,91 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import sys
+import taos
+from util.log import *
+from util.cases import *
+from util.sql import *
+import numpy as np
+
+
+class TDTestCase:
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor())
+
+ self.rowNum = 100
+ self.ts = 1537146000000
+ self.clist1 = []
+ self.clist2 = []
+ self.clist3 = []
+ self.clist4 = []
+ self.clist5 = []
+ self.clist6 = []
+
+ def getData(self):
+ for i in range(tdSql.queryRows):
+ for j in range(6):
+ exec('self.clist{}.append(tdSql.queryResult[i][j+1])'.format(j+1))
+
+ def run(self):
+ tdSql.prepare()
+
+ tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
+ col7 bool, col8 binary(20), col9 nchar(20)) tags(cid int,gbid binary(20),loc nchar(20))''')
+ tdSql.execute("create table test1 using test tags(1,'beijing','北京')")
+ tdSql.execute("create table test2 using test tags(2,'shanghai','深圳')")
+ tdSql.execute("create table test3 using test tags(2,'shenzhen','深圳')")
+ tdSql.execute("create table test4 using test tags(1,'shanghai','上海')")
+ for j in range(4):
+ for i in range(self.rowNum):
+ tdSql.execute("insert into test%d values(now-%dh, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
+ % (j+1,i, i + 1, i + 1, i + 1, i + 1, i + i * 0.1, i * 1.5, i % 2, i + 1, i + 1))
+
+ # stddev verifacation
+ tdSql.error("select stddev(ts) from test")
+ tdSql.error("select stddev(col7) from test")
+ tdSql.error("select stddev(col8) from test")
+ tdSql.error("select stddev(col9) from test")
+
+ con_list = [
+ ' where cid = 1 and ts >=now - 1d and ts =now - 1d and ts =now - 1d and ts =now - 1d and ts =now - 1d and ts now-1d')
- self.checkRows(1,cmd)
+ self.checkRows(2,cmd)
def stop(self):
os.system("sudo timedatectl set-ntp true")
- time.sleep(40)
+ os.system("date -s '%s'"%(datetime.datetime.now()+datetime.timedelta(hours=1)))
+ time.sleep(5)
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
diff --git a/tests/pytest/pytest_2.sh b/tests/pytest/pytest_2.sh
index dde9f78953..4ec517a0bf 100755
--- a/tests/pytest/pytest_2.sh
+++ b/tests/pytest/pytest_2.sh
@@ -1,18 +1,18 @@
# update
-#python3 ./test.py -f update/allow_update.py
+python3 ./test.py -f update/allow_update.py
python3 ./test.py -f update/allow_update-0.py
python3 ./test.py -f update/append_commit_data.py
python3 ./test.py -f update/append_commit_last-0.py
python3 ./test.py -f update/append_commit_last.py
-#python3 ./test.py -f update/merge_commit_data.py
-#python3 ./test.py -f update/merge_commit_data-0.py
-#python3 ./test.py -f update/merge_commit_data2.py
-#python3 ./test.py -f update/merge_commit_data2_update0.py
-#python3 ./test.py -f update/merge_commit_last-0.py
-#python3 ./test.py -f update/merge_commit_last.py
-#python3 ./test.py -f update/bug_td2279.py
+python3 ./test.py -f update/merge_commit_data.py
+python3 ./test.py -f update/merge_commit_data-0.py
+python3 ./test.py -f update/merge_commit_data2.py
+python3 ./test.py -f update/merge_commit_data2_update0.py
+python3 ./test.py -f update/merge_commit_last-0.py
+python3 ./test.py -f update/merge_commit_last.py
+python3 ./test.py -f update/bug_td2279.py
# wal
python3 ./test.py -f wal/addOldWalTest.py
diff --git a/tests/pytest/query/query.py b/tests/pytest/query/query.py
index 756aa0eda9..8cec38780e 100644
--- a/tests/pytest/query/query.py
+++ b/tests/pytest/query/query.py
@@ -111,6 +111,18 @@ class TDTestCase:
tdSql.query("select * from tb where c5 = 'true' ")
tdSql.checkRows(5)
+ # For jira: https://jira.taosdata.com:18080/browse/TD-2850
+ tdSql.execute("create database 'Test' ")
+ tdSql.execute("use 'Test' ")
+ tdSql.execute("create table 'TB'(ts timestamp, 'Col1' int) tags('Tag1' int)")
+ tdSql.execute("insert into 'Tb0' using tb tags(1) values(now, 1)")
+ tdSql.query("select * from tb")
+ tdSql.checkRows(1)
+
+ tdSql.query("select * from tb0")
+ tdSql.checkRows(1)
+
+
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
diff --git a/tests/pytest/stable/insert.py b/tests/pytest/stable/insert.py
index 3d37e6726c..0ef816da8d 100644
--- a/tests/pytest/stable/insert.py
+++ b/tests/pytest/stable/insert.py
@@ -47,6 +47,40 @@ class TDTestCase:
tdSql.query("select * from db.st where dev='dev_02'")
tdSql.checkRows(1)
+ #For: https://jira.taosdata.com:18080/browse/TD-2671
+ print("==============step3")
+ tdSql.execute(
+ "create stable if not exists stb (ts timestamp, tagtype int) tags(dev nchar(50))")
+ tdSql.execute(
+ 'CREATE TABLE if not exists dev_01 using stb tags("dev_01")')
+ tdSql.execute(
+ 'CREATE TABLE if not exists dev_02 using stb tags("dev_02")')
+
+ print("==============step4")
+
+ tdSql.execute(
+ """INSERT INTO dev_01(ts, tagtype) VALUES('2020-05-13 10:00:00.000', 1),
+ ('2020-05-13 10:00:00.001', 1)
+ dev_02 VALUES('2020-05-13 10:00:00.001', 1)""")
+
+ tdSql.query("select * from db.stb where dev='dev_01'")
+ tdSql.checkRows(2)
+
+ tdSql.query("select * from db.stb where dev='dev_02'")
+ tdSql.checkRows(1)
+
+ tdSql.query("describe db.stb")
+ tdSql.checkRows(3)
+
+ tdSql.execute("alter stable db.stb add tag t1 int")
+ tdSql.query("describe db.stb")
+ tdSql.checkRows(4)
+
+ tdSql.execute("drop stable db.stb")
+ tdSql.query("show stables")
+ tdSql.checkRows(1)
+
+
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
diff --git a/tests/pytest/tools/taosdemoTest2.py b/tests/pytest/tools/taosdemoTest2.py
index 7d5627be43..4d7e871e66 100644
--- a/tests/pytest/tools/taosdemoTest2.py
+++ b/tests/pytest/tools/taosdemoTest2.py
@@ -31,10 +31,18 @@ class TDTestCase:
def insertDataAndAlterTable(self, threadID):
if(threadID == 0):
- os.system("yes | taosdemo -t %d -n %d" % (self.numberOfTables, self.numberOfRecords))
+ os.system("yes | taosdemo -t %d -n %d -x" % (self.numberOfTables, self.numberOfRecords))
if(threadID == 1):
print("use test")
tdSql.execute("use test")
+ while True:
+ print("query started")
+ tdSql.query("select * from test.t9")
+ rows = tdSql.queryRows
+ print("rows %d" % rows)
+ if(rows > 0):
+ break
+ time.sleep(1)
print("alter table test.meters add column f4 int")
tdSql.execute("alter table test.meters add column f4 int")
print("insert into test.t0 values (now, 1, 2, 3, 4)")
@@ -46,8 +54,8 @@ class TDTestCase:
t1 = threading.Thread(target=self.insertDataAndAlterTable, args=(0, ))
t2 = threading.Thread(target=self.insertDataAndAlterTable, args=(1, ))
- t1.start()
- time.sleep(2)
+ t1.start()
+ time.sleep(2)
t2.start()
t1.join()
t2.join()
diff --git a/tests/script/general/parser/dbtbnameValidate.sim b/tests/script/general/parser/dbtbnameValidate.sim
index 48c5d4a1f9..5fc67334c4 100644
--- a/tests/script/general/parser/dbtbnameValidate.sim
+++ b/tests/script/general/parser/dbtbnameValidate.sim
@@ -12,24 +12,24 @@ sql create database 'abc123'
sql create database '_ab1234'
sql create database 'ABC123'
sql create database '_ABC123'
-sql create database 'aABb123 '
-sql create database ' xyz '
-sql create database ' XYZ '
+sql_error create database 'aABb123 '
+sql_error create database ' xyz '
+sql_error create database ' XYZ '
sql use 'abc123'
sql use '_ab1234'
sql use 'ABC123'
sql use '_ABC123'
-sql use 'aABb123'
-sql use ' xyz '
-sql use ' XYZ '
+sql_error use 'aABb123'
+sql_error use ' xyz '
+sql_error use ' XYZ '
sql drop database 'abc123'
sql drop database '_ab1234'
sql_error drop database 'ABC123'
sql drop database '_ABC123'
-sql drop database 'aABb123'
-sql drop database ' xyz '
+sql_error drop database 'aABb123'
+sql_error drop database ' xyz '
sql_error drop database ' XYZ '
diff --git a/tests/script/general/parser/function.sim b/tests/script/general/parser/function.sim
index c4d9d910e4..ca020c4063 100644
--- a/tests/script/general/parser/function.sim
+++ b/tests/script/general/parser/function.sim
@@ -407,4 +407,359 @@ sql insert into tm13 values('2020-1-1 1:1:1', 0);
sql select count(*) from m1 where ts='2020-1-1 1:1:1' interval(1h) group by tbname;
if $rows != 2 then
return -1
-endi
\ No newline at end of file
+endi
+
+sql drop table m1;
+sql drop table if exists tm1;
+sql drop table if exists tm2;
+sql create table m1(ts timestamp, k double, b double, c int, d smallint, e int unsigned) tags(a int);
+sql create table tm1 using m1 tags(1);
+sql create table tm2 using m1 tags(2);
+sql insert into tm1 values('2021-01-27 22:22:39.294', 1, 10, NULL, 110, 123) ('2021-01-27 22:22:40.294', 2, 20, NULL, 120, 124) ('2021-01-27 22:22:41.294', 3, 30, NULL, 130, 125)('2021-01-27 22:22:43.294', 4, 40, NULL, 140, 126)('2021-01-27 22:22:44.294', 5, 50, NULL, 150, 127);
+sql insert into tm2 values('2021-01-27 22:22:40.688', 5, 101, NULL, 210, 321) ('2021-01-27 22:22:41.688', 5, 102, NULL, 220, 322) ('2021-01-27 22:22:42.688', 5, 103, NULL, 230, 323)('2021-01-27 22:22:43.688', 5, 104, NULL, 240, 324)('2021-01-27 22:22:44.688', 5, 105, NULL, 250, 325)('2021-01-27 22:22:45.688', 5, 106, NULL, 260, 326);
+sql select stddev(k) from m1
+if $rows != 1 then
+ return -1
+endi
+
+if $data00 != 1.378704626 then
+ return -1
+endi
+
+sql select stddev(c) from m1
+if $rows != 0 then
+ return -1
+endi
+
+sql select stddev(k), stddev(c) from m1
+if $rows != 1 then
+ return -1
+endi
+
+if $data00 != 1.378704626 then
+ return -1
+endi
+
+if $data01 != NULL then
+ return -1;
+endi
+
+sql select stddev(b),stddev(b),stddev(k) from m1;
+if $rows != 1 then
+ return -1
+endi
+
+if $data00 != 37.840465463 then
+ return -1
+endi
+
+if $data01 != 37.840465463 then
+ return -1
+endi
+
+if $data02 != 1.378704626 then
+ return -1
+endi
+
+sql select stddev(k), stddev(b) from m1 group by a
+if $rows != 2 then
+ return -1
+endi
+
+if $data00 != 1.414213562 then
+ return -1
+endi
+
+if $data01 != 14.142135624 then
+ return -1
+endi
+
+if $data02 != 1 then
+ return -1
+endi
+
+if $data10 != 0.000000000 then
+ return -1
+endi
+
+if $data11 != 1.707825128 then
+ return -1
+endi
+
+if $data12 != 2 then
+ return -1
+endi
+
+sql select stddev(k), stddev(b) from m1 where a= 1 group by a
+if $rows != 1 then
+ return -1
+endi
+
+if $data00 != 1.414213562 then
+ return -1
+endi
+
+if $data01 != 14.142135624 then
+ return -1
+endi
+
+if $data02 != 1 then
+ return -1
+endi
+
+sql select stddev(k), stddev(b) from m1 group by tbname
+if $rows != 2 then
+ return -1
+endi
+
+if $data00 != 1.414213562 then
+ return -1
+endi
+
+if $data01 != 14.142135624 then
+ return -1
+endi
+
+if $data02 != @tm1@ then
+ return -1
+endi
+
+if $data10 != 0.000000000 then
+ return -1
+endi
+
+if $data11 != 1.707825128 then
+ return -1
+endi
+
+if $data12 != @tm2@ then
+ return -1
+endi
+
+sql select stddev(k), stddev(b) from m1 group by tbname,a
+if $rows != 2 then
+ return -1
+endi
+
+sql select stddev(k), stddev(b), stddev(c) from m1 group by tbname,a
+if $rows != 2 then
+ return -1
+endi
+
+if $data00 != 1.414213562 then
+ return -1
+endi
+
+if $data01 != 14.142135624 then
+ return -1
+endi
+
+if $data02 != NULL then
+ return -1
+endi
+
+if $data03 != @tm1@ then
+ return -1
+endi
+
+if $data04 != 1 then
+ return -1
+endi
+
+if $data10 != 0.000000000 then
+ return -1
+endi
+
+if $data11 != 1.707825128 then
+ return -1
+endi
+
+if $data12 != NULL then
+ return -1
+endi
+
+if $data13 != @tm2@ then
+ return -1
+endi
+
+if $data14 != 2 then
+ return -1
+endi
+
+sql select stddev(k), stddev(b), stddev(c) from m1 interval(10s) group by tbname,a
+if $rows != 3 then
+ return -1
+endi
+
+if $data01 != 0.000000000 then
+ return -1
+endi
+
+if $data02 != 0.000000000 then
+ return -1
+endi
+
+if $data03 != NULL then
+ return -1
+endi
+
+if $data04 != @tm1@ then
+ return -1
+endi
+
+if $data05 != 1 then
+ return -1
+endi
+
+if $data11 != 1.118033989 then
+ return -1
+endi
+
+if $data12 != 11.180339887 then
+ return -1
+endi
+
+if $data13 != NULL then
+ return -1
+endi
+
+if $data14 != @tm1@ then
+ return -1
+endi
+
+if $data22 != 1.707825128 then
+ return -1
+endi
+
+if $data23 != NULL then
+ return -1
+endi
+
+if $data24 != @tm2@ then
+ return -1
+endi
+
+if $data25 != 2 then
+ return -1
+endi
+
+sql select count(*), first(b), stddev(b), stddev(c) from m1 interval(10s) group by a
+if $rows != 3 then
+ return -1
+endi
+
+if $data00 != @21-01-27 22:22:30.000@ then
+ return -1
+endi
+
+if $data01 != 1 then
+ return -1
+endi
+
+if $data02 != 10.000000000 then
+ return -1
+endi
+
+if $data03 != 0.000000000 then
+ return -1
+endi
+
+if $data04 != NULL then
+ return -1
+endi
+
+if $data05 != 1 then
+ return -1
+endi
+
+if $data12 != 20.000000000 then
+ return -1
+endi
+
+if $data13 != 11.180339887 then
+ return -1
+endi
+
+if $data14 != NULL then
+ return -1
+endi
+
+if $data23 != 1.707825128 then
+ return -1
+endi
+
+sql select count(*), first(b), stddev(b), stddev(c) from m1 interval(10s) group by tbname,a
+if $rows != 3 then
+ return -1
+endi
+
+if $data23 != 1.707825128 then
+ return -1
+endi
+
+if $data25 != @tm2@ then
+ return -1
+endi
+
+sql select count(*), stddev(b), stddev(b)+20, stddev(c) from m1 interval(10s) group by tbname,a
+if $rows != 3 then
+ return -1
+endi
+
+if $data02 != 0.000000000 then
+ return -1
+endi
+
+if $data03 != 20.000000000 then
+ return -1
+endi
+
+if $data13 != 31.180339887 then
+ return -1
+endi
+
+if $data14 != NULL then
+ return -1
+endi
+
+sql select count(*), first(b), stddev(b)+first(b), stddev(c) from m1 interval(10s) group by tbname,a
+if $rows != 3 then
+ return -1
+endi
+
+if $data02 != 10.000000000 then
+ return -1
+endi
+
+if $data03 != 10.000000000 then
+ return -1
+endi
+
+if $data12 != 20.000000000 then
+ return -1
+endi
+
+if $data13 != 31.180339887 then
+ return -1
+endi
+
+if $data22 != 101.000000000 then
+ return -1
+endi
+
+if $data23 != 102.707825128 then
+ return -1
+endi
+
+sql select stddev(e),stddev(k) from m1 where a=1
+if $rows != 1 then
+ return -1
+endi
+
+if $data00 != 1.414213562 then
+ return -1
+endi
+
+if $data01 != 1.414213562 then
+ return -1
+endi
diff --git a/tests/script/general/parser/testSuite.sim b/tests/script/general/parser/testSuite.sim
index 1868ff9683..1dfdf9aac7 100644
--- a/tests/script/general/parser/testSuite.sim
+++ b/tests/script/general/parser/testSuite.sim
@@ -1,84 +1,84 @@
-run general/parser/alter.sim
-sleep 100
-run general/parser/alter1.sim
-sleep 100
-run general/parser/alter_stable.sim
-sleep 100
-run general/parser/auto_create_tb.sim
-sleep 100
-run general/parser/auto_create_tb_drop_tb.sim
-sleep 100
-run general/parser/col_arithmetic_operation.sim
-sleep 100
-run general/parser/columnValue.sim
-sleep 100
-run general/parser/commit.sim
-sleep 100
-run general/parser/create_db.sim
-sleep 100
-run general/parser/create_mt.sim
-sleep 100
-run general/parser/create_tb.sim
-sleep 100
-run general/parser/dbtbnameValidate.sim
-sleep 100
-run general/parser/fill.sim
-sleep 100
-run general/parser/fill_stb.sim
-sleep 100
-#run general/parser/fill_us.sim #
-sleep 100
-run general/parser/first_last.sim
-sleep 100
-run general/parser/import_commit1.sim
-sleep 100
-run general/parser/import_commit2.sim
-sleep 100
-run general/parser/import_commit3.sim
-sleep 100
-#run general/parser/import_file.sim
-sleep 100
-run general/parser/insert_tb.sim
-sleep 100
-run general/parser/tags_dynamically_specifiy.sim
-sleep 100
-run general/parser/interp.sim
-sleep 100
-run general/parser/lastrow.sim
-sleep 100
-run general/parser/limit.sim
-sleep 100
-run general/parser/limit1.sim
-sleep 100
-run general/parser/limit1_tblocks100.sim
-sleep 100
-run general/parser/limit2.sim
-sleep 100
-run general/parser/mixed_blocks.sim
-sleep 100
-run general/parser/nchar.sim
-sleep 100
-run general/parser/null_char.sim
-sleep 100
-run general/parser/selectResNum.sim
-sleep 100
-run general/parser/select_across_vnodes.sim
-sleep 100
-run general/parser/select_from_cache_disk.sim
-sleep 100
-run general/parser/set_tag_vals.sim
-sleep 100
-run general/parser/single_row_in_tb.sim
-sleep 100
-run general/parser/slimit.sim
-sleep 100
-run general/parser/slimit1.sim
-sleep 100
-run general/parser/slimit_alter_tags.sim
-sleep 100
-run general/parser/tbnameIn.sim
-sleep 100
-run general/parser/slimit_alter_tags.sim # persistent failed
+#run general/parser/alter.sim
+#sleep 100
+#run general/parser/alter1.sim
+#sleep 100
+#run general/parser/alter_stable.sim
+#sleep 100
+#run general/parser/auto_create_tb.sim
+#sleep 100
+#run general/parser/auto_create_tb_drop_tb.sim
+#sleep 100
+#run general/parser/col_arithmetic_operation.sim
+#sleep 100
+#run general/parser/columnValue.sim
+#sleep 100
+#run general/parser/commit.sim
+#sleep 100
+#run general/parser/create_db.sim
+#sleep 100
+#run general/parser/create_mt.sim
+#sleep 100
+#run general/parser/create_tb.sim
+#sleep 100
+#run general/parser/dbtbnameValidate.sim
+#sleep 100
+#run general/parser/fill.sim
+#sleep 100
+#run general/parser/fill_stb.sim
+#sleep 100
+##run general/parser/fill_us.sim #
+#sleep 100
+#run general/parser/first_last.sim
+#sleep 100
+#run general/parser/import_commit1.sim
+#sleep 100
+#run general/parser/import_commit2.sim
+#sleep 100
+#run general/parser/import_commit3.sim
+#sleep 100
+##run general/parser/import_file.sim
+#sleep 100
+#run general/parser/insert_tb.sim
+#sleep 100
+#run general/parser/tags_dynamically_specifiy.sim
+#sleep 100
+#run general/parser/interp.sim
+#sleep 100
+#run general/parser/lastrow.sim
+#sleep 100
+#run general/parser/limit.sim
+#sleep 100
+#run general/parser/limit1.sim
+#sleep 100
+#run general/parser/limit1_tblocks100.sim
+#sleep 100
+#run general/parser/limit2.sim
+#sleep 100
+#run general/parser/mixed_blocks.sim
+#sleep 100
+#run general/parser/nchar.sim
+#sleep 100
+#run general/parser/null_char.sim
+#sleep 100
+#run general/parser/selectResNum.sim
+#sleep 100
+#run general/parser/select_across_vnodes.sim
+#sleep 100
+#run general/parser/select_from_cache_disk.sim
+#sleep 100
+#run general/parser/set_tag_vals.sim
+#sleep 100
+#run general/parser/single_row_in_tb.sim
+#sleep 100
+#run general/parser/slimit.sim
+#sleep 100
+#run general/parser/slimit1.sim
+#sleep 100
+#run general/parser/slimit_alter_tags.sim
+#sleep 100
+#run general/parser/tbnameIn.sim
+#sleep 100
+#run general/parser/slimit_alter_tags.sim # persistent failed
sleep 100
run general/parser/join.sim
sleep 100
@@ -106,4 +106,4 @@ run general/parser/sliding.sim
sleep 100
run general/parser/function.sim
sleep 100
-run general/parse/stableOp.sim
+run general/parser/stableOp.sim
diff --git a/tests/script/wtest.bat b/tests/script/wtest.bat
index 0b5cdda527..9ed58a90d1 100644
--- a/tests/script/wtest.bat
+++ b/tests/script/wtest.bat
@@ -44,10 +44,10 @@ echo serverPort 7100 >> %TAOS_CFG%
echo logDir %LOG_DIR% >> %TAOS_CFG%
echo scriptDir %SCRIPT_DIR% >> %TAOS_CFG%
echo numOfLogLines 100000000 >> %TAOS_CFG%
-echo rpcDebugFlag 143 >> %TAOS_CFG%
+echo rpcDebugFlag 135 >> %TAOS_CFG%
echo tmrDebugFlag 131 >> %TAOS_CFG%
-echo cDebugFlag 143 >> %TAOS_CFG%
-echo udebugFlag 143 >> %TAOS_CFG%
+echo cDebugFlag 135 >> %TAOS_CFG%
+echo udebugFlag 135 >> %TAOS_CFG%
echo wal 0 >> %TAOS_CFG%
echo asyncLog 0 >> %TAOS_CFG%
echo locale en_US.UTF-8 >> %TAOS_CFG%
diff --git a/tests/test-all.sh b/tests/test-all.sh
index 13efbec7a2..2374750be4 100755
--- a/tests/test-all.sh
+++ b/tests/test-all.sh
@@ -6,15 +6,15 @@ GREEN='\033[1;32m'
GREEN_DARK='\033[0;32m'
GREEN_UNDERLINE='\033[4;32m'
NC='\033[0m'
-function git_branch {
- branch="`git branch 2>/dev/null | grep "^\*" | sed -e "s/^\*\ //"`"
- if [ "${branch}" != "" ];then
- if [ "${branch}" = "(no branch)" ];then
- branch="(`git rev-parse --short HEAD`...)"
- fi
- branch=(${branch////_})
- echo "$branch"
- fi
+
+function dohavecore(){
+ corefile=`find $corepath -mmin 1`
+ if [ -n "$corefile" ];then
+ echo 'taosd or taos has generated core'
+ if [[ $1 == 1 ]];then
+ exit 8
+ fi
+ fi
}
function runSimCaseOneByOne {
while read -r line; do
@@ -42,6 +42,7 @@ function runSimCaseOneByOne {
# fi
end_time=`date +%s`
echo execution time of $case was `expr $end_time - $start_time`s. | tee -a out.log
+ dohavecore 0
fi
done < $1
}
@@ -69,14 +70,15 @@ function runSimCaseOneByOnefq {
out_log=`tail -1 out.log `
if [[ $out_log =~ 'failed' ]];then
if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]]; then
- cp -r ../../../sim ~/sim_$(git_branch)_`date "+%Y_%m_%d_%H:%M:%S"`
+ cp -r ../../../sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S"`
else
- cp -r ../../sim ~/sim_$(git_branch)_`date "+%Y_%m_%d_%H:%M:%S" `
+ cp -r ../../sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S" `
fi
exit 8
fi
end_time=`date +%s`
echo execution time of $case was `expr $end_time - $start_time`s. | tee -a out.log
+ dohavecore 1
fi
done < $1
}
@@ -105,6 +107,7 @@ function runPyCaseOneByOne {
else
$line > /dev/null 2>&1
fi
+ dohavecore 0
fi
done < $1
}
@@ -126,13 +129,14 @@ function runPyCaseOneByOnefq {
end_time=`date +%s`
out_log=`tail -1 pytest-out.log `
if [[ $out_log =~ 'failed' ]];then
- cp -r ../../sim ~/sim_$(git_branch)_`date "+%Y_%m_%d_%H:%M:%S" `
+ cp -r ../../sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S" `
exit 8
fi
echo execution time of $case was `expr $end_time - $start_time`s. | tee -a pytest-out.log
else
$line > /dev/null 2>&1
fi
+ dohavecore 1
fi
done < $1
}
@@ -140,7 +144,7 @@ totalFailed=0
totalPyFailed=0
tests_dir=`pwd`
-
+corepath=`grep -oP '.*(?=core_)' /proc/sys/kernel/core_pattern||grep -oP '.*(?=core-)' /proc/sys/kernel/core_pattern`
if [ "$2" != "python" ]; then
echo "### run TSIM test case ###"
cd $tests_dir/script