diff --git a/include/common/tmsgcb.h b/include/common/tmsgcb.h
index 4002db06ea9d72e084ef28045ed233e779330b75..b6c96bb2d16e7b3b4bd644aa30a6e825f8c98250 100644
--- a/include/common/tmsgcb.h
+++ b/include/common/tmsgcb.h
@@ -57,6 +57,7 @@ typedef struct {
RegisterBrokenLinkArgFp registerBrokenLinkArgFp;
ReleaseHandleFp releaseHandleFp;
ReportStartup reportStartupFp;
+ void* clientRpc;
} SMsgCb;
void tmsgSetDefaultMsgCb(const SMsgCb* pMsgCb);
diff --git a/include/common/tname.h b/include/common/tname.h
index ffa4f8f253a57c5d9897a7cc0f1306998b2857a5..ae2dc32335d8e33692a3c05c773d539e31c8a669 100644
--- a/include/common/tname.h
+++ b/include/common/tname.h
@@ -17,6 +17,7 @@
#define _TD_COMMON_NAME_H_
#include "tdef.h"
+#include "tarray.h"
#ifdef __cplusplus
extern "C" {
@@ -62,6 +63,18 @@ int32_t tNameSetAcctId(SName* dst, int32_t acctId);
bool tNameDBNameEqual(SName* left, SName* right);
+typedef struct {
+ // input
+ SArray *tags; // element is SSmlKV
+ const char *sTableName; // super table name
+ uint8_t sTableNameLen; // the length of super table name
+
+ // output
+ char *childTableName; // must have size of TSDB_TABLE_NAME_LEN;
+ uint64_t uid; // child table uid, may be useful
+} RandTableName;
+
+void buildChildTableName(RandTableName *rName);
#ifdef __cplusplus
}
diff --git a/include/libs/executor/executor.h b/include/libs/executor/executor.h
index e0fce2aa6a7d2d7da21d11c5989486d4352c9b34..162b6fb2ed24539435dc3e4573b52b0a9759a5a4 100644
--- a/include/libs/executor/executor.h
+++ b/include/libs/executor/executor.h
@@ -22,6 +22,7 @@ extern "C" {
#include "query.h"
#include "tcommon.h"
+#include "tmsgcb.h"
typedef void* qTaskInfo_t;
typedef void* DataSinkHandle;
@@ -29,11 +30,12 @@ struct SRpcMsg;
struct SSubplan;
typedef struct SReadHandle {
- void* reader;
- void* meta;
- void* config;
- void* vnode;
- void* mnd;
+ void* reader;
+ void* meta;
+ void* config;
+ void* vnode;
+ void* mnd;
+ SMsgCb* pMsgCb;
} SReadHandle;
#define STREAM_DATA_TYPE_SUBMIT_BLOCK 0x1
diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h
index 4a37283ee57a0d2d5faaf552f90bc43766fa535b..40f8a9e38374fb5f08be14350504b299e36d081e 100644
--- a/include/libs/function/functionMgt.h
+++ b/include/libs/function/functionMgt.h
@@ -154,6 +154,7 @@ bool fmIsWindowClauseFunc(int32_t funcId);
bool fmIsSpecialDataRequiredFunc(int32_t funcId);
bool fmIsDynamicScanOptimizedFunc(int32_t funcId);
bool fmIsMultiResFunc(int32_t funcId);
+bool fmIsRepeatScanFunc(int32_t funcId);
bool fmIsUserDefinedFunc(int32_t funcId);
typedef enum EFuncDataRequired {
@@ -170,7 +171,7 @@ int32_t fmGetScalarFuncExecFuncs(int32_t funcId, SScalarFuncExecFuncs* pFpSet);
int32_t fmGetUdafExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet);
int32_t fmSetInvertFunc(int32_t funcId, SFuncExecFuncs* pFpSet);
int32_t fmSetNormalFunc(int32_t funcId, SFuncExecFuncs* pFpSet);
-bool fmIsInvertible(int32_t funcId);
+bool fmIsInvertible(int32_t funcId);
#ifdef __cplusplus
}
diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h
index ad8a472d08462682e58b6b952f8837c378b60566..702dd50df55e6fa98d555a796b8570eaf1e04883 100644
--- a/include/libs/nodes/nodes.h
+++ b/include/libs/nodes/nodes.h
@@ -206,6 +206,7 @@ typedef enum ENodeType {
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE,
QUERY_NODE_PHYSICAL_PLAN_SORT,
QUERY_NODE_PHYSICAL_PLAN_INTERVAL,
+ QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL,
QUERY_NODE_PHYSICAL_PLAN_FILL,
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW,
QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW,
diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h
index a756217c7a95a94a9bdb1af762c1fb4c8ee67e33..d0d10b27613fe58d9f47360e779c6b55146c8253 100644
--- a/include/libs/nodes/plannodes.h
+++ b/include/libs/nodes/plannodes.h
@@ -274,6 +274,8 @@ typedef struct SIntervalPhysiNode {
int8_t slidingUnit;
} SIntervalPhysiNode;
+typedef SIntervalPhysiNode SStreamIntervalPhysiNode;
+
typedef struct SFillPhysiNode {
SPhysiNode node;
EFillMode mode;
diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h
index 91c80f6cf52db5c99fad8e2b413a39face2f3515..0a835dae83fd636874206112dce950c0b0d48462 100644
--- a/include/libs/nodes/querynodes.h
+++ b/include/libs/nodes/querynodes.h
@@ -233,6 +233,7 @@ typedef struct SSelectStmt {
uint8_t precision;
bool isEmptyResult;
bool hasAggFuncs;
+ bool hasRepeatScanFuncs;
bool isTimeOrderQuery;
} SSelectStmt;
diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h
index c1e53fa80524922648dc85faf26e2b5820f2b308..cac60c33bb31bae252928795f5e615cbc482d26d 100644
--- a/include/libs/qcom/query.h
+++ b/include/libs/qcom/query.h
@@ -24,6 +24,7 @@ extern "C" {
#include "thash.h"
#include "tlog.h"
#include "tmsg.h"
+#include "tmsgcb.h"
typedef enum {
JOB_TASK_STATUS_NULL = 0,
@@ -149,7 +150,8 @@ int32_t cleanupTaskQueue();
*/
int32_t taosAsyncExec(__async_exec_fn_t execFn, void* execParam, int32_t* code);
-int32_t asyncSendMsgToServerExt(void* pTransporter, SEpSet* epSet, int64_t* pTransporterId, const SMsgSendInfo* pInfo, bool persistHandle, void *ctx);
+int32_t asyncSendMsgToServerExt(void* pTransporter, SEpSet* epSet, int64_t* pTransporterId, const SMsgSendInfo* pInfo,
+ bool persistHandle, void* ctx);
/**
* Asynchronously send message to server, after the response received, the callback will be incured.
diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c
index 2a0e85092b522dc8c2945405717db9c9aa6745c4..15d150086033e6044e0ee2a110579dbce26579fc 100644
--- a/source/client/src/clientSml.c
+++ b/source/client/src/clientSml.c
@@ -15,6 +15,7 @@
#include "tcommon.h"
#include "catalog.h"
#include "clientInt.h"
+#include "tname.h"
//=================================================================================================
#define SPACE ' '
@@ -97,6 +98,21 @@ typedef struct {
char *buf;
} SSmlMsgBuf;
+typedef struct {
+ int32_t code;
+ int32_t lineNum;
+
+ int32_t numOfSTables;
+ int32_t numOfCTables;
+ int32_t numOfCreateSTables;
+
+ int64_t parseTime;
+ int64_t schemaTime;
+ int64_t insertBindTime;
+ int64_t insertRpcTime;
+ int64_t endTime;
+} SSmlCostInfo;
+
typedef struct {
uint64_t id;
@@ -114,6 +130,7 @@ typedef struct {
SRequestObj *pRequest;
SQuery *pQuery;
+ SSmlCostInfo cost;
int32_t affectedRows;
SSmlMsgBuf msgBuf;
SHashObj *dumplicateKey; // for dumplicate key
@@ -147,45 +164,6 @@ static int32_t smlBuildInvalidDataMsg(SSmlMsgBuf* pBuf, const char *msg1, const
return TSDB_CODE_SML_INVALID_DATA;
}
-static int smlCompareKv(const void* p1, const void* p2) {
- SSmlKv* kv1 = *(SSmlKv**)p1;
- SSmlKv* kv2 = *(SSmlKv**)p2;
- int32_t kvLen1 = kv1->keyLen;
- int32_t kvLen2 = kv2->keyLen;
- int32_t res = strncasecmp(kv1->key, kv2->key, TMIN(kvLen1, kvLen2));
- if (res != 0) {
- return res;
- } else {
- return kvLen1-kvLen2;
- }
-}
-
-static void smlBuildChildTableName(SSmlTableInfo *tags) {
- int32_t size = taosArrayGetSize(tags->tags);
- ASSERT(size > 0);
- taosArraySort(tags->tags, smlCompareKv);
-
- SStringBuilder sb = {0};
- taosStringBuilderAppendStringLen(&sb, tags->sTableName, tags->sTableNameLen);
- for (int j = 0; j < size; ++j) {
- SSmlKv *tagKv = taosArrayGetP(tags->tags, j);
- taosStringBuilderAppendStringLen(&sb, tagKv->key, tagKv->keyLen);
- taosStringBuilderAppendStringLen(&sb, tagKv->value, tagKv->valueLen);
- }
- size_t len = 0;
- char* keyJoined = taosStringBuilderGetResult(&sb, &len);
- T_MD5_CTX context;
- tMD5Init(&context);
- tMD5Update(&context, (uint8_t *)keyJoined, (uint32_t)len);
- tMD5Final(&context);
- uint64_t digest1 = *(uint64_t*)(context.digest);
- //uint64_t digest2 = *(uint64_t*)(context.digest + 8);
- //snprintf(tags->childTableName, TSDB_TABLE_NAME_LEN, "t_%016"PRIx64"%016"PRIx64, digest1, digest2);
- snprintf(tags->childTableName, TSDB_TABLE_NAME_LEN, "t_%016"PRIx64, digest1);
- taosStringBuilderDestroy(&sb);
- tags->uid = digest1;
-}
-
static int32_t smlGenerateSchemaAction(SSchema* pointColField, SHashObj* dbAttrHash, SArray* dbAttrArray, bool isTag, char sTableName[],
SSchemaAction* action, bool* actionNeeded, SSmlHandle* info) {
// char fieldName[TSDB_COL_NAME_LEN] = {0};
@@ -444,6 +422,7 @@ static int32_t smlModifyDBSchemas(SSmlHandle* info) {
uError("SML:0x%"PRIx64" catalogGetSTableMeta failed. super table name %s", info->id, schemaAction.createSTable.sTableName);
return code;
}
+ info->cost.numOfCreateSTables++;
}else if (code == TSDB_CODE_SUCCESS) {
} else {
uError("SML:0x%"PRIx64" load table meta error: %s", info->id, tstrerror(code));
@@ -926,20 +905,6 @@ static bool smlParseValue(SSmlKv *pVal, SSmlMsgBuf *msg) {
return false;
}
-static bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlHandle* info) {
- char *val = NULL;
- val = taosHashGet(pHash, key, strlen(key));
- if (val) {
- uError("SML:0x%"PRIx64" Duplicate key detected:%s", info->id, key);
- return true;
- }
-
- uint8_t dummy_val = 0;
- taosHashPut(pHash, key, strlen(key), &dummy_val, sizeof(uint8_t));
-
- return false;
-}
-
static int32_t smlParseString(const char* sql, SSmlLineInfo *elements, SSmlMsgBuf *msg){
if(!sql) return TSDB_CODE_SML_INVALID_DATA;
while (*sql != '\0') { // jump the space at the begining
@@ -1546,8 +1511,10 @@ static int32_t smlParseLine(SSmlHandle* info, const char* sql) {
tinfo->sTableName = elements.measure;
tinfo->sTableNameLen = elements.measureLen;
- smlBuildChildTableName(tinfo);
- uDebug("SML:0x%"PRIx64" child table name: %s", info->id, tinfo->childTableName);
+ RandTableName rName = {.tags=tinfo->tags, .sTableName=tinfo->sTableName, .sTableNameLen=tinfo->sTableNameLen,
+ .childTableName=tinfo->childTableName};
+ buildChildTableName(&rName);
+ tinfo->uid = rName.uid;
SSmlSTableMeta** tableMeta = taosHashGet(info->superTables, elements.measure, elements.measureLen);
if(tableMeta){ // update meta
@@ -1604,7 +1571,7 @@ static void smlDestroyInfo(SSmlHandle* info){
static SSmlHandle* smlBuildSmlInfo(TAOS* taos, SRequestObj* request, SMLProtocolType protocol, int8_t precision, bool dataFormat){
int32_t code = TSDB_CODE_SUCCESS;
- SSmlHandle* info = taosMemoryMalloc(sizeof(SSmlHandle));
+ SSmlHandle* info = taosMemoryCalloc(1, sizeof(SSmlHandle));
if (NULL == info) {
return NULL;
}
@@ -1699,12 +1666,23 @@ static int32_t smlInsertData(SSmlHandle* info) {
}
smlBuildOutput(info->exec, info->pVgHash);
+ info->cost.insertRpcTime = taosGetTimestampUs();
+
launchQueryImpl(info->pRequest, info->pQuery, TSDB_CODE_SUCCESS, true);
info->affectedRows = taos_affected_rows(info->pRequest);
return info->pRequest->code;
}
+static void smlPrintStatisticInfo(SSmlHandle *info){
+ uError("SML:0x%"PRIx64" smlInsertLines result, code:%d,lineNum:%d,stable num:%d,ctable num:%d,create stable num:%d \
+ parse cost:%"PRId64",schema cost:%"PRId64",bind cost:%"PRId64",rpc cost:%"PRId64",total cost:%"PRId64"", info->id, info->cost.code,
+ info->cost.lineNum, info->cost.numOfSTables, info->cost.numOfCTables, info->cost.numOfCreateSTables,
+ info->cost.schemaTime-info->cost.parseTime, info->cost.insertBindTime-info->cost.schemaTime,
+ info->cost.insertRpcTime-info->cost.insertBindTime, info->cost.endTime-info->cost.insertRpcTime,
+ info->cost.endTime-info->cost.parseTime);
+}
+
static int smlInsertLines(SSmlHandle *info, char* lines[], int numLines) {
int32_t code = TSDB_CODE_SUCCESS;
@@ -1714,6 +1692,7 @@ static int smlInsertLines(SSmlHandle *info, char* lines[], int numLines) {
goto cleanup;
}
+ info->cost.parseTime = taosGetTimestampUs();
for (int32_t i = 0; i < numLines; ++i) {
code = smlParseLine(info, lines[i]);
if (code != TSDB_CODE_SUCCESS) {
@@ -1721,24 +1700,29 @@ static int smlInsertLines(SSmlHandle *info, char* lines[], int numLines) {
goto cleanup;
}
}
- uDebug("SML:0x%"PRIx64" smlInsertLines parse success. tables %d", info->id, taosHashGetSize(info->childTables));
- uDebug("SML:0x%"PRIx64" smlInsertLines parse success. super tables %d", info->id, taosHashGetSize(info->superTables));
+ info->cost.lineNum = numLines;
+ info->cost.numOfSTables = taosHashGetSize(info->superTables);
+ info->cost.numOfCTables = taosHashGetSize(info->childTables);
+
+ info->cost.schemaTime = taosGetTimestampUs();
code = smlModifyDBSchemas(info);
if (code != 0) {
uError("SML:0x%"PRIx64" smlModifyDBSchemas error : %s", info->id, tstrerror(code));
goto cleanup;
}
+ info->cost.insertBindTime = taosGetTimestampUs();
code = smlInsertData(info);
if (code != 0) {
uError("SML:0x%"PRIx64" smlInsertData error : %s", info->id, tstrerror(code));
goto cleanup;
}
-
- uDebug("SML:0x%"PRIx64" smlInsertLines finish inserting %d lines.", info->id, numLines);
+ info->cost.endTime = taosGetTimestampUs();
cleanup:
+ info->cost.code = code;
+ smlPrintStatisticInfo(info);
return code;
}
@@ -1790,7 +1774,6 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr
}
smlDestroyInfo(info);
-end:
return (TAOS_RES*)request;
}
diff --git a/source/common/src/tname.c b/source/common/src/tname.c
index f4755f5b5e4e924ed0c917701430c97c4e08f5ef..62ba4bfb792e34a2c3d45fb300bcf0ead865aa97 100644
--- a/source/common/src/tname.c
+++ b/source/common/src/tname.c
@@ -15,6 +15,8 @@
#define _DEFAULT_SOURCE
#include "tname.h"
+#include "tcommon.h"
+#include "tstrbuild.h"
#define VALID_NAME_TYPE(x) ((x) == TSDB_DB_NAME_T || (x) == TSDB_TABLE_NAME_T)
@@ -294,4 +296,43 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type) {
return 0;
}
+static int compareKv(const void* p1, const void* p2) {
+ SSmlKv* kv1 = *(SSmlKv**)p1;
+ SSmlKv* kv2 = *(SSmlKv**)p2;
+ int32_t kvLen1 = kv1->keyLen;
+ int32_t kvLen2 = kv2->keyLen;
+ int32_t res = strncasecmp(kv1->key, kv2->key, TMIN(kvLen1, kvLen2));
+ if (res != 0) {
+ return res;
+ } else {
+ return kvLen1-kvLen2;
+ }
+}
+/*
+ * use stable name and tags to grearate child table name
+ */
+void buildChildTableName(RandTableName *rName) {
+ int32_t size = taosArrayGetSize(rName->tags);
+ ASSERT(size > 0);
+ taosArraySort(rName->tags, compareKv);
+
+ SStringBuilder sb = {0};
+ taosStringBuilderAppendStringLen(&sb, rName->sTableName, rName->sTableNameLen);
+ for (int j = 0; j < size; ++j) {
+ SSmlKv *tagKv = taosArrayGetP(rName->tags, j);
+ taosStringBuilderAppendStringLen(&sb, tagKv->key, tagKv->keyLen);
+ taosStringBuilderAppendStringLen(&sb, tagKv->value, tagKv->valueLen);
+ }
+ size_t len = 0;
+ char* keyJoined = taosStringBuilderGetResult(&sb, &len);
+ T_MD5_CTX context;
+ tMD5Init(&context);
+ tMD5Update(&context, (uint8_t *)keyJoined, (uint32_t)len);
+ tMD5Final(&context);
+ uint64_t digest1 = *(uint64_t*)(context.digest);
+ uint64_t digest2 = *(uint64_t*)(context.digest + 8);
+ snprintf(rName->childTableName, TSDB_TABLE_NAME_LEN, "t_%016"PRIx64"%016"PRIx64, digest1, digest2);
+ taosStringBuilderDestroy(&sb);
+ rName->uid = digest1;
+}
diff --git a/source/dnode/mgmt/implement/inc/dmImp.h b/source/dnode/mgmt/implement/inc/dmImp.h
index 32869aee9e196bdf765f763926113eec018f70ff..8a1a116ab3ab2693921e0fe6a61132bb9b44bb29 100644
--- a/source/dnode/mgmt/implement/inc/dmImp.h
+++ b/source/dnode/mgmt/implement/inc/dmImp.h
@@ -26,8 +26,10 @@ int32_t dmOpenNode(SMgmtWrapper *pWrapper);
void dmCloseNode(SMgmtWrapper *pWrapper);
// dmTransport.c
-int32_t dmInitTrans(SDnode *pDnode);
-void dmCleanupTrans(SDnode *pDnode);
+int32_t dmInitServer(SDnode *pDnode);
+void dmCleanupServer(SDnode *pDnode);
+int32_t dmInitClient(SDnode *pDnode);
+void dmCleanupClient(SDnode *pDnode);
SProcCfg dmGenProcCfg(SMgmtWrapper *pWrapper);
SMsgCb dmGetMsgcb(SMgmtWrapper *pWrapper);
int32_t dmInitMsgHandle(SDnode *pDnode);
diff --git a/source/dnode/mgmt/implement/src/dmExec.c b/source/dnode/mgmt/implement/src/dmExec.c
index 06001028b5faca9ee7d2bf1ef28a7cc5663b3c79..6999cee0370059deca9af77cc9a8e036f85feeda 100644
--- a/source/dnode/mgmt/implement/src/dmExec.c
+++ b/source/dnode/mgmt/implement/src/dmExec.c
@@ -213,10 +213,12 @@ static int32_t dmOpenNodes(SDnode *pDnode) {
}
pWrapper->procType = DND_PROC_CHILD;
+ if (dmInitClient(pDnode) != 0) {
+ return -1;
+ }
- SMsgCb msgCb = pDnode->data.msgCb;
- msgCb.pWrapper = pWrapper;
- tmsgSetDefaultMsgCb(&msgCb);
+ pDnode->data.msgCb = dmGetMsgcb(pWrapper);
+ tmsgSetDefaultMsgCb(&pDnode->data.msgCb);
if (dmOpenNode(pWrapper) != 0) {
dError("node:%s, failed to open since %s", pWrapper->name, terrstr());
@@ -234,6 +236,15 @@ static int32_t dmOpenNodes(SDnode *pDnode) {
pWrapper->procType = DND_PROC_SINGLE;
}
+ if (n == DNODE) {
+ if (dmInitClient(pDnode) != 0) {
+ return -1;
+ }
+
+ pDnode->data.msgCb = dmGetMsgcb(pWrapper);
+ tmsgSetDefaultMsgCb(&pDnode->data.msgCb);
+ }
+
if (dmOpenNode(pWrapper) != 0) {
dError("node:%s, failed to open since %s", pWrapper->name, terrstr());
return -1;
@@ -281,21 +292,21 @@ static void dmProcessProcHandle(void *handle) {
}
static void dmWatchNodes(SDnode *pDnode) {
+ if (pDnode->ptype != DND_PROC_PARENT) return;
+ if (pDnode->ntype == NODE_END) return;
+
taosThreadMutexLock(&pDnode->mutex);
- if (pDnode->ptype == DND_PROC_PARENT) {
- for (EDndNodeType n = DNODE + 1; n < NODE_END; ++n) {
- SMgmtWrapper *pWrapper = &pDnode->wrappers[n];
- if (!pWrapper->required) continue;
- if (pWrapper->procType != DND_PROC_PARENT) continue;
- if (pDnode->ntype == NODE_END) continue;
+ for (EDndNodeType n = DNODE + 1; n < NODE_END; ++n) {
+ SMgmtWrapper *pWrapper = &pDnode->wrappers[n];
+ if (!pWrapper->required) continue;
+ if (pWrapper->procType != DND_PROC_PARENT) continue;
- if (pWrapper->procId <= 0 || !taosProcExist(pWrapper->procId)) {
- dWarn("node:%s, process:%d is killed and needs to be restarted", pWrapper->name, pWrapper->procId);
- if (pWrapper->procObj) {
- taosProcCloseHandles(pWrapper->procObj, dmProcessProcHandle);
- }
- dmNewNodeProc(pWrapper, n);
+ if (pWrapper->procId <= 0 || !taosProcExist(pWrapper->procId)) {
+ dWarn("node:%s, process:%d is killed and needs to be restarted", pWrapper->name, pWrapper->procId);
+ if (pWrapper->procObj) {
+ taosProcCloseHandles(pWrapper->procObj, dmProcessProcHandle);
}
+ dmNewNodeProc(pWrapper, n);
}
}
taosThreadMutexUnlock(&pDnode->mutex);
diff --git a/source/dnode/mgmt/implement/src/dmHandle.c b/source/dnode/mgmt/implement/src/dmHandle.c
index 129d41061edcfaca1aeccdbc17f537d4918715b1..097d18679b0a3bd99a6e61ad2d2d935b2ac1c3cb 100644
--- a/source/dnode/mgmt/implement/src/dmHandle.c
+++ b/source/dnode/mgmt/implement/src/dmHandle.c
@@ -242,7 +242,7 @@ static int32_t dmInitMgmt(SMgmtWrapper *pWrapper) {
return -1;
}
- if (dmInitTrans(pDnode) != 0) {
+ if (dmInitServer(pDnode) != 0) {
dError("failed to init transport since %s", terrstr());
return -1;
}
@@ -275,7 +275,8 @@ static void dmCleanupMgmt(SMgmtWrapper *pWrapper) {
}
taosWUnLockLatch(&pDnode->data.latch);
- dmCleanupTrans(pDnode);
+ dmCleanupClient(pDnode);
+ dmCleanupServer(pDnode);
dInfo("dnode-mgmt is cleaned up");
}
diff --git a/source/dnode/mgmt/implement/src/dmObj.c b/source/dnode/mgmt/implement/src/dmObj.c
index 66bfb2701624afe8ad5decfe849ac8a9bd9b39ca..a43439d4658beda0465e5a3c2179d7e71e755395 100644
--- a/source/dnode/mgmt/implement/src/dmObj.c
+++ b/source/dnode/mgmt/implement/src/dmObj.c
@@ -124,9 +124,6 @@ SDnode *dmCreate(const SDnodeOpt *pOption) {
goto _OVER;
}
- pDnode->data.msgCb = dmGetMsgcb(&pDnode->wrappers[DNODE]);
- tmsgSetDefaultMsgCb(&pDnode->data.msgCb);
-
dInfo("dnode is created, data:%p", pDnode);
code = 0;
diff --git a/source/dnode/mgmt/implement/src/dmTransport.c b/source/dnode/mgmt/implement/src/dmTransport.c
index 114d7b6dfcc29be8b677f84d34dce50b1b1f4a99..a58999bf2d852e7af5bcb90f1865c26784221831 100644
--- a/source/dnode/mgmt/implement/src/dmTransport.c
+++ b/source/dnode/mgmt/implement/src/dmTransport.c
@@ -16,6 +16,8 @@
#define _DEFAULT_SOURCE
#include "dmImp.h"
+#include "qworker.h"
+
#define INTERNAL_USER "_dnd"
#define INTERNAL_CKEY "_key"
#define INTERNAL_SECRET "_pwd"
@@ -85,17 +87,14 @@ static void dmProcessRpcMsg(SMgmtWrapper *pWrapper, SRpcMsg *pRpc, SEpSet *pEpSe
if ((pMsg = taosAllocateQitem(sizeof(SNodeMsg))) == NULL) goto _OVER;
if (dmBuildMsg(pMsg, pRpc) != 0) goto _OVER;
- if (pWrapper->procType == DND_PROC_SINGLE) {
+ if (pWrapper->procType != DND_PROC_PARENT) {
dTrace("msg:%p, created, type:%s handle:%p user:%s", pMsg, TMSG_INFO(msgType), pRpc->handle, pMsg->user);
code = (*msgFp)(pWrapper, pMsg);
- } else if (pWrapper->procType == DND_PROC_PARENT) {
+ } else {
dTrace("msg:%p, created and put into child queue, type:%s handle:%p code:0x%04x user:%s contLen:%d", pMsg,
TMSG_INFO(msgType), pRpc->handle, pMsg->rpcMsg.code & 0XFFFF, pMsg->user, pRpc->contLen);
code = taosProcPutToChildQ(pWrapper->procObj, pMsg, sizeof(SNodeMsg), pRpc->pCont, pRpc->contLen,
(isReq && (pMsg->rpcMsg.code == 0)) ? pRpc->handle : NULL, pRpc->refId, PROC_FUNC_REQ);
- } else {
- dTrace("msg:%p, should not processed in child process, handle:%p user:%s", pMsg, pRpc->handle, pMsg->user);
- ASSERT(1);
}
_OVER:
@@ -108,7 +107,7 @@ _OVER:
} else {
dError("msg:%p, type:%s handle:%p failed to process since 0x%04x:%s", pMsg, TMSG_INFO(msgType), pRpc->handle,
code & 0XFFFF, terrstr());
- if (msgType & 1U) {
+ if (isReq) {
if (terrno != 0) code = terrno;
if (code == TSDB_CODE_NODE_NOT_DEPLOYED || code == TSDB_CODE_NODE_OFFLINE) {
if (msgType > TDMT_MND_MSG && msgType < TDMT_VND_MSG) {
@@ -130,22 +129,27 @@ _OVER:
}
static void dmProcessMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
- SDnodeTrans * pTrans = &pDnode->trans;
+ SDnodeTrans *pTrans = &pDnode->trans;
tmsg_t msgType = pMsg->msgType;
bool isReq = msgType & 1u;
- SMsgHandle * pHandle = &pTrans->msgHandles[TMSG_INDEX(msgType)];
+ SMsgHandle *pHandle = &pTrans->msgHandles[TMSG_INDEX(msgType)];
SMgmtWrapper *pWrapper = pHandle->pNdWrapper;
- if (msgType == TDMT_DND_SERVER_STATUS) {
- dTrace("server status req will be processed, handle:%p, app:%p", pMsg->handle, pMsg->ahandle);
- dmProcessServerStatusReq(pDnode, pMsg);
- return;
- }
-
- if (msgType == TDMT_DND_NET_TEST) {
- dTrace("net test req will be processed, handle:%p, app:%p", pMsg->handle, pMsg->ahandle);
- dmProcessServerStatusReq(pDnode, pMsg);
- return;
+ switch (msgType) {
+ case TDMT_DND_SERVER_STATUS:
+ dTrace("server status req will be processed, handle:%p, app:%p", pMsg->handle, pMsg->ahandle);
+ dmProcessServerStatusReq(pDnode, pMsg);
+ return;
+ case TDMT_DND_NET_TEST:
+ dTrace("net test req will be processed, handle:%p, app:%p", pMsg->handle, pMsg->ahandle);
+ dmProcessNetTestReq(pDnode, pMsg);
+ return;
+ case TDMT_MND_SYSTABLE_RETRIEVE_RSP:
+ case TDMT_VND_FETCH_RSP:
+ dTrace("retrieve rsp is received");
+ qWorkerProcessFetchRsp(NULL, NULL, pMsg);
+ pMsg->pCont = NULL; // already freed in qworker
+ return;
}
if (pDnode->status != DND_STAT_RUNNING) {
@@ -233,16 +237,6 @@ int32_t dmInitMsgHandle(SDnode *pDnode) {
return 0;
}
-static inline int32_t dmSendRpcReq(SDnode *pDnode, const SEpSet *pEpSet, SRpcMsg *pReq) {
- if (pDnode->trans.clientRpc == NULL) {
- terrno = TSDB_CODE_NODE_OFFLINE;
- return -1;
- }
-
- rpcSendRequest(pDnode->trans.clientRpc, pEpSet, pReq, NULL);
- return 0;
-}
-
static void dmSendRpcRedirectRsp(SDnode *pDnode, const SRpcMsg *pReq) {
SEpSet epSet = {0};
dmGetMnodeEpSet(pDnode, &epSet);
@@ -288,28 +282,20 @@ void dmSendToMnodeRecv(SDnode *pDnode, SRpcMsg *pReq, SRpcMsg *pRsp) {
}
static inline int32_t dmSendReq(SMgmtWrapper *pWrapper, const SEpSet *pEpSet, SRpcMsg *pReq) {
- if (pWrapper->pDnode->status != DND_STAT_RUNNING) {
+ SDnode *pDnode = pWrapper->pDnode;
+ if (pDnode->status != DND_STAT_RUNNING) {
terrno = TSDB_CODE_NODE_OFFLINE;
dError("failed to send rpc msg since %s, handle:%p", terrstr(), pReq->handle);
return -1;
}
- if (pWrapper->procType != DND_PROC_CHILD) {
- return dmSendRpcReq(pWrapper->pDnode, pEpSet, pReq);
- } else {
- char *pHead = taosMemoryMalloc(sizeof(SRpcMsg) + sizeof(SEpSet));
- if (pHead == NULL) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
- }
-
- memcpy(pHead, pReq, sizeof(SRpcMsg));
- memcpy(pHead + sizeof(SRpcMsg), pEpSet, sizeof(SEpSet));
- taosProcPutToParentQ(pWrapper->procObj, pHead, sizeof(SRpcMsg) + sizeof(SEpSet), pReq->pCont, pReq->contLen,
- PROC_FUNC_REQ);
- taosMemoryFree(pHead);
- return 0;
+ if (pDnode->trans.clientRpc == NULL) {
+ terrno = TSDB_CODE_NODE_OFFLINE;
+ return -1;
}
+
+ rpcSendRequest(pDnode->trans.clientRpc, pEpSet, pReq, NULL);
+ return 0;
}
static inline void dmSendRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp) {
@@ -396,9 +382,10 @@ static void dmConsumeParentQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg, int16_t
pMsg->pCont = pCont;
if (ftype == PROC_FUNC_REQ) {
+ ASSERT(1);
dTrace("msg:%p, get from parent queue, send req:%s handle:%p code:0x%04x, app:%p", pMsg, TMSG_INFO(pMsg->msgType),
pMsg->handle, code, pMsg->ahandle);
- dmSendRpcReq(pWrapper->pDnode, (SEpSet *)((char *)pMsg + sizeof(SRpcMsg)), pMsg);
+ dmSendReq(pWrapper, (SEpSet *)((char *)pMsg + sizeof(SRpcMsg)), pMsg);
} else if (ftype == PROC_FUNC_RSP) {
dTrace("msg:%p, get from parent queue, rsp handle:%p code:0x%04x, app:%p", pMsg, pMsg->handle, code, pMsg->ahandle);
pMsg->refId = taosProcRemoveHandle(pWrapper->procObj, pMsg->handle);
@@ -421,23 +408,25 @@ static void dmConsumeParentQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg, int16_t
}
SProcCfg dmGenProcCfg(SMgmtWrapper *pWrapper) {
- SProcCfg cfg = {.childConsumeFp = (ProcConsumeFp)dmConsumeChildQueue,
- .childMallocHeadFp = (ProcMallocFp)taosAllocateQitem,
- .childFreeHeadFp = (ProcFreeFp)taosFreeQitem,
- .childMallocBodyFp = (ProcMallocFp)rpcMallocCont,
- .childFreeBodyFp = (ProcFreeFp)rpcFreeCont,
- .parentConsumeFp = (ProcConsumeFp)dmConsumeParentQueue,
- .parentMallocHeadFp = (ProcMallocFp)taosMemoryMalloc,
- .parentFreeHeadFp = (ProcFreeFp)taosMemoryFree,
- .parentMallocBodyFp = (ProcMallocFp)rpcMallocCont,
- .parentFreeBodyFp = (ProcFreeFp)rpcFreeCont,
- .shm = pWrapper->procShm,
- .parent = pWrapper,
- .name = pWrapper->name};
+ SProcCfg cfg = {
+ .childConsumeFp = (ProcConsumeFp)dmConsumeChildQueue,
+ .childMallocHeadFp = (ProcMallocFp)taosAllocateQitem,
+ .childFreeHeadFp = (ProcFreeFp)taosFreeQitem,
+ .childMallocBodyFp = (ProcMallocFp)rpcMallocCont,
+ .childFreeBodyFp = (ProcFreeFp)rpcFreeCont,
+ .parentConsumeFp = (ProcConsumeFp)dmConsumeParentQueue,
+ .parentMallocHeadFp = (ProcMallocFp)taosMemoryMalloc,
+ .parentFreeHeadFp = (ProcFreeFp)taosMemoryFree,
+ .parentMallocBodyFp = (ProcMallocFp)rpcMallocCont,
+ .parentFreeBodyFp = (ProcFreeFp)rpcFreeCont,
+ .shm = pWrapper->procShm,
+ .parent = pWrapper,
+ .name = pWrapper->name,
+ };
return cfg;
}
-bool rpcRfp(int32_t code) {
+static bool rpcRfp(int32_t code) {
if (code == TSDB_CODE_RPC_REDIRECT) {
return true;
} else {
@@ -445,7 +434,7 @@ bool rpcRfp(int32_t code) {
}
}
-static int32_t dmInitClient(SDnode *pDnode) {
+int32_t dmInitClient(SDnode *pDnode) {
SDnodeTrans *pTrans = &pDnode->trans;
SRpcInit rpcInit = {0};
@@ -471,11 +460,15 @@ static int32_t dmInitClient(SDnode *pDnode) {
return -1;
}
+ pDnode->data.msgCb = dmGetMsgcb(&pDnode->wrappers[DNODE]);
+ tmsgSetDefaultMsgCb(&pDnode->data.msgCb);
+
dDebug("dnode rpc client is initialized");
+
return 0;
}
-static void dmCleanupClient(SDnode *pDnode) {
+void dmCleanupClient(SDnode *pDnode) {
SDnodeTrans *pTrans = &pDnode->trans;
if (pTrans->clientRpc) {
rpcClose(pTrans->clientRpc);
@@ -517,7 +510,7 @@ static inline int32_t dmRetrieveUserAuthInfo(SDnode *pDnode, char *user, char *s
SAuthReq authReq = {0};
tstrncpy(authReq.user, user, TSDB_USER_LEN);
int32_t contLen = tSerializeSAuthReq(NULL, 0, &authReq);
- void * pReq = rpcMallocCont(contLen);
+ void *pReq = rpcMallocCont(contLen);
tSerializeSAuthReq(pReq, contLen, &authReq);
SRpcMsg rpcMsg = {.pCont = pReq, .contLen = contLen, .msgType = TDMT_MND_AUTH, .ahandle = (void *)9528};
@@ -543,7 +536,7 @@ static inline int32_t dmRetrieveUserAuthInfo(SDnode *pDnode, char *user, char *s
return rpcRsp.code;
}
-static int32_t dmInitServer(SDnode *pDnode) {
+int32_t dmInitServer(SDnode *pDnode) {
SDnodeTrans *pTrans = &pDnode->trans;
SRpcInit rpcInit = {0};
@@ -569,7 +562,7 @@ static int32_t dmInitServer(SDnode *pDnode) {
return 0;
}
-static void dmCleanupServer(SDnode *pDnode) {
+void dmCleanupServer(SDnode *pDnode) {
SDnodeTrans *pTrans = &pDnode->trans;
if (pTrans->serverRpc) {
rpcClose(pTrans->serverRpc);
@@ -578,17 +571,6 @@ static void dmCleanupServer(SDnode *pDnode) {
}
}
-int32_t dmInitTrans(SDnode *pDnode) {
- if (dmInitServer(pDnode) != 0) return -1;
- if (dmInitClient(pDnode) != 0) return -1;
- return 0;
-}
-
-void dmCleanupTrans(SDnode *pDnode) {
- dmCleanupServer(pDnode);
- dmCleanupClient(pDnode);
-}
-
SMsgCb dmGetMsgcb(SMgmtWrapper *pWrapper) {
SMsgCb msgCb = {
.sendReqFp = dmSendReq,
@@ -598,6 +580,7 @@ SMsgCb dmGetMsgcb(SMgmtWrapper *pWrapper) {
.releaseHandleFp = dmReleaseHandle,
.reportStartupFp = dmReportStartupByWrapper,
.pWrapper = pWrapper,
+ .clientRpc = pWrapper->pDnode->trans.clientRpc,
};
return msgCb;
}
diff --git a/source/dnode/mgmt/interface/inc/dmInt.h b/source/dnode/mgmt/interface/inc/dmInt.h
index 63bfaf5ad24809043f0a9ea83a6815310aa4d592..b56edd26300f19f39551a7f6911d8c7260c34171 100644
--- a/source/dnode/mgmt/interface/inc/dmInt.h
+++ b/source/dnode/mgmt/interface/inc/dmInt.h
@@ -37,7 +37,7 @@ void dmSetMsgHandle(SMgmtWrapper *pWrapper, tmsg_t msgType, NodeMsgFp nodeMsgF
void dmReportStartup(SDnode *pDnode, const char *pName, const char *pDesc);
void dmReportStartupByWrapper(SMgmtWrapper *pWrapper, const char *pName, const char *pDesc);
void dmProcessServerStatusReq(SDnode *pDnode, SRpcMsg *pMsg);
-void dmProcessNettestReq(SDnode *pDnode, SRpcMsg *pMsg);
+void dmProcessNetTestReq(SDnode *pDnode, SRpcMsg *pMsg);
void dmGetMonitorSysInfo(SMonSysInfo *pInfo);
// dmFile.c
diff --git a/source/dnode/mgmt/interface/src/dmInt.c b/source/dnode/mgmt/interface/src/dmInt.c
index 2d15a7a008c01f0035b26eb2396b4cc3e3efa506..f8e23ad26212c093ab11b1c83fea085094156ea5 100644
--- a/source/dnode/mgmt/interface/src/dmInt.c
+++ b/source/dnode/mgmt/interface/src/dmInt.c
@@ -171,16 +171,17 @@ static void dmGetServerStatus(SDnode *pDnode, SServerStatusRsp *pStatus) {
}
}
-void dmProcessNettestReq(SDnode *pDnode, SRpcMsg *pRpc) {
+void dmProcessNetTestReq(SDnode *pDnode, SRpcMsg *pReq) {
dDebug("net test req is received");
- SRpcMsg rsp = {.handle = pRpc->handle, .refId = pRpc->refId, .ahandle = pRpc->ahandle, .code = 0};
- rsp.pCont = rpcMallocCont(pRpc->contLen);
+ SRpcMsg rsp = {.handle = pReq->handle, .refId = pReq->refId, .ahandle = pReq->ahandle, .code = 0};
+ rsp.pCont = rpcMallocCont(pReq->contLen);
if (rsp.pCont == NULL) {
rsp.code = TSDB_CODE_OUT_OF_MEMORY;
} else {
- rsp.contLen = pRpc->contLen;
+ rsp.contLen = pReq->contLen;
}
rpcSendResponse(&rsp);
+ rpcFreeCont(pReq->pCont);
}
void dmProcessServerStatusReq(SDnode *pDnode, SRpcMsg *pReq) {
@@ -208,6 +209,7 @@ void dmProcessServerStatusReq(SDnode *pDnode, SRpcMsg *pReq) {
_OVER:
rpcSendResponse(&rspMsg);
+ rpcFreeCont(pReq->pCont);
}
void dmGetMonitorSysInfo(SMonSysInfo *pInfo) {
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
index b19602f3ffb5edd449c20b6bf28c8c48607d059e..c5919e06b6e649eb46d8fc55a5687513e82aa863 100644
--- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
+++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
@@ -289,7 +289,6 @@ void vmInitMsgHandle(SMgmtWrapper *pWrapper) {
dmSetMsgHandle(pWrapper, TDMT_VND_QUERY, vmProcessQueryMsg, DEFAULT_HANDLE);
dmSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, vmProcessQueryMsg, DEFAULT_HANDLE);
dmSetMsgHandle(pWrapper, TDMT_VND_FETCH, vmProcessFetchMsg, DEFAULT_HANDLE);
- dmSetMsgHandle(pWrapper, TDMT_VND_FETCH_RSP, vmProcessFetchMsg, DEFAULT_HANDLE);
dmSetMsgHandle(pWrapper, TDMT_VND_ALTER_TABLE, vmProcessWriteMsg, DEFAULT_HANDLE);
dmSetMsgHandle(pWrapper, TDMT_VND_UPDATE_TAG_VAL, vmProcessWriteMsg, DEFAULT_HANDLE);
dmSetMsgHandle(pWrapper, TDMT_VND_TABLE_META, vmProcessFetchMsg, DEFAULT_HANDLE);
diff --git a/source/dnode/mnode/impl/src/mndQuery.c b/source/dnode/mnode/impl/src/mndQuery.c
index 7aa55e21091df78f11475a7d245507d15eeb80fa..36cde396fa3b6ab8ad7dd968c27cc224ef2459fb 100644
--- a/source/dnode/mnode/impl/src/mndQuery.c
+++ b/source/dnode/mnode/impl/src/mndQuery.c
@@ -20,7 +20,7 @@
int32_t mndProcessQueryMsg(SNodeMsg *pReq) {
SMnode *pMnode = pReq->pNode;
- SReadHandle handle = {.mnd = pMnode};
+ SReadHandle handle = {.mnd = pMnode, .pMsgCb = &pMnode->msgCb};
mTrace("msg:%p, in query queue is processing", pReq);
switch (pReq->rpcMsg.msgType) {
diff --git a/source/dnode/qnode/src/qnode.c b/source/dnode/qnode/src/qnode.c
index b21141001aa96c8d26c4a1297f9f2d5fe19a56c7..54b29f546cc888af80adaf1ec13c3b1a8c4d3efb 100644
--- a/source/dnode/qnode/src/qnode.c
+++ b/source/dnode/qnode/src/qnode.c
@@ -51,7 +51,7 @@ int32_t qndGetLoad(SQnode *pQnode, SQnodeLoad *pLoad) { return 0; }
int32_t qndProcessQueryMsg(SQnode *pQnode, SRpcMsg *pMsg) {
qTrace("message in qnode query queue is processing");
- SReadHandle handle = {0};
+ SReadHandle handle = {.pMsgCb = &pQnode->msgCb};
switch (pMsg->msgType) {
case TDMT_VND_QUERY: {
diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h
index a7617291b06462bf82ddcc497fb51a5e8bf52df0..986b2740f3a3d97787e6a6f8aa7c44ea590540a1 100644
--- a/source/dnode/vnode/src/inc/vnodeInt.h
+++ b/source/dnode/vnode/src/inc/vnodeInt.h
@@ -34,6 +34,7 @@
#include "tlockfree.h"
#include "tlosertree.h"
#include "tmallocator.h"
+#include "tmsgcb.h"
#include "tskiplist.h"
#include "tstream.h"
#include "ttime.h"
@@ -121,7 +122,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId);
// sma
-int32_t tsdbRegisterRSma(STsdb* pTsdb, SMeta* pMeta, SVCreateStbReq* pReq);
+int32_t tsdbRegisterRSma(STsdb* pTsdb, SMeta* pMeta, SVCreateStbReq* pReq, SMsgCb* pMsgCb);
int32_t tsdbFetchTbUidList(STsdb* pTsdb, STbUidStore** ppStore, tb_uid_t suid, tb_uid_t uid);
int32_t tsdbUpdateTbUidList(STsdb* pTsdb, STbUidStore* pUidStore);
void tsdbUidStoreDestory(STbUidStore* pStore);
diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c
index b8d6e84b1c8fbd2bf7e0618654e069c9379095b4..f607e0367e863b7e6a7532eb09cc9c1846ac8fda 100644
--- a/source/dnode/vnode/src/tq/tq.c
+++ b/source/dnode/vnode/src/tq/tq.c
@@ -378,6 +378,7 @@ int32_t tqDeserializeConsumer(STQ* pTq, const STqSerializedHead* pHead, STqConsu
SReadHandle handle = {
.reader = pReadHandle,
.meta = pTq->pVnode->pMeta,
+ .pMsgCb = &pTq->pVnode->msgCb,
};
pTopic->buffer.output[j].pReadHandle = pReadHandle;
pTopic->buffer.output[j].task = qCreateStreamExecTaskInfo(pTopic->qmsg, &handle);
@@ -857,6 +858,7 @@ int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen) {
SReadHandle handle = {
.reader = pExec->pExecReader[i],
.meta = pTq->pVnode->pMeta,
+ .pMsgCb = &pTq->pVnode->msgCb,
};
pExec->task[i] = qCreateStreamExecTaskInfo(pExec->qmsg, &handle);
ASSERT(pExec->task[i]);
@@ -914,6 +916,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int32_t parallel) {
SReadHandle handle = {
.reader = pStreamReader,
.meta = pTq->pVnode->pMeta,
+ .pMsgCb = &pTq->pVnode->msgCb,
};
pTask->exec.runners[i].inputHandle = pStreamReader;
pTask->exec.runners[i].executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle);
diff --git a/source/dnode/vnode/src/tsdb/tsdbSma.c b/source/dnode/vnode/src/tsdb/tsdbSma.c
index 615018a9ea9f96c774e007bd9d82c70d02f1500b..32051c2de4caac68f309b11baa65cc9f93d2da11 100644
--- a/source/dnode/vnode/src/tsdb/tsdbSma.c
+++ b/source/dnode/vnode/src/tsdb/tsdbSma.c
@@ -1698,7 +1698,7 @@ int32_t tsdbDropTSma(STsdb *pTsdb, char *pMsg) {
* @param pReq
* @return int32_t
*/
-int32_t tsdbRegisterRSma(STsdb *pTsdb, SMeta *pMeta, SVCreateStbReq *pReq) {
+int32_t tsdbRegisterRSma(STsdb *pTsdb, SMeta *pMeta, SVCreateStbReq *pReq, SMsgCb *pMsgCb) {
if (!pReq->rollup) {
tsdbDebug("vgId:%d return directly since no rollup for stable %s %" PRIi64, REPO_ID(pTsdb), pReq->name, pReq->suid);
return TSDB_CODE_SUCCESS;
@@ -1742,6 +1742,7 @@ int32_t tsdbRegisterRSma(STsdb *pTsdb, SMeta *pMeta, SVCreateStbReq *pReq) {
SReadHandle handle = {
.reader = pReadHandle,
.meta = pMeta,
+ .pMsgCb = pMsgCb,
};
if (param->qmsg1) {
diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c
index ee6bdc1a59b064854062c6f6699b628fb1b33a67..c1e0a202a8780a20fd9f6a5a5ec7fcb372e092a9 100644
--- a/source/dnode/vnode/src/vnd/vnodeSvr.c
+++ b/source/dnode/vnode/src/vnd/vnodeSvr.c
@@ -142,9 +142,9 @@ _err:
int vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
vTrace("message in vnode query queue is processing");
#if 0
- SReadHandle handle = {.reader = pVnode->pTsdb, .meta = pVnode->pMeta, .config = &pVnode->config, .vnode = pVnode};
+ SReadHandle handle = {.reader = pVnode->pTsdb, .meta = pVnode->pMeta, .config = &pVnode->config, .vnode = pVnode, .pMsgCb = &pVnode->msgCb};
#endif
- SReadHandle handle = {.meta = pVnode->pMeta, .config = &pVnode->config, .vnode = pVnode};
+ SReadHandle handle = {.meta = pVnode->pMeta, .config = &pVnode->config, .vnode = pVnode, .pMsgCb = &pVnode->msgCb};
switch (pMsg->msgType) {
case TDMT_VND_QUERY:
return qWorkerProcessQueryMsg(&handle, pVnode->pQuery, pMsg);
@@ -305,7 +305,7 @@ static int vnodeProcessCreateStbReq(SVnode *pVnode, int64_t version, void *pReq,
goto _err;
}
- tsdbRegisterRSma(pVnode->pTsdb, pVnode->pMeta, &req);
+ tsdbRegisterRSma(pVnode->pTsdb, pVnode->pMeta, &req, &pVnode->msgCb);
tDecoderClear(&coder);
return 0;
diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h
index 5cfe796a2992435179da65656b18abae9ebf7f92..98559f974d4fc9a537d77389d5052dc0425d8f72 100644
--- a/source/libs/executor/inc/executorimpl.h
+++ b/source/libs/executor/inc/executorimpl.h
@@ -392,10 +392,7 @@ typedef struct SStreamBlockScanInfo {
} SStreamBlockScanInfo;
typedef struct SSysTableScanInfo {
- union {
- void* pTransporter;
- SReadHandle readHandle;
- };
+ SReadHandle readHandle;
SRetrieveMetaTableRsp* pRsp;
SRetrieveTableReq req;
@@ -663,8 +660,6 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
char* pData, int16_t bytes, bool masterscan, uint64_t groupId,
SExecTaskInfo* pTaskInfo, bool isIntervalQuery, SAggSupporter* pSup);
-SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
-
SOperatorInfo* createTableScanOperatorInfo(void* pDataReader, SQueryTableDataCond* pCond, int32_t numOfOutput, int32_t dataLoadFlag, const uint8_t* scanInfo,
SArray* pColMatchInfo, SSDataBlock* pResBlock, SNode* pCondition, SInterval* pInterval, double sampleRatio, SExecTaskInfo* pTaskInfo);
diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c
index 1327ddb48ece4816e817aae39c42a7e4c35ef2d7..99cad87e5aeeb7acae85142b4b0b1c324e70f6bd 100644
--- a/source/libs/executor/src/executorimpl.c
+++ b/source/libs/executor/src/executorimpl.c
@@ -13,6 +13,7 @@
* along with this program. If not, see .
*/
+#include
#include "filter.h"
#include "function.h"
#include "functionMgt.h"
@@ -203,9 +204,9 @@ SSDataBlock* createResDataBlock(SDataBlockDescNode* pNode) {
for (int32_t i = 0; i < numOfCols; ++i) {
SColumnInfoData idata = {{0}};
SSlotDescNode* pDescNode = nodesListGetNode(pNode->pSlots, i);
-// if (!pDescNode->output) { // todo disable it temporarily
-// continue;
-// }
+ // if (!pDescNode->output) { // todo disable it temporarily
+ // continue;
+ // }
idata.info.type = pDescNode->dataType.type;
idata.info.bytes = pDescNode->dataType.bytes;
@@ -803,7 +804,8 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunction
for (int32_t k = 0; k < pOperator->numOfExprs; ++k) {
if (functionNeedToExecute(&pCtx[k])) {
pCtx[k].startTs = startTs; // this can be set during create the struct
- pCtx[k].fpSet.process(&pCtx[k]);
+ if (pCtx[k].fpSet.process != NULL)
+ pCtx[k].fpSet.process(&pCtx[k]);
}
}
}
@@ -833,7 +835,8 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
if (pExpr[k].pExpr->nodeType == QUERY_NODE_COLUMN) { // it is a project query
SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
if (pResult->info.rows > 0 && !createNewColModel) {
- colDataMergeCol(pColInfoData, pResult->info.rows, &pResult->info.capacity, pfCtx->input.pData[0], pfCtx->input.numOfRows);
+ colDataMergeCol(pColInfoData, pResult->info.rows, &pResult->info.capacity, pfCtx->input.pData[0],
+ pfCtx->input.numOfRows);
} else {
colDataAssign(pColInfoData, pfCtx->input.pData[0], pfCtx->input.numOfRows);
}
@@ -1074,35 +1077,36 @@ void setBlockStatisInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock*
// set the output buffer for the selectivity + tag query
static int32_t setCtxTagColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
int32_t num = 0;
- int16_t tagLen = 0;
SqlFunctionCtx* p = NULL;
- SqlFunctionCtx** pTagCtx = taosMemoryCalloc(numOfOutput, POINTER_BYTES);
- if (pTagCtx == NULL) {
+ SqlFunctionCtx** pValCtx = taosMemoryCalloc(numOfOutput, POINTER_BYTES);
+ if (pValCtx == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY;
}
for (int32_t i = 0; i < numOfOutput; ++i) {
- int32_t functionId = pCtx[i].functionId;
-
- if (functionId == FUNCTION_TAG_DUMMY || functionId == FUNCTION_TS_DUMMY) {
- tagLen += pCtx[i].resDataInfo.bytes;
- pTagCtx[num++] = &pCtx[i];
- } else if (1 /*(aAggs[functionId].status & FUNCSTATE_SELECTIVITY) != 0*/) {
- p = &pCtx[i];
- } else if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG) {
- // tag function may be the group by tag column
- // ts may be the required primary timestamp column
- continue;
+ if (strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
+ pValCtx[num++] = &pCtx[i];
} else {
- // the column may be the normal column, group by normal_column, the functionId is FUNCTION_PRJ
+ p = &pCtx[i];
}
+// if (functionId == FUNCTION_TAG_DUMMY || functionId == FUNCTION_TS_DUMMY) {
+// tagLen += pCtx[i].resDataInfo.bytes;
+// pTagCtx[num++] = &pCtx[i];
+// } else if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG) {
+// // tag function may be the group by tag column
+// // ts may be the required primary timestamp column
+// continue;
+// } else {
+// // the column may be the normal column, group by normal_column, the functionId is FUNCTION_PRJ
+// }
}
+
if (p != NULL) {
- p->subsidiaries.pCtx = pTagCtx;
+ p->subsidiaries.pCtx = pValCtx;
p->subsidiaries.num = num;
} else {
- taosMemoryFreeClear(pTagCtx);
+ taosMemoryFreeClear(pValCtx);
}
return TSDB_CODE_SUCCESS;
@@ -1873,7 +1877,7 @@ static void updateTableQueryInfoForReverseScan(STableQueryInfo* pTableQueryInfo)
}
void initResultRow(SResultRow* pResultRow) {
-// pResultRow->pEntryInfo = (struct SResultRowEntryInfo*)((char*)pResultRow + sizeof(SResultRow));
+ // pResultRow->pEntryInfo = (struct SResultRowEntryInfo*)((char*)pResultRow + sizeof(SResultRow));
}
/*
@@ -1885,7 +1889,8 @@ void initResultRow(SResultRow* pResultRow) {
* offset[0] offset[1] offset[2]
*/
// TODO refactor: some function move away
-void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage, int32_t numOfExprs, SExecTaskInfo* pTaskInfo) {
+void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage, int32_t numOfExprs,
+ SExecTaskInfo* pTaskInfo) {
SqlFunctionCtx* pCtx = pInfo->pCtx;
SSDataBlock* pDataBlock = pInfo->pRes;
int32_t* rowCellInfoOffset = pInfo->rowCellInfoOffset;
@@ -2219,6 +2224,8 @@ int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbased
pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset);
if (pCtx[j].fpSet.process) {
pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
+ } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
+ // do nothing, todo refactor
} else {
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
@@ -2240,12 +2247,13 @@ int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbased
return 0;
}
-void doBuildResultDatablock(SOptrBasicInfo *pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf) {
+void doBuildResultDatablock(SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo,
+ SDiskbasedBuf* pBuf) {
assert(pGroupResInfo->currentGroup <= pGroupResInfo->totalGroup);
- int32_t* rowCellOffset = pbInfo->rowCellInfoOffset;
- SSDataBlock* pBlock = pbInfo->pRes;
- SqlFunctionCtx* pCtx = pbInfo->pCtx;
+ int32_t* rowCellOffset = pbInfo->rowCellInfoOffset;
+ SSDataBlock* pBlock = pbInfo->pRes;
+ SqlFunctionCtx* pCtx = pbInfo->pCtx;
blockDataCleanup(pBlock);
if (!hasRemainDataInCurrentGroup(pGroupResInfo)) {
@@ -2419,7 +2427,8 @@ void queryCostStatis(SExecTaskInfo* pTaskInfo) {
SFileBlockLoadRecorder* pRecorder = pSummary->pRecoder;
if (pSummary->pRecoder != NULL) {
- qDebug("%s :cost summary: elapsed time:%" PRId64 " us, first merge:%" PRId64 " us, total blocks:%d, "
+ qDebug("%s :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,
GET_TASKID(pTaskInfo), pSummary->elapsedTime, pSummary->firstStageMergeTime, pRecorder->totalBlocks,
pRecorder->loadBlockStatis, pRecorder->loadBlocks, pRecorder->totalRows, pRecorder->totalCheckedRows);
@@ -2954,7 +2963,7 @@ int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadI
relocateColumnData(pRes, pColList, pBlock->pDataBlock);
taosArrayDestroy(pBlock->pDataBlock);
taosMemoryFree(pBlock);
-// blockDataDestroy(pBlock);
+ // blockDataDestroy(pBlock);
}
pRes->info.rows = numOfRows;
@@ -3259,7 +3268,8 @@ static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) {
return TSDB_CODE_SUCCESS;
}
-SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
+SOperatorInfo* createExchangeOperatorInfo(void *pTransporter, const SNodeList* pSources, SSDataBlock* pBlock,
+ SExecTaskInfo* pTaskInfo) {
SExchangeInfo* pInfo = taosMemoryCalloc(1, sizeof(SExchangeInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
@@ -3302,29 +3312,7 @@ SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock
pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL,
destroyExchangeOperatorInfo, NULL, NULL, NULL);
-
-#if 1
- { // todo refactor
- SRpcInit rpcInit;
- memset(&rpcInit, 0, sizeof(rpcInit));
- rpcInit.localPort = 0;
- rpcInit.label = "EX";
- rpcInit.numOfThreads = 1;
- rpcInit.cfp = qProcessFetchRsp;
- rpcInit.sessions = tsMaxConnections;
- rpcInit.connType = TAOS_CONN_CLIENT;
- rpcInit.user = (char*)"root";
- rpcInit.idleTime = tsShellActivityTimer * 1000;
- rpcInit.ckey = "key";
- rpcInit.spi = 1;
- rpcInit.secret = (char*)"dcc5bed04851fec854c035b2e40263b6";
-
- pInfo->pTransporter = rpcOpen(&rpcInit);
- if (pInfo->pTransporter == NULL) {
- return NULL; // todo
- }
- }
-#endif
+ pInfo->pTransporter = pTransporter;
return pOperator;
@@ -3974,6 +3962,7 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
SSDataBlock* pRes = pInfo->pRes;
blockDataCleanup(pRes);
+ SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
if (pOperator->status == OP_EXEC_DONE) {
return NULL;
}
@@ -4037,9 +4026,13 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, false);
blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);
- projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs,
+ pTaskInfo->code = projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs,
pProjectInfo->pPseudoColInfo);
+ if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
+ longjmp(pTaskInfo->env, pTaskInfo->code);
+ }
+
int32_t status = handleLimitOffset(pOperator, pBlock);
if (status == PROJECT_RETRIEVE_CONTINUE) {
continue;
@@ -4099,8 +4092,8 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator) {
}
// todo handle different group data interpolation
- bool n = false;
- bool *newgroup = &n;
+ bool n = false;
+ bool* newgroup = &n;
doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) {
return pResBlock;
@@ -4224,7 +4217,7 @@ int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t n
}
uint32_t defaultPgsz = 4096;
- while(defaultPgsz < pAggSup->resultRowSize*4) {
+ while (defaultPgsz < pAggSup->resultRowSize * 4) {
defaultPgsz <<= 1u;
}
@@ -4375,7 +4368,7 @@ void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
}
void destroyMergeJoinOperator(void* param, int32_t numOfOutput) {
- SJoinOperatorInfo* pJoinOperator = (SJoinOperatorInfo*) param;
+ SJoinOperatorInfo* pJoinOperator = (SJoinOperatorInfo*)param;
}
void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
@@ -4487,8 +4480,9 @@ static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t
}
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
- SInterval* pInterval, STimeWindow* pWindow, SSDataBlock* pResBlock, int32_t fillType, SNodeListNode* pValueNode,
- bool multigroupResult, SExecTaskInfo* pTaskInfo) {
+ SInterval* pInterval, STimeWindow* pWindow, SSDataBlock* pResBlock,
+ int32_t fillType, SNodeListNode* pValueNode, bool multigroupResult,
+ SExecTaskInfo* pTaskInfo) {
SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
@@ -4522,8 +4516,8 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExp
SResultInfo* pResultInfo = &pOperator->resultInfo;
initResultSizeInfo(pOperator, 4096);
- int32_t code = initFillInfo(pInfo, pExpr, numOfCols, pValueNode, *pWindow, pResultInfo->capacity,
- pTaskInfo->id.str, pInterval, type);
+ int32_t code = initFillInfo(pInfo, pExpr, numOfCols, pValueNode, *pWindow, pResultInfo->capacity, pTaskInfo->id.str,
+ pInterval, type);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
@@ -4736,7 +4730,8 @@ static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t
uint64_t queryId, uint64_t taskId);
static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo);
static SArray* extractColumnInfo(SNodeList* pNodeList);
-static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols, int32_t type);
+static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols,
+ int32_t type);
static SArray* createSortInfo(SNodeList* pNodeList);
static SArray* extractPartitionColInfo(SNodeList* pNodeList);
@@ -4776,33 +4771,34 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
SSDataBlock* pResBlock = createResDataBlock(pDescNode);
SQueryTableDataCond cond = {0};
- int32_t code = initQueryTableDataCond(&cond, pTableScanNode);
+ int32_t code = initQueryTableDataCond(&cond, pTableScanNode);
if (code != TSDB_CODE_SUCCESS) {
return NULL;
}
- SInterval interval = extractIntervalInfo(pTableScanNode);
- SOperatorInfo* pOperator = createTableScanOperatorInfo(pDataReader, &cond, numOfCols, pTableScanNode->dataRequired,
- pTableScanNode->scanSeq, pColList, pResBlock, pScanPhyNode->node.pConditions,
- &interval, pTableScanNode->ratio, pTaskInfo);
+ SInterval interval = extractIntervalInfo(pTableScanNode);
+ SOperatorInfo* pOperator = createTableScanOperatorInfo(
+ pDataReader, &cond, numOfCols, pTableScanNode->dataRequired, pTableScanNode->scanSeq, pColList, pResBlock,
+ pScanPhyNode->node.pConditions, &interval, pTableScanNode->ratio, pTaskInfo);
STableScanInfo* pScanInfo = pOperator->info;
pTaskInfo->cost.pRecoder = &pScanInfo->readRecorder;
return pOperator;
} else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode;
SSDataBlock* pResBlock = createResDataBlock(pExchange->node.pOutputDataBlockDesc);
- return createExchangeOperatorInfo(pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
+ return createExchangeOperatorInfo(pHandle->pMsgCb->clientRpc, pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode; // simple child table.
- int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, queryId, taskId);
+ int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo,
+ queryId, taskId);
SArray* tableIdList = extractTableIdList(pTableGroupInfo);
SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;
- SSDataBlock* pResBlock = createResDataBlock(pDescNode);
+ SSDataBlock* pResBlock = createResDataBlock(pDescNode);
- int32_t numOfCols = 0;
- SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID);
+ int32_t numOfCols = 0;
+ SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID);
SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo,
pScanPhyNode->node.pConditions);
taosArrayDestroy(tableIdList);
@@ -4822,25 +4818,27 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
return pOperator;
} else if (QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN == type) {
- STagScanPhysiNode* pScanPhyNode = (STagScanPhysiNode*) pPhyNode;
+ STagScanPhysiNode* pScanPhyNode = (STagScanPhysiNode*)pPhyNode;
SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;
SSDataBlock* pResBlock = createResDataBlock(pDescNode);
- int32_t code =
- doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, queryId, taskId);
+ int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo,
+ queryId, taskId);
if (code != TSDB_CODE_SUCCESS) {
return NULL;
}
- int32_t num = 0;
+ int32_t num = 0;
SExprInfo* pExprInfo = createExprInfo(pScanPhyNode->pScanPseudoCols, NULL, &num);
int32_t numOfOutputCols = 0;
- SArray* colList = extractColMatchInfo(pScanPhyNode->pScanPseudoCols, pDescNode, &numOfOutputCols, COL_MATCH_FROM_COL_ID);
+ SArray* colList =
+ extractColMatchInfo(pScanPhyNode->pScanPseudoCols, pDescNode, &numOfOutputCols, COL_MATCH_FROM_COL_ID);
- SOperatorInfo* pOperator = createTagScanOperatorInfo(pHandle, pExprInfo, num, pResBlock, colList, pTableGroupInfo, pTaskInfo);
+ SOperatorInfo* pOperator =
+ createTagScanOperatorInfo(pHandle, pExprInfo, num, pResBlock, colList, pTableGroupInfo, pTaskInfo);
return pOperator;
} else {
ASSERT(0);
@@ -4887,7 +4885,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
pOptr = createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pScalarExprInfo, numOfScalarExpr,
pTaskInfo, pTableGroupInfo);
}
- } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == type) {
+ } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == type || QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL == type) {
SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &num);
@@ -4925,13 +4923,15 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
} else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;
- STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark, .calTrigger = pSessionNode->window.triggerType};
+ STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark,
+ .calTrigger = pSessionNode->window.triggerType};
SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &num);
SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
int32_t tsSlotId = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;
- pOptr = createSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, tsSlotId, &as, pTaskInfo);
+ pOptr =
+ createSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, tsSlotId, &as, pTaskInfo);
} else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
SPartitionPhysiNode* pPartNode = (SPartitionPhysiNode*)pPhyNode;
SArray* pColList = extractPartitionColInfo(pPartNode->pPartitionKeys);
@@ -4957,11 +4957,12 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
pOptr = createMergeJoinOperatorInfo(ops, size, pExprInfo, num, pResBlock, pJoinNode->pOnConditions, pTaskInfo);
} else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) {
SFillPhysiNode* pFillNode = (SFillPhysiNode*)pPhyNode;
- SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
- SExprInfo* pExprInfo = createExprInfo(pFillNode->pTargets, NULL, &num);
+ SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
+ SExprInfo* pExprInfo = createExprInfo(pFillNode->pTargets, NULL, &num);
SInterval* pInterval = &((SIntervalAggOperatorInfo*)ops[0]->info)->interval;
- pOptr = createFillOperatorInfo(ops[0], pExprInfo, num, pInterval, &pFillNode->timeRange, pResBlock, pFillNode->mode, (SNodeListNode*)pFillNode->pValues, false, pTaskInfo);
+ pOptr = createFillOperatorInfo(ops[0], pExprInfo, num, pInterval, &pFillNode->timeRange, pResBlock, pFillNode->mode,
+ (SNodeListNode*)pFillNode->pValues, false, pTaskInfo);
} else {
ASSERT(0);
}
@@ -5101,7 +5102,8 @@ SArray* createSortInfo(SNodeList* pNodeList) {
return pList;
}
-SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols, int32_t type) {
+SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols,
+ int32_t type) {
size_t numOfCols = LIST_LENGTH(pNodeList);
SArray* pList = taosArrayInit(numOfCols, sizeof(SColMatchInfo));
if (pList == NULL) {
@@ -5114,10 +5116,10 @@ SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
SColMatchInfo c = {0};
- c.output = true;
- c.colId = pColNode->colId;
- c.srcSlotId = pColNode->slotId;
- c.matchType = type;
+ c.output = true;
+ c.colId = pColNode->colId;
+ c.srcSlotId = pColNode->slotId;
+ c.matchType = type;
c.targetSlotId = pNode->slotId;
taosArrayPush(pList, &c);
}
@@ -5527,8 +5529,8 @@ static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator) {
}
SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
- int32_t numOfCols, SSDataBlock* pResBlock, SNode* pOnCondition,
- SExecTaskInfo* pTaskInfo) {
+ int32_t numOfCols, SSDataBlock* pResBlock, SNode* pOnCondition,
+ SExecTaskInfo* pTaskInfo) {
SJoinOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SJoinOperatorInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
if (pOperator == NULL || pInfo == NULL) {
@@ -5537,14 +5539,14 @@ SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t
initResultSizeInfo(pOperator, 4096);
- pInfo->pRes = pResBlock;
- pOperator->name = "MergeJoinOperator";
+ pInfo->pRes = pResBlock;
+ pOperator->name = "MergeJoinOperator";
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_JOIN;
- pOperator->blocking = false;
- pOperator->status = OP_NOT_OPENED;
- pOperator->pExpr = pExprInfo;
+ pOperator->blocking = false;
+ pOperator->status = OP_NOT_OPENED;
+ pOperator->pExpr = pExprInfo;
pOperator->numOfExprs = numOfCols;
- pOperator->info = pInfo;
+ pOperator->info = pInfo;
pOperator->pTaskInfo = pTaskInfo;
SOperatorNode* pNode = (SOperatorNode*)pOnCondition;
@@ -5568,9 +5570,9 @@ _error:
}
void setJoinColumnInfo(SColumnInfo* pColumn, const SColumnNode* pColumnNode) {
- pColumn->slotId = pColumnNode->slotId;
- pColumn->type = pColumnNode->node.resType.type;
- pColumn->bytes = pColumnNode->node.resType.bytes;
+ pColumn->slotId = pColumnNode->slotId;
+ pColumn->type = pColumnNode->node.resType.type;
+ pColumn->bytes = pColumnNode->node.resType.bytes;
pColumn->precision = pColumnNode->node.resType.precision;
- pColumn->scale = pColumnNode->node.resType.scale;
+ pColumn->scale = pColumnNode->node.resType.scale;
}
diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c
index 183cb9dbe66719584c7b4da51b1708d04a8b3fc0..2ba3e257b2f4af5fa141fb88196f8b37def6db2b 100644
--- a/source/libs/executor/src/groupoperator.c
+++ b/source/libs/executor/src/groupoperator.c
@@ -262,6 +262,8 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) {
return NULL;
}
+ SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
+
SGroupbyOperatorInfo* pInfo = pOperator->info;
SSDataBlock* pRes = pInfo->binfo.pRes;
@@ -289,7 +291,10 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) {
// there is an scalar expression that needs to be calculated right before apply the group aggregation.
if (pInfo->pScalarExprInfo != NULL) {
- projectApplyFunctions(pInfo->pScalarExprInfo, pBlock, pBlock, pInfo->pScalarFuncCtx, pInfo->numOfScalarExpr, NULL);
+ pTaskInfo->code = projectApplyFunctions(pInfo->pScalarExprInfo, pBlock, pBlock, pInfo->pScalarFuncCtx, pInfo->numOfScalarExpr, NULL);
+ if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
+ longjmp(pTaskInfo->env, pTaskInfo->code);
+ }
}
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->binfo.pCtx, pOperator->numOfExprs);
diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c
index c1aee5ba351544fbdb32d415cd9fa8078303ebe6..eaacb561d50a64ad7d9627692ffcbb86357594aa 100644
--- a/source/libs/executor/src/scanoperator.c
+++ b/source/libs/executor/src/scanoperator.c
@@ -1057,7 +1057,8 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
pMsgSendInfo->fp = loadSysTableCallback;
int64_t transporterId = 0;
- int32_t code = asyncSendMsgToServer(pInfo->pTransporter, &pInfo->epSet, &transporterId, pMsgSendInfo);
+ int32_t code =
+ asyncSendMsgToServer(pInfo->readHandle.pMsgCb->clientRpc, &pInfo->epSet, &transporterId, pMsgSendInfo);
tsem_wait(&pInfo->ready);
if (pTaskInfo->code) {
@@ -1182,29 +1183,7 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSDataBlock* pRe
} else {
tsem_init(&pInfo->ready, 0, 0);
pInfo->epSet = epset;
-
-#if 1
- { // todo refactor
- SRpcInit rpcInit;
- memset(&rpcInit, 0, sizeof(rpcInit));
- rpcInit.localPort = 0;
- rpcInit.label = "DB-META";
- rpcInit.numOfThreads = 1;
- rpcInit.cfp = qProcessFetchRsp;
- rpcInit.sessions = tsMaxConnections;
- rpcInit.connType = TAOS_CONN_CLIENT;
- rpcInit.user = (char*)"root";
- rpcInit.idleTime = tsShellActivityTimer * 1000;
- rpcInit.ckey = "key";
- rpcInit.spi = 1;
- rpcInit.secret = (char*)"dcc5bed04851fec854c035b2e40263b6";
-
- pInfo->pTransporter = rpcOpen(&rpcInit);
- if (pInfo->pTransporter == NULL) {
- return NULL; // todo
- }
- }
-#endif
+ pInfo->readHandle = *(SReadHandle*)readHandle;
}
pOperator->name = "SysTableScanOperator";
diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c
index a6548765133a05c9f8a7efcd32d50e414decc7c3..990dc0f20002134eebc0cbe15a0fc4d0e34e6dc8 100644
--- a/source/libs/executor/src/sortoperator.c
+++ b/source/libs/executor/src/sortoperator.c
@@ -114,7 +114,10 @@ void applyScalarFunction(SSDataBlock* pBlock, void* param) {
SOperatorInfo* pOperator = param;
SSortOperatorInfo* pSort = pOperator->info;
if (pOperator->pExpr != NULL) {
- projectApplyFunctions(pOperator->pExpr, pBlock, pBlock, pSort->binfo.pCtx, pOperator->numOfExprs, NULL);
+ int32_t code = projectApplyFunctions(pOperator->pExpr, pBlock, pBlock, pSort->binfo.pCtx, pOperator->numOfExprs, NULL);
+ if (code != TSDB_CODE_SUCCESS) {
+ longjmp(pOperator->pTaskInfo->env, code);
+ }
}
}
diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h
index 1f2ad0797d6d185e9d9c40036455e1d0ad622854..ce2f0b0651e1491a1c49de353054b7cbbc4519c9 100644
--- a/source/libs/function/inc/builtinsimpl.h
+++ b/source/libs/function/inc/builtinsimpl.h
@@ -37,11 +37,11 @@ bool getSumFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
int32_t sumFunction(SqlFunctionCtx *pCtx);
int32_t sumInvertFunction(SqlFunctionCtx *pCtx);
-bool minFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
-bool maxFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
+bool minmaxFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
bool getMinmaxFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
int32_t minFunction(SqlFunctionCtx* pCtx);
int32_t maxFunction(SqlFunctionCtx *pCtx);
+int32_t minmaxFunctionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
bool getAvgFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
bool avgFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
@@ -70,6 +70,7 @@ int32_t lastFunction(SqlFunctionCtx *pCtx);
bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
int32_t topFunction(SqlFunctionCtx *pCtx);
+int32_t bottomFunction(SqlFunctionCtx *pCtx);
int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
bool getSpreadFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
@@ -82,6 +83,8 @@ bool histogramFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultIn
int32_t histogramFunction(SqlFunctionCtx* pCtx);
int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
+bool getSelectivityFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/libs/function/inc/functionMgtInt.h b/source/libs/function/inc/functionMgtInt.h
index 3869a5d7b2898bd1ea7e621513f6f13ea6d25d4b..4d45eb91cebced879e75ce23368b7a650d119f2e 100644
--- a/source/libs/function/inc/functionMgtInt.h
+++ b/source/libs/function/inc/functionMgtInt.h
@@ -40,6 +40,7 @@ extern "C" {
#define FUNC_MGT_MULTI_RES_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(11)
#define FUNC_MGT_SCAN_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(12)
#define FUNC_MGT_SELECT_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(13)
+#define FUNC_MGT_REPEAT_SCAN_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(14)
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c
index 5aa1b63c7921b0dc0b9383fffba80140491a0439..b7bd0235816a1437eb268cec08d8d67a912e05f5 100644
--- a/source/libs/function/src/builtins.c
+++ b/source/libs/function/src/builtins.c
@@ -207,7 +207,8 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
}
static int32_t translateBottom(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
- // todo
+ SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
+ pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type};
return TSDB_CODE_SUCCESS;
}
@@ -241,7 +242,7 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
- pFunc->node.resType = (SDataType) { .bytes = 512, .type = TSDB_DATA_TYPE_BINARY };
+ pFunc->node.resType = (SDataType){.bytes = 512, .type = TSDB_DATA_TYPE_BINARY};
return TSDB_CODE_SUCCESS;
}
@@ -273,7 +274,8 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
}
SExprNode* p1 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
- if (!IS_NUMERIC_TYPE(p1->resType.type)) {
+ if (!IS_SIGNED_NUMERIC_TYPE(p1->resType.type) && !IS_FLOAT_TYPE(p1->resType.type) &&
+ TSDB_DATA_TYPE_BOOL != p1->resType.type) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
pFunc->node.resType = p1->resType;
@@ -509,9 +511,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.translateFunc = translateInOutNum,
.dataRequiredFunc = statisDataRequired,
.getEnvFunc = getMinmaxFuncEnv,
- .initFunc = minFunctionSetup,
+ .initFunc = minmaxFunctionSetup,
.processFunc = minFunction,
- .finalizeFunc = functionFinalize
+ .finalizeFunc = minmaxFunctionFinalize
},
{
.name = "max",
@@ -520,9 +522,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.translateFunc = translateInOutNum,
.dataRequiredFunc = statisDataRequired,
.getEnvFunc = getMinmaxFuncEnv,
- .initFunc = maxFunctionSetup,
+ .initFunc = minmaxFunctionSetup,
.processFunc = maxFunction,
- .finalizeFunc = functionFinalize
+ .finalizeFunc = minmaxFunctionFinalize
},
{
.name = "stddev",
@@ -549,7 +551,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{
.name = "percentile",
.type = FUNCTION_TYPE_PERCENTILE,
- .classification = FUNC_MGT_AGG_FUNC,
+ .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_REPEAT_SCAN_FUNC,
.translateFunc = translatePercentile,
.getEnvFunc = getPercentileFuncEnv,
.initFunc = percentileFunctionSetup,
@@ -562,14 +564,14 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateApercentile,
.getEnvFunc = getMinmaxFuncEnv,
- .initFunc = maxFunctionSetup,
+ .initFunc = minmaxFunctionSetup,
.processFunc = maxFunction,
.finalizeFunc = functionFinalize
},
{
.name = "top",
.type = FUNCTION_TYPE_TOP,
- .classification = FUNC_MGT_AGG_FUNC,
+ .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC,
.translateFunc = translateTop,
.getEnvFunc = getTopBotFuncEnv,
.initFunc = functionSetup,
@@ -579,12 +581,12 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{
.name = "bottom",
.type = FUNCTION_TYPE_BOTTOM,
- .classification = FUNC_MGT_AGG_FUNC,
+ .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC,
.translateFunc = translateBottom,
- .getEnvFunc = getMinmaxFuncEnv,
- .initFunc = maxFunctionSetup,
- .processFunc = maxFunction,
- .finalizeFunc = functionFinalize
+ .getEnvFunc = getTopBotFuncEnv,
+ .initFunc = functionSetup,
+ .processFunc = bottomFunction,
+ .finalizeFunc = topBotFinalize
},
{
.name = "spread",
@@ -603,7 +605,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC,
.translateFunc = translateLastRow,
.getEnvFunc = getMinmaxFuncEnv,
- .initFunc = maxFunctionSetup,
+ .initFunc = minmaxFunctionSetup,
.processFunc = maxFunction,
.finalizeFunc = functionFinalize
},
@@ -1032,8 +1034,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.type = FUNCTION_TYPE_SELECT_VALUE,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC,
.translateFunc = translateSelectValue,
- .getEnvFunc = NULL,
- .initFunc = NULL,
+ .getEnvFunc = getSelectivityFuncEnv, // todo remove this function later.
+ .initFunc = functionSetup,
.sprocessFunc = NULL,
.finalizeFunc = NULL
}
diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c
index 9c1601b61a00c9e0c5956e1a49d6f880b808b3ef..1cb47a0bf139c7ff638e34be1c351044bd3a5bdc 100644
--- a/source/libs/function/src/builtinsimpl.c
+++ b/source/libs/function/src/builtinsimpl.c
@@ -37,13 +37,15 @@ typedef struct SAvgRes {
int64_t count;
} SAvgRes;
+typedef struct STuplePos {
+ int32_t pageId;
+ int32_t offset;
+} STuplePos;
+
typedef struct STopBotResItem {
- SVariant v;
- uint64_t uid; // it is a table uid, used to extract tag data during building of the final result for the tag data
- struct {
- int32_t pageId;
- int32_t offset;
- } tuplePos; // tuple data of this chosen row
+ SVariant v;
+ uint64_t uid; // it is a table uid, used to extract tag data during building of the final result for the tag data
+ STuplePos tuplePos; // tuple data of this chosen row
} STopBotResItem;
typedef struct STopBotRes {
@@ -616,101 +618,25 @@ EFuncDataRequired statisDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWin
return FUNC_DATA_REQUIRED_STATIS_LOAD;
}
-bool maxFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
- if (!functionSetup(pCtx, pResultInfo)) {
- return false;
- }
-
- char* buf = GET_ROWCELL_INTERBUF(pResultInfo);
- switch (pCtx->resDataInfo.type) {
- case TSDB_DATA_TYPE_INT:
- *((int32_t*)buf) = INT32_MIN;
- break;
- case TSDB_DATA_TYPE_UINT:
- *((uint32_t*)buf) = 0;
- break;
- case TSDB_DATA_TYPE_FLOAT:
- *((float*)buf) = -FLT_MAX;
- break;
- case TSDB_DATA_TYPE_DOUBLE:
- SET_DOUBLE_VAL(((double*)buf), -DBL_MAX);
- break;
- case TSDB_DATA_TYPE_BIGINT:
- *((int64_t*)buf) = INT64_MIN;
- break;
- case TSDB_DATA_TYPE_UBIGINT:
- *((uint64_t*)buf) = 0;
- break;
- case TSDB_DATA_TYPE_SMALLINT:
- *((int16_t*)buf) = INT16_MIN;
- break;
- case TSDB_DATA_TYPE_USMALLINT:
- *((uint16_t*)buf) = 0;
- break;
- case TSDB_DATA_TYPE_TINYINT:
- *((int8_t*)buf) = INT8_MIN;
- break;
- case TSDB_DATA_TYPE_UTINYINT:
- *((uint8_t*)buf) = 0;
- break;
- case TSDB_DATA_TYPE_BOOL:
- *((int8_t*)buf) = 0;
- break;
- default:
- assert(0);
- }
- return true;
-}
+typedef struct SMinmaxResInfo {
+ bool assign; // assign the first value or not
+ int64_t v;
+ STuplePos tuplePos;
+} SMinmaxResInfo;
-bool minFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
+bool minmaxFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
if (!functionSetup(pCtx, pResultInfo)) {
return false; // not initialized since it has been initialized
}
- char* buf = GET_ROWCELL_INTERBUF(pResultInfo);
- switch (pCtx->resDataInfo.type) {
- case TSDB_DATA_TYPE_TINYINT:
- *((int8_t*)buf) = INT8_MAX;
- break;
- case TSDB_DATA_TYPE_UTINYINT:
- *(uint8_t*)buf = UINT8_MAX;
- break;
- case TSDB_DATA_TYPE_SMALLINT:
- *((int16_t*)buf) = INT16_MAX;
- break;
- case TSDB_DATA_TYPE_USMALLINT:
- *((uint16_t*)buf) = UINT16_MAX;
- break;
- case TSDB_DATA_TYPE_INT:
- *((int32_t*)buf) = INT32_MAX;
- break;
- case TSDB_DATA_TYPE_UINT:
- *((uint32_t*)buf) = UINT32_MAX;
- break;
- case TSDB_DATA_TYPE_BIGINT:
- *((int64_t*)buf) = INT64_MAX;
- break;
- case TSDB_DATA_TYPE_UBIGINT:
- *((uint64_t*)buf) = UINT64_MAX;
- break;
- case TSDB_DATA_TYPE_FLOAT:
- *((float*)buf) = FLT_MAX;
- break;
- case TSDB_DATA_TYPE_DOUBLE:
- SET_DOUBLE_VAL(((double*)buf), DBL_MAX);
- break;
- case TSDB_DATA_TYPE_BOOL:
- *((int8_t*)buf) = 1;
- break;
- default:
- assert(0);
- }
-
+ SMinmaxResInfo* buf = GET_ROWCELL_INTERBUF(pResultInfo);
+ buf->assign = false;
+ buf->tuplePos.pageId = -1;
return true;
}
bool getMinmaxFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
- pEnv->calcMemSize = sizeof(int64_t);
+ pEnv->calcMemSize = sizeof(SMinmaxResInfo);
return true;
}
@@ -758,6 +684,9 @@ bool getMinmaxFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
} \
} while (0)
+static void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos);
+static void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos);
+
int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
int32_t numOfElems = 0;
@@ -768,13 +697,12 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
int32_t type = pCol->info.type;
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
- char* buf = GET_ROWCELL_INTERBUF(pResInfo);
+ SMinmaxResInfo *pBuf = GET_ROWCELL_INTERBUF(pResInfo);
// data in current data block are qualified to the query
if (pInput->colDataAggIsSet) {
numOfElems = pInput->numOfRows - pAgg->numOfNull;
ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0);
-
if (numOfElems == 0) {
return numOfElems;
}
@@ -793,48 +721,82 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
// the index is the original position, not the relative position
TSKEY key = (pCtx->ptsList != NULL) ? pCtx->ptsList[index] : TSKEY_INITIAL_VAL;
- if (IS_SIGNED_NUMERIC_TYPE(type)) {
- int64_t prev = 0;
- GET_TYPED_DATA(prev, int64_t, type, buf);
-
- int64_t val = GET_INT64_VAL(tval);
- if ((prev < val) ^ isMinFunc) {
- *(int64_t*)buf = val;
- for (int32_t i = 0; i < (pCtx)->subsidiaries.num; ++i) {
- SqlFunctionCtx* __ctx = pCtx->subsidiaries.pCtx[i];
- if (__ctx->functionId == FUNCTION_TS_DUMMY) { // TODO refactor
- __ctx->tag.i = key;
- __ctx->tag.nType = TSDB_DATA_TYPE_BIGINT;
+ if (!pBuf->assign) {
+ pBuf->v = *(int64_t*)tval;
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, index, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ } else {
+ if (IS_SIGNED_NUMERIC_TYPE(type)) {
+ int64_t prev = 0;
+ GET_TYPED_DATA(prev, int64_t, type, &pBuf->v);
+
+ int64_t val = GET_INT64_VAL(tval);
+ if ((prev < val) ^ isMinFunc) {
+ pBuf->v = val;
+ // for (int32_t i = 0; i < (pCtx)->subsidiaries.num; ++i) {
+ // SqlFunctionCtx* __ctx = pCtx->subsidiaries.pCtx[i];
+ // if (__ctx->functionId == FUNCTION_TS_DUMMY) { // TODO refactor
+ // __ctx->tag.i = key;
+ // __ctx->tag.nType = TSDB_DATA_TYPE_BIGINT;
+ // }
+ //
+ // __ctx->fpSet.process(__ctx);
+ // }
+
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, index, pCtx->pSrcBlock, &pBuf->tuplePos);
}
+ }
- __ctx->fpSet.process(__ctx);
+ } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
+ uint64_t prev = 0;
+ GET_TYPED_DATA(prev, uint64_t, type, &pBuf->v);
+
+ uint64_t val = GET_UINT64_VAL(tval);
+ if ((prev < val) ^ isMinFunc) {
+ pBuf->v = val;
+ // for (int32_t i = 0; i < (pCtx)->subsidiaries.num; ++i) {
+ // SqlFunctionCtx* __ctx = pCtx->subsidiaries.pCtx[i];
+ // if (__ctx->functionId == FUNCTION_TS_DUMMY) { // TODO refactor
+ // __ctx->tag.i = key;
+ // __ctx->tag.nType = TSDB_DATA_TYPE_BIGINT;
+ // }
+ //
+ // __ctx->fpSet.process(__ctx);
+ // }
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, index, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
}
- }
- } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
- uint64_t prev = 0;
- GET_TYPED_DATA(prev, uint64_t, type, buf);
-
- uint64_t val = GET_UINT64_VAL(tval);
- if ((prev < val) ^ isMinFunc) {
- *(uint64_t*)buf = val;
- for (int32_t i = 0; i < (pCtx)->subsidiaries.num; ++i) {
- SqlFunctionCtx* __ctx = pCtx->subsidiaries.pCtx[i];
- if (__ctx->functionId == FUNCTION_TS_DUMMY) { // TODO refactor
- __ctx->tag.i = key;
- __ctx->tag.nType = TSDB_DATA_TYPE_BIGINT;
+ } else if (type == TSDB_DATA_TYPE_DOUBLE) {
+ double prev = 0;
+ GET_TYPED_DATA(prev, int64_t, type, &pBuf->v);
+
+ double val = GET_DOUBLE_VAL(tval);
+ if ((prev < val) ^ isMinFunc) {
+ pBuf->v = val;
+
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, index, pCtx->pSrcBlock, &pBuf->tuplePos);
}
+ }
+ } else if (type == TSDB_DATA_TYPE_FLOAT) {
+ double prev = 0;
+ GET_TYPED_DATA(prev, int64_t, type, &pBuf->v);
+
+ double val = GET_DOUBLE_VAL(tval);
+ if ((prev < val) ^ isMinFunc) {
+ pBuf->v = val;
+ }
- __ctx->fpSet.process(__ctx);
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, index, pCtx->pSrcBlock, &pBuf->tuplePos);
}
}
- } else if (type == TSDB_DATA_TYPE_DOUBLE) {
- double val = GET_DOUBLE_VAL(tval);
- UPDATE_DATA(pCtx, *(double*)buf, val, numOfElems, isMinFunc, key);
- } else if (type == TSDB_DATA_TYPE_FLOAT) {
- double val = GET_DOUBLE_VAL(tval);
- UPDATE_DATA(pCtx, *(float*)buf, val, numOfElems, isMinFunc, key);
}
+ pBuf->assign = true;
return numOfElems;
}
@@ -843,47 +805,318 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) {
if (type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_BOOL) {
- LOOPCHECK_N(*(int8_t*)buf, pCol, pCtx, int8_t, numOfRows, start, isMinFunc, numOfElems);
+ int8_t* pData = (int8_t*)pCol->pData;
+ int8_t* val = (int8_t*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
} else if (type == TSDB_DATA_TYPE_SMALLINT) {
- LOOPCHECK_N(*(int16_t*)buf, pCol, pCtx, int16_t, numOfRows, start, isMinFunc, numOfElems);
+ int16_t* pData = (int16_t*)pCol->pData;
+ int16_t* val = (int16_t*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
} else if (type == TSDB_DATA_TYPE_INT) {
int32_t* pData = (int32_t*)pCol->pData;
- int32_t* val = (int32_t*)buf;
+ int32_t* val = (int32_t*)&pBuf->v;
for (int32_t i = start; i < start + numOfRows; ++i) {
if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
- if ((*val < pData[i]) ^ isMinFunc) {
+ if (!pBuf->assign) {
*val = pData[i];
- TSKEY ts = (pCtx->ptsList != NULL) ? GET_TS_DATA(pCtx, i) : 0;
- DO_UPDATE_SUBSID_RES(pCtx, ts);
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
}
numOfElems += 1;
}
-
-#if defined(_DEBUG_VIEW)
- qDebug("max value updated:%d", *retVal);
-#endif
} else if (type == TSDB_DATA_TYPE_BIGINT) {
- LOOPCHECK_N(*(int64_t*)buf, pCol, pCtx, int64_t, numOfRows, start, isMinFunc, numOfElems);
+ int64_t* pData = (int64_t*)pCol->pData;
+ int64_t* val = (int64_t*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
}
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
if (type == TSDB_DATA_TYPE_UTINYINT) {
- LOOPCHECK_N(*(uint8_t*)buf, pCol, pCtx, uint8_t, numOfRows, start, isMinFunc, numOfElems);
+ uint8_t* pData = (uint8_t*)pCol->pData;
+ uint8_t* val = (uint8_t*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
} else if (type == TSDB_DATA_TYPE_USMALLINT) {
- LOOPCHECK_N(*(uint16_t*)buf, pCol, pCtx, uint16_t, numOfRows, start, isMinFunc, numOfElems);
+ uint16_t* pData = (uint16_t*)pCol->pData;
+ uint16_t* val = (uint16_t*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
} else if (type == TSDB_DATA_TYPE_UINT) {
- LOOPCHECK_N(*(uint32_t*)buf, pCol, pCtx, uint32_t, numOfRows, start, isMinFunc, numOfElems);
+ uint32_t* pData = (uint32_t*)pCol->pData;
+ uint32_t* val = (uint32_t*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
} else if (type == TSDB_DATA_TYPE_UBIGINT) {
- LOOPCHECK_N(*(uint64_t*)buf, pCol, pCtx, uint64_t, numOfRows, start, isMinFunc, numOfElems);
+ uint64_t* pData = (uint64_t*)pCol->pData;
+ uint64_t* val = (uint64_t*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
}
} else if (type == TSDB_DATA_TYPE_DOUBLE) {
- LOOPCHECK_N(*(double*)buf, pCol, pCtx, double, numOfRows, start, isMinFunc, numOfElems);
+ double* pData = (double*)pCol->pData;
+ double* val = (double*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
} else if (type == TSDB_DATA_TYPE_FLOAT) {
- LOOPCHECK_N(*(float*)buf, pCol, pCtx, float, numOfRows, start, isMinFunc, numOfElems);
+ float* pData = (float*)pCol->pData;
+ double* val = (double*)&pBuf->v;
+
+ for (int32_t i = start; i < start + numOfRows; ++i) {
+ if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ if (!pBuf->assign) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ saveTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ pBuf->assign = true;
+ } else {
+ // ignore the equivalent data value
+ if ((*val) == pData[i]) {
+ continue;
+ }
+
+ if ((*val < pData[i]) ^ isMinFunc) {
+ *val = pData[i];
+ if (pCtx->subsidiaries.num > 0) {
+ copyTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
+ }
+ }
+ }
+
+ numOfElems += 1;
+ }
}
return numOfElems;
@@ -901,6 +1134,65 @@ int32_t maxFunction(SqlFunctionCtx* pCtx) {
return TSDB_CODE_SUCCESS;
}
+static void setSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, const STuplePos *pTuplePos, int32_t rowIndex);
+
+int32_t minmaxFunctionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
+ SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
+
+ SMinmaxResInfo* pRes = GET_ROWCELL_INTERBUF(pEntryInfo);
+
+ int32_t type = pCtx->input.pData[0]->info.type;
+ int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
+
+ SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
+
+ // todo assign the tag value
+ int32_t currentRow = pBlock->info.rows;
+
+ if (pCol->info.type == TSDB_DATA_TYPE_FLOAT) {
+ float v = *(double*) &pRes->v;
+ colDataAppend(pCol, currentRow, (const char*)&v, false);
+ } else {
+ colDataAppend(pCol, currentRow, (const char*)&pRes->v, false);
+ }
+
+ setSelectivityValue(pCtx, pBlock, &pRes->tuplePos, currentRow);
+ return pEntryInfo->numOfRes;
+}
+
+void setSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, const STuplePos *pTuplePos, int32_t rowIndex) {
+ int32_t pageId = pTuplePos->pageId;
+ int32_t offset = pTuplePos->offset;
+ if (pTuplePos->pageId != -1) {
+ SFilePage* pPage = getBufPage(pCtx->pBuf, pageId);
+
+ bool* nullList = (bool*)((char*)pPage + offset);
+ char* pStart = (char*)(nullList + pCtx->pSrcBlock->info.numOfCols * sizeof(bool));
+
+ // todo set the offset value to optimize the performance.
+ for (int32_t j = 0; j < pCtx->subsidiaries.num; ++j) {
+ SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j];
+
+ SFunctParam* pFuncParam = &pc->pExpr->base.pParam[0];
+ int32_t srcSlotId = pFuncParam->pCol->slotId;
+ int32_t dstSlotId = pc->pExpr->base.resSchema.slotId;
+
+ int32_t ps = 0;
+ for (int32_t k = 0; k < srcSlotId; ++k) {
+ SColumnInfoData* pSrcCol = taosArrayGet(pCtx->pSrcBlock->pDataBlock, k);
+ ps += pSrcCol->info.bytes;
+ }
+
+ SColumnInfoData* pDstCol = taosArrayGet(pBlock->pDataBlock, dstSlotId);
+ if (nullList[srcSlotId]) {
+ colDataAppendNULL(pDstCol, rowIndex);
+ } else {
+ colDataAppend(pDstCol, rowIndex, (pStart + ps), false);
+ }
+ }
+ }
+}
+
bool getStddevFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
pEnv->calcMemSize = sizeof(SStddevRes);
return true;
@@ -1244,6 +1536,14 @@ bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
return true;
}
+bool getSelectivityFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
+ SColumnNode* pNode = nodesListGetNode(pFunc->pParameterList, 0);
+ pEnv->calcMemSize = pNode->node.resType.bytes;
+ return true;
+}
+
+
+
static FORCE_INLINE TSKEY getRowPTs(SColumnInfoData* pTsColInfo, int32_t rowIndex) {
if (pTsColInfo == NULL) {
return 0;
@@ -1622,35 +1922,49 @@ static STopBotRes* getTopBotOutputInfo(SqlFunctionCtx* pCtx) {
}
static void doAddIntoResult(SqlFunctionCtx* pCtx, void* pData, int32_t rowIndex, SSDataBlock* pSrcBlock, uint16_t type,
- uint64_t uid, SResultRowEntryInfo* pEntryInfo);
-
-static void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STopBotResItem* pItem);
-static void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STopBotResItem* pItem);
+ uint64_t uid, SResultRowEntryInfo* pEntryInfo, bool isTopQuery);
int32_t topFunction(SqlFunctionCtx* pCtx) {
int32_t numOfElems = 0;
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
- // if ((void *)pRes->res[0] != (void *)((char *)pRes + sizeof(STopBotRes) + POINTER_BYTES * pCtx->param[0].i)) {
- // buildTopBotStruct(pRes, pCtx);
- // }
-
SInputColumnInfoData* pInput = &pCtx->input;
SColumnInfoData* pCol = pInput->pData[0];
int32_t type = pInput->pData[0]->info.type;
int32_t start = pInput->startRowIndex;
- int32_t numOfRows = pInput->numOfRows;
-
- for (int32_t i = start; i < numOfRows + start; ++i) {
+ for (int32_t i = start; i < pInput->numOfRows + start; ++i) {
if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
+
numOfElems++;
+ char* data = colDataGetData(pCol, i);
+ doAddIntoResult(pCtx, data, i, pCtx->pSrcBlock, type, pInput->uid, pResInfo, true);
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+int32_t bottomFunction(SqlFunctionCtx* pCtx) {
+ int32_t numOfElems = 0;
+ SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
+
+ SInputColumnInfoData* pInput = &pCtx->input;
+ SColumnInfoData* pCol = pInput->pData[0];
+
+ int32_t type = pInput->pData[0]->info.type;
+
+ int32_t start = pInput->startRowIndex;
+ for (int32_t i = start; i < pInput->numOfRows + start; ++i) {
+ if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) {
+ continue;
+ }
+
+ numOfElems++;
char* data = colDataGetData(pCol, i);
- doAddIntoResult(pCtx, data, i, pCtx->pSrcBlock, type, pInput->uid, pResInfo);
+ doAddIntoResult(pCtx, data, i, pCtx->pSrcBlock, type, pInput->uid, pResInfo, false);
}
return TSDB_CODE_SUCCESS;
@@ -1684,7 +1998,7 @@ static int32_t topBotResComparFn(const void* p1, const void* p2, const void* par
}
void doAddIntoResult(SqlFunctionCtx* pCtx, void* pData, int32_t rowIndex, SSDataBlock* pSrcBlock, uint16_t type,
- uint64_t uid, SResultRowEntryInfo* pEntryInfo) {
+ uint64_t uid, SResultRowEntryInfo* pEntryInfo, bool isTopQuery) {
STopBotRes* pRes = getTopBotOutputInfo(pCtx);
int32_t maxSize = pCtx->param[1].param.i;
@@ -1701,30 +2015,36 @@ void doAddIntoResult(SqlFunctionCtx* pCtx, void* pData, int32_t rowIndex, SSData
pItem->uid = uid;
// save the data of this tuple
- saveTupleData(pCtx, rowIndex, pSrcBlock, pItem);
+ saveTupleData(pCtx, rowIndex, pSrcBlock, &pItem->tuplePos);
// allocate the buffer and keep the data of this row into the new allocated buffer
pEntryInfo->numOfRes++;
taosheapsort((void*)pItems, sizeof(STopBotResItem), pEntryInfo->numOfRes, (const void*)&type, topBotResComparFn,
- false);
+ !isTopQuery);
} else { // replace the minimum value in the result
- if ((IS_SIGNED_NUMERIC_TYPE(type) && val.i > pItems[0].v.i) ||
- (IS_UNSIGNED_NUMERIC_TYPE(type) && val.u > pItems[0].v.u) || (IS_FLOAT_TYPE(type) && val.d > pItems[0].v.d)) {
+ if ((isTopQuery && (
+ (IS_SIGNED_NUMERIC_TYPE(type) && val.i > pItems[0].v.i) ||
+ (IS_UNSIGNED_NUMERIC_TYPE(type) && val.u > pItems[0].v.u) ||
+ (IS_FLOAT_TYPE(type) && val.d > pItems[0].v.d)))
+ || (!isTopQuery && (
+ (IS_SIGNED_NUMERIC_TYPE(type) && val.i < pItems[0].v.i) ||
+ (IS_UNSIGNED_NUMERIC_TYPE(type) && val.u < pItems[0].v.u) ||
+ (IS_FLOAT_TYPE(type) && val.d < pItems[0].v.d))
+ )) {
// replace the old data and the coresponding tuple data
STopBotResItem* pItem = &pItems[0];
pItem->v = val;
pItem->uid = uid;
// save the data of this tuple by over writing the old data
- copyTupleData(pCtx, rowIndex, pSrcBlock, pItem);
-
+ copyTupleData(pCtx, rowIndex, pSrcBlock, &pItem->tuplePos);
taosheapadjust((void*)pItems, sizeof(STopBotResItem), 0, pEntryInfo->numOfRes - 1, (const void*)&type,
- topBotResComparFn, NULL, false);
+ topBotResComparFn, NULL, !isTopQuery);
}
}
}
-void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STopBotResItem* pItem) {
+void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) {
SFilePage* pPage = NULL;
int32_t completeRowSize = pSrcBlock->info.rowSize + pSrcBlock->info.numOfCols * sizeof(bool);
@@ -1740,7 +2060,7 @@ void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS
}
}
- pItem->tuplePos.pageId = pCtx->curBufPage;
+ pPos->pageId = pCtx->curBufPage;
// keep the current row data, extract method
int32_t offset = 0;
@@ -1751,6 +2071,7 @@ void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS
bool isNull = colDataIsNull_s(pCol, rowIndex);
if (isNull) {
nullList[i] = true;
+ offset += pCol->info.bytes;
continue;
}
@@ -1764,17 +2085,17 @@ void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS
offset += pCol->info.bytes;
}
- pItem->tuplePos.offset = pPage->num;
+ pPos->offset = pPage->num;
pPage->num += completeRowSize;
setBufPageDirty(pPage, true);
releaseBufPage(pCtx->pBuf, pPage);
}
-void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STopBotResItem* pItem) {
- SFilePage* pPage = getBufPage(pCtx->pBuf, pItem->tuplePos.pageId);
+void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) {
+ SFilePage* pPage = getBufPage(pCtx->pBuf, pPos->pageId);
- bool* nullList = (bool*)((char*)pPage + pItem->tuplePos.offset);
+ bool* nullList = (bool*)((char*)pPage + pPos->offset);
char* pStart = (char*)(nullList + pSrcBlock->info.numOfCols * sizeof(bool));
int32_t offset = 0;
@@ -1803,54 +2124,24 @@ int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
STopBotRes* pRes = GET_ROWCELL_INTERBUF(pEntryInfo);
pEntryInfo->complete = true;
- int32_t type = pCtx->input.pData[0]->info.type;
- int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
+ int32_t type = pCtx->input.pData[0]->info.type;
+ int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
+
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
// todo assign the tag value and the corresponding row data
int32_t currentRow = pBlock->info.rows;
- switch (type) {
- case TSDB_DATA_TYPE_INT: {
- for (int32_t i = 0; i < pEntryInfo->numOfRes; ++i) {
- STopBotResItem* pItem = &pRes->pItems[i];
- colDataAppendInt32(pCol, currentRow, (int32_t*)&pItem->v.i);
-
- int32_t pageId = pItem->tuplePos.pageId;
- int32_t offset = pItem->tuplePos.offset;
- if (pItem->tuplePos.pageId != -1) {
- SFilePage* pPage = getBufPage(pCtx->pBuf, pageId);
-
- bool* nullList = (bool*)((char*)pPage + offset);
- char* pStart = (char*)(nullList + pCtx->pSrcBlock->info.numOfCols * sizeof(bool));
-
- // todo set the offset value to optimize the performance.
- for (int32_t j = 0; j < pCtx->subsidiaries.num; ++j) {
- SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j];
-
- SFunctParam* pFuncParam = &pc->pExpr->base.pParam[0];
- int32_t srcSlotId = pFuncParam->pCol->slotId;
- int32_t dstSlotId = pCtx->pExpr->base.resSchema.slotId;
-
- int32_t ps = 0;
- for (int32_t k = 0; k < srcSlotId; ++k) {
- SColumnInfoData* pSrcCol = taosArrayGet(pCtx->pSrcBlock->pDataBlock, k);
- ps += pSrcCol->info.bytes;
- }
-
- SColumnInfoData* pDstCol = taosArrayGet(pBlock->pDataBlock, dstSlotId);
- if (nullList[srcSlotId]) {
- colDataAppendNULL(pDstCol, currentRow);
- } else {
- colDataAppend(pDstCol, currentRow, (pStart + ps), false);
- }
- }
- }
-
- currentRow += 1;
- }
-
- break;
+ for (int32_t i = 0; i < pEntryInfo->numOfRes; ++i) {
+ STopBotResItem* pItem = &pRes->pItems[i];
+ if (type == TSDB_DATA_TYPE_FLOAT) {
+ float v = pItem->v.d;
+ colDataAppend(pCol, currentRow, (const char*)&v, false);
+ } else {
+ colDataAppend(pCol, currentRow, (const char*)&pItem->v.i, false);
}
+
+ setSelectivityValue(pCtx, pBlock, &pRes->pItems[i].tuplePos, currentRow);
+ currentRow += 1;
}
return pEntryInfo->numOfRes;
diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c
index 46bbb33aa7533ca80382a4410024838df5f14aaf..73ec7f510b83650d58ac9ed569261b9b569bd390 100644
--- a/source/libs/function/src/functionMgt.c
+++ b/source/libs/function/src/functionMgt.c
@@ -169,6 +169,8 @@ bool fmIsDynamicScanOptimizedFunc(int32_t funcId) {
bool fmIsMultiResFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_MULTI_RES_FUNC); }
+bool fmIsRepeatScanFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_REPEAT_SCAN_FUNC); }
+
bool fmIsUserDefinedFunc(int32_t funcId) { return funcId > FUNC_UDF_ID_START; }
void fmFuncMgtDestroy() {
@@ -197,15 +199,14 @@ int32_t fmSetNormalFunc(int32_t funcId, SFuncExecFuncs* pFpSet) {
bool fmIsInvertible(int32_t funcId) {
bool res = false;
switch (funcMgtBuiltins[funcId].type) {
- case FUNCTION_TYPE_COUNT:
- case FUNCTION_TYPE_SUM:
- case FUNCTION_TYPE_STDDEV:
- case FUNCTION_TYPE_AVG:
- res = true;
- break;
- default:
- break;
+ case FUNCTION_TYPE_COUNT:
+ case FUNCTION_TYPE_SUM:
+ case FUNCTION_TYPE_STDDEV:
+ case FUNCTION_TYPE_AVG:
+ res = true;
+ break;
+ default:
+ break;
}
return res;
}
-
diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c
index 507cd79411c0c1fbf7d67de4686f5028a6dd5be1..a625fc0d0c468203ab7b17ee207c35c7bccdd762 100644
--- a/source/libs/nodes/src/nodesCodeFuncs.c
+++ b/source/libs/nodes/src/nodesCodeFuncs.c
@@ -222,6 +222,8 @@ const char* nodesNodeName(ENodeType type) {
return "PhysiSort";
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
return "PhysiInterval";
+ case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
+ return "PhysiStreamInterval";
case QUERY_NODE_PHYSICAL_PLAN_FILL:
return "PhysiFill";
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
@@ -2893,6 +2895,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_PHYSICAL_PLAN_SORT:
return physiSortNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
+ case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
return physiIntervalNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_FILL:
return physiFillNodeToJson(pObj, pJson);
@@ -2983,6 +2986,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
case QUERY_NODE_PHYSICAL_PLAN_SORT:
return jsonToPhysiSortNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
+ case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
return jsonToPhysiIntervalNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_FILL:
return jsonToPhysiFillNode(pJson, pObj);
@@ -3099,6 +3103,7 @@ int32_t nodesStringToNode(const char* pStr, SNode** pNode) {
return TSDB_CODE_FAILED;
}
int32_t code = makeNodeByJson(pJson, pNode);
+ tjsonDelete(pJson);
if (TSDB_CODE_SUCCESS != code) {
nodesDestroyNode(*pNode);
*pNode = NULL;
diff --git a/source/libs/nodes/src/nodesTraverseFuncs.c b/source/libs/nodes/src/nodesTraverseFuncs.c
index f2c043b9ea7b27e46748fa4893a26aa03da9ca47..e8274c3c8eaa916a6e2c3877cde6185b99a623d8 100644
--- a/source/libs/nodes/src/nodesTraverseFuncs.c
+++ b/source/libs/nodes/src/nodesTraverseFuncs.c
@@ -513,6 +513,7 @@ static EDealRes dispatchPhysiPlan(SNode* pNode, ETraversalOrder order, FNodeWalk
break;
}
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
+ case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
break;
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c
index eeb069383f81109871c0dbd9eb92ee99820c4b17..af7ebf5d102f27a1b9ebdab3224ca44c3e418f65 100644
--- a/source/libs/nodes/src/nodesUtilFuncs.c
+++ b/source/libs/nodes/src/nodesUtilFuncs.c
@@ -252,6 +252,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SSortPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
return makeNode(type, sizeof(SIntervalPhysiNode));
+ case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
+ return makeNode(type, sizeof(SStreamIntervalPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_FILL:
return makeNode(type, sizeof(SFillPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
@@ -644,6 +646,7 @@ void nodesDestroyNode(SNodeptr pNode) {
break;
}
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
+ case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
break;
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c
index ee1a92d8b35248cd315a432dc70f10f21f936f17..ebc8281f562421dd7b95355e015d78b7eb0f8021 100644
--- a/source/libs/parser/src/parAstParser.c
+++ b/source/libs/parser/src/parAstParser.c
@@ -64,8 +64,8 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) {
goto abort_parse;
}
default:
- Parse(pParser, t0.type, t0, &cxt);
// ParseTrace(stdout, "");
+ Parse(pParser, t0.type, t0, &cxt);
if (TSDB_CODE_SUCCESS != cxt.errCode) {
goto abort_parse;
}
diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c
index 54a0fce3e7f05e65fbcd632a2d0fd7e752a9a663..01327c08efb4a7de9f811e68bbd2d96156b4f3f8 100644
--- a/source/libs/parser/src/parTokenizer.c
+++ b/source/libs/parser/src/parTokenizer.c
@@ -590,6 +590,8 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
if (seg == 4) { // ip address
*tokenId = TK_NK_IPTOKEN;
return i;
+ } else if (seg > 2) {
+ break;
}
if ((z[i] == 'e' || z[i] == 'E') &&
diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c
index 1bd7e28c74b9e3bbffbc71058ff3603a979825cc..d40da8a6298b82f578db71cc8fd4ffe43a0191bc 100644
--- a/source/libs/parser/src/parTranslater.c
+++ b/source/libs/parser/src/parTranslater.c
@@ -699,6 +699,10 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
if (isCountStar(pFunc)) {
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
}
+
+ if (fmIsRepeatScanFunc(pFunc->funcId)) {
+ pCxt->pCurrStmt->hasRepeatScanFuncs = true;
+ }
}
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
}
@@ -2255,8 +2259,8 @@ static int32_t checkTableColsSchema(STranslateContext* pCxt, SHashObj* pHash, SN
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
}
if (TSDB_CODE_SUCCESS == code) {
- if ((TSDB_DATA_TYPE_VARCHAR == pCol->dataType.type && pCol->dataType.bytes > TSDB_MAX_BINARY_LEN) ||
- (TSDB_DATA_TYPE_NCHAR == pCol->dataType.type && pCol->dataType.bytes > TSDB_MAX_NCHAR_LEN)) {
+ if ((TSDB_DATA_TYPE_VARCHAR == pCol->dataType.type && calcTypeBytes(pCol->dataType) > TSDB_MAX_BINARY_LEN) ||
+ (TSDB_DATA_TYPE_NCHAR == pCol->dataType.type && calcTypeBytes(pCol->dataType) > TSDB_MAX_NCHAR_LEN)) {
code = code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
}
}
diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c
index 3e19ccbd82b8004849751fe941a81c9c2127f037..d4b9f5b2922c01d833244ed99ba9903f23e2615a 100644
--- a/source/libs/planner/src/planLogicCreater.c
+++ b/source/libs/planner/src/planLogicCreater.c
@@ -54,6 +54,9 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
pCol->node.resType = pToBeRewrittenExpr->resType;
strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName);
+ if (QUERY_NODE_FUNCTION == nodeType(pExpr) && FUNCTION_TYPE_WSTARTTS == ((SFunctionNode*)pExpr)->funcType) {
+ pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
+ }
nodesDestroyNode(*pNode);
*pNode = (SNode*)pCol;
return DEAL_RES_IGNORE_CHILD;
@@ -253,7 +256,7 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
TSWAP(pScan->pMeta, pRealTable->pMeta);
TSWAP(pScan->pVgroupList, pRealTable->pVgroupList);
- pScan->scanSeq[0] = 1;
+ pScan->scanSeq[0] = pSelect->hasRepeatScanFuncs ? 2 : 1;
pScan->scanSeq[1] = 0;
pScan->scanRange = TSWINDOW_INITIALIZER;
pScan->tableName.type = TSDB_TABLE_NAME_T;
diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c
index dbce9abf36c64739285480dc3ebe2cd0bab35e08..30f6f03a6cd6214a131d4a56be29a77d407f7468 100644
--- a/source/libs/planner/src/planOptimizer.c
+++ b/source/libs/planner/src/planOptimizer.c
@@ -754,10 +754,7 @@ static int32_t opkDoOptimized(SOptimizeContext* pCxt, SSortLogicNode* pSort, SNo
EOrder order = opkGetPrimaryKeyOrder(pSort);
if (ORDER_DESC == order) {
SNode* pScan = NULL;
- FOREACH(pScan, pScanNodes) {
- ((SScanLogicNode*)pScan)->scanSeq[0] = 0;
- ((SScanLogicNode*)pScan)->scanSeq[1] = 1;
- }
+ FOREACH(pScan, pScanNodes) { TSWAP(((SScanLogicNode*)pScan)->scanSeq[0], ((SScanLogicNode*)pScan)->scanSeq[1]); }
}
if (NULL == pSort->node.pParent) {
diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c
index 18fa5b93dd4e728521c2bbf4db003639a1c767e8..835d607099d919196af6c641ea0ba062b5752a12 100644
--- a/source/libs/planner/src/planPhysiCreater.c
+++ b/source/libs/planner/src/planPhysiCreater.c
@@ -869,7 +869,8 @@ static int32_t createWindowPhysiNodeFinalize(SPhysiPlanContext* pCxt, SNodeList*
static int32_t createIntervalPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SWindowLogicNode* pWindowLogicNode, SPhysiNode** pPhyNode) {
SIntervalPhysiNode* pInterval = (SIntervalPhysiNode*)makePhysiNode(
- pCxt, getPrecision(pChildren), (SLogicNode*)pWindowLogicNode, QUERY_NODE_PHYSICAL_PLAN_INTERVAL);
+ pCxt, getPrecision(pChildren), (SLogicNode*)pWindowLogicNode,
+ (pCxt->pPlanCxt->streamQuery ? QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL : QUERY_NODE_PHYSICAL_PLAN_INTERVAL));
if (NULL == pInterval) {
return TSDB_CODE_OUT_OF_MEMORY;
}
diff --git a/source/libs/planner/test/planBasicTest.cpp b/source/libs/planner/test/planBasicTest.cpp
index 639af2875eb8548378d136bf1a26ad4be4521fec..a17d8cd850d51ed38877b2db1550865408879666 100644
--- a/source/libs/planner/test/planBasicTest.cpp
+++ b/source/libs/planner/test/planBasicTest.cpp
@@ -48,4 +48,6 @@ TEST_F(PlanBasicTest, func) {
useDb("root", "test");
run("SELECT DIFF(c1) FROM t1");
+
+ run("SELECT PERCENTILE(c1, 60) FROM t1");
}
diff --git a/source/libs/planner/test/planOptimizeTest.cpp b/source/libs/planner/test/planOptimizeTest.cpp
index 4938618db62fc496eb8ce935c713713289039852..6c7b1d0a0e9bb2f757f36915af33065566b7c6d9 100644
--- a/source/libs/planner/test/planOptimizeTest.cpp
+++ b/source/libs/planner/test/planOptimizeTest.cpp
@@ -37,4 +37,6 @@ TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
run("SELECT * FROM t1 ORDER BY ts DESC");
run("SELECT c1 FROM t1 ORDER BY ts");
run("SELECT c1 FROM t1 ORDER BY ts DESC");
+
+ run("SELECT COUNT(*) FROM t1 INTERVAL(10S) ORDER BY _WSTARTTS DESC");
}
diff --git a/source/libs/qcom/src/queryUtil.c b/source/libs/qcom/src/queryUtil.c
index 288d2e5f766c2696e473ef3a4067c74f0d3b9eae..3e3e393f5f0283add29a313302515b38b5b81d4e 100644
--- a/source/libs/qcom/src/queryUtil.c
+++ b/source/libs/qcom/src/queryUtil.c
@@ -136,7 +136,8 @@ int32_t taosAsyncExec(__async_exec_fn_t execFn, void* execParam, int32_t* code)
return 0;
}
-int32_t asyncSendMsgToServerExt(void* pTransporter, SEpSet* epSet, int64_t* pTransporterId, const SMsgSendInfo* pInfo, bool persistHandle, void *rpcCtx) {
+int32_t asyncSendMsgToServerExt(void* pTransporter, SEpSet* epSet, int64_t* pTransporterId, const SMsgSendInfo* pInfo,
+ bool persistHandle, void* rpcCtx) {
char* pMsg = rpcMallocCont(pInfo->msgInfo.len);
if (NULL == pMsg) {
qError("0x%" PRIx64 " msg:%s malloc failed", pInfo->requestId, TMSG_INFO(pInfo->msgType));
diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c
index 9a8dcc57d904aceb581b159aae755ba2170fbdfe..911d8384f076a6ab36dfddfceeec623b794afab9 100644
--- a/source/libs/sync/src/syncMain.c
+++ b/source/libs/sync/src/syncMain.c
@@ -522,6 +522,7 @@ void syncNodeClose(SSyncNode* pSyncNode) {
ret = raftStoreClose(pSyncNode->pRaftStore);
assert(ret == 0);
+ syncRespMgrDestroy(pSyncNode->pSyncRespMgr);
voteGrantedDestroy(pSyncNode->pVotesGranted);
votesRespondDestory(pSyncNode->pVotesRespond);
syncIndexMgrDestroy(pSyncNode->pNextIndex);
@@ -1138,6 +1139,7 @@ static int32_t syncNodeAppendNoop(SSyncNode* ths) {
syncNodeReplicate(ths);
}
+ syncEntryDestory(pEntry);
return ret;
}
diff --git a/source/util/test/encodeTest.cpp b/source/util/test/encodeTest.cpp
index 00e12a4fe8975456bf5336b0371c72b0a7e506a2..974677d26c9baa660fa0f92b627291fd192a29e0 100644
--- a/source/util/test/encodeTest.cpp
+++ b/source/util/test/encodeTest.cpp
@@ -440,6 +440,7 @@ TEST(td_encode_test, compound_struct_encode_test) {
tCoderClear(&decoder);
}
#endif
+
#pragma GCC diagnostic pop
#endif
diff --git a/tests/script/sh/exec.sh b/tests/script/sh/exec.sh
index 1310cf26566615f63d53b6b7723b7ea3533f1cba..74015eebd64317006ae1c808d2fe37512bbf8b03 100755
--- a/tests/script/sh/exec.sh
+++ b/tests/script/sh/exec.sh
@@ -101,8 +101,8 @@ if [ "$EXEC_OPTON" = "start" ]; then
if [ "$VALGRIND_OPTION" = "true" ]; then
TT=`date +%s`
#mkdir ${LOG_DIR}/${TT}
- echo "nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &"
- nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &
+ echo "nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &"
+ nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &
else
echo "nohup $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &"
nohup $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &
diff --git a/tests/script/test.sh b/tests/script/test.sh
index e4191da0a91a85584b9aefa21547bcef06e6fb92..1cfe8dd6f56bc4a38895fa5d75f701abffccd59b 100755
--- a/tests/script/test.sh
+++ b/tests/script/test.sh
@@ -131,8 +131,8 @@ if [ -n "$FILE_NAME" ]; then
FLAG="-v"
fi
- echo valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --child-silent-after-fork=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes --log-file=${LOG_DIR}/valgrind-tsim.log $PROGRAM -c $CFG_DIR -f $FILE_NAME $FLAG
- valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --child-silent-after-fork=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes --log-file=${LOG_DIR}/valgrind-tsim.log $PROGRAM -c $CFG_DIR -f $FILE_NAME $FLAG
+ echo valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --child-silent-after-fork=yes --show-leak-kinds=all --num-callers=20 -v --workaround-gcc296-bugs=yes --log-file=${LOG_DIR}/valgrind-tsim.log $PROGRAM -c $CFG_DIR -f $FILE_NAME $FLAG
+ valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --child-silent-after-fork=yes --show-leak-kinds=all --num-callers=20 -v --workaround-gcc296-bugs=yes --log-file=${LOG_DIR}/valgrind-tsim.log $PROGRAM -c $CFG_DIR -f $FILE_NAME $FLAG
else
if [[ $MULTIPROCESS -eq 1 ]];then
echo "ExcuteCmd(multiprocess):" $PROGRAM -m -c $CFG_DIR -f $FILE_NAME
diff --git a/tests/script/tsim/insert/basic0.sim b/tests/script/tsim/insert/basic0.sim
index 94bd0f1ecffb388af56773a241b5f89982e5b23a..d8dde20e4e92f762c6dfca5435f0d92b9a3ffdb9 100644
--- a/tests/script/tsim/insert/basic0.sim
+++ b/tests/script/tsim/insert/basic0.sim
@@ -140,7 +140,8 @@ endi
if $data00 != -13 then
return -1
endi
-if $data01 != -2.30000 then
+if $data01 != -2.30000 then
+ print expect -2.30000, actual: $data01
return -1
endi
if $data02 != -3.300000000 then
diff --git a/tests/system-test/2-query/diff.py b/tests/system-test/2-query/diff.py
index 82c450771fc04f2f3d0cb877398d0b9ca97b3276..1a6a2e7cf135095bd2967d03e23df2aa1b723a06 100644
--- a/tests/system-test/2-query/diff.py
+++ b/tests/system-test/2-query/diff.py
@@ -1,3 +1,4 @@
+from wsgiref.headers import tspecials
from util.log import *
from util.cases import *
from util.sql import *
@@ -27,6 +28,36 @@ class TDTestCase:
def run(self):
tdSql.prepare()
+ tdSql.execute("create table ntb(ts timestamp,c1 int,c2 double,c3 float)")
+ tdSql.execute("insert into ntb values(now,1,1.0,10.5)(now+1s,10,-100.0,5.1)(now+10s,-1,15.1,5.0)")
+
+ tdSql.query("select diff(c1,0) from ntb")
+ tdSql.checkRows(2)
+ tdSql.checkData(0,0,9)
+ tdSql.checkData(1,0,-11)
+ tdSql.query("select diff(c1,1) from ntb")
+ tdSql.checkRows(2)
+ tdSql.checkData(0,0,9)
+ tdSql.checkData(1,0,None)
+
+ tdSql.query("select diff(c2,0) from ntb")
+ tdSql.checkRows(2)
+ tdSql.checkData(0,0,-101)
+ tdSql.checkData(1,0,115.1)
+ tdSql.query("select diff(c2,1) from ntb")
+ tdSql.checkRows(2)
+ tdSql.checkData(0,0,None)
+ tdSql.checkData(1,0,115.1)
+
+ tdSql.query("select diff(c3,0) from ntb")
+ tdSql.checkRows(2)
+ tdSql.checkData(0,0,-5.4)
+ tdSql.checkData(1,0,-0.1)
+ tdSql.query("select diff(c3,1) from ntb")
+ tdSql.checkRows(2)
+ tdSql.checkData(0,0,None)
+ tdSql.checkData(1,0,None)
+
tdSql.execute('''create table stb(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
col7 bool, col8 binary(20), col9 nchar(20), col11 tinyint unsigned, col12 smallint unsigned, col13 int unsigned, col14 bigint unsigned) tags(loc nchar(20))''')
@@ -58,12 +89,6 @@ class TDTestCase:
tdSql.error("select diff(ts) from stb")
tdSql.error("select diff(ts) from stb_1")
- tdSql.error("select diff(col1) from stb")
- tdSql.error("select diff(col2) from stb")
- tdSql.error("select diff(col3) from stb")
- tdSql.error("select diff(col4) from stb")
- tdSql.error("select diff(col5) from stb")
- tdSql.error("select diff(col6) from stb")
tdSql.error("select diff(col7) from stb")
tdSql.error("select diff(col7) from stb_1")
tdSql.error("select diff(col8) from stb")
@@ -74,10 +99,6 @@ class TDTestCase:
tdSql.error("select diff(col12) from stb_1")
tdSql.error("select diff(col13) from stb_1")
tdSql.error("select diff(col14) from stb_1")
- tdSql.error("select diff(col11) from stb")
- tdSql.error("select diff(col12) from stb")
- tdSql.error("select diff(col13) from stb")
- tdSql.error("select diff(col14) from stb")
tdSql.query("select ts,diff(col1),ts from stb_1")
tdSql.checkRows(10)
@@ -88,14 +109,14 @@ class TDTestCase:
tdSql.checkData(9, 1, "2018-09-17 09:00:00.009")
tdSql.checkData(9, 3, "2018-09-17 09:00:00.009")
- tdSql.query("select ts,diff(col1),ts from stb group by tbname")
- tdSql.checkRows(10)
- tdSql.checkData(0, 0, "2018-09-17 09:00:00.000")
- tdSql.checkData(0, 1, "2018-09-17 09:00:00.000")
- tdSql.checkData(0, 3, "2018-09-17 09:00:00.000")
- tdSql.checkData(9, 0, "2018-09-17 09:00:00.009")
- tdSql.checkData(9, 1, "2018-09-17 09:00:00.009")
- tdSql.checkData(9, 3, "2018-09-17 09:00:00.009")
+ # tdSql.query("select ts,diff(col1),ts from stb group by tbname")
+ # tdSql.checkRows(10)
+ # tdSql.checkData(0, 0, "2018-09-17 09:00:00.000")
+ # tdSql.checkData(0, 1, "2018-09-17 09:00:00.000")
+ # tdSql.checkData(0, 3, "2018-09-17 09:00:00.000")
+ # tdSql.checkData(9, 0, "2018-09-17 09:00:00.009")
+ # tdSql.checkData(9, 1, "2018-09-17 09:00:00.009")
+ # tdSql.checkData(9, 3, "2018-09-17 09:00:00.009")
tdSql.query("select ts,diff(col1),ts from stb_1")
tdSql.checkRows(10)
@@ -106,14 +127,14 @@ class TDTestCase:
tdSql.checkData(9, 1, "2018-09-17 09:00:00.009")
tdSql.checkData(9, 3, "2018-09-17 09:00:00.009")
- tdSql.query("select ts,diff(col1),ts from stb group by tbname")
- tdSql.checkRows(10)
- tdSql.checkData(0, 0, "2018-09-17 09:00:00.000")
- tdSql.checkData(0, 1, "2018-09-17 09:00:00.000")
- tdSql.checkData(0, 3, "2018-09-17 09:00:00.000")
- tdSql.checkData(9, 0, "2018-09-17 09:00:00.009")
- tdSql.checkData(9, 1, "2018-09-17 09:00:00.009")
- tdSql.checkData(9, 3, "2018-09-17 09:00:00.009")
+ # tdSql.query("select ts,diff(col1),ts from stb group by tbname")
+ # tdSql.checkRows(10)
+ # tdSql.checkData(0, 0, "2018-09-17 09:00:00.000")
+ # tdSql.checkData(0, 1, "2018-09-17 09:00:00.000")
+ # tdSql.checkData(0, 3, "2018-09-17 09:00:00.000")
+ # tdSql.checkData(9, 0, "2018-09-17 09:00:00.009")
+ # tdSql.checkData(9, 1, "2018-09-17 09:00:00.009")
+ # tdSql.checkData(9, 3, "2018-09-17 09:00:00.009")
tdSql.query("select diff(col1) from stb_1")
tdSql.checkRows(10)
diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh
index f713f707cb8ae954a4371df7cdd800f74e477d39..4009f10d70634120256518710f75a398d238c7d0 100755
--- a/tests/system-test/fulltest.sh
+++ b/tests/system-test/fulltest.sh
@@ -31,8 +31,8 @@ python3 ./test.py -f 2-query/last.py
#python3 ./test.py -f 2-query/To_iso8601.py
python3 ./test.py -f 2-query/To_unixtimestamp.py
python3 ./test.py -f 2-query/timetruncate.py
-
-# python3 ./test.py -f 2-query/Timediff.py
+# python3 ./test.py -f 2-query/diff.py
+python3 ./test.py -f 2-query/Timediff.py
#python3 ./test.py -f 2-query/cast.py
diff --git a/tools/taos-tools b/tools/taos-tools
index 2f3dfddd4d9a869e706ba3cf98fb6d769404cd7c..0ae9f872c26d5da8cb61aa9eb00b5c7aeba10ec4 160000
--- a/tools/taos-tools
+++ b/tools/taos-tools
@@ -1 +1 @@
-Subproject commit 2f3dfddd4d9a869e706ba3cf98fb6d769404cd7c
+Subproject commit 0ae9f872c26d5da8cb61aa9eb00b5c7aeba10ec4