Merge remote-tracking branch 'origin/3.0' into feature/dnode
This commit is contained in:
commit
bd817f1a6f
|
@ -44,7 +44,6 @@ ENDIF ()
|
|||
|
||||
IF (TD_WINDOWS)
|
||||
MESSAGE("${Yellow} set compiler flag for Windows! ${ColourReset}")
|
||||
SET(CMAKE_GENERATOR "NMake Makefiles" CACHE INTERNAL "" FORCE)
|
||||
SET(COMMON_FLAGS "/W3 /D_WIN32")
|
||||
|
||||
# IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900))
|
||||
|
|
|
@ -28,15 +28,16 @@ typedef int64_t tb_uid_t;
|
|||
#define TSWINDOW_INITIALIZER ((STimeWindow){INT64_MIN, INT64_MAX})
|
||||
#define TSWINDOW_DESC_INITIALIZER ((STimeWindow){INT64_MAX, INT64_MIN})
|
||||
#define IS_TSWINDOW_SPECIFIED(win) (((win).skey != INT64_MIN) || ((win).ekey != INT64_MAX))
|
||||
#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))
|
||||
|
||||
typedef enum {
|
||||
TSDB_SUPER_TABLE = 1, // super table
|
||||
TSDB_CHILD_TABLE = 2, // table created from super table
|
||||
TSDB_NORMAL_TABLE = 3, // ordinary table
|
||||
TSDB_STREAM_TABLE = 4, // table created from stream computing
|
||||
TSDB_TEMP_TABLE = 5, // temp table created by nest query
|
||||
TSDB_SUPER_TABLE = 1, // super table
|
||||
TSDB_CHILD_TABLE = 2, // table created from super table
|
||||
TSDB_NORMAL_TABLE = 3, // ordinary table
|
||||
TSDB_STREAM_TABLE = 4, // table created from stream computing
|
||||
TSDB_TEMP_TABLE = 5, // temp table created by nest query
|
||||
TSDB_SYSTEM_TABLE = 6,
|
||||
TSDB_TABLE_MAX = 7
|
||||
TSDB_TABLE_MAX = 7
|
||||
} ETableType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -78,15 +79,15 @@ typedef enum {
|
|||
} ETsdbSmaType;
|
||||
|
||||
typedef enum {
|
||||
TSDB_RSMA_RETENTION_0 = 0,
|
||||
TSDB_RSMA_RETENTION_1 = 1,
|
||||
TSDB_RSMA_RETENTION_2 = 2,
|
||||
TSDB_RSMA_RETENTION_MAX = 3
|
||||
} ERSmaRetention;
|
||||
TSDB_RETENTION_L0 = 0,
|
||||
TSDB_RETENTION_L1 = 1,
|
||||
TSDB_RETENTION_L2 = 2,
|
||||
TSDB_RETENTION_MAX = 3
|
||||
} ERetentionLevel;
|
||||
|
||||
extern char *qtypeStr[];
|
||||
|
||||
#define TSDB_PORT_HTTP 11
|
||||
#define TSDB_PORT_HTTP 11
|
||||
|
||||
#undef TD_DEBUG_PRINT_ROW
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ typedef struct SDataBlockInfo {
|
|||
uint64_t groupId; // no need to serialize
|
||||
int16_t numOfCols;
|
||||
int16_t hasVarCol;
|
||||
int16_t capacity;
|
||||
int32_t capacity;
|
||||
} SDataBlockInfo;
|
||||
|
||||
typedef struct SSDataBlock {
|
||||
|
|
|
@ -183,7 +183,7 @@ static FORCE_INLINE void colDataAppendDouble(SColumnInfoData* pColumnInfoData, u
|
|||
}
|
||||
|
||||
int32_t colDataAppend(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, bool isNull);
|
||||
int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, uint32_t numOfRow1, const SColumnInfoData* pSource,
|
||||
int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, uint32_t numOfRow1, int32_t* capacity, const SColumnInfoData* pSource,
|
||||
uint32_t numOfRow2);
|
||||
int32_t colDataAssign(SColumnInfoData* pColumnInfoData, const SColumnInfoData* pSource, int32_t numOfRows);
|
||||
int32_t blockDataUpdateTsWindow(SSDataBlock* pDataBlock);
|
||||
|
@ -225,6 +225,9 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData);
|
|||
|
||||
void blockDebugShowData(const SArray* dataBlocks);
|
||||
|
||||
int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks, STSchema* pTSchema, int32_t vgId,
|
||||
tb_uid_t uid, tb_uid_t suid);
|
||||
|
||||
static FORCE_INLINE int32_t blockGetEncodeSize(const SSDataBlock* pBlock) {
|
||||
return blockDataGetSerialMetaSize(pBlock) + blockDataGetSize(pBlock);
|
||||
}
|
||||
|
|
|
@ -64,19 +64,19 @@ typedef struct {
|
|||
col_id_t colId; // column ID(start from PRIMARYKEY_TIMESTAMP_COL_ID(1))
|
||||
int32_t type : 8; // column type
|
||||
int32_t bytes : 24; // column bytes (0~16M)
|
||||
int32_t sma : 8; // block SMA: 0, no SMA, 1, sum/min/max, 2, ...
|
||||
int32_t flags : 8; // flags: 0 no index, 1 SCHEMA_SMA_ON, 2 SCHEMA_IDX_ON
|
||||
int32_t offset : 24; // point offset in STpRow after the header part.
|
||||
} STColumn;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define colType(col) ((col)->type)
|
||||
#define colSma(col) ((col)->sma)
|
||||
#define colFlags(col) ((col)->flags)
|
||||
#define colColId(col) ((col)->colId)
|
||||
#define colBytes(col) ((col)->bytes)
|
||||
#define colOffset(col) ((col)->offset)
|
||||
|
||||
#define colSetType(col, t) (colType(col) = (t))
|
||||
#define colSetSma(col, s) (colSma(col) = (s))
|
||||
#define colSetFlags(col, f) (colFlags(col) = (f))
|
||||
#define colSetColId(col, id) (colColId(col) = (id))
|
||||
#define colSetBytes(col, b) (colBytes(col) = (b))
|
||||
#define colSetOffset(col, o) (colOffset(col) = (o))
|
||||
|
@ -146,7 +146,7 @@ typedef struct {
|
|||
int32_t tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version);
|
||||
void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder);
|
||||
void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version);
|
||||
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t sma, col_id_t colId, col_bytes_t bytes);
|
||||
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, col_id_t colId, col_bytes_t bytes);
|
||||
STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder);
|
||||
|
||||
// ----------------- Semantic timestamp key definition
|
||||
|
|
|
@ -181,8 +181,8 @@ typedef struct SField {
|
|||
} SField;
|
||||
|
||||
typedef struct SRetention {
|
||||
int32_t freq;
|
||||
int32_t keep;
|
||||
int64_t freq;
|
||||
int64_t keep;
|
||||
int8_t freqUnit;
|
||||
int8_t keepUnit;
|
||||
} SRetention;
|
||||
|
@ -243,18 +243,9 @@ typedef struct {
|
|||
|
||||
int32_t tInitSubmitMsgIter(const SSubmitReq* pMsg, SSubmitMsgIter* pIter);
|
||||
int32_t tGetSubmitMsgNext(SSubmitMsgIter* pIter, SSubmitBlk** pPBlock);
|
||||
int32_t tInitSubmitBlkIter(SSubmitBlk* pBlock, SSubmitBlkIter* pIter);
|
||||
int32_t tInitSubmitBlkIter(SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, SSubmitBlkIter* pIter);
|
||||
STSRow* tGetSubmitBlkNext(SSubmitBlkIter* pIter);
|
||||
|
||||
// TODO: KEEP one suite of iterator API finally.
|
||||
// 1) use tInitSubmitMsgIterEx firstly as not decrease the merge conflicts
|
||||
// 2) replace tInitSubmitMsgIterEx with tInitSubmitMsgIter later
|
||||
// 3) finally, rename tInitSubmitMsgIterEx to tInitSubmitMsgIter
|
||||
int32_t tInitSubmitMsgIterEx(const SSubmitReq* pMsg, SSubmitMsgIter* pIter);
|
||||
int32_t tGetSubmitMsgNextEx(SSubmitMsgIter* pIter, SSubmitBlk** pPBlock);
|
||||
int32_t tInitSubmitBlkIterEx(SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, SSubmitBlkIter* pIter);
|
||||
STSRow* tGetSubmitBlkNextEx(SSubmitBlkIter* pIter);
|
||||
|
||||
typedef struct {
|
||||
int32_t index; // index of failed block in submit blocks
|
||||
int32_t vnode; // vnode index of failed block
|
||||
|
@ -281,8 +272,10 @@ typedef struct SSchema {
|
|||
char name[TSDB_COL_NAME_LEN];
|
||||
} SSchema;
|
||||
|
||||
#define IS_BSMA_ON(s) (((s)->flags & 0x01) == SCHEMA_SMA_ON)
|
||||
|
||||
#define SSCHMEA_TYPE(s) ((s)->type)
|
||||
#define SSCHMEA_SMA(s) ((s)->sma)
|
||||
#define SSCHMEA_FLAGS(s) ((s)->flags)
|
||||
#define SSCHMEA_COLID(s) ((s)->colId)
|
||||
#define SSCHMEA_BYTES(s) ((s)->bytes)
|
||||
#define SSCHMEA_NAME(s) ((s)->name)
|
||||
|
@ -842,7 +835,7 @@ typedef struct {
|
|||
char db[TSDB_DB_FNAME_LEN];
|
||||
int64_t dbUid;
|
||||
int32_t vgVersion;
|
||||
int32_t numOfStables;
|
||||
int32_t numOfStables;
|
||||
int32_t buffer;
|
||||
int32_t pageSize;
|
||||
int32_t pages;
|
||||
|
@ -1442,32 +1435,32 @@ typedef struct {
|
|||
SArray* lostConsumers; // SArray<int64_t>
|
||||
SArray* removedConsumers; // SArray<int64_t>
|
||||
SArray* newConsumers; // SArray<int64_t>
|
||||
} SMqRebSubscribe;
|
||||
} SMqRebInfo;
|
||||
|
||||
static FORCE_INLINE SMqRebSubscribe* tNewSMqRebSubscribe(const char* key) {
|
||||
SMqRebSubscribe* pRebSub = (SMqRebSubscribe*)taosMemoryCalloc(1, sizeof(SMqRebSubscribe));
|
||||
if (pRebSub == NULL) {
|
||||
static FORCE_INLINE SMqRebInfo* tNewSMqRebSubscribe(const char* key) {
|
||||
SMqRebInfo* pRebInfo = (SMqRebInfo*)taosMemoryCalloc(1, sizeof(SMqRebInfo));
|
||||
if (pRebInfo == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
strcpy(pRebSub->key, key);
|
||||
pRebSub->lostConsumers = taosArrayInit(0, sizeof(int64_t));
|
||||
if (pRebSub->lostConsumers == NULL) {
|
||||
strcpy(pRebInfo->key, key);
|
||||
pRebInfo->lostConsumers = taosArrayInit(0, sizeof(int64_t));
|
||||
if (pRebInfo->lostConsumers == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
pRebSub->removedConsumers = taosArrayInit(0, sizeof(int64_t));
|
||||
if (pRebSub->removedConsumers == NULL) {
|
||||
pRebInfo->removedConsumers = taosArrayInit(0, sizeof(int64_t));
|
||||
if (pRebInfo->removedConsumers == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
pRebSub->newConsumers = taosArrayInit(0, sizeof(int64_t));
|
||||
if (pRebSub->newConsumers == NULL) {
|
||||
pRebInfo->newConsumers = taosArrayInit(0, sizeof(int64_t));
|
||||
if (pRebInfo->newConsumers == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
return pRebSub;
|
||||
return pRebInfo;
|
||||
_err:
|
||||
taosArrayDestroy(pRebSub->lostConsumers);
|
||||
taosArrayDestroy(pRebSub->removedConsumers);
|
||||
taosArrayDestroy(pRebSub->newConsumers);
|
||||
taosMemoryFreeClear(pRebSub);
|
||||
taosArrayDestroy(pRebInfo->lostConsumers);
|
||||
taosArrayDestroy(pRebInfo->removedConsumers);
|
||||
taosArrayDestroy(pRebInfo->newConsumers);
|
||||
taosMemoryFreeClear(pRebInfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ typedef int32_t (*GetQueueSizeFp)(SMgmtWrapper* pWrapper, int32_t vgId, EQueueTy
|
|||
typedef int32_t (*SendReqFp)(SMgmtWrapper* pWrapper, const SEpSet* epSet, SRpcMsg* pReq);
|
||||
typedef int32_t (*SendMnodeReqFp)(SMgmtWrapper* pWrapper, SRpcMsg* pReq);
|
||||
typedef void (*SendRspFp)(SMgmtWrapper* pWrapper, const SRpcMsg* pRsp);
|
||||
typedef void (*SendRedirectRspFp)(SMgmtWrapper* pWrapper, const SRpcMsg* pRsp, const SEpSet* pNewEpSet);
|
||||
typedef void (*RegisterBrokenLinkArgFp)(SMgmtWrapper* pWrapper, SRpcMsg* pMsg);
|
||||
typedef void (*ReleaseHandleFp)(SMgmtWrapper* pWrapper, void* handle, int8_t type);
|
||||
typedef void (*ReportStartup)(SMgmtWrapper* pWrapper, const char* name, const char* desc);
|
||||
|
@ -52,6 +53,7 @@ typedef struct {
|
|||
GetQueueSizeFp qsizeFp;
|
||||
SendReqFp sendReqFp;
|
||||
SendRspFp sendRspFp;
|
||||
SendRedirectRspFp sendRedirectRspFp;
|
||||
RegisterBrokenLinkArgFp registerBrokenLinkArgFp;
|
||||
ReleaseHandleFp releaseHandleFp;
|
||||
ReportStartup reportStartupFp;
|
||||
|
@ -62,6 +64,7 @@ int32_t tmsgPutToQueue(const SMsgCb* pMsgCb, EQueueType qtype, SRpcMsg* pReq);
|
|||
int32_t tmsgGetQueueSize(const SMsgCb* pMsgCb, int32_t vgId, EQueueType qtype);
|
||||
int32_t tmsgSendReq(const SMsgCb* pMsgCb, const SEpSet* epSet, SRpcMsg* pReq);
|
||||
void tmsgSendRsp(const SRpcMsg* pRsp);
|
||||
void tmsgSendRedirectRsp(const SRpcMsg* pRsp, const SEpSet* pNewEpSet);
|
||||
void tmsgRegisterBrokenLinkArg(const SMsgCb* pMsgCb, SRpcMsg* pMsg);
|
||||
void tmsgReleaseHandle(void* handle, int8_t type);
|
||||
void tmsgReportStartup(const char* name, const char* desc);
|
||||
|
|
|
@ -202,6 +202,7 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_VND_CREATE_SMA, "vnode-create-sma", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_CANCEL_SMA, "vnode-cancel-sma", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_DROP_SMA, "vnode-drop-sma", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SUBMIT_RSMA, "vnode-submit-rsma", SSubmitReq, SSubmitRsp)
|
||||
|
||||
// sync integration
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_TIMEOUT, "vnode-sync-timeout", NULL, NULL)
|
||||
|
|
|
@ -113,6 +113,9 @@ typedef enum EFunctionType {
|
|||
FUNCTION_TYPE_WENDTS,
|
||||
FUNCTION_TYPE_WDURATION,
|
||||
|
||||
// internal function
|
||||
FUNCTION_TYPE_SELECT_VALUE,
|
||||
|
||||
// user defined funcion
|
||||
FUNCTION_TYPE_UDF = 10000
|
||||
} EFunctionType;
|
||||
|
@ -141,6 +144,7 @@ bool fmIsScalarFunc(int32_t funcId);
|
|||
bool fmIsNonstandardSQLFunc(int32_t funcId);
|
||||
bool fmIsStringFunc(int32_t funcId);
|
||||
bool fmIsDatetimeFunc(int32_t funcId);
|
||||
bool fmIsSelectFunc(int32_t funcId);
|
||||
bool fmIsTimelineFunc(int32_t funcId);
|
||||
bool fmIsTimeorderFunc(int32_t funcId);
|
||||
bool fmIsPseudoColumnFunc(int32_t funcId);
|
||||
|
|
|
@ -185,6 +185,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_LOGIC_PLAN_VNODE_MODIF,
|
||||
QUERY_NODE_LOGIC_PLAN_EXCHANGE,
|
||||
QUERY_NODE_LOGIC_PLAN_WINDOW,
|
||||
QUERY_NODE_LOGIC_PLAN_FILL,
|
||||
QUERY_NODE_LOGIC_PLAN_SORT,
|
||||
QUERY_NODE_LOGIC_PLAN_PARTITION,
|
||||
QUERY_NODE_LOGIC_SUBPLAN,
|
||||
|
@ -202,6 +203,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE,
|
||||
QUERY_NODE_PHYSICAL_PLAN_SORT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_FILL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW,
|
||||
QUERY_NODE_PHYSICAL_PLAN_PARTITION,
|
||||
|
|
|
@ -102,7 +102,6 @@ typedef struct SWindowLogicNode {
|
|||
int64_t sliding;
|
||||
int8_t intervalUnit;
|
||||
int8_t slidingUnit;
|
||||
SFillNode* pFill;
|
||||
int64_t sessionGap;
|
||||
SNode* pTspk;
|
||||
SNode* pStateExpr;
|
||||
|
@ -110,6 +109,14 @@ typedef struct SWindowLogicNode {
|
|||
int64_t watermark;
|
||||
} SWindowLogicNode;
|
||||
|
||||
typedef struct SFillLogicNode {
|
||||
SLogicNode node;
|
||||
EFillMode mode;
|
||||
SNode* pWStartTs;
|
||||
SNode* pValues; // SNodeListNode
|
||||
STimeWindow timeRange;
|
||||
} SFillLogicNode;
|
||||
|
||||
typedef struct SSortLogicNode {
|
||||
SLogicNode node;
|
||||
SNodeList* pSortKeys;
|
||||
|
@ -223,10 +230,12 @@ typedef struct SProjectPhysiNode {
|
|||
typedef struct SJoinPhysiNode {
|
||||
SPhysiNode node;
|
||||
EJoinType joinType;
|
||||
SNode* pOnConditions; // in or out tuple ?
|
||||
SNode* pOnConditions;
|
||||
SNodeList* pTargets;
|
||||
} SJoinPhysiNode;
|
||||
|
||||
typedef SJoinPhysiNode SSortMergeJoinPhysiNode;
|
||||
|
||||
typedef struct SAggPhysiNode {
|
||||
SPhysiNode node;
|
||||
SNodeList* pExprs; // these are expression list of group_by_clause and parameter expression of aggregate function
|
||||
|
@ -263,9 +272,17 @@ typedef struct SIntervalPhysiNode {
|
|||
int64_t sliding;
|
||||
int8_t intervalUnit;
|
||||
int8_t slidingUnit;
|
||||
SFillNode* pFill;
|
||||
} SIntervalPhysiNode;
|
||||
|
||||
typedef struct SFillPhysiNode {
|
||||
SPhysiNode node;
|
||||
EFillMode mode;
|
||||
SNode* pWStartTs; // SColumnNode
|
||||
SNode* pValues; // SNodeListNode
|
||||
SNodeList* pTargets;
|
||||
STimeWindow timeRange;
|
||||
} SFillPhysiNode;
|
||||
|
||||
typedef struct SMultiTableIntervalPhysiNode {
|
||||
SIntervalPhysiNode interval;
|
||||
SNodeList* pPartitionKeys;
|
||||
|
@ -340,7 +357,7 @@ typedef struct SQueryPlan {
|
|||
int32_t numOfSubplans;
|
||||
SNodeList* pSubplans; // Element is SNodeListNode. The execution level of subplan, starting from 0.
|
||||
SExplainInfo explainInfo;
|
||||
SArray* pPlaceholderValues;
|
||||
SArray* pPlaceholderValues;
|
||||
} SQueryPlan;
|
||||
|
||||
void nodesWalkPhysiPlan(SNode* pNode, FNodeWalker walker, void* pContext);
|
||||
|
|
|
@ -89,7 +89,7 @@ typedef struct SValueNode {
|
|||
char* p;
|
||||
} datum;
|
||||
int64_t typeData;
|
||||
char unit;
|
||||
char unit;
|
||||
} SValueNode;
|
||||
|
||||
typedef struct SOperatorNode {
|
||||
|
@ -209,9 +209,11 @@ typedef enum EFillMode {
|
|||
} EFillMode;
|
||||
|
||||
typedef struct SFillNode {
|
||||
ENodeType type; // QUERY_NODE_FILL
|
||||
EFillMode mode;
|
||||
SNode* pValues; // SNodeListNode
|
||||
ENodeType type; // QUERY_NODE_FILL
|
||||
EFillMode mode;
|
||||
SNode* pValues; // SNodeListNode
|
||||
SNode* pWStartTs; // _wstartts pseudo column
|
||||
STimeWindow timeRange;
|
||||
} SFillNode;
|
||||
|
||||
typedef struct SSelectStmt {
|
||||
|
@ -300,7 +302,7 @@ int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char*
|
|||
SNodeList** pCols);
|
||||
|
||||
typedef bool (*FFuncClassifier)(int32_t funcId);
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs);
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, FFuncClassifier classifier, SNodeList** pFuncs);
|
||||
|
||||
int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeType type, SNodeList** pNodes);
|
||||
|
||||
|
@ -314,11 +316,11 @@ bool nodesIsJsonOp(const SOperatorNode* pOp);
|
|||
bool nodesIsTimeorderQuery(const SNode* pQuery);
|
||||
bool nodesIsTimelineQuery(const SNode* pQuery);
|
||||
|
||||
void* nodesGetValueFromNode(SValueNode* pNode);
|
||||
int32_t nodesSetValueNodeValue(SValueNode* pNode, void *value);
|
||||
char* nodesGetStrValueFromNode(SValueNode* pNode);
|
||||
char* getFillModeString(EFillMode mode);
|
||||
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
|
||||
void* nodesGetValueFromNode(SValueNode* pNode);
|
||||
int32_t nodesSetValueNodeValue(SValueNode* pNode, void* value);
|
||||
char* nodesGetStrValueFromNode(SValueNode* pNode);
|
||||
char* getFillModeString(EFillMode mode);
|
||||
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ typedef struct SSyncFSM {
|
|||
struct SSyncRaftEntry;
|
||||
typedef struct SSyncRaftEntry SSyncRaftEntry;
|
||||
|
||||
#define SYNC_INDEX_BEGIN 0
|
||||
#define SYNC_INDEX_BEGIN 0
|
||||
#define SYNC_INDEX_INVALID -1
|
||||
|
||||
// abstract definition of log store in raft
|
||||
|
@ -149,6 +149,8 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg);
|
|||
ESyncState syncGetMyRole(int64_t rid);
|
||||
const char* syncGetMyRoleStr(int64_t rid);
|
||||
SyncTerm syncGetMyTerm(int64_t rid);
|
||||
void syncGetEpSet(int64_t rid, SEpSet* pEpSet);
|
||||
int32_t syncGetVgId(int64_t rid);
|
||||
|
||||
typedef enum {
|
||||
TAOS_SYNC_PROPOSE_SUCCESS = 0,
|
||||
|
|
|
@ -62,7 +62,7 @@ extern "C" {
|
|||
#define strncasecmp _strnicmp
|
||||
#define wcsncasecmp _wcsnicmp
|
||||
#define strtok_r strtok_s
|
||||
#define snprintf _snprintf
|
||||
// #define snprintf _snprintf
|
||||
#define in_addr_t unsigned long
|
||||
// #define socklen_t int
|
||||
|
||||
|
|
|
@ -619,9 +619,12 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_SLIMIT_LEAK_PARTITION_BY TAOS_DEF_ERROR_CODE(0, 0x2638)
|
||||
#define TSDB_CODE_PAR_INVALID_TOPIC_QUERY TAOS_DEF_ERROR_CODE(0, 0x2639)
|
||||
#define TSDB_CODE_PAR_INVALID_DROP_STABLE TAOS_DEF_ERROR_CODE(0, 0x263A)
|
||||
#define TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE TAOS_DEF_ERROR_CODE(0, 0x263B)
|
||||
|
||||
//planner
|
||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||
#define TSDB_CODE_PLAN_EXPECTED_TS_EQUAL TAOS_DEF_ERROR_CODE(0, 0x2701)
|
||||
#define TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN TAOS_DEF_ERROR_CODE(0, 0x2702)
|
||||
|
||||
//function
|
||||
#define TSDB_CODE_FUNC_FUNTION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2800)
|
||||
|
|
|
@ -168,13 +168,6 @@ static void doBitmapMerge(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, c
|
|||
|
||||
uint32_t total = numOfRow1 + numOfRow2;
|
||||
|
||||
if (BitmapLen(numOfRow1) < BitmapLen(total)) {
|
||||
char* tmp = taosMemoryRealloc(pColumnInfoData->nullbitmap, BitmapLen(total));
|
||||
uint32_t extend = BitmapLen(total) - BitmapLen(numOfRow1);
|
||||
memset(tmp + BitmapLen(numOfRow1), 0, extend);
|
||||
pColumnInfoData->nullbitmap = tmp;
|
||||
}
|
||||
|
||||
uint32_t remindBits = BitPos(numOfRow1);
|
||||
uint32_t shiftBits = 8 - remindBits;
|
||||
|
||||
|
@ -194,25 +187,24 @@ static void doBitmapMerge(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, c
|
|||
int32_t i = 0;
|
||||
|
||||
uint8_t* start = (uint8_t*)&pColumnInfoData->nullbitmap[BitmapLen(numOfRow1)];
|
||||
int32_t overCount = BitmapLen(total) - BitmapLen(numOfRow1);
|
||||
while (i < len) { // size limit of pSource->nullbitmap
|
||||
int32_t overCount = BitmapLen(total) - BitmapLen(numOfRow1);
|
||||
while (i < len) { // size limit of pSource->nullbitmap
|
||||
if (i >= 1) {
|
||||
start[i - 1] |= (p[i] >> remindBits); //copy remind bits
|
||||
start[i - 1] |= (p[i] >> remindBits); // copy remind bits
|
||||
}
|
||||
|
||||
if (i >= overCount) { // size limit of pColumnInfoData->nullbitmap
|
||||
if (i >= overCount) { // size limit of pColumnInfoData->nullbitmap
|
||||
return;
|
||||
}
|
||||
|
||||
start[i] |= (p[i] << shiftBits); //copy shift bits
|
||||
start[i] |= (p[i] << shiftBits); // copy shift bits
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, uint32_t numOfRow1, const SColumnInfoData* pSource,
|
||||
uint32_t numOfRow2) {
|
||||
int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, uint32_t numOfRow1, int32_t* capacity,
|
||||
const SColumnInfoData* pSource, uint32_t numOfRow2) {
|
||||
ASSERT(pColumnInfoData != NULL && pSource != NULL && pColumnInfoData->info.type == pSource->info.type);
|
||||
|
||||
if (numOfRow2 == 0) {
|
||||
return numOfRow1;
|
||||
}
|
||||
|
@ -221,14 +213,19 @@ int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, uint32_t numOfRow1, co
|
|||
pColumnInfoData->hasNull = pSource->hasNull;
|
||||
}
|
||||
|
||||
uint32_t finalNumOfRows = numOfRow1 + numOfRow2;
|
||||
if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
|
||||
// Handle the bitmap
|
||||
char* p = taosMemoryRealloc(pColumnInfoData->varmeta.offset, sizeof(int32_t) * (numOfRow1 + numOfRow2));
|
||||
if (p == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
if (finalNumOfRows > *capacity) {
|
||||
char* p = taosMemoryRealloc(pColumnInfoData->varmeta.offset, sizeof(int32_t) * (numOfRow1 + numOfRow2));
|
||||
if (p == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*capacity = finalNumOfRows;
|
||||
pColumnInfoData->varmeta.offset = (int32_t*)p;
|
||||
}
|
||||
|
||||
pColumnInfoData->varmeta.offset = (int32_t*)p;
|
||||
for (int32_t i = 0; i < numOfRow2; ++i) {
|
||||
if (pSource->varmeta.offset[i] == -1) {
|
||||
pColumnInfoData->varmeta.offset[i + numOfRow1] = -1;
|
||||
|
@ -253,15 +250,27 @@ int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, uint32_t numOfRow1, co
|
|||
memcpy(pColumnInfoData->pData + oldLen, pSource->pData, len);
|
||||
pColumnInfoData->varmeta.length = len + oldLen;
|
||||
} else {
|
||||
doBitmapMerge(pColumnInfoData, numOfRow1, pSource, numOfRow2);
|
||||
if (finalNumOfRows > *capacity) {
|
||||
char* tmp = taosMemoryRealloc(pColumnInfoData->pData, finalNumOfRows * pColumnInfoData->info.bytes);
|
||||
if (tmp == NULL) {
|
||||
return TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t newSize = (numOfRow1 + numOfRow2) * pColumnInfoData->info.bytes;
|
||||
char* tmp = taosMemoryRealloc(pColumnInfoData->pData, newSize);
|
||||
if (tmp == NULL) {
|
||||
return TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||
pColumnInfoData->pData = tmp;
|
||||
|
||||
if (BitmapLen(numOfRow1) < BitmapLen(finalNumOfRows)) {
|
||||
char* btmp = taosMemoryRealloc(pColumnInfoData->nullbitmap, BitmapLen(finalNumOfRows));
|
||||
uint32_t extend = BitmapLen(finalNumOfRows) - BitmapLen(numOfRow1);
|
||||
memset(btmp + BitmapLen(numOfRow1), 0, extend);
|
||||
|
||||
pColumnInfoData->nullbitmap = btmp;
|
||||
}
|
||||
|
||||
*capacity = finalNumOfRows;
|
||||
}
|
||||
|
||||
pColumnInfoData->pData = tmp;
|
||||
doBitmapMerge(pColumnInfoData, numOfRow1, pSource, numOfRow2);
|
||||
|
||||
int32_t offset = pColumnInfoData->info.bytes * numOfRow1;
|
||||
memcpy(pColumnInfoData->pData + offset, pSource->pData, pSource->info.bytes * numOfRow2);
|
||||
}
|
||||
|
@ -350,29 +359,22 @@ int32_t blockDataUpdateTsWindow(SSDataBlock* pDataBlock) {
|
|||
// if pIndexMap = NULL, merger one column by on column
|
||||
int32_t blockDataMerge(SSDataBlock* pDest, const SSDataBlock* pSrc, SArray* pIndexMap) {
|
||||
assert(pSrc != NULL && pDest != NULL);
|
||||
int32_t capacity = pDest->info.capacity;
|
||||
|
||||
int32_t numOfCols = pDest->info.numOfCols;
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
for (int32_t i = 0; i < pDest->info.numOfCols; ++i) {
|
||||
int32_t mapIndex = i;
|
||||
if(pIndexMap) {
|
||||
if (pIndexMap) {
|
||||
mapIndex = *(int32_t*)taosArrayGet(pIndexMap, i);
|
||||
}
|
||||
|
||||
SColumnInfoData* pCol2 = taosArrayGet(pDest->pDataBlock, i);
|
||||
SColumnInfoData* pCol1 = taosArrayGet(pSrc->pDataBlock, mapIndex);
|
||||
|
||||
uint32_t oldLen = colDataGetLength(pCol2, pDest->info.rows);
|
||||
uint32_t newLen = colDataGetLength(pCol1, pSrc->info.rows);
|
||||
|
||||
int32_t newSize = oldLen + newLen;
|
||||
char* tmp = taosMemoryRealloc(pCol2->pData, newSize);
|
||||
if (tmp != NULL) {
|
||||
pCol2->pData = tmp;
|
||||
colDataMergeCol(pCol2, pDest->info.rows, pCol1, pSrc->info.rows);
|
||||
} else {
|
||||
return TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||
}
|
||||
capacity = pDest->info.capacity;
|
||||
colDataMergeCol(pCol2, pDest->info.rows, &capacity, pCol1, pSrc->info.rows);
|
||||
}
|
||||
|
||||
pDest->info.capacity = capacity;
|
||||
pDest->info.rows += pSrc->info.rows;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -451,7 +453,6 @@ int32_t blockDataSplitRows(SSDataBlock* pBlock, bool hasVarCol, int32_t startInd
|
|||
// all fit in
|
||||
*stopIndex = numOfRows - 1;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
SSDataBlock* blockDataExtractBlock(SSDataBlock* pBlock, int32_t startIndex, int32_t rowCount) {
|
||||
|
@ -556,7 +557,7 @@ int32_t blockDataFromBuf(SSDataBlock* pBlock, const char* buf) {
|
|||
|
||||
if (IS_VAR_DATA_TYPE(pCol->info.type)) {
|
||||
size_t metaSize = pBlock->info.rows * sizeof(int32_t);
|
||||
char* tmp = taosMemoryRealloc(pCol->varmeta.offset, metaSize); // preview calloc is too small
|
||||
char* tmp = taosMemoryRealloc(pCol->varmeta.offset, metaSize); // preview calloc is too small
|
||||
if (tmp == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -938,8 +939,9 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) {
|
|||
copyBackToBlock(pDataBlock, pCols);
|
||||
int64_t p4 = taosGetTimestampUs();
|
||||
|
||||
uDebug("blockDataSort complex sort:%" PRId64 ", create:%" PRId64 ", assign:%" PRId64 ", copyback:%" PRId64 ", rows:%d\n", p1 - p0, p2 - p1,
|
||||
p3 - p2, p4 - p3, rows);
|
||||
uDebug("blockDataSort complex sort:%" PRId64 ", create:%" PRId64 ", assign:%" PRId64 ", copyback:%" PRId64
|
||||
", rows:%d\n",
|
||||
p1 - p0, p2 - p1, p3 - p2, p4 - p3, rows);
|
||||
destroyTupleIndex(index);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -1176,7 +1178,7 @@ void* blockDataDestroy(SSDataBlock* pBlock) {
|
|||
}
|
||||
|
||||
SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
||||
if(pDataBlock == NULL){
|
||||
if (pDataBlock == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1187,7 +1189,7 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
|||
|
||||
pBlock->info.numOfCols = numOfCols;
|
||||
pBlock->info.hasVarCol = pDataBlock->info.hasVarCol;
|
||||
pBlock->info.rowSize = pDataBlock->info.rows;
|
||||
pBlock->info.rowSize = pDataBlock->info.rows;
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData colInfo = {0};
|
||||
|
@ -1217,7 +1219,7 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
|||
}
|
||||
|
||||
size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize) {
|
||||
return (int32_t) ((pageSize - blockDataGetSerialMetaSize(pBlock))/ blockDataGetSerialRowSize(pBlock));
|
||||
return (int32_t)((pageSize - blockDataGetSerialMetaSize(pBlock)) / blockDataGetSerialRowSize(pBlock));
|
||||
}
|
||||
|
||||
void colDataDestroy(SColumnInfoData* pColData) {
|
||||
|
@ -1234,14 +1236,14 @@ static void doShiftBitmap(char* nullBitmap, size_t n, size_t total) {
|
|||
int32_t len = BitmapLen(total);
|
||||
|
||||
int32_t newLen = BitmapLen(total - n);
|
||||
if (n%8 == 0) {
|
||||
memmove(nullBitmap, nullBitmap + n/8, newLen);
|
||||
if (n % 8 == 0) {
|
||||
memmove(nullBitmap, nullBitmap + n / 8, newLen);
|
||||
} else {
|
||||
int32_t tail = n % 8;
|
||||
int32_t i = 0;
|
||||
|
||||
uint8_t* p = (uint8_t*) nullBitmap;
|
||||
while(i < len) {
|
||||
uint8_t* p = (uint8_t*)nullBitmap;
|
||||
while (i < len) {
|
||||
uint8_t v = p[i];
|
||||
|
||||
p[i] = 0;
|
||||
|
@ -1268,7 +1270,7 @@ static void colDataTrimFirstNRows(SColumnInfoData* pColInfoData, size_t n, size_
|
|||
}
|
||||
}
|
||||
|
||||
int32_t blockDataTrimFirstNRows(SSDataBlock *pBlock, size_t n) {
|
||||
int32_t blockDataTrimFirstNRows(SSDataBlock* pBlock, size_t n) {
|
||||
if (n == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1276,7 +1278,7 @@ int32_t blockDataTrimFirstNRows(SSDataBlock *pBlock, size_t n) {
|
|||
if (pBlock->info.rows <= n) {
|
||||
blockDataCleanup(pBlock);
|
||||
} else {
|
||||
for(int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
|
||||
for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
colDataTrimFirstNRows(pColInfoData, n, pBlock->info.rows);
|
||||
}
|
||||
|
@ -1462,3 +1464,128 @@ void blockDebugShowData(const SArray* dataBlocks) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TODO: Assume that the final generated result it less than 3M
|
||||
*
|
||||
* @param pReq
|
||||
* @param pDataBlocks
|
||||
* @param vgId
|
||||
* @param uid set as parameter temporarily // TODO: remove this parameter, and the executor should set uid in
|
||||
* SDataBlock->info.uid
|
||||
* @param suid // TODO: check with Liao whether suid response is reasonable
|
||||
*
|
||||
* TODO: colId should be set
|
||||
*/
|
||||
int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks, STSchema *pTSchema, int32_t vgId, tb_uid_t uid,
|
||||
tb_uid_t suid) {
|
||||
int32_t sz = taosArrayGetSize(pDataBlocks);
|
||||
int32_t bufSize = sizeof(SSubmitReq);
|
||||
for (int32_t i = 0; i < sz; ++i) {
|
||||
SDataBlockInfo* pBlkInfo = &((SSDataBlock*)taosArrayGet(pDataBlocks, i))->info;
|
||||
bufSize += pBlkInfo->rows * (TD_ROW_HEAD_LEN + pBlkInfo->rowSize + BitmapLen(pBlkInfo->numOfCols));
|
||||
bufSize += sizeof(SSubmitBlk);
|
||||
}
|
||||
|
||||
ASSERT(bufSize < 3 * 1024 * 1024);
|
||||
|
||||
*pReq = taosMemoryCalloc(1, bufSize);
|
||||
if(!(*pReq)) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
void* pDataBuf = *pReq;
|
||||
|
||||
int32_t msgLen = sizeof(SSubmitReq);
|
||||
int32_t numOfBlks = 0;
|
||||
SRowBuilder rb = {0};
|
||||
tdSRowInit(&rb, 0); // TODO: use the latest version
|
||||
|
||||
for (int32_t i = 0; i < sz; ++i) {
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pDataBlocks, i);
|
||||
int32_t colNum = pDataBlock->info.numOfCols;
|
||||
int32_t rows = pDataBlock->info.rows;
|
||||
int32_t rowSize = pDataBlock->info.rowSize;
|
||||
int64_t groupId = pDataBlock->info.groupId;
|
||||
|
||||
if(rb.nCols != colNum) {
|
||||
tdSRowSetTpInfo(&rb, colNum, pTSchema->flen);
|
||||
}
|
||||
|
||||
SSubmitBlk* pSubmitBlk = POINTER_SHIFT(pDataBuf, msgLen);
|
||||
pSubmitBlk->suid = suid;
|
||||
pSubmitBlk->uid = uid;
|
||||
pSubmitBlk->numOfRows = rows;
|
||||
|
||||
++numOfBlks;
|
||||
|
||||
msgLen += sizeof(SSubmitBlk);
|
||||
int32_t dataLen = 0;
|
||||
for (int32_t j = 0; j < rows; ++j) { // iterate by row
|
||||
tdSRowResetBuf(&rb, POINTER_SHIFT(pDataBuf, msgLen)); // set row buf
|
||||
printf("|");
|
||||
bool isStartKey = false;
|
||||
for (int32_t k = 0; k < colNum; ++k) { // iterate by column
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k);
|
||||
void* var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes);
|
||||
switch (pColInfoData->info.type) {
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
if (!isStartKey) {
|
||||
isStartKey = true;
|
||||
tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID, TSDB_DATA_TYPE_TIMESTAMP, TD_VTYPE_NORM, var, true, 0, 0);
|
||||
} else {
|
||||
tdAppendColValToRow(&rb, 2, TSDB_DATA_TYPE_TIMESTAMP, TD_VTYPE_NORM, var, true, 8, k);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
tdAppendColValToRow(&rb, 2, TSDB_DATA_TYPE_NCHAR, TD_VTYPE_NORM, var, true, 8, k);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_VARCHAR: { // TSDB_DATA_TYPE_BINARY
|
||||
tdAppendColValToRow(&rb, 2, TSDB_DATA_TYPE_VARCHAR, TD_VTYPE_NORM, var, true, 8, k);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
case TSDB_DATA_TYPE_DECIMAL:
|
||||
case TSDB_DATA_TYPE_BLOB:
|
||||
case TSDB_DATA_TYPE_MEDIUMBLOB:
|
||||
printf("the column type %" PRIi16 " is defined but not implemented yet\n", pColInfoData->info.type);
|
||||
TASSERT(0);
|
||||
break;
|
||||
default:
|
||||
if (pColInfoData->info.type < TSDB_DATA_TYPE_MAX && pColInfoData->info.type > TSDB_DATA_TYPE_NULL) {
|
||||
tdAppendColValToRow(&rb, 2, pColInfoData->info.type, TD_VTYPE_NORM, var, true, 8, k);
|
||||
} else {
|
||||
printf("the column type %" PRIi16 " is undefined\n", pColInfoData->info.type);
|
||||
TASSERT(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
dataLen += TD_ROW_LEN(rb.pBuf);
|
||||
}
|
||||
pSubmitBlk->dataLen = dataLen;
|
||||
msgLen += pSubmitBlk->dataLen;
|
||||
}
|
||||
|
||||
(*pReq)->length = msgLen;
|
||||
|
||||
(*pReq)->header.vgId = htonl(vgId);
|
||||
(*pReq)->header.contLen = htonl(msgLen);
|
||||
(*pReq)->length = (*pReq)->header.contLen;
|
||||
(*pReq)->numOfBlocks = htonl(numOfBlks);
|
||||
SSubmitBlk* blk = (SSubmitBlk*)((*pReq) + 1);
|
||||
while (numOfBlks--) {
|
||||
int32_t dataLen = blk->dataLen;
|
||||
blk->uid = htobe64(blk->uid);
|
||||
blk->suid = htobe64(blk->suid);
|
||||
blk->padding = htonl(blk->padding);
|
||||
blk->sversion = htonl(blk->sversion);
|
||||
blk->dataLen = htonl(blk->dataLen);
|
||||
blk->schemaLen = htonl(blk->schemaLen);
|
||||
blk->numOfRows = htons(blk->numOfRows);
|
||||
blk = (SSubmitBlk*)(blk->data + dataLen);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ int tdEncodeSchema(void **buf, STSchema *pSchema) {
|
|||
for (int i = 0; i < schemaNCols(pSchema); i++) {
|
||||
STColumn *pCol = schemaColAt(pSchema, i);
|
||||
tlen += taosEncodeFixedI8(buf, colType(pCol));
|
||||
tlen += taosEncodeFixedI8(buf, colSma(pCol));
|
||||
tlen += taosEncodeFixedI8(buf, colFlags(pCol));
|
||||
tlen += taosEncodeFixedI16(buf, colColId(pCol));
|
||||
tlen += taosEncodeFixedI16(buf, colBytes(pCol));
|
||||
}
|
||||
|
@ -110,14 +110,14 @@ void *tdDecodeSchema(void *buf, STSchema **pRSchema) {
|
|||
|
||||
for (int i = 0; i < numOfCols; i++) {
|
||||
col_type_t type = 0;
|
||||
int8_t sma = 0;
|
||||
int8_t flags = 0;
|
||||
col_id_t colId = 0;
|
||||
col_bytes_t bytes = 0;
|
||||
buf = taosDecodeFixedI8(buf, &type);
|
||||
buf = taosDecodeFixedI8(buf, &sma);
|
||||
buf = taosDecodeFixedI8(buf, &flags);
|
||||
buf = taosDecodeFixedI16(buf, &colId);
|
||||
buf = taosDecodeFixedI32(buf, &bytes);
|
||||
if (tdAddColToSchema(&schemaBuilder, type, sma, colId, bytes) < 0) {
|
||||
if (tdAddColToSchema(&schemaBuilder, type, flags, colId, bytes) < 0) {
|
||||
tdDestroyTSchemaBuilder(&schemaBuilder);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
|
|||
pBuilder->version = version;
|
||||
}
|
||||
|
||||
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t sma, col_id_t colId, col_bytes_t bytes) {
|
||||
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, col_id_t colId, col_bytes_t bytes) {
|
||||
if (!isValidDataType(type)) return -1;
|
||||
|
||||
if (pBuilder->nCols >= pBuilder->tCols) {
|
||||
|
@ -166,7 +166,7 @@ int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t sma, col
|
|||
STColumn *pCol = &(pBuilder->columns[pBuilder->nCols]);
|
||||
colSetType(pCol, type);
|
||||
colSetColId(pCol, colId);
|
||||
colSetSma(pCol, sma);
|
||||
colSetFlags(pCol, flags);
|
||||
if (pBuilder->nCols == 0) {
|
||||
colSetOffset(pCol, 0);
|
||||
} else {
|
||||
|
|
|
@ -34,77 +34,6 @@ int32_t tInitSubmitMsgIter(const SSubmitReq *pMsg, SSubmitMsgIter *pIter) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
pIter->totalLen = pMsg->length;
|
||||
ASSERT(pIter->totalLen > 0);
|
||||
pIter->len = 0;
|
||||
pIter->pMsg = pMsg;
|
||||
if (pMsg->length <= sizeof(SSubmitReq)) {
|
||||
terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock) {
|
||||
ASSERT(pIter->len >= 0);
|
||||
|
||||
if (pIter->len == 0) {
|
||||
pIter->len += sizeof(SSubmitReq);
|
||||
} else {
|
||||
if (pIter->len >= pIter->totalLen) {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
SSubmitBlk *pSubmitBlk = (SSubmitBlk *)POINTER_SHIFT(pIter->pMsg, pIter->len);
|
||||
pIter->len += (sizeof(SSubmitBlk) + pSubmitBlk->dataLen + pSubmitBlk->schemaLen);
|
||||
ASSERT(pIter->len > 0);
|
||||
}
|
||||
|
||||
if (pIter->len > pIter->totalLen) {
|
||||
terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP;
|
||||
*pPBlock = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pPBlock = (pIter->len == pIter->totalLen) ? NULL : (SSubmitBlk *)POINTER_SHIFT(pIter->pMsg, pIter->len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter) {
|
||||
if (pBlock->dataLen <= 0) return -1;
|
||||
pIter->totalLen = pBlock->dataLen;
|
||||
pIter->len = 0;
|
||||
pIter->row = (STSRow *)(pBlock->data + pBlock->schemaLen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
STSRow *tGetSubmitBlkNext(SSubmitBlkIter *pIter) {
|
||||
STSRow *row = pIter->row;
|
||||
|
||||
if (pIter->len >= pIter->totalLen) {
|
||||
return NULL;
|
||||
} else {
|
||||
pIter->len += TD_ROW_LEN(row);
|
||||
if (pIter->len < pIter->totalLen) {
|
||||
pIter->row = POINTER_SHIFT(row, TD_ROW_LEN(row));
|
||||
}
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: KEEP one suite of iterator API finally.
|
||||
// 1) use tInitSubmitMsgIterEx firstly as not decrease the merge conflicts
|
||||
// 2) replace tInitSubmitMsgIterEx with tInitSubmitMsgIter later
|
||||
// 3) finally, rename tInitSubmitMsgIterEx to tInitSubmitMsgIter
|
||||
|
||||
int32_t tInitSubmitMsgIterEx(const SSubmitReq *pMsg, SSubmitMsgIter *pIter) {
|
||||
if (pMsg == NULL) {
|
||||
terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pIter->totalLen = htonl(pMsg->length);
|
||||
ASSERT(pIter->totalLen > 0);
|
||||
pIter->len = 0;
|
||||
|
@ -117,7 +46,7 @@ int32_t tInitSubmitMsgIterEx(const SSubmitReq *pMsg, SSubmitMsgIter *pIter) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tGetSubmitMsgNextEx(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock) {
|
||||
int32_t tGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock) {
|
||||
ASSERT(pIter->len >= 0);
|
||||
|
||||
if (pIter->len == 0) {
|
||||
|
@ -152,7 +81,7 @@ int32_t tGetSubmitMsgNextEx(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tInitSubmitBlkIterEx(SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlock, SSubmitBlkIter *pIter) {
|
||||
int32_t tInitSubmitBlkIter(SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlock, SSubmitBlkIter *pIter) {
|
||||
if (pMsgIter->dataLen <= 0) return -1;
|
||||
pIter->totalLen = pMsgIter->dataLen;
|
||||
pIter->len = 0;
|
||||
|
@ -160,7 +89,7 @@ int32_t tInitSubmitBlkIterEx(SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlock, SSubm
|
|||
return 0;
|
||||
}
|
||||
|
||||
STSRow *tGetSubmitBlkNextEx(SSubmitBlkIter *pIter) {
|
||||
STSRow *tGetSubmitBlkNext(SSubmitBlkIter *pIter) {
|
||||
STSRow *row = pIter->row;
|
||||
|
||||
if (pIter->len >= pIter->totalLen) {
|
||||
|
@ -1682,8 +1611,8 @@ int32_t tSerializeSCreateDbReq(void *buf, int32_t bufLen, SCreateDbReq *pReq) {
|
|||
if (tEncodeI32(&encoder, pReq->numOfRetensions) < 0) return -1;
|
||||
for (int32_t i = 0; i < pReq->numOfRetensions; ++i) {
|
||||
SRetention *pRetension = taosArrayGet(pReq->pRetensions, i);
|
||||
if (tEncodeI32(&encoder, pRetension->freq) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pRetension->keep) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pRetension->freq) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pRetension->keep) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRetension->freqUnit) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRetension->keepUnit) < 0) return -1;
|
||||
}
|
||||
|
@ -1728,8 +1657,8 @@ int32_t tDeserializeSCreateDbReq(void *buf, int32_t bufLen, SCreateDbReq *pReq)
|
|||
|
||||
for (int32_t i = 0; i < pReq->numOfRetensions; ++i) {
|
||||
SRetention rentension = {0};
|
||||
if (tDecodeI32(&decoder, &rentension.freq) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &rentension.keep) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &rentension.freq) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &rentension.keep) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &rentension.freqUnit) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &rentension.keepUnit) < 0) return -1;
|
||||
if (taosArrayPush(pReq->pRetensions, &rentension) == NULL) {
|
||||
|
@ -2158,8 +2087,8 @@ int32_t tSerializeSDbCfgRsp(void *buf, int32_t bufLen, const SDbCfgRsp *pRsp) {
|
|||
if (tEncodeI32(&encoder, pRsp->numOfRetensions) < 0) return -1;
|
||||
for (int32_t i = 0; i < pRsp->numOfRetensions; ++i) {
|
||||
SRetention *pRetension = taosArrayGet(pRsp->pRetensions, i);
|
||||
if (tEncodeI32(&encoder, pRetension->freq) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pRetension->keep) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pRetension->freq) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pRetension->keep) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRetension->freqUnit) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRetension->keepUnit) < 0) return -1;
|
||||
}
|
||||
|
@ -2202,8 +2131,8 @@ int32_t tDeserializeSDbCfgRsp(void *buf, int32_t bufLen, SDbCfgRsp *pRsp) {
|
|||
|
||||
for (int32_t i = 0; i < pRsp->numOfRetensions; ++i) {
|
||||
SRetention rentension = {0};
|
||||
if (tDecodeI32(&decoder, &rentension.freq) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &rentension.keep) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &rentension.freq) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &rentension.keep) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &rentension.freqUnit) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &rentension.keepUnit) < 0) return -1;
|
||||
if (taosArrayPush(pRsp->pRetensions, &rentension) == NULL) {
|
||||
|
@ -2820,8 +2749,8 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR
|
|||
if (tEncodeI32(&encoder, pReq->numOfRetensions) < 0) return -1;
|
||||
for (int32_t i = 0; i < pReq->numOfRetensions; ++i) {
|
||||
SRetention *pRetension = taosArrayGet(pReq->pRetensions, i);
|
||||
if (tEncodeI32(&encoder, pRetension->freq) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pRetension->keep) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pRetension->freq) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pRetension->keep) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRetension->freqUnit) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRetension->keepUnit) < 0) return -1;
|
||||
}
|
||||
|
@ -2877,8 +2806,8 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *
|
|||
|
||||
for (int32_t i = 0; i < pReq->numOfRetensions; ++i) {
|
||||
SRetention rentension = {0};
|
||||
if (tDecodeI32(&decoder, &rentension.freq) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &rentension.keep) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &rentension.freq) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &rentension.keep) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &rentension.freqUnit) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &rentension.keepUnit) < 0) return -1;
|
||||
if (taosArrayPush(pReq->pRetensions, &rentension) == NULL) {
|
||||
|
|
|
@ -34,6 +34,10 @@ int32_t tmsgSendReq(const SMsgCb* pMsgCb, const SEpSet* epSet, SRpcMsg* pReq) {
|
|||
|
||||
void tmsgSendRsp(const SRpcMsg* pRsp) { return (*tsDefaultMsgCb.sendRspFp)(tsDefaultMsgCb.pWrapper, pRsp); }
|
||||
|
||||
void tmsgSendRedirectRsp(const SRpcMsg* pRsp, const SEpSet* pNewEpSet) {
|
||||
return (*tsDefaultMsgCb.sendRedirectRspFp)(tsDefaultMsgCb.pWrapper, pRsp, pNewEpSet);
|
||||
}
|
||||
|
||||
void tmsgRegisterBrokenLinkArg(const SMsgCb* pMsgCb, SRpcMsg* pMsg) {
|
||||
(*pMsgCb->registerBrokenLinkArgFp)(pMsgCb->pWrapper, pMsg);
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "dmImp.h"
|
||||
|
||||
#define INTERNAL_USER "_dnd"
|
||||
#define INTERNAL_CKEY "_key"
|
||||
#define INTERNAL_USER "_dnd"
|
||||
#define INTERNAL_CKEY "_key"
|
||||
#define INTERNAL_SECRET "_pwd"
|
||||
|
||||
static void dmGetMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet) {
|
||||
|
@ -130,10 +130,10 @@ _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) {
|
||||
|
@ -320,6 +320,37 @@ static inline void dmSendRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline void dmSendRedirectRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp, const SEpSet *pNewEpSet) {
|
||||
ASSERT(pRsp->code == TSDB_CODE_RPC_REDIRECT);
|
||||
ASSERT(pRsp->pCont == NULL);
|
||||
if (pWrapper->procType != DND_PROC_CHILD) {
|
||||
SRpcMsg resp = {0};
|
||||
SMEpSet msg = {.epSet = *pNewEpSet};
|
||||
int32_t len = tSerializeSMEpSet(NULL, 0, &msg);
|
||||
resp.pCont = rpcMallocCont(len);
|
||||
resp.contLen = len;
|
||||
tSerializeSMEpSet(resp.pCont, len, &msg);
|
||||
|
||||
resp.code = TSDB_CODE_RPC_REDIRECT;
|
||||
resp.handle = pRsp->handle;
|
||||
resp.refId = pRsp->refId;
|
||||
rpcSendResponse(&resp);
|
||||
} else {
|
||||
taosProcPutToParentQ(pWrapper->procObj, pRsp, sizeof(SRpcMsg), pRsp->pCont, pRsp->contLen, PROC_FUNC_RSP);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline void dmSendRedirectRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp, const SEpSet *pNewEpSet) {
|
||||
ASSERT(pRsp->code == TSDB_CODE_RPC_REDIRECT);
|
||||
if (pWrapper->procType != DND_PROC_CHILD) {
|
||||
rpcSendRedirectRsp(pRsp->handle, pNewEpSet);
|
||||
} else {
|
||||
taosProcPutToParentQ(pWrapper->procObj, pRsp, sizeof(SRpcMsg), pRsp->pCont, pRsp->contLen, PROC_FUNC_RSP);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void dmRegisterBrokenLinkArg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg) {
|
||||
if (pWrapper->procType != DND_PROC_CHILD) {
|
||||
rpcRegisterBrokenLinkArg(pMsg);
|
||||
|
@ -406,6 +437,14 @@ SProcCfg dmGenProcCfg(SMgmtWrapper *pWrapper) {
|
|||
return cfg;
|
||||
}
|
||||
|
||||
bool rpcRfp(int32_t code) {
|
||||
if (code == TSDB_CODE_RPC_REDIRECT) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t dmInitClient(SDnode *pDnode) {
|
||||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
|
||||
|
@ -420,6 +459,7 @@ static int32_t dmInitClient(SDnode *pDnode) {
|
|||
rpcInit.ckey = INTERNAL_CKEY;
|
||||
rpcInit.spi = 1;
|
||||
rpcInit.parent = pDnode;
|
||||
rpcInit.rfp = rpcRfp;
|
||||
|
||||
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
||||
taosEncryptPass_c((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass);
|
||||
|
@ -477,7 +517,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};
|
||||
|
@ -551,6 +591,7 @@ SMsgCb dmGetMsgcb(SMgmtWrapper *pWrapper) {
|
|||
SMsgCb msgCb = {
|
||||
.sendReqFp = dmSendReq,
|
||||
.sendRspFp = dmSendRsp,
|
||||
.sendRedirectRspFp = dmSendRedirectRsp,
|
||||
.registerBrokenLinkArgFp = dmRegisterBrokenLinkArg,
|
||||
.releaseHandleFp = dmReleaseHandle,
|
||||
.reportStartupFp = dmReportStartupByWrapper,
|
||||
|
|
|
@ -284,6 +284,7 @@ void vmInitMsgHandle(SMgmtWrapper *pWrapper) {
|
|||
dmSetMsgHandle(pWrapper, TDMT_VND_CREATE_SMA, vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||
dmSetMsgHandle(pWrapper, TDMT_VND_CANCEL_SMA, vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||
dmSetMsgHandle(pWrapper, TDMT_VND_DROP_SMA, vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||
dmSetMsgHandle(pWrapper, TDMT_VND_SUBMIT_RSMA, vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||
dmSetMsgHandle(pWrapper, TDMT_VND_MQ_VG_CHANGE, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||
dmSetMsgHandle(pWrapper, TDMT_VND_CONSUME, vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||
dmSetMsgHandle(pWrapper, TDMT_VND_TASK_DEPLOY, vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||
|
|
|
@ -149,8 +149,15 @@ static void vmProcessWriteQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO
|
|||
|
||||
int32_t ret = syncPropose(vnodeGetSyncHandle(pVnode->pImpl), pRpc, false);
|
||||
if (ret == TAOS_SYNC_PROPOSE_NOT_LEADER) {
|
||||
rsp.code = TSDB_CODE_SYN_NOT_LEADER;
|
||||
tmsgSendRsp(&rsp);
|
||||
// rsp.code = TSDB_CODE_SYN_NOT_LEADER;
|
||||
// tmsgSendRsp(&rsp);
|
||||
dTrace("syncPropose not leader redirect, vgId:%d ", syncGetVgId(vnodeGetSyncHandle(pVnode->pImpl)));
|
||||
rsp.code = TSDB_CODE_RPC_REDIRECT;
|
||||
SEpSet newEpSet;
|
||||
syncGetEpSet(vnodeGetSyncHandle(pVnode->pImpl), &newEpSet);
|
||||
newEpSet.inUse = (newEpSet.inUse + 1) % newEpSet.numOfEps;
|
||||
tmsgSendRedirectRsp(&rsp, &newEpSet);
|
||||
|
||||
} else if (ret == TAOS_SYNC_PROPOSE_OTHER_ERROR) {
|
||||
rsp.code = TSDB_CODE_SYN_INTERNAL_ERROR;
|
||||
tmsgSendRsp(&rsp);
|
||||
|
|
|
@ -554,9 +554,8 @@ int32_t tEncodeSMqSubActionLogObj(void** buf, const SMqSubActionLogO
|
|||
void* tDecodeSMqSubActionLogObj(const void* buf, SMqSubActionLogObj* pLog);
|
||||
|
||||
typedef struct {
|
||||
const SMqSubscribeObj* pOldSub;
|
||||
const SMqTopicObj* pTopic;
|
||||
const SMqRebSubscribe* pRebInfo;
|
||||
int32_t oldConsumerNum;
|
||||
const SMqRebInfo* pRebInfo;
|
||||
} SMqRebInputObj;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -134,15 +134,15 @@ FAIL:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static SMqRebSubscribe *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
|
||||
SMqRebSubscribe *pRebSub = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
static SMqRebInfo *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
|
||||
SMqRebInfo *pRebSub = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
if (pRebSub == NULL) {
|
||||
pRebSub = tNewSMqRebSubscribe(key);
|
||||
if (pRebSub == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
taosHashPut(pHash, key, strlen(key) + 1, pRebSub, sizeof(SMqRebSubscribe));
|
||||
taosHashPut(pHash, key, strlen(key) + 1, pRebSub, sizeof(SMqRebInfo));
|
||||
}
|
||||
return pRebSub;
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ static int32_t mndProcessMqTimerMsg(SNodeMsg *pMsg) {
|
|||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *removedTopic = taosArrayGetP(pConsumer->currentTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, removedTopic);
|
||||
SMqRebSubscribe *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
taosRUnLockLatch(&pConsumer->lock);
|
||||
|
@ -200,7 +200,7 @@ static int32_t mndProcessMqTimerMsg(SNodeMsg *pMsg) {
|
|||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *newTopic = taosArrayGetP(pConsumer->rebNewTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, newTopic);
|
||||
SMqRebSubscribe *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
taosArrayPush(pRebSub->newConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ static int32_t mndProcessMqTimerMsg(SNodeMsg *pMsg) {
|
|||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *removedTopic = taosArrayGetP(pConsumer->rebRemovedTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, removedTopic);
|
||||
SMqRebSubscribe *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
taosRUnLockLatch(&pConsumer->lock);
|
||||
|
|
|
@ -107,8 +107,8 @@ static SSdbRaw *mndDbActionEncode(SDbObj *pDb) {
|
|||
for (int32_t i = 0; i < pDb->cfg.numOfRetensions; ++i) {
|
||||
TASSERT(taosArrayGetSize(pDb->cfg.pRetensions) == pDb->cfg.numOfRetensions);
|
||||
SRetention *pRetension = taosArrayGet(pDb->cfg.pRetensions, i);
|
||||
SDB_SET_INT32(pRaw, dataPos, pRetension->freq, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pRetension->keep, _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pRetension->freq, _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pRetension->keep, _OVER)
|
||||
SDB_SET_INT8(pRaw, dataPos, pRetension->freqUnit, _OVER)
|
||||
SDB_SET_INT8(pRaw, dataPos, pRetension->keepUnit, _OVER)
|
||||
}
|
||||
|
@ -180,8 +180,8 @@ static SSdbRow *mndDbActionDecode(SSdbRaw *pRaw) {
|
|||
if (pDb->cfg.pRetensions == NULL) goto _OVER;
|
||||
for (int32_t i = 0; i < pDb->cfg.numOfRetensions; ++i) {
|
||||
SRetention retension = {0};
|
||||
SDB_GET_INT32(pRaw, dataPos, &retension.freq, _OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &retension.keep, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &retension.freq, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &retension.keep, _OVER)
|
||||
SDB_GET_INT8(pRaw, dataPos, &retension.freqUnit, _OVER)
|
||||
SDB_GET_INT8(pRaw, dataPos, &retension.keepUnit, _OVER)
|
||||
if (taosArrayPush(pDb->cfg.pRetensions, &retension) == NULL) {
|
||||
|
|
|
@ -277,6 +277,7 @@ SMqSubscribeObj *tCloneSubscribeObj(const SMqSubscribeObj *pSub) {
|
|||
memcpy(pSubNew->key, pSub->key, TSDB_SUBSCRIBE_KEY_LEN);
|
||||
taosInitRWLatch(&pSubNew->lock);
|
||||
|
||||
pSubNew->dbUid = pSub->dbUid;
|
||||
pSubNew->subType = pSub->subType;
|
||||
pSubNew->withTbName = pSub->withTbName;
|
||||
pSubNew->withSchema = pSub->withSchema;
|
||||
|
@ -310,6 +311,7 @@ void tDeleteSubscribeObj(SMqSubscribeObj *pSub) {
|
|||
int32_t tEncodeSubscribeObj(void **buf, const SMqSubscribeObj *pSub) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeString(buf, pSub->key);
|
||||
tlen += taosEncodeFixedI64(buf, pSub->dbUid);
|
||||
tlen += taosEncodeFixedI32(buf, pSub->vgNum);
|
||||
tlen += taosEncodeFixedI8(buf, pSub->subType);
|
||||
tlen += taosEncodeFixedI8(buf, pSub->withTbName);
|
||||
|
@ -336,6 +338,7 @@ int32_t tEncodeSubscribeObj(void **buf, const SMqSubscribeObj *pSub) {
|
|||
void *tDecodeSubscribeObj(const void *buf, SMqSubscribeObj *pSub) {
|
||||
//
|
||||
buf = taosDecodeStringTo(buf, pSub->key);
|
||||
buf = taosDecodeFixedI64(buf, &pSub->dbUid);
|
||||
buf = taosDecodeFixedI32(buf, &pSub->vgNum);
|
||||
buf = taosDecodeFixedI8(buf, &pSub->subType);
|
||||
buf = taosDecodeFixedI8(buf, &pSub->withTbName);
|
||||
|
|
|
@ -175,27 +175,20 @@ static int32_t mndSplitSubscribeKey(const char *key, char *topic, char *cgroup)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SMqRebSubscribe *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
|
||||
SMqRebSubscribe *pRebSub = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
static SMqRebInfo *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
|
||||
SMqRebInfo *pRebSub = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
if (pRebSub == NULL) {
|
||||
pRebSub = tNewSMqRebSubscribe(key);
|
||||
if (pRebSub == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
taosHashPut(pHash, key, strlen(key) + 1, pRebSub, sizeof(SMqRebSubscribe));
|
||||
taosHashPut(pHash, key, strlen(key) + 1, pRebSub, sizeof(SMqRebInfo));
|
||||
}
|
||||
return pRebSub;
|
||||
}
|
||||
|
||||
static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqRebOutputObj *pOutput) {
|
||||
if (pInput->pTopic != NULL) {
|
||||
// create subscribe
|
||||
pOutput->pSub = mndCreateSub(pMnode, pInput->pTopic, pInput->pRebInfo->key);
|
||||
ASSERT(taosHashGetSize(pOutput->pSub->consumerHash) == 0);
|
||||
} else {
|
||||
pOutput->pSub = tCloneSubscribeObj(pInput->pOldSub);
|
||||
}
|
||||
int32_t totalVgNum = pOutput->pSub->vgNum;
|
||||
|
||||
mInfo("mq rebalance subscription: %s, vgNum: %d", pOutput->pSub->key, pOutput->pSub->vgNum);
|
||||
|
@ -246,12 +239,8 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR
|
|||
}
|
||||
|
||||
// 3. calc vg number of each consumer
|
||||
int32_t oldSz = 0;
|
||||
if (pInput->pOldSub) {
|
||||
oldSz = taosHashGetSize(pInput->pOldSub->consumerHash);
|
||||
}
|
||||
int32_t afterRebConsumerNum =
|
||||
oldSz + taosArrayGetSize(pInput->pRebInfo->newConsumers) - taosArrayGetSize(pInput->pRebInfo->removedConsumers);
|
||||
int32_t afterRebConsumerNum = pInput->oldConsumerNum + taosArrayGetSize(pInput->pRebInfo->newConsumers) -
|
||||
taosArrayGetSize(pInput->pRebInfo->removedConsumers);
|
||||
int32_t minVgCnt = 0;
|
||||
int32_t imbConsumerNum = 0;
|
||||
// calc num
|
||||
|
@ -489,22 +478,34 @@ static int32_t mndProcessRebalanceReq(SNodeMsg *pMsg) {
|
|||
rebOutput.touchedConsumers = taosArrayInit(0, sizeof(void *));
|
||||
rebOutput.rebVgs = taosArrayInit(0, sizeof(SMqRebOutputVg));
|
||||
|
||||
SMqRebSubscribe *pRebSub = (SMqRebSubscribe *)pIter;
|
||||
SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pRebSub->key);
|
||||
SMqRebInfo *pRebInfo = (SMqRebInfo *)pIter;
|
||||
SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pRebInfo->key);
|
||||
|
||||
rebInput.pRebInfo = pRebInfo;
|
||||
|
||||
if (pSub == NULL) {
|
||||
// split sub key and extract topic
|
||||
char topic[TSDB_TOPIC_FNAME_LEN];
|
||||
char cgroup[TSDB_CGROUP_LEN];
|
||||
mndSplitSubscribeKey(pRebSub->key, topic, cgroup);
|
||||
mndSplitSubscribeKey(pRebInfo->key, topic, cgroup);
|
||||
SMqTopicObj *pTopic = mndAcquireTopic(pMnode, topic);
|
||||
ASSERT(pTopic);
|
||||
taosRLockLatch(&pTopic->lock);
|
||||
rebInput.pTopic = pTopic;
|
||||
}
|
||||
|
||||
rebInput.pRebInfo = pRebSub;
|
||||
rebInput.pOldSub = pSub;
|
||||
rebOutput.pSub = mndCreateSub(pMnode, pTopic, pRebInfo->key);
|
||||
ASSERT(taosHashGetSize(rebOutput.pSub->consumerHash) == 0);
|
||||
|
||||
taosRUnLockLatch(&pTopic->lock);
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
|
||||
rebInput.oldConsumerNum = 0;
|
||||
} else {
|
||||
taosRLockLatch(&pSub->lock);
|
||||
rebInput.oldConsumerNum = taosHashGetSize(pSub->consumerHash);
|
||||
rebOutput.pSub = tCloneSubscribeObj(pSub);
|
||||
taosRUnLockLatch(&pSub->lock);
|
||||
mndReleaseSubscribe(pMnode, pSub);
|
||||
}
|
||||
|
||||
// TODO replace assert with error check
|
||||
ASSERT(mndDoRebalance(pMnode, &rebInput, &rebOutput) == 0);
|
||||
|
@ -517,14 +518,6 @@ static int32_t mndProcessRebalanceReq(SNodeMsg *pMsg) {
|
|||
if (mndPersistRebResult(pMnode, pMsg, &rebOutput) < 0) {
|
||||
mError("persist rebalance output error, possibly vnode splitted or dropped");
|
||||
}
|
||||
|
||||
if (rebInput.pTopic) {
|
||||
SMqTopicObj *pTopic = (SMqTopicObj *)rebInput.pTopic;
|
||||
taosRUnLockLatch(&pTopic->lock);
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
} else {
|
||||
mndReleaseSubscribe(pMnode, pSub);
|
||||
}
|
||||
}
|
||||
|
||||
// reset flag
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define TSDB_VNODE_SMA_DEBUG // TODO: evaluate to remove the macro and the relative codes
|
||||
|
||||
// vnode
|
||||
typedef struct SVnode SVnode;
|
||||
typedef struct STsdbCfg STsdbCfg; // todo: remove
|
||||
|
@ -145,7 +145,7 @@ struct STsdbCfg {
|
|||
int32_t keep2;
|
||||
// TODO: save to tsdb cfg file
|
||||
int8_t type; // ETsdbType
|
||||
SRetention retentions[TSDB_RSMA_RETENTION_MAX];
|
||||
SRetention retentions[TSDB_RETENTION_MAX];
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct STable STable;
|
|||
|
||||
int tsdbMemTableCreate(STsdb *pTsdb, STsdbMemTable **ppMemTable);
|
||||
void tsdbMemTableDestroy(STsdb *pTsdb, STsdbMemTable *pMemTable);
|
||||
int tsdbInsertTableData(STsdb *pTsdb, SSubmitBlk *pBlock, int32_t *pAffectedRows);
|
||||
int tsdbInsertTableData(STsdb *pTsdb, SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlock, int32_t *pAffectedRows);
|
||||
int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead, SDataCols *pCols,
|
||||
TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo);
|
||||
|
||||
|
@ -72,6 +72,7 @@ struct STsdb {
|
|||
char *path;
|
||||
SVnode *pVnode;
|
||||
bool repoLocked;
|
||||
int8_t level; // retention level
|
||||
TdThreadMutex mutex;
|
||||
STsdbMemTable *mem;
|
||||
STsdbMemTable *imem;
|
||||
|
|
|
@ -40,7 +40,6 @@ static FORCE_INLINE int32_t tsdbUidStoreInit(STbUidStore **pStore) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -123,7 +123,8 @@ int32_t tsdbFetchTbUidList(STsdb* pTsdb, STbUidStore** ppStore, tb_uid_t suid, t
|
|||
int32_t tsdbUpdateTbUidList(STsdb* pTsdb, STbUidStore* pUidStore);
|
||||
void tsdbUidStoreDestory(STbUidStore* pStore);
|
||||
void* tsdbUidStoreFree(STbUidStore* pStore);
|
||||
int32_t tsdbTriggerRSma(STsdb* pTsdb, SMeta* pMeta, void* pMsg, int32_t inputType);
|
||||
int32_t tsdbTriggerRSma(STsdb* pTsdb, void* pMsg, int32_t inputType);
|
||||
int32_t tsdbProcessSubmitReq(STsdb* pTsdb, int64_t version, void* pReq);
|
||||
|
||||
typedef struct {
|
||||
int8_t streamType; // sma or other
|
||||
|
@ -181,6 +182,7 @@ struct SVnode {
|
|||
|
||||
struct STbUidStore {
|
||||
tb_uid_t suid;
|
||||
tb_uid_t uid; // TODO: just for debugging, remove when uid provided in SSDataBlock
|
||||
SArray* tbUids;
|
||||
SHashObj* uidHash;
|
||||
};
|
||||
|
@ -188,7 +190,7 @@ struct STbUidStore {
|
|||
#define TD_VID(PVNODE) (PVNODE)->config.vgId
|
||||
|
||||
|
||||
static FORCE_INLINE bool tsdbIsRollup(SVnode* pVnode) {
|
||||
static FORCE_INLINE bool vnodeIsRollup(SVnode* pVnode) {
|
||||
SRetention* pRetention = &(pVnode->config.tsdbCfg.retentions[0]);
|
||||
return (pRetention->freq > 0 && pRetention->keep > 0);
|
||||
}
|
||||
|
|
|
@ -37,9 +37,9 @@ int32_t tqReadHandleSetMsg(STqReadHandle* pReadHandle, SSubmitReq* pMsg, int64_t
|
|||
// pMsg->numOfBlocks = htonl(pMsg->numOfBlocks);
|
||||
|
||||
// iterate and convert
|
||||
if (tInitSubmitMsgIterEx(pMsg, &pReadHandle->msgIter) < 0) return -1;
|
||||
if (tInitSubmitMsgIter(pMsg, &pReadHandle->msgIter) < 0) return -1;
|
||||
while (true) {
|
||||
if (tGetSubmitMsgNextEx(&pReadHandle->msgIter, &pReadHandle->pBlock) < 0) return -1;
|
||||
if (tGetSubmitMsgNext(&pReadHandle->msgIter, &pReadHandle->pBlock) < 0) return -1;
|
||||
if (pReadHandle->pBlock == NULL) break;
|
||||
|
||||
// pReadHandle->pBlock->uid = htobe64(pReadHandle->pBlock->uid);
|
||||
|
@ -50,7 +50,7 @@ int32_t tqReadHandleSetMsg(STqReadHandle* pReadHandle, SSubmitReq* pMsg, int64_t
|
|||
// pReadHandle->pBlock->numOfRows = htons(pReadHandle->pBlock->numOfRows);
|
||||
}
|
||||
|
||||
if (tInitSubmitMsgIterEx(pMsg, &pReadHandle->msgIter) < 0) return -1;
|
||||
if (tInitSubmitMsgIter(pMsg, &pReadHandle->msgIter) < 0) return -1;
|
||||
pReadHandle->ver = ver;
|
||||
memset(&pReadHandle->blkIter, 0, sizeof(SSubmitBlkIter));
|
||||
return 0;
|
||||
|
@ -58,7 +58,7 @@ int32_t tqReadHandleSetMsg(STqReadHandle* pReadHandle, SSubmitReq* pMsg, int64_t
|
|||
|
||||
bool tqNextDataBlock(STqReadHandle* pHandle) {
|
||||
while (1) {
|
||||
if (tGetSubmitMsgNextEx(&pHandle->msgIter, &pHandle->pBlock) < 0) {
|
||||
if (tGetSubmitMsgNext(&pHandle->msgIter, &pHandle->pBlock) < 0) {
|
||||
return false;
|
||||
}
|
||||
if (pHandle->pBlock == NULL) return false;
|
||||
|
@ -169,8 +169,8 @@ int32_t tqRetrieveDataBlock(SArray** ppCols, STqReadHandle* pHandle, uint64_t* p
|
|||
tdSTSRowIterInit(&iter, pTschema);
|
||||
STSRow* row;
|
||||
int32_t curRow = 0;
|
||||
tInitSubmitBlkIterEx(&pHandle->msgIter, pHandle->pBlock, &pHandle->blkIter);
|
||||
while ((row = tGetSubmitBlkNextEx(&pHandle->blkIter)) != NULL) {
|
||||
tInitSubmitBlkIter(&pHandle->msgIter, pHandle->pBlock, &pHandle->blkIter);
|
||||
while ((row = tGetSubmitBlkNext(&pHandle->blkIter)) != NULL) {
|
||||
tdSTSRowIterReset(&iter, row);
|
||||
// get all wanted col of that block
|
||||
for (int32_t i = 0; i < colActual; i++) {
|
||||
|
|
|
@ -935,7 +935,7 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDFile *pDF
|
|||
pBlockCol->type = pDataCol->type;
|
||||
pAggrBlkCol->colId = pDataCol->colId;
|
||||
|
||||
if (isSuper && pColumn->sma && tDataTypes[pDataCol->type].statisFunc) {
|
||||
if (isSuper && IS_BSMA_ON(pColumn) && tDataTypes[pDataCol->type].statisFunc) {
|
||||
#if 0
|
||||
(*tDataTypes[pDataCol->type].statisFunc)(pDataCol->pData, rowsToWrite, &(pBlockCol->min), &(pBlockCol->max),
|
||||
&(pBlockCol->sum), &(pBlockCol->minIndex), &(pBlockCol->maxIndex),
|
||||
|
|
|
@ -27,7 +27,13 @@ static const char *TSDB_FNAME_SUFFIX[] = {
|
|||
"rsma", // TSDB_FILE_RSMA
|
||||
};
|
||||
|
||||
static void tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, char *fname);
|
||||
static const char *TSDB_LEVEL_DNAME[] = {
|
||||
"tsdb",
|
||||
"rsma1",
|
||||
"rsma2",
|
||||
};
|
||||
|
||||
static void tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, const char* dname, char *fname);
|
||||
// static int tsdbRollBackMFile(SMFile *pMFile);
|
||||
static int tsdbEncodeDFInfo(void **buf, SDFInfo *pInfo);
|
||||
static void *tsdbDecodeDFInfo(void *buf, SDFInfo *pInfo);
|
||||
|
@ -45,7 +51,7 @@ void tsdbInitDFile(STsdb *pRepo, SDFile *pDFile, SDiskID did, int fid, uint32_t
|
|||
pDFile->info.magic = TSDB_FILE_INIT_MAGIC;
|
||||
pDFile->info.fver = tsdbGetDFSVersion(ftype);
|
||||
|
||||
tsdbGetFilename(REPO_ID(pRepo), fid, ver, ftype, fname);
|
||||
tsdbGetFilename(REPO_ID(pRepo), fid, ver, ftype, TSDB_LEVEL_DNAME[pRepo->level], fname);
|
||||
tfsInitFile(REPO_TFS(pRepo), &(pDFile->f), did, fname);
|
||||
}
|
||||
|
||||
|
@ -431,14 +437,15 @@ int tsdbParseDFilename(const char *fname, int *vid, int *fid, TSDB_FILE_T *ftype
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, char *fname) {
|
||||
static void tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, const char *dname, char *fname) {
|
||||
ASSERT(ftype != TSDB_FILE_MAX);
|
||||
|
||||
if (ftype < TSDB_FILE_MAX) {
|
||||
if (ver == 0) {
|
||||
snprintf(fname, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/data/v%df%d.%s", vid, vid, fid, TSDB_FNAME_SUFFIX[ftype]);
|
||||
snprintf(fname, TSDB_FILENAME_LEN, "vnode/vnode%d/%s/data/v%df%d.%s", vid, dname, vid, fid,
|
||||
TSDB_FNAME_SUFFIX[ftype]);
|
||||
} else {
|
||||
snprintf(fname, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/data/v%df%d.%s-ver%" PRIu32, vid, vid, fid,
|
||||
snprintf(fname, TSDB_FILENAME_LEN, "vnode/vnode%d/%s/data/v%df%d.%s-ver%" PRIu32, vid, dname, vid, fid,
|
||||
TSDB_FNAME_SUFFIX[ftype], ver);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -190,35 +190,7 @@ int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tdScanAndConvertSubmitMsg(SSubmitReq *pMsg) {
|
||||
ASSERT(pMsg != NULL);
|
||||
SSubmitMsgIter msgIter = {0};
|
||||
SSubmitBlk *pBlock = NULL;
|
||||
SSubmitBlkIter blkIter = {0};
|
||||
STSRow *row = NULL;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
pMsg->length = htonl(pMsg->length);
|
||||
pMsg->numOfBlocks = htonl(pMsg->numOfBlocks);
|
||||
|
||||
if (tInitSubmitMsgIter(pMsg, &msgIter) < 0) return -1;
|
||||
while (true) {
|
||||
if (tGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1;
|
||||
if (pBlock == NULL) break;
|
||||
|
||||
pBlock->uid = htobe64(pBlock->uid);
|
||||
pBlock->suid = htobe64(pBlock->suid);
|
||||
pBlock->sversion = htonl(pBlock->sversion);
|
||||
pBlock->dataLen = htonl(pBlock->dataLen);
|
||||
pBlock->schemaLen = htonl(pBlock->schemaLen);
|
||||
pBlock->numOfRows = htons(pBlock->numOfRows);
|
||||
}
|
||||
|
||||
if (terrno != TSDB_CODE_SUCCESS) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbInsertTableData(STsdb *pTsdb, SSubmitBlk *pBlock, int32_t *pAffectedRows) {
|
||||
int tsdbInsertTableData(STsdb *pTsdb, SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlock, int32_t *pAffectedRows) {
|
||||
// STsdbMeta *pMeta = pRepo->tsdbMeta;
|
||||
// int32_t points = 0;
|
||||
// STable *pTable = NULL;
|
||||
|
@ -232,15 +204,15 @@ int tsdbInsertTableData(STsdb *pTsdb, SSubmitBlk *pBlock, int32_t *pAffectedRows
|
|||
SSubmitBlk *pBlkCopy;
|
||||
|
||||
// create container is nedd
|
||||
tptr = taosHashGet(pMemTable->pHashIdx, &(pBlock->uid), sizeof(pBlock->uid));
|
||||
tptr = taosHashGet(pMemTable->pHashIdx, &(pMsgIter->uid), sizeof(pMsgIter->uid));
|
||||
if (tptr == NULL) {
|
||||
pTbData = tsdbNewTbData(pBlock->uid);
|
||||
pTbData = tsdbNewTbData(pMsgIter->uid);
|
||||
if (pTbData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Put into hash
|
||||
taosHashPut(pMemTable->pHashIdx, &(pBlock->uid), sizeof(pBlock->uid), &(pTbData), sizeof(pTbData));
|
||||
taosHashPut(pMemTable->pHashIdx, &(pMsgIter->uid), sizeof(pMsgIter->uid), &(pTbData), sizeof(pTbData));
|
||||
|
||||
// Put into skiplist
|
||||
tSkipListPut(pMemTable->pSlIdx, pTbData);
|
||||
|
@ -249,10 +221,10 @@ int tsdbInsertTableData(STsdb *pTsdb, SSubmitBlk *pBlock, int32_t *pAffectedRows
|
|||
}
|
||||
|
||||
// copy data to buffer pool
|
||||
pBlkCopy = (SSubmitBlk *)vnodeBufPoolMalloc(pTsdb->mem->pPool, pBlock->dataLen + sizeof(*pBlock));
|
||||
memcpy(pBlkCopy, pBlock, pBlock->dataLen + sizeof(*pBlock));
|
||||
pBlkCopy = (SSubmitBlk *)vnodeBufPoolMalloc(pTsdb->mem->pPool, pMsgIter->dataLen + sizeof(*pBlock));
|
||||
memcpy(pBlkCopy, pBlock, pMsgIter->dataLen + sizeof(*pBlock));
|
||||
|
||||
tInitSubmitBlkIter(pBlkCopy, &blkIter);
|
||||
tInitSubmitBlkIter(pMsgIter, pBlkCopy, &blkIter);
|
||||
if (blkIter.row == NULL) return 0;
|
||||
keyMin = TD_ROW_KEY(blkIter.row);
|
||||
|
||||
|
@ -261,15 +233,15 @@ int tsdbInsertTableData(STsdb *pTsdb, SSubmitBlk *pBlock, int32_t *pAffectedRows
|
|||
// Set statistics
|
||||
keyMax = TD_ROW_KEY(blkIter.row);
|
||||
|
||||
pTbData->nrows += pBlock->numOfRows;
|
||||
pTbData->nrows += pMsgIter->numOfRows;
|
||||
if (pTbData->keyMin > keyMin) pTbData->keyMin = keyMin;
|
||||
if (pTbData->keyMax < keyMax) pTbData->keyMax = keyMax;
|
||||
|
||||
pMemTable->nRow += pBlock->numOfRows;
|
||||
pMemTable->nRow += pMsgIter->numOfRows;
|
||||
if (pMemTable->keyMin > keyMin) pMemTable->keyMin = keyMin;
|
||||
if (pMemTable->keyMax < keyMax) pMemTable->keyMax = keyMax;
|
||||
|
||||
(*pAffectedRows) += pBlock->numOfRows;
|
||||
(*pAffectedRows) += pMsgIter->numOfRows;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,21 +15,21 @@
|
|||
|
||||
#include "tsdb.h"
|
||||
|
||||
static int tsdbOpenImpl(SVnode *pVnode, int8_t type, STsdb **ppTsdb, const char *dir);
|
||||
static int tsdbOpenImpl(SVnode *pVnode, int8_t type, STsdb **ppTsdb, const char *dir, int8_t level);
|
||||
|
||||
int tsdbOpen(SVnode *pVnode, int8_t type) {
|
||||
switch (type) {
|
||||
case TSDB_TYPE_TSDB:
|
||||
return tsdbOpenImpl(pVnode, type, &VND_TSDB(pVnode), VNODE_TSDB_DIR);
|
||||
return tsdbOpenImpl(pVnode, type, &VND_TSDB(pVnode), VNODE_TSDB_DIR, TSDB_RETENTION_L0);
|
||||
case TSDB_TYPE_TSMA:
|
||||
ASSERT(0);
|
||||
break;
|
||||
case TSDB_TYPE_RSMA_L0:
|
||||
return tsdbOpenImpl(pVnode, type, &VND_RSMA0(pVnode), VNODE_TSDB_DIR);
|
||||
return tsdbOpenImpl(pVnode, type, &VND_RSMA0(pVnode), VNODE_TSDB_DIR, TSDB_RETENTION_L0);
|
||||
case TSDB_TYPE_RSMA_L1:
|
||||
return tsdbOpenImpl(pVnode, type, &VND_RSMA1(pVnode), VNODE_RSMA1_DIR);
|
||||
return tsdbOpenImpl(pVnode, type, &VND_RSMA1(pVnode), VNODE_RSMA1_DIR, TSDB_RETENTION_L1);
|
||||
case TSDB_TYPE_RSMA_L2:
|
||||
return tsdbOpenImpl(pVnode, type, &VND_RSMA2(pVnode), VNODE_RSMA2_DIR);
|
||||
return tsdbOpenImpl(pVnode, type, &VND_RSMA2(pVnode), VNODE_RSMA2_DIR, TSDB_RETENTION_L2);
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
|
@ -37,7 +37,17 @@ int tsdbOpen(SVnode *pVnode, int8_t type) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tsdbOpenImpl(SVnode *pVnode, int8_t type, STsdb **ppTsdb, const char *dir) {
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param pVnode
|
||||
* @param type
|
||||
* @param ppTsdb
|
||||
* @param dir
|
||||
* @param level retention level
|
||||
* @return int
|
||||
*/
|
||||
int tsdbOpenImpl(SVnode *pVnode, int8_t type, STsdb **ppTsdb, const char *dir, int8_t level) {
|
||||
STsdb *pTsdb = NULL;
|
||||
int slen = 0;
|
||||
|
||||
|
@ -55,6 +65,7 @@ int tsdbOpenImpl(SVnode *pVnode, int8_t type, STsdb **ppTsdb, const char *dir) {
|
|||
sprintf(pTsdb->path, "%s%s%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path, TD_DIRSEP,
|
||||
dir);
|
||||
pTsdb->pVnode = pVnode;
|
||||
pTsdb->level = level;
|
||||
pTsdb->repoLocked = false;
|
||||
taosThreadMutexInit(&pTsdb->mutex, NULL);
|
||||
pTsdb->fs = tsdbNewFS(REPO_CFG(pTsdb));
|
||||
|
@ -67,7 +78,7 @@ int tsdbOpenImpl(SVnode *pVnode, int8_t type, STsdb **ppTsdb, const char *dir) {
|
|||
goto _err;
|
||||
}
|
||||
|
||||
tsdbDebug("vgId: %d tsdb is opened for %s", TD_VID(pVnode), pTsdb->path);
|
||||
tsdbDebug("vgId:%d tsdb is opened for %s", TD_VID(pVnode), pTsdb->path);
|
||||
|
||||
*ppTsdb = pTsdb;
|
||||
return 0;
|
||||
|
@ -79,6 +90,7 @@ _err:
|
|||
|
||||
int tsdbClose(STsdb *pTsdb) {
|
||||
if (pTsdb) {
|
||||
// TODO: destroy mem/imem
|
||||
tsdbCloseFS(pTsdb);
|
||||
tsdbFreeFS(pTsdb->fs);
|
||||
taosMemoryFree(pTsdb);
|
||||
|
|
|
@ -351,14 +351,25 @@ static void setQueryTimewindow(STsdbReadHandle* pTsdbReadHandle, SQueryTableData
|
|||
}
|
||||
}
|
||||
|
||||
static STsdb* getTsdbByRetentions(SVnode* pVnode, TSKEY winSKey, SRetention* retentions) {
|
||||
if (vnodeIsRollup(pVnode)) {
|
||||
// for(int32_t i=0; i< TSDB_; ) {
|
||||
|
||||
// }
|
||||
}
|
||||
return pVnode->pTsdb;
|
||||
}
|
||||
|
||||
static STsdbReadHandle* tsdbQueryTablesImpl(SVnode* pVnode, SQueryTableDataCond* pCond, uint64_t qId, uint64_t taskId) {
|
||||
STsdbReadHandle* pReadHandle = taosMemoryCalloc(1, sizeof(STsdbReadHandle));
|
||||
if (pReadHandle == NULL) {
|
||||
goto _end;
|
||||
}
|
||||
|
||||
STsdb* pTsdb = getTsdbByRetentions(pVnode, pCond->twindow.skey, pVnode->config.tsdbCfg.retentions);
|
||||
|
||||
pReadHandle->order = pCond->order;
|
||||
pReadHandle->pTsdb = pVnode->pTsdb;
|
||||
pReadHandle->pTsdb = pTsdb;
|
||||
pReadHandle->type = TSDB_QUERY_TYPE_ALL;
|
||||
pReadHandle->cur.fid = INT32_MIN;
|
||||
pReadHandle->cur.win = TSWINDOW_INITIALIZER;
|
||||
|
@ -376,7 +387,7 @@ static STsdbReadHandle* tsdbQueryTablesImpl(SVnode* pVnode, SQueryTableDataCond*
|
|||
snprintf(buf, tListLen(buf), "TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, qId);
|
||||
pReadHandle->idStr = strdup(buf);
|
||||
|
||||
if (tsdbInitReadH(&pReadHandle->rhelper, (STsdb*)pVnode->pTsdb) != 0) {
|
||||
if (tsdbInitReadH(&pReadHandle->rhelper, pReadHandle->pTsdb) != 0) {
|
||||
goto _end;
|
||||
}
|
||||
|
||||
|
@ -413,7 +424,7 @@ static STsdbReadHandle* tsdbQueryTablesImpl(SVnode* pVnode, SQueryTableDataCond*
|
|||
pReadHandle->suppInfo.plist = taosMemoryCalloc(taosArrayGetSize(pReadHandle->suppInfo.defaultLoadColumn), POINTER_BYTES);
|
||||
}
|
||||
|
||||
pReadHandle->pDataCols = tdNewDataCols(1000, pReadHandle->pTsdb->pVnode->config.tsdbCfg.maxRows);
|
||||
pReadHandle->pDataCols = tdNewDataCols(1000, pVnode->config.tsdbCfg.maxRows);
|
||||
if (pReadHandle->pDataCols == NULL) {
|
||||
tsdbError("%p failed to malloc buf for pDataCols, %s", pReadHandle, pReadHandle->idStr);
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
|
@ -3330,7 +3341,7 @@ int32_t tsdbRetrieveDataBlockStatisInfo(tsdbReaderT* pTsdbReadHandle, SColumnDat
|
|||
int32_t* slotIds = pHandle->suppInfo.slotIds;
|
||||
for (int32_t i = 1; i < numOfCols; ++i) {
|
||||
ASSERT(colIds[i] == pHandle->pSchema->columns[slotIds[i]].colId);
|
||||
if (pHandle->pSchema->columns[slotIds[i]].sma) {
|
||||
if (IS_BSMA_ON(&(pHandle->pSchema->columns[slotIds[i]]))) {
|
||||
if (pHandle->suppInfo.pstatis[i].numOfNull == -1) { // set the column data are all NULL
|
||||
pHandle->suppInfo.pstatis[i].numOfNull = pBlockInfo->compBlock->numOfRows;
|
||||
} else {
|
||||
|
|
|
@ -105,7 +105,7 @@ typedef struct {
|
|||
|
||||
#define RSMA_TASK_INFO_HASH_SLOT 8
|
||||
struct SRSmaInfo {
|
||||
void *taskInfo[TSDB_RSMA_RETENTION_2]; // qTaskInfo_t
|
||||
void *taskInfo[TSDB_RETENTION_L2]; // qTaskInfo_t
|
||||
};
|
||||
|
||||
struct SSmaStat {
|
||||
|
@ -127,7 +127,7 @@ static FORCE_INLINE void tsdbFreeTaskHandle(qTaskInfo_t *taskHandle) {
|
|||
}
|
||||
|
||||
static FORCE_INLINE void *tsdbFreeRSmaInfo(SRSmaInfo *pInfo) {
|
||||
for (int32_t i = 0; i < TSDB_RSMA_RETENTION_MAX; ++i) {
|
||||
for (int32_t i = 0; i < TSDB_RETENTION_MAX; ++i) {
|
||||
if (pInfo->taskInfo[i]) {
|
||||
tsdbFreeTaskHandle(pInfo->taskInfo[i]);
|
||||
}
|
||||
|
@ -174,6 +174,9 @@ static int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, const char *msg);
|
|||
|
||||
static FORCE_INLINE int32_t tsdbUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid);
|
||||
static FORCE_INLINE int32_t tsdbUpdateTbUidListImpl(STsdb *pTsdb, tb_uid_t *suid, SArray *tbUids);
|
||||
static FORCE_INLINE int32_t tsdbExecuteRSmaImpl(STsdb *pTsdb, const void *pMsg, int32_t inputType,
|
||||
qTaskInfo_t *taskInfo, STSchema *pTSchema, tb_uid_t suid, tb_uid_t uid,
|
||||
int8_t level);
|
||||
// mgmt interface
|
||||
static int32_t tsdbDropTSmaDataImpl(STsdb *pTsdb, int64_t indexUid);
|
||||
|
||||
|
@ -702,25 +705,25 @@ int32_t tsdbUpdateExpiredWindowImpl(STsdb *pTsdb, SSubmitReq *pMsg, int64_t vers
|
|||
SInterval interval = {0};
|
||||
TSKEY lastWinSKey = INT64_MIN;
|
||||
|
||||
if (tInitSubmitMsgIterEx(pMsg, &msgIter) != TSDB_CODE_SUCCESS) {
|
||||
if (tInitSubmitMsgIter(pMsg, &msgIter) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
tGetSubmitMsgNextEx(&msgIter, &pBlock);
|
||||
tGetSubmitMsgNext(&msgIter, &pBlock);
|
||||
if (!pBlock) break;
|
||||
|
||||
STSmaWrapper *pSW = NULL;
|
||||
STSma *pTSma = NULL;
|
||||
|
||||
SSubmitBlkIter blkIter = {0};
|
||||
if (tInitSubmitBlkIterEx(&msgIter, pBlock, &blkIter) != TSDB_CODE_SUCCESS) {
|
||||
if (tInitSubmitBlkIter(&msgIter, pBlock, &blkIter) != TSDB_CODE_SUCCESS) {
|
||||
pSW = tdFreeTSmaWrapper(pSW);
|
||||
break;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
STSRow *row = tGetSubmitBlkNextEx(&blkIter);
|
||||
STSRow *row = tGetSubmitBlkNext(&blkIter);
|
||||
if (!row) {
|
||||
tdFreeTSmaWrapper(pSW);
|
||||
break;
|
||||
|
@ -1881,8 +1884,10 @@ int32_t tsdbFetchTbUidList(STsdb *pTsdb, STbUidStore **ppStore, tb_uid_t suid, t
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
ASSERT(ppStore != NULL);
|
||||
|
||||
if (!(*ppStore)) {
|
||||
if (tsdbUidStoreInit((STbUidStore **)ppStore) != 0) {
|
||||
if (tsdbUidStoreInit(ppStore) != 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
@ -1966,87 +1971,101 @@ static int32_t tsdbFetchSubmitReqSuids(SSubmitReq *pMsg, STbUidStore *pStore) {
|
|||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (tInitSubmitMsgIterEx(pMsg, &msgIter) < 0) return -1;
|
||||
if (tInitSubmitMsgIter(pMsg, &msgIter) < 0) return -1;
|
||||
while (true) {
|
||||
if (tGetSubmitMsgNextEx(&msgIter, &pBlock) < 0) return -1;
|
||||
if (tGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1;
|
||||
|
||||
if (!pBlock) break;
|
||||
tsdbUidStorePut(pStore, msgIter.suid, NULL);
|
||||
pStore->uid = msgIter.uid; // TODO: remove, just for debugging
|
||||
}
|
||||
|
||||
if (terrno != TSDB_CODE_SUCCESS) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tsdbExecuteRSma(STsdb *pTsdb, SMeta *pMeta, const void *pMsg, int32_t inputType, tb_uid_t *suid) {
|
||||
static FORCE_INLINE int32_t tsdbExecuteRSmaImpl(STsdb *pTsdb, const void *pMsg, int32_t inputType,
|
||||
qTaskInfo_t *taskInfo, STSchema *pTSchema, tb_uid_t suid, tb_uid_t uid,
|
||||
int8_t level) {
|
||||
SArray *pResult = NULL;
|
||||
tsdbDebug("vgId:%d execute rsma %" PRIi8 " task for qTaskInfo:%p suid:%" PRIu64, REPO_ID(pTsdb), level, taskInfo,
|
||||
suid);
|
||||
|
||||
qSetStreamInput(taskInfo, pMsg, inputType);
|
||||
while (1) {
|
||||
SSDataBlock *output = NULL;
|
||||
uint64_t ts;
|
||||
if (qExecTask(taskInfo, &output, &ts) < 0) {
|
||||
ASSERT(false);
|
||||
}
|
||||
if (!output) {
|
||||
break;
|
||||
}
|
||||
if (!pResult) {
|
||||
pResult = taosArrayInit(0, sizeof(SSDataBlock));
|
||||
if (!pResult) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pResult, output);
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pResult) > 0) {
|
||||
blockDebugShowData(pResult);
|
||||
STsdb *sinkTsdb = (level == TSDB_RETENTION_L1 ? pTsdb->pVnode->pRSma1 : pTsdb->pVnode->pRSma2);
|
||||
SSubmitReq *pReq = NULL;
|
||||
if (buildSubmitReqFromDataBlock(&pReq, pResult, pTSchema, TD_VID(pTsdb->pVnode), uid, suid) != 0) {
|
||||
taosArrayDestroy(pResult);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
if (tsdbProcessSubmitReq(sinkTsdb, INT64_MAX, pReq) != 0) {
|
||||
taosArrayDestroy(pResult);
|
||||
taosMemoryFreeClear(pReq);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
taosMemoryFreeClear(pReq);
|
||||
} else {
|
||||
tsdbWarn("vgId:%d no rsma % " PRIi8 " data generated since %s", REPO_ID(pTsdb), level, tstrerror(terrno));
|
||||
}
|
||||
|
||||
taosArrayDestroy(pResult);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tsdbExecuteRSma(STsdb *pTsdb, const void *pMsg, int32_t inputType, tb_uid_t suid, tb_uid_t uid) {
|
||||
SSmaEnv *pEnv = REPO_RSMA_ENV(pTsdb);
|
||||
if (!pEnv) {
|
||||
// only applicable when rsma env exists
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
ASSERT(uid != 0); // TODO: remove later
|
||||
|
||||
SSmaStat *pStat = SMA_ENV_STAT(pEnv);
|
||||
SRSmaInfo *pRSmaInfo = NULL;
|
||||
|
||||
pRSmaInfo = taosHashGet(SMA_STAT_INFO_HASH(pStat), suid, sizeof(tb_uid_t));
|
||||
pRSmaInfo = taosHashGet(SMA_STAT_INFO_HASH(pStat), &suid, sizeof(tb_uid_t));
|
||||
|
||||
if (!pRSmaInfo || !(pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
|
||||
tsdbDebug("vgId:%d no rsma info for suid:%" PRIu64, REPO_ID(pTsdb), *suid);
|
||||
tsdbDebug("vgId:%d no rsma info for suid:%" PRIu64, REPO_ID(pTsdb), suid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SArray *pResult = NULL;
|
||||
|
||||
pResult = taosArrayInit(0, sizeof(SSDataBlock));
|
||||
if (!pResult) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (inputType == STREAM_DATA_TYPE_SUBMIT_BLOCK) {
|
||||
if (pRSmaInfo->taskInfo[0]) {
|
||||
tsdbDebug("vgId:%d execute rsma task for qTaskInfo:%p suid:%" PRIu64, REPO_ID(pTsdb), pRSmaInfo->taskInfo[0],
|
||||
*suid);
|
||||
qSetStreamInput(pRSmaInfo->taskInfo[0], pMsg, inputType);
|
||||
while (1) {
|
||||
SSDataBlock *output;
|
||||
uint64_t ts;
|
||||
if (qExecTask(pRSmaInfo->taskInfo[0], &output, &ts) < 0) {
|
||||
ASSERT(false);
|
||||
}
|
||||
if (!output) {
|
||||
break;
|
||||
}
|
||||
taosArrayPush(pResult, output);
|
||||
}
|
||||
if (taosArrayGetSize(pResult) > 0) {
|
||||
blockDebugShowData(pResult);
|
||||
} else {
|
||||
tsdbWarn("vgId:%d no sma data generated since %s", REPO_ID(pTsdb), tstrerror(terrno));
|
||||
}
|
||||
}
|
||||
|
||||
// if (pRSmaInfo->taskInfo[1]) {
|
||||
// qSetStreamInput(pRSmaInfo->taskInfo[1], pMsg, inputType);
|
||||
// while (1) {
|
||||
// SSDataBlock *output;
|
||||
// uint64_t ts;
|
||||
// if (qExecTask(pRSmaInfo->taskInfo[1], &output, &ts) < 0) {
|
||||
// ASSERT(false);
|
||||
// }
|
||||
// if (!output) {
|
||||
// break;
|
||||
// }
|
||||
// taosArrayPush(pResult, output);
|
||||
// }
|
||||
// blockDebugShowData(pResult);
|
||||
// }
|
||||
// TODO: use the proper schema instead of 0, and cache STSchema in cache
|
||||
STSchema *pTSchema = metaGetTbTSchema(pTsdb->pVnode->pMeta, suid, 0);
|
||||
tsdbExecuteRSmaImpl(pTsdb, pMsg, inputType, pRSmaInfo->taskInfo[0], pTSchema, suid, uid, TSDB_RETENTION_L1);
|
||||
tsdbExecuteRSmaImpl(pTsdb, pMsg, inputType, pRSmaInfo->taskInfo[1], pTSchema, suid, uid, TSDB_RETENTION_L2);
|
||||
taosMemoryFree(pTSchema);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tsdbTriggerRSma(STsdb *pTsdb, SMeta *pMeta, void *pMsg, int32_t inputType) {
|
||||
int32_t tsdbTriggerRSma(STsdb *pTsdb, void *pMsg, int32_t inputType) {
|
||||
SSmaEnv *pEnv = REPO_RSMA_ENV(pTsdb);
|
||||
if (!pEnv) {
|
||||
// only applicable when rsma env exists
|
||||
|
@ -2058,12 +2077,12 @@ int32_t tsdbTriggerRSma(STsdb *pTsdb, SMeta *pMeta, void *pMsg, int32_t inputTyp
|
|||
tsdbFetchSubmitReqSuids(pMsg, &uidStore);
|
||||
|
||||
if (uidStore.suid != 0) {
|
||||
tsdbExecuteRSma(pTsdb, pMeta, pMsg, inputType, &uidStore.suid);
|
||||
tsdbExecuteRSma(pTsdb, pMsg, inputType, uidStore.suid, uidStore.uid);
|
||||
|
||||
void *pIter = taosHashIterate(uidStore.uidHash, NULL);
|
||||
while (pIter) {
|
||||
tb_uid_t *pTbSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
|
||||
tsdbExecuteRSma(pTsdb, pMeta, pMsg, inputType, pTbSuid);
|
||||
tsdbExecuteRSma(pTsdb, pMsg, inputType, *pTbSuid, 0);
|
||||
pIter = taosHashIterate(uidStore.uidHash, pIter);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,11 +38,11 @@ int tsdbInsertData(STsdb *pTsdb, int64_t version, SSubmitReq *pMsg, SSubmitRsp *
|
|||
while (true) {
|
||||
tGetSubmitMsgNext(&msgIter, &pBlock);
|
||||
if (pBlock == NULL) break;
|
||||
if (tsdbInsertTableData(pTsdb, pBlock, &affectedrows) < 0) {
|
||||
if (tsdbInsertTableData(pTsdb, &msgIter, pBlock, &affectedrows) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
numOfRows += pBlock->numOfRows;
|
||||
numOfRows += msgIter.numOfRows;
|
||||
}
|
||||
|
||||
if (pRsp != NULL) {
|
||||
|
@ -66,20 +66,20 @@ static int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq *pMsg) {
|
|||
TSKEY maxKey = now + tsTickPerDay[pCfg->precision] * pCfg->days;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
pMsg->length = htonl(pMsg->length);
|
||||
pMsg->numOfBlocks = htonl(pMsg->numOfBlocks);
|
||||
// pMsg->length = htonl(pMsg->length);
|
||||
// pMsg->numOfBlocks = htonl(pMsg->numOfBlocks);
|
||||
|
||||
if (tInitSubmitMsgIter(pMsg, &msgIter) < 0) return -1;
|
||||
while (true) {
|
||||
if (tGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1;
|
||||
if (pBlock == NULL) break;
|
||||
|
||||
pBlock->uid = htobe64(pBlock->uid);
|
||||
pBlock->suid = htobe64(pBlock->suid);
|
||||
pBlock->sversion = htonl(pBlock->sversion);
|
||||
pBlock->dataLen = htonl(pBlock->dataLen);
|
||||
pBlock->schemaLen = htonl(pBlock->schemaLen);
|
||||
pBlock->numOfRows = htons(pBlock->numOfRows);
|
||||
// pBlock->uid = htobe64(pBlock->uid);
|
||||
// pBlock->suid = htobe64(pBlock->suid);
|
||||
// pBlock->sversion = htonl(pBlock->sversion);
|
||||
// pBlock->dataLen = htonl(pBlock->dataLen);
|
||||
// pBlock->schemaLen = htonl(pBlock->schemaLen);
|
||||
// pBlock->numOfRows = htons(pBlock->numOfRows);
|
||||
|
||||
#if 0
|
||||
if (pBlock->tid <= 0 || pBlock->tid >= pMeta->maxTables) {
|
||||
|
|
|
@ -66,7 +66,6 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
|
|||
if (tjsonAddIntegerToObject(pJson, "keep0", pCfg->tsdbCfg.keep0) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "keep1", pCfg->tsdbCfg.keep1) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "keep2", pCfg->tsdbCfg.keep2) < 0) return -1;
|
||||
#ifdef TSDB_VNODE_SMA_DEBUG
|
||||
if (pCfg->tsdbCfg.retentions[0].freq > 0) {
|
||||
int32_t nRetention = 1;
|
||||
if (pCfg->tsdbCfg.retentions[1].freq > 0) {
|
||||
|
@ -87,7 +86,6 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
|
|||
tjsonAddItemToArray(pNodeRetentions, pNodeRetention);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (tjsonAddIntegerToObject(pJson, "wal.vgId", pCfg->walCfg.vgId) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "wal.fsyncPeriod", pCfg->walCfg.fsyncPeriod) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "wal.retentionPeriod", pCfg->walCfg.retentionPeriod) < 0) return -1;
|
||||
|
@ -135,11 +133,11 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
if (tjsonGetNumberValue(pJson, "keep0", pCfg->tsdbCfg.keep0) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "keep1", pCfg->tsdbCfg.keep1) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "keep2", pCfg->tsdbCfg.keep2) < 0) return -1;
|
||||
#ifdef TSDB_VNODE_SMA_DEBUG
|
||||
SJson *pNodeRetentions = tjsonGetObjectItem(pJson, "retentions");
|
||||
int nRetention = tjsonGetArraySize(pNodeRetentions);
|
||||
ASSERT(nRetention <= TSDB_RSMA_RETENTION_MAX);
|
||||
|
||||
int32_t nRetention = tjsonGetArraySize(pNodeRetentions);
|
||||
if (nRetention > TSDB_RETENTION_MAX) {
|
||||
nRetention = TSDB_RETENTION_MAX;
|
||||
}
|
||||
for (int32_t i = 0; i < nRetention; ++i) {
|
||||
SJson *pNodeRetention = tjsonGetArrayItem(pNodeRetentions, i);
|
||||
ASSERT(pNodeRetention != NULL);
|
||||
|
@ -148,7 +146,6 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
tjsonGetNumberValue(pNodeRetention, "keep", (pCfg->tsdbCfg.retentions)[i].keep);
|
||||
tjsonGetNumberValue(pNodeRetention, "keepUnit", (pCfg->tsdbCfg.retentions)[i].keepUnit);
|
||||
}
|
||||
#endif
|
||||
if (tjsonGetNumberValue(pJson, "wal.vgId", pCfg->walCfg.vgId) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "wal.fsyncPeriod", pCfg->walCfg.fsyncPeriod) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "wal.retentionPeriod", pCfg->walCfg.retentionPeriod) < 0) return -1;
|
||||
|
|
|
@ -47,9 +47,26 @@ int vnodeBegin(SVnode *pVnode) {
|
|||
}
|
||||
|
||||
// begin tsdb
|
||||
if (tsdbBegin(pVnode->pTsdb) < 0) {
|
||||
vError("vgId:%d failed to begin tsdb since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
return -1;
|
||||
if (vnodeIsRollup(pVnode)) {
|
||||
if (tsdbBegin(VND_RSMA0(pVnode)) < 0) {
|
||||
vError("vgId:%d failed to begin rsma0 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbBegin(VND_RSMA1(pVnode)) < 0) {
|
||||
vError("vgId:%d failed to begin rsma1 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbBegin(VND_RSMA2(pVnode)) < 0) {
|
||||
vError("vgId:%d failed to begin rsma2 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (tsdbBegin(pVnode->pTsdb) < 0) {
|
||||
vError("vgId:%d failed to begin tsdb since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -96,24 +96,24 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|||
}
|
||||
|
||||
// open tsdb
|
||||
if (tsdbIsRollup(pVnode)) {
|
||||
if (vnodeIsRollup(pVnode)) {
|
||||
if (tsdbOpen(pVnode, TSDB_TYPE_RSMA_L0) < 0) {
|
||||
vError("vgId: %d failed to open vnode rsma0 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
vError("vgId:%d failed to open vnode rsma0 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (tsdbOpen(pVnode, TSDB_TYPE_RSMA_L1) < 0) {
|
||||
vError("vgId: %d failed to open vnode rsma1 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
vError("vgId:%d failed to open vnode rsma1 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (tsdbOpen(pVnode, TSDB_TYPE_RSMA_L2) < 0) {
|
||||
vError("vgId: %d failed to open vnode rsma2 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
vError("vgId:%d failed to open vnode rsma2 since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
goto _err;
|
||||
}
|
||||
} else {
|
||||
if (tsdbOpen(pVnode, TSDB_TYPE_TSDB) < 0) {
|
||||
vError("vgId: %d failed to open vnode tsdb since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
vError("vgId:%d failed to open vnode tsdb since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
@ -160,8 +160,8 @@ _err:
|
|||
if (pVnode->pWal) walClose(pVnode->pWal);
|
||||
if (pVnode->pTsdb) tsdbClose(pVnode->pTsdb);
|
||||
if (pVnode->pMeta) metaClose(pVnode->pMeta);
|
||||
tsdbClose(VND_RSMA1(pVnode));
|
||||
tsdbClose(VND_RSMA2(pVnode));
|
||||
tsdbClose(VND_RSMA1(pVnode));
|
||||
tsdbClose(VND_RSMA2(pVnode));
|
||||
tsem_destroy(&(pVnode->canCommit));
|
||||
taosMemoryFree(pVnode);
|
||||
return NULL;
|
||||
|
|
|
@ -461,7 +461,7 @@ static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
SSubmitRsp rsp = {0};
|
||||
|
||||
pRsp->code = 0;
|
||||
tsdbTriggerRSma(pVnode->pTsdb, pVnode->pMeta, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK);
|
||||
|
||||
// handle the request
|
||||
if (tsdbInsertData(pVnode->pTsdb, version, pSubmitReq, &rsp) < 0) {
|
||||
pRsp->code = terrno;
|
||||
|
@ -470,12 +470,28 @@ static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
|
||||
// pRsp->msgType = TDMT_VND_SUBMIT_RSP;
|
||||
// vnodeProcessSubmitReq(pVnode, ptr, pRsp);
|
||||
// tsdbTriggerRSma(pVnode->pTsdb, pVnode->pMeta, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK);
|
||||
|
||||
// encode the response (TODO)
|
||||
pRsp->pCont = rpcMallocCont(sizeof(SSubmitRsp));
|
||||
memcpy(pRsp->pCont, &rsp, sizeof(rsp));
|
||||
pRsp->contLen = sizeof(SSubmitRsp);
|
||||
|
||||
tsdbTriggerRSma(pVnode->pTsdb, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tsdbProcessSubmitReq(STsdb *pTsdb, int64_t version, void *pReq) {
|
||||
if(!pReq) {
|
||||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
SSubmitReq *pSubmitReq = (SSubmitReq *)pReq;
|
||||
|
||||
if (tsdbInsertData(pTsdb, version, pSubmitReq, NULL) < 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -13,14 +13,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "query.h"
|
||||
#include "plannodes.h"
|
||||
#include "commandInt.h"
|
||||
#include "plannodes.h"
|
||||
#include "query.h"
|
||||
|
||||
int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pRes);
|
||||
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level);
|
||||
|
||||
|
||||
void qExplainFreeResNode(SExplainResNode *resNode) {
|
||||
if (NULL == resNode) {
|
||||
return;
|
||||
|
@ -28,12 +27,10 @@ void qExplainFreeResNode(SExplainResNode *resNode) {
|
|||
|
||||
taosMemoryFreeClear(resNode->pExecInfo);
|
||||
|
||||
SNode* node = NULL;
|
||||
FOREACH(node, resNode->pChildren) {
|
||||
qExplainFreeResNode((SExplainResNode *)node);
|
||||
}
|
||||
SNode *node = NULL;
|
||||
FOREACH(node, resNode->pChildren) { qExplainFreeResNode((SExplainResNode *)node); }
|
||||
nodesClearList(resNode->pChildren);
|
||||
|
||||
|
||||
taosMemoryFreeClear(resNode);
|
||||
}
|
||||
|
||||
|
@ -59,24 +56,24 @@ void qExplainFreeCtx(SExplainCtx *pCtx) {
|
|||
taosMemoryFreeClear(rsp->subplanInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pIter = taosHashIterate(pCtx->groupHash, pIter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
taosHashCleanup(pCtx->groupHash);
|
||||
taosArrayDestroy(pCtx->rows);
|
||||
taosMemoryFree(pCtx);
|
||||
}
|
||||
|
||||
int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, double ratio, EExplainMode mode) {
|
||||
int32_t code = 0;
|
||||
int32_t code = 0;
|
||||
SExplainCtx *ctx = taosMemoryCalloc(1, sizeof(SExplainCtx));
|
||||
if (NULL == ctx) {
|
||||
qError("calloc SExplainCtx failed");
|
||||
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
|
||||
SArray *rows = taosArrayInit(10, sizeof(SQueryExplainRowInfo));
|
||||
if (NULL == rows) {
|
||||
qError("taosArrayInit SQueryExplainRowInfo failed");
|
||||
|
@ -95,7 +92,7 @@ int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, d
|
|||
ctx->tbuf = tbuf;
|
||||
ctx->rows = rows;
|
||||
ctx->groupHash = groupHash;
|
||||
|
||||
|
||||
*pCtx = ctx;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -110,9 +107,9 @@ _return:
|
|||
}
|
||||
|
||||
int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
|
||||
int32_t tlen = 0;
|
||||
int32_t tlen = 0;
|
||||
SNodeList *pPhysiChildren = NULL;
|
||||
|
||||
|
||||
switch (pNode->type) {
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
|
||||
STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
|
||||
|
@ -120,47 +117,47 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNo
|
|||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {
|
||||
STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
|
||||
pPhysiChildren = pTblScanNode->scan.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: {
|
||||
SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
|
||||
pPhysiChildren = pSTblScanNode->scan.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
|
||||
SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
|
||||
pPhysiChildren = pPrjNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_JOIN:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_JOIN: {
|
||||
SJoinPhysiNode *pJoinNode = (SJoinPhysiNode *)pNode;
|
||||
pPhysiChildren = pJoinNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_AGG:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_AGG: {
|
||||
SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
|
||||
pPhysiChildren = pAggNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
|
||||
SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
|
||||
pPhysiChildren = pExchNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT: {
|
||||
SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
|
||||
pPhysiChildren = pSortNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: {
|
||||
SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
|
||||
pPhysiChildren = pIntNode->window.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: {
|
||||
SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
|
||||
pPhysiChildren = pSessNode->window.node.pChildren;
|
||||
break;
|
||||
|
@ -178,7 +175,7 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNo
|
|||
}
|
||||
}
|
||||
|
||||
SNode* node = NULL;
|
||||
SNode *node = NULL;
|
||||
SExplainResNode *pResNode = NULL;
|
||||
FOREACH(node, pPhysiChildren) {
|
||||
QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode));
|
||||
|
@ -195,14 +192,14 @@ int32_t qExplainGenerateResNodeExecInfo(SArray **pExecInfo, SExplainGroup *group
|
|||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SExplainRsp *rsp = NULL;
|
||||
SExplainRsp *rsp = NULL;
|
||||
for (int32_t i = 0; i < group->nodeNum; ++i) {
|
||||
rsp = taosArrayGet(group->nodeExecInfo, i);
|
||||
if (group->physiPlanExecIdx >= rsp->numOfPlans) {
|
||||
qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
|
||||
taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx);
|
||||
}
|
||||
|
||||
|
@ -217,7 +214,7 @@ int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplai
|
|||
qError("physical node is NULL");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
|
||||
SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
|
||||
if (NULL == resNode) {
|
||||
qError("calloc SPhysiNodeExplainRes failed");
|
||||
|
@ -226,15 +223,15 @@ int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplai
|
|||
|
||||
int32_t code = 0;
|
||||
resNode->pNode = pNode;
|
||||
|
||||
|
||||
if (group->nodeExecInfo) {
|
||||
QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(&resNode->pExecInfo, group));
|
||||
}
|
||||
|
||||
|
||||
QRY_ERR_JRET(qExplainGenerateResChildren(pNode, group, &resNode->pChildren));
|
||||
|
||||
++group->physiPlanNum;
|
||||
|
||||
|
||||
*pResNode = resNode;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -242,15 +239,15 @@ int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplai
|
|||
_return:
|
||||
|
||||
qExplainFreeResNode(resNode);
|
||||
|
||||
|
||||
QRY_RET(code);
|
||||
}
|
||||
|
||||
int32_t qExplainBufAppendExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
|
||||
int32_t tlen = *len;
|
||||
int32_t nodeNum = taosArrayGetSize(pExecInfo);
|
||||
int32_t tlen = *len;
|
||||
int32_t nodeNum = taosArrayGetSize(pExecInfo);
|
||||
SExplainExecInfo maxExecInfo = {0};
|
||||
|
||||
|
||||
for (int32_t i = 0; i < nodeNum; ++i) {
|
||||
SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
|
||||
if (execInfo->startupCost > maxExecInfo.startupCost) {
|
||||
|
@ -263,20 +260,20 @@ int32_t qExplainBufAppendExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
|
|||
maxExecInfo.numOfRows = execInfo->numOfRows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, maxExecInfo.startupCost, maxExecInfo.totalCost, maxExecInfo.numOfRows);
|
||||
|
||||
*len = tlen;
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qExplainBufAppendVerboseExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
|
||||
int32_t tlen = 0;
|
||||
bool gotVerbose = false;
|
||||
int32_t nodeNum = taosArrayGetSize(pExecInfo);
|
||||
int32_t tlen = 0;
|
||||
bool gotVerbose = false;
|
||||
int32_t nodeNum = taosArrayGetSize(pExecInfo);
|
||||
SExplainExecInfo maxExecInfo = {0};
|
||||
|
||||
|
||||
for (int32_t i = 0; i < nodeNum; ++i) {
|
||||
SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
|
||||
if (execInfo->verboseInfo) {
|
||||
|
@ -289,11 +286,10 @@ int32_t qExplainBufAppendVerboseExecInfo(SArray *pExecInfo, char *tbuf, int32_t
|
|||
}
|
||||
|
||||
*len = tlen;
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t level) {
|
||||
SQueryExplainRowInfo row = {0};
|
||||
row.buf = taosMemoryMalloc(len);
|
||||
|
@ -304,7 +300,7 @@ int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t
|
|||
|
||||
memcpy(row.buf, tbuf, len);
|
||||
row.level = level;
|
||||
row.len = len;
|
||||
row.len = len;
|
||||
ctx->dataSize += row.len;
|
||||
|
||||
if (NULL == taosArrayPush(ctx->rows, &row)) {
|
||||
|
@ -316,21 +312,21 @@ int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static uint8_t getIntervalPrecision(SIntervalPhysiNode* pIntNode) {
|
||||
return ((SColumnNode*)pIntNode->window.pTspk)->node.resType.precision;
|
||||
static uint8_t getIntervalPrecision(SIntervalPhysiNode *pIntNode) {
|
||||
return ((SColumnNode *)pIntNode->window.pTspk)->node.resType.precision;
|
||||
}
|
||||
|
||||
int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
|
||||
int32_t tlen = 0;
|
||||
bool isVerboseLine = false;
|
||||
char *tbuf = ctx->tbuf;
|
||||
bool verbose = ctx->verbose;
|
||||
SPhysiNode* pNode = pResNode->pNode;
|
||||
int32_t tlen = 0;
|
||||
bool isVerboseLine = false;
|
||||
char *tbuf = ctx->tbuf;
|
||||
bool verbose = ctx->verbose;
|
||||
SPhysiNode *pNode = pResNode->pNode;
|
||||
if (NULL == pNode) {
|
||||
qError("pyhsical node in explain res node is NULL");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
|
||||
switch (pNode->type) {
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
|
||||
STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
|
||||
|
@ -339,7 +335,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTagScanNode->pScanCols->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||
|
@ -350,80 +346,85 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pTagScanNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pTagScanNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
if (tlen) {
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {
|
||||
STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_TBL_SCAN_FORMAT, pTblScanNode->scan.tableName.tname);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_TABLE_SCAN_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (verbose) {
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey, pTblScanNode->scanRange.ekey);
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey,
|
||||
pTblScanNode->scanRange.ekey);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pTblScanNode->scan.node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: {
|
||||
SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (verbose) {
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
|
@ -431,91 +432,96 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
|
||||
if (pSTblScanNode->scan.node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pSTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
QRY_ERR_RET(nodesNodeToSQL(pSTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
|
||||
SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
|
||||
if (pPrjNode->node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pPrjNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pPrjNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_JOIN:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_JOIN: {
|
||||
SJoinPhysiNode *pJoinNode = (SJoinPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, EXPLAIN_JOIN_STRING(pJoinNode->joinType));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pJoinNode->node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pOnConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
|
||||
QRY_ERR_RET(
|
||||
nodesNodeToSQL(pJoinNode->pOnConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_AGG:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_AGG: {
|
||||
SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||
|
@ -523,57 +529,61 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pAggNode->node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pAggNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pAggNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
|
||||
SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
|
||||
SExplainGroup *group = taosHashGet(ctx->groupHash, &pExchNode->srcGroupId, sizeof(pExchNode->srcGroupId));
|
||||
SExplainGroup *group = taosHashGet(ctx->groupHash, &pExchNode->srcGroupId, sizeof(pExchNode->srcGroupId));
|
||||
if (NULL == group) {
|
||||
qError("exchange src group %d not in groupHash", pExchNode->srcGroupId);
|
||||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, group->nodeNum);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pExchNode->node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pExchNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pExchNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
@ -582,14 +592,14 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
QRY_ERR_RET(qExplainAppendGroupResRows(ctx, pExchNode->srcGroupId, level + 1));
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT: {
|
||||
SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSortNode->pSortKeys->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||
|
@ -599,29 +609,31 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pSortNode->node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: {
|
||||
SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
|
||||
|
@ -630,41 +642,39 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
uint8_t precision = getIntervalPrecision(pIntNode);
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT, INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision),
|
||||
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
|
||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision), pIntNode->slidingUnit);
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
|
||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision),
|
||||
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
|
||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision),
|
||||
pIntNode->slidingUnit);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pIntNode->pFill) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_FORMAT, getFillModeString(pIntNode->pFill->mode));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
||||
if (pIntNode->window.node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: {
|
||||
SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pSessNode->window.pFuncs->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize);
|
||||
|
@ -672,10 +682,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
|
||||
nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_END();
|
||||
|
@ -686,8 +696,9 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pSessNode->window.node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pSessNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pSessNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
@ -702,7 +713,6 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
|
||||
if (NULL == pResNode) {
|
||||
qError("explain res node is NULL");
|
||||
|
@ -712,29 +722,28 @@ int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32
|
|||
int32_t code = 0;
|
||||
QRY_ERR_RET(qExplainResNodeToRowsImpl(pResNode, ctx, level));
|
||||
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pResNode->pChildren) {
|
||||
QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, level + 1));
|
||||
}
|
||||
SNode *pNode = NULL;
|
||||
FOREACH(pNode, pResNode->pChildren) { QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, level + 1)); }
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level) {
|
||||
SExplainResNode *node = NULL;
|
||||
int32_t code = 0;
|
||||
SExplainCtx *ctx = (SExplainCtx *)pCtx;
|
||||
int32_t code = 0;
|
||||
SExplainCtx *ctx = (SExplainCtx *)pCtx;
|
||||
|
||||
SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
|
||||
if (NULL == group) {
|
||||
qError("group %d not in groupHash", groupId);
|
||||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
|
||||
QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group, &node));
|
||||
|
||||
if ((EXPLAIN_MODE_ANALYZE == ctx->mode) && (group->physiPlanNum != group->physiPlanExecNum)) {
|
||||
qError("physiPlanNum %d mismatch with physiExecNum %d in group %d", group->physiPlanNum, group->physiPlanExecNum, groupId);
|
||||
qError("physiPlanNum %d mismatch with physiExecNum %d in group %d", group->physiPlanNum, group->physiPlanExecNum,
|
||||
groupId);
|
||||
QRY_ERR_JRET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
|
@ -743,21 +752,21 @@ int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level) {
|
|||
_return:
|
||||
|
||||
qExplainFreeResNode(node);
|
||||
|
||||
|
||||
QRY_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
||||
SExplainCtx *pCtx = (SExplainCtx *)ctx;
|
||||
int32_t rowNum = taosArrayGetSize(pCtx->rows);
|
||||
int32_t rowNum = taosArrayGetSize(pCtx->rows);
|
||||
if (rowNum <= 0) {
|
||||
qError("empty explain res rows");
|
||||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
|
||||
int32_t colNum = 1;
|
||||
int32_t rspSize = sizeof(SRetrieveTableRsp) + sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize;
|
||||
int32_t rspSize = sizeof(SRetrieveTableRsp) + sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum +
|
||||
sizeof(int32_t) * rowNum + pCtx->dataSize;
|
||||
SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
|
||||
if (NULL == rsp) {
|
||||
qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
|
||||
|
@ -768,13 +777,14 @@ int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
|||
rsp->numOfRows = htonl(rowNum);
|
||||
|
||||
// payload length
|
||||
*(int32_t *)rsp->data = sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize;
|
||||
*(int32_t *)rsp->data =
|
||||
sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize;
|
||||
|
||||
// group id
|
||||
*(uint64_t*)(rsp->data + sizeof(int32_t)) = 0;
|
||||
*(uint64_t *)(rsp->data + sizeof(int32_t)) = 0;
|
||||
|
||||
// column length
|
||||
int32_t* colLength = (int32_t *)(rsp->data + sizeof(int32_t) + sizeof(uint64_t));
|
||||
int32_t *colLength = (int32_t *)(rsp->data + sizeof(int32_t) + sizeof(uint64_t));
|
||||
|
||||
// varchar column offset segment
|
||||
int32_t *offset = (int32_t *)((char *)colLength + sizeof(int32_t));
|
||||
|
@ -782,7 +792,7 @@ int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
|||
// varchar data real payload
|
||||
char *data = (char *)(offset + rowNum);
|
||||
|
||||
char* start = data;
|
||||
char *start = data;
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
|
||||
offset[i] = data - start;
|
||||
|
@ -800,11 +810,11 @@ int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
|||
}
|
||||
|
||||
int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
|
||||
int32_t code = 0;
|
||||
int32_t code = 0;
|
||||
SNodeListNode *plans = NULL;
|
||||
int32_t taskNum = 0;
|
||||
SExplainGroup *pGroup = NULL;
|
||||
SExplainCtx *ctx = NULL;
|
||||
SExplainCtx *ctx = NULL;
|
||||
|
||||
if (pDag->numOfSubplans <= 0) {
|
||||
qError("invalid subplan num:%d", pDag->numOfSubplans);
|
||||
|
@ -817,13 +827,15 @@ int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
|
|||
QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SHashObj *groupHash = taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||
SHashObj *groupHash =
|
||||
taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||
if (NULL == groupHash) {
|
||||
qError("groupHash %d failed", EXPLAIN_MAX_GROUP_NUM);
|
||||
QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
QRY_ERR_JRET(qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
|
||||
QRY_ERR_JRET(
|
||||
qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
|
||||
|
||||
for (int32_t i = 0; i < levelNum; ++i) {
|
||||
plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
|
||||
|
@ -850,7 +862,7 @@ int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
|
|||
SExplainGroup group = {0};
|
||||
group.nodeNum = 1;
|
||||
group.plan = plan;
|
||||
|
||||
|
||||
if (0 != taosHashPut(groupHash, &plan->id.groupId, sizeof(plan->id.groupId), &group, sizeof(group))) {
|
||||
qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
|
||||
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
|
@ -872,7 +884,7 @@ int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
|
|||
*pCtx = ctx;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
|
||||
_return:
|
||||
|
||||
qExplainFreeCtx(ctx);
|
||||
|
@ -886,7 +898,7 @@ int32_t qExplainAppendPlanRows(SExplainCtx *pCtx) {
|
|||
}
|
||||
|
||||
int32_t tlen = 0;
|
||||
char *tbuf = pCtx->tbuf;
|
||||
char *tbuf = pCtx->tbuf;
|
||||
|
||||
EXPLAIN_SUM_ROW_NEW(EXPLAIN_RATIO_TIME_FORMAT, pCtx->ratio);
|
||||
EXPLAIN_SUM_ROW_END();
|
||||
|
@ -911,11 +923,11 @@ int32_t qExplainGenerateRsp(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
|
||||
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
|
||||
SExplainResNode *node = NULL;
|
||||
int32_t code = 0;
|
||||
bool groupDone = false;
|
||||
SExplainCtx *ctx = (SExplainCtx *)pCtx;
|
||||
int32_t code = 0;
|
||||
bool groupDone = false;
|
||||
SExplainCtx *ctx = (SExplainCtx *)pCtx;
|
||||
|
||||
SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
|
||||
if (NULL == group) {
|
||||
|
@ -931,30 +943,32 @@ int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, i
|
|||
qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
|
||||
taosMemoryFreeClear(pRspMsg->subplanInfo);
|
||||
taosWUnLockLatch(&group->lock);
|
||||
|
||||
|
||||
QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
group->physiPlanExecNum = pRspMsg->numOfPlans;
|
||||
} else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) {
|
||||
qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo), group->nodeNum);
|
||||
qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo),
|
||||
group->nodeNum);
|
||||
taosMemoryFreeClear(pRspMsg->subplanInfo);
|
||||
taosWUnLockLatch(&group->lock);
|
||||
|
||||
|
||||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
if (group->physiPlanExecNum != pRspMsg->numOfPlans) {
|
||||
qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum, groupId);
|
||||
qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum,
|
||||
groupId);
|
||||
taosMemoryFreeClear(pRspMsg->subplanInfo);
|
||||
taosWUnLockLatch(&group->lock);
|
||||
|
||||
|
||||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
taosArrayPush(group->nodeExecInfo, pRspMsg);
|
||||
groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
|
||||
|
||||
|
||||
taosWUnLockLatch(&group->lock);
|
||||
|
||||
if (groupDone && (taosHashGetSize(pCtx->groupHash) == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) {
|
||||
|
@ -969,14 +983,13 @@ int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, i
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
|
||||
int32_t code = 0;
|
||||
int32_t code = 0;
|
||||
SExplainCtx *pCtx = NULL;
|
||||
|
||||
QRY_ERR_RET(qExplainPrepareCtx(pDag, &pCtx));
|
||||
QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
|
||||
|
||||
|
||||
_return:
|
||||
qExplainFreeCtx(pCtx);
|
||||
QRY_RET(code);
|
||||
|
@ -984,7 +997,7 @@ _return:
|
|||
|
||||
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs) {
|
||||
QRY_ERR_RET(qExplainPrepareCtx(pDag, pCtx));
|
||||
|
||||
|
||||
(*pCtx)->reqStartTs = startTs;
|
||||
(*pCtx)->jobStartTs = taosGetTimestampUs();
|
||||
|
||||
|
@ -994,7 +1007,7 @@ int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs)
|
|||
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
|
||||
int32_t code = 0;
|
||||
pCtx->jobDoneTs = taosGetTimestampUs();
|
||||
|
||||
|
||||
atomic_store_8((int8_t *)&pCtx->execDone, true);
|
||||
|
||||
if (taosHashGetSize(pCtx->groupHash) == atomic_load_32(&pCtx->groupDoneNum)) {
|
||||
|
@ -1006,6 +1019,3 @@ int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ add_library(executor STATIC ${EXECUTOR_SRC})
|
|||
# )
|
||||
|
||||
target_link_libraries(executor
|
||||
PRIVATE os util common function parser planner qcom vnode scalar nodes
|
||||
PRIVATE os util common function parser planner qcom vnode scalar nodes index
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
|
@ -19,4 +19,4 @@ target_include_directories(
|
|||
|
||||
#if(${BUILD_TEST})
|
||||
ADD_SUBDIRECTORY(test)
|
||||
#endif(${BUILD_TEST})
|
||||
#endif(${BUILD_TEST})
|
||||
|
|
|
@ -41,8 +41,6 @@
|
|||
#define SET_MAIN_SCAN_FLAG(runtime) ((runtime)->scanFlag = MAIN_SCAN)
|
||||
#define SET_REVERSE_SCAN_FLAG(runtime) ((runtime)->scanFlag = REVERSE_SCAN)
|
||||
|
||||
#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))
|
||||
|
||||
#define SDATA_BLOCK_INITIALIZER \
|
||||
(SDataBlockInfo) { {0}, 0 }
|
||||
|
||||
|
@ -1101,7 +1099,10 @@ static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCt
|
|||
pInput->numOfRows = pBlock->info.rows;
|
||||
pInput->startRowIndex = 0;
|
||||
|
||||
pInput->pPTS = taosArrayGet(pBlock->pDataBlock, 0); // todo set the correct timestamp column
|
||||
// the last parameter is the timestamp column
|
||||
if (fmIsTimelineFunc(pCtx[i].functionId) && (j == pOneExpr->base.numOfParams - 1)) {
|
||||
pInput->pPTS = pInput->pData[j];
|
||||
}
|
||||
ASSERT(pInput->pData[j] != NULL);
|
||||
} else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
|
||||
// todo avoid case: top(k, 12), 12 is the value parameter.
|
||||
|
@ -1179,7 +1180,7 @@ static void setPseudoOutputColInfo(SSDataBlock* pResult, SqlFunctionCtx* pCtx, S
|
|||
}
|
||||
|
||||
int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
|
||||
int32_t numOfOutput, SArray* pPseudoList) {
|
||||
int32_t numOfOutput, SArray* pPseudoList) {
|
||||
setPseudoOutputColInfo(pResult, pCtx, pPseudoList);
|
||||
pResult->info.groupId = pSrcBlock->info.groupId;
|
||||
|
||||
|
@ -1196,7 +1197,7 @@ 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, 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);
|
||||
}
|
||||
|
@ -1224,7 +1225,7 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
|
|||
scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);
|
||||
|
||||
int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
|
||||
colDataMergeCol(pResColData, startOffset, &idata, dest.numOfRows);
|
||||
colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows);
|
||||
|
||||
numOfRows = dest.numOfRows;
|
||||
taosArrayDestroy(pBlockList);
|
||||
|
@ -1258,14 +1259,14 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
|
|||
SColumnInfoData idata = {.info = pResColData->info, .hasNull = true};
|
||||
|
||||
SScalarParam dest = {.columnData = &idata};
|
||||
int32_t code = scalarCalculate((SNode*)pExpr[k].pExpr->_function.pFunctNode, pBlockList, &dest);
|
||||
int32_t code = scalarCalculate((SNode*)pExpr[k].pExpr->_function.pFunctNode, pBlockList, &dest);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosArrayDestroy(pBlockList);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
|
||||
colDataMergeCol(pResColData, startOffset, &idata, dest.numOfRows);
|
||||
colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows);
|
||||
|
||||
numOfRows = dest.numOfRows;
|
||||
taosArrayDestroy(pBlockList);
|
||||
|
@ -3959,9 +3960,8 @@ static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SEx
|
|||
}
|
||||
|
||||
SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
|
||||
code =
|
||||
setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
||||
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
|
||||
code = setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
||||
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
|
||||
if (code != 0) {
|
||||
goto _error;
|
||||
}
|
||||
|
@ -4781,8 +4781,8 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
|||
|
||||
// there is an scalar expression that needs to be calculated before apply the group aggregation.
|
||||
if (pAggInfo->pScalarExprInfo != NULL) {
|
||||
int32_t code = projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx, pAggInfo->numOfScalarExpr,
|
||||
NULL);
|
||||
int32_t code = projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx,
|
||||
pAggInfo->numOfScalarExpr, NULL);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pTaskInfo->code = code;
|
||||
longjmp(pTaskInfo->env, pTaskInfo->code);
|
||||
|
@ -6540,8 +6540,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
|
||||
int32_t numOfCols = 0;
|
||||
SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
|
||||
SOperatorInfo* pOperator =
|
||||
createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo, pScanPhyNode->node.pConditions);
|
||||
SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo,
|
||||
pScanPhyNode->node.pConditions);
|
||||
taosArrayDestroy(tableIdList);
|
||||
return pOperator;
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
|
||||
|
@ -6622,10 +6622,11 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, primaryTsSlotId, &as,
|
||||
pTableGroupInfo, pTaskInfo);
|
||||
|
||||
if (pIntervalPhyNode->pFill != NULL) {
|
||||
pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode, NULL,
|
||||
false, pTaskInfo);
|
||||
}
|
||||
// if (pIntervalPhyNode->pFill != NULL) {
|
||||
// pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode,
|
||||
// NULL,
|
||||
// false, pTaskInfo);
|
||||
// }
|
||||
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
|
||||
SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
|
||||
|
@ -6927,7 +6928,7 @@ tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle*
|
|||
code = initQueryTableDataCond(&cond, pTableScanNode);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
return tsdbQueryTables(pHandle->reader, &cond, pTableGroupInfo, queryId, taskId);
|
||||
#endif
|
||||
|
@ -7167,7 +7168,6 @@ int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo
|
|||
|
||||
static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup) {
|
||||
SJoinOperatorInfo* pJoinInfo = pOperator->info;
|
||||
// SOptrBasicInfo* pInfo = &pJoinInfo->binfo;
|
||||
|
||||
SSDataBlock* pRes = pJoinInfo->pRes;
|
||||
blockDataCleanup(pRes);
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
#include "indexoperator.h"
|
||||
#include "executorimpl.h"
|
||||
#include "index.h"
|
||||
#include "nodes.h"
|
||||
#include "tdatablock.h"
|
||||
|
||||
typedef struct SIFCtx {
|
||||
int32_t code;
|
||||
|
@ -48,11 +50,19 @@ typedef struct SIFCtx {
|
|||
} while (0)
|
||||
|
||||
typedef struct SIFParam {
|
||||
SArray * result;
|
||||
SHashObj *pFilter;
|
||||
|
||||
SArray *result;
|
||||
char * condValue;
|
||||
|
||||
col_id_t colId;
|
||||
|
||||
int64_t suid; // add later
|
||||
char dbName[TSDB_DB_NAME_LEN];
|
||||
char colName[TSDB_COL_NAME_LEN];
|
||||
} SIFParam;
|
||||
|
||||
typedef int32_t (*sif_func_t)(SNode *left, SNode *rigth, SIFParam *output);
|
||||
typedef int32_t (*sif_func_t)(SIFParam *left, SIFParam *rigth, SIFParam *output);
|
||||
// construct tag filter operator later
|
||||
static void destroyTagFilterOperatorInfo(void *param) {
|
||||
STagFilterOperatorInfo *pInfo = (STagFilterOperatorInfo *)param;
|
||||
|
@ -60,7 +70,10 @@ static void destroyTagFilterOperatorInfo(void *param) {
|
|||
|
||||
static void sifFreeParam(SIFParam *param) {
|
||||
if (param == NULL) return;
|
||||
|
||||
taosArrayDestroy(param->result);
|
||||
taosMemoryFree(param->condValue);
|
||||
taosHashCleanup(param->pFilter);
|
||||
}
|
||||
|
||||
static int32_t sifGetOperParamNum(EOperatorType ty) {
|
||||
|
@ -71,15 +84,70 @@ static int32_t sifGetOperParamNum(EOperatorType ty) {
|
|||
}
|
||||
return 2;
|
||||
}
|
||||
static int32_t sifValidateColumn(SColumnNode *cn) {
|
||||
// add more check
|
||||
if (cn == NULL) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
if (cn->colType != COLUMN_TYPE_TAG) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t sifGetValueFromNode(SNode *node, char **value) {
|
||||
// covert data From snode;
|
||||
SValueNode *vn = (SValueNode *)node;
|
||||
|
||||
char * pData = nodesGetValueFromNode(vn);
|
||||
SDataType *pType = &vn->node.resType;
|
||||
int32_t type = pType->type;
|
||||
int32_t valLen = 0;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(type)) {
|
||||
int32_t dataLen = varDataTLen(pData);
|
||||
if (type == TSDB_DATA_TYPE_JSON) {
|
||||
if (*pData == TSDB_DATA_TYPE_NULL) {
|
||||
dataLen = 0;
|
||||
} else if (*pData == TSDB_DATA_TYPE_NCHAR) {
|
||||
dataLen = varDataTLen(pData + CHAR_BYTES);
|
||||
} else if (*pData == TSDB_DATA_TYPE_BIGINT || *pData == TSDB_DATA_TYPE_DOUBLE) {
|
||||
dataLen = LONG_BYTES;
|
||||
} else if (*pData == TSDB_DATA_TYPE_BOOL) {
|
||||
dataLen = CHAR_BYTES;
|
||||
}
|
||||
dataLen += CHAR_BYTES;
|
||||
}
|
||||
valLen = dataLen;
|
||||
} else {
|
||||
valLen = pType->bytes;
|
||||
}
|
||||
char *tv = taosMemoryCalloc(1, valLen + 1);
|
||||
if (tv == NULL) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(tv, pData, valLen);
|
||||
*value = tv;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t sifInitParam(SNode *node, SIFParam *param, SIFCtx *ctx) {
|
||||
switch (nodeType(node)) {
|
||||
case QUERY_NODE_VALUE: {
|
||||
SValueNode *vn = (SValueNode *)node;
|
||||
|
||||
SIF_ERR_RET(sifGetValueFromNode(node, ¶m->condValue));
|
||||
param->colId = -1;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_COLUMN: {
|
||||
SColumnNode *cn = (SColumnNode *)node;
|
||||
/*only support tag column*/
|
||||
SIF_ERR_RET(sifValidateColumn(cn));
|
||||
param->colId = cn->colId;
|
||||
memcpy(param->dbName, cn->dbName, sizeof(cn->dbName));
|
||||
memcpy(param->colName, cn->colName, sizeof(cn->colName));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -89,7 +157,7 @@ static int32_t sifInitParam(SNode *node, SIFParam *param, SIFCtx *ctx) {
|
|||
qError("invalid length for node:%p, length: %d", node, LIST_LENGTH(nl->pNodeList));
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SIF_ERR_RET(scalarGenerateSetFromList((void **)¶m->pFilter, node, nl->dataType.type));
|
||||
if (taosHashPut(ctx->pRes, &node, POINTER_BYTES, param, sizeof(*param))) {
|
||||
taosHashCleanup(param->pFilter);
|
||||
qError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param));
|
||||
|
@ -163,58 +231,63 @@ static int32_t sifExecFunction(SFunctionNode *node, SIFCtx *ctx, SIFParam *outpu
|
|||
qError("index-filter not support buildin function");
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
static int32_t sifLessThanFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t sifLessEqualFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t sifGreaterThanFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t sifGreaterEqualFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
static int32_t sifIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFParam *output) {
|
||||
SIndexMultiTermQuery *mq = indexMultiTermQueryCreate(MUST);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t sifEqualFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
static int32_t sifLessThanFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_LOWER_THAN;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifNotEqualFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t sifInFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t sifNotInFunc(SNode *left, SNode *right, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t sifLikeFunc(SNode *left, SNode *right, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t sifNotLikeFunc(SNode *left, SNode *right, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
static int32_t sifLessEqualFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_LOWER_EQUAL;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
|
||||
static int32_t sifMatchFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
static int32_t sifGreaterThanFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_GREATER_THAN;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifNotMatchFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
// impl later
|
||||
return TSDB_CODE_SUCCESS;
|
||||
static int32_t sifGreaterEqualFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_GREATER_EQUAL;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifDefaultFunc(SNode *left, SNode *rigth, SIFParam *output) {
|
||||
|
||||
static int32_t sifEqualFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_EQUAL;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifNotEqualFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_NOT_EQUAL;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifInFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_IN;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifNotInFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_NOT_IN;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifLikeFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_LIKE;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifNotLikeFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_NOT_LIKE;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
|
||||
static int32_t sifMatchFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_MATCH;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifNotMatchFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
int id = OP_TYPE_NMATCH;
|
||||
return sifIndex(left, right, id, output);
|
||||
}
|
||||
static int32_t sifDefaultFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
// add more except
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
@ -252,17 +325,18 @@ static sif_func_t sifGetOperFn(int32_t funcId) {
|
|||
return sifDefaultFunc;
|
||||
}
|
||||
static int32_t sifExecOper(SOperatorNode *node, SIFCtx *ctx, SIFParam *output) {
|
||||
int32_t code = 0;
|
||||
SIFParam *params = NULL;
|
||||
SIF_ERR_RET(sifInitOperParams(¶ms, node, ctx));
|
||||
|
||||
int32_t code = 0;
|
||||
int32_t nParam = sifGetOperParamNum(node->opType);
|
||||
if (nParam <= 1) {
|
||||
SIF_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SIFParam *params = NULL;
|
||||
SIF_ERR_RET(sifInitOperParams(¶ms, node, ctx));
|
||||
|
||||
sif_func_t operFn = sifGetOperFn(node->opType);
|
||||
|
||||
return operFn(node->pLeft, node->pRight, output);
|
||||
return operFn(¶ms[0], nParam > 1 ? ¶ms[1] : NULL, output);
|
||||
_return:
|
||||
taosMemoryFree(params);
|
||||
SIF_RET(code);
|
||||
|
@ -335,7 +409,6 @@ static EDealRes sifWalkOper(SNode *pNode, void *context) {
|
|||
if (ctx->code) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
|
||||
ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
|
|
|
@ -39,6 +39,7 @@ extern "C" {
|
|||
#define FUNC_MGT_DYNAMIC_SCAN_OPTIMIZED FUNC_MGT_FUNC_CLASSIFICATION_MASK(10)
|
||||
#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_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
||||
|
||||
|
|
|
@ -438,6 +438,11 @@ static int32_t translateToJson(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateSelectValue(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
pFunc->node.resType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||
{
|
||||
|
@ -465,7 +470,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "min",
|
||||
.type = FUNCTION_TYPE_MIN,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_SELECT_FUNC,
|
||||
.translateFunc = translateInOutNum,
|
||||
.dataRequiredFunc = statisDataRequired,
|
||||
.getEnvFunc = getMinmaxFuncEnv,
|
||||
|
@ -476,7 +481,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "max",
|
||||
.type = FUNCTION_TYPE_MAX,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_SELECT_FUNC,
|
||||
.translateFunc = translateInOutNum,
|
||||
.dataRequiredFunc = statisDataRequired,
|
||||
.getEnvFunc = getMinmaxFuncEnv,
|
||||
|
@ -974,6 +979,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = NULL,
|
||||
.sprocessFunc = toJsonFunction,
|
||||
.finalizeFunc = NULL
|
||||
},
|
||||
{
|
||||
.name = "_select_value",
|
||||
.type = FUNCTION_TYPE_SELECT_VALUE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC,
|
||||
.translateFunc = translateSelectValue,
|
||||
.getEnvFunc = NULL,
|
||||
.initFunc = NULL,
|
||||
.sprocessFunc = NULL,
|
||||
.finalizeFunc = NULL
|
||||
}
|
||||
};
|
||||
// clang-format on
|
||||
|
|
|
@ -145,6 +145,8 @@ bool fmIsAggFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MG
|
|||
|
||||
bool fmIsScalarFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_SCALAR_FUNC); }
|
||||
|
||||
bool fmIsSelectFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_SELECT_FUNC); }
|
||||
|
||||
bool fmIsTimelineFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_TIMELINE_FUNC); }
|
||||
|
||||
bool fmIsPseudoColumnFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_PSEUDO_COLUMN_FUNC); }
|
||||
|
|
|
@ -1176,7 +1176,7 @@ int32_t callUdfAggMerge(UdfcFuncHandle handle, SUdfInterBuf *interBuf1, SUdfInte
|
|||
// input: interBuf
|
||||
// output: resultData
|
||||
int32_t callUdfAggFinalize(UdfcFuncHandle handle, SUdfInterBuf *interBuf, SUdfInterBuf *resultData) {
|
||||
int8_t callType = TSDB_UDF_CALL_AGG_PROC;
|
||||
int8_t callType = TSDB_UDF_CALL_AGG_FIN;
|
||||
int32_t err = callUdf(handle, callType, NULL, interBuf, NULL, NULL, resultData);
|
||||
return err;
|
||||
}
|
||||
|
@ -1243,12 +1243,12 @@ bool udfAggInit(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo* pResult
|
|||
}
|
||||
SUdfUvSession *session = (SUdfUvSession *)handle;
|
||||
SUdfAggRes *udfRes = (SUdfAggRes*)GET_ROWCELL_INTERBUF(pResultCellInfo);
|
||||
udfRes->finalResBuf = (char*)udfRes + sizeof(SUdfAggRes);
|
||||
udfRes->interResBuf = (char*)udfRes + sizeof(SUdfAggRes) + session->outputLen;
|
||||
|
||||
int32_t envSize = sizeof(SUdfAggRes) + session->outputLen + session->bufSize;
|
||||
memset(udfRes, 0, envSize);
|
||||
|
||||
udfRes->finalResBuf = (char*)udfRes + sizeof(SUdfAggRes);
|
||||
udfRes->interResBuf = (char*)udfRes + sizeof(SUdfAggRes) + session->outputLen;
|
||||
|
||||
udfRes->session = (SUdfUvSession *)handle;
|
||||
SUdfInterBuf buf = {0};
|
||||
if (callUdfAggInit(handle, &buf) != 0) {
|
||||
|
@ -1260,7 +1260,6 @@ bool udfAggInit(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo* pResult
|
|||
}
|
||||
|
||||
int32_t udfAggProcess(struct SqlFunctionCtx *pCtx) {
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
int32_t numOfCols = pInput->numOfInputCols;
|
||||
|
||||
|
@ -1320,13 +1319,15 @@ int32_t udfAggFinalize(struct SqlFunctionCtx *pCtx, SSDataBlock* pBlock) {
|
|||
udfRes->interResBuf = (char*)udfRes + sizeof(SUdfAggRes) + session->outputLen;
|
||||
|
||||
|
||||
SUdfInterBuf resultBuf = {.buf = udfRes->finalResBuf,
|
||||
.bufLen = session->outputLen,
|
||||
.numOfResult = udfRes->finalResNum};
|
||||
SUdfInterBuf resultBuf = {0};
|
||||
SUdfInterBuf state = {.buf = udfRes->interResBuf,
|
||||
.bufLen = session->bufSize,
|
||||
.numOfResult = udfRes->interResNum};
|
||||
callUdfAggFinalize(session, &state, &resultBuf);
|
||||
|
||||
udfRes->finalResBuf = resultBuf.buf;
|
||||
udfRes->finalResNum = resultBuf.numOfResult;
|
||||
|
||||
teardownUdf(session);
|
||||
|
||||
if (resultBuf.numOfResult == 1) {
|
||||
|
|
|
@ -124,7 +124,7 @@ int32_t udfdLoadUdf(char *udfName, SUdf *udf) {
|
|||
char *finishSuffix = "_finish";
|
||||
strncpy(finishFuncName, processFuncName, strlen(processFuncName));
|
||||
strncat(finishFuncName, finishSuffix, strlen(finishSuffix));
|
||||
uv_dlsym(&udf->lib, startFuncName, (void **)(&udf->aggFinishFunc));
|
||||
uv_dlsym(&udf->lib, finishFuncName, (void **)(&udf->aggFinishFunc));
|
||||
//TODO: merge
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -27,7 +27,7 @@ int32_t udf2_start(SUdfInterBuf *buf) {
|
|||
int32_t udf2(SUdfDataBlock* block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) {
|
||||
int64_t sumSquares = *(int64_t*)interBuf->buf;
|
||||
for (int32_t i = 0; i < block->numOfCols; ++i) {
|
||||
for (int32_t j = 0; j < block->numOfRows; ++i) {
|
||||
for (int32_t j = 0; j < block->numOfRows; ++j) {
|
||||
SUdfColumn* col = block->udfCols[i];
|
||||
//TODO: check the bitmap for null value
|
||||
int32_t* rows = (int32_t*)col->colData.fixLenCol.data;
|
||||
|
@ -35,7 +35,7 @@ int32_t udf2(SUdfDataBlock* block, SUdfInterBuf *interBuf, SUdfInterBuf *newInte
|
|||
}
|
||||
}
|
||||
|
||||
*(int64_t*)newInterBuf = sumSquares;
|
||||
*(int64_t*)(newInterBuf->buf) = sumSquares;
|
||||
newInterBuf->bufLen = sizeof(int64_t);
|
||||
//TODO: if all null value, numOfResult = 0;
|
||||
newInterBuf->numOfResult = 1;
|
||||
|
|
|
@ -68,7 +68,7 @@ extern "C" {
|
|||
*/
|
||||
void iIntersection(SArray *interResults, SArray *finalResult);
|
||||
|
||||
/* multi sorted result intersection
|
||||
/* multi sorted result union
|
||||
* input: [1, 2, 4, 5]
|
||||
* [2, 3, 4, 5]
|
||||
* [1, 4, 5]
|
||||
|
@ -76,7 +76,7 @@ void iIntersection(SArray *interResults, SArray *finalResult);
|
|||
*/
|
||||
void iUnion(SArray *interResults, SArray *finalResult);
|
||||
|
||||
/* sorted array
|
||||
/* see example
|
||||
* total: [1, 2, 4, 5, 7, 8]
|
||||
* except: [4, 5]
|
||||
* return: [1, 2, 7, 8] saved in total
|
||||
|
|
|
@ -258,13 +258,13 @@ void indexOptsDestroy(SIndexOpts* opts) {
|
|||
*
|
||||
*/
|
||||
SIndexMultiTermQuery* indexMultiTermQueryCreate(EIndexOperatorType opera) {
|
||||
SIndexMultiTermQuery* p = (SIndexMultiTermQuery*)taosMemoryMalloc(sizeof(SIndexMultiTermQuery));
|
||||
if (p == NULL) {
|
||||
SIndexMultiTermQuery* mtq = (SIndexMultiTermQuery*)taosMemoryMalloc(sizeof(SIndexMultiTermQuery));
|
||||
if (mtq == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
p->opera = opera;
|
||||
p->query = taosArrayInit(4, sizeof(SIndexTermQuery));
|
||||
return p;
|
||||
mtq->opera = opera;
|
||||
mtq->query = taosArrayInit(4, sizeof(SIndexTermQuery));
|
||||
return mtq;
|
||||
}
|
||||
void indexMultiTermQueryDestroy(SIndexMultiTermQuery* pQuery) {
|
||||
for (int i = 0; i < taosArrayGetSize(pQuery->query); i++) {
|
||||
|
@ -282,23 +282,24 @@ int indexMultiTermQueryAdd(SIndexMultiTermQuery* pQuery, SIndexTerm* term, EInde
|
|||
|
||||
SIndexTerm* indexTermCreate(int64_t suid, SIndexOperOnColumn oper, uint8_t colType, const char* colName,
|
||||
int32_t nColName, const char* colVal, int32_t nColVal) {
|
||||
SIndexTerm* t = (SIndexTerm*)taosMemoryCalloc(1, (sizeof(SIndexTerm)));
|
||||
if (t == NULL) {
|
||||
SIndexTerm* tm = (SIndexTerm*)taosMemoryCalloc(1, (sizeof(SIndexTerm)));
|
||||
if (tm == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t->suid = suid;
|
||||
t->operType = oper;
|
||||
t->colType = colType;
|
||||
tm->suid = suid;
|
||||
tm->operType = oper;
|
||||
tm->colType = colType;
|
||||
|
||||
t->colName = (char*)taosMemoryCalloc(1, nColName + 1);
|
||||
memcpy(t->colName, colName, nColName);
|
||||
t->nColName = nColName;
|
||||
tm->colName = (char*)taosMemoryCalloc(1, nColName + 1);
|
||||
memcpy(tm->colName, colName, nColName);
|
||||
tm->nColName = nColName;
|
||||
|
||||
t->colVal = (char*)taosMemoryCalloc(1, nColVal + 1);
|
||||
memcpy(t->colVal, colVal, nColVal);
|
||||
t->nColVal = nColVal;
|
||||
return t;
|
||||
tm->colVal = (char*)taosMemoryCalloc(1, nColVal + 1);
|
||||
memcpy(tm->colVal, colVal, nColVal);
|
||||
tm->nColVal = nColVal;
|
||||
|
||||
return tm;
|
||||
}
|
||||
void indexTermDestroy(SIndexTerm* p) {
|
||||
taosMemoryFree(p->colName);
|
||||
|
|
|
@ -154,6 +154,7 @@ static SNode* logicConditionNodeCopy(const SLogicConditionNode* pSrc, SLogicCond
|
|||
}
|
||||
|
||||
static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) {
|
||||
COPY_ALL_SCALAR_FIELDS;
|
||||
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
||||
COPY_CHAR_ARRAY_FIELD(functionName);
|
||||
COPY_SCALAR_FIELD(funcId);
|
||||
|
@ -190,6 +191,7 @@ static SNode* nodeListNodeCopy(const SNodeListNode* pSrc, SNodeListNode* pDst) {
|
|||
static SNode* fillNodeCopy(const SFillNode* pSrc, SFillNode* pDst) {
|
||||
COPY_SCALAR_FIELD(mode);
|
||||
CLONE_NODE_FIELD(pValues);
|
||||
CLONE_NODE_FIELD(pWStartTs);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
|
@ -268,11 +270,18 @@ static SNode* logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* pD
|
|||
COPY_ALL_SCALAR_FIELDS;
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
CLONE_NODE_LIST_FIELD(pFuncs);
|
||||
CLONE_NODE_FIELD(pFill);
|
||||
CLONE_NODE_FIELD(pTspk);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicFillCopy(const SFillLogicNode* pSrc, SFillLogicNode* pDst) {
|
||||
COPY_ALL_SCALAR_FIELDS;
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
CLONE_NODE_FIELD(pWStartTs);
|
||||
CLONE_NODE_FIELD(pValues);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicSortCopy(const SSortLogicNode* pSrc, SSortLogicNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
CLONE_NODE_LIST_FIELD(pSortKeys);
|
||||
|
@ -369,6 +378,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
|||
return logicExchangeCopy((const SExchangeLogicNode*)pNode, (SExchangeLogicNode*)pDst);
|
||||
case QUERY_NODE_LOGIC_PLAN_WINDOW:
|
||||
return logicWindowCopy((const SWindowLogicNode*)pNode, (SWindowLogicNode*)pDst);
|
||||
case QUERY_NODE_LOGIC_PLAN_FILL:
|
||||
return logicFillCopy((const SFillLogicNode*)pNode, (SFillLogicNode*)pDst);
|
||||
case QUERY_NODE_LOGIC_PLAN_SORT:
|
||||
return logicSortCopy((const SSortLogicNode*)pNode, (SSortLogicNode*)pDst);
|
||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||
|
|
|
@ -192,6 +192,8 @@ const char* nodesNodeName(ENodeType type) {
|
|||
return "LogicExchange";
|
||||
case QUERY_NODE_LOGIC_PLAN_WINDOW:
|
||||
return "LogicWindow";
|
||||
case QUERY_NODE_LOGIC_PLAN_FILL:
|
||||
return "LogicFill";
|
||||
case QUERY_NODE_LOGIC_PLAN_SORT:
|
||||
return "LogicSort";
|
||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||
|
@ -222,6 +224,8 @@ const char* nodesNodeName(ENodeType type) {
|
|||
return "PhysiSort";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return "PhysiInterval";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
return "PhysiFill";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
return "PhysiSessionWindow";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
|
||||
|
@ -564,6 +568,58 @@ static int32_t jsonToLogicProjectNode(const SJson* pJson, void* pObj) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static const char* jkFillLogicPlanMode = "Mode";
|
||||
static const char* jkFillLogicPlanWStartTs = "WStartTs";
|
||||
static const char* jkFillLogicPlanValues = "Values";
|
||||
static const char* jkFillLogicPlanStartTime = "StartTime";
|
||||
static const char* jkFillLogicPlanEndTime = "EndTime";
|
||||
|
||||
static int32_t logicFillNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFillLogicNode* pNode = (const SFillLogicNode*)pObj;
|
||||
|
||||
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillLogicPlanMode, pNode->mode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkFillLogicPlanWStartTs, nodeToJson, pNode->pWStartTs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkFillLogicPlanValues, nodeToJson, pNode->pValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillLogicPlanStartTime, pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillLogicPlanEndTime, pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t jsonToLogicFillNode(const SJson* pJson, void* pObj) {
|
||||
SFillLogicNode* pNode = (SFillLogicNode*)pObj;
|
||||
|
||||
int32_t code = jsonToLogicPlanNode(pJson, pObj);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetNumberValue(pJson, jkFillLogicPlanMode, pNode->mode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkFillLogicPlanWStartTs, &pNode->pWStartTs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkFillLogicPlanValues, &pNode->pValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillLogicPlanStartTime, &pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillLogicPlanEndTime, &pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkSortLogicPlanSortKeys = "SortKeys";
|
||||
|
||||
static int32_t logicSortNodeToJson(const void* pObj, SJson* pJson) {
|
||||
|
@ -1382,7 +1438,6 @@ static const char* jkIntervalPhysiPlanOffset = "Offset";
|
|||
static const char* jkIntervalPhysiPlanSliding = "Sliding";
|
||||
static const char* jkIntervalPhysiPlanIntervalUnit = "intervalUnit";
|
||||
static const char* jkIntervalPhysiPlanSlidingUnit = "slidingUnit";
|
||||
static const char* jkIntervalPhysiPlanFill = "Fill";
|
||||
|
||||
static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SIntervalPhysiNode* pNode = (const SIntervalPhysiNode*)pObj;
|
||||
|
@ -1403,9 +1458,6 @@ static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanSlidingUnit, pNode->slidingUnit);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkIntervalPhysiPlanFill, nodeToJson, pNode->pFill);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1429,8 +1481,64 @@ static int32_t jsonToPhysiIntervalNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetTinyIntValue(pJson, jkIntervalPhysiPlanSlidingUnit, &pNode->slidingUnit);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkFillPhysiPlanMode = "Mode";
|
||||
static const char* jkFillPhysiPlanWStartTs = "WStartTs";
|
||||
static const char* jkFillPhysiPlanValues = "Values";
|
||||
static const char* jkFillPhysiPlanTargets = "Targets";
|
||||
static const char* jkFillPhysiPlanStartTime = "StartTime";
|
||||
static const char* jkFillPhysiPlanEndTime = "EndTime";
|
||||
|
||||
static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFillPhysiNode* pNode = (const SFillPhysiNode*)pObj;
|
||||
|
||||
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkIntervalPhysiPlanFill, (SNode**)&pNode->pFill);
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanMode, pNode->mode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkFillPhysiPlanWStartTs, nodeToJson, pNode->pWStartTs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkFillPhysiPlanValues, nodeToJson, pNode->pValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkFillPhysiPlanTargets, pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanStartTime, pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanEndTime, pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t jsonToPhysiFillNode(const SJson* pJson, void* pObj) {
|
||||
SFillPhysiNode* pNode = (SFillPhysiNode*)pObj;
|
||||
|
||||
int32_t code = jsonToPhysiWindowNode(pJson, pObj);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetNumberValue(pJson, jkFillPhysiPlanMode, pNode->mode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkFillPhysiPlanWStartTs, &pNode->pWStartTs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkFillPhysiPlanValues, &pNode->pValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkFillPhysiPlanTargets, &pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillPhysiPlanStartTime, &pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillPhysiPlanEndTime, &pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -2077,6 +2185,7 @@ static const char* jkFunctionName = "Name";
|
|||
static const char* jkFunctionId = "Id";
|
||||
static const char* jkFunctionType = "Type";
|
||||
static const char* jkFunctionParameter = "Parameters";
|
||||
static const char* jkFunctionUdfBufSize = "UdfBufSize";
|
||||
|
||||
static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFunctionNode* pNode = (const SFunctionNode*)pObj;
|
||||
|
@ -2094,6 +2203,9 @@ static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkFunctionParameter, pNode->pParameterList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFunctionUdfBufSize, pNode->udfBufSize);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2114,6 +2226,9 @@ static int32_t jsonToFunctionNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkFunctionParameter, &pNode->pParameterList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetIntValue(pJson, jkFunctionUdfBufSize, &pNode->udfBufSize);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2321,6 +2436,9 @@ static int32_t jsonToNodeListNode(const SJson* pJson, void* pObj) {
|
|||
|
||||
static const char* jkFillMode = "Mode";
|
||||
static const char* jkFillValues = "Values";
|
||||
static const char* jkFillWStartTs = "WStartTs";
|
||||
static const char* jkFillStartTime = "StartTime";
|
||||
static const char* jkFillEndTime = "EndTime";
|
||||
|
||||
static int32_t fillNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFillNode* pNode = (const SFillNode*)pObj;
|
||||
|
@ -2329,6 +2447,15 @@ static int32_t fillNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkFillValues, nodeToJson, pNode->pValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkFillWStartTs, nodeToJson, pNode->pWStartTs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillStartTime, pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillEndTime, pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2340,6 +2467,15 @@ static int32_t jsonToFillNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkFillValues, &pNode->pValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkFillWStartTs, &pNode->pWStartTs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillStartTime, &pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillEndTime, &pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2700,6 +2836,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
return logicProjectNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
|
||||
break;
|
||||
case QUERY_NODE_LOGIC_PLAN_FILL:
|
||||
return logicFillNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN_SORT:
|
||||
return logicSortNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||
|
@ -2728,6 +2866,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
return physiSortNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return physiIntervalNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
return physiFillNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
return physiSessionWindowNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
|
||||
|
@ -2788,6 +2928,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
|||
return jsonToLogicScanNode(pJson, pObj);
|
||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||
return jsonToLogicProjectNode(pJson, pObj);
|
||||
case QUERY_NODE_LOGIC_PLAN_FILL:
|
||||
return jsonToLogicFillNode(pJson, pObj);
|
||||
case QUERY_NODE_LOGIC_PLAN_SORT:
|
||||
return jsonToLogicSortNode(pJson, pObj);
|
||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||
|
@ -2814,6 +2956,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
|||
return jsonToPhysiSortNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return jsonToPhysiIntervalNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
return jsonToPhysiFillNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
return jsonToPhysiSessionWindowNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
|
||||
|
|
|
@ -132,9 +132,14 @@ static EDealRes dispatchExpr(SNode* pNode, ETraversalOrder order, FNodeWalker wa
|
|||
case QUERY_NODE_NODE_LIST:
|
||||
res = walkExprs(((SNodeListNode*)pNode)->pNodeList, order, walker, pContext);
|
||||
break;
|
||||
case QUERY_NODE_FILL:
|
||||
res = walkExpr(((SFillNode*)pNode)->pValues, order, walker, pContext);
|
||||
case QUERY_NODE_FILL: {
|
||||
SFillNode* pFill = (SFillNode*)pNode;
|
||||
res = walkExpr(pFill->pValues, order, walker, pContext);
|
||||
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
|
||||
res = walkExpr(pFill->pWStartTs, order, walker, pContext);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_RAW_EXPR:
|
||||
res = walkExpr(((SRawExprNode*)pNode)->pNode, order, walker, pContext);
|
||||
break;
|
||||
|
@ -272,9 +277,14 @@ static EDealRes rewriteExpr(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
|
|||
case QUERY_NODE_NODE_LIST:
|
||||
res = rewriteExprs(((SNodeListNode*)pNode)->pNodeList, order, rewriter, pContext);
|
||||
break;
|
||||
case QUERY_NODE_FILL:
|
||||
res = rewriteExpr(&(((SFillNode*)pNode)->pValues), order, rewriter, pContext);
|
||||
case QUERY_NODE_FILL: {
|
||||
SFillNode* pFill = (SFillNode*)pNode;
|
||||
res = rewriteExpr(&pFill->pValues, order, rewriter, pContext);
|
||||
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
|
||||
res = rewriteExpr(&(pFill->pWStartTs), order, rewriter, pContext);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_RAW_EXPR:
|
||||
res = rewriteExpr(&(((SRawExprNode*)pNode)->pNode), order, rewriter, pContext);
|
||||
break;
|
||||
|
@ -333,6 +343,9 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa
|
|||
case SQL_CLAUSE_PARTITION_BY:
|
||||
nodesWalkExpr(pSelect->pWindow, walker, pContext);
|
||||
case SQL_CLAUSE_WINDOW:
|
||||
if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
|
||||
nodesWalkExpr(((SIntervalWindowNode*)pSelect->pWindow)->pFill, walker, pContext);
|
||||
}
|
||||
nodesWalkExprs(pSelect->pGroupByList, walker, pContext);
|
||||
case SQL_CLAUSE_GROUP_BY:
|
||||
nodesWalkExpr(pSelect->pHaving, walker, pContext);
|
||||
|
@ -362,6 +375,9 @@ void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewrit
|
|||
case SQL_CLAUSE_PARTITION_BY:
|
||||
nodesRewriteExpr(&(pSelect->pWindow), rewriter, pContext);
|
||||
case SQL_CLAUSE_WINDOW:
|
||||
if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
|
||||
nodesRewriteExpr(&(((SIntervalWindowNode*)pSelect->pWindow)->pFill), rewriter, pContext);
|
||||
}
|
||||
nodesRewriteExprs(pSelect->pGroupByList, rewriter, pContext);
|
||||
case SQL_CLAUSE_GROUP_BY:
|
||||
nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext);
|
||||
|
@ -496,14 +512,9 @@ static EDealRes dispatchPhysiPlan(SNode* pNode, ETraversalOrder order, FNodeWalk
|
|||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: {
|
||||
SIntervalPhysiNode* pInterval = (SIntervalPhysiNode*)pNode;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
|
||||
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
|
||||
res = walkPhysiPlan((SNode*)pInterval->pFill, order, walker, pContext);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
|
||||
break;
|
||||
|
|
|
@ -213,6 +213,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SExchangeLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_WINDOW:
|
||||
return makeNode(type, sizeof(SWindowLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_FILL:
|
||||
return makeNode(type, sizeof(SFillLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_SORT:
|
||||
return makeNode(type, sizeof(SSortLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||
|
@ -243,6 +245,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_FILL:
|
||||
return makeNode(type, sizeof(SFillPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
return makeNode(type, sizeof(SSessionWinodwPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
|
||||
|
@ -373,9 +377,12 @@ void nodesDestroyNode(SNodeptr pNode) {
|
|||
case QUERY_NODE_NODE_LIST:
|
||||
nodesDestroyList(((SNodeListNode*)pNode)->pNodeList);
|
||||
break;
|
||||
case QUERY_NODE_FILL:
|
||||
nodesDestroyNode(((SFillNode*)pNode)->pValues);
|
||||
case QUERY_NODE_FILL: {
|
||||
SFillNode* pFill = (SFillNode*)pNode;
|
||||
nodesDestroyNode(pFill->pValues);
|
||||
nodesDestroyNode(pFill->pWStartTs);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_RAW_EXPR:
|
||||
nodesDestroyNode(((SRawExprNode*)pNode)->pNode);
|
||||
break;
|
||||
|
@ -554,7 +561,6 @@ void nodesDestroyNode(SNodeptr pNode) {
|
|||
SWindowLogicNode* pLogicNode = (SWindowLogicNode*)pNode;
|
||||
destroyLogicNode((SLogicNode*)pLogicNode);
|
||||
nodesDestroyList(pLogicNode->pFuncs);
|
||||
nodesDestroyNode(pLogicNode->pFill);
|
||||
nodesDestroyNode(pLogicNode->pTspk);
|
||||
break;
|
||||
}
|
||||
|
@ -630,12 +636,9 @@ void nodesDestroyNode(SNodeptr pNode) {
|
|||
nodesDestroyNode(pPhyNode->pSortKeys);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: {
|
||||
SIntervalPhysiNode* pPhyNode = (SIntervalPhysiNode*)pNode;
|
||||
destroyWinodwPhysiNode((SWinodwPhysiNode*)pPhyNode);
|
||||
nodesDestroyNode(pPhyNode->pFill);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
|
||||
break;
|
||||
|
@ -894,7 +897,7 @@ void* nodesGetValueFromNode(SValueNode* pNode) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int32_t nodesSetValueNodeValue(SValueNode* pNode, void *value) {
|
||||
int32_t nodesSetValueNodeValue(SValueNode* pNode, void* value) {
|
||||
switch (pNode->node.resType.type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
pNode->datum.b = *(bool*)value;
|
||||
|
@ -1192,7 +1195,7 @@ static EDealRes collectFuncs(SNode* pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs) {
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, FFuncClassifier classifier, SNodeList** pFuncs) {
|
||||
if (NULL == pSelect || NULL == pFuncs) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
@ -1203,7 +1206,7 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNod
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
*pFuncs = NULL;
|
||||
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_GROUP_BY, collectFuncs, &cxt);
|
||||
nodesWalkSelectStmt(pSelect, clause, collectFuncs, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyList(cxt.pFuncs);
|
||||
return cxt.errCode;
|
||||
|
|
|
@ -501,6 +501,12 @@ SNode* createFillNode(SAstCreateContext* pCxt, EFillMode mode, SNode* pValues) {
|
|||
CHECK_OUT_OF_MEM(fill);
|
||||
fill->mode = mode;
|
||||
fill->pValues = pValues;
|
||||
fill->pWStartTs = nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
if (NULL == fill->pWStartTs) {
|
||||
nodesDestroyNode(fill);
|
||||
CHECK_OUT_OF_MEM(fill->pWStartTs);
|
||||
}
|
||||
strcpy(((SFunctionNode*)fill->pWStartTs)->functionName, "_wstartts");
|
||||
return (SNode*)fill;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,193 +26,192 @@ typedef struct SKeyword {
|
|||
uint8_t len; // length
|
||||
} SKeyword;
|
||||
|
||||
// clang-format off
|
||||
// keywords in sql string
|
||||
static SKeyword keywordTable[] = {
|
||||
{"ACCOUNT", TK_ACCOUNT},
|
||||
{"ACCOUNTS", TK_ACCOUNTS},
|
||||
{"ADD", TK_ADD},
|
||||
{"AGGREGATE", TK_AGGREGATE},
|
||||
{"ALL", TK_ALL},
|
||||
{"ALTER", TK_ALTER},
|
||||
{"ANALYZE", TK_ANALYZE},
|
||||
{"AND", TK_AND},
|
||||
{"APPS", TK_APPS},
|
||||
{"AS", TK_AS},
|
||||
{"ASC", TK_ASC},
|
||||
{"AT_ONCE", TK_AT_ONCE},
|
||||
{"BETWEEN", TK_BETWEEN},
|
||||
{"BINARY", TK_BINARY},
|
||||
{"BIGINT", TK_BIGINT},
|
||||
// {"BLOCKS", TK_BLOCKS},
|
||||
{"BNODE", TK_BNODE},
|
||||
{"BNODES", TK_BNODES},
|
||||
{"BOOL", TK_BOOL},
|
||||
{"BUFFER", TK_BUFFER},
|
||||
{"BUFSIZE", TK_BUFSIZE},
|
||||
{"BY", TK_BY},
|
||||
{"CACHE", TK_CACHE},
|
||||
{"CACHELAST", TK_CACHELAST},
|
||||
{"CAST", TK_CAST},
|
||||
{"CLUSTER", TK_CLUSTER},
|
||||
{"COLUMN", TK_COLUMN},
|
||||
{"COMMENT", TK_COMMENT},
|
||||
{"COMP", TK_COMP},
|
||||
{"COMPACT", TK_COMPACT},
|
||||
{"CONNS", TK_CONNS},
|
||||
{"CONNECTION", TK_CONNECTION},
|
||||
{"CONNECTIONS", TK_CONNECTIONS},
|
||||
{"COUNT", TK_COUNT},
|
||||
{"CREATE", TK_CREATE},
|
||||
{"DATABASE", TK_DATABASE},
|
||||
{"DATABASES", TK_DATABASES},
|
||||
{"DAYS", TK_DAYS},
|
||||
{"DBS", TK_DBS},
|
||||
{"DELAY", TK_DELAY},
|
||||
{"DESC", TK_DESC},
|
||||
{"DESCRIBE", TK_DESCRIBE},
|
||||
{"DISTINCT", TK_DISTINCT},
|
||||
{"DNODE", TK_DNODE},
|
||||
{"DNODES", TK_DNODES},
|
||||
{"DOUBLE", TK_DOUBLE},
|
||||
{"DROP", TK_DROP},
|
||||
{"EXISTS", TK_EXISTS},
|
||||
{"EXPLAIN", TK_EXPLAIN},
|
||||
{"FILE_FACTOR", TK_FILE_FACTOR},
|
||||
{"FILL", TK_FILL},
|
||||
{"FIRST", TK_FIRST},
|
||||
{"FLOAT", TK_FLOAT},
|
||||
{"FROM", TK_FROM},
|
||||
{"FSYNC", TK_FSYNC},
|
||||
{"FUNCTION", TK_FUNCTION},
|
||||
{"FUNCTIONS", TK_FUNCTIONS},
|
||||
{"GRANTS", TK_GRANTS},
|
||||
{"GROUP", TK_GROUP},
|
||||
{"HAVING", TK_HAVING},
|
||||
{"IF", TK_IF},
|
||||
{"IMPORT", TK_IMPORT},
|
||||
{"IN", TK_IN},
|
||||
{"INDEX", TK_INDEX},
|
||||
{"INDEXES", TK_INDEXES},
|
||||
{"INNER", TK_INNER},
|
||||
{"INT", TK_INT},
|
||||
{"INSERT", TK_INSERT},
|
||||
{"INTEGER", TK_INTEGER},
|
||||
{"INTERVAL", TK_INTERVAL},
|
||||
{"INTO", TK_INTO},
|
||||
{"IS", TK_IS},
|
||||
{"JOIN", TK_JOIN},
|
||||
{"JSON", TK_JSON},
|
||||
{"KEEP", TK_KEEP},
|
||||
{"KILL", TK_KILL},
|
||||
{"LAST", TK_LAST},
|
||||
{"LAST_ROW", TK_LAST_ROW},
|
||||
{"LICENCE", TK_LICENCE},
|
||||
{"LIKE", TK_LIKE},
|
||||
{"LIMIT", TK_LIMIT},
|
||||
{"LINEAR", TK_LINEAR},
|
||||
{"LOCAL", TK_LOCAL},
|
||||
{"MATCH", TK_MATCH},
|
||||
{"MAXROWS", TK_MAXROWS},
|
||||
{"MINROWS", TK_MINROWS},
|
||||
{"MINUS", TK_MINUS},
|
||||
{"MNODE", TK_MNODE},
|
||||
{"MNODES", TK_MNODES},
|
||||
{"MODIFY", TK_MODIFY},
|
||||
{"MODULES", TK_MODULES},
|
||||
{"NCHAR", TK_NCHAR},
|
||||
{"NMATCH", TK_NMATCH},
|
||||
{"NONE", TK_NONE},
|
||||
{"NOT", TK_NOT},
|
||||
{"NOW", TK_NOW},
|
||||
{"NULL", TK_NULL},
|
||||
{"NULLS", TK_NULLS},
|
||||
{"OFFSET", TK_OFFSET},
|
||||
{"ON", TK_ON},
|
||||
{"OR", TK_OR},
|
||||
{"ORDER", TK_ORDER},
|
||||
{"OUTPUTTYPE", TK_OUTPUTTYPE},
|
||||
{"PARTITION", TK_PARTITION},
|
||||
{"PASS", TK_PASS},
|
||||
{"PAGES", TK_PAGES},
|
||||
{"PAGESIZE", TK_PAGESIZE},
|
||||
{"PORT", TK_PORT},
|
||||
{"PPS", TK_PPS},
|
||||
{"PRECISION", TK_PRECISION},
|
||||
{"PRIVILEGE", TK_PRIVILEGE},
|
||||
{"PREV", TK_PREV},
|
||||
{"QNODE", TK_QNODE},
|
||||
{"QNODES", TK_QNODES},
|
||||
{"QTIME", TK_QTIME},
|
||||
{"QUERIES", TK_QUERIES},
|
||||
{"QUERY", TK_QUERY},
|
||||
// {"QUORUM", TK_QUORUM},
|
||||
{"RATIO", TK_RATIO},
|
||||
{"REPLICA", TK_REPLICA},
|
||||
{"RESET", TK_RESET},
|
||||
{"RETENTIONS", TK_RETENTIONS},
|
||||
{"ROLLUP", TK_ROLLUP},
|
||||
{"SCHEMA", TK_SCHEMA},
|
||||
{"SCORES", TK_SCORES},
|
||||
{"SELECT", TK_SELECT},
|
||||
{"SESSION", TK_SESSION},
|
||||
{"SET", TK_SET},
|
||||
{"SHOW", TK_SHOW},
|
||||
{"ACCOUNT", TK_ACCOUNT},
|
||||
{"ACCOUNTS", TK_ACCOUNTS},
|
||||
{"ADD", TK_ADD},
|
||||
{"AGGREGATE", TK_AGGREGATE},
|
||||
{"ALL", TK_ALL},
|
||||
{"ALTER", TK_ALTER},
|
||||
{"ANALYZE", TK_ANALYZE},
|
||||
{"AND", TK_AND},
|
||||
{"APPS", TK_APPS},
|
||||
{"AS", TK_AS},
|
||||
{"ASC", TK_ASC},
|
||||
{"AT_ONCE", TK_AT_ONCE},
|
||||
{"BETWEEN", TK_BETWEEN},
|
||||
{"BINARY", TK_BINARY},
|
||||
{"BIGINT", TK_BIGINT},
|
||||
{"BNODE", TK_BNODE},
|
||||
{"BNODES", TK_BNODES},
|
||||
{"BOOL", TK_BOOL},
|
||||
{"BUFFER", TK_BUFFER},
|
||||
{"BUFSIZE", TK_BUFSIZE},
|
||||
{"BY", TK_BY},
|
||||
{"CACHE", TK_CACHE},
|
||||
{"CACHELAST", TK_CACHELAST},
|
||||
{"CAST", TK_CAST},
|
||||
{"CLUSTER", TK_CLUSTER},
|
||||
{"COLUMN", TK_COLUMN},
|
||||
{"COMMENT", TK_COMMENT},
|
||||
{"COMP", TK_COMP},
|
||||
{"COMPACT", TK_COMPACT},
|
||||
{"CONNS", TK_CONNS},
|
||||
{"CONNECTION", TK_CONNECTION},
|
||||
{"CONNECTIONS", TK_CONNECTIONS},
|
||||
{"COUNT", TK_COUNT},
|
||||
{"CREATE", TK_CREATE},
|
||||
{"DATABASE", TK_DATABASE},
|
||||
{"DATABASES", TK_DATABASES},
|
||||
{"DAYS", TK_DAYS},
|
||||
{"DBS", TK_DBS},
|
||||
{"DELAY", TK_DELAY},
|
||||
{"DESC", TK_DESC},
|
||||
{"DESCRIBE", TK_DESCRIBE},
|
||||
{"DISTINCT", TK_DISTINCT},
|
||||
{"DNODE", TK_DNODE},
|
||||
{"DNODES", TK_DNODES},
|
||||
{"DOUBLE", TK_DOUBLE},
|
||||
{"DROP", TK_DROP},
|
||||
{"EXISTS", TK_EXISTS},
|
||||
{"EXPLAIN", TK_EXPLAIN},
|
||||
{"FILE_FACTOR", TK_FILE_FACTOR},
|
||||
{"FILL", TK_FILL},
|
||||
{"FIRST", TK_FIRST},
|
||||
{"FLOAT", TK_FLOAT},
|
||||
{"FROM", TK_FROM},
|
||||
{"FSYNC", TK_FSYNC},
|
||||
{"FUNCTION", TK_FUNCTION},
|
||||
{"FUNCTIONS", TK_FUNCTIONS},
|
||||
{"GRANTS", TK_GRANTS},
|
||||
{"GROUP", TK_GROUP},
|
||||
{"HAVING", TK_HAVING},
|
||||
{"IF", TK_IF},
|
||||
{"IMPORT", TK_IMPORT},
|
||||
{"IN", TK_IN},
|
||||
{"INDEX", TK_INDEX},
|
||||
{"INDEXES", TK_INDEXES},
|
||||
{"INNER", TK_INNER},
|
||||
{"INT", TK_INT},
|
||||
{"INSERT", TK_INSERT},
|
||||
{"INTEGER", TK_INTEGER},
|
||||
{"INTERVAL", TK_INTERVAL},
|
||||
{"INTO", TK_INTO},
|
||||
{"IS", TK_IS},
|
||||
{"JOIN", TK_JOIN},
|
||||
{"JSON", TK_JSON},
|
||||
{"KEEP", TK_KEEP},
|
||||
{"KILL", TK_KILL},
|
||||
{"LAST", TK_LAST},
|
||||
{"LAST_ROW", TK_LAST_ROW},
|
||||
{"LICENCE", TK_LICENCE},
|
||||
{"LIKE", TK_LIKE},
|
||||
{"LIMIT", TK_LIMIT},
|
||||
{"LINEAR", TK_LINEAR},
|
||||
{"LOCAL", TK_LOCAL},
|
||||
{"MATCH", TK_MATCH},
|
||||
{"MAXROWS", TK_MAXROWS},
|
||||
{"MINROWS", TK_MINROWS},
|
||||
{"MINUS", TK_MINUS},
|
||||
{"MNODE", TK_MNODE},
|
||||
{"MNODES", TK_MNODES},
|
||||
{"MODIFY", TK_MODIFY},
|
||||
{"MODULES", TK_MODULES},
|
||||
{"NCHAR", TK_NCHAR},
|
||||
{"NEXT", TK_NEXT},
|
||||
{"NMATCH", TK_NMATCH},
|
||||
{"NONE", TK_NONE},
|
||||
{"NOT", TK_NOT},
|
||||
{"NOW", TK_NOW},
|
||||
{"NULL", TK_NULL},
|
||||
{"NULLS", TK_NULLS},
|
||||
{"OFFSET", TK_OFFSET},
|
||||
{"ON", TK_ON},
|
||||
{"OR", TK_OR},
|
||||
{"ORDER", TK_ORDER},
|
||||
{"OUTPUTTYPE", TK_OUTPUTTYPE},
|
||||
{"PARTITION", TK_PARTITION},
|
||||
{"PASS", TK_PASS},
|
||||
{"PAGES", TK_PAGES},
|
||||
{"PAGESIZE", TK_PAGESIZE},
|
||||
{"PORT", TK_PORT},
|
||||
{"PPS", TK_PPS},
|
||||
{"PRECISION", TK_PRECISION},
|
||||
{"PRIVILEGE", TK_PRIVILEGE},
|
||||
{"PREV", TK_PREV},
|
||||
{"QNODE", TK_QNODE},
|
||||
{"QNODES", TK_QNODES},
|
||||
{"QTIME", TK_QTIME},
|
||||
{"QUERIES", TK_QUERIES},
|
||||
{"QUERY", TK_QUERY},
|
||||
{"RATIO", TK_RATIO},
|
||||
{"REPLICA", TK_REPLICA},
|
||||
{"RESET", TK_RESET},
|
||||
{"RETENTIONS", TK_RETENTIONS},
|
||||
{"ROLLUP", TK_ROLLUP},
|
||||
{"SCHEMA", TK_SCHEMA},
|
||||
{"SCORES", TK_SCORES},
|
||||
{"SELECT", TK_SELECT},
|
||||
{"SESSION", TK_SESSION},
|
||||
{"SET", TK_SET},
|
||||
{"SHOW", TK_SHOW},
|
||||
{"SINGLE_STABLE", TK_SINGLE_STABLE},
|
||||
{"SLIDING", TK_SLIDING},
|
||||
{"SLIMIT", TK_SLIMIT},
|
||||
{"SMA", TK_SMA},
|
||||
{"SMALLINT", TK_SMALLINT},
|
||||
{"SNODE", TK_SNODE},
|
||||
{"SNODES", TK_SNODES},
|
||||
{"SOFFSET", TK_SOFFSET},
|
||||
{"STABLE", TK_STABLE},
|
||||
{"STABLES", TK_STABLES},
|
||||
{"STATE", TK_STATE},
|
||||
{"STATE_WINDOW", TK_STATE_WINDOW},
|
||||
{"STORAGE", TK_STORAGE},
|
||||
{"STREAM", TK_STREAM},
|
||||
{"STREAMS", TK_STREAMS},
|
||||
// {"STREAM_MODE", TK_STREAM_MODE},
|
||||
{"STRICT", TK_STRICT},
|
||||
{"SYNCDB", TK_SYNCDB},
|
||||
{"TABLE", TK_TABLE},
|
||||
{"TABLES", TK_TABLES},
|
||||
{"TAG", TK_TAG},
|
||||
{"TAGS", TK_TAGS},
|
||||
{"TBNAME", TK_TBNAME},
|
||||
{"TIMESTAMP", TK_TIMESTAMP},
|
||||
{"TIMEZONE", TK_TIMEZONE},
|
||||
{"TINYINT", TK_TINYINT},
|
||||
{"TODAY", TK_TODAY},
|
||||
{"TOPIC", TK_TOPIC},
|
||||
{"TOPICS", TK_TOPICS},
|
||||
{"TRIGGER", TK_TRIGGER},
|
||||
{"TSERIES", TK_TSERIES},
|
||||
{"TTL", TK_TTL},
|
||||
{"UNION", TK_UNION},
|
||||
{"UNSIGNED", TK_UNSIGNED},
|
||||
{"USE", TK_USE},
|
||||
{"USER", TK_USER},
|
||||
{"USERS", TK_USERS},
|
||||
{"USING", TK_USING},
|
||||
{"VALUE", TK_VALUE},
|
||||
{"VALUES", TK_VALUES},
|
||||
{"VARCHAR", TK_VARCHAR},
|
||||
{"VARIABLES", TK_VARIABLES},
|
||||
{"VERBOSE", TK_VERBOSE},
|
||||
{"VGROUPS", TK_VGROUPS},
|
||||
{"VNODES", TK_VNODES},
|
||||
{"WAL", TK_WAL},
|
||||
{"WATERMARK", TK_WATERMARK},
|
||||
{"WHERE", TK_WHERE},
|
||||
{"WINDOW_CLOSE", TK_WINDOW_CLOSE},
|
||||
{"WITH", TK_WITH},
|
||||
{"_QENDTS", TK_QENDTS},
|
||||
{"_QSTARTTS", TK_QSTARTTS},
|
||||
{"_ROWTS", TK_ROWTS},
|
||||
{"_WDURATION", TK_WDURATION},
|
||||
{"_WENDTS", TK_WENDTS},
|
||||
{"_WSTARTTS", TK_WSTARTTS},
|
||||
{"SLIDING", TK_SLIDING},
|
||||
{"SLIMIT", TK_SLIMIT},
|
||||
{"SMA", TK_SMA},
|
||||
{"SMALLINT", TK_SMALLINT},
|
||||
{"SNODE", TK_SNODE},
|
||||
{"SNODES", TK_SNODES},
|
||||
{"SOFFSET", TK_SOFFSET},
|
||||
{"STABLE", TK_STABLE},
|
||||
{"STABLES", TK_STABLES},
|
||||
{"STATE", TK_STATE},
|
||||
{"STATE_WINDOW", TK_STATE_WINDOW},
|
||||
{"STORAGE", TK_STORAGE},
|
||||
{"STREAM", TK_STREAM},
|
||||
{"STREAMS", TK_STREAMS},
|
||||
{"STRICT", TK_STRICT},
|
||||
{"SYNCDB", TK_SYNCDB},
|
||||
{"TABLE", TK_TABLE},
|
||||
{"TABLES", TK_TABLES},
|
||||
{"TAG", TK_TAG},
|
||||
{"TAGS", TK_TAGS},
|
||||
{"TBNAME", TK_TBNAME},
|
||||
{"TIMESTAMP", TK_TIMESTAMP},
|
||||
{"TIMEZONE", TK_TIMEZONE},
|
||||
{"TINYINT", TK_TINYINT},
|
||||
{"TODAY", TK_TODAY},
|
||||
{"TOPIC", TK_TOPIC},
|
||||
{"TOPICS", TK_TOPICS},
|
||||
{"TRIGGER", TK_TRIGGER},
|
||||
{"TSERIES", TK_TSERIES},
|
||||
{"TTL", TK_TTL},
|
||||
{"UNION", TK_UNION},
|
||||
{"UNSIGNED", TK_UNSIGNED},
|
||||
{"USE", TK_USE},
|
||||
{"USER", TK_USER},
|
||||
{"USERS", TK_USERS},
|
||||
{"USING", TK_USING},
|
||||
{"VALUE", TK_VALUE},
|
||||
{"VALUES", TK_VALUES},
|
||||
{"VARCHAR", TK_VARCHAR},
|
||||
{"VARIABLES", TK_VARIABLES},
|
||||
{"VERBOSE", TK_VERBOSE},
|
||||
{"VGROUPS", TK_VGROUPS},
|
||||
{"VNODES", TK_VNODES},
|
||||
{"WAL", TK_WAL},
|
||||
{"WATERMARK", TK_WATERMARK},
|
||||
{"WHERE", TK_WHERE},
|
||||
{"WINDOW_CLOSE", TK_WINDOW_CLOSE},
|
||||
{"WITH", TK_WITH},
|
||||
{"_QENDTS", TK_QENDTS},
|
||||
{"_QSTARTTS", TK_QSTARTTS},
|
||||
{"_ROWTS", TK_ROWTS},
|
||||
{"_WDURATION", TK_WDURATION},
|
||||
{"_WENDTS", TK_WENDTS},
|
||||
{"_WSTARTTS", TK_WSTARTTS},
|
||||
// {"ID", TK_ID},
|
||||
// {"STRING", TK_STRING},
|
||||
// {"EQ", TK_EQ},
|
||||
|
@ -279,6 +278,7 @@ static SKeyword keywordTable[] = {
|
|||
// {"PARTITIONS", TK_PARTITIONS},
|
||||
// {"MODE", TK_MODE},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static const char isIdChar[] = {
|
||||
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "catalog.h"
|
||||
#include "cmdnodes.h"
|
||||
#include "filter.h"
|
||||
#include "functionMgt.h"
|
||||
#include "parUtil.h"
|
||||
#include "scalar.h"
|
||||
|
@ -255,6 +256,26 @@ static void destroyTranslateContext(STranslateContext* pCxt) {
|
|||
taosHashCleanup(pCxt->pTables);
|
||||
}
|
||||
|
||||
static bool isAliasColumn(const SNode* pNode) {
|
||||
return (QUERY_NODE_COLUMN == nodeType(pNode) && ('\0' == ((SColumnNode*)pNode)->tableAlias[0]));
|
||||
}
|
||||
|
||||
static bool isAggFunc(const SNode* pNode) {
|
||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId));
|
||||
}
|
||||
|
||||
static bool isSelectFunc(const SNode* pNode) {
|
||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsSelectFunc(((SFunctionNode*)pNode)->funcId));
|
||||
}
|
||||
|
||||
static bool isTimelineFunc(const SNode* pNode) {
|
||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId));
|
||||
}
|
||||
|
||||
static bool isDistinctOrderBy(STranslateContext* pCxt) {
|
||||
return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct);
|
||||
}
|
||||
|
||||
static bool belongTable(const char* currentDb, const SColumnNode* pCol, const STableNode* pTable) {
|
||||
int cmp = 0;
|
||||
if ('\0' != pCol->dbName[0]) {
|
||||
|
@ -468,19 +489,19 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
pVal->datum.b = (0 == strcasecmp(pVal->literal, "true"));
|
||||
*(bool*)&pVal->typeData = pVal->datum.b;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:{
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
|
||||
*(int8_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT:{
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
|
||||
*(int16_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT:{
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
|
||||
*(int32_t*)&pVal->typeData = pVal->datum.i;
|
||||
|
@ -489,43 +510,43 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UTINYINT:{
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
|
||||
*(uint8_t*)&pVal->typeData = pVal->datum.u;
|
||||
*(uint8_t*)&pVal->typeData = pVal->datum.u;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_USMALLINT:{
|
||||
case TSDB_DATA_TYPE_USMALLINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
|
||||
*(uint16_t*)&pVal->typeData = pVal->datum.u;
|
||||
*(uint16_t*)&pVal->typeData = pVal->datum.u;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UINT:{
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
|
||||
*(uint32_t*)&pVal->typeData = pVal->datum.u;
|
||||
*(uint32_t*)&pVal->typeData = pVal->datum.u;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
|
||||
*(uint64_t*)&pVal->typeData = pVal->datum.u;
|
||||
*(uint64_t*)&pVal->typeData = pVal->datum.u;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:{
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.d = strtold(pVal->literal, &endPtr);
|
||||
*(float*)&pVal->typeData = pVal->datum.d;
|
||||
*(float*)&pVal->typeData = pVal->datum.d;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.d = strtold(pVal->literal, &endPtr);
|
||||
*(double*)&pVal->typeData = pVal->datum.d;
|
||||
*(double*)&pVal->typeData = pVal->datum.d;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
|
@ -543,7 +564,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
TSDB_CODE_SUCCESS) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||
}
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
|
@ -616,13 +637,45 @@ static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
|
|||
}
|
||||
|
||||
static EDealRes haveAggFunction(SNode* pNode, void* pContext) {
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId)) {
|
||||
if (isAggFunc(pNode)) {
|
||||
*((bool*)pContext) = true;
|
||||
return DEAL_RES_END;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t findTable(STranslateContext* pCxt, const char* pTableAlias, STableNode** pOutput) {
|
||||
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
|
||||
size_t nums = taosArrayGetSize(pTables);
|
||||
for (size_t i = 0; i < nums; ++i) {
|
||||
STableNode* pTable = taosArrayGetP(pTables, i);
|
||||
if (NULL == pTableAlias || 0 == strcmp(pTable->tableAlias, pTableAlias)) {
|
||||
*pOutput = pTable;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TABLE_NOT_EXIST, pTableAlias);
|
||||
}
|
||||
|
||||
static bool isCountStar(SFunctionNode* pFunc) {
|
||||
if (FUNCTION_TYPE_COUNT != pFunc->funcType || 1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return false;
|
||||
}
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
return (QUERY_NODE_COLUMN == nodeType(pPara) && 0 == strcmp(((SColumnNode*)pPara)->colName, "*"));
|
||||
}
|
||||
|
||||
// count(*) is rewritten as count(ts) for scannning optimization
|
||||
static int32_t rewriteCountStar(STranslateContext* pCxt, SFunctionNode* pCount) {
|
||||
SColumnNode* pCol = nodesListGetNode(pCount->pParameterList, 0);
|
||||
STableNode* pTable = NULL;
|
||||
int32_t code = findTable(pCxt, ('\0' == pCol->tableAlias[0] ? NULL : pCol->tableAlias), &pTable);
|
||||
if (TSDB_CODE_SUCCESS == code && QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, false, pCol);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||
SFmGetFuncInfoParam param = {.pCtg = pCxt->pParseCxt->pCatalog,
|
||||
.pRpc = pCxt->pParseCxt->pTransporter,
|
||||
|
@ -630,10 +683,7 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
|||
.pErrBuf = pCxt->msgBuf.buf,
|
||||
.errBufLen = pCxt->msgBuf.len};
|
||||
pCxt->errCode = fmGetFuncInfo(¶m, pFunc);
|
||||
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
if (fmIsAggFunc(pFunc->funcId)) {
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode && fmIsAggFunc(pFunc->funcId)) {
|
||||
if (beforeHaving(pCxt->currClause)) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
|
||||
}
|
||||
|
@ -642,11 +692,14 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
|||
if (haveAggFunc) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_AGG_FUNC_NESTING);
|
||||
}
|
||||
|
||||
pCxt->pCurrStmt->hasAggFuncs = true;
|
||||
pCxt->pCurrStmt->isTimeOrderQuery = false;
|
||||
if (isCountStar(pFunc)) {
|
||||
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
|
||||
}
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
static EDealRes translateExprSubquery(STranslateContext* pCxt, SNode* pNode) {
|
||||
|
@ -690,12 +743,6 @@ static int32_t translateExprList(STranslateContext* pCxt, SNodeList* pList) {
|
|||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
static bool isAliasColumn(SColumnNode* pCol) { return ('\0' == pCol->tableAlias[0]); }
|
||||
|
||||
static bool isDistinctOrderBy(STranslateContext* pCxt) {
|
||||
return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct);
|
||||
}
|
||||
|
||||
static SNodeList* getGroupByList(STranslateContext* pCxt) {
|
||||
if (isDistinctOrderBy(pCxt)) {
|
||||
return pCxt->pCurrStmt->pProjectionList;
|
||||
|
@ -717,31 +764,71 @@ static int32_t getGroupByErrorCode(STranslateContext* pCxt) {
|
|||
return TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION;
|
||||
}
|
||||
|
||||
static EDealRes doCheckExprForGroupBy(SNode* pNode, void* pContext) {
|
||||
STranslateContext* pCxt = (STranslateContext*)pContext;
|
||||
if (!nodesIsExprNode(pNode) || (QUERY_NODE_COLUMN == nodeType(pNode) && isAliasColumn((SColumnNode*)pNode))) {
|
||||
typedef struct SCheckExprForGroupByCxt {
|
||||
STranslateContext* pTranslateCxt;
|
||||
int32_t selectFuncNum;
|
||||
bool hasSelectValFunc;
|
||||
} SCheckExprForGroupByCxt;
|
||||
|
||||
static EDealRes rewriteColToSelectValFunc(STranslateContext* pCxt, bool* pHasSelectValFunc, SNode** pNode) {
|
||||
SFunctionNode* pFunc = nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
if (NULL == pFunc) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
strcpy(pFunc->functionName, "_select_value");
|
||||
pCxt->errCode = nodesListMakeAppend(&pFunc->pParameterList, *pNode);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
translateFunction(pCxt, pFunc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
*pNode = (SNode*)pFunc;
|
||||
if (NULL != pHasSelectValFunc) {
|
||||
*pHasSelectValFunc = true;
|
||||
}
|
||||
} else {
|
||||
nodesDestroyNode(pFunc);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
|
||||
SCheckExprForGroupByCxt* pCxt = (SCheckExprForGroupByCxt*)pContext;
|
||||
if (!nodesIsExprNode(*pNode) || isAliasColumn(*pNode)) {
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId) &&
|
||||
!isDistinctOrderBy(pCxt)) {
|
||||
pCxt->selectFuncNum += isSelectFunc(*pNode) ? 1 : 0;
|
||||
if (pCxt->selectFuncNum > 1 && pCxt->hasSelectValFunc) {
|
||||
return generateDealNodeErrMsg(pCxt->pTranslateCxt, getGroupByErrorCode(pCxt->pTranslateCxt));
|
||||
}
|
||||
if (isAggFunc(*pNode) && !isDistinctOrderBy(pCxt->pTranslateCxt)) {
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
SNode* pGroupNode;
|
||||
FOREACH(pGroupNode, getGroupByList(pCxt)) {
|
||||
if (nodesEqualNode(getGroupByNode(pGroupNode), pNode)) {
|
||||
FOREACH(pGroupNode, getGroupByList(pCxt->pTranslateCxt)) {
|
||||
if (nodesEqualNode(getGroupByNode(pGroupNode), *pNode)) {
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
}
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode) ||
|
||||
(QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId) &&
|
||||
isDistinctOrderBy(pCxt))) {
|
||||
return generateDealNodeErrMsg(pCxt, getGroupByErrorCode(pCxt));
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||
if (pCxt->selectFuncNum > 1) {
|
||||
return generateDealNodeErrMsg(pCxt->pTranslateCxt, getGroupByErrorCode(pCxt->pTranslateCxt));
|
||||
} else {
|
||||
return rewriteColToSelectValFunc(pCxt->pTranslateCxt, &pCxt->hasSelectValFunc, pNode);
|
||||
}
|
||||
}
|
||||
if (isAggFunc(*pNode) && isDistinctOrderBy(pCxt->pTranslateCxt)) {
|
||||
return generateDealNodeErrMsg(pCxt->pTranslateCxt, getGroupByErrorCode(pCxt->pTranslateCxt));
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t checkExprForGroupBy(STranslateContext* pCxt, SNode* pNode) {
|
||||
nodesWalkExpr(pNode, doCheckExprForGroupBy, pCxt);
|
||||
static int32_t checkExprForGroupBy(STranslateContext* pCxt, SNode** pNode) {
|
||||
SCheckExprForGroupByCxt cxt = {.pTranslateCxt = pCxt, .selectFuncNum = 0, .hasSelectValFunc = false};
|
||||
nodesRewriteExpr(pNode, doCheckExprForGroupBy, &cxt);
|
||||
if (cxt.selectFuncNum != 1 && cxt.hasSelectValFunc) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, getGroupByErrorCode(pCxt));
|
||||
}
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
|
@ -749,7 +836,29 @@ static int32_t checkExprListForGroupBy(STranslateContext* pCxt, SNodeList* pList
|
|||
if (NULL == getGroupByList(pCxt)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
nodesWalkExprs(pList, doCheckExprForGroupBy, pCxt);
|
||||
SCheckExprForGroupByCxt cxt = {.pTranslateCxt = pCxt, .selectFuncNum = 0, .hasSelectValFunc = false};
|
||||
nodesRewriteExprs(pList, doCheckExprForGroupBy, &cxt);
|
||||
if (cxt.selectFuncNum != 1 && cxt.hasSelectValFunc) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, getGroupByErrorCode(pCxt));
|
||||
}
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
static EDealRes rewriteColsToSelectValFuncImpl(SNode** pNode, void* pContext) {
|
||||
if (isAggFunc(*pNode)) {
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||
return rewriteColToSelectValFunc((STranslateContext*)pContext, NULL, pNode);
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t rewriteColsToSelectValFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
nodesRewriteExprs(pSelect->pProjectionList, rewriteColsToSelectValFuncImpl, pCxt);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode && !pSelect->isDistinct) {
|
||||
nodesRewriteExprs(pSelect->pOrderByList, rewriteColsToSelectValFuncImpl, pCxt);
|
||||
}
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
|
@ -757,11 +866,13 @@ typedef struct CheckAggColCoexistCxt {
|
|||
STranslateContext* pTranslateCxt;
|
||||
bool existAggFunc;
|
||||
bool existCol;
|
||||
int32_t selectFuncNum;
|
||||
} CheckAggColCoexistCxt;
|
||||
|
||||
static EDealRes doCheckAggColCoexist(SNode* pNode, void* pContext) {
|
||||
CheckAggColCoexistCxt* pCxt = (CheckAggColCoexistCxt*)pContext;
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId)) {
|
||||
pCxt->selectFuncNum += isSelectFunc(pNode) ? 1 : 0;
|
||||
if (isAggFunc(pNode)) {
|
||||
pCxt->existAggFunc = true;
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
|
@ -780,7 +891,9 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
|||
if (!pSelect->isDistinct) {
|
||||
nodesWalkExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
||||
}
|
||||
if ((cxt.existAggFunc || NULL != pSelect->pWindow) && cxt.existCol) {
|
||||
if (1 == cxt.selectFuncNum) {
|
||||
return rewriteColsToSelectValFunc(pCxt, pSelect);
|
||||
} else if ((cxt.selectFuncNum > 1 || cxt.existAggFunc || NULL != pSelect->pWindow) && cxt.existCol) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -989,19 +1102,6 @@ static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) {
|
|||
return (SNode*)pFunc;
|
||||
}
|
||||
|
||||
static int32_t findTable(STranslateContext* pCxt, const char* pTableAlias, STableNode** pOutput) {
|
||||
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
|
||||
size_t nums = taosArrayGetSize(pTables);
|
||||
for (size_t i = 0; i < nums; ++i) {
|
||||
STableNode* pTable = taosArrayGetP(pTables, i);
|
||||
if (NULL == pTableAlias || 0 == strcmp(pTable->tableAlias, pTableAlias)) {
|
||||
*pOutput = pTable;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TABLE_NOT_EXIST, pTableAlias);
|
||||
}
|
||||
|
||||
static int32_t createTableAllCols(STranslateContext* pCxt, SColumnNode* pCol, SNodeList** pOutput) {
|
||||
STableNode* pTable = NULL;
|
||||
int32_t code = findTable(pCxt, pCol->tableAlias, &pTable);
|
||||
|
@ -1227,7 +1327,7 @@ static int32_t translateHaving(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
pCxt->currClause = SQL_CLAUSE_HAVING;
|
||||
int32_t code = translateExpr(pCxt, pSelect->pHaving);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkExprForGroupBy(pCxt, pSelect->pHaving);
|
||||
code = checkExprForGroupBy(pCxt, &pSelect->pHaving);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -1244,6 +1344,113 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static EDealRes isPrimaryKeyCondImpl(SNode* pNode, void* pContext) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
*((bool*)pContext) = ((PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pNode)->colId) ? true : false);
|
||||
return *((bool*)pContext) ? DEAL_RES_CONTINUE : DEAL_RES_END;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static bool isPrimaryKeyCond(SNode* pNode) {
|
||||
bool isPrimaryKeyCond = false;
|
||||
nodesWalkExpr(pNode, isPrimaryKeyCondImpl, &isPrimaryKeyCond);
|
||||
return isPrimaryKeyCond;
|
||||
}
|
||||
|
||||
static int32_t getTimeRangeFromLogicCond(STranslateContext* pCxt, SLogicConditionNode* pLogicCond,
|
||||
STimeWindow* pTimeRange) {
|
||||
SNodeList* pPrimaryKeyConds = NULL;
|
||||
SNode* pCond = NULL;
|
||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||
if (isPrimaryKeyCond(pCond)) {
|
||||
if (TSDB_CODE_SUCCESS != nodesListMakeAppend(&pPrimaryKeyConds, pCond)) {
|
||||
nodesClearList(pPrimaryKeyConds);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == pPrimaryKeyConds) {
|
||||
*pTimeRange = TSWINDOW_INITIALIZER;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SLogicConditionNode* pPrimaryKeyLogicCond = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||
if (NULL == pPrimaryKeyLogicCond) {
|
||||
nodesClearList(pPrimaryKeyConds);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pPrimaryKeyLogicCond->condType = LOGIC_COND_TYPE_AND;
|
||||
pPrimaryKeyLogicCond->pParameterList = pPrimaryKeyConds;
|
||||
bool isStrict = false;
|
||||
int32_t code = filterGetTimeRange((SNode*)pPrimaryKeyLogicCond, pTimeRange, &isStrict);
|
||||
nodesClearList(pPrimaryKeyConds);
|
||||
pPrimaryKeyLogicCond->pParameterList = NULL;
|
||||
nodesDestroyNode(pPrimaryKeyLogicCond);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t getTimeRange(STranslateContext* pCxt, SNode* pWhere, STimeWindow* pTimeRange) {
|
||||
if (NULL == pWhere) {
|
||||
*pTimeRange = TSWINDOW_INITIALIZER;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pWhere) &&
|
||||
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)pWhere)->condType) {
|
||||
return getTimeRangeFromLogicCond(pCxt, (SLogicConditionNode*)pWhere, pTimeRange);
|
||||
}
|
||||
|
||||
if (isPrimaryKeyCond(pWhere)) {
|
||||
bool isStrict = false;
|
||||
return filterGetTimeRange(pWhere, pTimeRange, &isStrict);
|
||||
} else {
|
||||
*pTimeRange = TSWINDOW_INITIALIZER;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkFill(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
|
||||
SFillNode* pFill = (SFillNode*)pInterval->pFill;
|
||||
if (TSWINDOW_IS_EQUAL(pFill->timeRange, TSWINDOW_INITIALIZER) ||
|
||||
TSWINDOW_IS_EQUAL(pFill->timeRange, TSWINDOW_DESC_INITIALIZER)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
|
||||
}
|
||||
|
||||
int64_t timeRange = TABS(pFill->timeRange.skey - pFill->timeRange.ekey);
|
||||
int64_t intervalRange = 0;
|
||||
SValueNode* pInter = (SValueNode*)pInterval->pInterval;
|
||||
if (TIME_IS_VAR_DURATION(pInter->unit)) {
|
||||
int64_t f = 1;
|
||||
if (pInter->unit == 'n') {
|
||||
f = 30L * MILLISECOND_PER_DAY;
|
||||
} else if (pInter->unit == 'y') {
|
||||
f = 365L * MILLISECOND_PER_DAY;
|
||||
}
|
||||
intervalRange = pInter->datum.i * f;
|
||||
} else {
|
||||
intervalRange = pInter->datum.i;
|
||||
}
|
||||
if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateFill(STranslateContext* pCxt, SNode* pWhere, SIntervalWindowNode* pInterval) {
|
||||
if (NULL == pInterval->pFill) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = getTimeRange(pCxt, pWhere, &(((SFillNode*)pInterval->pFill)->timeRange));
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkFill(pCxt, pInterval);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char unit) {
|
||||
int64_t days = convertTimeFromPrecisionToUnit(val, fromPrecision, 'd');
|
||||
switch (unit) {
|
||||
|
@ -1266,7 +1473,7 @@ static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char uni
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
|
||||
static int32_t checkIntervalWindow(STranslateContext* pCxt, SNode* pWhere, SIntervalWindowNode* pInterval) {
|
||||
uint8_t precision = ((SColumnNode*)pInterval->pCol)->node.resType.precision;
|
||||
|
||||
SValueNode* pInter = (SValueNode*)pInterval->pInterval;
|
||||
|
@ -1308,7 +1515,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
|
|||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return translateFill(pCxt, pWhere, pInterval);
|
||||
}
|
||||
|
||||
static EDealRes checkStateExpr(SNode* pNode, void* pContext) {
|
||||
|
@ -1345,28 +1552,28 @@ static int32_t checkSessionWindow(STranslateContext* pCxt, SSessionWindowNode* p
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkWindow(STranslateContext* pCxt, SNode* pWindow) {
|
||||
switch (nodeType(pWindow)) {
|
||||
static int32_t checkWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
switch (nodeType(pSelect->pWindow)) {
|
||||
case QUERY_NODE_STATE_WINDOW:
|
||||
return checkStateWindow(pCxt, (SStateWindowNode*)pWindow);
|
||||
return checkStateWindow(pCxt, (SStateWindowNode*)pSelect->pWindow);
|
||||
case QUERY_NODE_SESSION_WINDOW:
|
||||
return checkSessionWindow(pCxt, (SSessionWindowNode*)pWindow);
|
||||
return checkSessionWindow(pCxt, (SSessionWindowNode*)pSelect->pWindow);
|
||||
case QUERY_NODE_INTERVAL_WINDOW:
|
||||
return checkIntervalWindow(pCxt, (SIntervalWindowNode*)pWindow);
|
||||
return checkIntervalWindow(pCxt, pSelect->pWhere, (SIntervalWindowNode*)pSelect->pWindow);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateWindow(STranslateContext* pCxt, SNode* pWindow) {
|
||||
if (NULL == pWindow) {
|
||||
static int32_t translateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL == pSelect->pWindow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
pCxt->currClause = SQL_CLAUSE_WINDOW;
|
||||
int32_t code = translateExpr(pCxt, pWindow);
|
||||
int32_t code = translateExpr(pCxt, pSelect->pWindow);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkWindow(pCxt, pWindow);
|
||||
code = checkWindow(pCxt, pSelect);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -1403,25 +1610,6 @@ static int32_t checkLimit(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool isCountStar(SFunctionNode* pFunc) {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return false;
|
||||
}
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
return (QUERY_NODE_COLUMN == nodeType(pPara) && 0 == strcmp(((SColumnNode*)pPara)->colName, "*"));
|
||||
}
|
||||
|
||||
// count(*) is rewritten as count(ts) for scannning optimization
|
||||
static int32_t rewriteCountStar(STranslateContext* pCxt, SFunctionNode* pCount) {
|
||||
SColumnNode* pCol = nodesListGetNode(pCount->pParameterList, 0);
|
||||
STableNode* pTable = NULL;
|
||||
int32_t code = findTable(pCxt, ('\0' == pCol->tableAlias[0] ? NULL : pCol->tableAlias), &pTable);
|
||||
if (TSDB_CODE_SUCCESS == code && QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, false, pCol);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t createPrimaryKeyColByTable(STranslateContext* pCxt, STableNode* pTable, SNode** pPrimaryKey) {
|
||||
SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
if (NULL == pCol) {
|
||||
|
@ -1445,33 +1633,22 @@ static int32_t createPrimaryKeyCol(STranslateContext* pCxt, SNode** pPrimaryKey)
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t rewriteTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||
SNode* pPrimaryKey = NULL;
|
||||
int32_t code = createPrimaryKeyCol(pCxt, &pPrimaryKey);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListMakeStrictAppend(&pFunc->pParameterList, pPrimaryKey);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
EDealRes rewriteFuncForSelectImpl(SNode* pNode, void* pContext) {
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
||||
STranslateContext* pCxt = pContext;
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
if (isCountStar(pFunc)) {
|
||||
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
|
||||
} else if (fmIsTimelineFunc(pFunc->funcId)) {
|
||||
pCxt->errCode = rewriteTimelineFunc(pCxt, pFunc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
|
||||
return DEAL_RES_ERROR;
|
||||
static EDealRes rewriteTimelineFuncImpl(SNode* pNode, void* pContext) {
|
||||
STranslateContext* pCxt = pContext;
|
||||
if (isTimelineFunc(pNode)) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
SNode* pPrimaryKey = NULL;
|
||||
pCxt->errCode = createPrimaryKeyCol(pCxt, &pPrimaryKey);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pCxt->errCode = nodesListMakeStrictAppend(&pFunc->pParameterList, pPrimaryKey);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t rewriteFuncForSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, rewriteFuncForSelectImpl, pCxt);
|
||||
static int32_t rewriteTimelineFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, rewriteTimelineFuncImpl, pCxt);
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
|
@ -1485,7 +1662,7 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
code = translatePartitionBy(pCxt, pSelect->pPartitionByList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateWindow(pCxt, pSelect->pWindow);
|
||||
code = translateWindow(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateGroupBy(pCxt, pSelect);
|
||||
|
@ -1506,7 +1683,7 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
code = checkLimit(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = rewriteFuncForSelect(pCxt, pSelect);
|
||||
code = rewriteTimelineFunc(pCxt, pSelect);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -1770,9 +1947,6 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete
|
|||
if (DEAL_RES_ERROR == translateValue(pCxt, pVal)) {
|
||||
return pCxt->errCode;
|
||||
}
|
||||
if (!TIME_IS_VAR_DURATION(pVal->unit)) {
|
||||
pVal->datum.i = convertTimeFromPrecisionToUnit(pVal->datum.i, pVal->node.resType.precision, pVal->unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,6 +128,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
|||
return "Invalid topic query";
|
||||
case TSDB_CODE_PAR_INVALID_DROP_STABLE:
|
||||
return "Cannot drop super table in batch";
|
||||
case TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE:
|
||||
return "start(end) time of query range required or time range too large";
|
||||
case TSDB_CODE_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
default:
|
||||
|
@ -140,7 +142,6 @@ int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...) {
|
|||
va_start(vArgList, errCode);
|
||||
vsnprintf(pBuf->buf, pBuf->len, getSyntaxErrFormat(errCode), vArgList);
|
||||
va_end(vArgList);
|
||||
terrno = errCode;
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,6 @@ class MockCatalogServiceImpl {
|
|||
const char* tname = tNameGetTableName(pTableName);
|
||||
int32_t code = copyTableSchemaMeta(db, tname, &table);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
std::cout << "db : " << db << ", table :" << tname << std::endl;
|
||||
return code;
|
||||
}
|
||||
*pTableMeta = table.release();
|
||||
|
|
|
@ -24,170 +24,211 @@ class ParserSelectTest : public ParserTestBase {};
|
|||
TEST_F(ParserSelectTest, basic) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select * from t1");
|
||||
run("SELECT * FROM t1");
|
||||
|
||||
run("select * from test.t1");
|
||||
run("SELECT * FROM test.t1");
|
||||
|
||||
run("select ts, c1 from t1");
|
||||
run("SELECT ts, c1 FROM t1");
|
||||
|
||||
run("select ts, t.c1 from (select * from t1) t");
|
||||
run("SELECT ts, t.c1 FROM (SELECT * FROM t1) t");
|
||||
|
||||
run("select * from t1 tt1, t1 tt2 where tt1.c1 = tt2.c1");
|
||||
run("SELECT * FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, constant) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select 123, 20.4, 'abc', \"wxy\", timestamp '2022-02-09 17:30:20', true, false, 10s from t1");
|
||||
run("SELECT 123, 20.4, 'abc', \"wxy\", timestamp '2022-02-09 17:30:20', true, false, 10s FROM t1");
|
||||
|
||||
run("select 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", "
|
||||
"timestamp '2022-02-09 17:30:20', true, false, 15s from t1");
|
||||
run("SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", "
|
||||
"timestamp '2022-02-09 17:30:20', true, false, 15s FROM t1");
|
||||
|
||||
run("select 123 + 45 from t1 where 2 - 1");
|
||||
run("SELECT 123 + 45 FROM t1 WHERE 2 - 1");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, expression) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select ts + 10s, c1 + 10, concat(c2, 'abc') from t1");
|
||||
run("SELECT ts + 10s, c1 + 10, concat(c2, 'abc') FROM t1");
|
||||
|
||||
run("select ts > 0, c1 < 20 and c2 = 'qaz' from t1");
|
||||
run("SELECT ts > 0, c1 < 20 and c2 = 'qaz' FROM t1");
|
||||
|
||||
run("select ts > 0, c1 between 10 and 20 and c2 = 'qaz' from t1");
|
||||
run("SELECT ts > 0, c1 between 10 and 20 and c2 = 'qaz' FROM t1");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, condition) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select c1 from t1 where ts in (true, false)");
|
||||
run("SELECT c1 FROM t1 WHERE ts in (true, false)");
|
||||
|
||||
run("select * from t1 where c1 > 10 and c1 is not null");
|
||||
run("SELECT * FROM t1 WHERE c1 > 10 and c1 is not null");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, pseudoColumn) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select _wstartts, _wendts, count(*) from t1 interval(10s)");
|
||||
run("SELECT _WSTARTTS, _WENDTS, COUNT(*) FROM t1 INTERVAL(10s)");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, multiResFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select last(*), first(*), last_row(*) from t1");
|
||||
run("SELECT LAST(*), FIRST(*), LAST_ROW(*) FROM t1");
|
||||
|
||||
run("select last(c1, c2), first(t1.*), last_row(c3) from t1");
|
||||
run("SELECT LAST(c1, c2), FIRST(t1.*), LAST_ROW(c3) FROM t1");
|
||||
|
||||
run("select last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) from st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
|
||||
run("SELECT LAST(t2.*), FIRST(t1.c1, t2.*), LAST_ROW(t1.*, t2.*) FROM st1s1 t1, st1s2 t2 WHERE t1.ts = t2.ts");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, timelineFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select last(*), first(*) from t1");
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1");
|
||||
|
||||
run("select last(*), first(*) from t1 group by c1");
|
||||
run("SELECT FIRST(ts), FIRST(c1), FIRST(c2), FIRST(c3) FROM t1");
|
||||
|
||||
run("select last(*), first(*) from t1 interval(10s)");
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1 GROUP BY c1");
|
||||
|
||||
run("select diff(c1) from t1");
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1 INTERVAL(10s)");
|
||||
|
||||
run("SELECT diff(c1) FROM t1");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, selectFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
// select function
|
||||
run("SELECT MAX(c1), MIN(c1) FROM t1");
|
||||
// select function for GROUP BY clause
|
||||
run("SELECT MAX(c1), MIN(c1) FROM t1 GROUP BY c1");
|
||||
// select function for INTERVAL clause
|
||||
run("SELECT MAX(c1), MIN(c1) FROM t1 INTERVAL(10s)");
|
||||
// select function along with the columns of select row
|
||||
run("SELECT MAX(c1), c2 FROM t1");
|
||||
run("SELECT MAX(c1), t1.* FROM t1");
|
||||
// select function along with the columns of select row, and with GROUP BY clause
|
||||
run("SELECT MAX(c1), c2 FROM t1 GROUP BY c3");
|
||||
run("SELECT MAX(c1), t1.* FROM t1 GROUP BY c3");
|
||||
// select function along with the columns of select row, and with window clause
|
||||
run("SELECT MAX(c1), c2 FROM t1 INTERVAL(10s)");
|
||||
run("SELECT MAX(c1), c2 FROM t1 SESSION(ts, 10s)");
|
||||
run("SELECT MAX(c1), c2 FROM t1 STATE_WINDOW(c3)");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, clause) {
|
||||
useDb("root", "test");
|
||||
|
||||
// group by clause
|
||||
run("select count(*) cnt from t1 where c1 > 0");
|
||||
// GROUP BY clause
|
||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0");
|
||||
|
||||
run("select count(*), c2 cnt from t1 where c1 > 0 group by c2");
|
||||
run("SELECT COUNT(*), c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2");
|
||||
|
||||
run("select count(*) cnt from t1 where c1 > 0 group by c2 having count(c1) > 10");
|
||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 having COUNT(c1) > 10");
|
||||
|
||||
run("select count(*), c1, c2 + 10, c1 + c2 cnt from t1 where c1 > 0 group by c2, c1");
|
||||
run("SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2, c1");
|
||||
|
||||
run("select count(*), c1 + 10, c2 cnt from t1 where c1 > 0 group by c1 + 10, c2");
|
||||
run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c1 + 10, c2");
|
||||
|
||||
// order by clause
|
||||
run("select count(*) cnt from t1 where c1 > 0 group by c2 order by cnt");
|
||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 order by cnt");
|
||||
|
||||
run("select count(*) cnt from t1 where c1 > 0 group by c2 order by 1");
|
||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 order by 1");
|
||||
|
||||
// distinct clause
|
||||
// run("select distinct c1, c2 from t1 where c1 > 0 order by c1");
|
||||
// run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by c1");
|
||||
|
||||
// run("select distinct c1 + 10, c2 from t1 where c1 > 0 order by c1 + 10, c2");
|
||||
// run("SELECT distinct c1 + 10, c2 FROM t1 WHERE c1 > 0 order by c1 + 10, c2");
|
||||
|
||||
// run("select distinct c1 + 10 cc1, c2 cc2 from t1 where c1 > 0 order by cc1, c2");
|
||||
// run("SELECT distinct c1 + 10 cc1, c2 cc2 FROM t1 WHERE c1 > 0 order by cc1, c2");
|
||||
|
||||
// run("select distinct count(c2) from t1 where c1 > 0 group by c1 order by count(c2)");
|
||||
// run("SELECT distinct COUNT(c2) FROM t1 WHERE c1 > 0 GROUP BY c1 order by COUNT(c2)");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, window) {
|
||||
// INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [FILL(fill_mod_and_val)]
|
||||
// fill_mod_and_val = { NONE | PREV | NULL | LINEAR | NEXT | value_mod }
|
||||
// value_mod = VALUE , val ...
|
||||
TEST_F(ParserSelectTest, interval) {
|
||||
useDb("root", "test");
|
||||
// INTERVAL(interval_val)
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10s)");
|
||||
// INTERVAL(interval_val, interval_offset)
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10s, 5s)");
|
||||
// INTERVAL(interval_val, interval_offset) SLIDING (sliding_val)
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10s, 5s) SLIDING(7s)");
|
||||
// INTERVAL(interval_val) FILL(NONE)
|
||||
run("SELECT COUNT(*) FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
|
||||
"INTERVAL(10s) FILL(NONE)");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, intervalSemanticCheck) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select count(*) from t1 interval(10s)");
|
||||
run("SELECT c1 FROM t1 INTERVAL(10s)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT DISTINCT c1, c2 FROM t1 WHERE c1 > 3 INTERVAL(1d) FILL(NEXT)", TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, semanticError) {
|
||||
useDb("root", "test");
|
||||
|
||||
// TSDB_CODE_PAR_INVALID_COLUMN
|
||||
run("select c1, cc1 from t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c1, cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select t1.c1, t1.cc1 from t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT t1.c1, t1.cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_TABLE_NOT_EXIST
|
||||
run("select * from t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT * FROM t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select * from test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT * FROM test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select t2.c1 from t1", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT t2.c1 FROM t1", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN
|
||||
run("select c2 from t1 tt1, t1 tt2 where tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_WRONG_VALUE_TYPE
|
||||
run("select timestamp '2010' from t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT timestamp '2010' FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
|
||||
run("select c2 from t1 tt1 join t1 tt2 on count(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION,
|
||||
run("SELECT c2 FROM t1 tt1 join t1 tt2 on COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select c2 from t1 where count(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 WHERE COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select c2 from t1 group by count(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 GROUP BY COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
|
||||
run("select c2 from t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select c2 from t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
|
||||
run("select count(*) cnt from t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*) cnt FROM t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select count(*) cnt from t1 group by c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select count(*), c1 cnt from t1 group by c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
run("SELECT COUNT(*), c1 cnt FROM t1 GROUP BY c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select count(*) cnt from t1 group by c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_NOT_SINGLE_GROUP
|
||||
run("select count(*), c1 from t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*), c1 FROM t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select count(*) from t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*) FROM t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select c1 from t1 order by count(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
|
||||
run("select distinct c1, c2 from t1 where c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select distinct c1 from t1 where c1 > 0 order by count(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
run("SELECT distinct c1 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("select distinct c2 from t1 where c1 > 0 order by count(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
run("SELECT distinct c2 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "planner.h"
|
||||
#include "taoserror.h"
|
||||
|
||||
#define QUERY_POLICY_VNODE 1
|
||||
#define QUERY_POLICY_HYBRID 2
|
||||
|
@ -33,6 +34,8 @@ extern "C" {
|
|||
#define planDebug(param, ...) qDebug("PLAN: " param, __VA_ARGS__)
|
||||
#define planTrace(param, ...) qTrace("PLAN: " param, __VA_ARGS__)
|
||||
|
||||
int32_t generateUsageErrMsg(char* pBuf, int32_t len, int32_t errCode, ...);
|
||||
|
||||
int32_t createLogicPlan(SPlanContext* pCxt, SLogicNode** pLogicNode);
|
||||
int32_t optimizeLogicPlan(SPlanContext* pCxt, SLogicNode* pLogicNode);
|
||||
int32_t splitLogicPlan(SPlanContext* pCxt, SLogicNode* pLogicNode, SLogicSubplan** pLogicSubplan);
|
||||
|
|
|
@ -274,7 +274,7 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
|||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesCollectFuncs(pSelect, fmIsScanPseudoColumnFunc, &pScan->pScanPseudoCols);
|
||||
code = nodesCollectFuncs(pSelect, SQL_CLAUSE_FROM, fmIsScanPseudoColumnFunc, &pScan->pScanPseudoCols);
|
||||
}
|
||||
|
||||
pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->pMeta);
|
||||
|
@ -440,7 +440,7 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && pSelect->hasAggFuncs) {
|
||||
code = nodesCollectFuncs(pSelect, fmIsAggFunc, &pAgg->pAggFuncs);
|
||||
code = nodesCollectFuncs(pSelect, SQL_CLAUSE_GROUP_BY, fmIsAggFunc, &pAgg->pAggFuncs);
|
||||
}
|
||||
|
||||
// rewrite the expression in subsequent clauses
|
||||
|
@ -474,7 +474,7 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
|
||||
static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow,
|
||||
SLogicNode** pLogicNode) {
|
||||
int32_t code = nodesCollectFuncs(pSelect, fmIsWindowClauseFunc, &pWindow->pFuncs);
|
||||
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_WINDOW, fmIsWindowClauseFunc, &pWindow->pFuncs);
|
||||
|
||||
if (pCxt->pPlanCxt->streamQuery) {
|
||||
pWindow->triggerType = pCxt->pPlanCxt->triggerType;
|
||||
|
@ -559,14 +559,6 @@ static int32_t createWindowLogicNodeByInterval(SLogicPlanContext* pCxt, SInterva
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (NULL != pInterval->pFill) {
|
||||
pWindow->pFill = nodesCloneNode(pInterval->pFill);
|
||||
if (NULL == pWindow->pFill) {
|
||||
nodesDestroyNode(pWindow);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
|
||||
}
|
||||
|
||||
|
@ -589,6 +581,38 @@ static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||
if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow) ||
|
||||
NULL == ((SIntervalWindowNode*)pSelect->pWindow)->pFill) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SFillNode* pFillNode = (SFillNode*)(((SIntervalWindowNode*)pSelect->pWindow)->pFill);
|
||||
|
||||
SFillLogicNode* pFill = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILL);
|
||||
if (NULL == pFill) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_WINDOW, NULL, COLLECT_COL_TYPE_ALL, &pFill->node.pTargets);
|
||||
|
||||
pFill->mode = pFillNode->mode;
|
||||
pFill->timeRange = pFillNode->timeRange;
|
||||
pFill->pValues = nodesCloneNode(pFillNode->pValues);
|
||||
pFill->pWStartTs = nodesCloneNode(pFillNode->pWStartTs);
|
||||
if ((NULL != pFillNode->pValues && NULL == pFill->pValues) || NULL == pFill->pWStartTs) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pLogicNode = (SLogicNode*)pFill;
|
||||
} else {
|
||||
nodesDestroyNode(pFill);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||
if (NULL == pSelect->pOrderByList) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -753,6 +777,9 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createFillLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
|
||||
}
|
||||
|
|
|
@ -554,22 +554,19 @@ static bool cpdIsPrimaryKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
|
|||
|
||||
static int32_t cpdCheckOpCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SNode* pOnCond) {
|
||||
if (!cpdIsPrimaryKeyEqualCond(pJoin, pOnCond)) {
|
||||
snprintf(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, "l.ts = r.ts is expected in join expression");
|
||||
return TSDB_CODE_FAILED;
|
||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t cpdCheckLogicCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SLogicConditionNode* pOnCond) {
|
||||
if (LOGIC_COND_TYPE_AND != pOnCond->condType) {
|
||||
snprintf(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, "l.ts = r.ts is expected in join expression");
|
||||
return TSDB_CODE_FAILED;
|
||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL);
|
||||
}
|
||||
SNode* pCond = NULL;
|
||||
FOREACH(pCond, pOnCond->pParameterList) {
|
||||
if (!cpdIsPrimaryKeyEqualCond(pJoin, pCond)) {
|
||||
snprintf(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, "l.ts = r.ts is expected in join expression");
|
||||
return TSDB_CODE_FAILED;
|
||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -577,8 +574,7 @@ static int32_t cpdCheckLogicCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin,
|
|||
|
||||
static int32_t cpdCheckJoinOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||
if (NULL == pJoin->pOnConditions) {
|
||||
snprintf(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, "not support cross join");
|
||||
return TSDB_CODE_FAILED;
|
||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN);
|
||||
}
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pOnConditions)) {
|
||||
return cpdCheckLogicCond(pCxt, pJoin, (SLogicConditionNode*)pJoin->pOnConditions);
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
#include "catalog.h"
|
||||
#include "functionMgt.h"
|
||||
#include "tglobal.h"
|
||||
#include "systable.h"
|
||||
#include "tglobal.h"
|
||||
|
||||
typedef struct SSlotIdInfo {
|
||||
int16_t slotId;
|
||||
|
@ -880,12 +880,6 @@ static int32_t createIntervalPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChil
|
|||
pInterval->intervalUnit = pWindowLogicNode->intervalUnit;
|
||||
pInterval->slidingUnit = pWindowLogicNode->slidingUnit;
|
||||
|
||||
pInterval->pFill = nodesCloneNode(pWindowLogicNode->pFill);
|
||||
if (NULL != pWindowLogicNode->pFill && NULL == pInterval->pFill) {
|
||||
nodesDestroyNode(pInterval);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return createWindowPhysiNodeFinalize(pCxt, pChildren, &pInterval->window, pWindowLogicNode, pPhyNode);
|
||||
}
|
||||
|
||||
|
@ -1035,6 +1029,46 @@ static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SFillLogicNode* pFillNode,
|
||||
SPhysiNode** pPhyNode) {
|
||||
SFillPhysiNode* pFill = (SFillPhysiNode*)makePhysiNode(pCxt, getPrecision(pChildren), (SLogicNode*)pFillNode,
|
||||
QUERY_NODE_PHYSICAL_PLAN_FILL);
|
||||
if (NULL == pFill) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pFill->mode = pFillNode->mode;
|
||||
pFill->timeRange = pFillNode->timeRange;
|
||||
|
||||
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
|
||||
int32_t code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->node.pTargets, &pFill->pTargets);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addDataBlockSlots(pCxt, pFill->pTargets, pFill->node.pOutputDataBlockDesc);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pFill->pWStartTs = nodesCloneNode(pFillNode->pWStartTs);
|
||||
if (NULL == pFill->pWStartTs) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pFillNode->pValues) {
|
||||
pFill->pValues = nodesCloneNode(pFillNode->pValues);
|
||||
if (NULL == pFill->pValues) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pPhyNode = (SPhysiNode*)pFill;
|
||||
} else {
|
||||
nodesDestroyNode(pFill);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, SSubplan* pSubplan,
|
||||
SNodeList* pChildren, SPhysiNode** pPhyNode) {
|
||||
switch (nodeType(pLogicNode)) {
|
||||
|
@ -1054,6 +1088,8 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
|
|||
return createSortPhysiNode(pCxt, pChildren, (SSortLogicNode*)pLogicNode, pPhyNode);
|
||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||
return createPartitionPhysiNode(pCxt, pChildren, (SPartitionLogicNode*)pLogicNode, pPhyNode);
|
||||
case QUERY_NODE_LOGIC_PLAN_FILL:
|
||||
return createFillPhysiNode(pCxt, pChildren, (SFillLogicNode*)pLogicNode, pPhyNode);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "planInt.h"
|
||||
|
||||
static char* getUsageErrFormat(int32_t errCode) {
|
||||
switch (errCode) {
|
||||
case TSDB_CODE_PLAN_EXPECTED_TS_EQUAL:
|
||||
return "l.ts = r.ts is expected in join expression";
|
||||
case TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN:
|
||||
return "not support cross join";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
int32_t generateUsageErrMsg(char* pBuf, int32_t len, int32_t errCode, ...) {
|
||||
va_list vArgList;
|
||||
va_start(vArgList, errCode);
|
||||
vsnprintf(pBuf, len, getUsageErrFormat(errCode), vArgList);
|
||||
va_end(vArgList);
|
||||
return errCode;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* This program is free software: you can use, redistribute, AND/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
|
@ -20,30 +20,32 @@ using namespace std;
|
|||
|
||||
class PlanBasicTest : public PlannerTestBase {};
|
||||
|
||||
TEST_F(PlanBasicTest, select) {
|
||||
TEST_F(PlanBasicTest, selectClause) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select * from t1");
|
||||
run("select 1 from t1");
|
||||
run("select * from st1");
|
||||
run("select 1 from st1");
|
||||
run("SELECT * FROM t1");
|
||||
run("SELECT 1 FROM t1");
|
||||
run("SELECT * FROM st1");
|
||||
run("SELECT 1 FROM st1");
|
||||
}
|
||||
|
||||
TEST_F(PlanBasicTest, where) {
|
||||
TEST_F(PlanBasicTest, whereClause) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select * from t1 where c1 > 10");
|
||||
run("SELECT * FROM t1 WHERE c1 > 10");
|
||||
|
||||
run("SELECT * FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59'");
|
||||
}
|
||||
|
||||
TEST_F(PlanBasicTest, join) {
|
||||
TEST_F(PlanBasicTest, joinClause) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select t1.c1, t2.c2 from st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
|
||||
run("select t1.c1, t2.c2 from st1s1 t1 join st1s2 t2 on t1.ts = t2.ts");
|
||||
run("SELECT t1.c1, t2.c2 FROM st1s1 t1, st1s2 t2 WHERE t1.ts = t2.ts");
|
||||
run("SELECT t1.c1, t2.c2 FROM st1s1 t1 JOIN st1s2 t2 ON t1.ts = t2.ts");
|
||||
}
|
||||
|
||||
TEST_F(PlanBasicTest, func) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select diff(c1) from t1");
|
||||
run("SELECT DIFF(c1) FROM t1");
|
||||
}
|
||||
|
|
|
@ -23,30 +23,45 @@ class PlanGroupByTest : public PlannerTestBase {};
|
|||
TEST_F(PlanGroupByTest, basic) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select count(*) from t1");
|
||||
run("SELECT COUNT(*) FROM t1");
|
||||
|
||||
run("select c1, max(c3), min(c3), count(*) from t1 group by c1");
|
||||
run("SELECT c1, MAX(c3), MIN(c3), COUNT(*) FROM t1 GROUP BY c1");
|
||||
|
||||
run("select c1 + c3, c1 + count(*) from t1 where c2 = 'abc' group by c1, c3");
|
||||
run("SELECT c1 + c3, c1 + COUNT(*) FROM t1 WHERE c2 = 'abc' GROUP BY c1, c3");
|
||||
|
||||
run("select c1 + c3, sum(c4 * c5) from t1 where concat(c2, 'wwww') = 'abcwww' group by c1 + c3");
|
||||
run("SELECT c1 + c3, SUM(c4 * c5) FROM t1 WHERE CONCAT(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3");
|
||||
|
||||
run("select sum(ceil(c1)) from t1 group by ceil(c1)");
|
||||
run("SELECT SUM(CEIL(c1)) FROM t1 GROUP BY CEIL(c1)");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, withOrderBy) {
|
||||
useDb("root", "test");
|
||||
|
||||
// order by aggfunc
|
||||
run("select count(*), sum(c1) from t1 order by sum(c1)");
|
||||
// order by alias of aggfunc
|
||||
// run("select count(*), sum(c1) a from t1 order by a");
|
||||
// ORDER BY aggfunc
|
||||
run("SELECT COUNT(*), SUM(c1) FROM t1 ORDER BY SUM(c1)");
|
||||
// ORDER BY alias of aggfunc
|
||||
// run("SELECT COUNT(*), SUM(c1) a FROM t1 ORDER BY a");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, aggFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select last(*), first(*) from t1");
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1");
|
||||
|
||||
run("select last(*), first(*) from t1 group by c1");
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1 GROUP BY c1");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, selectFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
// select function
|
||||
run("SELECT MAX(c1), MIN(c1) FROM t1");
|
||||
// select function for GROUP BY clause
|
||||
run("SELECT MAX(c1), MIN(c1) FROM t1 GROUP BY c1");
|
||||
// select function along with the columns of select row
|
||||
run("SELECT MAX(c1), c2 FROM t1");
|
||||
run("SELECT MAX(c1), t1.* FROM t1");
|
||||
// select function along with the columns of select row, and with GROUP BY clause
|
||||
run("SELECT MAX(c1), c2 FROM t1 GROUP BY c3");
|
||||
run("SELECT MAX(c1), t1.* FROM t1 GROUP BY c3");
|
||||
}
|
||||
|
|
|
@ -23,19 +23,31 @@ class PlanIntervalTest : public PlannerTestBase {};
|
|||
TEST_F(PlanIntervalTest, basic) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select count(*) from t1 interval(10s)");
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10s)");
|
||||
}
|
||||
|
||||
TEST_F(PlanIntervalTest, pseudoCol) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select _wstartts, _wduration, _wendts, count(*) from t1 interval(10s)");
|
||||
run("SELECT _WSTARTTS, _WDURATION, _WENDTS, COUNT(*) FROM t1 INTERVAL(10s)");
|
||||
}
|
||||
|
||||
TEST_F(PlanIntervalTest, fill) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select count(*) from t1 interval(10s) fill(linear)");
|
||||
run("SELECT COUNT(*) FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
|
||||
"INTERVAL(10s) FILL(LINEAR)");
|
||||
|
||||
run("select count(*), sum(c1) from t1 interval(10s) fill(value, 10, 20)");
|
||||
run("SELECT COUNT(*), SUM(c1) FROM t1 "
|
||||
"WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
|
||||
"INTERVAL(10s) FILL(VALUE, 10, 20)");
|
||||
}
|
||||
|
||||
TEST_F(PlanIntervalTest, selectFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
// select function for INTERVAL clause
|
||||
run("SELECT MAX(c1), MIN(c1) FROM t1 INTERVAL(10s)");
|
||||
// select function along with the columns of select row, and with INTERVAL clause
|
||||
run("SELECT MAX(c1), c2 FROM t1 INTERVAL(10s)");
|
||||
}
|
|
@ -25,3 +25,12 @@ TEST_F(PlanSessionTest, basic) {
|
|||
|
||||
run("select count(*) from t1 session(ts, 10s)");
|
||||
}
|
||||
|
||||
TEST_F(PlanSessionTest, selectFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
// select function for SESSION clause
|
||||
run("SELECT MAX(c1), MIN(c1) FROM t1 SESSION(ts, 10s)");
|
||||
// select function along with the columns of select row, and with SESSION clause
|
||||
run("SELECT MAX(c1), c2 FROM t1 SESSION(ts, 10s)");
|
||||
}
|
||||
|
|
|
@ -31,3 +31,12 @@ TEST_F(PlanStateTest, stateExpr) {
|
|||
|
||||
run("select count(*) from t1 state_window(c1 + 10)");
|
||||
}
|
||||
|
||||
TEST_F(PlanStateTest, selectFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
// select function for STATE_WINDOW clause
|
||||
run("SELECT MAX(c1), MIN(c1) FROM t1 STATE_WINDOW(c3)");
|
||||
// select function along with the columns of select row, and with STATE_WINDOW clause
|
||||
run("SELECT MAX(c1), c2 FROM t1 STATE_WINDOW(c3)");
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "osDef.h"
|
||||
#include "qworker.h"
|
||||
#include "tlockfree.h"
|
||||
#include "ttimer.h"
|
||||
|
@ -301,9 +302,9 @@ typedef struct SQWorkerMgmt {
|
|||
|
||||
extern SQWorkerMgmt gQwMgmt;
|
||||
|
||||
FORCE_INLINE SQWorker *qwAcquire(int64_t refId) { return (SQWorker *)taosAcquireRef(atomic_load_32(&gQwMgmt.qwRef), refId); }
|
||||
static FORCE_INLINE SQWorker *qwAcquire(int64_t refId) { return (SQWorker *)taosAcquireRef(atomic_load_32(&gQwMgmt.qwRef), refId); }
|
||||
|
||||
FORCE_INLINE int32_t qwRelease(int64_t refId) { return taosReleaseRef(gQwMgmt.qwRef, refId); }
|
||||
static FORCE_INLINE int32_t qwRelease(int64_t refId) { return taosReleaseRef(gQwMgmt.qwRef, refId); }
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -37,7 +37,7 @@ bool syncEnvIsStart() {
|
|||
int32_t syncEnvStart() {
|
||||
int32_t ret = 0;
|
||||
taosSeedRand(taosGetTimestampSec());
|
||||
//gSyncEnv = doSyncEnvStart(gSyncEnv);
|
||||
// gSyncEnv = doSyncEnvStart(gSyncEnv);
|
||||
gSyncEnv = doSyncEnvStart();
|
||||
assert(gSyncEnv != NULL);
|
||||
sTrace("syncEnvStart ok!");
|
||||
|
@ -97,14 +97,14 @@ static SSyncEnv *doSyncEnvStart() {
|
|||
// start tmr thread
|
||||
pSyncEnv->pTimerManager = taosTmrInit(1000, 50, 10000, "SYNC-ENV");
|
||||
|
||||
atomic_store_8(&(pSyncEnv->isStart), 1);
|
||||
atomic_store_8(&(pSyncEnv->isStart), 1);
|
||||
return pSyncEnv;
|
||||
}
|
||||
|
||||
static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv) {
|
||||
assert(pSyncEnv == gSyncEnv);
|
||||
if (pSyncEnv != NULL) {
|
||||
atomic_store_8(&(pSyncEnv->isStart), 0);
|
||||
atomic_store_8(&(pSyncEnv->isStart), 0);
|
||||
taosTmrCleanUp(pSyncEnv->pTimerManager);
|
||||
taosMemoryFree(pSyncEnv);
|
||||
}
|
||||
|
|
|
@ -141,6 +141,18 @@ const char* syncGetMyRoleStr(int64_t rid) {
|
|||
return s;
|
||||
}
|
||||
|
||||
int32_t syncGetVgId(int64_t rid) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pSyncNode == NULL) {
|
||||
return TAOS_SYNC_STATE_ERROR;
|
||||
}
|
||||
assert(rid == pSyncNode->rid);
|
||||
int32_t vgId = pSyncNode->vgId;
|
||||
|
||||
taosReleaseRef(tsNodeRefId, pSyncNode->rid);
|
||||
return vgId;
|
||||
}
|
||||
|
||||
SyncTerm syncGetMyTerm(int64_t rid) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pSyncNode == NULL) {
|
||||
|
@ -153,6 +165,29 @@ SyncTerm syncGetMyTerm(int64_t rid) {
|
|||
return term;
|
||||
}
|
||||
|
||||
void syncGetEpSet(int64_t rid, SEpSet* pEpSet) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pSyncNode == NULL) {
|
||||
memset(pEpSet, 0, sizeof(*pEpSet));
|
||||
return;
|
||||
}
|
||||
assert(rid == pSyncNode->rid);
|
||||
pEpSet->numOfEps = 0;
|
||||
for (int i = 0; i < pSyncNode->pRaftCfg->cfg.replicaNum; ++i) {
|
||||
snprintf(pEpSet->eps[i].fqdn, sizeof(pEpSet->eps[i].fqdn), "%s", (pSyncNode->pRaftCfg->cfg.nodeInfo)[i].nodeFqdn);
|
||||
pEpSet->eps[i].port = (pSyncNode->pRaftCfg->cfg.nodeInfo)[i].nodePort;
|
||||
(pEpSet->numOfEps)++;
|
||||
|
||||
sInfo("syncGetEpSet index:%d %s:%d", i, pEpSet->eps[i].fqdn, pEpSet->eps[i].port);
|
||||
|
||||
}
|
||||
pEpSet->inUse = pSyncNode->pRaftCfg->cfg.myIndex;
|
||||
|
||||
sInfo("syncGetEpSet pEpSet->inUse:%d ", pEpSet->inUse);
|
||||
|
||||
taosReleaseRef(tsNodeRefId, pSyncNode->rid);
|
||||
}
|
||||
|
||||
int32_t syncGetRespRpc(int64_t rid, uint64_t index, SRpcMsg* msg) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pSyncNode == NULL) {
|
||||
|
@ -260,6 +295,8 @@ void setHeartbeatTimerMS(int64_t rid, int32_t hbTimerMS) {
|
|||
}
|
||||
|
||||
int32_t syncPropose(int64_t rid, const SRpcMsg* pMsg, bool isWeak) {
|
||||
sTrace("syncPropose msgType:%d ", pMsg->msgType);
|
||||
|
||||
int32_t ret = TAOS_SYNC_PROPOSE_SUCCESS;
|
||||
SSyncNode* pSyncNode = (SSyncNode*)taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pSyncNode == NULL) {
|
||||
|
@ -459,18 +496,17 @@ void syncNodeStart(SSyncNode* pSyncNode) {
|
|||
// start raft
|
||||
if (pSyncNode->replicaNum == 1) {
|
||||
syncNodeBecomeLeader(pSyncNode);
|
||||
|
||||
|
||||
syncNodeLog2("==state change become leader immediately==", pSyncNode);
|
||||
|
||||
|
||||
// Raft 3.6.2 Committing entries from previous terms
|
||||
|
||||
|
||||
// use this now
|
||||
syncNodeAppendNoop(pSyncNode);
|
||||
syncMaybeAdvanceCommitIndex(pSyncNode); // maybe only one replica
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
syncNodeBecomeFollower(pSyncNode);
|
||||
|
||||
// for test
|
||||
|
|
|
@ -891,7 +891,6 @@ static void doDelayTask(void* param) {
|
|||
|
||||
SCliMsg* pMsg = arg->param1;
|
||||
SCliThrdObj* pThrd = arg->param2;
|
||||
|
||||
cliHandleReq(pMsg, pThrd);
|
||||
|
||||
taosMemoryFree(arg);
|
||||
|
@ -937,8 +936,8 @@ int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) {
|
|||
tDeserializeSMEpSet(pResp->pCont, pResp->contLen, &emsg);
|
||||
pCtx->epSet = emsg.epSet;
|
||||
}
|
||||
addConnToPool(pThrd, pConn);
|
||||
tTrace("use remote epset, current in use: %d, retry count%d, try limit: %d", pEpSet->inUse, pCtx->retryCount + 1,
|
||||
addConnToPool(pThrd->pool, pConn);
|
||||
tTrace("use remote epset, current in use: %d, retry count:%d, try limit: %d", pEpSet->inUse, pCtx->retryCount + 1,
|
||||
TRANS_RETRY_COUNT_LIMIT);
|
||||
|
||||
STaskArg* arg = taosMemoryMalloc(sizeof(STaskArg));
|
||||
|
|
|
@ -425,10 +425,19 @@ void transDQDestroy(SDelayQueue* queue) {
|
|||
}
|
||||
|
||||
int transDQSched(SDelayQueue* queue, void (*func)(void* arg), void* arg, uint64_t timeoutMs) {
|
||||
uint64_t now = taosGetTimestampMs();
|
||||
SDelayTask* task = taosMemoryCalloc(1, sizeof(SDelayTask));
|
||||
task->func = func;
|
||||
task->arg = arg;
|
||||
task->execTime = taosGetTimestampMs() + timeoutMs;
|
||||
task->execTime = now + timeoutMs;
|
||||
|
||||
HeapNode* minNode = heapMin(queue->heap);
|
||||
if (minNode) {
|
||||
SDelayTask* minTask = container_of(minNode, SDelayTask, node);
|
||||
if (minTask->execTime < task->execTime) {
|
||||
timeoutMs = minTask->execTime <= now ? 0 : now - minTask->execTime;
|
||||
}
|
||||
}
|
||||
|
||||
tTrace("timer %p put task into queue, timeoutMs: %" PRIu64 "", queue->timer, timeoutMs);
|
||||
heapInsert(queue->heap, &task->node);
|
||||
|
|
|
@ -810,12 +810,14 @@ void* transInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads,
|
|||
|
||||
for (int i = 0; i < srv->numOfThreads; i++) {
|
||||
SWorkThrdObj* thrd = (SWorkThrdObj*)taosMemoryCalloc(1, sizeof(SWorkThrdObj));
|
||||
thrd->pTransInst = shandle;
|
||||
thrd->quit = false;
|
||||
srv->pThreadObj[i] = thrd;
|
||||
thrd->pTransInst = shandle;
|
||||
|
||||
srv->pipe[i] = (uv_pipe_t*)taosMemoryCalloc(2, sizeof(uv_pipe_t));
|
||||
|
||||
|
||||
uv_os_sock_t fds[2];
|
||||
if (uv_socketpair(SOCK_STREAM, 0, fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE) != 0) {
|
||||
goto End;
|
||||
|
|
|
@ -101,7 +101,7 @@ class TDTestCase:
|
|||
# tdSql.error("select distinct c1, ts from stb1 group by c2")
|
||||
tdSql.error("select distinct c1, ts from t1 group by c2")
|
||||
# tdSql.error("select distinct c1, max(c2) from stb1 ")
|
||||
tdSql.error("select distinct c1, max(c2) from t1 ")
|
||||
# tdSql.error("select distinct c1, max(c2) from t1 ")
|
||||
# tdSql.error("select max(c2), distinct c1 from stb1 ")
|
||||
tdSql.error("select max(c2), distinct c1 from t1 ")
|
||||
# tdSql.error("select distinct c1, c2 from stb1 where c1 > 3 group by t0")
|
||||
|
|
Loading…
Reference in New Issue