diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 5e2bfc52e1..575a0e6274 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -127,6 +127,11 @@ target_include_directories( # zlib set(CMAKE_PROJECT_INCLUDE_BEFORE "${CMAKE_SUPPORT_DIR}/EnableCMP0048.txt.in") add_subdirectory(zlib) +target_include_directories( + zlibstatic + PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/zlib + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/zlib +) target_include_directories( zlib PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/zlib diff --git a/include/common/taosdef.h b/include/common/taosdef.h index 9e5e5ebdcf..39d08f2e86 100644 --- a/include/common/taosdef.h +++ b/include/common/taosdef.h @@ -33,7 +33,7 @@ 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_STREAM_TABLE = 4, // table created by stream processing TSDB_TEMP_TABLE = 5, // temp table created by nest query TSDB_TABLE_MAX = 6 } ETableType; @@ -50,7 +50,12 @@ typedef enum { TSDB_CHECK_ITEM_MAX } ECheckItemType; -typedef enum { TD_ROW_DISCARD_UPDATE = 0, TD_ROW_OVERWRITE_UPDATE = 1, TD_ROW_PARTIAL_UPDATE = 2 } TDUpdateConfig; +typedef enum { + TD_ROW_DISCARD_UPDATE = 0, + TD_ROW_OVERWRITE_UPDATE = 1, + TD_ROW_PARTIAL_UPDATE = 2, +} TDUpdateConfig; + typedef enum { TSDB_STATIS_OK = 0, // statis part exist and load successfully TSDB_STATIS_NONE = 1, // statis part not exist @@ -61,6 +66,12 @@ typedef enum { TSDB_SMA_STAT_EXPIRED = 1, // not ready or expired } ETsdbSmaStat; +typedef enum { + TSDB_SMA_TYPE_BLOCK = 0, // Block-wise SMA + TSDB_SMA_TYPE_TIME_RANGE = 1, // Time-range-wise SMA + TSDB_SMA_TYPE_ROLLUP = 2, // Rollup SMA +} ETsdbSmaType; + extern char *qtypeStr[]; #define TSDB_PORT_HTTP 11 diff --git a/include/common/tcommon.h b/include/common/tcommon.h index b5bd088006..3ca1209818 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -54,10 +54,11 @@ typedef struct SColumnDataAgg { } SColumnDataAgg; typedef struct SDataBlockInfo { - STimeWindow window; - int32_t rows; - int32_t rowSize; - int32_t numOfCols; + STimeWindow window; + int32_t rows; + int32_t rowSize; + int16_t numOfCols; + int16_t hasVarCol; union {int64_t uid; int64_t blockId;}; } SDataBlockInfo; @@ -96,13 +97,15 @@ typedef struct SColumnInfoData { static FORCE_INLINE int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) { int64_t tbUid = pBlock->info.uid; - int32_t numOfCols = pBlock->info.numOfCols; + int16_t numOfCols = pBlock->info.numOfCols; + int16_t hasVarCol = pBlock->info.hasVarCol; int32_t rows = pBlock->info.rows; int32_t sz = taosArrayGetSize(pBlock->pDataBlock); int32_t tlen = 0; tlen += taosEncodeFixedI64(buf, tbUid); - tlen += taosEncodeFixedI32(buf, numOfCols); + tlen += taosEncodeFixedI16(buf, numOfCols); + tlen += taosEncodeFixedI16(buf, hasVarCol); tlen += taosEncodeFixedI32(buf, rows); tlen += taosEncodeFixedI32(buf, sz); for (int32_t i = 0; i < sz; i++) { @@ -120,7 +123,8 @@ static FORCE_INLINE void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock) int32_t sz; buf = taosDecodeFixedI64(buf, &pBlock->info.uid); - buf = taosDecodeFixedI32(buf, &pBlock->info.numOfCols); + buf = taosDecodeFixedI16(buf, &pBlock->info.numOfCols); + buf = taosDecodeFixedI16(buf, &pBlock->info.hasVarCol); buf = taosDecodeFixedI32(buf, &pBlock->info.rows); buf = taosDecodeFixedI32(buf, &sz); pBlock->pDataBlock = taosArrayInit(sz, sizeof(SColumnInfoData)); @@ -136,6 +140,23 @@ static FORCE_INLINE void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock) return (void*)buf; } +static FORCE_INLINE void tDeleteSSDataBlock(SSDataBlock* pBlock) { + if (pBlock == NULL) { + return; + } + + // int32_t numOfOutput = pBlock->info.numOfCols; + int32_t sz = taosArrayGetSize(pBlock->pDataBlock); + for (int32_t i = 0; i < sz; ++i) { + SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i); + tfree(pColInfoData->pData); + } + + taosArrayDestroy(pBlock->pDataBlock); + tfree(pBlock->pBlockAgg); + // tfree(pBlock); +} + static FORCE_INLINE int32_t tEncodeSMqPollRsp(void** buf, const SMqPollRsp* pRsp) { int32_t tlen = 0; int32_t sz = 0; @@ -178,23 +199,6 @@ static FORCE_INLINE void* tDecodeSMqPollRsp(void* buf, SMqPollRsp* pRsp) { return buf; } -static FORCE_INLINE void tDeleteSSDataBlock(SSDataBlock* pBlock) { - if (pBlock == NULL) { - return; - } - - // int32_t numOfOutput = pBlock->info.numOfCols; - int32_t sz = taosArrayGetSize(pBlock->pDataBlock); - for (int32_t i = 0; i < sz; ++i) { - SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i); - tfree(pColInfoData->pData); - } - - taosArrayDestroy(pBlock->pDataBlock); - tfree(pBlock->pBlockAgg); - // tfree(pBlock); -} - static FORCE_INLINE void tDeleteSMqConsumeRsp(SMqPollRsp* pRsp) { if (pRsp->schemas) { if (pRsp->schemas->nCols) { @@ -204,10 +208,6 @@ static FORCE_INLINE void tDeleteSMqConsumeRsp(SMqPollRsp* pRsp) { } taosArrayDestroyEx(pRsp->pBlockData, (void (*)(void*))tDeleteSSDataBlock); pRsp->pBlockData = NULL; - // for (int32_t i = 0; i < taosArrayGetSize(pRsp->pBlockData); i++) { - // SSDataBlock* pDataBlock = (SSDataBlock*)taosArrayGet(pRsp->pBlockData, i); - // tDeleteSSDataBlock(pDataBlock); - //} } //====================================================================================================================== diff --git a/include/common/tdatablock.h b/include/common/tdatablock.h index c2249f408a..7e60013aa1 100644 --- a/include/common/tdatablock.h +++ b/include/common/tdatablock.h @@ -117,7 +117,7 @@ int32_t blockDataSort_rv(SSDataBlock* pDataBlock, SArray* pOrderInfo, bool nullF int32_t blockDataEnsureColumnCapacity(SColumnInfoData* pColumn, uint32_t numOfRows); int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows); -void blockDataClearup(SSDataBlock* pDataBlock, bool hasVarCol); +void blockDataClearup(SSDataBlock* pDataBlock); SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock); size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize); void* blockDataDestroy(SSDataBlock* pBlock); diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 5d12fc4ffc..f0718900c0 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -190,7 +190,10 @@ typedef struct SEp { typedef struct { int32_t contLen; - int32_t vgId; + union { + int32_t vgId; + int32_t streamTaskId; + }; } SMsgHead; // Submit message for one table @@ -1139,6 +1142,17 @@ int32_t tSerializeSCMCreateStreamReq(void* buf, int32_t bufLen, const SCMCreateS int32_t tDeserializeSCMCreateStreamReq(void* buf, int32_t bufLen, SCMCreateStreamReq* pReq); void tFreeSCMCreateStreamReq(SCMCreateStreamReq* pReq); +typedef struct { + char name[TSDB_TOPIC_FNAME_LEN]; + int64_t streamId; + char* sql; + char* executorMsg; +} SMVCreateStreamReq, SMSCreateStreamReq; + +typedef struct { + int64_t streamId; +} SMVCreateStreamRsp, SMSCreateStreamRsp; + typedef struct { char name[TSDB_TOPIC_FNAME_LEN]; int8_t igExists; @@ -1903,11 +1917,12 @@ typedef struct { int8_t slidingUnit; char indexName[TSDB_INDEX_NAME_LEN]; char timezone[TD_TIMEZONE_LEN]; // sma data is invalid if timezone change. - uint16_t exprLen; - uint16_t tagsFilterLen; + int32_t exprLen; + int32_t tagsFilterLen; int64_t indexUid; tb_uid_t tableUid; // super/child/common table uid int64_t interval; + int64_t offset; int64_t sliding; char* expr; // sma expression char* tagsFilter; @@ -2009,11 +2024,12 @@ static FORCE_INLINE int32_t tEncodeTSma(void** buf, const STSma* pSma) { tlen += taosEncodeFixedI8(buf, pSma->slidingUnit); tlen += taosEncodeString(buf, pSma->indexName); tlen += taosEncodeString(buf, pSma->timezone); - tlen += taosEncodeFixedU16(buf, pSma->exprLen); - tlen += taosEncodeFixedU16(buf, pSma->tagsFilterLen); + tlen += taosEncodeFixedI32(buf, pSma->exprLen); + tlen += taosEncodeFixedI32(buf, pSma->tagsFilterLen); tlen += taosEncodeFixedI64(buf, pSma->indexUid); tlen += taosEncodeFixedI64(buf, pSma->tableUid); tlen += taosEncodeFixedI64(buf, pSma->interval); + tlen += taosEncodeFixedI64(buf, pSma->offset); tlen += taosEncodeFixedI64(buf, pSma->sliding); if (pSma->exprLen > 0) { @@ -2043,14 +2059,14 @@ static FORCE_INLINE void* tDecodeTSma(void* buf, STSma* pSma) { buf = taosDecodeFixedI8(buf, &pSma->slidingUnit); buf = taosDecodeStringTo(buf, pSma->indexName); buf = taosDecodeStringTo(buf, pSma->timezone); - buf = taosDecodeFixedU16(buf, &pSma->exprLen); - buf = taosDecodeFixedU16(buf, &pSma->tagsFilterLen); + buf = taosDecodeFixedI32(buf, &pSma->exprLen); + buf = taosDecodeFixedI32(buf, &pSma->tagsFilterLen); buf = taosDecodeFixedI64(buf, &pSma->indexUid); buf = taosDecodeFixedI64(buf, &pSma->tableUid); buf = taosDecodeFixedI64(buf, &pSma->interval); + buf = taosDecodeFixedI64(buf, &pSma->offset); buf = taosDecodeFixedI64(buf, &pSma->sliding); - if (pSma->exprLen > 0) { pSma->expr = (char*)calloc(pSma->exprLen, 1); if (pSma->expr != NULL) { diff --git a/include/common/ttime.h b/include/common/ttime.h index b71426e312..57af24e635 100644 --- a/include/common/ttime.h +++ b/include/common/ttime.h @@ -25,6 +25,17 @@ extern "C" { #define TIME_IS_VAR_DURATION(_t) ((_t) == 'n' || (_t) == 'y' || (_t) == 'N' || (_t) == 'Y') +#define TIME_UNIT_NANOSECOND 'b' +#define TIME_UNIT_MICROSECOND 'u' +#define TIME_UNIT_MILLISECOND 'a' +#define TIME_UNIT_SECOND 's' +#define TIME_UNIT_MINUTE 'm' +#define TIME_UNIT_HOUR 'h' +#define TIME_UNIT_DAY 'd' +#define TIME_UNIT_WEEK 'w' +#define TIME_UNIT_MONTH 'n' +#define TIME_UNIT_YEAR 'y' + /* * @return timestamp decided by global conf variable, tsTimePrecision * if precision == TSDB_TIME_PRECISION_MICRO, it returns timestamp in microsecond. diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h index 2121b3175a..5693091bd5 100644 --- a/include/common/ttokendef.h +++ b/include/common/ttokendef.h @@ -48,108 +48,113 @@ #define TK_DNODES 30 #define TK_NK_ID 31 #define TK_NK_IPTOKEN 32 -#define TK_DATABASE 33 -#define TK_DATABASES 34 -#define TK_USE 35 -#define TK_IF 36 -#define TK_NOT 37 -#define TK_EXISTS 38 -#define TK_BLOCKS 39 -#define TK_CACHE 40 -#define TK_CACHELAST 41 -#define TK_COMP 42 -#define TK_DAYS 43 -#define TK_FSYNC 44 -#define TK_MAXROWS 45 -#define TK_MINROWS 46 -#define TK_KEEP 47 -#define TK_PRECISION 48 -#define TK_QUORUM 49 -#define TK_REPLICA 50 -#define TK_TTL 51 -#define TK_WAL 52 -#define TK_VGROUPS 53 -#define TK_SINGLE_STABLE 54 -#define TK_STREAM_MODE 55 -#define TK_TABLE 56 -#define TK_NK_LP 57 -#define TK_NK_RP 58 -#define TK_STABLE 59 -#define TK_TABLES 60 -#define TK_STABLES 61 -#define TK_USING 62 -#define TK_TAGS 63 -#define TK_NK_DOT 64 -#define TK_NK_COMMA 65 -#define TK_COMMENT 66 -#define TK_BOOL 67 -#define TK_TINYINT 68 -#define TK_SMALLINT 69 -#define TK_INT 70 -#define TK_INTEGER 71 -#define TK_BIGINT 72 -#define TK_FLOAT 73 -#define TK_DOUBLE 74 -#define TK_BINARY 75 -#define TK_TIMESTAMP 76 -#define TK_NCHAR 77 -#define TK_UNSIGNED 78 -#define TK_JSON 79 -#define TK_VARCHAR 80 -#define TK_MEDIUMBLOB 81 -#define TK_BLOB 82 -#define TK_VARBINARY 83 -#define TK_DECIMAL 84 -#define TK_SMA 85 -#define TK_MNODES 86 -#define TK_NK_FLOAT 87 -#define TK_NK_BOOL 88 -#define TK_NK_VARIABLE 89 -#define TK_BETWEEN 90 -#define TK_IS 91 -#define TK_NULL 92 -#define TK_NK_LT 93 -#define TK_NK_GT 94 -#define TK_NK_LE 95 -#define TK_NK_GE 96 -#define TK_NK_NE 97 -#define TK_NK_EQ 98 -#define TK_LIKE 99 -#define TK_MATCH 100 -#define TK_NMATCH 101 -#define TK_IN 102 -#define TK_FROM 103 -#define TK_AS 104 -#define TK_JOIN 105 -#define TK_ON 106 -#define TK_INNER 107 -#define TK_SELECT 108 -#define TK_DISTINCT 109 -#define TK_WHERE 110 -#define TK_PARTITION 111 -#define TK_BY 112 -#define TK_SESSION 113 -#define TK_STATE_WINDOW 114 -#define TK_INTERVAL 115 -#define TK_SLIDING 116 -#define TK_FILL 117 -#define TK_VALUE 118 -#define TK_NONE 119 -#define TK_PREV 120 -#define TK_LINEAR 121 -#define TK_NEXT 122 -#define TK_GROUP 123 -#define TK_HAVING 124 -#define TK_ORDER 125 -#define TK_SLIMIT 126 -#define TK_SOFFSET 127 -#define TK_LIMIT 128 -#define TK_OFFSET 129 -#define TK_ASC 130 -#define TK_DESC 131 -#define TK_NULLS 132 -#define TK_FIRST 133 -#define TK_LAST 134 +#define TK_QNODE 33 +#define TK_ON 34 +#define TK_QNODES 35 +#define TK_DATABASE 36 +#define TK_DATABASES 37 +#define TK_USE 38 +#define TK_IF 39 +#define TK_NOT 40 +#define TK_EXISTS 41 +#define TK_BLOCKS 42 +#define TK_CACHE 43 +#define TK_CACHELAST 44 +#define TK_COMP 45 +#define TK_DAYS 46 +#define TK_FSYNC 47 +#define TK_MAXROWS 48 +#define TK_MINROWS 49 +#define TK_KEEP 50 +#define TK_PRECISION 51 +#define TK_QUORUM 52 +#define TK_REPLICA 53 +#define TK_TTL 54 +#define TK_WAL 55 +#define TK_VGROUPS 56 +#define TK_SINGLE_STABLE 57 +#define TK_STREAM_MODE 58 +#define TK_TABLE 59 +#define TK_NK_LP 60 +#define TK_NK_RP 61 +#define TK_STABLE 62 +#define TK_TABLES 63 +#define TK_STABLES 64 +#define TK_USING 65 +#define TK_TAGS 66 +#define TK_NK_DOT 67 +#define TK_NK_COMMA 68 +#define TK_COMMENT 69 +#define TK_BOOL 70 +#define TK_TINYINT 71 +#define TK_SMALLINT 72 +#define TK_INT 73 +#define TK_INTEGER 74 +#define TK_BIGINT 75 +#define TK_FLOAT 76 +#define TK_DOUBLE 77 +#define TK_BINARY 78 +#define TK_TIMESTAMP 79 +#define TK_NCHAR 80 +#define TK_UNSIGNED 81 +#define TK_JSON 82 +#define TK_VARCHAR 83 +#define TK_MEDIUMBLOB 84 +#define TK_BLOB 85 +#define TK_VARBINARY 86 +#define TK_DECIMAL 87 +#define TK_SMA 88 +#define TK_INDEX 89 +#define TK_FULLTEXT 90 +#define TK_FUNCTION 91 +#define TK_INTERVAL 92 +#define TK_MNODES 93 +#define TK_NK_FLOAT 94 +#define TK_NK_BOOL 95 +#define TK_NK_VARIABLE 96 +#define TK_BETWEEN 97 +#define TK_IS 98 +#define TK_NULL 99 +#define TK_NK_LT 100 +#define TK_NK_GT 101 +#define TK_NK_LE 102 +#define TK_NK_GE 103 +#define TK_NK_NE 104 +#define TK_NK_EQ 105 +#define TK_LIKE 106 +#define TK_MATCH 107 +#define TK_NMATCH 108 +#define TK_IN 109 +#define TK_FROM 110 +#define TK_AS 111 +#define TK_JOIN 112 +#define TK_INNER 113 +#define TK_SELECT 114 +#define TK_DISTINCT 115 +#define TK_WHERE 116 +#define TK_PARTITION 117 +#define TK_BY 118 +#define TK_SESSION 119 +#define TK_STATE_WINDOW 120 +#define TK_SLIDING 121 +#define TK_FILL 122 +#define TK_VALUE 123 +#define TK_NONE 124 +#define TK_PREV 125 +#define TK_LINEAR 126 +#define TK_NEXT 127 +#define TK_GROUP 128 +#define TK_HAVING 129 +#define TK_ORDER 130 +#define TK_SLIMIT 131 +#define TK_SOFFSET 132 +#define TK_LIMIT 133 +#define TK_OFFSET 134 +#define TK_ASC 135 +#define TK_DESC 136 +#define TK_NULLS 137 +#define TK_FIRST 138 +#define TK_LAST 139 #define TK_NK_SPACE 300 #define TK_NK_COMMENT 301 diff --git a/include/dnode/snode/snode.h b/include/dnode/snode/snode.h index c9fab140cc..21a93532e0 100644 --- a/include/dnode/snode/snode.h +++ b/include/dnode/snode/snode.h @@ -80,6 +80,10 @@ int32_t sndGetLoad(SSnode *pSnode, SSnodeLoad *pLoad); */ int32_t sndProcessMsg(SSnode *pSnode, SRpcMsg *pMsg, SRpcMsg **pRsp); +int32_t sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg); + +int32_t sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg); + /** * @brief Drop a snode. * diff --git a/include/libs/function/function.h b/include/libs/function/function.h index c01e267c42..1abdca465e 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -295,19 +295,8 @@ typedef struct SMultiFunctionsDesc { int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength, bool isSuperTable); -/** - * If the given name is a valid built-in sql function, the value of true will be returned. - * @param name - * @param len - * @return - */ -int32_t qIsBuiltinFunction(const char* name, int32_t len, bool* scalarFunction); - bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId); -bool qIsAggregateFunction(const char* functionName); -bool qIsSelectivityFunction(const char* functionName); - tExprNode* exprTreeFromBinary(const void* data, size_t size); void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc); diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index 084258e48f..21d9ff83c8 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -23,6 +23,7 @@ extern "C" { #include "querynodes.h" typedef struct SDatabaseOptions { + ENodeType type; int32_t numOfBlocks; int32_t cacheBlockSize; int8_t cachelast; @@ -46,7 +47,7 @@ typedef struct SCreateDatabaseStmt { ENodeType type; char dbName[TSDB_DB_NAME_LEN]; bool ignoreExists; - SDatabaseOptions options; + SDatabaseOptions* pOptions; } SCreateDatabaseStmt; typedef struct SUseDatabaseStmt { @@ -61,6 +62,7 @@ typedef struct SDropDatabaseStmt { } SDropDatabaseStmt; typedef struct STableOptions { + ENodeType type; int32_t keep; int32_t ttl; char comments[TSDB_STB_COMMENT_LEN]; @@ -81,7 +83,7 @@ typedef struct SCreateTableStmt { bool ignoreExists; SNodeList* pCols; SNodeList* pTags; - STableOptions options; + STableOptions* pOptions; } SCreateTableStmt; typedef struct SCreateSubTableClause { @@ -155,6 +157,33 @@ typedef struct SShowStmt { char dbName[TSDB_DB_NAME_LEN]; } SShowStmt; +typedef enum EIndexType { + INDEX_TYPE_SMA = 1, + INDEX_TYPE_FULLTEXT +} EIndexType; + +typedef struct SIndexOptions { + ENodeType type; + SNodeList* pFuncs; + SNode* pInterval; + SNode* pOffset; + SNode* pSliding; +} SIndexOptions; + +typedef struct SCreateIndexStmt { + ENodeType type; + EIndexType indexType; + char indexName[TSDB_INDEX_NAME_LEN]; + char tableName[TSDB_TABLE_NAME_LEN]; + SNodeList* pCols; + SIndexOptions* pOptions; +} SCreateIndexStmt; + +typedef struct SCreateQnodeStmt { + ENodeType type; + int32_t dnodeId; +} SCreateQnodeStmt; + #ifdef __cplusplus } #endif diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 8fb52ceb85..cf34c6665a 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -67,6 +67,9 @@ typedef enum ENodeType { QUERY_NODE_SLOT_DESC, QUERY_NODE_COLUMN_DEF, QUERY_NODE_DOWNSTREAM_SOURCE, + QUERY_NODE_DATABASE_OPTIONS, + QUERY_NODE_TABLE_OPTIONS, + QUERY_NODE_INDEX_OPTIONS, // Statement nodes are used in parser and planner module. QUERY_NODE_SET_OPERATOR, @@ -93,6 +96,9 @@ typedef enum ENodeType { QUERY_NODE_SHOW_DNODES_STMT, QUERY_NODE_SHOW_VGROUPS_STMT, QUERY_NODE_SHOW_MNODES_STMT, + QUERY_NODE_SHOW_QNODES_STMT, + QUERY_NODE_CREATE_INDEX_STMT, + QUERY_NODE_CREATE_QNODE_STMT, // logic plan node QUERY_NODE_LOGIC_PLAN_SCAN, @@ -101,6 +107,7 @@ typedef enum ENodeType { QUERY_NODE_LOGIC_PLAN_PROJECT, QUERY_NODE_LOGIC_PLAN_VNODE_MODIF, QUERY_NODE_LOGIC_PLAN_EXCHANGE, + QUERY_NODE_LOGIC_PLAN_WINDOW, QUERY_NODE_LOGIC_SUBPLAN, QUERY_NODE_LOGIC_PLAN, @@ -115,6 +122,7 @@ typedef enum ENodeType { QUERY_NODE_PHYSICAL_PLAN_AGG, QUERY_NODE_PHYSICAL_PLAN_EXCHANGE, QUERY_NODE_PHYSICAL_PLAN_SORT, + QUERY_NODE_PHYSICAL_PLAN_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_DISPATCH, QUERY_NODE_PHYSICAL_PLAN_INSERT, QUERY_NODE_PHYSICAL_SUBPLAN, @@ -183,6 +191,9 @@ const char* nodesNodeName(ENodeType type); int32_t nodesNodeToString(const SNodeptr pNode, bool format, char** pStr, int32_t* pLen); int32_t nodesStringToNode(const char* pStr, SNode** pNode); +int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int32_t* pLen); +int32_t nodesStringToList(const char* pStr, SNodeList** pList); + #ifdef __cplusplus } #endif diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 717baf24cd..8871bae4e9 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -80,6 +80,24 @@ typedef struct SExchangeLogicNode { int32_t srcGroupId; } SExchangeLogicNode; +typedef enum EWindowType { + WINDOW_TYPE_INTERVAL = 1, + WINDOW_TYPE_SESSION, + WINDOW_TYPE_STATE +} EWindowType; + +typedef struct SWindowLogicNode { + SLogicNode node; + EWindowType winType; + SNodeList* pFuncs; + int64_t interval; + int64_t offset; + int64_t sliding; + int8_t intervalUnit; + int8_t slidingUnit; + SFillNode* pFill; +} SWindowLogicNode; + typedef enum ESubplanType { SUBPLAN_TYPE_MERGE = 1, SUBPLAN_TYPE_PARTIAL, @@ -187,10 +205,22 @@ typedef struct SDownstreamSourceNode { typedef struct SExchangePhysiNode { SPhysiNode node; - int32_t srcGroupId; // group id of datasource suplans + int32_t srcGroupId; // group id of datasource suplans SNodeList* pSrcEndPoints; // element is SDownstreamSource, scheduler fill by calling qSetSuplanExecutionNode } SExchangePhysiNode; +typedef struct SIntervalPhysiNode { + SPhysiNode node; + SNodeList* pExprs; // these are expression list of parameter expression of function + SNodeList* pFuncs; + int64_t interval; + int64_t offset; + int64_t sliding; + int8_t intervalUnit; + int8_t slidingUnit; + SFillNode* pFill; +} SIntervalPhysiNode; + typedef struct SDataSinkNode { ENodeType type; SDataBlockDescNode* pInputDataBlockDesc; diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 6a6d508096..fe44d8666b 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -82,6 +82,7 @@ typedef struct SValueNode { double d; char* p; } datum; + char unit; } SValueNode; typedef struct SOperatorNode { diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index bf0c963059..77838c705f 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -51,6 +51,7 @@ typedef struct SQuery { SSchema* pResSchema; SCmdMsgInfo* pCmdMsg; int32_t msgType; + bool streamQuery; } SQuery; int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery); diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index 07579e0a7d..7eb9d038a5 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -26,6 +26,7 @@ typedef struct SPlanContext { uint64_t queryId; int32_t acctId; SNode* pAstRoot; + bool streamQuery; } SPlanContext; // Create the physical plan for the query, according to the AST. diff --git a/include/libs/transport/trpc.h b/include/libs/transport/trpc.h index 8341b2f0bb..35733bcc1e 100644 --- a/include/libs/transport/trpc.h +++ b/include/libs/transport/trpc.h @@ -78,6 +78,10 @@ typedef struct SRpcInit { // call back to keep conn or not bool (*pfp)(void *parent, tmsg_t msgType); + // to support Send messages multiple times on a link + // + void* (*mfp)(void *parent, tmsg_t msgType); + void *parent; } SRpcInit; @@ -96,6 +100,9 @@ void rpcSendRecv(void *shandle, SEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp) int rpcReportProgress(void *pConn, char *pCont, int contLen); void rpcCancelRequest(int64_t rid); +// just release client conn to rpc instance, no close sock +void rpcReleaseHandle(void *handle); + void rpcRefHandle(void *handle, int8_t type); void rpcUnrefHandle(void *handle, int8_t type); diff --git a/include/os/osLocale.h b/include/os/osLocale.h index 6e313eb8cd..ddafd2e93c 100644 --- a/include/os/osLocale.h +++ b/include/os/osLocale.h @@ -17,12 +17,16 @@ #define _TD_OS_LOCALE_H_ #include "os.h" -#include "osString.h" #ifdef __cplusplus extern "C" { #endif +// If the error is in a third-party library, place this header file under the third-party library header file. +#ifndef ALLOW_FORBID_FUNC + #define setlocale SETLOCALE_FUNC_TAOS_FORBID +#endif + char *taosCharsetReplace(char *charsetstr); void taosGetSystemLocale(char *outLocale, char *outCharset); void taosSetSystemLocale(const char *inLocale, const char *inCharSet); diff --git a/include/util/taoserror.h b/include/util/taoserror.h index f93d67019d..bfb1c66e3a 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -354,6 +354,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TDB_MESSED_MSG TAOS_DEF_ERROR_CODE(0, 0x0614) #define TSDB_CODE_TDB_IVLD_TAG_VAL TAOS_DEF_ERROR_CODE(0, 0x0615) #define TSDB_CODE_TDB_NO_CACHE_LAST_ROW TAOS_DEF_ERROR_CODE(0, 0x0616) +#define TSDB_CODE_TDB_NO_SMA_INDEX_IN_META TAOS_DEF_ERROR_CODE(0, 0x0617) // query #define TSDB_CODE_QRY_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0700) diff --git a/include/util/tdef.h b/include/util/tdef.h index a53b81894a..41a61ceb55 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -345,19 +345,19 @@ typedef enum ELogicConditionType { #define TSDB_MAX_DB_QUORUM_OPTION 2 #define TSDB_DEFAULT_DB_QUORUM_OPTION 1 -#define TSDB_MIN_DB_TTL_OPTION 1 -#define TSDB_DEFAULT_DB_TTL_OPTION 0 +#define TSDB_MIN_DB_TTL_OPTION 1 +#define TSDB_DEFAULT_DB_TTL_OPTION 0 -#define TSDB_MIN_DB_SINGLE_STABLE_OPTION 0 -#define TSDB_MAX_DB_SINGLE_STABLE_OPTION 1 -#define TSDB_DEFAULT_DB_SINGLE_STABLE_OPTION 0 +#define TSDB_MIN_DB_SINGLE_STABLE_OPTION 0 +#define TSDB_MAX_DB_SINGLE_STABLE_OPTION 1 +#define TSDB_DEFAULT_DB_SINGLE_STABLE_OPTION 0 -#define TSDB_MIN_DB_STREAM_MODE_OPTION 0 -#define TSDB_MAX_DB_STREAM_MODE_OPTION 1 -#define TSDB_DEFAULT_DB_STREAM_MODE_OPTION 0 +#define TSDB_MIN_DB_STREAM_MODE_OPTION 0 +#define TSDB_MAX_DB_STREAM_MODE_OPTION 1 +#define TSDB_DEFAULT_DB_STREAM_MODE_OPTION 0 -#define TSDB_MAX_JOIN_TABLE_NUM 10 -#define TSDB_MAX_UNION_CLAUSE 5 +#define TSDB_MAX_JOIN_TABLE_NUM 10 +#define TSDB_MAX_UNION_CLAUSE 5 #define TSDB_MIN_DB_UPDATE 0 #define TSDB_MAX_DB_UPDATE 2 @@ -445,6 +445,9 @@ typedef struct { #define TMQ_SEPARATOR ':' +#define SND_UNIQUE_THREAD_NUM 2 +#define SND_SHARED_THREAD_NUM 2 + #ifdef __cplusplus } #endif diff --git a/include/util/tjson.h b/include/util/tjson.h index 335ff0d4ba..1218caae35 100644 --- a/include/util/tjson.h +++ b/include/util/tjson.h @@ -25,6 +25,7 @@ extern "C" { typedef void SJson; SJson* tjsonCreateObject(); +SJson* tjsonCreateArray(); void tjsonDelete(SJson* pJson); SJson* tjsonAddArrayToObject(SJson* pJson, const char* pName); diff --git a/include/util/tuuid.h b/include/util/tuuid.h new file mode 100644 index 0000000000..315c2ad497 --- /dev/null +++ b/include/util/tuuid.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ +#include "os.h" +#include "taoserror.h" +#include "thash.h" + +/** + * Generate an non-negative signed 32bit id + *+------------+-----+-----------+---------------+ + *| uid|localIp| PId | timestamp | serial number | + *+------------+-----+-----------+---------------+ + *| 6bit |6bit | 12bit | 8bit | + *+------------+-----+-----------+---------------+ + * @return + */ +int32_t tGenIdPI32(void); + +/** + * Generate an non-negative signed 64bit id + *+------------+-----+-----------+---------------+ + *| uid|localIp| PId | timestamp | serial number | + *+------------+-----+-----------+---------------+ + *| 12bit |12bit|24bit |16bit | + *+------------+-----+-----------+---------------+ + * @return + */ +int64_t tGenIdPI64(void); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 321e8ab77b..b672c9bb47 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -21,6 +21,7 @@ extern "C" { #endif #include "parser.h" +#include "planner.h" #include "query.h" #include "taos.h" #include "tcommon.h" @@ -229,6 +230,7 @@ void setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32_t int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj** pRequest); int32_t parseSql(SRequestObj* pRequest, SQuery** pQuery); +int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList); // --- heartbeat // global, called by mgmt diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 13a4fc70f7..fc97f4113c 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -1,8 +1,6 @@ #include "clientInt.h" #include "clientLog.h" -#include "parser.h" -#include "planner.h" #include "scheduler.h" #include "tdatablock.h" #include "tdef.h" @@ -195,11 +193,7 @@ int32_t execDdlQuery(SRequestObj* pRequest, SQuery* pQuery) { int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList) { pRequest->type = pQuery->msgType; SPlanContext cxt = { .queryId = pRequest->requestId, .pAstRoot = pQuery->pRoot, .acctId = pRequest->pTscObj->acctId }; - int32_t code = qCreateQueryPlan(&cxt, pPlan, pNodeList); - if (code != 0) { - return code; - } - return code; + return qCreateQueryPlan(&cxt, pPlan, pNodeList); } void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t numOfCols) { @@ -215,7 +209,6 @@ void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t } } - int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) { void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter; diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 846329f0f4..b3f71c1075 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -459,7 +459,7 @@ void tmq_conf_set_offset_commit_cb(tmq_conf_t* conf, tmq_commit_cb* cb) { conf-> TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, int sqlLen) { STscObj* pTscObj = (STscObj*)taos; SRequestObj* pRequest = NULL; - SQuery* pQueryNode = NULL; + SQuery* pQueryNode = NULL; char* pStr = NULL; terrno = TSDB_CODE_SUCCESS; @@ -482,21 +482,19 @@ TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, i } tscDebug("start to create topic, %s", topicName); -#if 0 + CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return); CHECK_CODE_GOTO(parseSql(pRequest, &pQueryNode), _return); - SQueryStmtInfo* pQueryStmtInfo = (SQueryStmtInfo*)pQueryNode; - pQueryStmtInfo->info.continueQuery = true; + pQueryNode->streamQuery = true; // todo check for invalid sql statement and return with error code SSchema* schema = NULL; int32_t numOfCols = 0; - CHECK_CODE_GOTO(qCreateQueryDag(pQueryNode, &pRequest->body.pDag, &schema, &numOfCols, NULL, pRequest->requestId), - _return); + CHECK_CODE_GOTO(getPlan(pRequest, pQueryNode, &pRequest->body.pDag, NULL), _return); - pStr = qDagToString(pRequest->body.pDag); + pStr = qQueryPlanToString(pRequest->body.pDag); if (pStr == NULL) { goto _return; } @@ -506,7 +504,7 @@ TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, i // The topic should be related to a database that the queried table is belonged to. SName name = {0}; char dbName[TSDB_DB_FNAME_LEN] = {0}; - tNameGetFullDbName(&((SQueryStmtInfo*)pQueryNode)->pTableMetaInfo[0]->name, dbName); + // tNameGetFullDbName(&((SQueryStmtInfo*)pQueryNode)->pTableMetaInfo[0]->name, dbName); tNameFromString(&name, dbName, T_NAME_ACCT | T_NAME_DB); tNameFromString(&name, topicName, T_NAME_TABLE); @@ -538,7 +536,7 @@ TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, i asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo); tsem_wait(&pRequest->body.rspSem); -#endif + _return: qDestroyQuery(pQueryNode); /*if (sendInfo != NULL) {*/ diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 4070224ab8..7e4f1d9025 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -1059,10 +1059,10 @@ int32_t blockDataSort_rv(SSDataBlock* pDataBlock, SArray* pOrderInfo, bool nullF // destroyTupleIndex(index); } -void blockDataClearup(SSDataBlock* pDataBlock, bool hasVarCol) { +void blockDataClearup(SSDataBlock* pDataBlock) { pDataBlock->info.rows = 0; - if (hasVarCol) { + if (pDataBlock->info.hasVarCol) { for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) { SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i); @@ -1148,7 +1148,9 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock) { SSDataBlock* pBlock = calloc(1, sizeof(SSDataBlock)); pBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData)); + pBlock->info.numOfCols = numOfCols; + pBlock->info.hasVarCol = pDataBlock->info.hasVarCol; for(int32_t i = 0; i < numOfCols; ++i) { SColumnInfoData colInfo = {0}; diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index ff853145fa..f26f19f3b2 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -2666,7 +2666,6 @@ int32_t tSerializeSCMCreateStreamReq(void *buf, int32_t bufLen, const SCMCreateS if (tEncodeCStr(&encoder, pReq->sql) < 0) return -1; if (tEncodeCStr(&encoder, pReq->physicalPlan) < 0) return -1; if (tEncodeCStr(&encoder, pReq->logicalPlan) < 0) return -1; - tEndEncode(&encoder); int32_t tlen = encoder.pos; diff --git a/source/dnode/mgmt/container/src/dndWorker.c b/source/dnode/mgmt/container/src/dndWorker.c index 2c89c2a20a..35bcb4f0a7 100644 --- a/source/dnode/mgmt/container/src/dndWorker.c +++ b/source/dnode/mgmt/container/src/dndWorker.c @@ -111,4 +111,4 @@ int32_t dndWriteMsgToWorker(SDnodeWorker *pWorker, void *pCont, int32_t contLen) } return 0; -} \ No newline at end of file +} diff --git a/source/dnode/mgmt/snode/inc/smInt.h b/source/dnode/mgmt/snode/inc/smInt.h index 26d5792a17..a4874dda08 100644 --- a/source/dnode/mgmt/snode/inc/smInt.h +++ b/source/dnode/mgmt/snode/inc/smInt.h @@ -26,11 +26,11 @@ typedef struct SSnodeMgmt { int32_t refCount; int8_t deployed; int8_t dropped; + int8_t uniqueWorkerInUse; SSnode *pSnode; SRWLatch latch; - SDnodeWorker writeWorker; - SProcObj *pProcess; - bool singleProc; + SArray *uniqueWorkers; // SArray + SDnodeWorker sharedWorker; } SSnodeMgmt; void smGetMgmtFp(SMgmtWrapper *pMgmt); diff --git a/source/dnode/mgmt/snode/src/smMgmt.c b/source/dnode/mgmt/snode/src/smMgmt.c index 9e3d711dc5..40e7a7ca93 100644 --- a/source/dnode/mgmt/snode/src/smMgmt.c +++ b/source/dnode/mgmt/snode/src/smMgmt.c @@ -20,7 +20,21 @@ // #include "dndWorker.h" #if 0 -static void dndProcessSnodeQueue(SDnode *pDnode, SRpcMsg *pMsg); + +typedef struct { + int32_t vgId; + int32_t refCount; + int32_t snVersion; + int8_t dropped; + char *path; + SSnode *pImpl; + STaosQueue *pSharedQ; + STaosQueue *pUniqueQ; +} SSnodeObj; + +static void dndProcessSnodeSharedQueue(SDnode *pDnode, SRpcMsg *pMsg); + +static void dndProcessSnodeUniqueQueue(SDnode *pDnode, STaosQall *qall, int32_t numOfMsgs); static SSnode *dndAcquireSnode(SDnode *pDnode) { SSnodeMgmt *pMgmt = &pDnode->smgmt; @@ -153,8 +167,21 @@ static int32_t dndWriteSnodeFile(SDnode *pDnode) { static int32_t dndStartSnodeWorker(SDnode *pDnode) { SSnodeMgmt *pMgmt = &pDnode->smgmt; - if (dndInitWorker(pDnode, &pMgmt->writeWorker, DND_WORKER_SINGLE, "snode-write", 0, 1, dndProcessSnodeQueue) != 0) { - dError("failed to start snode write worker since %s", terrstr()); + pMgmt->uniqueWorkers = taosArrayInit(0, sizeof(void *)); + for (int32_t i = 0; i < SND_UNIQUE_THREAD_NUM; i++) { + SDnodeWorker *pUniqueWorker = malloc(sizeof(SDnodeWorker)); + if (pUniqueWorker == NULL) { + return -1; + } + if (dndInitWorker(pDnode, pUniqueWorker, DND_WORKER_MULTI, "snode-unique", 1, 1, dndProcessSnodeSharedQueue) != 0) { + dError("failed to start snode unique worker since %s", terrstr()); + return -1; + } + taosArrayPush(pMgmt->uniqueWorkers, &pUniqueWorker); + } + if (dndInitWorker(pDnode, &pMgmt->sharedWorker, DND_WORKER_SINGLE, "snode-shared", SND_SHARED_THREAD_NUM, + SND_SHARED_THREAD_NUM, dndProcessSnodeSharedQueue)) { + dError("failed to start snode shared worker since %s", terrstr()); return -1; } @@ -170,9 +197,13 @@ static void dndStopSnodeWorker(SDnode *pDnode) { while (pMgmt->refCount > 0) { taosMsleep(10); - } + } - dndCleanupWorker(&pMgmt->writeWorker); + for (int32_t i = 0; i < taosArrayGetSize(pMgmt->uniqueWorkers); i++) { + SDnodeWorker *worker = taosArrayGetP(pMgmt->uniqueWorkers, i); + dndCleanupWorker(worker); + } + taosArrayDestroy(pMgmt->uniqueWorkers); } static void dndBuildSnodeOption(SDnode *pDnode, SSnodeOpt *pOption) { @@ -293,17 +324,36 @@ int32_t smProcessDropReq(SDnode *pDnode, SRpcMsg *pReq) { } } -static void dndProcessSnodeQueue(SDnode *pDnode, SRpcMsg *pMsg) { +static void dndProcessSnodeUniqueQueue(SDnode *pDnode, STaosQall *qall, int32_t numOfMsgs) { SSnodeMgmt *pMgmt = &pDnode->smgmt; - SRpcMsg *pRsp = NULL; int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED; SSnode *pSnode = dndAcquireSnode(pDnode); if (pSnode != NULL) { - code = sndProcessMsg(pSnode, pMsg, &pRsp); + for (int32_t i = 0; i < numOfMsgs; i++) { + SRpcMsg *pMsg = NULL; + taosGetQitem(qall, (void **)&pMsg); + + sndProcessUMsg(pSnode, pMsg); + + rpcFreeCont(pMsg->pCont); + taosFreeQitem(pMsg); + } + } + dndReleaseSnode(pDnode, pSnode); +} + +static void dndProcessSnodeSharedQueue(SDnode *pDnode, SRpcMsg *pMsg) { + SSnodeMgmt *pMgmt = &pDnode->smgmt; + int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED; + + SSnode *pSnode = dndAcquireSnode(pDnode); + if (pSnode != NULL) { + code = sndProcessSMsg(pSnode, pMsg); } dndReleaseSnode(pDnode, pSnode); +#if 0 if (pMsg->msgType & 1u) { if (pRsp != NULL) { pRsp->ahandle = pMsg->ahandle; @@ -315,11 +365,58 @@ static void dndProcessSnodeQueue(SDnode *pDnode, SRpcMsg *pMsg) { rpcSendResponse(&rpcRsp); } } +#endif rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } +static FORCE_INLINE int32_t dndGetSWIdFromMsg(SRpcMsg *pMsg) { + SMsgHead *pHead = pMsg->pCont; + pHead->streamTaskId = htonl(pHead->streamTaskId); + return pHead->streamTaskId % SND_UNIQUE_THREAD_NUM; +} + +static void dndWriteSnodeMsgToWorkerByMsg(SDnode *pDnode, SRpcMsg *pMsg) { + int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED; + + SSnode *pSnode = dndAcquireSnode(pDnode); + if (pSnode != NULL) { + int32_t index = dndGetSWIdFromMsg(pMsg); + SDnodeWorker *pWorker = taosArrayGetP(pDnode->smgmt.uniqueWorkers, index); + code = dndWriteMsgToWorker(pWorker, pMsg, sizeof(SRpcMsg)); + } + + dndReleaseSnode(pDnode, pSnode); + + if (code != 0) { + if (pMsg->msgType & 1u) { + SRpcMsg rsp = {.handle = pMsg->handle, .ahandle = pMsg->ahandle, .code = code}; + rpcSendResponse(&rsp); + } + rpcFreeCont(pMsg->pCont); + } +} + +static void dndWriteSnodeMsgToMgmtWorker(SDnode *pDnode, SRpcMsg *pMsg) { + int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED; + + SSnode *pSnode = dndAcquireSnode(pDnode); + if (pSnode != NULL) { + SDnodeWorker *pWorker = taosArrayGet(pDnode->smgmt.uniqueWorkers, 0); + code = dndWriteMsgToWorker(pWorker, pMsg, sizeof(SRpcMsg)); + } + dndReleaseSnode(pDnode, pSnode); + + if (code != 0) { + if (pMsg->msgType & 1u) { + SRpcMsg rsp = {.handle = pMsg->handle, .ahandle = pMsg->ahandle, .code = code}; + rpcSendResponse(&rsp); + } + rpcFreeCont(pMsg->pCont); + } +} + static void dndWriteSnodeMsgToWorker(SDnode *pDnode, SDnodeWorker *pWorker, SRpcMsg *pMsg) { int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED; @@ -338,8 +435,16 @@ static void dndWriteSnodeMsgToWorker(SDnode *pDnode, SDnodeWorker *pWorker, SRpc } } -void dndProcessSnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { - dndWriteSnodeMsgToWorker(pDnode, &pDnode->smgmt.writeWorker, pMsg); +void dndProcessSnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { + dndWriteSnodeMsgToMgmtWorker(pDnode, pMsg); +} + +void dndProcessSnodeUniqueMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { + dndWriteSnodeMsgToWorkerByMsg(pDnode, pMsg); +} + +void dndProcessSnodeSharedMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { + dndWriteSnodeMsgToWorker(pDnode, &pDnode->smgmt.sharedWorker, pMsg); } int32_t dndInitSnode(SDnode *pDnode) { diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index fe40aa64c4..859bf6c659 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -679,6 +679,12 @@ static FORCE_INLINE void* tDecodeSMqConsumerObj(void* buf, SMqConsumerObj* pCons return buf; } +typedef struct { + int32_t taskId; + int32_t level; + SSubplan* plan; +} SStreamTaskMeta; + typedef struct { char name[TSDB_TOPIC_FNAME_LEN]; char db[TSDB_DB_FNAME_LEN]; @@ -687,12 +693,14 @@ typedef struct { int64_t uid; int64_t dbUid; int32_t version; + int32_t vgNum; SRWLatch lock; int8_t status; // int32_t sqlLen; - char* sql; - char* logicalPlan; - char* physicalPlan; + char* sql; + char* logicalPlan; + char* physicalPlan; + SArray* tasks; // SArray> } SStreamObj; int32_t tEncodeSStreamObj(SCoder* pEncoder, const SStreamObj* pObj); diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index 1694745f96..6f5a2acd21 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -1292,11 +1292,11 @@ static int32_t mndGetDbMeta(SMndMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta pSchema[cols].bytes = pShow->bytes[cols]; cols++; - pShow->bytes[cols] = 1; - pSchema[cols].type = TSDB_DATA_TYPE_TINYINT; - strcpy(pSchema[cols].name, "update"); - pSchema[cols].bytes = pShow->bytes[cols]; - cols++; +// pShow->bytes[cols] = 1; +// pSchema[cols].type = TSDB_DATA_TYPE_TINYINT; +// strcpy(pSchema[cols].name, "update"); +// pSchema[cols].bytes = pShow->bytes[cols]; +// cols++; pMeta->numOfColumns = cols; pShow->numOfColumns = cols; @@ -1432,9 +1432,9 @@ static int32_t mndRetrieveDbs(SMndMsg *pReq, SShowObj *pShow, char *data, int32_ STR_WITH_SIZE_TO_VARSTR(pWrite, prec, 2); cols++; - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int8_t *)pWrite = pDb->cfg.update; - cols++; +// pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; +// *(int8_t *)pWrite = pDb->cfg.update; +// cols++; numOfRows++; sdbRelease(pSdb, pDb); diff --git a/source/dnode/mnode/impl/src/mndScheduler.c b/source/dnode/mnode/impl/src/mndScheduler.c index e827810cc9..855e244daa 100644 --- a/source/dnode/mnode/impl/src/mndScheduler.c +++ b/source/dnode/mnode/impl/src/mndScheduler.c @@ -21,6 +21,7 @@ #include "mndOffset.h" #include "mndShow.h" #include "mndStb.h" +#include "mndStream.h" #include "mndSubscribe.h" #include "mndTopic.h" #include "mndTrans.h" @@ -28,10 +29,84 @@ #include "mndVgroup.h" #include "tcompare.h" #include "tname.h" +#include "tuuid.h" + +int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream) { + SSdb* pSdb = pMnode->pSdb; + SVgObj* pVgroup = NULL; + SQueryPlan* pPlan = qStringToQueryPlan(pStream->physicalPlan); + if (pPlan == NULL) { + terrno = TSDB_CODE_QRY_INVALID_INPUT; + return -1; + } + ASSERT(pStream->vgNum == 0); + + int32_t levelNum = LIST_LENGTH(pPlan->pSubplans); + pStream->tasks = taosArrayInit(levelNum, sizeof(SArray)); + + for (int32_t i = 0; i < levelNum; i++) { + SArray* taskOneLevel = taosArrayInit(0, sizeof(SStreamTaskMeta)); + SNodeListNode* inner = nodesListGetNode(pPlan->pSubplans, i); + int32_t opNum = LIST_LENGTH(inner->pNodeList); + ASSERT(opNum == 1); + + SSubplan* plan = nodesListGetNode(inner->pNodeList, 0); + if (i == 0) { + ASSERT(plan->type == SUBPLAN_TYPE_SCAN); + void* pIter = NULL; + while (1) { + pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup); + if (pIter == NULL) break; + if (pVgroup->dbUid != pStream->dbUid) { + sdbRelease(pSdb, pVgroup); + continue; + } + + pStream->vgNum++; + plan->execNode.nodeId = pVgroup->vgId; + plan->execNode.epSet = mndGetVgroupEpset(pMnode, pVgroup); + SStreamTaskMeta task = { + .taskId = tGenIdPI32(), + .level = i, + .plan = plan, + }; + // send to vnode + taosArrayPush(taskOneLevel, &task); + } + } else if (plan->subplanType == SUBPLAN_TYPE_SCAN) { + // duplicatable + + int32_t parallel = 0; + // if no snode, parallel set to fetch thread num in vnode + + // if has snode, set to shared thread num in snode + parallel = SND_SHARED_THREAD_NUM; + + for (int32_t j = 0; j < parallel; j++) { + SStreamTaskMeta task = { + .taskId = tGenIdPI32(), + .level = i, + .plan = plan, + }; + taosArrayPush(taskOneLevel, &task); + } + } else { + // not duplicatable + SStreamTaskMeta task = { + .taskId = tGenIdPI32(), + .level = i, + .plan = plan, + }; + taosArrayPush(taskOneLevel, &task); + } + taosArrayPush(pStream->tasks, taskOneLevel); + } + return 0; +} int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscribeObj* pSub) { - SSdb* pSdb = pMnode->pSdb; - SVgObj* pVgroup = NULL; + SSdb* pSdb = pMnode->pSdb; + SVgObj* pVgroup = NULL; SQueryPlan* pPlan = qStringToQueryPlan(pTopic->physicalPlan); if (pPlan == NULL) { terrno = TSDB_CODE_QRY_INVALID_INPUT; diff --git a/source/dnode/mnode/impl/src/mnode.c b/source/dnode/mnode/impl/src/mnode.c index 8ec1b959fb..729c09bce5 100644 --- a/source/dnode/mnode/impl/src/mnode.c +++ b/source/dnode/mnode/impl/src/mnode.c @@ -30,6 +30,7 @@ #include "mndShow.h" #include "mndSnode.h" #include "mndStb.h" +#include "mndStream.h" #include "mndSubscribe.h" #include "mndSync.h" #include "mndTelem.h" @@ -214,6 +215,7 @@ static int32_t mndInitSteps(SMnode *pMnode) { if (mndAllocStep(pMnode, "mnode-user", mndInitUser, mndCleanupUser) != 0) return -1; if (mndAllocStep(pMnode, "mnode-auth", mndInitAuth, mndCleanupAuth) != 0) return -1; if (mndAllocStep(pMnode, "mnode-acct", mndInitAcct, mndCleanupAcct) != 0) return -1; + if (mndAllocStep(pMnode, "mnode-stream", mndInitStream, mndCleanupStream) != 0) return -1; if (mndAllocStep(pMnode, "mnode-topic", mndInitTopic, mndCleanupTopic) != 0) return -1; if (mndAllocStep(pMnode, "mnode-consumer", mndInitConsumer, mndCleanupConsumer) != 0) return -1; if (mndAllocStep(pMnode, "mnode-subscribe", mndInitSubscribe, mndCleanupSubscribe) != 0) return -1; diff --git a/source/dnode/mnode/impl/test/db/db.cpp b/source/dnode/mnode/impl/test/db/db.cpp index 9dbc1be4e9..0282663b17 100644 --- a/source/dnode/mnode/impl/test/db/db.cpp +++ b/source/dnode/mnode/impl/test/db/db.cpp @@ -27,7 +27,7 @@ Testbase MndTestDb::test; TEST_F(MndTestDb, 01_ShowDb) { test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); - CHECK_META("show databases", 18); + CHECK_META("show databases", 17); CHECK_SCHEMA(0, TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN - 1 + VARSTR_HEADER_SIZE, "name"); CHECK_SCHEMA(1, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); CHECK_SCHEMA(2, TSDB_DATA_TYPE_SMALLINT, 2, "vgroups"); @@ -45,7 +45,7 @@ TEST_F(MndTestDb, 01_ShowDb) { CHECK_SCHEMA(14, TSDB_DATA_TYPE_TINYINT, 1, "comp"); CHECK_SCHEMA(15, TSDB_DATA_TYPE_TINYINT, 1, "cachelast"); CHECK_SCHEMA(16, TSDB_DATA_TYPE_BINARY, 3 + VARSTR_HEADER_SIZE, "precision"); - CHECK_SCHEMA(17, TSDB_DATA_TYPE_TINYINT, 1, "update"); +// CHECK_SCHEMA(17, TSDB_DATA_TYPE_TINYINT, 1, "update"); test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 0); @@ -85,7 +85,7 @@ TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) { } test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); - CHECK_META("show databases", 18); + CHECK_META("show databases", 17); test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); @@ -173,7 +173,7 @@ TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) { test.Restart(); test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); - CHECK_META("show databases", 18); + CHECK_META("show databases", 17); test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); @@ -215,7 +215,7 @@ TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) { } test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); - CHECK_META("show databases", 18); + CHECK_META("show databases", 17); test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 0); @@ -255,7 +255,7 @@ TEST_F(MndTestDb, 03_Create_Use_Restart_Use_Db) { } test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); - CHECK_META("show databases", 18); + CHECK_META("show databases", 17); test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); diff --git a/source/dnode/snode/inc/sndInt.h b/source/dnode/snode/inc/sndInt.h index 5851e18478..3fe816845d 100644 --- a/source/dnode/snode/inc/sndInt.h +++ b/source/dnode/snode/inc/sndInt.h @@ -30,47 +30,48 @@ extern "C" { #endif enum { - STREAM_STATUS__READY = 1, + STREAM_STATUS__RUNNING = 1, STREAM_STATUS__STOPPED, STREAM_STATUS__CREATING, STREAM_STATUS__STOPING, - STREAM_STATUS__RESUMING, + STREAM_STATUS__RESTORING, STREAM_STATUS__DELETING, }; enum { - STREAM_RUNNER__RUNNING = 1, - STREAM_RUNNER__STOP, + STREAM_TASK_STATUS__RUNNING = 1, + STREAM_TASK_STATUS__STOP, }; +typedef struct { + SHashObj* pHash; // taskId -> streamTask +} SStreamMeta; + typedef struct SSnode { - SSnodeOpt cfg; + SStreamMeta* pMeta; + SSnodeOpt cfg; } SSnode; typedef struct { int64_t streamId; + int32_t taskId; int32_t IdxInLevel; int32_t level; -} SStreamInfo; +} SStreamTaskInfo; typedef struct { - SStreamInfo meta; - int8_t status; - void* executor; - STaosQueue* queue; - void* stateStore; + SStreamTaskInfo meta; + int8_t status; + void* executor; + void* stateStore; // storage handle -} SStreamRunner; +} SStreamTask; -typedef struct { - SHashObj* pHash; -} SStreamMeta; +int32_t sndCreateTask(); +int32_t sndDropTaskOfStream(int64_t streamId); -int32_t sndCreateStream(); -int32_t sndDropStream(); - -int32_t sndStopStream(); -int32_t sndResumeStream(); +int32_t sndStopTaskOfStream(int64_t streamId); +int32_t sndResumeTaskOfStream(int64_t streamId); #ifdef __cplusplus } diff --git a/source/dnode/snode/src/snode.c b/source/dnode/snode/src/snode.c index 01500fbc54..74e41d45c5 100644 --- a/source/dnode/snode/src/snode.c +++ b/source/dnode/snode/src/snode.c @@ -14,6 +14,7 @@ */ #include "sndInt.h" +#include "tuuid.h" SSnode *sndOpen(const char *path, const SSnodeOpt *pOption) { SSnode *pSnode = calloc(1, sizeof(SSnode)); @@ -31,3 +32,25 @@ int32_t sndProcessMsg(SSnode *pSnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { } void sndDestroy(const char *path) {} + +static int32_t sndDeployTask(SSnode *pSnode, SRpcMsg *pMsg) { + SStreamTask *task = malloc(sizeof(SStreamTask)); + if (task == NULL) { + return -1; + } + task->meta.taskId = tGenIdPI32(); + taosHashPut(pSnode->pMeta->pHash, &task->meta.taskId, sizeof(int32_t), &task, sizeof(void *)); + return 0; +} + +int32_t sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg) { + // stream deployment + // stream stop/resume + // operator exec + return 0; +} + +int32_t sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg) { + // operator exec + return 0; +} diff --git a/source/dnode/vnode/inc/tsdb.h b/source/dnode/vnode/inc/tsdb.h index e67e0cae4b..87edfb8dde 100644 --- a/source/dnode/vnode/inc/tsdb.h +++ b/source/dnode/vnode/inc/tsdb.h @@ -95,6 +95,7 @@ int tsdbCommit(STsdb *pTsdb); * @return int32_t */ int32_t tsdbInsertTSmaData(STsdb *pTsdb, char *msg); +int32_t tsdbUpdateSmaWindow(STsdb *pTsdb, int8_t smaType, char *msg); /** * @brief Insert RSma(Time-range-wise Rollup SMA) data. @@ -105,6 +106,12 @@ int32_t tsdbInsertTSmaData(STsdb *pTsdb, char *msg); */ int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg); +// TODO: This is the basic params, and should wrap the params to a queryHandle. +int32_t tsdbGetTSmaData(STsdb *pTsdb, STSmaDataWrapper *pData, int64_t indexUid, int64_t interval, + int8_t intervalUnit, tb_uid_t tableUid, col_id_t colId, TSKEY querySkey, + int32_t nMaxResult); + + // STsdbCfg int tsdbOptionsInit(STsdbCfg *); void tsdbOptionsClear(STsdbCfg *); diff --git a/source/dnode/vnode/src/inc/tsdbDBDef.h b/source/dnode/vnode/src/inc/tsdbDBDef.h new file mode 100644 index 0000000000..2e37b0ba45 --- /dev/null +++ b/source/dnode/vnode/src/inc/tsdbDBDef.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_TSDB_DB_DEF_H_ +#define _TD_TSDB_DB_DEF_H_ + +#include "db.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SDBFile SDBFile; +typedef DB_ENV* TDBEnv; + +struct SDBFile { + DB* pDB; + char* path; +}; + +int32_t tsdbOpenDBF(TDBEnv pEnv, SDBFile* pDBF); +void tsdbCloseDBF(SDBFile* pDBF); +int32_t tsdbOpenBDBEnv(DB_ENV** ppEnv, const char* path); +void tsdbCloseBDBEnv(DB_ENV* pEnv); +int32_t tsdbSaveSmaToDB(SDBFile* pDBF, void* key, uint32_t keySize, void* data, uint32_t dataSize); +void* tsdbGetSmaDataByKey(SDBFile* pDBF, void* key, uint32_t keySize, uint32_t* valueSize); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_TSDB_DB_DEF_H_*/ diff --git a/source/dnode/vnode/src/inc/tsdbDef.h b/source/dnode/vnode/src/inc/tsdbDef.h index 1451ac9685..6f91b4d3ab 100644 --- a/source/dnode/vnode/src/inc/tsdbDef.h +++ b/source/dnode/vnode/src/inc/tsdbDef.h @@ -27,6 +27,7 @@ #include "ttime.h" #include "tsdb.h" +#include "tsdbDBDef.h" #include "tsdbCommit.h" #include "tsdbFS.h" #include "tsdbFile.h" @@ -37,12 +38,15 @@ #include "tsdbReadImpl.h" #include "tsdbSma.h" + #ifdef __cplusplus extern "C" { #endif struct STsdb { int32_t vgId; + bool repoLocked; + pthread_mutex_t mutex; char * path; STsdbCfg config; STsdbMemTable * mem; @@ -52,12 +56,17 @@ struct STsdb { STsdbFS * fs; SMeta * pMeta; STfs * pTfs; - SSmaStat * pSmaStat; + SSmaEnv * pTSmaEnv; + SSmaEnv * pRSmaEnv; }; -#define REPO_ID(r) ((r)->vgId) -#define REPO_CFG(r) (&(r)->config) -#define REPO_FS(r) (r)->fs +#define REPO_ID(r) ((r)->vgId) +#define REPO_CFG(r) (&(r)->config) +#define REPO_FS(r) (r)->fs +#define IS_REPO_LOCKED(r) (r)->repoLocked + +int tsdbLockRepo(STsdb *pTsdb); +int tsdbUnlockRepo(STsdb *pTsdb); static FORCE_INLINE STSchema *tsdbGetTableSchemaImpl(STable *pTable, bool lock, bool copy, int32_t version) { return pTable->pSchema; diff --git a/source/dnode/vnode/src/inc/tsdbFile.h b/source/dnode/vnode/src/inc/tsdbFile.h index 5cc8cc045e..e65ef72623 100644 --- a/source/dnode/vnode/src/inc/tsdbFile.h +++ b/source/dnode/vnode/src/inc/tsdbFile.h @@ -329,21 +329,23 @@ static FORCE_INLINE int tsdbCopyDFile(SDFile* pSrc, SDFile* pDest) { // =============== SDFileSet typedef struct { int fid; - int8_t state; // -128~127 - uint8_t ver; // 0~255, DFileSet version + int8_t state; // -128~127 + uint8_t ver; // 0~255, DFileSet version uint16_t reserve; SDFile files[TSDB_FILE_MAX]; } SDFileSet; typedef struct { - int fid; - int8_t state; - uint8_t ver; + int fid; + int8_t state; + uint8_t ver; + uint16_t reserve; #if 0 SDFInfo info; #endif STfsFile f; TdFilePtr pFile; + } SSFile; // files split by days with fid #define TSDB_LATEST_FSET_VER 0 diff --git a/source/dnode/vnode/src/inc/tsdbSma.h b/source/dnode/vnode/src/inc/tsdbSma.h index 7fceb580d6..649b5a2d47 100644 --- a/source/dnode/vnode/src/inc/tsdbSma.h +++ b/source/dnode/vnode/src/inc/tsdbSma.h @@ -17,27 +17,29 @@ #define _TD_TSDB_SMA_H_ typedef struct SSmaStat SSmaStat; +typedef struct SSmaEnv SSmaEnv; -// insert/update interface -int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, char *msg); -int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg); +struct SSmaEnv { + pthread_rwlock_t lock; + TDBEnv dbEnv; + char * path; + SSmaStat * pStat; +}; +#define SMA_ENV_LOCK(env) ((env)->lock) +#define SMA_ENV_ENV(env) ((env)->dbEnv) +#define SMA_ENV_PATH(env) ((env)->path) +#define SMA_ENV_STAT(env) ((env)->pStat) +#define SMA_ENV_STAT_ITEMS(env) ((env)->pStat->smaStatItems) -// query interface -// TODO: This is the basic params, and should wrap the params to a queryHandle. -int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, STimeWindow *queryWin, int32_t nMaxResult); - -// management interface -int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg); -int32_t tsdbDestroySmaState(SSmaStat *pSmaStat); +void tsdbDestroySmaEnv(SSmaEnv *pSmaEnv); +void *tsdbFreeSmaEnv(SSmaEnv *pSmaEnv); #if 0 int32_t tsdbGetTSmaStatus(STsdb *pTsdb, STSma *param, void *result); int32_t tsdbRemoveTSmaData(STsdb *pTsdb, STSma *param, STimeWindow *pWin); #endif // internal func - - static FORCE_INLINE int32_t tsdbEncodeTSmaKey(tb_uid_t tableUid, col_id_t colId, TSKEY tsKey, void **pData) { int32_t len = 0; len += taosEncodeFixedI64(pData, tableUid); @@ -46,4 +48,31 @@ static FORCE_INLINE int32_t tsdbEncodeTSmaKey(tb_uid_t tableUid, col_id_t colId, return len; } +static FORCE_INLINE int tsdbRLockSma(SSmaEnv *pEnv) { + int code = pthread_rwlock_rdlock(&(pEnv->lock)); + if (code != 0) { + terrno = TAOS_SYSTEM_ERROR(code); + return -1; + } + return 0; +} + +static FORCE_INLINE int tsdbWLockSma(SSmaEnv *pEnv) { + int code = pthread_rwlock_wrlock(&(pEnv->lock)); + if (code != 0) { + terrno = TAOS_SYSTEM_ERROR(code); + return -1; + } + return 0; +} + +static FORCE_INLINE int tsdbUnLockSma(SSmaEnv *pEnv) { + int code = pthread_rwlock_unlock(&(pEnv->lock)); + if (code != 0) { + terrno = TAOS_SYSTEM_ERROR(code); + return -1; + } + return 0; +} + #endif /* _TD_TSDB_SMA_H_ */ \ No newline at end of file diff --git a/source/dnode/vnode/src/meta/metaBDBImpl.c b/source/dnode/vnode/src/meta/metaBDBImpl.c index d9af526c2a..a729288e34 100644 --- a/source/dnode/vnode/src/meta/metaBDBImpl.c +++ b/source/dnode/vnode/src/meta/metaBDBImpl.c @@ -231,30 +231,31 @@ int metaSaveSmaToDB(SMeta *pMeta, STSma *pSmaCfg) { void *pBuf = NULL, *qBuf = NULL; DBT key1 = {0}, value1 = {0}; - { - // save sma info - int32_t len = tEncodeTSma(NULL, pSmaCfg); - pBuf = calloc(len, 1); - if (pBuf == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - key1.data = (void *)&pSmaCfg->indexUid; - key1.size = sizeof(pSmaCfg->indexUid); - - qBuf = pBuf; - tEncodeTSma(&qBuf, pSmaCfg); - - value1.data = pBuf; - value1.size = POINTER_DISTANCE(qBuf, pBuf); - value1.app_data = pSmaCfg; + // save sma info + int32_t len = tEncodeTSma(NULL, pSmaCfg); + pBuf = calloc(len, 1); + if (pBuf == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; } + key1.data = (void *)&pSmaCfg->indexUid; + key1.size = sizeof(pSmaCfg->indexUid); + + qBuf = pBuf; + tEncodeTSma(&qBuf, pSmaCfg); + + value1.data = pBuf; + value1.size = POINTER_DISTANCE(qBuf, pBuf); + value1.app_data = pSmaCfg; + metaDBWLock(pMeta->pDB); pMeta->pDB->pSmaDB->put(pMeta->pDB->pSmaDB, NULL, &key1, &value1, 0); metaDBULock(pMeta->pDB); + // release + tfree(pBuf); + return 0; } diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 92a111298f..a2342ec85a 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -83,8 +83,8 @@ bool tqNextDataBlock(STqReadHandle* pHandle) { } int tqRetrieveDataBlockInfo(STqReadHandle* pHandle, SDataBlockInfo* pBlockInfo) { - /*int32_t sversion = pHandle->pBlock->sversion;*/ - /*SSchemaWrapper* pSchema = metaGetTableSchema(pHandle->pMeta, pHandle->pBlock->uid, sversion, false);*/ + // currently only rows are used + pBlockInfo->numOfCols = taosArrayGetSize(pHandle->pColIdList); pBlockInfo->rows = pHandle->pBlock->numOfRows; pBlockInfo->uid = pHandle->pBlock->uid; diff --git a/source/dnode/vnode/src/tsdb/tsdbBDBImpl.c b/source/dnode/vnode/src/tsdb/tsdbBDBImpl.c index f2f48bbc8a..cf3351c5d8 100644 --- a/source/dnode/vnode/src/tsdb/tsdbBDBImpl.c +++ b/source/dnode/vnode/src/tsdb/tsdbBDBImpl.c @@ -12,3 +12,162 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ + +#define ALLOW_FORBID_FUNC +#include "db.h" + +#include "taoserror.h" +#include "tcoding.h" +#include "thash.h" +#include "tsdbDBDef.h" +#include "tsdbLog.h" + +#define IMPL_WITH_LOCK 1 + +static int tsdbOpenBDBDb(DB **ppDB, DB_ENV *pEnv, const char *pFName, bool isDup); +static void tsdbCloseBDBDb(DB *pDB); + +#define BDB_PERR(info, code) fprintf(stderr, "%s:%d " info " reason: %s\n", __FILE__, __LINE__, db_strerror(code)) + +int32_t tsdbOpenDBF(TDBEnv pEnv, SDBFile *pDBF) { + // TDBEnv is shared by a group of SDBFile + if (!pEnv) { + terrno = TSDB_CODE_INVALID_PTR; + return -1; + } + + // Open DBF + if (tsdbOpenBDBDb(&(pDBF->pDB), pEnv, pDBF->path, false) < 0) { + terrno = TSDB_CODE_TDB_INIT_FAILED; + tsdbCloseBDBDb(pDBF->pDB); + return -1; + } + + return 0; +} + +void tsdbCloseDBF(SDBFile *pDBF) { + if (pDBF->pDB) { + tsdbCloseBDBDb(pDBF->pDB); + pDBF->pDB = NULL; + } + tfree(pDBF->path); +} + +int32_t tsdbOpenBDBEnv(DB_ENV **ppEnv, const char *path) { + int ret = 0; + DB_ENV *pEnv = NULL; + + if (path == NULL) return 0; + + ret = db_env_create(&pEnv, 0); + if (ret != 0) { + BDB_PERR("Failed to create tsdb env", ret); + return -1; + } + + ret = pEnv->open(pEnv, path, DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL, 0); + if (ret != 0) { + // BDB_PERR("Failed to open tsdb env", ret); + tsdbWarn("Failed to open tsdb env for path %s since %d", path ? path : "NULL", ret); + return -1; + } + + *ppEnv = pEnv; + + return 0; +} + +void tsdbCloseBDBEnv(DB_ENV *pEnv) { + if (pEnv) { + pEnv->close(pEnv, 0); + } +} + +static int tsdbOpenBDBDb(DB **ppDB, DB_ENV *pEnv, const char *pFName, bool isDup) { + int ret; + DB *pDB; + + ret = db_create(&(pDB), pEnv, 0); + if (ret != 0) { + BDB_PERR("Failed to create DBP", ret); + return -1; + } + + if (isDup) { + ret = pDB->set_flags(pDB, DB_DUPSORT); + if (ret != 0) { + BDB_PERR("Failed to set DB flags", ret); + return -1; + } + } + + ret = pDB->open(pDB, NULL, pFName, NULL, DB_BTREE, DB_CREATE, 0); + if (ret) { + BDB_PERR("Failed to open DBF", ret); + return -1; + } + + *ppDB = pDB; + + return 0; +} + +static void tsdbCloseBDBDb(DB *pDB) { + if (pDB) { + pDB->close(pDB, 0); + } +} + +int32_t tsdbSaveSmaToDB(SDBFile *pDBF, void *key, uint32_t keySize, void *data, uint32_t dataSize) { + int ret; + DBT key1 = {0}, value1 = {0}; + + key1.data = key; + key1.size = keySize; + + value1.data = data; + value1.size = dataSize; + + // TODO: lock + ret = pDBF->pDB->put(pDBF->pDB, NULL, &key1, &value1, 0); + if (ret) { + BDB_PERR("Failed to put data to DBF", ret); + // TODO: unlock + return -1; + } + // TODO: unlock + + return 0; +} + +void *tsdbGetSmaDataByKey(SDBFile *pDBF, void* key, uint32_t keySize, uint32_t *valueSize) { + void *result = NULL; + DBT key1 = {0}; + DBT value1 = {0}; + int ret; + + // Set key/value + key1.data = key; + key1.size = keySize; + + // Query + // TODO: lock + ret = pDBF->pDB->get(pDBF->pDB, NULL, &key1, &value1, 0); + // TODO: unlock + if (ret != 0) { + return NULL; + } + + result = calloc(1, value1.size); + + if (result == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return NULL; + } + + *valueSize = value1.size; + memcpy(result, value1.data, value1.size); + + return result; +} \ No newline at end of file diff --git a/source/dnode/vnode/src/tsdb/tsdbMain.c b/source/dnode/vnode/src/tsdb/tsdbMain.c index 0c82911226..afa8921c00 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMain.c +++ b/source/dnode/vnode/src/tsdb/tsdbMain.c @@ -80,6 +80,8 @@ static STsdb *tsdbNew(const char *path, int32_t vgId, const STsdbCfg *pTsdbCfg, pTsdb->pmaf = pMAF; pTsdb->pMeta = pMeta; pTsdb->pTfs = pTfs; + pTsdb->pTSmaEnv = NULL; + pTsdb->pRSmaEnv = NULL; pTsdb->fs = tsdbNewFS(pTsdbCfg); @@ -88,8 +90,9 @@ static STsdb *tsdbNew(const char *path, int32_t vgId, const STsdbCfg *pTsdbCfg, static void tsdbFree(STsdb *pTsdb) { if (pTsdb) { + tsdbFreeSmaEnv(pTsdb->pRSmaEnv); + tsdbFreeSmaEnv(pTsdb->pTSmaEnv); tsdbFreeFS(pTsdb->fs); - tsdbDestroySmaState(pTsdb->pSmaStat); tfree(pTsdb->path); free(pTsdb); } @@ -105,6 +108,30 @@ static void tsdbCloseImpl(STsdb *pTsdb) { tsdbCloseFS(pTsdb); // TODO } + +int tsdbLockRepo(STsdb *pTsdb) { + int code = pthread_mutex_lock(&pTsdb->mutex); + if (code != 0) { + tsdbError("vgId:%d failed to lock tsdb since %s", REPO_ID(pTsdb), strerror(errno)); + terrno = TAOS_SYSTEM_ERROR(code); + return -1; + } + pTsdb->repoLocked = true; + return 0; +} + +int tsdbUnlockRepo(STsdb *pTsdb) { + ASSERT(IS_REPO_LOCKED(pTsdb)); + pTsdb->repoLocked = false; + int code = pthread_mutex_unlock(&pTsdb->mutex); + if (code != 0) { + tsdbError("vgId:%d failed to unlock tsdb since %s", REPO_ID(pTsdb), strerror(errno)); + terrno = TAOS_SYSTEM_ERROR(code); + return -1; + } + return 0; +} + #if 0 /* * Copyright (c) 2019 TAOS Data, Inc. diff --git a/source/dnode/vnode/src/tsdb/tsdbSma.c b/source/dnode/vnode/src/tsdb/tsdbSma.c index dc0d262725..7335e4f585 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSma.c +++ b/source/dnode/vnode/src/tsdb/tsdbSma.c @@ -15,7 +15,9 @@ #include "tsdbDef.h" +#undef SMA_PRINT_DEBUG_LOG #define SMA_STORAGE_TSDB_DAYS 30 +#define SMA_STORAGE_TSDB_TIMES 30 #define SMA_STORAGE_SPLIT_HOURS 24 #define SMA_KEY_LEN 18 // tableUid_colId_TSKEY 8+2+8 @@ -23,7 +25,7 @@ #define SMA_STATE_ITEM_HASH_SLOT 32 #define SMA_TEST_INDEX_NAME "smaTestIndexName" // TODO: just for test -#define SMA_TEST_INDEX_UID 123456 // TODO: just for test +#define SMA_TEST_INDEX_UID 2000000001 // TODO: just for test typedef enum { SMA_STORAGE_LEVEL_TSDB = 0, // use days of self-defined e.g. vnode${N}/tsdb/tsma/sma_index_uid/v2t200.dat SMA_STORAGE_LEVEL_DFILESET = 1 // use days of TS data e.g. vnode${N}/tsdb/rsma/sma_index_uid/v2r200.dat @@ -31,23 +33,22 @@ typedef enum { typedef struct { STsdb * pTsdb; - char * pDFile; // TODO: use the real DFile type, not char* - int32_t interval; // interval with the precision of DB - // TODO + SDBFile dFile; + int32_t interval; // interval with the precision of DB } STSmaWriteH; typedef struct { int32_t iter; + int32_t fid; } SmaFsIter; typedef struct { STsdb * pTsdb; - char * pDFile; // TODO: use the real DFile type, not char* + SDBFile dFile; int32_t interval; // interval with the precision of DB int32_t blockSize; // size of SMA block item int8_t storageLevel; int8_t days; SmaFsIter smaFsIter; - // TODO } STSmaReadH; typedef struct { @@ -68,18 +69,117 @@ struct SSmaStat { }; // declaration of static functions -static int32_t tsdbInitTSmaWriteH(STSmaWriteH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData); -static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData); -static int32_t tsdbJudgeStorageLevel(int64_t interval, int8_t intervalUnit); -static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *pData); -static int32_t tsdbInsertTSmaBlocks(void *bTree, const char *smaKey, const char *pData, int32_t dataLen); +static int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, char *msg); +static int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg); +// TODO: This is the basic params, and should wrap the params to a queryHandle. +static int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, int64_t indexUid, int64_t interval, + int8_t intervalUnit, tb_uid_t tableUid, col_id_t colId, TSKEY querySkey, + int32_t nMaxResult); +static int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, int8_t smaType, char *msg); + +static int32_t tsdbInitSmaStat(SSmaStat **pSmaStat); +static int32_t tsdbDestroySmaState(SSmaStat *pSmaStat); +static SSmaEnv *tsdbNewSmaEnv(const STsdb *pTsdb, const char *path); +static int32_t tsdbInitSmaEnv(STsdb *pTsdb, const char *path, SSmaEnv **pEnv); +static int32_t tsdbInitTSmaWriteH(STSmaWriteH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData); +static void tsdbDestroyTSmaWriteH(STSmaWriteH *pSmaH); +static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, int64_t interval, int8_t intervalUnit); +static int32_t tsdbGetSmaStorageLevel(int64_t interval, int8_t intervalUnit); +static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *pData); +static int32_t tsdbInsertTSmaBlocks(STSmaWriteH *pSmaH, void *smaKey, uint32_t keyLen, void *pData, uint32_t dataLen); static int64_t tsdbGetIntervalByPrecision(int64_t interval, uint8_t intervalUnit, int8_t precision); +static int32_t tsdbGetTSmaDays(STsdb *pTsdb, int64_t interval, int32_t storageLevel); static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData, int32_t storageLevel, int32_t fid); +static int32_t tsdbInitTSmaFile(STSmaReadH *pSmaH, TSKEY skey); +static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, TSKEY *queryKey); -static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData); -static int32_t tsdbInitTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin); -static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin); +static SSmaEnv *tsdbNewSmaEnv(const STsdb *pTsdb, const char *path) { + SSmaEnv *pEnv = NULL; + + pEnv = (SSmaEnv *)calloc(1, sizeof(SSmaEnv)); + if (pEnv == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return NULL; + } + + int code = pthread_rwlock_init(&(pEnv->lock), NULL); + if (code) { + terrno = TAOS_SYSTEM_ERROR(code); + free(pEnv); + return NULL; + } + + ASSERT(path && (strlen(path) > 0)); + pEnv->path = strdup(path); + if (pEnv->path == NULL) { + tsdbFreeSmaEnv(pEnv); + return NULL; + } + + if (tsdbInitSmaStat(&pEnv->pStat) != TSDB_CODE_SUCCESS) { + tsdbFreeSmaEnv(pEnv); + return NULL; + } + + if (tsdbOpenBDBEnv(&pEnv->dbEnv, pEnv->path) != TSDB_CODE_SUCCESS) { + tsdbFreeSmaEnv(pEnv); + return NULL; + } + + return pEnv; +} + +static int32_t tsdbInitSmaEnv(STsdb *pTsdb, const char *path, SSmaEnv **pEnv) { + if (!pEnv) { + terrno = TSDB_CODE_INVALID_PTR; + return TSDB_CODE_FAILED; + } + + if (pEnv && *pEnv) { + return TSDB_CODE_SUCCESS; + } + + if (tsdbLockRepo(pTsdb) != 0) { + return TSDB_CODE_FAILED; + } + + if (*pEnv == NULL) { + if ((*pEnv = tsdbNewSmaEnv(pTsdb, path)) == NULL) { + tsdbUnlockRepo(pTsdb); + return TSDB_CODE_FAILED; + } + } + + if (tsdbUnlockRepo(pTsdb) != 0) { + tsdbFreeSmaEnv(*pEnv); + return TSDB_CODE_FAILED; + } + + return TSDB_CODE_SUCCESS; +} + +/** + * @brief Release resources allocated for its member fields, not including itself. + * + * @param pSmaEnv + * @return int32_t + */ +void tsdbDestroySmaEnv(SSmaEnv *pSmaEnv) { + if (pSmaEnv) { + tsdbDestroySmaState(pSmaEnv->pStat); + tfree(pSmaEnv->pStat); + tfree(pSmaEnv->path); + pthread_rwlock_destroy(&(pSmaEnv->lock)); + tsdbCloseBDBEnv(pSmaEnv->dbEnv); + } +} + +void *tsdbFreeSmaEnv(SSmaEnv *pSmaEnv) { + tsdbDestroySmaEnv(pSmaEnv); + tfree(pSmaEnv); + return NULL; +} static int32_t tsdbInitSmaStat(SSmaStat **pSmaStat) { ASSERT(pSmaStat != NULL); @@ -125,6 +225,12 @@ static SSmaStatItem *tsdbNewSmaStatItem(int8_t state) { return pItem; } +/** + * @brief Release resources allocated for its member fields, not including itself. + * + * @param pSmaStat + * @return int32_t + */ int32_t tsdbDestroySmaState(SSmaStat *pSmaStat) { if (pSmaStat) { // TODO: use taosHashSetFreeFp when taosHashSetFreeFp is ready. @@ -135,7 +241,6 @@ int32_t tsdbDestroySmaState(SSmaStat *pSmaStat) { item = taosHashIterate(pSmaStat->smaStatItems, item); } taosHashCleanup(pSmaStat->smaStatItems); - free(pSmaStat); } } @@ -143,22 +248,35 @@ int32_t tsdbDestroySmaState(SSmaStat *pSmaStat) { * @brief Update expired window according to msg from stream computing module. * * @param pTsdb + * @param smaType ETsdbSmaType * @param msg * @return int32_t */ -int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg) { - if (msg == NULL) { +int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, int8_t smaType, char *msg) { + STsdbCfg *pCfg = REPO_CFG(pTsdb); + SSmaEnv * pEnv = NULL; + + if (!msg || !pTsdb->pMeta) { + terrno = TSDB_CODE_INVALID_PTR; return TSDB_CODE_FAILED; } - // lazy mode - if (tsdbInitSmaStat(&pTsdb->pSmaStat) != TSDB_CODE_SUCCESS) { + char smaPath[TSDB_FILENAME_LEN] = "/proj/.sma/"; + if (tsdbInitSmaEnv(pTsdb, smaPath, &pEnv) != TSDB_CODE_SUCCESS) { return TSDB_CODE_FAILED; } + if (smaType == TSDB_SMA_TYPE_TIME_RANGE) { + pTsdb->pTSmaEnv = pEnv; + } else if (smaType == TSDB_SMA_TYPE_ROLLUP) { + pTsdb->pRSmaEnv = pEnv; + } else { + ASSERT(0); + } + // TODO: decode the msg => start - int64_t indexUid = SMA_TEST_INDEX_UID; - const char * indexName = SMA_TEST_INDEX_NAME; + int64_t indexUid = SMA_TEST_INDEX_UID; + // const char * indexName = SMA_TEST_INDEX_NAME; const int32_t SMA_TEST_EXPIRED_WINDOW_SIZE = 10; TSKEY expiredWindows[SMA_TEST_EXPIRED_WINDOW_SIZE]; int64_t now = taosGetTimestampMs(); @@ -167,9 +285,9 @@ int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg) { } // TODO: decode the msg <= end - SHashObj *pItemsHash = pTsdb->pSmaStat->smaStatItems; + SHashObj *pItemsHash = SMA_ENV_STAT_ITEMS(pEnv); - SSmaStatItem *pItem = (SSmaStatItem *)taosHashGet(pItemsHash, indexName, strlen(indexName)); + SSmaStatItem *pItem = (SSmaStatItem *)taosHashGet(pItemsHash, &indexUid, sizeof(indexUid)); if (pItem == NULL) { pItem = tsdbNewSmaStatItem(TSDB_SMA_STAT_EXPIRED); // TODO use the real state if (pItem == NULL) { @@ -181,20 +299,28 @@ int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg) { // cache smaMeta STSma *pSma = metaGetSmaInfoByIndex(pTsdb->pMeta, indexUid); if (pSma == NULL) { + terrno = TSDB_CODE_TDB_NO_SMA_INDEX_IN_META; taosHashCleanup(pItem->expiredWindows); free(pItem); + tsdbWarn("vgId:%d update expired window failed for smaIndex %" PRIi64 " since %s", REPO_ID(pTsdb), indexUid, + tstrerror(terrno)); return TSDB_CODE_FAILED; } pItem->pSma = pSma; // TODO: change indexName to indexUid - if (taosHashPut(pItemsHash, indexName, strnlen(indexName, TSDB_INDEX_NAME_LEN), &pItem, sizeof(pItem)) != 0) { + if (taosHashPut(pItemsHash, &indexUid, sizeof(indexUid), &pItem, sizeof(pItem)) != 0) { // If error occurs during put smaStatItem, free the resources of pItem taosHashCleanup(pItem->expiredWindows); free(pItem); return TSDB_CODE_FAILED; } } +#if 0 + SSmaStatItem *pItem1 = (SSmaStatItem *)taosHashGet(pItemsHash, &indexUid, sizeof(indexUid)); + int size1 = taosHashGetSize(pItem1->expiredWindows); + tsdbWarn("vgId:%d smaIndex %" PRIi64 " size is %d before hashPut", REPO_ID(pTsdb), indexUid, size1); +#endif int8_t state = TSDB_SMA_STAT_EXPIRED; for (int32_t i = 0; i < SMA_TEST_EXPIRED_WINDOW_SIZE; ++i) { @@ -207,21 +333,28 @@ int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg) { // windows failed to put into hash table. taosHashCleanup(pItem->expiredWindows); tfree(pItem->pSma); - taosHashRemove(pItemsHash, indexName, sizeof(indexName)); + taosHashRemove(pItemsHash, &indexUid, sizeof(indexUid)); return TSDB_CODE_FAILED; } } +#if 0 + SSmaStatItem *pItem2 = (SSmaStatItem *)taosHashGet(pItemsHash, &indexUid, sizeof(indexUid)); + int size2 = taosHashGetSize(pItem1->expiredWindows); + tsdbWarn("vgId:%d smaIndex %" PRIi64 " size is %d after hashPut", REPO_ID(pTsdb), indexUid, size2); +#endif + return TSDB_CODE_SUCCESS; } -static int32_t tsdbResetExpiredWindow(STsdb *pTsdb, int64_t indexUid, TSKEY skey) { +static int32_t tsdbResetExpiredWindow(SSmaStat *pStat, int64_t indexUid, TSKEY skey) { SSmaStatItem *pItem = NULL; - if (pTsdb->pSmaStat && pTsdb->pSmaStat->smaStatItems) { - pItem = (SSmaStatItem *)taosHashGet(pTsdb->pSmaStat->smaStatItems, &indexUid, sizeof(indexUid)); + // TODO: If HASH_ENTRY_LOCK used, whether rwlock needed to handle cases of removing hashNode? + if (pStat && pStat->smaStatItems) { + pItem = (SSmaStatItem *)taosHashGet(pStat->smaStatItems, &indexUid, sizeof(indexUid)); } - +#if 0 if (pItem != NULL) { // TODO: reset time window for the sma data blocks if (taosHashRemove(pItem->expiredWindows, &skey, sizeof(TSKEY)) != 0) { @@ -231,6 +364,7 @@ static int32_t tsdbResetExpiredWindow(STsdb *pTsdb, int64_t indexUid, TSKEY skey } else { // error handling } +#endif return TSDB_CODE_SUCCESS; } @@ -241,7 +375,7 @@ static int32_t tsdbResetExpiredWindow(STsdb *pTsdb, int64_t indexUid, TSKEY skey * @param intervalUnit * @return int32_t */ -static int32_t tsdbJudgeStorageLevel(int64_t interval, int8_t intervalUnit) { +static int32_t tsdbGetSmaStorageLevel(int64_t interval, int8_t intervalUnit) { // TODO: configurable for SMA_STORAGE_SPLIT_HOURS? switch (intervalUnit) { case TD_TIME_UNIT_HOUR: @@ -281,18 +415,35 @@ static int32_t tsdbJudgeStorageLevel(int64_t interval, int8_t intervalUnit) { } /** - * @brief Insert TSma data blocks to B+Tree + * @brief Insert TSma data blocks to DB File build by B+Tree * - * @param bTree + * @param pSmaH * @param smaKey + * @param keyLen * @param pData * @param dataLen * @return int32_t */ -static int32_t tsdbInsertTSmaBlocks(void *bTree, const char *smaKey, const char *pData, int32_t dataLen) { +static int32_t tsdbInsertTSmaBlocks(STSmaWriteH *pSmaH, void *smaKey, uint32_t keyLen, void *pData, uint32_t dataLen) { + SDBFile *pDBFile = &pSmaH->dFile; + // TODO: insert sma data blocks into B+Tree - tsdbDebug("insert sma data blocks into B+Tree: smaKey %" PRIx64 "-%" PRIu16 "-%" PRIx64 ", dataLen %d", - *(uint64_t *)smaKey, *(uint16_t *)POINTER_SHIFT(smaKey, 8), *(int64_t *)POINTER_SHIFT(smaKey, 10), dataLen); + tsdbDebug("vgId:%d insert sma data blocks into %s: smaKey %" PRIx64 "-%" PRIu16 "-%" PRIx64 ", dataLen %d", + REPO_ID(pSmaH->pTsdb), pDBFile->path, *(tb_uid_t *)smaKey, *(uint16_t *)POINTER_SHIFT(smaKey, 8), + *(int64_t *)POINTER_SHIFT(smaKey, 10), dataLen); + + if (tsdbSaveSmaToDB(pDBFile, smaKey, keyLen, pData, dataLen) != 0) { + return TSDB_CODE_FAILED; + } + +#ifdef SMA_PRINT_DEBUG_LOG + uint32_t valueSize = 0; + void * data = tsdbGetSmaDataByKey(pDBFile, smaKey, keyLen, &valueSize); + ASSERT(data != NULL); + for (uint32_t v = 0; v < valueSize; v += 8) { + tsdbWarn("vgId:%d sma data - val[%d] is %" PRIi64, REPO_ID(pSmaH->pTsdb), v, *(int64_t *)POINTER_SHIFT(data, v)); + } +#endif return TSDB_CODE_SUCCESS; } @@ -324,41 +475,41 @@ static int64_t tsdbGetIntervalByPrecision(int64_t interval, uint8_t intervalUnit } } - switch (intervalUnit) { - case TD_TIME_UNIT_MILLISEC: - if (TSDB_TIME_PRECISION_MILLI == precision) { - return interval; - } else if (TSDB_TIME_PRECISION_MICRO == precision) { - return interval * 1e3; - } else { // nano second - return interval * 1e6; - } - break; - case TD_TIME_UNIT_MICROSEC: - if (TSDB_TIME_PRECISION_MILLI == precision) { + switch (precision) { + case TSDB_TIME_PRECISION_MILLI: + if (TD_TIME_UNIT_MICROSEC == intervalUnit) { // us return interval / 1e3; - } else if (TSDB_TIME_PRECISION_MICRO == precision) { - return interval; - } else { // nano second - return interval * 1e3; - } - break; - case TD_TIME_UNIT_NANOSEC: - if (TSDB_TIME_PRECISION_MILLI == precision) { + } else if (TD_TIME_UNIT_NANOSEC == intervalUnit) { // nano second return interval / 1e6; - } else if (TSDB_TIME_PRECISION_MICRO == precision) { - return interval / 1e3; - } else { // nano second + } else { return interval; } break; - default: - if (TSDB_TIME_PRECISION_MILLI == precision) { + case TSDB_TIME_PRECISION_MICRO: + if (TD_TIME_UNIT_MICROSEC == intervalUnit) { // us + return interval; + } else if (TD_TIME_UNIT_NANOSEC == intervalUnit) { // nano second + return interval / 1e3; + } else { return interval * 1e3; - } else if (TSDB_TIME_PRECISION_MICRO == precision) { + } + break; + case TSDB_TIME_PRECISION_NANO: + if (TD_TIME_UNIT_MICROSEC == intervalUnit) { + return interval * 1e3; + } else if (TD_TIME_UNIT_NANOSEC == intervalUnit) { // nano second + return interval; + } else { return interval * 1e6; - } else { // nano second - return interval * 1e9; + } + break; + default: // ms + if (TD_TIME_UNIT_MICROSEC == intervalUnit) { // us + return interval / 1e3; + } else if (TD_TIME_UNIT_NANOSEC == intervalUnit) { // nano second + return interval / 1e6; + } else { + return interval; } break; } @@ -381,8 +532,6 @@ static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *p // TODO: check the data integrity - void *bTree = pSmaH->pDFile; - int32_t len = 0; while (true) { if (len >= pData->dataLen) { @@ -405,7 +554,7 @@ static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *p pData->indexUid, pData->skey, pTbData->tableUid, pColData->colId); #endif tsdbEncodeTSmaKey(pTbData->tableUid, pColData->colId, pData->skey, (void **)&pSmaKey); - if (tsdbInsertTSmaBlocks(bTree, smaKey, pColData->data, pColData->blockSize) < 0) { + if (tsdbInsertTSmaBlocks(pSmaH, smaKey, SMA_KEY_LEN, pColData->data, pColData->blockSize) < 0) { tsdbWarn("vgId:%d insert tSma blocks failed since %s", REPO_ID(pTsdb), tstrerror(terrno)); } tbLen += (sizeof(STSmaColData) + pColData->blockSize); @@ -419,15 +568,43 @@ static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *p static int32_t tsdbInitTSmaWriteH(STSmaWriteH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData) { pSmaH->pTsdb = pTsdb; pSmaH->interval = tsdbGetIntervalByPrecision(pData->interval, pData->intervalUnit, REPO_CFG(pTsdb)->precision); + return TSDB_CODE_SUCCESS; +} + +static void tsdbDestroyTSmaWriteH(STSmaWriteH *pSmaH) { + if (pSmaH) { + tsdbCloseDBF(&pSmaH->dFile); + } } static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData, int32_t storageLevel, int32_t fid) { - // TODO - pSmaH->pDFile = "tSma_interval_file_name"; - + STsdb *pTsdb = pSmaH->pTsdb; + ASSERT(pSmaH->dFile.path == NULL && pSmaH->dFile.pDB == NULL); + char tSmaFile[TSDB_FILENAME_LEN] = {0}; + snprintf(tSmaFile, TSDB_FILENAME_LEN, "v%df%d.tsma", REPO_ID(pTsdb), fid); + pSmaH->dFile.path = strdup(tSmaFile); return TSDB_CODE_SUCCESS; -} +} +/** + * @brief + * + * @param pTsdb + * @param interval Interval calculated by DB's precision + * @param storageLevel + * @return int32_t + */ +static int32_t tsdbGetTSmaDays(STsdb *pTsdb, int64_t interval, int32_t storageLevel) { + STsdbCfg *pCfg = REPO_CFG(pTsdb); + int32_t daysPerFile = pCfg->daysPerFile; + + if (storageLevel == SMA_STORAGE_LEVEL_TSDB) { + int32_t days = SMA_STORAGE_TSDB_TIMES * (interval / tsTickPerDay[pCfg->precision]); + daysPerFile = days > SMA_STORAGE_TSDB_DAYS ? days : SMA_STORAGE_TSDB_DAYS; + } + + return daysPerFile; +} /** * @brief Insert/Update Time-range-wise SMA data. @@ -441,51 +618,72 @@ static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData, * @param msg * @return int32_t */ -int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, char *msg) { - STsdbCfg * pCfg = REPO_CFG(pTsdb); +static int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, char *msg) { + STsdbCfg * pCfg = REPO_CFG(pTsdb); STSmaDataWrapper *pData = (STSmaDataWrapper *)msg; - STSmaWriteH tSmaH = {0}; - tsdbInitTSmaWriteH(&tSmaH, pTsdb, pData); + if (!pTsdb->pTSmaEnv) { + terrno = TSDB_CODE_INVALID_PTR; + tsdbWarn("vgId:%d insert tSma data failed since pTSmaEnv is NULL", REPO_ID(pTsdb)); + return terrno; + } if (pData->dataLen <= 0) { TASSERT(0); terrno = TSDB_CODE_INVALID_PARA; - return terrno; + return TSDB_CODE_FAILED; } - // Step 1: Judge the storage level - int32_t storageLevel = tsdbJudgeStorageLevel(pData->interval, pData->intervalUnit); - int32_t daysPerFile = storageLevel == SMA_STORAGE_LEVEL_TSDB ? SMA_STORAGE_TSDB_DAYS : pCfg->daysPerFile; + STSmaWriteH tSmaH = {0}; + + if (tsdbInitTSmaWriteH(&tSmaH, pTsdb, pData) != 0) { + return TSDB_CODE_FAILED; + } + + // Step 1: Judge the storage level and days + int32_t storageLevel = tsdbGetSmaStorageLevel(pData->interval, pData->intervalUnit); + int32_t daysPerFile = tsdbGetTSmaDays(pTsdb, tSmaH.interval, storageLevel); + int32_t fid = (int32_t)(TSDB_KEY_FID(pData->skey, daysPerFile, pCfg->precision)); // Step 2: Set the DFile for storage of SMA index, and iterate/split the TSma data and store to B+Tree index file // - Set and open the DFile or the B+Tree file - - int32_t fid = (int32_t)(TSDB_KEY_FID(pData->skey, daysPerFile, pCfg->precision)); - - // Save all the TSma data to one file // TODO: tsdbStartTSmaCommit(); tsdbSetTSmaDataFile(&tSmaH, pData, storageLevel, fid); - tsdbInsertTSmaDataSection(&tSmaH, pData); + if (tsdbOpenDBF(pTsdb->pTSmaEnv->dbEnv, &tSmaH.dFile) != 0) { + tsdbWarn("vgId:%d open DB file %s failed since %s", REPO_ID(pTsdb), + tSmaH.dFile.path ? tSmaH.dFile.path : "path is NULL", tstrerror(terrno)); + tsdbDestroyTSmaWriteH(&tSmaH); + return TSDB_CODE_FAILED; + } + + if (tsdbInsertTSmaDataSection(&tSmaH, pData) != 0) { + tsdbWarn("vgId:%d insert tSma data section failed since %s", REPO_ID(pTsdb), tstrerror(terrno)); + tsdbDestroyTSmaWriteH(&tSmaH); + return TSDB_CODE_FAILED; + } // TODO:tsdbEndTSmaCommit(); - // reset the SSmaStat - tsdbResetExpiredWindow(pTsdb, pData->indexUid, pData->skey); + // Step 3: reset the SSmaStat + tsdbResetExpiredWindow(SMA_ENV_STAT(pTsdb->pTSmaEnv), pData->indexUid, pData->skey); + tsdbDestroyTSmaWriteH(&tSmaH); return TSDB_CODE_SUCCESS; } static int32_t tsdbSetRSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData, int32_t fid) { - // TODO - pSmaH->pDFile = "rSma_interval_file_name"; + STsdb *pTsdb = pSmaH->pTsdb; + + char tSmaFile[TSDB_FILENAME_LEN] = {0}; + snprintf(tSmaFile, TSDB_FILENAME_LEN, "v%df%d.rsma", REPO_ID(pTsdb), fid); + pSmaH->dFile.path = strdup(tSmaFile); return TSDB_CODE_SUCCESS; } -int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg) { - STsdbCfg * pCfg = REPO_CFG(pTsdb); +static int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg) { + STsdbCfg * pCfg = REPO_CFG(pTsdb); STSmaDataWrapper *pData = (STSmaDataWrapper *)msg; - STSmaWriteH tSmaH = {0}; + STSmaWriteH tSmaH = {0}; tsdbInitTSmaWriteH(&tSmaH, pTsdb, pData); @@ -496,7 +694,7 @@ int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg) { } // Step 1: Judge the storage level - int32_t storageLevel = tsdbJudgeStorageLevel(pData->interval, pData->intervalUnit); + int32_t storageLevel = tsdbGetSmaStorageLevel(pData->interval, pData->intervalUnit); int32_t daysPerFile = storageLevel == SMA_STORAGE_LEVEL_TSDB ? SMA_STORAGE_TSDB_DAYS : pCfg->daysPerFile; // Step 2: Set the DFile for storage of SMA index, and iterate/split the TSma data and store to B+Tree index file @@ -507,45 +705,46 @@ int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg) { // Save all the TSma data to one file // TODO: tsdbStartTSmaCommit(); tsdbSetTSmaDataFile(&tSmaH, pData, storageLevel, fid); + tsdbInsertTSmaDataSection(&tSmaH, pData); // TODO:tsdbEndTSmaCommit(); // reset the SSmaStat - tsdbResetExpiredWindow(pTsdb, pData->indexUid, pData->skey); + tsdbResetExpiredWindow(SMA_ENV_STAT(pTsdb->pRSmaEnv), pData->indexUid, pData->skey); return TSDB_CODE_SUCCESS; } /** - * @brief Init of tSma ReadH + * @brief * * @param pSmaH * @param pTsdb - * @param param - * @param pData + * @param interval + * @param intervalUnit * @return int32_t */ -static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData) { +static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, int64_t interval, int8_t intervalUnit) { pSmaH->pTsdb = pTsdb; - pSmaH->interval = tsdbGetIntervalByPrecision(pData->interval, pData->intervalUnit, REPO_CFG(pTsdb)->precision); - // pSmaH->blockSize = param->numOfFuncIds * sizeof(int64_t); + pSmaH->interval = tsdbGetIntervalByPrecision(interval, intervalUnit, REPO_CFG(pTsdb)->precision); + pSmaH->storageLevel = tsdbGetSmaStorageLevel(interval, intervalUnit); + pSmaH->days = tsdbGetTSmaDays(pTsdb, pSmaH->interval, pSmaH->storageLevel); } /** * @brief Init of tSma FS * * @param pReadH - * @param param - * @param queryWin + * @param skey * @return int32_t */ -static int32_t tsdbInitTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin) { - int32_t storageLevel = 0; //tsdbJudgeStorageLevel(param->interval, param->intervalUnit); - int32_t daysPerFile = - storageLevel == SMA_STORAGE_LEVEL_TSDB ? SMA_STORAGE_TSDB_DAYS : REPO_CFG(pReadH->pTsdb)->daysPerFile; - pReadH->storageLevel = storageLevel; - pReadH->days = daysPerFile; - pReadH->smaFsIter.iter = 0; +static int32_t tsdbInitTSmaFile(STSmaReadH *pSmaH, TSKEY skey) { + int32_t fid = (int32_t)(TSDB_KEY_FID(skey, pSmaH->days, REPO_CFG(pSmaH->pTsdb)->precision)); + char tSmaFile[TSDB_FILENAME_LEN] = {0}; + snprintf(tSmaFile, TSDB_FILENAME_LEN, "v%df%d.tsma", REPO_ID(pSmaH->pTsdb), fid); + pSmaH->dFile.path = strdup(tSmaFile); + pSmaH->smaFsIter.iter = 0; + pSmaH->smaFsIter.fid = fid; } /** @@ -557,17 +756,18 @@ static int32_t tsdbInitTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin) { * @return true * @return false */ -static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin) { +static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, TSKEY *queryKey) { SArray *smaFs = pReadH->pTsdb->fs->cstatus->sf; int32_t nSmaFs = taosArrayGetSize(smaFs); - pReadH->pDFile = NULL; + tsdbCloseDBF(&pReadH->dFile); +#if 0 while (pReadH->smaFsIter.iter < nSmaFs) { void *pSmaFile = taosArrayGet(smaFs, pReadH->smaFsIter.iter); if (pSmaFile) { // match(indexName, queryWindow) // TODO: select the file by index_name ... - pReadH->pDFile = pSmaFile; + pReadH->dFile = pSmaFile; ++pReadH->smaFsIter.iter; break; } @@ -578,41 +778,83 @@ static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin) { tsdbDebug("vg%d: smaFile %s matched", REPO_ID(pReadH->pTsdb), "[pSmaFile dir]"); return true; } +#endif return false; } /** - * @brief Return the data between queryWin and fill the pData. + * @brief * - * @param pTsdb - * @param param + * @param pTsdb Return the data between queryWin and fill the pData. * @param pData - * @param queryWin + * @param indexUid + * @param interval + * @param intervalUnit + * @param tableUid + * @param colId + * @param pQuerySKey * @param nMaxResult The query invoker should control the nMaxResult need to return to avoid OOM. * @return int32_t */ -int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, STimeWindow *queryWin, int32_t nMaxResult) { - SSmaStatItem *pItem = - (SSmaStatItem *)taosHashGet(pTsdb->pSmaStat->smaStatItems, &pData->indexUid, sizeof(pData->indexUid)); +static int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, int64_t indexUid, int64_t interval, + int8_t intervalUnit, tb_uid_t tableUid, col_id_t colId, TSKEY querySkey, + int32_t nMaxResult) { + SSmaStatItem *pItem = (SSmaStatItem *)taosHashGet(SMA_ENV_STAT_ITEMS(pTsdb->pTSmaEnv), &indexUid, sizeof(indexUid)); if (pItem == NULL) { // mark all window as expired and notify query module to query raw TS data. return TSDB_CODE_SUCCESS; } - int32_t nQueryWin = 0; +#if 0 + int32_t nQueryWin = taosArrayGetSize(pQuerySKey); for (int32_t n = 0; n < nQueryWin; ++n) { - TSKEY thisWindow = n; - if (taosHashGet(pItem->expiredWindows, &thisWindow, sizeof(thisWindow)) != NULL) { + TSKEY skey = taosArrayGet(pQuerySKey, n); + if (taosHashGet(pItem->expiredWindows, &skey, sizeof(TSKEY)) != NULL) { // TODO: mark this window as expired. } } - +#endif +#if 0 + if (taosHashGet(pItem->expiredWindows, &querySkey, sizeof(TSKEY)) != NULL) { + // TODO: mark this window as expired. + } +#endif STSmaReadH tReadH = {0}; - tsdbInitTSmaReadH(&tReadH, pTsdb, pData); + tsdbInitTSmaReadH(&tReadH, pTsdb, interval, intervalUnit); + tsdbCloseDBF(&tReadH.dFile); - tsdbInitTSmaFile(&tReadH, queryWin); + tsdbInitTSmaFile(&tReadH, querySkey); + if (tsdbOpenDBF(SMA_ENV_ENV(pTsdb->pTSmaEnv), &tReadH.dFile) != 0) { + tsdbWarn("vgId:%d open DBF %s failed since %s", REPO_ID(pTsdb), tReadH.dFile.path, tstrerror(terrno)); + return TSDB_CODE_FAILED; + } + char smaKey[SMA_KEY_LEN] = {0}; + void *pSmaKey = &smaKey; + tsdbEncodeTSmaKey(tableUid, colId, querySkey, (void **)&pSmaKey); + + tsdbDebug("vgId:%d get sma data from %s: smaKey %" PRIx64 "-%" PRIu16 "-%" PRIx64 ", keyLen %d", REPO_ID(pTsdb), + tReadH.dFile.path, *(tb_uid_t *)smaKey, *(uint16_t *)POINTER_SHIFT(smaKey, 8), + *(int64_t *)POINTER_SHIFT(smaKey, 10), SMA_KEY_LEN); + + void * result = NULL; + uint32_t valueSize = 0; + if ((result = tsdbGetSmaDataByKey(&tReadH.dFile, smaKey, SMA_KEY_LEN, &valueSize)) == NULL) { + tsdbWarn("vgId:%d get sma data failed from smaIndex %" PRIi64 ", smaKey %" PRIx64 "-%" PRIu16 "-%" PRIx64 + " since %s", + REPO_ID(pTsdb), indexUid, *(tb_uid_t *)smaKey, *(uint16_t *)POINTER_SHIFT(smaKey, 8), + *(int64_t *)POINTER_SHIFT(smaKey, 10), tstrerror(terrno)); + tsdbCloseDBF(&tReadH.dFile); + return TSDB_CODE_FAILED; + } + tfree(result); +#ifdef SMA_PRINT_DEBUG_LOG + for (uint32_t v = 0; v < valueSize; v += 8) { + tsdbWarn("vgId:%d v[%d]=%" PRIi64, REPO_ID(pTsdb), v, *(int64_t *)POINTER_SHIFT(result, v)); + } +#endif +#if 0 int32_t nResult = 0; int64_t lastKey = 0; @@ -634,8 +876,9 @@ int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, STimeWindow * } } } - +#endif // read data from file and fill the result + tsdbCloseDBF(&tReadH.dFile); return TSDB_CODE_SUCCESS; } @@ -673,4 +916,55 @@ int32_t tsdbRemoveTSmaData(STsdb *pTsdb, void *smaIndex, STimeWindow *pWin) { // } return TSDB_CODE_SUCCESS; } -#endif \ No newline at end of file +#endif + +/** + * @brief Insert/Update tSma(Time-range-wise SMA) data from stream computing engine + * + * @param pTsdb + * @param param + * @param msg + * @return int32_t + * TODO: Who is responsible for resource allocate and release? + */ +int32_t tsdbInsertTSmaData(STsdb *pTsdb, char *msg) { + int32_t code = TSDB_CODE_SUCCESS; + if ((code = tsdbInsertTSmaDataImpl(pTsdb, msg)) < 0) { + tsdbWarn("vgId:%d insert tSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno)); + } + return code; +} + +int32_t tsdbUpdateSmaWindow(STsdb *pTsdb, int8_t smaType, char *msg) { + int32_t code = TSDB_CODE_SUCCESS; + if ((code = tsdbUpdateExpiredWindow(pTsdb, smaType, msg)) < 0) { + tsdbWarn("vgId:%d update expired sma window failed since %s", REPO_ID(pTsdb), tstrerror(terrno)); + } + return code; +} + +/** + * @brief Insert Time-range-wise Rollup Sma(RSma) data + * + * @param pTsdb + * @param param + * @param msg + * @return int32_t + */ +int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg) { + int32_t code = TSDB_CODE_SUCCESS; + if ((code = tsdbInsertRSmaDataImpl(pTsdb, msg)) < 0) { + tsdbWarn("vgId:%d insert rSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno)); + } + return code; +} + +int32_t tsdbGetTSmaData(STsdb *pTsdb, STSmaDataWrapper *pData, int64_t indexUid, int64_t interval, int8_t intervalUnit, + tb_uid_t tableUid, col_id_t colId, TSKEY querySkey, int32_t nMaxResult) { + int32_t code = TSDB_CODE_SUCCESS; + if ((code = tsdbGetTSmaDataImpl(pTsdb, pData, indexUid, interval, intervalUnit, tableUid, colId, querySkey, + nMaxResult)) < 0) { + tsdbWarn("vgId:%d get tSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno)); + } + return code; +} \ No newline at end of file diff --git a/source/dnode/vnode/src/tsdb/tsdbWrite.c b/source/dnode/vnode/src/tsdb/tsdbWrite.c index 26d31af4f3..3ccb483fe4 100644 --- a/source/dnode/vnode/src/tsdb/tsdbWrite.c +++ b/source/dnode/vnode/src/tsdb/tsdbWrite.c @@ -34,6 +34,7 @@ int tsdbInsertData(STsdb *pTsdb, SSubmitReq *pMsg, SSubmitRsp *pRsp) { return tsdbMemTableInsert(pTsdb, pTsdb->mem, pMsg, NULL); } +#if 0 /** * @brief Insert/Update tSma(Time-range-wise SMA) data from stream computing engine * @@ -51,6 +52,14 @@ int32_t tsdbInsertTSmaData(STsdb *pTsdb, char *msg) { return code; } +int32_t tsdbUpdateSmaWindow(STsdb *pTsdb, int8_t smaType, char *msg) { + int32_t code = TSDB_CODE_SUCCESS; + if ((code = tsdbUpdateExpiredWindow(pTsdb, smaType, msg)) < 0) { + tsdbWarn("vgId:%d update expired sma window failed since %s", REPO_ID(pTsdb), tstrerror(terrno)); + } + return code; +} + /** * @brief Insert Time-range-wise Rollup Sma(RSma) data * @@ -65,4 +74,6 @@ int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg) { tsdbWarn("vgId:%d insert rSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno)); } return code; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/source/dnode/vnode/test/tsdbSmaTest.cpp b/source/dnode/vnode/test/tsdbSmaTest.cpp index ac9a8fd3d0..18dca33bda 100644 --- a/source/dnode/vnode/test/tsdbSmaTest.cpp +++ b/source/dnode/vnode/test/tsdbSmaTest.cpp @@ -33,7 +33,7 @@ int main(int argc, char **argv) { return RUN_ALL_TESTS(); } -TEST(testCase, tSmaEncodeDecodeTest) { +TEST(testCase, tSma_Meta_Encode_Decode_Test) { // encode STSma tSma = {0}; tSma.version = 0; @@ -87,8 +87,9 @@ TEST(testCase, tSmaEncodeDecodeTest) { tdDestroyTSma(&tSma); tdDestroyTSmaWrapper(&dstTSmaWrapper); } + #if 1 -TEST(testCase, tSma_DB_Put_Get_Del_Test) { +TEST(testCase, tSma_metaDB_Put_Get_Del_Test) { const char * smaIndexName1 = "sma_index_test_1"; const char * smaIndexName2 = "sma_index_test_2"; const char * timezone = "Asia/Shanghai"; @@ -220,13 +221,84 @@ TEST(testCase, tSma_DB_Put_Get_Del_Test) { #endif #if 1 -TEST(testCase, tSmaInsertTest) { - const int64_t indexUid = 2000000002; +TEST(testCase, tSma_Data_Insert_Query_Test) { + // step 1: prepare meta + const char * smaIndexName1 = "sma_index_test_1"; + const char * timezone = "Asia/Shanghai"; + const char * expr = "select count(a,b, top 20), from table interval 1d, sliding 1h;"; + const char * tagsFilter = "where tags.location='Beijing' and tags.district='ChaoYang'"; + const char * smaTestDir = "./smaTest"; + const tb_uid_t tbUid = 1234567890; + const int64_t indexUid1 = 2000000001; + const int64_t interval1 = 1; + const int8_t intervalUnit1 = TD_TIME_UNIT_DAY; + const uint32_t nCntTSma = 2; + TSKEY skey1 = 1646987196; + const int64_t testSmaData1 = 100; + const int64_t testSmaData2 = 200; + // encode + STSma tSma = {0}; + tSma.version = 0; + tSma.intervalUnit = TD_TIME_UNIT_DAY; + tSma.interval = 1; + tSma.slidingUnit = TD_TIME_UNIT_HOUR; + tSma.sliding = 0; + tSma.indexUid = indexUid1; + tstrncpy(tSma.indexName, smaIndexName1, TSDB_INDEX_NAME_LEN); + tstrncpy(tSma.timezone, timezone, TD_TIMEZONE_LEN); + tSma.tableUid = tbUid; + + tSma.exprLen = strlen(expr); + tSma.expr = (char *)calloc(tSma.exprLen + 1, 1); + tstrncpy(tSma.expr, expr, tSma.exprLen + 1); + + tSma.tagsFilterLen = strlen(tagsFilter); + tSma.tagsFilter = (char *)calloc(tSma.tagsFilterLen + 1, 1); + tstrncpy(tSma.tagsFilter, tagsFilter, tSma.tagsFilterLen + 1); + + SMeta * pMeta = NULL; + STSma * pSmaCfg = &tSma; + const SMetaCfg *pMetaCfg = &defaultMetaOptions; + + taosRemoveDir(smaTestDir); + + pMeta = metaOpen(smaTestDir, pMetaCfg, NULL); + assert(pMeta != NULL); + // save index 1 + EXPECT_EQ(metaSaveSmaToDB(pMeta, pSmaCfg), 0); + + // step 2: insert data STSmaDataWrapper *pSmaData = NULL; STsdb tsdb = {0}; STsdbCfg * pCfg = &tsdb.config; - pCfg->daysPerFile = 1; + tsdb.pMeta = pMeta; + tsdb.vgId = 2; + tsdb.config.daysPerFile = 10; // default days is 10 + tsdb.config.keep1 = 30; + tsdb.config.keep2 = 90; + tsdb.config.keep = 365; + tsdb.config.precision = TSDB_TIME_PRECISION_MILLI; + tsdb.config.update = TD_ROW_OVERWRITE_UPDATE; + tsdb.config.compression = TWO_STAGE_COMP; + + switch (tsdb.config.precision) { + case TSDB_TIME_PRECISION_MILLI: + skey1 *= 1e3; + break; + case TSDB_TIME_PRECISION_MICRO: + skey1 *= 1e6; + break; + case TSDB_TIME_PRECISION_NANO: + skey1 *= 1e9; + break; + default: // ms + skey1 *= 1e3; + break; + } + + char *msg = (char *)calloc(100, 1); + EXPECT_EQ(tsdbUpdateSmaWindow(&tsdb, TSDB_SMA_TYPE_TIME_RANGE, msg), 0); // init int32_t allocCnt = 0; @@ -235,21 +307,21 @@ TEST(testCase, tSmaInsertTest) { void * buf = NULL; EXPECT_EQ(tsdbMakeRoom(&buf, allocStep), 0); int32_t bufSize = taosTSizeof(buf); - int32_t numOfTables = 25; + int32_t numOfTables = 10; col_id_t numOfCols = 4096; EXPECT_GT(numOfCols, 0); pSmaData = (STSmaDataWrapper *)buf; printf(">> allocate [%d] time to %d and addr is %p\n", ++allocCnt, bufSize, pSmaData); - pSmaData->skey = 1646987196; - pSmaData->interval = 10; - pSmaData->intervalUnit = TD_TIME_UNIT_MINUTE; - pSmaData->indexUid = indexUid; + pSmaData->skey = skey1; + pSmaData->interval = interval1; + pSmaData->intervalUnit = intervalUnit1; + pSmaData->indexUid = indexUid1; int32_t len = sizeof(STSmaDataWrapper); for (int32_t t = 0; t < numOfTables; ++t) { STSmaTbData *pTbData = (STSmaTbData *)POINTER_SHIFT(pSmaData, len); - pTbData->tableUid = t; + pTbData->tableUid = tbUid + t; int32_t tableDataLen = sizeof(STSmaTbData); for (col_id_t c = 0; c < numOfCols; ++c) { @@ -262,8 +334,17 @@ TEST(testCase, tSmaInsertTest) { } STSmaColData *pColData = (STSmaColData *)POINTER_SHIFT(pSmaData, len + tableDataLen); pColData->colId = c + PRIMARYKEY_TIMESTAMP_COL_ID; - pColData->blockSize = ((c & 1) == 0) ? 8 : 16; + // TODO: fill col data + if ((c & 1) == 0) { + pColData->blockSize = 8; + memcpy(pColData->data, &testSmaData1, 8); + } else { + pColData->blockSize = 16; + memcpy(pColData->data, &testSmaData1, 8); + memcpy(POINTER_SHIFT(pColData->data, 8), &testSmaData2, 8); + } + tableDataLen += (sizeof(STSmaColData) + pColData->blockSize); } pTbData->dataLen = (tableDataLen - sizeof(STSmaTbData)); @@ -277,8 +358,24 @@ TEST(testCase, tSmaInsertTest) { // execute EXPECT_EQ(tsdbInsertTSmaData(&tsdb, (char *)pSmaData), TSDB_CODE_SUCCESS); - // release + // step 3: query + uint32_t checkDataCnt = 0; + for (int32_t t = 0; t < numOfTables; ++t) { + for (col_id_t c = 0; c < numOfCols; ++c) { + EXPECT_EQ(tsdbGetTSmaData(&tsdb, NULL, indexUid1, interval1, intervalUnit1, tbUid + t, + c + PRIMARYKEY_TIMESTAMP_COL_ID, skey1, 1), + TSDB_CODE_SUCCESS); + ++checkDataCnt; + } + } + + printf("%s:%d The sma data check count for insert and query is %" PRIu32 "\n", __FILE__, __LINE__, checkDataCnt); + + // release data taosTZfree(buf); + // release meta + tdDestroyTSma(&tSma); + metaClose(pMeta); } #endif diff --git a/source/libs/executor/inc/executil.h b/source/libs/executor/inc/executil.h index b34067ba4e..bcbfeb7015 100644 --- a/source/libs/executor/inc/executil.h +++ b/source/libs/executor/inc/executil.h @@ -50,7 +50,7 @@ typedef struct SGroupResInfo { int32_t totalGroup; int32_t currentGroup; int32_t index; - SArray* pRows; // SArray + SArray* pRows; // SArray bool ordered; int32_t position; } SGroupResInfo; @@ -67,10 +67,15 @@ typedef struct SResultRow { char *key; // start key of current result row } SResultRow; +typedef struct SResultRowPosition { + int32_t pageId; + int32_t offset; +} SResultRowPosition; + typedef struct SResultRowInfo { - SList* pRows; - SResultRow** pResult; // result list -// int16_t type:8; // data type for hash key + SList *pRows; + SResultRowPosition *pPosition; + SResultRow **pResult; // result list int32_t size; // number of result set int32_t capacity; // max capacity int32_t curPos; // current active result row index of pResult list @@ -131,7 +136,7 @@ static FORCE_INLINE char* getPosInResultPage_rv(SFilePage* page, int32_t rowOffs assert(rowOffset >= 0); int32_t numOfRows = 1;//(int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery); - return ((char *)page->data) + rowOffset + offset * numOfRows; + return (char*) page + rowOffset + offset * numOfRows; } //bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type); @@ -139,12 +144,7 @@ static FORCE_INLINE char* getPosInResultPage_rv(SFilePage* page, int32_t rowOffs __filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr); -SResultRowPool* initResultRowPool(size_t size); SResultRow* getNewResultRow(SResultRowPool* p); -int64_t getResultRowPoolMemSize(SResultRowPool* p); -void* destroyResultRowPool(SResultRowPool* p); -int32_t getNumOfAllocatedResultRows(SResultRowPool* p); -int32_t getNumOfUsedResultRows(SResultRowPool* p); typedef struct { SArray* pResult; // SArray diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index ee841e3ce9..833ac13226 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -240,12 +240,12 @@ typedef struct STaskAttr { SArray* pUdfInfo; // no need to free } STaskAttr; -typedef int32_t (*__optr_open_fn_t)(void* param); -typedef SSDataBlock* (*__optr_fn_t)(void* param, bool* newgroup); -typedef void (*__optr_close_fn_t)(void* param, int32_t num); - struct SOperatorInfo; +typedef int32_t (*__optr_open_fn_t)(struct SOperatorInfo* param); +typedef SSDataBlock* (*__optr_fn_t)(struct SOperatorInfo* param, bool* newgroup); +typedef void (*__optr_close_fn_t)(void* param, int32_t num); + typedef struct STaskIdInfo { uint64_t queryId; // this is also a request id uint64_t subplanId; @@ -275,36 +275,36 @@ typedef struct SExecTaskInfo { } SExecTaskInfo; typedef struct STaskRuntimeEnv { - jmp_buf env; - STaskAttr* pQueryAttr; - uint32_t status; // query status - void* qinfo; - uint8_t scanFlag; // denotes reversed scan of data or not - void* pTsdbReadHandle; + jmp_buf env; + STaskAttr* pQueryAttr; + uint32_t status; // query status + void* qinfo; + uint8_t scanFlag; // denotes reversed scan of data or not + void* pTsdbReadHandle; - int32_t prevGroupId; // previous executed group id - bool enableGroupData; - SDiskbasedBuf* pResultBuf; // query result buffer based on blocked-wised disk file - SHashObj* pResultRowHashTable; // quick locate the window object for each result - SHashObj* pResultRowListSet; // used to check if current ResultRowInfo has ResultRow object or not - SArray* pResultRowArrayList; // The array list that contains the Result rows - char* keyBuf; // window key buffer + int32_t prevGroupId; // previous executed group id + bool enableGroupData; + SDiskbasedBuf* pResultBuf; // query result buffer based on blocked-wised disk file + SHashObj* pResultRowHashTable; // quick locate the window object for each result + SHashObj* pResultRowListSet; // used to check if current ResultRowInfo has ResultRow object or not + SArray* pResultRowArrayList; // The array list that contains the Result rows + char* keyBuf; // window key buffer // The window result objects pool, all the resultRow Objects are allocated and managed by this object. - char** prevRow; + char** prevRow; SResultRowPool* pool; - SArray* prevResult; // intermediate result, SArray - STSBuf* pTsBuf; // timestamp filter list - STSCursor cur; + SArray* prevResult; // intermediate result, SArray + STSBuf* pTsBuf; // timestamp filter list + STSCursor cur; - char* tagVal; // tag value of current data block + char* tagVal; // tag value of current data block struct SScalarFunctionSupport* scalarSup; SSDataBlock* outputBuf; STableGroupInfo tableqinfoGroupInfo; // this is a group array list, including SArray structure struct SOperatorInfo* proot; - SGroupResInfo groupResInfo; - int64_t currentOffset; // dynamic offset value + SGroupResInfo groupResInfo; + int64_t currentOffset; // dynamic offset value STableQueryInfo* current; SRspResultInfo resultInfo; @@ -328,7 +328,7 @@ typedef struct SOperatorInfo { char* name; // name, used to show the query execution plan void* info; // extension attribution SExprInfo* pExpr; - STaskRuntimeEnv* pRuntimeEnv; // todo remove it + STaskRuntimeEnv* pRuntimeEnv; // todo remove it SExecTaskInfo* pTaskInfo; SOperatorCostInfo cost; @@ -365,28 +365,6 @@ typedef struct SQInfo { STaskCostInfo summary; } SQInfo; -typedef struct STaskParam { - char* sql; - char* tagCond; - char* colCond; - char* tbnameCond; - char* prevResult; - SArray* pTableIdList; - SExprBasicInfo** pExpr; - SExprBasicInfo** pSecExpr; - SExprInfo* pExprs; - SExprInfo* pSecExprs; - - SFilterInfo* pFilters; - - SColIndex* pGroupColIndex; - SColumnInfo* pTagColumnInfo; - SGroupbyExpr* pGroupbyExpr; - int32_t tableScanOperator; - SArray* pOperator; - struct SUdfInfo* pUdfInfo; -} STaskParam; - enum { EX_SOURCE_DATA_NOT_READY = 0x1, EX_SOURCE_DATA_READY = 0x2, @@ -472,75 +450,75 @@ typedef struct SSysTableScanInfo { } SSysTableScanInfo; typedef struct SOptrBasicInfo { - SResultRowInfo resultRowInfo; - int32_t* rowCellInfoOffset; // offset value for each row result cell info - SqlFunctionCtx* pCtx; - SSDataBlock* pRes; - int32_t capacity; + SResultRowInfo resultRowInfo; + int32_t* rowCellInfoOffset; // offset value for each row result cell info + SqlFunctionCtx* pCtx; + SSDataBlock* pRes; + int32_t capacity; } SOptrBasicInfo; //TODO move the resultrowsiz together with SOptrBasicInfo:rowCellInfoOffset typedef struct SAggSupporter { - SHashObj* pResultRowHashTable; // quick locate the window object for each result - SHashObj* pResultRowListSet; // used to check if current ResultRowInfo has ResultRow object or not - SArray* pResultRowArrayList; // The array list that contains the Result rows - char* keyBuf; // window key buffer - SResultRowPool *pool; // The window result objects pool, all the resultRow Objects are allocated and managed by this object. - int32_t resultRowSize; // the result buffer size for each result row, with the meta data size for each row + SHashObj* pResultRowHashTable; // quick locate the window object for each result + SHashObj* pResultRowListSet; // used to check if current ResultRowInfo has ResultRow object or not + SArray* pResultRowArrayList; // The array list that contains the Result rows + char* keyBuf; // window key buffer + SDiskbasedBuf *pResultBuf; // query result buffer based on blocked-wised disk file + int32_t resultRowSize; // the result buffer size for each result row, with the meta data size for each row } SAggSupporter; typedef struct STableIntervalOperatorInfo { - SOptrBasicInfo binfo; - SDiskbasedBuf *pResultBuf; // query result buffer based on blocked-wised disk file - SGroupResInfo groupResInfo; - SInterval interval; - STimeWindow win; - int32_t precision; - bool timeWindowInterpo; - char **pRow; - SAggSupporter aggSup; - STableQueryInfo *pCurrent; - int32_t order; + SOptrBasicInfo binfo; + SGroupResInfo groupResInfo; + SInterval interval; + STimeWindow win; + int32_t precision; + bool timeWindowInterpo; + char **pRow; + SAggSupporter aggSup; + STableQueryInfo *pCurrent; + int32_t order; } STableIntervalOperatorInfo; typedef struct SAggOperatorInfo { - SOptrBasicInfo binfo; - SDiskbasedBuf *pResultBuf; // query result buffer based on blocked-wised disk file - SAggSupporter aggSup; - STableQueryInfo *current; - uint32_t groupId; - SGroupResInfo groupResInfo; - STableQueryInfo *pTableQueryInfo; + SOptrBasicInfo binfo; + SDiskbasedBuf *pResultBuf; // query result buffer based on blocked-wised disk file + SAggSupporter aggSup; + STableQueryInfo *current; + uint32_t groupId; + SGroupResInfo groupResInfo; + STableQueryInfo *pTableQueryInfo; } SAggOperatorInfo; typedef struct SProjectOperatorInfo { - SOptrBasicInfo binfo; - SSDataBlock* existDataBlock; + SOptrBasicInfo binfo; + SSDataBlock *existDataBlock; + int32_t threshold; + bool hasVarCol; } SProjectOperatorInfo; typedef struct SLimitOperatorInfo { - int64_t limit; - int64_t total; + SLimit limit; + int64_t currentOffset; + int64_t currentRows; } SLimitOperatorInfo; typedef struct SSLimitOperatorInfo { - int64_t groupTotal; - int64_t currentGroupOffset; - - int64_t rowsTotal; - int64_t currentOffset; - SLimit limit; - SLimit slimit; - - char** prevRow; - SArray* orderColumnList; - bool hasPrev; - bool ignoreCurrentGroup; - bool multigroupResult; - SSDataBlock* pRes; // result buffer - SSDataBlock* pPrevBlock; - int64_t capacity; - int64_t threshold; + int64_t groupTotal; + int64_t currentGroupOffset; + int64_t rowsTotal; + int64_t currentOffset; + SLimit limit; + SLimit slimit; + char** prevRow; + SArray* orderColumnList; + bool hasPrev; + bool ignoreCurrentGroup; + bool multigroupResult; + SSDataBlock* pRes; // result buffer + SSDataBlock* pPrevBlock; + int64_t capacity; + int64_t threshold; } SSLimitOperatorInfo; typedef struct SFilterOperatorInfo { @@ -563,14 +541,15 @@ typedef struct SGroupbyOperatorInfo { char* prevData; // previous group by value } SGroupbyOperatorInfo; -typedef struct SSWindowOperatorInfo { +typedef struct SSessionAggOperatorInfo { SOptrBasicInfo binfo; + SAggSupporter aggSup; STimeWindow curWindow; // current time window TSKEY prevTs; // previous timestamp int32_t numOfRows; // number of rows int32_t start; // start row index bool reptScan; // next round scan -} SSWindowOperatorInfo; +} SSessionAggOperatorInfo; typedef struct SStateWindowOperatorInfo { SOptrBasicInfo binfo; @@ -582,23 +561,6 @@ typedef struct SStateWindowOperatorInfo { bool reptScan; } SStateWindowOperatorInfo; -typedef struct SDistinctDataInfo { - int32_t index; - int32_t type; - int32_t bytes; -} SDistinctDataInfo; - -typedef struct SDistinctOperatorInfo { - SHashObj* pSet; - SSDataBlock* pRes; - bool recordNullVal; // has already record the null value, no need to try again - int64_t threshold; - int64_t outputCapacity; - int32_t totalBytes; - char* buf; - SArray* pDistinctDataInfo; -} SDistinctOperatorInfo; - typedef struct SSortedMergeOperatorInfo { SOptrBasicInfo binfo; bool hasVarCol; @@ -624,45 +586,61 @@ typedef struct SSortedMergeOperatorInfo { } SSortedMergeOperatorInfo; typedef struct SOrderOperatorInfo { - uint32_t sortBufSize; // max buffer size for in-memory sort - SSDataBlock *pDataBlock; - bool hasVarCol; // has variable length column, such as binary/varchar/nchar - SArray *orderInfo; - bool nullFirst; - SSortHandle *pSortHandle; - - int32_t bufPageSize; - int32_t numOfRowsInRes; + uint32_t sortBufSize; // max buffer size for in-memory sort + SSDataBlock *pDataBlock; + bool hasVarCol; // has variable length column, such as binary/varchar/nchar + SArray *orderInfo; + bool nullFirst; + SSortHandle *pSortHandle; + int32_t bufPageSize; + int32_t numOfRowsInRes; // TODO extact struct - int64_t startTs; // sort start time - uint64_t sortElapsed; // sort elapsed time, time to flush to disk not included. - uint64_t totalSize; // total load bytes from remote - uint64_t totalRows; // total number of rows - uint64_t totalElapsed; // total elapsed time + int64_t startTs; // sort start time + uint64_t sortElapsed; // sort elapsed time, time to flush to disk not included. + uint64_t totalSize; // total load bytes from remote + uint64_t totalRows; // total number of rows + uint64_t totalElapsed; // total elapsed time } SOrderOperatorInfo; +typedef struct SDistinctDataInfo { + int32_t index; + int32_t type; + int32_t bytes; +} SDistinctDataInfo; + +typedef struct SDistinctOperatorInfo { + SHashObj* pSet; + SSDataBlock* pRes; + bool recordNullVal; // has already record the null value, no need to try again + int64_t threshold; + int64_t outputCapacity; + int32_t totalBytes; + char* buf; + SArray* pDistinctDataInfo; +} SDistinctOperatorInfo; + SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo); SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, int32_t reverseTime, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv); -SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo); -SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo); -SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createOrderOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SArray* pOrderVal, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SArray* pExprInfo, SArray* pOrderVal, SArray* pGroupInfo, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, + SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo); +SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo); +SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createOrderOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SArray* pOrderVal, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo, int32_t num, SArray* pOrderVal, SArray* pGroupInfo, SExecTaskInfo* pTaskInfo); SOperatorInfo* createSysTableScanOperatorInfo(void* pSysTableReadHandle, const SArray* pExprInfo, const SSchema* pSchema, int32_t tableType, SEpSet epset, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createLimitOperatorInfo(SOperatorInfo* downstream, int32_t numOfDownstream, SLimit* pLimit, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream); -SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SInterval* pInterval, SExecTaskInfo* pTaskInfo); - -SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream); +SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SInterval* pInterval, + const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv); SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, - int32_t numOfOutput); + SOperatorInfo* createFillOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult); SOperatorInfo* createGroupbyOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, @@ -699,16 +677,13 @@ SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numO void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols); void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order); -void finalizeQueryResult(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, - int32_t* rowCellInfoOffset); +void finalizeQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput); + void clearOutputBuf(SOptrBasicInfo* pBInfo, int32_t* bufCapacity); void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput); int32_t createQueryFilter(char* data, uint16_t len, SFilterInfo** pFilters); -int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, STaskParam* param, char* start, - int32_t prevResultLen, void* merger); - int32_t createFilterInfo(STaskAttr* pQueryAttr, uint64_t qId); void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters); diff --git a/source/libs/executor/src/dataDispatcher.c b/source/libs/executor/src/dataDispatcher.c index a2e526c2bd..a0ee048d82 100644 --- a/source/libs/executor/src/dataDispatcher.c +++ b/source/libs/executor/src/dataDispatcher.c @@ -115,7 +115,8 @@ static bool allocBuf(SDataDispatchHandle* pDispatcher, const SInputData* pInput, return false; } - pBuf->allocSize = sizeof(SRetrieveTableRsp) + pDispatcher->pSchema->resultRowSize * pInput->pData->info.rows; + // struct size + data payload + length for each column + pBuf->allocSize = sizeof(SRetrieveTableRsp) + pDispatcher->pSchema->resultRowSize * pInput->pData->info.rows + pInput->pData->info.numOfCols * sizeof(int32_t); pBuf->pData = malloc(pBuf->allocSize); if (pBuf->pData == NULL) { qError("SinkNode failed to malloc memory, size:%d, code:%d", pBuf->allocSize, TAOS_SYSTEM_ERROR(errno)); diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 9d77e23d38..a04a10ef95 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -59,7 +59,8 @@ int32_t initResultRowInfo(SResultRowInfo *pResultRowInfo, int32_t size) { pResultRowInfo->capacity = size; pResultRowInfo->pResult = calloc(pResultRowInfo->capacity, POINTER_BYTES); - if (pResultRowInfo->pResult == NULL) { + pResultRowInfo->pPosition = calloc(pResultRowInfo->capacity, sizeof(SResultRowPosition)); + if (pResultRowInfo->pResult == NULL || pResultRowInfo->pPosition == NULL) { return TSDB_CODE_QRY_OUT_OF_MEMORY; } @@ -182,22 +183,6 @@ size_t getResultRowSize(SqlFunctionCtx* pCtx, int32_t numOfOutput) { return rowSize; } -SResultRowPool* initResultRowPool(size_t size) { - SResultRowPool* p = calloc(1, sizeof(SResultRowPool)); - if (p == NULL) { - return NULL; - } - - p->numOfElemPerBlock = 128; - - p->elemSize = (int32_t) size; - p->blockSize = p->numOfElemPerBlock * p->elemSize; - p->position.pos = 0; - - p->pData = taosArrayInit(8, POINTER_BYTES); - return p; -} - SResultRow* getNewResultRow(SResultRowPool* p) { if (p == NULL) { return NULL; @@ -221,132 +206,6 @@ SResultRow* getNewResultRow(SResultRowPool* p) { return ptr; } -int64_t getResultRowPoolMemSize(SResultRowPool* p) { - if (p == NULL) { - return 0; - } - - return taosArrayGetSize(p->pData) * p->blockSize; -} - -int32_t getNumOfAllocatedResultRows(SResultRowPool* p) { - return (int32_t) taosArrayGetSize(p->pData) * p->numOfElemPerBlock; -} - -int32_t getNumOfUsedResultRows(SResultRowPool* p) { - return getNumOfAllocatedResultRows(p) - p->numOfElemPerBlock + p->position.pos; -} - -void* destroyResultRowPool(SResultRowPool* p) { - if (p == NULL) { - return NULL; - } - - size_t size = taosArrayGetSize(p->pData); - for(int32_t i = 0; i < size; ++i) { - void** ptr = taosArrayGet(p->pData, i); - tfree(*ptr); - } - - taosArrayDestroy(p->pData); - - tfree(p); - return NULL; -} - -void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen) { - uint32_t numOfGroup = (uint32_t) taosArrayGetSize(pRes); - tbufWriteUint32(bw, numOfGroup); - tbufWriteUint16(bw, tagLen); - - for(int32_t i = 0; i < numOfGroup; ++i) { - SInterResult* pOne = taosArrayGet(pRes, i); - if (tagLen > 0) { - tbufWriteBinary(bw, pOne->tags, tagLen); - } - - uint32_t numOfCols = (uint32_t) taosArrayGetSize(pOne->pResult); - tbufWriteUint32(bw, numOfCols); - for(int32_t j = 0; j < numOfCols; ++j) { - SStddevInterResult* p = taosArrayGet(pOne->pResult, j); - uint32_t numOfRows = (uint32_t) taosArrayGetSize(p->pResult); - - tbufWriteUint16(bw, p->colId); - tbufWriteUint32(bw, numOfRows); - - for(int32_t k = 0; k < numOfRows; ++k) { -// SResPair v = *(SResPair*) taosArrayGet(p->pResult, k); -// tbufWriteDouble(bw, v.avg); -// tbufWriteInt64(bw, v.key); - } - } - } -} - -SArray* interResFromBinary(const char* data, int32_t len) { - SBufferReader br = tbufInitReader(data, len, false); - uint32_t numOfGroup = tbufReadUint32(&br); - uint16_t tagLen = tbufReadUint16(&br); - - char* tag = NULL; - if (tagLen > 0) { - tag = calloc(1, tagLen); - } - - SArray* pResult = taosArrayInit(4, sizeof(SInterResult)); - - for(int32_t i = 0; i < numOfGroup; ++i) { - if (tagLen > 0) { - memset(tag, 0, tagLen); - tbufReadToBinary(&br, tag, tagLen); - } - - uint32_t numOfCols = tbufReadUint32(&br); - - SArray* p = taosArrayInit(numOfCols, sizeof(SStddevInterResult)); - for(int32_t j = 0; j < numOfCols; ++j) { -// int16_t colId = tbufReadUint16(&br); - int32_t numOfRows = tbufReadUint32(&br); - -// SStddevInterResult interRes = {.colId = colId, .pResult = taosArrayInit(4, sizeof(struct SResPair)),}; - for(int32_t k = 0; k < numOfRows; ++k) { -// SResPair px = {0}; -// px.avg = tbufReadDouble(&br); -// px.key = tbufReadInt64(&br); -// -// taosArrayPush(interRes.pResult, &px); - } - -// taosArrayPush(p, &interRes); - } - - char* p1 = NULL; - if (tagLen > 0) { - p1 = malloc(tagLen); - memcpy(p1, tag, tagLen); - } - - SInterResult d = {.pResult = p, .tags = p1,}; - taosArrayPush(pResult, &d); - } - - tfree(tag); - return pResult; -} - -void freeInterResult(void* param) { - SInterResult* pResult = (SInterResult*) param; - tfree(pResult->tags); - - int32_t numOfCols = (int32_t) taosArrayGetSize(pResult->pResult); - for(int32_t i = 0; i < numOfCols; ++i) { - SStddevInterResult *p = taosArrayGet(pResult->pResult, i); - taosArrayDestroy(p->pResult); - } - - taosArrayDestroy(pResult->pResult); -} - void cleanupGroupResInfo(SGroupResInfo* pGroupResInfo) { assert(pGroupResInfo != NULL); @@ -360,7 +219,7 @@ void initGroupResInfo(SGroupResInfo* pGroupResInfo, SResultRowInfo* pResultInfo) taosArrayDestroy(pGroupResInfo->pRows); } - pGroupResInfo->pRows = taosArrayFromList(pResultInfo->pResult, pResultInfo->size, POINTER_BYTES); + pGroupResInfo->pRows = taosArrayFromList(pResultInfo->pPosition, pResultInfo->size, sizeof(SResultRowPosition)); pGroupResInfo->index = 0; assert(pGroupResInfo->index <= getNumOfTotalRes(pGroupResInfo)); } diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 8b0b46dbbd..947fb08ff9 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -26,15 +26,16 @@ #include "tsort.h" #include "ttime.h" +#include "../../function/inc/taggfunction.h" #include "executorimpl.h" #include "function.h" +#include "query.h" #include "tcompare.h" #include "tcompression.h" #include "thash.h" -#include "ttypes.h" -#include "query.h" -#include "vnode.h" #include "tsdb.h" +#include "ttypes.h" +#include "vnode.h" #define IS_MAIN_SCAN(runtime) ((runtime)->scanFlag == MAIN_SCAN) #define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN) @@ -211,6 +212,7 @@ static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput); static void destroySWindowOperatorInfo(void* param, int32_t numOfOutput); static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput); static void destroyAggOperatorInfo(void* param, int32_t numOfOutput); +static void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput); static void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput); static void destroyConditionOperatorInfo(void* param, int32_t numOfOutput); @@ -227,15 +229,14 @@ static void doSetOperatorCompleted(SOperatorInfo* pOperator) { #define OPTR_IS_OPENED(_optr) (((_optr)->status & OP_OPENED) == OP_OPENED) #define OPTR_SET_OPENED(_optr) ((_optr)->status |= OP_OPENED) -static int32_t operatorDummyOpenFn(void* param) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static int32_t operatorDummyOpenFn(SOperatorInfo *pOperator) { OPTR_SET_OPENED(pOperator); return TSDB_CODE_SUCCESS; } static void operatorDummyCloseFn(void* param, int32_t numOfCols) {} -static int32_t doCopyToSDataBlock(SDiskbasedBuf *pBuf, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock, int32_t rowCapacity); +static int32_t doCopyToSDataBlock(SDiskbasedBuf *pBuf, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock, int32_t rowCapacity, int32_t* rowCellOffset); static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock); static int32_t setGroupResultOutputBuf(STaskRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binf, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex); @@ -444,10 +445,12 @@ static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, jmp_buf env) longjmp(env, TSDB_CODE_QRY_OUT_OF_MEMORY); } + pResultRowInfo->pPosition = realloc(pResultRowInfo->pPosition, newCapacity * sizeof(SResultRowPosition)); pResultRowInfo->pResult = (SResultRow **)t; int32_t inc = (int32_t)newCapacity - pResultRowInfo->capacity; memset(&pResultRowInfo->pResult[pResultRowInfo->capacity], 0, POINTER_BYTES * inc); + memset(&pResultRowInfo->pPosition[pResultRowInfo->capacity], 0, sizeof(SResultRowPosition)); pResultRowInfo->capacity = (int32_t)newCapacity; } @@ -564,7 +567,47 @@ static SResultRow* doSetResultOutBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultR return pResultRowInfo->pResult[pResultRowInfo->curPos]; } -static SResultRow* doSetResultOutBufByKey_rv(SResultRowInfo* pResultRowInfo, int64_t tid, char* pData, int16_t bytes, +SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) { + SFilePage *pData = NULL; + + // in the first scan, new space needed for results + int32_t pageId = -1; + SIDList list = getDataBufPagesIdList(pResultBuf, tableGroupId); + + if (taosArrayGetSize(list) == 0) { + pData = getNewBufPage(pResultBuf, tableGroupId, &pageId); + pData->num = sizeof(SFilePage); + } else { + SPageInfo* pi = getLastPageInfo(list); + pData = getBufPage(pResultBuf, getPageId(pi)); + pageId = getPageId(pi); + + if (pData->num + interBufSize + sizeof(SResultRow) > getBufPageSize(pResultBuf)) { + // release current page first, and prepare the next one + releaseBufPageInfo(pResultBuf, pi); + + pData = getNewBufPage(pResultBuf, tableGroupId, &pageId); + if (pData != NULL) { + pData->num = sizeof(SFilePage); + } + } + } + + if (pData == NULL) { + return NULL; + } + + // set the number of rows in current disk page + SResultRow* pResultRow = (SResultRow*)((char*)pData + pData->num); + pResultRow->pageId = pageId; + pResultRow->offset = (int32_t)pData->num; + + pData->num += interBufSize + sizeof(SResultRow); + + return pResultRow; +} + +static SResultRow* doSetResultOutBufByKey_rv(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, int64_t tid, char* pData, int16_t bytes, bool masterscan, uint64_t tableGroupId, SExecTaskInfo* pTaskInfo, bool isIntervalQuery, SAggSupporter* pSup) { bool existed = false; SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, tableGroupId); @@ -608,7 +651,7 @@ static SResultRow* doSetResultOutBufByKey_rv(SResultRowInfo* pResultRowInfo, int SResultRow *pResult = NULL; if (p1 == NULL) { - pResult = getNewResultRow(pSup->pool); + pResult = getNewResultRow_rv(pResultBuf, tableGroupId, pSup->resultRowSize); int32_t ret = initResultRow(pResult); if (ret != TSDB_CODE_SUCCESS) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -623,6 +666,7 @@ static SResultRow* doSetResultOutBufByKey_rv(SResultRowInfo* pResultRowInfo, int } pResultRowInfo->curPos = pResultRowInfo->size; + pResultRowInfo->pPosition[pResultRowInfo->size] = (SResultRowPosition) {.pageId = pResult->pageId, .offset = pResult->offset}; pResultRowInfo->pResult[pResultRowInfo->size++] = pResult; int64_t index = pResultRowInfo->curPos; @@ -742,6 +786,7 @@ static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedBuf *pRes if (taosArrayGetSize(list) == 0) { pData = getNewBufPage(pResultBuf, tid, &pageId); + pData->num = sizeof(SFilePage); } else { SPageInfo* pi = getLastPageInfo(list); pData = getBufPage(pResultBuf, getPageId(pi)); @@ -750,9 +795,10 @@ static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedBuf *pRes if (pData->num + size > getBufPageSize(pResultBuf)) { // release current page first, and prepare the next one releaseBufPageInfo(pResultBuf, pi); + pData = getNewBufPage(pResultBuf, tid, &pageId); if (pData != NULL) { - assert(pData->num == 0); // number of elements must be 0 for new allocated buffer + pData->num = sizeof(SFilePage); } } } @@ -812,9 +858,9 @@ static void setResultRowOutputBufInitCtx_rv(SDiskbasedBuf * pBuf, SResultRow *pR static int32_t setResultOutputBufByKey_rv(SResultRowInfo *pResultRowInfo, int64_t id, STimeWindow *win, bool masterscan, SResultRow **pResult, int64_t tableGroupId, SqlFunctionCtx* pCtx, - int32_t numOfOutput, int32_t* rowCellInfoOffset, SDiskbasedBuf *pBuf, SAggSupporter *pAggSup, SExecTaskInfo* pTaskInfo) { + int32_t numOfOutput, int32_t* rowCellInfoOffset, SAggSupporter *pAggSup, SExecTaskInfo* pTaskInfo) { assert(win->skey <= win->ekey); - SResultRow *pResultRow = doSetResultOutBufByKey_rv(pResultRowInfo, id, (char *)&win->skey, TSDB_KEYSIZE, masterscan, tableGroupId, + SResultRow *pResultRow = doSetResultOutBufByKey_rv(pAggSup->pResultBuf, pResultRowInfo, id, (char *)&win->skey, TSDB_KEYSIZE, masterscan, tableGroupId, pTaskInfo, true, pAggSup); if (pResultRow == NULL) { @@ -822,19 +868,10 @@ static int32_t setResultOutputBufByKey_rv(SResultRowInfo *pResultRowInfo, int64_ return TSDB_CODE_SUCCESS; } - // not assign result buffer yet, add new result buffer - if (pResultRow->pageId == -1) { // todo intermediate result size - int32_t ret = addNewWindowResultBuf(pResultRow, pBuf, (int32_t) tableGroupId, 0); - if (ret != TSDB_CODE_SUCCESS) { - return -1; - } - } - // set time window for current result pResultRow->win = (*win); *pResult = pResultRow; - setResultRowOutputBufInitCtx_rv(pBuf, pResultRow, pCtx, numOfOutput, rowCellInfoOffset); - + setResultRowOutputBufInitCtx_rv(pAggSup->pResultBuf, pResultRow, pCtx, numOfOutput, rowCellInfoOffset); return TSDB_CODE_SUCCESS; } @@ -988,20 +1025,21 @@ static int32_t getNumOfRowsInTimeWindow(SDataBlockInfo *pDataBlockInfo, TSKEY *p } static void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, int32_t forwardStep, TSKEY* tsCol, - int32_t numOfTotal, int32_t numOfOutput, int32_t order) { + int32_t numOfTotal, int32_t numOfOutput, int32_t order) { for (int32_t k = 0; k < numOfOutput; ++k) { - pCtx[k].size = forwardStep; pCtx[k].startTs = pWin->skey; // keep it temporarialy - int32_t startOffset = pCtx[k].startRow; - bool hasAgg = pCtx[k].isAggSet; + int32_t startOffset = pCtx[k].input.startRowIndex; + bool hasAgg = pCtx[k].input.colDataAggIsSet; + int32_t numOfRows = pCtx[k].input.numOfRows; int32_t pos = (order == TSDB_ORDER_ASC) ? offset : offset - (forwardStep - 1); - pCtx[k].startRow = pos; + pCtx[k].input.startRowIndex = pos; + pCtx[k].input.numOfRows = forwardStep; if (tsCol != NULL) { - pCtx[k].ptsList = &tsCol[pos]; + pCtx[k].ptsList = tsCol; } // not a whole block involved in query processing, statistics data can not be used @@ -1011,12 +1049,13 @@ static void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, int32_t of } if (functionNeedToExecute(&pCtx[k])) { -// pCtx[k].fpSet.process(&pCtx[k]); + pCtx[k].fpSet.process(&pCtx[k]); } // restore it - pCtx[k].isAggSet = hasAgg; - pCtx[k].startRow = startOffset; + pCtx[k].input.colDataAggIsSet = hasAgg; + pCtx[k].input.startRowIndex = startOffset; + pCtx[k].input.numOfRows = numOfRows; } } @@ -1236,26 +1275,15 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunction } } -static void projectApplyFunctions(STaskRuntimeEnv *pRuntimeEnv, SqlFunctionCtx *pCtx, int32_t numOfOutput) { - STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; - +static void projectApplyFunctions(SqlFunctionCtx *pCtx, int32_t numOfOutput) { for (int32_t k = 0; k < numOfOutput; ++k) { - pCtx[k].startTs = pQueryAttr->window.skey; - // Always set the asc order for merge stage process if (pCtx[k].currentStage == MERGE_STAGE) { pCtx[k].order = TSDB_ORDER_ASC; } - - pCtx[k].startTs = pQueryAttr->window.skey; - - if (pCtx[k].functionId < 0) { - // load the script and exec -// SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo; -// doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL); -// } else { +// pCtx[k].fpSet.process(&pCtx[k]); // aAggs[pCtx[k].functionId].xFunction(&pCtx[k]); - } +// } } } @@ -1451,8 +1479,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul if (pSDataBlock->pDataBlock != NULL) { SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, 0); tsCols = (int64_t*) pColDataInfo->pData; - assert(tsCols[0] == pSDataBlock->info.window.skey && - tsCols[pSDataBlock->info.rows - 1] == pSDataBlock->info.window.ekey); + assert(tsCols[0] == pSDataBlock->info.window.skey && tsCols[pSDataBlock->info.rows - 1] == pSDataBlock->info.window.ekey); } int32_t startPos = ascQuery? 0 : (pSDataBlock->info.rows - 1); @@ -1463,7 +1490,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul SResultRow* pResult = NULL; int32_t ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId, pInfo->binfo.pCtx, - numOfOutput, pInfo->binfo.rowCellInfoOffset, pInfo->pResultBuf, &pInfo->aggSup, pTaskInfo); + numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -1485,7 +1512,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul STimeWindow w = pRes->win; ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &w, masterScan, &pResult, - tableGroupId, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, pInfo->pResultBuf, &pInfo->aggSup, pTaskInfo); + tableGroupId, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -1503,7 +1530,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul // restore current time window ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId, pInfo->binfo.pCtx, - numOfOutput, pInfo->binfo.rowCellInfoOffset, pInfo->pResultBuf, &pInfo->aggSup, pTaskInfo); + numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -1523,7 +1550,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul // null data, failed to allocate more memory buffer int32_t code = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &nextWin, masterScan, &pResult, tableGroupId, - pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, pInfo->pResultBuf, &pInfo->aggSup, pTaskInfo); + pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo); if (code != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -1544,7 +1571,6 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul // updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false); } - static void hashAllIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pSDataBlock, int32_t tableGroupId) { STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*) pOperatorInfo->info; @@ -1704,7 +1730,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn tfree(pInfo->prevData); } -static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { +static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; STableQueryInfo* item = pRuntimeEnv->current; @@ -2041,9 +2067,7 @@ static SqlFunctionCtx* createSqlFunctionCtx(STaskRuntimeEnv* pRuntimeEnv, SExprI return pFuncCtx; } -static SqlFunctionCtx* createSqlFunctionCtx_rv(SArray* pExprInfo, int32_t** rowCellInfoOffset) { - size_t numOfOutput = taosArrayGetSize(pExprInfo); - +static SqlFunctionCtx* createSqlFunctionCtx_rv(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowCellInfoOffset) { SqlFunctionCtx * pFuncCtx = (SqlFunctionCtx *)calloc(numOfOutput, sizeof(SqlFunctionCtx)); if (pFuncCtx == NULL) { return NULL; @@ -2056,7 +2080,7 @@ static SqlFunctionCtx* createSqlFunctionCtx_rv(SArray* pExprInfo, int32_t** rowC } for (int32_t i = 0; i < numOfOutput; ++i) { - SExprInfo* pExpr = taosArrayGetP(pExprInfo, i); + SExprInfo* pExpr = &pExprInfo[i]; SExprBasicInfo *pFunct = &pExpr->base; SqlFunctionCtx* pCtx = &pFuncCtx[i]; @@ -2873,6 +2897,8 @@ int32_t loadDataBlock(SExecTaskInfo *pTaskInfo, STableScanInfo* pTableScanInfo, pCost->totalCheckedRows += pBlock->info.rows; pCost->loadBlocks += 1; + *status = BLK_DATA_ALL_NEEDED; + pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL); if (pBlock->pDataBlock == NULL) { return terrno; @@ -3289,10 +3315,9 @@ void switchCtxOrder(SqlFunctionCtx* pCtx, int32_t numOfOutput) { } } +// TODO fix this bug. int32_t initResultRow(SResultRow *pResultRow) { pResultRow->pEntryInfo = (struct SResultRowEntryInfo*)((char*)pResultRow + sizeof(SResultRow)); - pResultRow->pageId = -1; - pResultRow->offset = -1; return TSDB_CODE_SUCCESS; } @@ -3348,7 +3373,7 @@ void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t int64_t tid = 0; int64_t groupId = 0; - SResultRow* pRow = doSetResultOutBufByKey_rv(pResultRowInfo, tid, (char *)&tid, sizeof(tid), true, groupId, pTaskInfo, false, pSup); + SResultRow* pRow = doSetResultOutBufByKey_rv(pSup->pResultBuf, pResultRowInfo, tid, (char *)&tid, sizeof(tid), true, groupId, pTaskInfo, false, pSup); for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) { SColumnInfoData* pData = taosArrayGet(pDataBlock->pDataBlock, i); @@ -3412,11 +3437,11 @@ void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput) int32_t functionId = pCtx[i].functionId; if (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE) { needCopyTs = true; - if (i > 0 && pCtx[i-1].functionId == FUNCTION_TS_DUMMY){ + if (i > 0 && pCtx[i-1].functionId == FUNCTION_TS_DUMMY) { SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i - 1); // find ts data src = pColRes->pData; } - }else if(functionId == FUNCTION_TS_DUMMY) { + } else if(functionId == FUNCTION_TS_DUMMY) { tsNum++; } } @@ -3489,48 +3514,44 @@ static void setupEnvForReverseScan(STableScanInfo *pTableScanInfo, SqlFunctionCt pTableScanInfo->reverseTimes = 0; } -void finalizeQueryResult(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { - int32_t numOfOutput = pOperator->numOfOutput; -// if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow) { -// // for each group result, call the finalize function for each column -// if (pQueryAttr->groupbyColumn) { -// closeAllResultRows(pResultRowInfo); -// } -// -// for (int32_t i = 0; i < pResultRowInfo->size; ++i) { -// SResultRow *buf = pResultRowInfo->pResult[i]; -// if (!isResultRowClosed(pResultRowInfo, i)) { -// continue; -// } -// -// setResultOutputBuf(pRuntimeEnv, buf, pCtx, numOfOutput, rowCellInfoOffset); -// -// for (int32_t j = 0; j < numOfOutput; ++j) { -//// pCtx[j].startTs = buf->win.skey; -//// if (pCtx[j].functionId < 0) { -//// doInvokeUdf(pRuntimeEnv->pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE); -//// } else { -//// aAggs[pCtx[j].functionId].xFinalize(&pCtx[j]); -//// } -// } -// -// -// /* -// * set the number of output results for group by normal columns, the number of output rows usually is 1 except -// * the top and bottom query -// */ -// buf->numOfRows = (uint16_t)getNumOfResult(pCtx, numOfOutput); -// } -// -// } else { - for (int32_t j = 0; j < numOfOutput; ++j) { -// if (pCtx[j].functionId < 0) { -// doInvokeUdf(pRuntimeEnv->pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE); -// } else { - pCtx[j].fpSet.finalize(&pCtx[j]); -// } +void finalizeQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput) { + for (int32_t j = 0; j < numOfOutput; ++j) { + pCtx[j].fpSet.finalize(&pCtx[j]); + } +} + +void finalizeMultiTupleQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf *pBuf, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { + for (int32_t i = 0; i < pResultRowInfo->size; ++i) { + SResultRowPosition* pPos = &pResultRowInfo->pPosition[i]; + + SFilePage* bufPage = getBufPage(pBuf, pPos->pageId); + SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->offset); + if (!isResultRowClosed(pResultRowInfo, i)) { + continue; } -// } + + for (int32_t j = 0; j < numOfOutput; ++j) { + pCtx[j].resultInfo = getResultCell(pRow, j, rowCellInfoOffset); + + struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo; + if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) { + continue; + } + + pCtx[j].fpSet.finalize(&pCtx[j]); + + if (pRow->numOfRows < pResInfo->numOfRes) { + pRow->numOfRows = pResInfo->numOfRes; + } + } + + releaseBufPage(pBuf, bufPage); + /* + * set the number of output results for group by normal columns, the number of output rows usually is 1 except + * the top and bottom query + */ +// buf->numOfRows = (uint16_t)getNumOfResult(pCtx, numOfOutput); + } } static bool hasMainOutput(STaskAttr *pQueryAttr) { @@ -3625,31 +3646,29 @@ void setResultRowOutputBufInitCtx_rv(SDiskbasedBuf * pBuf, SResultRow *pResult, // Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group SFilePage* bufPage = getBufPage(pBuf, pResult->pageId); - int32_t offset = 0; +// int32_t offset = 0; for (int32_t i = 0; i < numOfOutput; ++i) { pCtx[i].resultInfo = getResultCell(pResult, i, rowCellInfoOffset); struct SResultRowEntryInfo* pResInfo = pCtx[i].resultInfo; if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) { - offset += pCtx[i].resDataInfo.bytes; +// offset += pCtx[i].resDataInfo.bytes; continue; } - pCtx[i].pOutput = getPosInResultPage_rv(bufPage, pResult->offset, offset); - offset += pCtx[i].resDataInfo.bytes; +// offset += pCtx[i].resDataInfo.bytes; - int32_t functionId = pCtx[i].functionId; - if (functionId < 0) { - continue; +// int32_t functionId = pCtx[i].functionId; +// if (functionId < 0) { +// continue; +// } +// if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF) { +// if (i > 0) pCtx[i].ptsOutputBuf = pCtx[i - 1].pOutput; +// } + + if (!pResInfo->initialized) { + pCtx[i].fpSet.init(&pCtx[i], pResInfo); } - - if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF) { - if (i > 0) pCtx[i].ptsOutputBuf = pCtx[i - 1].pOutput; - } - - // if (!pResInfo->initialized) { - // aAggs[functionId].init(&pCtx[i], pResInfo); - // } } } @@ -3663,7 +3682,7 @@ void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, i int32_t* rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset; SResultRow* pResultRow = - doSetResultOutBufByKey_rv(pResultRowInfo, tid, (char*)&tableGroupId, sizeof(tableGroupId), true, uid, pTaskInfo, false, &pAggInfo->aggSup); + doSetResultOutBufByKey_rv(pAggInfo->pResultBuf, pResultRowInfo, tid, (char*)&tableGroupId, sizeof(tableGroupId), true, uid, pTaskInfo, false, &pAggInfo->aggSup); assert (pResultRow != NULL); /* @@ -3904,8 +3923,7 @@ void setIntervalQueryRange(STaskRuntimeEnv *pRuntimeEnv, TSKEY key) { * @param pQInfo * @param result */ - -static int32_t doCopyToSDataBlock(SDiskbasedBuf *pBuf, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock, int32_t rowCapacity) { +static int32_t doCopyToSDataBlock(SDiskbasedBuf *pBuf, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock, int32_t rowCapacity, int32_t* rowCellOffset) { int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); int32_t numOfResult = pBlock->info.rows; // there are already exists result rows @@ -3923,13 +3941,19 @@ static int32_t doCopyToSDataBlock(SDiskbasedBuf *pBuf, SGroupResInfo* pGroupResI step = -1; } + int32_t nrows = pBlock->info.rows; + for (int32_t i = start; (i < numOfRows) && (i >= 0); i += step) { - SResultRow* pRow = taosArrayGetP(pGroupResInfo->pRows, i); + SResultRowPosition* pPos = taosArrayGet(pGroupResInfo->pRows, i); + SFilePage *page = getBufPage(pBuf, pPos->pageId); + + SResultRow* pRow = (SResultRow*)((char*)page + pPos->offset); if (pRow->numOfRows == 0) { pGroupResInfo->index += 1; continue; } + // TODO copy multiple rows? int32_t numOfRowsToCopy = pRow->numOfRows; if (numOfResult + numOfRowsToCopy >= rowCapacity) { break; @@ -3937,20 +3961,17 @@ static int32_t doCopyToSDataBlock(SDiskbasedBuf *pBuf, SGroupResInfo* pGroupResI pGroupResInfo->index += 1; - SFilePage *page = getBufPage(pBuf, pRow->pageId); - - int32_t offset = 0; for (int32_t j = 0; j < pBlock->info.numOfCols; ++j) { SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, j); - int32_t bytes = pColInfoData->info.bytes; + SResultRowEntryInfo* pEntryInfo = getResultCell(pRow, j, rowCellOffset); - char *out = pColInfoData->pData + numOfResult * bytes; - char *in = getPosInResultPage_rv(page, pRow->offset, offset); - memcpy(out, in, bytes * numOfRowsToCopy); - - offset += bytes; + char* in = GET_ROWCELL_INTERBUF(pEntryInfo); + colDataAppend(pColInfoData, nrows, in, pEntryInfo->numOfRes == 0); } + releaseBufPage(pBuf, page); + nrows += 1; + numOfResult += numOfRowsToCopy; if (numOfResult == rowCapacity) { // output buffer is full break; @@ -3962,16 +3983,16 @@ static int32_t doCopyToSDataBlock(SDiskbasedBuf *pBuf, SGroupResInfo* pGroupResI return 0; } -static void toSDatablock(SGroupResInfo *pGroupResInfo, SDiskbasedBuf* pBuf, SSDataBlock* pBlock, int32_t rowCapacity) { +static void toSDatablock(SGroupResInfo *pGroupResInfo, SDiskbasedBuf* pBuf, SSDataBlock* pBlock, int32_t rowCapacity, int32_t* rowCellOffset) { assert(pGroupResInfo->currentGroup <= pGroupResInfo->totalGroup); - pBlock->info.rows = 0; + blockDataClearup(pBlock); if (!hasRemainDataInCurrentGroup(pGroupResInfo)) { return; } int32_t orderType = TSDB_ORDER_ASC;//(pQueryAttr->pGroupbyExpr != NULL) ? pQueryAttr->pGroupbyExpr->orderType : TSDB_ORDER_ASC; - doCopyToSDataBlock(pBuf, pGroupResInfo, orderType, pBlock, rowCapacity); + doCopyToSDataBlock(pBuf, pGroupResInfo, orderType, pBlock, rowCapacity, rowCellOffset); // add condition (pBlock->info.rows >= 1) just to runtime happy blockDataUpdateTsWindow(pBlock); @@ -4681,9 +4702,7 @@ static void doCloseAllTimeWindow(STaskRuntimeEnv* pRuntimeEnv) { } } -static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { - SOperatorInfo *pOperator = (SOperatorInfo*) param; - +static SSDataBlock* doTableScanImpl(SOperatorInfo *pOperator, bool* newgroup) { STableScanInfo *pTableScanInfo = pOperator->info; SExecTaskInfo *pTaskInfo = pOperator->pTaskInfo; @@ -4713,7 +4732,7 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { // } // this function never returns error? - uint32_t status; + uint32_t status = BLK_DATA_ALL_NEEDED; int32_t code = loadDataBlock(pTaskInfo, pTableScanInfo, pBlock, &status); // int32_t code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status); if (code != TSDB_CODE_SUCCESS) { @@ -4731,9 +4750,7 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { return NULL; } -static SSDataBlock* doTableScan(void* param, bool *newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; - +static SSDataBlock* doTableScan(SOperatorInfo *pOperator, bool *newgroup) { STableScanInfo *pTableScanInfo = pOperator->info; SExecTaskInfo *pTaskInfo = pOperator->pTaskInfo; @@ -4804,8 +4821,7 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) { return p; } -static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) { - SOperatorInfo *pOperator = (SOperatorInfo*)param; +static SSDataBlock* doBlockInfoScan(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -4852,9 +4868,7 @@ static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) { #endif } -static SSDataBlock* doStreamBlockScan(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*)param; - +static SSDataBlock* doStreamBlockScan(SOperatorInfo *pOperator, bool* newgroup) { // NOTE: this operator never check if current status is done or not SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SStreamBlockScanInfo* pInfo = pOperator->info; @@ -5170,8 +5184,7 @@ static SSDataBlock* seqLoadRemoteData(SOperatorInfo *pOperator) { } } -static int32_t prepareLoadRemoteData(void* param) { - SOperatorInfo *pOperator = (SOperatorInfo*) param; +static int32_t prepareLoadRemoteData(SOperatorInfo *pOperator) { if (OPTR_IS_OPENED(pOperator)) { return TSDB_CODE_SUCCESS; } @@ -5190,15 +5203,12 @@ static int32_t prepareLoadRemoteData(void* param) { return TSDB_CODE_SUCCESS; } -static SSDataBlock* doLoadRemoteData(void* param, bool* newgroup) { - SOperatorInfo *pOperator = (SOperatorInfo*) param; - +static SSDataBlock* doLoadRemoteData(SOperatorInfo *pOperator, bool* newgroup) { SExchangeInfo *pExchangeInfo = pOperator->info; SExecTaskInfo *pTaskInfo = pOperator->pTaskInfo; - int32_t code = pOperator->_openFn(pOperator); - if (code != TSDB_CODE_SUCCESS) { - pTaskInfo->code = code; + pTaskInfo->code = pOperator->_openFn(pOperator); + if (pTaskInfo->code != TSDB_CODE_SUCCESS) { return NULL; } @@ -5248,9 +5258,8 @@ static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) { return TSDB_CODE_SUCCESS; } -// TODO handle the error SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) { - SExchangeInfo* pInfo = calloc(1, sizeof(SExchangeInfo)); + SExchangeInfo* pInfo = calloc(1, sizeof(SExchangeInfo)); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { @@ -5259,11 +5268,9 @@ SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock size_t numOfSources = LIST_LENGTH(pSources); pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode)); - if (pInfo->pSources == NULL) { - tfree(pInfo); - tfree(pOperator); - terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; - return NULL; + pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo)); + if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) { + goto _error; } for(int32_t i = 0; i < numOfSources; ++i) { @@ -5271,16 +5278,6 @@ SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock taosArrayPush(pInfo->pSources, pNode); } - pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo)); - if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) { - tfree(pInfo); - tfree(pOperator); - taosArrayDestroy(pInfo->pSources); - taosArrayDestroy(pInfo->pSourceDataInfo); - terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; - return NULL; - } - int32_t code = initDataSource(numOfSources, pInfo); if (code != TSDB_CODE_SUCCESS) { goto _error; @@ -5331,12 +5328,12 @@ SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock _error: if (pInfo != NULL) { - destroyExchangeOperatorInfo(pInfo, 0); + destroyExchangeOperatorInfo(pInfo, numOfSources); } tfree(pInfo); tfree(pOperator); - terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; + pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY; return NULL; } @@ -5375,7 +5372,7 @@ SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, tfree(pInfo); tfree(pOperator); - terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; + pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY; return NULL; } @@ -5418,7 +5415,7 @@ SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntim pOperator->info = pInfo; pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->getNextFn = doTableScanImpl; + pOperator->getNextFn = doTableScanImpl; return pOperator; } @@ -5497,9 +5494,8 @@ static int32_t loadSysTableContentCb(void* param, const SDataBuf* pMsg, int32_t tsem_post(&pSourceDataInfo->pEx->ready); } -static SSDataBlock* doSysTableScan(void* param, bool* newgroup) { +static SSDataBlock* doSysTableScan(SOperatorInfo *pOperator, bool* newgroup) { // build message and send to mnode to fetch the content of system tables. - SOperatorInfo* pOperator = (SOperatorInfo*) param; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SSysTableScanInfo* pInfo = pOperator->info; @@ -5638,7 +5634,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo; pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset; } else if (pDownstream->operatorType == OP_SessionWindow) { - SSWindowOperatorInfo* pInfo = pDownstream->info; + SSessionAggOperatorInfo* pInfo = pDownstream->info; pTableScanInfo->pCtx = pInfo->binfo.pCtx; pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo; @@ -5730,8 +5726,8 @@ SArray* getResultGroupCheckColumns(STaskAttr* pQuery) { return pOrderColumns; } -static int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx *pCtx, int32_t numOfOutput); -static void clearupAggSup(SAggSupporter* pAggSup); +static int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx *pCtx, int32_t numOfOutput, const char* pKey); +static void cleanupAggSup(SAggSupporter* pAggSup); static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) { SSortedMergeOperatorInfo* pInfo = (SSortedMergeOperatorInfo*) param; @@ -5743,7 +5739,7 @@ static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) { } blockDataDestroy(pInfo->binfo.pRes); - clearupAggSup(&pInfo->aggSup); + cleanupAggSup(&pInfo->aggSup); } static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) { @@ -5798,7 +5794,7 @@ static void appendOneRowToDataBlock(SSDataBlock *pBlock, STupleHandle* pTupleHan } static SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, bool hasVarCol, int32_t capacity) { - blockDataClearup(pDataBlock, hasVarCol); + blockDataClearup(pDataBlock); while(1) { STupleHandle* pTupleHandle = tsortNextTuple(pHandle); @@ -5954,7 +5950,7 @@ static SSDataBlock* doMerge(SOperatorInfo* pOperator) { while(1) { - blockDataClearup(pDataBlock, pInfo->hasVarCol); + blockDataClearup(pDataBlock); while (1) { STupleHandle* pTupleHandle = tsortNextTuple(pHandle); if (pTupleHandle == NULL) { @@ -5989,8 +5985,7 @@ static SSDataBlock* doMerge(SOperatorInfo* pOperator) { return (pInfo->binfo.pRes->info.rows > 0)? pInfo->binfo.pRes:NULL; } -static SSDataBlock* doSortedMerge(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doSortedMerge(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -6024,7 +6019,7 @@ static SSDataBlock* doSortedMerge(void* param, bool* newgroup) { return doMerge(pOperator); } -static SArray* createBlockOrder(SArray* pExprInfo, SArray* pOrderVal) { +static SArray* createBlockOrder(SExprInfo* pExprInfo, int32_t numOfCols, SArray* pOrderVal) { SArray* pOrderInfo = taosArrayInit(1, sizeof(SBlockOrderInfo)); size_t numOfOrder = taosArrayGetSize(pOrderVal); @@ -6033,8 +6028,8 @@ static SArray* createBlockOrder(SArray* pExprInfo, SArray* pOrderVal) { SOrder* pOrder = taosArrayGet(pOrderVal, j); orderInfo.order = pOrder->order; - for (int32_t i = 0; i < taosArrayGetSize(pExprInfo); ++i) { - SExprInfo* pExpr = taosArrayGet(pExprInfo, i); + for (int32_t i = 0; i < numOfCols; ++i) { + SExprInfo* pExpr = &pExprInfo[i]; if (pExpr->base.resSchema.colId == pOrder->col.colId) { orderInfo.colIndex = i; break; @@ -6047,7 +6042,7 @@ static SArray* createBlockOrder(SArray* pExprInfo, SArray* pOrderVal) { return pOrderInfo; } -static int32_t initGroupCol(SArray* pExprInfo, SArray* pGroupInfo, SSortedMergeOperatorInfo* pInfo) { +static int32_t initGroupCol(SExprInfo* pExprInfo, int32_t numOfCols, SArray* pGroupInfo, SSortedMergeOperatorInfo* pInfo) { if (pGroupInfo == NULL || taosArrayGetSize(pGroupInfo) == 0) { return 0; } @@ -6063,8 +6058,8 @@ static int32_t initGroupCol(SArray* pExprInfo, SArray* pGroupInfo, SSortedMergeO size_t numOfGroupCol = taosArrayGetSize(pInfo->groupInfo); for(int32_t i = 0; i < numOfGroupCol; ++i) { SColumn* pCol = taosArrayGet(pGroupInfo, i); - for(int32_t j = 0; j < taosArrayGetSize(pExprInfo); ++j) { - SExprInfo* pe = taosArrayGet(pExprInfo, j); + for(int32_t j = 0; j < numOfCols; ++j) { + SExprInfo* pe = &pExprInfo[j]; if (pe->base.resSchema.colId == pCol->colId) { taosArrayPush(plist, pCol); taosArrayPush(pInfo->groupInfo, &j); @@ -6095,29 +6090,27 @@ static int32_t initGroupCol(SArray* pExprInfo, SArray* pGroupInfo, SSortedMergeO return TSDB_CODE_SUCCESS; } -SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SArray* pExprInfo, SArray* pOrderVal, SArray* pGroupInfo, SExecTaskInfo* pTaskInfo) { +SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo, int32_t num, SArray* pOrderVal, SArray* pGroupInfo, SExecTaskInfo* pTaskInfo) { SSortedMergeOperatorInfo* pInfo = calloc(1, sizeof(SSortedMergeOperatorInfo)); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { goto _error; } - int32_t numOfOutput = taosArrayGetSize(pExprInfo); - pInfo->binfo.pCtx = createSqlFunctionCtx_rv(pExprInfo, &pInfo->binfo.rowCellInfoOffset); - pInfo->binfo.pRes = createOutputBuf_rv(pExprInfo, pInfo->binfo.capacity); + pInfo->binfo.pCtx = createSqlFunctionCtx_rv(pExprInfo, num, &pInfo->binfo.rowCellInfoOffset); initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1); if (pInfo->binfo.pCtx == NULL || pInfo->binfo.pRes == NULL) { goto _error; } - int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, numOfOutput); + int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, num, pTaskInfo->id.str); if (code != TSDB_CODE_SUCCESS) { goto _error; } setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo); - code = initGroupCol(pExprInfo, pGroupInfo, pInfo); + code = initGroupCol(pExprInfo, num, pGroupInfo, pInfo); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -6126,7 +6119,7 @@ SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t // pRuntimeEnv->pQueryAttr->topBotQuery, false)); pInfo->sortBufSize = 1024 * 16; // 1MB pInfo->bufPageSize = 1024; - pInfo->orderInfo = createBlockOrder(pExprInfo, pOrderVal); + pInfo->orderInfo = createBlockOrder(pExprInfo, num, pOrderVal); pInfo->binfo.capacity = blockDataGetCapacityInRow(pInfo->binfo.pRes, pInfo->bufPageSize); @@ -6135,12 +6128,12 @@ SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t pOperator->blockingOptr = true; pOperator->status = OP_NOT_OPENED; pOperator->info = pInfo; - pOperator->numOfOutput = numOfOutput; - pOperator->pExpr = exprArrayDup(pExprInfo); + pOperator->numOfOutput = num; + pOperator->pExpr = pExprInfo; pOperator->pTaskInfo = pTaskInfo; - pOperator->getNextFn = doSortedMerge; - pOperator->closeFn = destroySortedMergeOperatorInfo; + pOperator->getNextFn = doSortedMerge; + pOperator->closeFn = destroySortedMergeOperatorInfo; code = appendDownstream(pOperator, downstream, numOfDownstream); if (code != TSDB_CODE_SUCCESS) { @@ -6151,7 +6144,7 @@ SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t _error: if (pInfo != NULL) { - destroySortedMergeOperatorInfo(pInfo, numOfOutput); + destroySortedMergeOperatorInfo(pInfo, num); } tfree(pInfo); @@ -6160,8 +6153,7 @@ SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t return NULL; } -static SSDataBlock* doSort(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doSort(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -6194,12 +6186,12 @@ static SSDataBlock* doSort(void* param, bool* newgroup) { return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->hasVarCol, pInfo->numOfRowsInRes); } -SOperatorInfo *createOrderOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SArray* pOrderVal, SExecTaskInfo* pTaskInfo) { +SOperatorInfo *createOrderOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SArray* pOrderVal, SExecTaskInfo* pTaskInfo) { SOrderOperatorInfo* pInfo = calloc(1, sizeof(SOrderOperatorInfo)); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { tfree(pInfo); - + tfree(pOperator); terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; return NULL; } @@ -6208,12 +6200,10 @@ SOperatorInfo *createOrderOperatorInfo(SOperatorInfo* downstream, SArray* pExprI pInfo->bufPageSize = 1024; pInfo->numOfRowsInRes = 1024; - pInfo->pDataBlock = createOutputBuf_rv(pExprInfo, pInfo->numOfRowsInRes); - pInfo->orderInfo = createBlockOrder(pExprInfo, pOrderVal); + pInfo->orderInfo = createBlockOrder(pExprInfo, numOfCols, pOrderVal); - for(int32_t i = 0; i < taosArrayGetSize(pExprInfo); ++i) { - SExprInfo* pExpr = taosArrayGetP(pExprInfo, i); - if (IS_VAR_DATA_TYPE(pExpr->base.resSchema.type)) { + for(int32_t i = 0; i < numOfCols; ++i) { + if (IS_VAR_DATA_TYPE(pExprInfo[i].base.resSchema.type)) { pInfo->hasVarCol = true; break; } @@ -6221,7 +6211,7 @@ SOperatorInfo *createOrderOperatorInfo(SOperatorInfo* downstream, SArray* pExprI if (pInfo->orderInfo == NULL || pInfo->pDataBlock == NULL) { tfree(pOperator); - destroyOrderOperatorInfo(pInfo, taosArrayGetSize(pExprInfo)); + destroyOrderOperatorInfo(pInfo, numOfCols); tfree(pInfo); terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; @@ -6247,46 +6237,63 @@ static int32_t getTableScanOrder(STableScanInfo* pTableScanInfo) { } // this is a blocking operator -static SSDataBlock* doAggregate(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; - if (pOperator->status == OP_EXEC_DONE) { - return NULL; +static int32_t doOpenAggregateOptr(SOperatorInfo *pOperator) { + if (OPTR_IS_OPENED(pOperator)) { + return TSDB_CODE_SUCCESS; } SAggOperatorInfo* pAggInfo = pOperator->info; - SOptrBasicInfo* pInfo = &pAggInfo->binfo; + SOptrBasicInfo* pInfo = &pAggInfo->binfo; - int32_t order = TSDB_ORDER_ASC; + int32_t order = TSDB_ORDER_ASC; SOperatorInfo* downstream = pOperator->pDownstream[0]; - while(1) { + bool newgroup = true; + while (1) { publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup); + SSDataBlock* pBlock = downstream->getNextFn(downstream, &newgroup); publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; } -// if (pAggInfo->current != NULL) { -// setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput); -// } + // if (pAggInfo->current != NULL) { + // setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput); + // } // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); doAggregateImpl(pOperator, 0, pInfo->pCtx); } - doSetOperatorCompleted(pOperator); + finalizeQueryResult(pInfo->pCtx, pOperator->numOfOutput); + + OPTR_SET_OPENED(pOperator); + return TSDB_CODE_SUCCESS; +} + +static SSDataBlock* getAggregateResult(SOperatorInfo *pOperator, bool* newgroup) { + SAggOperatorInfo *pAggInfo = pOperator->info; + SOptrBasicInfo* pInfo = &pAggInfo->binfo; + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SExecTaskInfo *pTaskInfo = pOperator->pTaskInfo; + pTaskInfo->code = pOperator->_openFn(pOperator); + if (pTaskInfo->code != TSDB_CODE_SUCCESS) { + return NULL; + } - finalizeQueryResult(pOperator, pInfo->pCtx, &pInfo->resultRowInfo, pInfo->rowCellInfoOffset); getNumOfResult(pInfo->pCtx, pOperator->numOfOutput, pInfo->pRes); + doSetOperatorCompleted(pOperator); return (blockDataGetNumOfRows(pInfo->pRes) != 0)? pInfo->pRes:NULL; } -static SSDataBlock* doMultiTableAggregate(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doMultiTableAggregate(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -6296,7 +6303,7 @@ static SSDataBlock* doMultiTableAggregate(void* param, bool* newgroup) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; if (pOperator->status == OP_RES_TO_RETURN) { - toSDatablock(&pAggInfo->groupResInfo, pAggInfo->pResultBuf, pInfo->pRes, pAggInfo->binfo.capacity); + toSDatablock(&pAggInfo->groupResInfo, pAggInfo->pResultBuf, pInfo->pRes, pAggInfo->binfo.capacity, pAggInfo->binfo.rowCellInfoOffset); if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) { pOperator->status = OP_EXEC_DONE; @@ -6345,7 +6352,7 @@ static SSDataBlock* doMultiTableAggregate(void* param, bool* newgroup) { updateNumOfRowsInResultRows(pInfo->pCtx, pOperator->numOfOutput, &pInfo->resultRowInfo, pInfo->rowCellInfoOffset); initGroupResInfo(&pAggInfo->groupResInfo, &pInfo->resultRowInfo); - toSDatablock(&pAggInfo->groupResInfo, pAggInfo->pResultBuf, pInfo->pRes, pAggInfo->binfo.capacity); + toSDatablock(&pAggInfo->groupResInfo, pAggInfo->pResultBuf, pInfo->pRes, pAggInfo->binfo.capacity, pAggInfo->binfo.rowCellInfoOffset); if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); @@ -6354,55 +6361,50 @@ static SSDataBlock* doMultiTableAggregate(void* param, bool* newgroup) { return pInfo->pRes; } -static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; - +static SSDataBlock* doProjectOperation(SOperatorInfo *pOperator, bool* newgroup) { SProjectOperatorInfo* pProjectInfo = pOperator->info; - STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; SOptrBasicInfo *pInfo = &pProjectInfo->binfo; SSDataBlock* pRes = pInfo->pRes; - int32_t order = pRuntimeEnv->pQueryAttr->order.order; - - pRes->info.rows = 0; + blockDataClearup(pRes); if (pProjectInfo->existDataBlock) { // TODO refactor - STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; - +// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; SSDataBlock* pBlock = pProjectInfo->existDataBlock; pProjectInfo->existDataBlock = NULL; *newgroup = true; // todo dynamic set tags - if (pTableQueryInfo != NULL) { +// if (pTableQueryInfo != NULL) { // setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); - } +// } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); + setInputDataBlock(pOperator, pInfo->pCtx, pBlock, TSDB_ORDER_ASC); updateOutputBuf(pInfo, &pInfo->capacity, pBlock->info.rows); - projectApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); + projectApplyFunctions(pInfo->pCtx, pOperator->numOfOutput); pRes->info.rows = getNumOfResult(pInfo->pCtx, pOperator->numOfOutput, NULL); - if (pRes->info.rows >= pRuntimeEnv->resultInfo.threshold) { + if (pRes->info.rows >= pProjectInfo->threshold) { copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput); resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput); return pRes; } } + SOperatorInfo* downstream = pOperator->pDownstream[0]; + while(1) { bool prevVal = *newgroup; // The downstream exec may change the value of the newgroup, so use a local variable instead. - publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = pOperator->pDownstream[0]->getNextFn(pOperator->pDownstream[0], newgroup); - publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { assert(*newgroup == false); - *newgroup = prevVal; setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED); break; @@ -6421,75 +6423,76 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { } } - STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; - // todo dynamic set tags - if (pTableQueryInfo != NULL) { -// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); - } + + // STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; + // if (pTableQueryInfo != NULL) { + // setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); + // } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); + setInputDataBlock(pOperator, pInfo->pCtx, pBlock, TSDB_ORDER_ASC); updateOutputBuf(pInfo, &pInfo->capacity, pBlock->info.rows); - projectApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); - pRes->info.rows = getNumOfResult(pInfo->pCtx, pOperator->numOfOutput, NULL); - if (pRes->info.rows >= 1000/*pRuntimeEnv->resultInfo.threshold*/) { + projectApplyFunctions(pInfo->pCtx, pOperator->numOfOutput); +// pRes->info.rows = getNumOfResult(pInfo->pCtx, pOperator->numOfOutput, pRes); + if (pRes->info.rows >= pProjectInfo->threshold) { break; } } + copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput); - resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput); +// resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput); return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; } -static SSDataBlock* doLimit(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*)param; +static SSDataBlock* doLimit(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } SLimitOperatorInfo* pInfo = pOperator->info; - STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; SSDataBlock* pBlock = NULL; + SOperatorInfo* pDownstream = pOperator->pDownstream[0]; + while (1) { - publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); - pBlock = pOperator->pDownstream[0]->getNextFn(pOperator->pDownstream[0], newgroup); - publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + pBlock = pDownstream->getNextFn(pDownstream, newgroup); + publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { doSetOperatorCompleted(pOperator); return NULL; } - if (pRuntimeEnv->currentOffset == 0) { + if (pInfo->currentOffset == 0) { break; - } else if (pRuntimeEnv->currentOffset >= pBlock->info.rows) { - pRuntimeEnv->currentOffset -= pBlock->info.rows; - } else { - int32_t remain = (int32_t)(pBlock->info.rows - pRuntimeEnv->currentOffset); + } else if (pInfo->currentOffset >= pBlock->info.rows) { + pInfo->currentOffset -= pBlock->info.rows; + } else { // TODO handle the data movement + int32_t remain = (int32_t)(pBlock->info.rows - pInfo->currentOffset); pBlock->info.rows = remain; for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); int16_t bytes = pColInfoData->info.bytes; - memmove(pColInfoData->pData, pColInfoData->pData + bytes * pRuntimeEnv->currentOffset, remain * bytes); + memmove(pColInfoData->pData, pColInfoData->pData + bytes * pInfo->currentOffset, remain * bytes); } - pRuntimeEnv->currentOffset = 0; + pInfo->currentOffset = 0; break; } } - if (pInfo->total + pBlock->info.rows >= pInfo->limit) { - pBlock->info.rows = (int32_t)(pInfo->limit - pInfo->total); - pInfo->total = pInfo->limit; + if (pInfo->currentRows + pBlock->info.rows >= pInfo->limit.limit) { + pBlock->info.rows = (int32_t)(pInfo->limit.limit - pInfo->currentRows); + pInfo->currentRows = pInfo->limit.limit; doSetOperatorCompleted(pOperator); } else { - pInfo->total += pBlock->info.rows; + pInfo->currentRows += pBlock->info.rows; } return pBlock; @@ -6526,54 +6529,57 @@ static SSDataBlock* doFilter(void* param, bool* newgroup) { return NULL; } -static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; - if (pOperator->status == OP_EXEC_DONE) { - return NULL; +static int32_t doOpenIntervalAgg(SOperatorInfo *pOperator) { + if (OPTR_IS_OPENED(pOperator)) { + return TSDB_CODE_SUCCESS; } STableIntervalOperatorInfo* pInfo = pOperator->info; - if (pOperator->status == OP_RES_TO_RETURN) { -// toSDatablock(pAggInfo->pGroupResInfo, pAggInfo->pResultBuf, pInfo->pRes, pAggInfo->binfo.capacity); - if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { - doSetOperatorCompleted(pOperator); - } - - return pInfo->binfo.pRes; - } - -// int32_t order = pQueryAttr->order.order; -// STimeWindow win = pQueryAttr->window; + // int32_t order = pQueryAttr->order.order; + // STimeWindow win = pQueryAttr->window; + bool newgroup = false; SOperatorInfo* downstream = pOperator->pDownstream[0]; - while(1) { + while (1) { publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup); + SSDataBlock* pBlock = downstream->getNextFn(downstream, &newgroup); publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; } -// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput); + // setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput); // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC); hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, 0); } - // restore the value -// pQueryAttr->order.order = order; -// pQueryAttr->window = win; - - pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pInfo->binfo.resultRowInfo); - setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED); - finalizeQueryResult(pOperator, pInfo->binfo.pCtx, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); + finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); initGroupResInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo); - toSDatablock(&pInfo->groupResInfo, pInfo->pResultBuf, pInfo->binfo.pRes, pInfo->binfo.capacity); + OPTR_SET_OPENED(pOperator); + return TSDB_CODE_SUCCESS; +} + +static SSDataBlock* doIntervalAgg(SOperatorInfo *pOperator, bool* newgroup) { + STableIntervalOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + pTaskInfo->code = pOperator->_openFn(pOperator); + if (pTaskInfo->code != TSDB_CODE_SUCCESS) { + return NULL; + } + + blockDataEnsureCapacity(pInfo->binfo.pRes, pInfo->binfo.capacity); + toSDatablock(&pInfo->groupResInfo, pInfo->aggSup.pResultBuf, pInfo->binfo.pRes, pInfo->binfo.capacity, pInfo->binfo.rowCellInfoOffset); if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); @@ -6582,8 +6588,7 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { return pInfo->binfo.pRes->info.rows == 0? NULL:pInfo->binfo.pRes; } -static SSDataBlock* doAllIntervalAgg(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doAllIntervalAgg(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -6630,7 +6635,7 @@ static SSDataBlock* doAllIntervalAgg(void* param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pIntervalInfo->binfo.resultRowInfo); setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED); - finalizeQueryResult(pOperator, pIntervalInfo->binfo.pCtx, &pIntervalInfo->binfo.resultRowInfo, pIntervalInfo->binfo.rowCellInfoOffset); + finalizeQueryResult(pIntervalInfo->binfo.pCtx, pOperator->numOfOutput); initGroupResInfo(&pRuntimeEnv->groupResInfo, &pIntervalInfo->binfo.resultRowInfo); // toSDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes); @@ -6642,8 +6647,7 @@ static SSDataBlock* doAllIntervalAgg(void* param, bool* newgroup) { return pIntervalInfo->binfo.pRes->info.rows == 0? NULL:pIntervalInfo->binfo.pRes; } -static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doSTableIntervalAgg(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -6702,8 +6706,7 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { return pIntervalInfo->binfo.pRes; } -static SSDataBlock* doAllSTableIntervalAgg(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doAllSTableIntervalAgg(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -6836,8 +6839,7 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI // pSDataBlock->info.rows, pOperator->numOfOutput); } -static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doStateWindowAgg(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -6882,7 +6884,7 @@ static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pBInfo->resultRowInfo); setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED); - finalizeQueryResult(pOperator, pBInfo->pCtx, &pBInfo->resultRowInfo, pBInfo->rowCellInfoOffset); + finalizeQueryResult(pBInfo->pCtx, pOperator->numOfOutput); initGroupResInfo(&pRuntimeEnv->groupResInfo, &pBInfo->resultRowInfo); // toSDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes); @@ -6894,32 +6896,24 @@ static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) { return pBInfo->pRes->info.rows == 0? NULL:pBInfo->pRes; } -static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doSessionWindowAgg(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } - SSWindowOperatorInfo* pWindowInfo = pOperator->info; + SSessionAggOperatorInfo* pWindowInfo = pOperator->info; SOptrBasicInfo* pBInfo = &pWindowInfo->binfo; - - STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { // toSDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes); - - if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) { + if (pBInfo->pRes->info.rows == 0/* || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)*/) { pOperator->status = OP_EXEC_DONE; } return pBInfo->pRes; } - STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - //pQueryAttr->order.order = TSDB_ORDER_ASC; - int32_t order = pQueryAttr->order.order; - STimeWindow win = pQueryAttr->window; - + int32_t order = TSDB_ORDER_ASC; SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { @@ -6931,31 +6925,26 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQueryAttr->order.order); + setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order); doSessionWindowAggImpl(pOperator, pWindowInfo, pBlock); } // restore the value - pQueryAttr->order.order = order; - pQueryAttr->window = win; - pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pBInfo->resultRowInfo); // setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); - finalizeQueryResult(pOperator, pBInfo->pCtx, &pBInfo->resultRowInfo, pBInfo->rowCellInfoOffset); + finalizeQueryResult(pBInfo->pCtx, pOperator->numOfOutput); - initGroupResInfo(&pRuntimeEnv->groupResInfo, &pBInfo->resultRowInfo); +// initGroupResInfo(&pBInfo->groupResInfo, &pBInfo->resultRowInfo); // toSDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes); - - if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) { + if (pBInfo->pRes->info.rows == 0/* || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)*/) { pOperator->status = OP_EXEC_DONE; } return pBInfo->pRes->info.rows == 0? NULL:pBInfo->pRes; } -static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* hashGroupbyAggregate(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -6998,7 +6987,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { // setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); if (!pRuntimeEnv->pQueryAttr->stableQuery) { // finalize include the update of result rows - finalizeQueryResult(pOperator, pInfo->binfo.pCtx, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); + finalizeQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput); } else { updateNumOfRowsInResultRows(pInfo->binfo.pCtx, pOperator->numOfOutput, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); } @@ -7044,9 +7033,7 @@ static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo *pInfo, STaskRunti } } -static SSDataBlock* doFill(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; - +static SSDataBlock* doFill(SOperatorInfo *pOperator, bool* newgroup) { SFillOperatorInfo *pInfo = pOperator->info; pInfo->pRes->info.rows = 0; @@ -7152,39 +7139,50 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) { tfree(pOperator); } -int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx *pCtx, int32_t numOfOutput) { +int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx *pCtx, int32_t numOfOutput, const char* pKey) { _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); pAggSup->resultRowSize = getResultRowSize(pCtx, numOfOutput); pAggSup->keyBuf = calloc(1, sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES); pAggSup->pResultRowHashTable = taosHashInit(10, hashFn, true, HASH_NO_LOCK); pAggSup->pResultRowListSet = taosHashInit(100, hashFn, false, HASH_NO_LOCK); - pAggSup->pool = initResultRowPool(pAggSup->resultRowSize); pAggSup->pResultRowArrayList = taosArrayInit(10, sizeof(SResultRowCell)); if (pAggSup->keyBuf == NULL || pAggSup->pResultRowArrayList == NULL || pAggSup->pResultRowListSet == NULL || - pAggSup->pResultRowHashTable == NULL || pAggSup->pool == NULL) { + pAggSup->pResultRowHashTable == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } + int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, 4096, 4096 * 256, pKey, "/tmp/"); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + return TSDB_CODE_SUCCESS; } -static void clearupAggSup(SAggSupporter* pAggSup) { +static void cleanupAggSup(SAggSupporter* pAggSup) { tfree(pAggSup->keyBuf); taosHashCleanup(pAggSup->pResultRowHashTable); taosHashCleanup(pAggSup->pResultRowListSet); taosArrayDestroy(pAggSup->pResultRowArrayList); - destroyResultRowPool(pAggSup->pool); + destroyDiskbasedBuf(pAggSup->pResultBuf); } -static int32_t initAggInfo(SAggOperatorInfo* pInfo, SArray* pExprInfo, int32_t numOfRows, SSDataBlock* pResultBlock, const STableGroupInfo* pTableGroupInfo) { - pInfo->binfo.pCtx = createSqlFunctionCtx_rv(pExprInfo, &pInfo->binfo.rowCellInfoOffset); - pInfo->binfo.pRes = pResultBlock; - pInfo->binfo.capacity = numOfRows; +static int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols, + int32_t numOfRows, SSDataBlock* pResultBlock, const char* pkey) { + pBasicInfo->pCtx = createSqlFunctionCtx_rv(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset); + pBasicInfo->pRes = pResultBlock; + pBasicInfo->capacity = numOfRows; - doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, taosArrayGetSize(pExprInfo)); - pInfo->pTableQueryInfo = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo)); + doInitAggInfoSup(pAggSup, pBasicInfo->pCtx, numOfCols, pkey); +} + +static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInfo) { + STableQueryInfo* pTableQueryInfo = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo)); + if (pTableQueryInfo == NULL) { + return NULL; + } int32_t index = 0; for(int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pGroupList); ++i) { @@ -7192,7 +7190,7 @@ static int32_t initAggInfo(SAggOperatorInfo* pInfo, SArray* pExprInfo, int32_t n for(int32_t j = 0; j < taosArrayGetSize(pa); ++j) { STableKeyInfo* pk = taosArrayGet(pa, j); - STableQueryInfo* pTQueryInfo = &pInfo->pTableQueryInfo[index++]; + STableQueryInfo* pTQueryInfo = &pTableQueryInfo[index++]; pTQueryInfo->uid = pk->uid; pTQueryInfo->lastKey = pk->lastKey; pTQueryInfo->groupIndex = i; @@ -7200,36 +7198,53 @@ static int32_t initAggInfo(SAggOperatorInfo* pInfo, SArray* pExprInfo, int32_t n } STimeWindow win = {0, INT64_MAX}; - createTableQueryInfo(pInfo->pTableQueryInfo, false, win); - - return TSDB_CODE_SUCCESS; + createTableQueryInfo(pTableQueryInfo, false, win); + return pTableQueryInfo; } -SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SSDataBlock* pResultBlock, +SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo) { SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo)); + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } - int32_t numOfRows = 1; //(int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); + int32_t numOfRows = 1; + int32_t code = initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, numOfRows, pResultBlock, pTaskInfo->id.str); + pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo); + if (code != TSDB_CODE_SUCCESS || pInfo->pTableQueryInfo == NULL) { + goto _error; + } - initAggInfo(pInfo, pExprInfo, numOfRows, pResultBlock, pTableGroupInfo); setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo); - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableAggregate"; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG; pOperator->blockingOptr = true; pOperator->status = OP_NOT_OPENED; pOperator->info = pInfo; - pOperator->pExpr = exprArrayDup(pExprInfo); - pOperator->numOfOutput = taosArrayGetSize(pExprInfo); + pOperator->pExpr = pExprInfo; + pOperator->numOfOutput = numOfCols; pOperator->pTaskInfo = pTaskInfo; - pOperator->getNextFn = doAggregate; + pOperator->_openFn = doOpenAggregateOptr; + pOperator->getNextFn = getAggregateResult; pOperator->closeFn = destroyAggOperatorInfo; - int32_t code = appendDownstream(pOperator, &downstream, 1); + + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } return pOperator; + _error: + destroyAggOperatorInfo(pInfo, numOfCols); + tfree(pInfo); + tfree(pOperator); + pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY; + return NULL; } static void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) { @@ -7242,33 +7257,41 @@ static void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) { pInfo->pRes = blockDataDestroy(pInfo->pRes); } -static void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) { +void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) { SOptrBasicInfo* pInfo = (SOptrBasicInfo*) param; doDestroyBasicInfo(pInfo, numOfOutput); } -static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) { + +void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) { SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*) param; doDestroyBasicInfo(&pInfo->binfo, numOfOutput); tfree(pInfo->prevData); } -static void destroyAggOperatorInfo(void* param, int32_t numOfOutput) { + +void destroyAggOperatorInfo(void* param, int32_t numOfOutput) { SAggOperatorInfo* pInfo = (SAggOperatorInfo*) param; doDestroyBasicInfo(&pInfo->binfo, numOfOutput); } -static void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) { - SSWindowOperatorInfo* pInfo = (SSWindowOperatorInfo*) param; +void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput) { + STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*) param; + doDestroyBasicInfo(&pInfo->binfo, numOfOutput); + cleanupAggSup(&pInfo->aggSup); +} + +void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) { + SSessionAggOperatorInfo* pInfo = (SSessionAggOperatorInfo*) param; doDestroyBasicInfo(&pInfo->binfo, numOfOutput); } -static void destroySFillOperatorInfo(void* param, int32_t numOfOutput) { +void destroySFillOperatorInfo(void* param, int32_t numOfOutput) { SFillOperatorInfo* pInfo = (SFillOperatorInfo*) param; pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo); pInfo->pRes = blockDataDestroy(pInfo->pRes); tfree(pInfo->p); } -static void destroyGroupbyOperatorInfo(void* param, int32_t numOfOutput) { +void destroyGroupbyOperatorInfo(void* param, int32_t numOfOutput) { SGroupbyOperatorInfo* pInfo = (SGroupbyOperatorInfo*) param; doDestroyBasicInfo(&pInfo->binfo, numOfOutput); tfree(pInfo->prevData); @@ -7325,12 +7348,15 @@ void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) { tsem_destroy(&pExInfo->ready); } -SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo) { +SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo) { SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo)); int32_t numOfRows = 1; - size_t numOfOutput = taosArrayGetSize(pExprInfo); - initAggInfo(pInfo, pExprInfo, numOfRows, pResBlock, pTableGroupInfo); + int32_t code = initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, numOfRows, pResBlock, pTaskInfo->id.str); + pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo); + if (code != TSDB_CODE_SUCCESS || pInfo->pTableQueryInfo == NULL) { + goto _error; + } size_t tableGroup = taosArrayGetSize(pTableGroupInfo->pGroupList); initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)tableGroup); @@ -7341,41 +7367,62 @@ SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SArray pOperator->blockingOptr = true; pOperator->status = OP_NOT_OPENED; pOperator->info = pInfo; - pOperator->pExpr = exprArrayDup(pExprInfo); - pOperator->numOfOutput = numOfOutput; + pOperator->pExpr = pExprInfo; + pOperator->numOfOutput = numOfCols; pOperator->pTaskInfo = pTaskInfo; pOperator->getNextFn = doMultiTableAggregate; pOperator->closeFn = destroyAggOperatorInfo; - int32_t code = appendDownstream(pOperator, &downstream, 1); + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } return pOperator; + +_error: + return NULL; } -SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SExecTaskInfo* pTaskInfo) { +SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo) { SProjectOperatorInfo* pInfo = calloc(1, sizeof(SProjectOperatorInfo)); + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } - int32_t numOfRows = 4096; - pInfo->binfo.pRes = createOutputBuf_rv(pExprInfo, numOfRows); - pInfo->binfo.pCtx = createSqlFunctionCtx_rv(pExprInfo, &pInfo->binfo.rowCellInfoOffset); + pInfo->binfo.pRes = pResBlock; + pInfo->binfo.pCtx = createSqlFunctionCtx_rv(pExprInfo, num, &pInfo->binfo.rowCellInfoOffset); + if (pInfo->binfo.pCtx == NULL) { + goto _error; + } // initResultRowInfo(&pBInfo->resultRowInfo, 8); // setFunctionResultOutput(pBInfo, MAIN_SCAN); - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "ProjectOperator"; - // pOperator->operatorType = OP_Project; + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT; pOperator->blockingOptr = false; pOperator->status = OP_NOT_OPENED; pOperator->info = pInfo; - pOperator->pExpr = exprArrayDup(pExprInfo); - pOperator->numOfOutput = taosArrayGetSize(pExprInfo); + pOperator->pExpr = pExprInfo; + pOperator->numOfOutput = num; - pOperator->getNextFn = doProjectOperation; + pOperator->_openFn = operatorDummyOpenFn; + pOperator->getNextFn = doProjectOperation; pOperator->closeFn = destroyProjectOperatorInfo; + + pOperator->pTaskInfo = pTaskInfo; int32_t code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_OUT_OF_MEMORY) { + goto _error; + } return pOperator; + + _error: + pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY; + return NULL; } SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int32_t* numOfFilterCols) { @@ -7411,58 +7458,86 @@ SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int3 return 0; } -SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream) { +SOperatorInfo* createLimitOperatorInfo(SOperatorInfo* downstream, int32_t numOfDownstream, SLimit* pLimit, SExecTaskInfo* pTaskInfo) { + ASSERT(numOfDownstream == 1); SLimitOperatorInfo* pInfo = calloc(1, sizeof(SLimitOperatorInfo)); - pInfo->limit = pRuntimeEnv->pQueryAttr->limit.limit; - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + pInfo->limit = *pLimit; + pInfo->currentOffset = pLimit->offset; pOperator->name = "LimitOperator"; -// pOperator->operatorType = OP_Limit; +// pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_LIMIT; pOperator->blockingOptr = false; pOperator->status = OP_NOT_OPENED; - pOperator->getNextFn = doLimit; + pOperator->_openFn = operatorDummyOpenFn; + pOperator->getNextFn = doLimit; pOperator->info = pInfo; - pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->pTaskInfo = pTaskInfo; int32_t code = appendDownstream(pOperator, &downstream, 1); return pOperator; + _error: + tfree(pInfo); + tfree(pOperator); + terrno = TSDB_CODE_OUT_OF_MEMORY; + return NULL; } -SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SInterval* pInterval, SExecTaskInfo* pTaskInfo) { +SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SInterval* pInterval, + const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); - - size_t numOfOutput = taosArrayGetSize(pExprInfo); - doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, numOfOutput); + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } pInfo->order = TSDB_ORDER_ASC; pInfo->precision = TSDB_TIME_PRECISION_MICRO; pInfo->win = pTaskInfo->window; pInfo->interval = *pInterval; - int32_t code = createDiskbasedBuf(&pInfo->pResultBuf, 4096, 4096 * 256, pTaskInfo->id.str, "/tmp/"); + pInfo->win.skey = INT64_MIN; + pInfo->win.ekey = INT64_MAX; - pInfo->binfo.pCtx = createSqlFunctionCtx_rv(pExprInfo, &pInfo->binfo.rowCellInfoOffset); - pInfo->binfo.pRes = createOutputBuf_rv(pExprInfo, pInfo->binfo.capacity); + int32_t numOfRows = 4096; + int32_t code = initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, numOfRows, pResBlock, pTaskInfo->id.str); +// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo); + if (code != TSDB_CODE_SUCCESS/* || pInfo->pTableQueryInfo == NULL*/) { + goto _error; + } initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1); - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "TimeIntervalAggOperator"; - // pOperator->operatorType = OP_TimeWindow; + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL; pOperator->blockingOptr = true; pOperator->status = OP_NOT_OPENED; - pOperator->pExpr = exprArrayDup(pExprInfo); + pOperator->pExpr = pExprInfo; pOperator->pTaskInfo = pTaskInfo; - pOperator->numOfOutput = taosArrayGetSize(pExprInfo); + pOperator->numOfOutput = numOfCols; pOperator->info = pInfo; - pOperator->getNextFn = doIntervalAgg; - pOperator->closeFn = destroyBasicOperatorInfo; + pOperator->_openFn = doOpenIntervalAgg; + pOperator->getNextFn = doIntervalAgg; + pOperator->closeFn = destroyIntervalOperatorInfo; code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + return pOperator; + + _error: + destroyIntervalOperatorInfo(pInfo, numOfCols); + tfree(pInfo); + tfree(pOperator); + pTaskInfo->code = code; + return NULL; } SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { @@ -7509,33 +7584,51 @@ SOperatorInfo* createStatewindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOper pOperator->getNextFn = doStateWindowAgg; pOperator->closeFn = destroyStateWindowOperatorInfo; - int32_t code = appendDownstream(pOperator, &downstream, 1); + int32_t code = appendDownstream(pOperator, &downstream, 1); return pOperator; } -SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { - SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo)); - pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); - pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); +SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo) { + SSessionAggOperatorInfo* pInfo = calloc(1, sizeof(SSessionAggOperatorInfo)); + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, numOfCols, pTaskInfo->id.str); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + initResultRowInfo(&pInfo->binfo.resultRowInfo, 8); - pInfo->prevTs = INT64_MIN; - pInfo->reptScan = false; - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - + pInfo->binfo.pRes = pResBlock; + pInfo->prevTs = INT64_MIN; + pInfo->reptScan = false; pOperator->name = "SessionWindowAggOperator"; // pOperator->operatorType = OP_SessionWindow; pOperator->blockingOptr = true; pOperator->status = OP_NOT_OPENED; - pOperator->pExpr = pExpr; - pOperator->numOfOutput = numOfOutput; - pOperator->info = pInfo; - pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->getNextFn = doSessionWindowAgg; - pOperator->closeFn = destroySWindowOperatorInfo; + pOperator->pExpr = pExprInfo; + pOperator->numOfOutput = numOfCols; - int32_t code = appendDownstream(pOperator, &downstream, 1); + pOperator->info = pInfo; + pOperator->getNextFn = doSessionWindowAgg; + pOperator->closeFn = destroySWindowOperatorInfo; + pOperator->pTaskInfo = pTaskInfo; + + code = appendDownstream(pOperator, &downstream, 1); return pOperator; + + _error: + if (pInfo != NULL) { + destroySWindowOperatorInfo(pInfo, numOfCols); + } + + tfree(pInfo); + tfree(pOperator); + pTaskInfo->code = code; + return NULL; } SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { @@ -7660,15 +7753,13 @@ SOperatorInfo* createFillOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInf SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, void* pMerger, bool multigroupResult) { SSLimitOperatorInfo* pInfo = calloc(1, sizeof(SSLimitOperatorInfo)); - STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - - pInfo->orderColumnList = getResultGroupCheckColumns(pQueryAttr); - pInfo->slimit = pQueryAttr->slimit; - pInfo->limit = pQueryAttr->limit; - pInfo->capacity = pRuntimeEnv->resultInfo.capacity; - pInfo->threshold = (int64_t)(pInfo->capacity * 0.8); - pInfo->currentOffset = pQueryAttr->limit.offset; - pInfo->currentGroupOffset = pQueryAttr->slimit.offset; +// pInfo->orderColumnList = getResultGroupCheckColumns(pQueryAttr); +// pInfo->slimit = pQueryAttr->slimit; +// pInfo->limit = pQueryAttr->limit; +// pInfo->capacity = pRuntimeEnv->resultInfo.capacity; +// pInfo->threshold = (int64_t)(pInfo->capacity * 0.8); +// pInfo->currentOffset = pQueryAttr->limit.offset; +// pInfo->currentGroupOffset = pQueryAttr->slimit.offset; pInfo->multigroupResult= multigroupResult; // TODO refactor @@ -7704,7 +7795,7 @@ SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorI return pOperator; } -static SSDataBlock* doTagScan(void* param, bool* newgroup) { +static SSDataBlock* doTagScan(SOperatorInfo *pOperator, bool* newgroup) { #if 0 SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { @@ -7909,8 +8000,7 @@ static void buildMultiDistinctKey(SDistinctOperatorInfo *pInfo, SSDataBlock *pBl } } -static SSDataBlock* hashDistinct(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* hashDistinct(SOperatorInfo *pOperator, bool* newgroup) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -8113,12 +8203,14 @@ static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, i return s; } -SArray* createExprInfo(SAggPhysiNode* pPhyNode) { - int32_t numOfAggFuncs = LIST_LENGTH(pPhyNode->pAggFuncs); +SExprInfo* createExprInfo(SNodeList* pNodeList, int32_t* numOfExprs) { + int32_t numOfFuncs = LIST_LENGTH(pNodeList); - SArray* pArray = taosArrayInit(numOfAggFuncs, POINTER_BYTES); - for(int32_t i = 0; i < numOfAggFuncs; ++i) { - SExprInfo* pExp = calloc(1, sizeof(SExprInfo)); + *numOfExprs = numOfFuncs; + SExprInfo* pExprs = calloc(numOfFuncs, sizeof(SExprInfo)); + + for(int32_t i = 0; i < numOfFuncs; ++i) { + SExprInfo* pExp = &pExprs[i]; pExp->pExpr = calloc(1, sizeof(tExprNode)); pExp->pExpr->_function.num = 1; @@ -8129,7 +8221,7 @@ SArray* createExprInfo(SAggPhysiNode* pPhyNode) { pExp->base.pParam[0].pCol = calloc(1, sizeof(SColumn)); SColumn* pCol = pExp->base.pParam[0].pCol; - STargetNode* pTargetNode = (STargetNode*) nodesListGetNode(pPhyNode->pAggFuncs, i); + STargetNode* pTargetNode = (STargetNode*) nodesListGetNode(pNodeList, i); ASSERT(pTargetNode->slotId == i); SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr; @@ -8154,10 +8246,9 @@ SArray* createExprInfo(SAggPhysiNode* pPhyNode) { pCol->precision = pcn->node.resType.precision; pCol->dataBlockId = pcn->dataBlockId; } - taosArrayPush(pArray, &pExp); } - return pArray; + return pExprs; } static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId) { @@ -8217,7 +8308,7 @@ SOperatorInfo* doCreateOperatorTreeNode(SPhysiNode* pPhyNode, SExecTaskInfo* pTa } } - if (QUERY_NODE_PHYSICAL_PLAN_AGG == nodeType(pPhyNode)) { + if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == nodeType(pPhyNode)) { size_t size = LIST_LENGTH(pPhyNode->pChildren); assert(size == 1); @@ -8225,9 +8316,40 @@ SOperatorInfo* doCreateOperatorTreeNode(SPhysiNode* pPhyNode, SExecTaskInfo* pTa SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i); SOperatorInfo* op = doCreateOperatorTreeNode(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo); - SArray* pExprInfo = createExprInfo((SAggPhysiNode*)pPhyNode); + int32_t num = 0; + SExprInfo* pExprInfo = createExprInfo(((SProjectPhysiNode*)pPhyNode)->pProjections, &num); SSDataBlock* pResBlock = createOutputBuf_rv1(pPhyNode->pOutputDataBlockDesc); - return createAggregateOperatorInfo(op, pExprInfo, pResBlock, pTaskInfo, pTableGroupInfo); + return createProjectOperatorInfo(op, pExprInfo, num, pResBlock, pTaskInfo); + } + } else if (QUERY_NODE_PHYSICAL_PLAN_AGG == nodeType(pPhyNode)) { + size_t size = LIST_LENGTH(pPhyNode->pChildren); + assert(size == 1); + + for (int32_t i = 0; i < size; ++i) { + SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i); + SOperatorInfo* op = doCreateOperatorTreeNode(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo); + + int32_t num = 0; + SExprInfo* pExprInfo = createExprInfo(((SAggPhysiNode*)pPhyNode)->pAggFuncs, &num); + SSDataBlock* pResBlock = createOutputBuf_rv1(pPhyNode->pOutputDataBlockDesc); + return createAggregateOperatorInfo(op, pExprInfo, num, pResBlock, pTaskInfo, pTableGroupInfo); + } + } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == nodeType(pPhyNode)) { + size_t size = LIST_LENGTH(pPhyNode->pChildren); + assert(size == 1); + + for (int32_t i = 0; i < size; ++i) { + SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i); + SOperatorInfo* op = doCreateOperatorTreeNode(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo); + + SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode; + + int32_t num = 0; + SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->pFuncs, &num); + SSDataBlock* pResBlock = createOutputBuf_rv1(pPhyNode->pOutputDataBlockDesc); + + SInterval interval = {.interval = pIntervalPhyNode->interval, .sliding = pIntervalPhyNode->sliding, .intervalUnit = 'a', .slidingUnit = 'a'}; + return createIntervalOperatorInfo(op, pExprInfo, num, pResBlock, &interval, pTableGroupInfo, pTaskInfo); } } /*else if (pPhyNode->info.type == OP_MultiTableAggregate) { size_t size = taosArrayGetSize(pPhyNode->pChildren); diff --git a/source/libs/executor/src/tsort.c b/source/libs/executor/src/tsort.c index 34dd248ba7..08bab762be 100644 --- a/source/libs/executor/src/tsort.c +++ b/source/libs/executor/src/tsort.c @@ -37,7 +37,6 @@ typedef struct SSortHandle { SArray *pOrderInfo; bool nullFirst; - bool hasVarCol; SArray *pOrderedSource; _sort_fetch_block_fn_t fetchfp; @@ -77,6 +76,10 @@ static SSDataBlock* createDataBlock_rv(SSchema* pSchema, int32_t numOfCols) { colInfo.info.bytes = pSchema[i].bytes; colInfo.info.colId = pSchema[i].colId; taosArrayPush(pBlock->pDataBlock, &colInfo); + + if (IS_VAR_DATA_TYPE(colInfo.info.type)) { + pBlock->info.hasVarCol = true; + } } return pBlock; @@ -155,7 +158,7 @@ static int32_t doAddToBuf(SSDataBlock* pDataBlock, SSortHandle* pHandle) { while(start < pDataBlock->info.rows) { int32_t stop = 0; - blockDataSplitRows(pDataBlock, pHandle->hasVarCol, start, &stop, pHandle->pageSize); + blockDataSplitRows(pDataBlock, pDataBlock->info.hasVarCol, start, &stop, pHandle->pageSize); SSDataBlock* p = blockDataExtractBlock(pDataBlock, start, stop - start + 1); if (p == NULL) { return terrno; @@ -179,7 +182,7 @@ static int32_t doAddToBuf(SSDataBlock* pDataBlock, SSortHandle* pHandle) { start = stop + 1; } - blockDataClearup(pDataBlock, pHandle->hasVarCol); + blockDataClearup(pDataBlock); SSDataBlock* pBlock = createOneDataBlock(pDataBlock); int32_t code = doAddNewExternalMemSource(pHandle->pBuf, pHandle->pOrderedSource, pBlock, &pHandle->sourceId); @@ -309,7 +312,7 @@ static int32_t adjustMergeTreeForNextTuple(SExternalMemSource *pSource, SMultiwa } static SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SMsortComparParam* cmpParam, int32_t capacity) { - blockDataClearup(pHandle->pDataBlock, pHandle->hasVarCol); + blockDataClearup(pHandle->pDataBlock); while(1) { if (cmpParam->numOfSources == pHandle->numOfCompletedSources) { @@ -475,7 +478,7 @@ static int32_t doInternalMergeSort(SSortHandle* pHandle) { setBufPageDirty(pPage, true); releaseBufPage(pHandle->pBuf, pPage); - blockDataClearup(pDataBlock, pHandle->hasVarCol); + blockDataClearup(pDataBlock); } tMergeTreeDestroy(pHandle->pMergeTree); diff --git a/source/libs/executor/test/executorTests.cpp b/source/libs/executor/test/executorTests.cpp index 38ceeffc20..6737f57bbf 100644 --- a/source/libs/executor/test/executorTests.cpp +++ b/source/libs/executor/test/executorTests.cpp @@ -55,8 +55,7 @@ typedef struct SDummyInputInfo { SSDataBlock* pBlock; } SDummyInputInfo; -SSDataBlock* getDummyBlock(void* param, bool* newgroup) { - SOperatorInfo* pOperator = static_cast(param); +SSDataBlock* getDummyBlock(SOperatorInfo* pOperator, bool* newgroup) { SDummyInputInfo* pInfo = static_cast(pOperator->info); if (pInfo->current >= pInfo->totalPages) { return NULL; @@ -87,7 +86,7 @@ SSDataBlock* getDummyBlock(void* param, bool* newgroup) { // // taosArrayPush(pInfo->pBlock->pDataBlock, &colInfo1); } else { - blockDataClearup(pInfo->pBlock, true); + blockDataClearup(pInfo->pBlock); } SSDataBlock* pBlock = pInfo->pBlock; @@ -122,8 +121,7 @@ SSDataBlock* getDummyBlock(void* param, bool* newgroup) { return pBlock; } -SSDataBlock* get2ColsDummyBlock(void* param, bool* newgroup) { - SOperatorInfo* pOperator = static_cast(param); +SSDataBlock* get2ColsDummyBlock(SOperatorInfo* pOperator, bool* newgroup) { SDummyInputInfo* pInfo = static_cast(pOperator->info); if (pInfo->current >= pInfo->totalPages) { return NULL; @@ -153,7 +151,7 @@ SSDataBlock* get2ColsDummyBlock(void* param, bool* newgroup) { taosArrayPush(pInfo->pBlock->pDataBlock, &colInfo1); } else { - blockDataClearup(pInfo->pBlock, false); + blockDataClearup(pInfo->pBlock); } SSDataBlock* pBlock = pInfo->pBlock; diff --git a/source/libs/function/inc/taggfunction.h b/source/libs/function/inc/taggfunction.h index d71ff789ba..906d4f63fb 100644 --- a/source/libs/function/inc/taggfunction.h +++ b/source/libs/function/inc/taggfunction.h @@ -46,13 +46,6 @@ extern SAggFunctionInfo aggFunc[35]; #define DATA_SET_FLAG ',' // to denote the output area has data, not null value #define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG) -#define TOP_BOTTOM_QUERY_LIMIT 100 - -#define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0) -#define QUERY_IS_JOIN_QUERY(type) (TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_JOIN_QUERY)) -#define QUERY_IS_PROJECTION_QUERY(type) (((type)&TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) -#define QUERY_IS_FREE_RESOURCE(type) (((type)&TSDB_QUERY_TYPE_FREE_RESOURCE) != 0) - typedef struct SInterpInfoDetail { TSKEY ts; // interp specified timestamp int8_t type; @@ -61,9 +54,6 @@ typedef struct SInterpInfoDetail { #define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowEntryInfo))) -#define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0) -#define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 0) - typedef struct STwaInfo { int8_t hasResult; // flag to denote has value double dOutput; @@ -71,8 +61,6 @@ typedef struct STwaInfo { STimeWindow win; } STwaInfo; -extern int32_t functionCompatList[]; // compatible check array list - bool topbot_datablock_filter(SqlFunctionCtx *pCtx, const char *minval, const char *maxval); /** diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index aaaee6d56c..f0f00434f0 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -52,10 +52,6 @@ static void doFinalizer(SResultRowEntryInfo* pResInfo) { cleanupResultRowEntry(p void functionFinalizer(SqlFunctionCtx *pCtx) { SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); - if (pResInfo->hasResult != DATA_SET_FLAG) { -// setNull(pCtx->pOutput, pCtx->resDataInfo.type, pCtx->resDataInfo.bytes); - } - doFinalizer(pResInfo); } @@ -398,7 +394,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx *pCtx, int32_t isMinFunc) { int32_t *pData = (int32_t*)pCol->pData; int32_t *val = (int32_t*) buf; - for (int32_t i = 0; i < pCtx->size; ++i) { + for (int32_t i = start; i < start + numOfRows; ++i) { if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { continue; } diff --git a/source/libs/function/src/tfunction.c b/source/libs/function/src/tfunction.c deleted file mode 100644 index e302643c32..0000000000 --- a/source/libs/function/src/tfunction.c +++ /dev/null @@ -1,415 +0,0 @@ -#include "os.h" -#include "tarray.h" -#include "function.h" -#include "thash.h" -#include "taggfunction.h" - -static SHashObj* functionHashTable = NULL; -static SHashObj* udfHashTable = NULL; - -static void doInitFunctionHashTable() { - int numOfEntries = tListLen(aggFunc); - functionHashTable = taosHashInit(numOfEntries, MurmurHash3_32, false, false); - for (int32_t i = 0; i < numOfEntries; i++) { - int32_t len = (uint32_t)strlen(aggFunc[i].name); - - SAggFunctionInfo* ptr = &aggFunc[i]; - taosHashPut(functionHashTable, aggFunc[i].name, len, (void*)&ptr, POINTER_BYTES); - } - -/* - numOfEntries = tListLen(scalarFunc); - for(int32_t i = 0; i < numOfEntries; ++i) { - int32_t len = (int32_t) strlen(scalarFunc[i].name); - SScalarFunctionInfo* ptr = &scalarFunc[i]; - taosHashPut(functionHashTable, scalarFunc[i].name, len, (void*)&ptr, POINTER_BYTES); - } -*/ - - udfHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, true); -} - -static pthread_once_t functionHashTableInit = PTHREAD_ONCE_INIT; - -int32_t qIsBuiltinFunction(const char* name, int32_t len, bool* scalarFunction) { - pthread_once(&functionHashTableInit, doInitFunctionHashTable); - - SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, name, len); - if (pInfo != NULL) { - *scalarFunction = ((*pInfo)->type == FUNCTION_TYPE_SCALAR); - return (*pInfo)->functionId; - } else { - return -1; - } -} - -bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId) { - return true; -} - -bool qIsAggregateFunction(const char* functionName) { - assert(functionName != NULL); - bool scalarfunc = false; - qIsBuiltinFunction(functionName, strlen(functionName), &scalarfunc); - - return !scalarfunc; -} - -bool qIsSelectivityFunction(const char* functionName) { - assert(functionName != NULL); - pthread_once(&functionHashTableInit, doInitFunctionHashTable); - - size_t len = strlen(functionName); - SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, functionName, len); - if (pInfo != NULL) { - return ((*pInfo)->status | FUNCSTATE_SELECTIVITY) != 0; - } - - return false; -} - -SAggFunctionInfo* qGetFunctionInfo(const char* name, int32_t len) { - pthread_once(&functionHashTableInit, doInitFunctionHashTable); - - SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, name, len); - if (pInfo != NULL) { - return (*pInfo); - } else { - return NULL; - } -} - -void qAddUdfInfo(uint64_t id, SUdfInfo* pUdfInfo) { - int32_t len = (uint32_t)strlen(pUdfInfo->name); - taosHashPut(udfHashTable, pUdfInfo->name, len, (void*)&pUdfInfo, POINTER_BYTES); -} - -void qRemoveUdfInfo(uint64_t id, SUdfInfo* pUdfInfo) { - int32_t len = (uint32_t)strlen(pUdfInfo->name); - taosHashRemove(udfHashTable, pUdfInfo->name, len); -} - -bool isTagsQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - char* f = *(char**) taosArrayGet(pFunctionIdList, i); - - // todo handle count(tbname) query - if (strcmp(f, "project") != 0 && strcmp(f, "count") != 0) { - return false; - } - - // "select count(tbname)" query -// if (functId == FUNCTION_COUNT && pExpr->base.colpDesc->colId == TSDB_TBNAME_COLUMN_INDEX) { -// continue; -// } - } - - return true; -} - -//bool tscMultiRoundQuery(SArray* pFunctionIdList, int32_t index) { -// if (!UTIL_TABLE_IS_SUPER_TABLE(pQueryInfo->pTableMetaInfo[index])) { -// return false; -// } -// -// size_t numOfExprs = (int32_t) getNumOfExprs(pQueryInfo); -// for(int32_t i = 0; i < numOfExprs; ++i) { -// SExprInfo* pExpr = getExprInfo(pQueryInfo, i); -// if (pExpr->base.functionId == FUNCTION_STDDEV_DST) { -// return true; -// } -// } -// -// return false; -//} - -bool isProjectionQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - char* f = *(char**) taosArrayGet(pFunctionIdList, i); - if (strcmp(f, "project") == 0) { - return true; - } - } - - return false; -} - -bool isDiffDerivativeQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); - if (f == FUNCTION_TS_DUMMY) { - continue; - } - - if (f == FUNCTION_DIFF || f == FUNCTION_DERIVATIVE) { - return true; - } - } - - return false; -} - -bool isInterpQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); - if (f == FUNCTION_TAG || f == FUNCTION_TS) { - continue; - } - - if (f != FUNCTION_INTERP) { - return false; - } - } - - return true; -} - -bool isArithmeticQueryOnAggResult(SArray* pFunctionIdList) { - if (isProjectionQuery(pFunctionIdList)) { - return false; - } - - assert(0); - -// size_t numOfOutput = getNumOfFields(pQueryInfo); -// for(int32_t i = 0; i < numOfOutput; ++i) { -// SExprInfo* pExprInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pExpr; -// if (pExprInfo->pExpr != NULL) { -// return true; -// } -// } - - return false; -} - -bool isGroupbyColumn(SGroupbyExpr* pGroupby) { - return !pGroupby->groupbyTag; -} - -bool isTopBotQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - char* f = *(char**) taosArrayGet(pFunctionIdList, i); - if (strcmp(f, "project") == 0) { - continue; - } - - if (strcmp(f, "top") == 0 || strcmp(f, "bottom") == 0) { - return true; - } - } - - return false; -} - -bool isTsCompQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - if (num != 1) { - return false; - } - - int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, 0); - return f == FUNCTION_TS_COMP; -} - -bool isTWAQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); - if (f == FUNCTION_TWA) { - return true; - } - } - - return false; -} - -bool isIrateQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); - if (f == FUNCTION_IRATE) { - return true; - } - } - - return false; -} - -bool isStabledev(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); - if (f == FUNCTION_STDDEV_DST) { - return true; - } - } - - return false; -} - -bool needReverseScan(SArray* pFunctionIdList) { - assert(0); - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < num; ++i) { - int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); - if (f == FUNCTION_TS || f == FUNCTION_TS_DUMMY || f == FUNCTION_TAG) { - continue; - } - -// if ((f == FUNCTION_FIRST || f == FUNCTION_FIRST_DST) && pQueryInfo->order.order == TSDB_ORDER_DESC) { -// return true; -// } - - if (f == FUNCTION_LAST || f == FUNCTION_LAST_DST) { - // the scan order to acquire the last result of the specified column -// int32_t order = (int32_t)pExpr->base.param[0].i64; -// if (order != pQueryInfo->order.order) { -// return true; -// } - } - } - - return false; -} - -bool isAgg(SArray* pFunctionIdList) { - size_t size = taosArrayGetSize(pFunctionIdList); - for (int32_t i = 0; i < size; ++i) { - char* f = *(char**) taosArrayGet(pFunctionIdList, i); - if (strcmp(f, "project") == 0) { - return false; - } - - if (qIsAggregateFunction(f)) { - return true; - } - } - - return false; -} - -bool isBlockDistQuery(SArray* pFunctionIdList) { - int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); - char* f = *(char**) taosArrayGet(pFunctionIdList, 0); - return (num == 1 && strcmp(f, "block_dist") == 0); -} - -bool isTwoStageSTableQuery(SArray* pFunctionIdList, int32_t tableIndex) { -// if (pQueryInfo == NULL) { -// return false; -// } -// -// STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); -// if (pTableMetaInfo == NULL) { -// return false; -// } -// -// if ((pQueryInfo->type & TSDB_QUERY_TYPE_FREE_RESOURCE) == TSDB_QUERY_TYPE_FREE_RESOURCE) { -// return false; -// } -// -// // for ordered projection query, iterate all qualified vnodes sequentially -// if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, tableIndex)) { -// return false; -// } -// -// if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_SUBQUERY) && pQueryInfo->command == TSDB_SQL_SELECT) { -// return UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); -// } - - return false; -} - -bool isProjectionQueryOnSTable(SArray* pFunctionIdList, int32_t tableIndex) { -// STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); -// -// /* -// * In following cases, return false for non ordered project query on super table -// * 1. failed to get tableMeta from server; 2. not a super table; 3. limitation is 0; -// * 4. show queries, instead of a select query -// */ -// size_t numOfExprs = getNumOfExprs(pQueryInfo); -// if (pTableMetaInfo == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) || -// pQueryInfo->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT || numOfExprs == 0) { -// return false; -// } -// -// for (int32_t i = 0; i < numOfExprs; ++i) { -// int32_t functionId = getExprInfo(pQueryInfo, i)->base.functionId; -// -// if (functionId < 0) { -// SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1); -// if (pUdfInfo->funcType == TSDB_FUNC_TYPE_AGGREGATE) { -// return false; -// } -// -// continue; -// } -// -// if (functionId != FUNCTION_PRJ && -// functionId != FUNCTION_TAGPRJ && -// functionId != FUNCTION_TAG && -// functionId != FUNCTION_TS && -// functionId != FUNCTION_ARITHM && -// functionId != FUNCTION_TS_COMP && -// functionId != FUNCTION_DIFF && -// functionId != FUNCTION_DERIVATIVE && -// functionId != FUNCTION_TS_DUMMY && -// functionId != FUNCTION_TID_TAG) { -// return false; -// } -// } - - return true; -} - -bool hasTagValOutput(SArray* pFunctionIdList) { - size_t size = taosArrayGetSize(pFunctionIdList); - - // if (numOfExprs == 1 && pExpr1->base.functionId == FUNCTION_TS_COMP) { -// return true; -// } - - for (int32_t i = 0; i < size; ++i) { - int32_t functionId = *(int16_t*) taosArrayGet(pFunctionIdList, i); - - // ts_comp column required the tag value for join filter - if (functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) { - return true; - } - } - - return false; -} - -//bool timeWindowInterpoRequired(SArray* pFunctionIdList) { -// int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); -// for (int32_t i = 0; i < num; ++i) { -// int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); -// if (f == FUNCTION_TWA || f == FUNCTION_INTERP) { -// return true; -// } -// } -// -// return false; -//} - -void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc) { - assert(pFunctionIdList != NULL); - - pDesc->blockDistribution = isBlockDistQuery(pFunctionIdList); - if (pDesc->blockDistribution) { - return; - } - -// pDesc->projectionQuery = isProjectionQuery(pFunctionIdList); -// pDesc->onlyTagQuery = isTagsQuery(pFunctionIdList); - pDesc->interpQuery = isInterpQuery(pFunctionIdList); - pDesc->topbotQuery = isTopBotQuery(pFunctionIdList); - pDesc->agg = isAgg(pFunctionIdList); -} diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index c675827253..34c211561b 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -183,6 +183,12 @@ static SNode* groupingSetNodeCopy(const SGroupingSetNode* pSrc, SGroupingSetNode return (SNode*)pDst; } +static SNode* fillNodeCopy(const SFillNode* pSrc, SFillNode* pDst) { + COPY_SCALAR_FIELD(mode); + CLONE_NODE_FIELD(pValues); + return (SNode*)pDst; +} + static SNode* logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) { COPY_SCALAR_FIELD(id); CLONE_NODE_LIST_FIELD(pTargets); @@ -248,6 +254,17 @@ static SNode* logicExchangeCopy(const SExchangeLogicNode* pSrc, SExchangeLogicNo return (SNode*)pDst; } +static SNode* logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* pDst) { + COPY_BASE_OBJECT_FIELD(node, logicNodeCopy); + COPY_SCALAR_FIELD(winType); + CLONE_NODE_LIST_FIELD(pFuncs); + COPY_SCALAR_FIELD(interval); + COPY_SCALAR_FIELD(offset); + COPY_SCALAR_FIELD(sliding); + CLONE_NODE_FIELD(pFill); + return (SNode*)pDst; +} + static SNode* logicSubplanCopy(const SSubLogicPlan* pSrc, SSubLogicPlan* pDst) { CLONE_NODE_FIELD(pNode); COPY_SCALAR_FIELD(subplanType); @@ -309,6 +326,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) { case QUERY_NODE_ORDER_BY_EXPR: case QUERY_NODE_LIMIT: break; + case QUERY_NODE_FILL: + return fillNodeCopy((const SFillNode*)pNode, (SFillNode*)pDst); case QUERY_NODE_DATABLOCK_DESC: return dataBlockDescCopy((const SDataBlockDescNode*)pNode, (SDataBlockDescNode*)pDst); case QUERY_NODE_SLOT_DESC: @@ -325,6 +344,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) { return logicVnodeModifCopy((const SVnodeModifLogicNode*)pNode, (SVnodeModifLogicNode*)pDst); case QUERY_NODE_LOGIC_PLAN_EXCHANGE: return logicExchangeCopy((const SExchangeLogicNode*)pNode, (SExchangeLogicNode*)pDst); + case QUERY_NODE_LOGIC_PLAN_WINDOW: + return logicWindowCopy((const SWindowLogicNode*)pNode, (SWindowLogicNode*)pDst); case QUERY_NODE_LOGIC_SUBPLAN: return logicSubplanCopy((const SSubLogicPlan*)pNode, (SSubLogicPlan*)pDst); default: diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 782cdcb71a..457f863a5e 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -117,6 +117,8 @@ const char* nodesNodeName(ENodeType type) { return "PhysiExchange"; case QUERY_NODE_PHYSICAL_PLAN_SORT: return "PhysiSort"; + case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: + return "PhysiInterval"; case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: return "PhysiDispatch"; case QUERY_NODE_PHYSICAL_PLAN_INSERT: @@ -149,8 +151,7 @@ static int32_t nodeListToJson(SJson* pJson, const char* pName, const SNodeList* return TSDB_CODE_SUCCESS; } -static int32_t jsonToNodeList(const SJson* pJson, const char* pName, SNodeList** pList) { - const SJson* pJsonArray = tjsonGetObjectItem(pJson, pName); +static int32_t jsonToNodeListImpl(const SJson* pJsonArray, SNodeList** pList) { int32_t size = (NULL == pJsonArray ? 0 : tjsonGetArraySize(pJsonArray)); if (size > 0) { *pList = nodesMakeList(); @@ -174,6 +175,10 @@ static int32_t jsonToNodeList(const SJson* pJson, const char* pName, SNodeList** return code; } +static int32_t jsonToNodeList(const SJson* pJson, const char* pName, SNodeList** pList) { + return jsonToNodeListImpl(tjsonGetObjectItem(pJson, pName), pList); +} + static const char* jkTableMetaUid = "TableMetaUid"; static const char* jkTableMetaSuid = "TableMetaSuid"; @@ -573,6 +578,79 @@ static int32_t jsonToPhysiExchangeNode(const SJson* pJson, void* pObj) { return code; } +static const char* jkIntervalPhysiPlanExprs = "Exprs"; +static const char* jkIntervalPhysiPlanFuncs = "Funcs"; +static const char* jkIntervalPhysiPlanInterval = "Interval"; +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; + + int32_t code = physicPlanNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = nodeListToJson(pJson, jkIntervalPhysiPlanExprs, pNode->pExprs); + } + if (TSDB_CODE_SUCCESS == code) { + code = nodeListToJson(pJson, jkIntervalPhysiPlanFuncs, pNode->pFuncs); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanInterval, pNode->interval); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanOffset, pNode->offset); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanSliding, pNode->sliding); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanIntervalUnit, pNode->intervalUnit); + } + 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; +} + +static int32_t jsonToPhysiIntervalNode(const SJson* pJson, void* pObj) { + SIntervalPhysiNode* pNode = (SIntervalPhysiNode*)pObj; + + int32_t code = jsonToPhysicPlanNode(pJson, pObj); + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeList(pJson, jkIntervalPhysiPlanExprs, &pNode->pExprs); + } + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeList(pJson, jkIntervalPhysiPlanFuncs, &pNode->pFuncs); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBigIntValue(pJson, jkIntervalPhysiPlanInterval, &pNode->interval); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBigIntValue(pJson, jkIntervalPhysiPlanOffset, &pNode->offset); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBigIntValue(pJson, jkIntervalPhysiPlanSliding, &pNode->sliding); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetTinyIntValue(pJson, jkIntervalPhysiPlanIntervalUnit, &pNode->intervalUnit); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetTinyIntValue(pJson, jkIntervalPhysiPlanSlidingUnit, &pNode->slidingUnit); + } + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeObject(pJson, jkIntervalPhysiPlanFill, (SNode**)&pNode->pFill); + } + + return code; +} + static const char* jkDataSinkInputDataBlockDesc = "InputDataBlockDesc"; static int32_t physicDataSinkNodeToJson(const void* pObj, SJson* pJson) { @@ -1500,6 +1578,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { return physiExchangeNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_SORT: break; + case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: + return physiIntervalNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: return physiDispatchNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_INSERT: @@ -1581,7 +1661,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { return jsonToSubplan(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN: return jsonToPlan(pJson, pObj); + case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: + return jsonToPhysiIntervalNode(pJson, pObj); default: + assert(0); break; } nodesWarn("jsonToSpecificNode unknown node = %s", nodesNodeName(nodeType(pObj))); @@ -1687,3 +1770,52 @@ int32_t nodesStringToNode(const char* pStr, SNode** pNode) { } return TSDB_CODE_SUCCESS; } + +int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int32_t* pLen) { + if (NULL == pList || NULL == pStr || NULL == pLen) { + terrno = TSDB_CODE_FAILED; + return TSDB_CODE_FAILED; + } + + if (0 == LIST_LENGTH(pList)) { + return TSDB_CODE_SUCCESS; + } + + SJson* pJson = tjsonCreateArray(); + if (NULL == pJson) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return TSDB_CODE_OUT_OF_MEMORY; + } + + SNode* pNode; + FOREACH(pNode, pList) { + int32_t code = tjsonAddItem(pJson, nodeToJson, pNode); + if (TSDB_CODE_SUCCESS != code) { + terrno = code; + return code; + } + } + + *pStr = format ? tjsonToString(pJson) : tjsonToUnformattedString(pJson); + tjsonDelete(pJson); + + *pLen = strlen(*pStr) + 1; + return TSDB_CODE_SUCCESS; +} + +int32_t nodesStringToList(const char* pStr, SNodeList** pList) { + if (NULL == pStr || NULL == pList) { + return TSDB_CODE_SUCCESS; + } + SJson* pJson = tjsonParse(pStr); + if (NULL == pJson) { + return TSDB_CODE_FAILED; + } + int32_t code = jsonToNodeListImpl(pJson, pList); + if (TSDB_CODE_SUCCESS != code) { + nodesDestroyList(*pList); + terrno = code; + return code; + } + return TSDB_CODE_SUCCESS; +} diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 7e1d15c191..b17a4904da 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -76,6 +76,12 @@ SNodeptr nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SColumnDefNode)); case QUERY_NODE_DOWNSTREAM_SOURCE: return makeNode(type, sizeof(SDownstreamSourceNode)); + case QUERY_NODE_DATABASE_OPTIONS: + return makeNode(type, sizeof(SDatabaseOptions)); + case QUERY_NODE_TABLE_OPTIONS: + return makeNode(type, sizeof(STableOptions)); + case QUERY_NODE_INDEX_OPTIONS: + return makeNode(type, sizeof(SIndexOptions)); case QUERY_NODE_SET_OPERATOR: return makeNode(type, sizeof(SSetOperator)); case QUERY_NODE_SELECT_STMT: @@ -121,7 +127,12 @@ SNodeptr nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SShowStmt)); case QUERY_NODE_SHOW_VGROUPS_STMT: case QUERY_NODE_SHOW_MNODES_STMT: + case QUERY_NODE_SHOW_QNODES_STMT: return makeNode(type, sizeof(SShowStmt)); + case QUERY_NODE_CREATE_INDEX_STMT: + return makeNode(type, sizeof(SCreateIndexStmt)); + case QUERY_NODE_CREATE_QNODE_STMT: + return makeNode(type, sizeof(SCreateQnodeStmt)); case QUERY_NODE_LOGIC_PLAN_SCAN: return makeNode(type, sizeof(SScanLogicNode)); case QUERY_NODE_LOGIC_PLAN_JOIN: @@ -134,6 +145,8 @@ SNodeptr nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SVnodeModifLogicNode)); case QUERY_NODE_LOGIC_PLAN_EXCHANGE: return makeNode(type, sizeof(SExchangeLogicNode)); + case QUERY_NODE_LOGIC_PLAN_WINDOW: + return makeNode(type, sizeof(SWindowLogicNode)); case QUERY_NODE_LOGIC_SUBPLAN: return makeNode(type, sizeof(SSubLogicPlan)); case QUERY_NODE_LOGIC_PLAN: @@ -156,6 +169,8 @@ SNodeptr nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SExchangePhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_SORT: return makeNode(type, sizeof(SNode)); + case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: + return makeNode(type, sizeof(SIntervalPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: return makeNode(type, sizeof(SDataDispatcherNode)); case QUERY_NODE_PHYSICAL_PLAN_INSERT: @@ -204,6 +219,14 @@ static EDealRes destroyNode(SNode** pNode, void* pContext) { case QUERY_NODE_NODE_LIST: nodesClearList(((SNodeListNode*)(*pNode))->pNodeList); break; + case QUERY_NODE_INDEX_OPTIONS: { + SIndexOptions* pStmt = (SIndexOptions*)*pNode; + nodesDestroyList(pStmt->pFuncs); + nodesDestroyNode(pStmt->pInterval); + nodesDestroyNode(pStmt->pOffset); + nodesDestroyNode(pStmt->pSliding); + break; + } case QUERY_NODE_SELECT_STMT: { SSelectStmt* pStmt = (SSelectStmt*)*pNode; nodesDestroyList(pStmt->pProjectionList); @@ -244,6 +267,12 @@ static EDealRes destroyNode(SNode** pNode, void* pContext) { case QUERY_NODE_CREATE_MULTI_TABLE_STMT: nodesDestroyList(((SCreateMultiTableStmt*)(*pNode))->pSubTables); break; + case QUERY_NODE_CREATE_INDEX_STMT: { + SCreateIndexStmt* pStmt = (SCreateIndexStmt*)*pNode; + nodesDestroyNode(pStmt->pOptions); + nodesDestroyList(pStmt->pCols); + break; + } default: break; } diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index 11c56ddf3c..f2fcced1a9 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -109,17 +109,17 @@ SNode* addLimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit); SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pProjectionList, SNode* pTable); SNode* createSetOperator(SAstCreateContext* pCxt, ESetOperatorType type, SNode* pLeft, SNode* pRight); -SDatabaseOptions* createDefaultDatabaseOptions(SAstCreateContext* pCxt); -SDatabaseOptions* setDatabaseOption(SAstCreateContext* pCxt, SDatabaseOptions* pOptions, EDatabaseOptionType type, const SToken* pVal); -SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pDbName, SDatabaseOptions* pOptions); +SNode* createDefaultDatabaseOptions(SAstCreateContext* pCxt); +SNode* setDatabaseOption(SAstCreateContext* pCxt, SNode* pOptions, EDatabaseOptionType type, const SToken* pVal); +SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pDbName, SNode* pOptions); SNode* createDropDatabaseStmt(SAstCreateContext* pCxt, bool ignoreNotExists, const SToken* pDbName); -STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt); -STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ETableOptionType type, const SToken* pVal); -STableOptions* setTableSmaOption(SAstCreateContext* pCxt, STableOptions* pOptions, SNodeList* pSma); +SNode* createDefaultTableOptions(SAstCreateContext* pCxt); +SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, const SToken* pVal); +SNode* setTableSmaOption(SAstCreateContext* pCxt, SNode* pOptions, SNodeList* pSma); SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment); SDataType createDataType(uint8_t type); SDataType createVarLenDataType(uint8_t type, const SToken* pLen); -SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNodeList* pTags, STableOptions* pOptions); +SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNodeList* pTags, SNode* pOptions); SNode* createCreateSubTableClause(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNode* pUseRealTable, SNodeList* pSpecificTags, SNodeList* pValsOfTags); SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables); SNode* createDropTableClause(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pRealTable); @@ -132,6 +132,9 @@ SNode* createAlterUserStmt(SAstCreateContext* pCxt, const SToken* pUserName, int SNode* createDropUserStmt(SAstCreateContext* pCxt, const SToken* pUserName); SNode* createCreateDnodeStmt(SAstCreateContext* pCxt, const SToken* pFqdn, const SToken* pPort); SNode* createDropDnodeStmt(SAstCreateContext* pCxt, const SToken* pDnode); +SNode* createCreateIndexStmt(SAstCreateContext* pCxt, EIndexType type, const SToken* pIndexName, const SToken* pTableName, SNodeList* pCols, SNode* pOptions); +SNode* createIndexOption(SAstCreateContext* pCxt, SNodeList* pFuncs, SNode* pInterval, SNode* pOffset, SNode* pSliding); +SNode* createCreateQnodeStmt(SAstCreateContext* pCxt, const SToken* pDnodeId); #ifdef __cplusplus } diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 310da2e966..af2fb12c52 100644 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -64,6 +64,10 @@ dnode_endpoint(A) ::= NK_STRING(B). dnode_host_name(A) ::= NK_ID(B). { A = B; } dnode_host_name(A) ::= NK_IPTOKEN(B). { A = B; } +/************************************************ create qnode ********************************************************/ +cmd ::= CREATE QNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createCreateQnodeStmt(pCxt, &A); } +cmd ::= SHOW QNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT, NULL); } + /************************************************ create/drop/show/use database ***************************************/ cmd ::= CREATE DATABASE not_exists_opt(A) db_name(B) db_options(C). { pCxt->pRootNode = createCreateDatabaseStmt(pCxt, A, &B, C);} cmd ::= DROP DATABASE exists_opt(A) db_name(B). { pCxt->pRootNode = createDropDatabaseStmt(pCxt, A, &B); } @@ -80,8 +84,6 @@ not_exists_opt(A) ::= . exists_opt(A) ::= IF EXISTS. { A = true; } exists_opt(A) ::= . { A = false; } -%type db_options { SDatabaseOptions* } -%destructor db_options { tfree($$); } db_options(A) ::= . { A = createDefaultDatabaseOptions(pCxt); } db_options(A) ::= db_options(B) BLOCKS NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_BLOCKS, &C); } db_options(A) ::= db_options(B) CACHE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_CACHE, &C); } @@ -179,8 +181,6 @@ tags_def_opt(A) ::= tags_def(B). %destructor tags_def { nodesDestroyList($$); } tags_def(A) ::= TAGS NK_LP column_def_list(B) NK_RP. { A = B; } -%type table_options { STableOptions* } -%destructor table_options { tfree($$); } table_options(A) ::= . { A = createDefaultTableOptions(pCxt);} table_options(A) ::= table_options(B) COMMENT NK_STRING(C). { A = setTableOption(pCxt, B, TABLE_OPTION_COMMENT, &C); } table_options(A) ::= table_options(B) KEEP NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); } @@ -194,11 +194,29 @@ col_name_list(A) ::= col_name_list(B) NK_COMMA col_name(C). col_name(A) ::= column_name(B). { A = createColumnNode(pCxt, NULL, &B); } +/************************************************ create index ********************************************************/ +cmd ::= CREATE SMA INDEX index_name(A) ON table_name(B) index_options(C). { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, &A, &B, NULL, C); } +cmd ::= CREATE FULLTEXT INDEX + index_name(A) ON table_name(B) NK_LP col_name_list(C) NK_RP. { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_FULLTEXT, &A, &B, C, NULL); } + +index_options(A) ::= . { A = NULL; } +index_options(A) ::= FUNCTION NK_LP func_list(B) NK_RP INTERVAL + NK_LP duration_literal(C) NK_RP sliding_opt(D). { A = createIndexOption(pCxt, B, releaseRawExprNode(pCxt, C), NULL, D); } +index_options(A) ::= FUNCTION NK_LP func_list(B) NK_RP INTERVAL + NK_LP duration_literal(C) NK_COMMA duration_literal(D) NK_RP sliding_opt(E). { A = createIndexOption(pCxt, B, releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, D), E); } + +%type func_list { SNodeList* } +%destructor func_list { nodesDestroyList($$); } +func_list(A) ::= func(B). { A = createNodeList(pCxt, B); } +func_list(A) ::= func_list(B) NK_COMMA func(C). { A = addNodeToList(pCxt, B, C); } + +func(A) ::= function_name(B) NK_LP expression_list(C) NK_RP. { A = createFunctionNode(pCxt, &B, C); } + /************************************************ show vgroups ********************************************************/ cmd ::= SHOW VGROUPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, NULL); } cmd ::= SHOW db_name(B) NK_DOT VGROUPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, &B); } -/************************************************ show vgroups ********************************************************/ +/************************************************ show mnodes *********************************************************/ cmd ::= SHOW MNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT, NULL); } /************************************************ select **************************************************************/ @@ -248,6 +266,10 @@ column_alias(A) ::= NK_ID(B). %destructor user_name { } user_name(A) ::= NK_ID(B). { A = B; } +%type index_name { SToken } +%destructor index_name { } +index_name(A) ::= NK_ID(B). { A = B; } + /************************************************ expression **********************************************************/ expression(A) ::= literal(B). { A = B; } //expression(A) ::= NK_QUESTION(B). { A = B; } @@ -463,13 +485,13 @@ twindow_clause_opt(A) ::= SESSION NK_LP column_reference(B) NK_COMMA NK_INTEGER(C) NK_RP. { A = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, B), &C); } twindow_clause_opt(A) ::= STATE_WINDOW NK_LP column_reference(B) NK_RP. { A = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, B)); } twindow_clause_opt(A) ::= - INTERVAL NK_LP duration_literal(B) NK_RP sliding_opt(C) fill_opt(D). { A = createIntervalWindowNode(pCxt, B, NULL, C, D); } + INTERVAL NK_LP duration_literal(B) NK_RP sliding_opt(C) fill_opt(D). { A = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, B), NULL, C, D); } twindow_clause_opt(A) ::= INTERVAL NK_LP duration_literal(B) NK_COMMA duration_literal(C) NK_RP - sliding_opt(D) fill_opt(E). { A = createIntervalWindowNode(pCxt, B, C, D, E); } + sliding_opt(D) fill_opt(E). { A = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C), D, E); } sliding_opt(A) ::= . { A = NULL; } -sliding_opt(A) ::= SLIDING NK_LP duration_literal(B) NK_RP. { A = B; } +sliding_opt(A) ::= SLIDING NK_LP duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); } fill_opt(A) ::= . { A = NULL; } fill_opt(A) ::= FILL NK_LP fill_mode(B) NK_RP. { A = createFillNode(pCxt, B, NULL); } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index f21db0f133..b7ecf160fd 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -420,6 +420,14 @@ static bool checkColumnName(SAstCreateContext* pCxt, const SToken* pColumnName) return pCxt->valid; } +static bool checkIndexName(SAstCreateContext* pCxt, const SToken* pIndexName) { + if (NULL == pIndexName) { + return false; + } + pCxt->valid = pIndexName->n < TSDB_INDEX_NAME_LEN ? true : false; + return pCxt->valid; +} + SNode* createRawExprNode(SAstCreateContext* pCxt, const SToken* pToken, SNode* pNode) { SRawExprNode* target = (SRawExprNode*)nodesMakeNode(QUERY_NODE_RAW_EXPR); CHECK_OUT_OF_MEM(target); @@ -741,8 +749,8 @@ SNode* createSetOperator(SAstCreateContext* pCxt, ESetOperatorType type, SNode* return (SNode*)setOp; } -SDatabaseOptions* createDefaultDatabaseOptions(SAstCreateContext* pCxt) { - SDatabaseOptions* pOptions = calloc(1, sizeof(SDatabaseOptions)); +SNode* createDefaultDatabaseOptions(SAstCreateContext* pCxt) { + SDatabaseOptions* pOptions = nodesMakeNode(QUERY_NODE_DATABASE_OPTIONS); CHECK_OUT_OF_MEM(pOptions); pOptions->numOfBlocks = TSDB_DEFAULT_TOTAL_BLOCKS; pOptions->cacheBlockSize = TSDB_DEFAULT_CACHE_BLOCK_SIZE; @@ -761,14 +769,14 @@ SDatabaseOptions* createDefaultDatabaseOptions(SAstCreateContext* pCxt) { pOptions->numOfVgroups = TSDB_DEFAULT_VN_PER_DB; pOptions->singleStable = TSDB_DEFAULT_DB_SINGLE_STABLE_OPTION; pOptions->streamMode = TSDB_DEFAULT_DB_STREAM_MODE_OPTION; - return pOptions; + return (SNode*)pOptions; } -SDatabaseOptions* setDatabaseOption(SAstCreateContext* pCxt, SDatabaseOptions* pOptions, EDatabaseOptionType type, const SToken* pVal) { - return setDbOptionFuncs[type](pCxt, pOptions, pVal); +SNode* setDatabaseOption(SAstCreateContext* pCxt, SNode* pOptions, EDatabaseOptionType type, const SToken* pVal) { + return (SNode*)setDbOptionFuncs[type](pCxt, (SDatabaseOptions*)pOptions, pVal); } -SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pDbName, SDatabaseOptions* pOptions) { +SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pDbName, SNode* pOptions) { if (!checkDbName(pCxt, pDbName)) { return NULL; } @@ -776,8 +784,7 @@ SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, cons CHECK_OUT_OF_MEM(pStmt); strncpy(pStmt->dbName, pDbName->z, pDbName->n); pStmt->ignoreExists = ignoreExists; - pStmt->options = *pOptions; - tfree(pOptions); + pStmt->pOptions = (SDatabaseOptions*)pOptions; return (SNode*)pStmt; } @@ -792,20 +799,20 @@ SNode* createDropDatabaseStmt(SAstCreateContext* pCxt, bool ignoreNotExists, con return (SNode*)pStmt; } -STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt) { - STableOptions* pOptions = calloc(1, sizeof(STableOptions)); +SNode* createDefaultTableOptions(SAstCreateContext* pCxt) { + STableOptions* pOptions = nodesMakeNode(QUERY_NODE_TABLE_OPTIONS); CHECK_OUT_OF_MEM(pOptions); pOptions->keep = TSDB_DEFAULT_KEEP; pOptions->ttl = TSDB_DEFAULT_DB_TTL_OPTION; - return pOptions; + return (SNode*)pOptions; } -STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ETableOptionType type, const SToken* pVal) { - return setTableOptionFuncs[type](pCxt, pOptions, pVal); +SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, const SToken* pVal) { + return (SNode*)setTableOptionFuncs[type](pCxt, (STableOptions*)pOptions, pVal); } -STableOptions* setTableSmaOption(SAstCreateContext* pCxt, STableOptions* pOptions, SNodeList* pSma) { - pOptions->pSma = pSma; +SNode* setTableSmaOption(SAstCreateContext* pCxt, SNode* pOptions, SNodeList* pSma) { + ((STableOptions*)pOptions)->pSma = pSma; return pOptions; } @@ -831,7 +838,7 @@ SDataType createVarLenDataType(uint8_t type, const SToken* pLen) { } SNode* createCreateTableStmt(SAstCreateContext* pCxt, - bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNodeList* pTags, STableOptions* pOptions) { + bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNodeList* pTags, SNode* pOptions) { SCreateTableStmt* pStmt = (SCreateTableStmt*)nodesMakeNode(QUERY_NODE_CREATE_TABLE_STMT); CHECK_OUT_OF_MEM(pStmt); strcpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName); @@ -839,9 +846,7 @@ SNode* createCreateTableStmt(SAstCreateContext* pCxt, pStmt->ignoreExists = ignoreExists; pStmt->pCols = pCols; pStmt->pTags = pTags; - pStmt->options = *pOptions; - nodesDestroyList(pOptions->pSma); - tfree(pOptions); + pStmt->pOptions = (STableOptions*)pOptions; nodesDestroyNode(pRealTable); return (SNode*)pStmt; } @@ -992,3 +997,34 @@ SNode* createDropDnodeStmt(SAstCreateContext* pCxt, const SToken* pDnode) { } return (SNode*)pStmt; } + +SNode* createCreateIndexStmt(SAstCreateContext* pCxt, EIndexType type, const SToken* pIndexName, const SToken* pTableName, SNodeList* pCols, SNode* pOptions) { + if (!checkIndexName(pCxt, pIndexName) || !checkTableName(pCxt, pTableName)) { + return NULL; + } + SCreateIndexStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_INDEX_STMT); + CHECK_OUT_OF_MEM(pStmt); + pStmt->indexType = type; + strncpy(pStmt->indexName, pIndexName->z, pIndexName->n); + strncpy(pStmt->tableName, pTableName->z, pTableName->n); + pStmt->pCols = pCols; + pStmt->pOptions = (SIndexOptions*)pOptions; + return (SNode*)pStmt; +} + +SNode* createIndexOption(SAstCreateContext* pCxt, SNodeList* pFuncs, SNode* pInterval, SNode* pOffset, SNode* pSliding) { + SIndexOptions* pOptions = nodesMakeNode(QUERY_NODE_INDEX_OPTIONS); + CHECK_OUT_OF_MEM(pOptions); + pOptions->pFuncs = pFuncs; + pOptions->pInterval = pInterval; + pOptions->pOffset = pOffset; + pOptions->pSliding = pSliding; + return (SNode*)pOptions; +} + +SNode* createCreateQnodeStmt(SAstCreateContext* pCxt, const SToken* pDnodeId) { + SCreateQnodeStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_QNODE_STMT); + CHECK_OUT_OF_MEM(pStmt); + pStmt->dnodeId = strtol(pDnodeId->z, NULL, 10);; + return (SNode*)pStmt; +} diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c index eefa99dae0..4d50d92d9e 100644 --- a/source/libs/parser/src/parTokenizer.c +++ b/source/libs/parser/src/parTokenizer.c @@ -59,11 +59,13 @@ static SKeyword keywordTable[] = { {"FLOAT", TK_FLOAT}, {"FROM", TK_FROM}, {"FSYNC", TK_FSYNC}, + {"FUNCTION", TK_FUNCTION}, {"GROUP", TK_GROUP}, {"HAVING", TK_HAVING}, {"IF", TK_IF}, {"IMPORT", TK_IMPORT}, {"IN", TK_IN}, + {"INDEX", TK_INDEX}, {"INNER", TK_INNER}, {"INT", TK_INT}, {"INSERT", TK_INSERT}, @@ -97,6 +99,8 @@ static SKeyword keywordTable[] = { {"PRECISION", TK_PRECISION}, {"PRIVILEGE", TK_PRIVILEGE}, {"PREV", TK_PREV}, + {"QNODE", TK_QNODE}, + {"QNODES", TK_QNODES}, {"QUORUM", TK_QUORUM}, {"REPLICA", TK_REPLICA}, {"SELECT", TK_SELECT}, @@ -230,7 +234,6 @@ static SKeyword keywordTable[] = { // {"TOPICS", TK_TOPICS}, // {"COMPACT", TK_COMPACT}, // {"MODIFY", TK_MODIFY}, - // {"FUNCTION", TK_FUNCTION}, // {"FUNCTIONS", TK_FUNCTIONS}, // {"OUTPUTTYPE", TK_OUTPUTTYPE}, // {"AGGREGATE", TK_AGGREGATE}, diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index ac1509462b..4f89e7e703 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -254,8 +254,7 @@ static int32_t trimStringWithVarFormat(const char* src, int32_t len, bool format static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { if (pVal->isDuration) { - char unit = 0; - if (parseAbsoluteDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &unit, pVal->node.resType.precision) != TSDB_CODE_SUCCESS) { + if (parseAbsoluteDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit, pVal->node.resType.precision) != TSDB_CODE_SUCCESS) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); } } else { @@ -706,9 +705,17 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SNodeList* pGroupByList return translateExprList(pCxt, pGroupByList); } +static int32_t doTranslateWindow(STranslateContext* pCxt, SNode* pWindow) { + return TSDB_CODE_SUCCESS; +} + static int32_t translateWindow(STranslateContext* pCxt, SNode* pWindow) { pCxt->currClause = SQL_CLAUSE_WINDOW; - return translateExpr(pCxt, pWindow); + int32_t code = translateExpr(pCxt, pWindow); + if (TSDB_CODE_SUCCESS == code) { + code = doTranslateWindow(pCxt, pWindow); + } + return code; } static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartitionByList) { @@ -760,26 +767,26 @@ static void buildCreateDbReq(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt SName name = {0}; tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName)); tNameGetFullDbName(&name, pReq->db); - pReq->numOfVgroups = pStmt->options.numOfVgroups; - pReq->cacheBlockSize = pStmt->options.cacheBlockSize; - pReq->totalBlocks = pStmt->options.numOfBlocks; - pReq->daysPerFile = pStmt->options.daysPerFile; - pReq->daysToKeep0 = pStmt->options.keep; + pReq->numOfVgroups = pStmt->pOptions->numOfVgroups; + pReq->cacheBlockSize = pStmt->pOptions->cacheBlockSize; + pReq->totalBlocks = pStmt->pOptions->numOfBlocks; + pReq->daysPerFile = pStmt->pOptions->daysPerFile; + pReq->daysToKeep0 = pStmt->pOptions->keep; pReq->daysToKeep1 = -1; pReq->daysToKeep2 = -1; - pReq->minRows = pStmt->options.minRowsPerBlock; - pReq->maxRows = pStmt->options.maxRowsPerBlock; + pReq->minRows = pStmt->pOptions->minRowsPerBlock; + pReq->maxRows = pStmt->pOptions->maxRowsPerBlock; pReq->commitTime = -1; - pReq->fsyncPeriod = pStmt->options.fsyncPeriod; - pReq->walLevel = pStmt->options.walLevel; - pReq->precision = pStmt->options.precision; - pReq->compression = pStmt->options.compressionLevel; - pReq->replications = pStmt->options.replica; - pReq->quorum = pStmt->options.quorum; + pReq->fsyncPeriod = pStmt->pOptions->fsyncPeriod; + pReq->walLevel = pStmt->pOptions->walLevel; + pReq->precision = pStmt->pOptions->precision; + pReq->compression = pStmt->pOptions->compressionLevel; + pReq->replications = pStmt->pOptions->replica; + pReq->quorum = pStmt->pOptions->quorum; pReq->update = -1; - pReq->cacheLastRow = pStmt->options.cachelast; + pReq->cacheLastRow = pStmt->pOptions->cachelast; pReq->ignoreExist = pStmt->ignoreExists; - pReq->streamMode = pStmt->options.streamMode; + pReq->streamMode = pStmt->pOptions->streamMode; return; } @@ -788,14 +795,14 @@ static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseS buildCreateDbReq(pCxt, pStmt, &createReq); pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_DB; pCxt->pCmdMsg->msgLen = tSerializeSCreateDbReq(NULL, 0, &createReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSCreateDbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq); @@ -811,14 +818,14 @@ static int32_t translateDropDatabase(STranslateContext* pCxt, SDropDatabaseStmt* dropReq.ignoreNotExists = pStmt->ignoreNotExists; pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_DROP_DB; pCxt->pCmdMsg->msgLen = tSerializeSDropDbReq(NULL, 0, &dropReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSDropDbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &dropReq); @@ -852,7 +859,7 @@ static int32_t translateCreateSuperTable(STranslateContext* pCxt, SCreateTableSt tNameExtractFullName(&tableName, createReq.name); pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { tFreeSMCreateStbReq(&createReq); return TSDB_CODE_OUT_OF_MEMORY; } @@ -860,7 +867,7 @@ static int32_t translateCreateSuperTable(STranslateContext* pCxt, SCreateTableSt pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_STB; pCxt->pCmdMsg->msgLen = tSerializeSMCreateStbReq(NULL, 0, &createReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { tFreeSMCreateStbReq(&createReq); return TSDB_CODE_OUT_OF_MEMORY; } @@ -876,14 +883,14 @@ static int32_t doTranslateDropSuperTable(STranslateContext* pCxt, const SName* p dropReq.igNotExists = ignoreNotExists; pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_DROP_STB; pCxt->pCmdMsg->msgLen = tSerializeSMDropStbReq(NULL, 0, &dropReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSMDropStbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &dropReq); @@ -929,14 +936,14 @@ static int32_t translateUseDatabase(STranslateContext* pCxt, SUseDatabaseStmt* p catalogGetDBVgVersion(pCxt->pParseCxt->pCatalog, usedbReq.db, &usedbReq.vgVersion, &usedbReq.dbId, &usedbReq.numOfTable); pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_USE_DB; pCxt->pCmdMsg->msgLen = tSerializeSUseDbReq(NULL, 0, &usedbReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSUseDbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &usedbReq); @@ -952,14 +959,14 @@ static int32_t translateCreateUser(STranslateContext* pCxt, SCreateUserStmt* pSt strcpy(createReq.pass, pStmt->password); pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_USER; pCxt->pCmdMsg->msgLen = tSerializeSCreateUserReq(NULL, 0, &createReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSCreateUserReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq); @@ -978,14 +985,14 @@ static int32_t translateAlterUser(STranslateContext* pCxt, SAlterUserStmt* pStmt } pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_ALTER_USER; pCxt->pCmdMsg->msgLen = tSerializeSAlterUserReq(NULL, 0, &alterReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSAlterUserReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &alterReq); @@ -998,14 +1005,14 @@ static int32_t translateDropUser(STranslateContext* pCxt, SDropUserStmt* pStmt) strcpy(dropReq.user, pStmt->useName); pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_DROP_USER; pCxt->pCmdMsg->msgLen = tSerializeSDropUserReq(NULL, 0, &dropReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSDropUserReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &dropReq); @@ -1019,14 +1026,14 @@ static int32_t translateCreateDnode(STranslateContext* pCxt, SCreateDnodeStmt* p createReq.port = pStmt->port; pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_DNODE; pCxt->pCmdMsg->msgLen = tSerializeSCreateDnodeReq(NULL, 0, &createReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSCreateDnodeReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq); @@ -1041,14 +1048,14 @@ static int32_t translateDropDnode(STranslateContext* pCxt, SDropDnodeStmt* pStmt dropReq.port = pStmt->port; pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_DROP_DNODE; pCxt->pCmdMsg->msgLen = tSerializeSDropDnodeReq(NULL, 0, &dropReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSDropDnodeReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &dropReq); @@ -1070,6 +1077,8 @@ static int32_t nodeTypeToShowType(ENodeType nt) { return TSDB_MGMT_TABLE_VGROUP; case QUERY_NODE_SHOW_MNODES_STMT: return TSDB_MGMT_TABLE_MNODE; + case QUERY_NODE_SHOW_QNODES_STMT: + return TSDB_MGMT_TABLE_QNODE; default: break; } @@ -1086,14 +1095,14 @@ static int32_t translateShow(STranslateContext* pCxt, SShowStmt* pStmt) { } pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; pCxt->pCmdMsg->msgType = TDMT_MND_SHOW; pCxt->pCmdMsg->msgLen = tSerializeSShowReq(NULL, 0, &showReq); pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); - if (NULL== pCxt->pCmdMsg->pMsg) { + if (NULL == pCxt->pCmdMsg->pMsg) { return TSDB_CODE_OUT_OF_MEMORY; } tSerializeSShowReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &showReq); @@ -1121,7 +1130,7 @@ static int32_t translateShowTables(STranslateContext* pCxt) { pShowReq->head.vgId = htonl(info->vgId); pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); - if (NULL== pCxt->pCmdMsg) { + if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } pCxt->pCmdMsg->epSet = info->epSet; @@ -1133,6 +1142,84 @@ static int32_t translateShowTables(STranslateContext* pCxt) { return TSDB_CODE_SUCCESS; } +static int32_t translateCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) { + SVCreateTSmaReq createSmaReq = {0}; + + if (DEAL_RES_ERROR == translateValue(pCxt, (SValueNode*)pStmt->pOptions->pInterval) || + (NULL != pStmt->pOptions->pOffset && DEAL_RES_ERROR == translateValue(pCxt, (SValueNode*)pStmt->pOptions->pOffset)) || + (NULL != pStmt->pOptions->pSliding && DEAL_RES_ERROR == translateValue(pCxt, (SValueNode*)pStmt->pOptions->pSliding))) { + return pCxt->errCode; + } + + createSmaReq.tSma.intervalUnit = ((SValueNode*)pStmt->pOptions->pInterval)->unit; + createSmaReq.tSma.slidingUnit = (NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->unit : 0); + strcpy(createSmaReq.tSma.indexName, pStmt->indexName); + + SName name; + name.type = TSDB_TABLE_NAME_T; + name.acctId = pCxt->pParseCxt->acctId; + strcpy(name.dbname, pCxt->pParseCxt->db); + strcpy(name.tname, pStmt->tableName); + STableMeta* pMeta = NULL; + int32_t code = catalogGetTableMeta(pCxt->pParseCxt->pCatalog, pCxt->pParseCxt->pTransporter, &pCxt->pParseCxt->mgmtEpSet, &name, &pMeta); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + + createSmaReq.tSma.tableUid = pMeta->uid; + createSmaReq.tSma.interval = ((SValueNode*)pStmt->pOptions->pInterval)->datum.i; + createSmaReq.tSma.sliding = (NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->datum.i : 0); + code = nodesListToString(pStmt->pOptions->pFuncs, false, &createSmaReq.tSma.expr, &createSmaReq.tSma.exprLen); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + + pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); + if (NULL == pCxt->pCmdMsg) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; + pCxt->pCmdMsg->msgType = TDMT_VND_CREATE_SMA; + pCxt->pCmdMsg->msgLen = tSerializeSVCreateTSmaReq(NULL, &createSmaReq); + pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); + if (NULL == pCxt->pCmdMsg->pMsg) { + return TSDB_CODE_OUT_OF_MEMORY; + } + void* pBuf = pCxt->pCmdMsg->pMsg; + tSerializeSVCreateTSmaReq(&pBuf, &createSmaReq); + tdDestroyTSma(&createSmaReq.tSma); + + return TSDB_CODE_SUCCESS; +} + +static int32_t translateCreateIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) { + if (INDEX_TYPE_SMA == pStmt->indexType) { + return translateCreateSmaIndex(pCxt, pStmt); + } else { + // todo fulltext index + return TSDB_CODE_FAILED; + } +} + +static int32_t translateCreateQnode(STranslateContext* pCxt, SCreateQnodeStmt* pStmt) { + SMCreateQnodeReq createReq = { .dnodeId = pStmt->dnodeId }; + + pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo)); + if (NULL == pCxt->pCmdMsg) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet; + pCxt->pCmdMsg->msgType = TDMT_DND_CREATE_QNODE; + pCxt->pCmdMsg->msgLen = tSerializeSMCreateDropQSBNodeReq(NULL, 0, &createReq); + pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen); + if (NULL == pCxt->pCmdMsg->pMsg) { + return TSDB_CODE_OUT_OF_MEMORY; + } + tSerializeSMCreateDropQSBNodeReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq); + + return TSDB_CODE_SUCCESS; +} + static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) { int32_t code = TSDB_CODE_SUCCESS; switch (nodeType(pNode)) { @@ -1178,11 +1265,18 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) { case QUERY_NODE_SHOW_DNODES_STMT: case QUERY_NODE_SHOW_VGROUPS_STMT: case QUERY_NODE_SHOW_MNODES_STMT: + case QUERY_NODE_SHOW_QNODES_STMT: code = translateShow(pCxt, (SShowStmt*)pNode); break; case QUERY_NODE_SHOW_TABLES_STMT: code = translateShowTables(pCxt); break; + case QUERY_NODE_CREATE_INDEX_STMT: + code = translateCreateIndex(pCxt, (SCreateIndexStmt*)pNode); + break; + case QUERY_NODE_CREATE_QNODE_STMT: + code = translateCreateQnode(pCxt, (SCreateQnodeStmt*)pNode); + break; default: break; } diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index c54bbd41cc..8b46d3600b 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -99,24 +99,22 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned char -#define YYNOCODE 209 +#define YYNOCODE 218 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SToken typedef union { int yyinit; ParseTOKENTYPE yy0; - SNodeList* yy46; - SDataType yy70; - SToken yy129; - ENullOrder yy147; - bool yy185; - EOrder yy202; - SNode* yy256; - EJoinType yy266; - EOperatorType yy326; - STableOptions* yy340; - EFillMode yy360; - SDatabaseOptions* yy391; + SToken yy5; + bool yy25; + SNodeList* yy40; + ENullOrder yy53; + EOrder yy54; + SNode* yy68; + EJoinType yy92; + EFillMode yy94; + SDataType yy372; + EOperatorType yy416; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -131,17 +129,17 @@ typedef union { #define ParseCTX_PARAM #define ParseCTX_FETCH #define ParseCTX_STORE -#define YYNSTATE 279 -#define YYNRULE 237 -#define YYNTOKEN 135 -#define YY_MAX_SHIFT 278 -#define YY_MIN_SHIFTREDUCE 439 -#define YY_MAX_SHIFTREDUCE 675 -#define YY_ERROR_ACTION 676 -#define YY_ACCEPT_ACTION 677 -#define YY_NO_ACTION 678 -#define YY_MIN_REDUCE 679 -#define YY_MAX_REDUCE 915 +#define YYNSTATE 313 +#define YYNRULE 248 +#define YYNTOKEN 140 +#define YY_MAX_SHIFT 312 +#define YY_MIN_SHIFTREDUCE 480 +#define YY_MAX_SHIFTREDUCE 727 +#define YY_ERROR_ACTION 728 +#define YY_ACCEPT_ACTION 729 +#define YY_NO_ACTION 730 +#define YY_MIN_REDUCE 731 +#define YY_MAX_REDUCE 978 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -208,285 +206,307 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (905) +#define YY_ACTTAB_COUNT (963) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 137, 149, 23, 95, 772, 721, 770, 247, 150, 784, - /* 10 */ 782, 148, 30, 28, 26, 25, 24, 784, 782, 194, - /* 20 */ 177, 808, 201, 735, 66, 30, 28, 26, 25, 24, - /* 30 */ 692, 166, 194, 222, 808, 60, 208, 132, 793, 782, - /* 40 */ 195, 209, 222, 54, 794, 730, 797, 833, 733, 58, - /* 50 */ 132, 139, 829, 906, 19, 785, 782, 733, 558, 73, - /* 60 */ 840, 841, 867, 845, 30, 28, 26, 25, 24, 271, - /* 70 */ 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, - /* 80 */ 260, 259, 258, 257, 256, 255, 26, 25, 24, 550, - /* 90 */ 22, 141, 171, 576, 577, 578, 579, 580, 581, 582, - /* 100 */ 584, 585, 586, 22, 141, 617, 576, 577, 578, 579, - /* 110 */ 580, 581, 582, 584, 585, 586, 275, 274, 499, 245, - /* 120 */ 244, 243, 503, 242, 505, 506, 241, 508, 238, 41, - /* 130 */ 514, 235, 516, 517, 232, 229, 194, 194, 808, 808, - /* 140 */ 729, 184, 793, 782, 195, 77, 45, 53, 794, 170, - /* 150 */ 797, 833, 194, 719, 808, 131, 829, 726, 793, 782, - /* 160 */ 195, 104, 93, 125, 794, 145, 797, 894, 153, 78, - /* 170 */ 221, 772, 180, 770, 808, 103, 736, 66, 793, 782, - /* 180 */ 195, 76, 209, 54, 794, 892, 797, 833, 194, 254, - /* 190 */ 808, 139, 829, 71, 793, 782, 195, 221, 42, 54, - /* 200 */ 794, 101, 797, 833, 772, 94, 771, 139, 829, 906, - /* 210 */ 616, 156, 860, 894, 180, 254, 808, 551, 890, 50, - /* 220 */ 793, 782, 195, 10, 47, 54, 794, 893, 797, 833, - /* 230 */ 194, 892, 808, 139, 829, 71, 793, 782, 195, 29, - /* 240 */ 27, 54, 794, 677, 797, 833, 41, 187, 539, 139, - /* 250 */ 829, 906, 114, 61, 861, 763, 537, 728, 146, 221, - /* 260 */ 851, 29, 27, 618, 11, 194, 182, 808, 196, 548, - /* 270 */ 539, 793, 782, 195, 77, 639, 121, 794, 537, 797, - /* 280 */ 146, 194, 56, 808, 1, 10, 11, 793, 782, 195, - /* 290 */ 79, 51, 55, 794, 894, 797, 833, 9, 8, 62, - /* 300 */ 832, 829, 725, 223, 222, 449, 1, 219, 76, 173, - /* 310 */ 248, 152, 892, 212, 538, 540, 543, 720, 191, 733, - /* 320 */ 194, 573, 808, 735, 66, 223, 793, 782, 195, 6, - /* 330 */ 613, 125, 794, 157, 797, 77, 538, 540, 543, 194, - /* 340 */ 222, 808, 96, 220, 184, 793, 782, 195, 29, 27, - /* 350 */ 119, 794, 163, 797, 594, 733, 847, 539, 172, 167, - /* 360 */ 165, 88, 29, 27, 251, 537, 188, 146, 250, 186, - /* 370 */ 894, 539, 222, 11, 844, 109, 847, 177, 852, 537, - /* 380 */ 613, 146, 192, 252, 76, 863, 154, 733, 892, 194, - /* 390 */ 177, 808, 60, 1, 843, 793, 782, 195, 735, 66, - /* 400 */ 55, 794, 249, 797, 833, 60, 58, 7, 181, 829, - /* 410 */ 184, 449, 223, 9, 8, 179, 72, 840, 841, 58, - /* 420 */ 845, 450, 451, 538, 540, 543, 223, 85, 189, 91, - /* 430 */ 840, 176, 625, 175, 82, 847, 894, 538, 540, 543, - /* 440 */ 178, 98, 29, 27, 183, 222, 29, 27, 155, 548, - /* 450 */ 76, 539, 809, 842, 892, 539, 674, 675, 77, 537, - /* 460 */ 733, 146, 194, 537, 808, 146, 20, 2, 793, 782, - /* 470 */ 195, 29, 27, 55, 794, 583, 797, 833, 587, 211, - /* 480 */ 539, 217, 830, 551, 215, 642, 539, 7, 537, 588, - /* 490 */ 146, 1, 864, 194, 537, 808, 31, 164, 161, 793, - /* 500 */ 782, 195, 555, 874, 68, 794, 223, 797, 80, 31, - /* 510 */ 223, 162, 640, 641, 643, 644, 7, 538, 540, 543, - /* 520 */ 789, 538, 540, 543, 106, 543, 194, 787, 808, 492, - /* 530 */ 159, 63, 793, 782, 195, 223, 64, 125, 794, 140, - /* 540 */ 797, 223, 873, 185, 907, 718, 538, 540, 543, 194, - /* 550 */ 160, 808, 538, 540, 543, 793, 782, 195, 487, 84, - /* 560 */ 68, 794, 138, 797, 194, 56, 808, 5, 854, 174, - /* 570 */ 793, 782, 195, 520, 70, 120, 794, 524, 797, 194, - /* 580 */ 227, 808, 4, 87, 63, 793, 782, 195, 158, 613, - /* 590 */ 122, 794, 251, 797, 89, 194, 250, 808, 529, 547, - /* 600 */ 908, 793, 782, 195, 59, 64, 117, 794, 65, 797, - /* 610 */ 194, 252, 808, 550, 848, 63, 793, 782, 195, 32, - /* 620 */ 16, 123, 794, 142, 797, 194, 815, 808, 90, 909, - /* 630 */ 249, 793, 782, 195, 193, 891, 118, 794, 194, 797, - /* 640 */ 808, 97, 546, 190, 793, 782, 195, 197, 210, 124, - /* 650 */ 794, 194, 797, 808, 40, 102, 552, 793, 782, 195, - /* 660 */ 734, 213, 805, 794, 147, 797, 194, 46, 808, 113, - /* 670 */ 44, 225, 793, 782, 195, 115, 110, 804, 794, 194, - /* 680 */ 797, 808, 278, 3, 128, 793, 782, 195, 129, 116, - /* 690 */ 803, 794, 31, 797, 194, 14, 808, 81, 636, 83, - /* 700 */ 793, 782, 195, 35, 638, 135, 794, 194, 797, 808, - /* 710 */ 69, 86, 37, 793, 782, 195, 632, 631, 134, 794, - /* 720 */ 194, 797, 808, 168, 38, 169, 793, 782, 195, 787, - /* 730 */ 610, 136, 794, 18, 797, 194, 15, 808, 609, 92, - /* 740 */ 207, 793, 782, 195, 206, 546, 133, 794, 205, 797, - /* 750 */ 33, 194, 34, 808, 75, 8, 574, 793, 782, 195, - /* 760 */ 556, 665, 126, 794, 17, 797, 177, 202, 12, 39, - /* 770 */ 660, 659, 143, 664, 204, 203, 30, 28, 26, 25, - /* 780 */ 24, 60, 99, 663, 130, 144, 13, 776, 218, 695, - /* 790 */ 127, 67, 775, 774, 112, 58, 200, 773, 199, 724, - /* 800 */ 198, 100, 57, 21, 723, 74, 840, 841, 111, 845, - /* 810 */ 694, 688, 683, 30, 28, 26, 25, 24, 30, 28, - /* 820 */ 26, 25, 24, 722, 458, 693, 30, 28, 26, 25, - /* 830 */ 24, 52, 687, 686, 107, 682, 681, 214, 680, 216, - /* 840 */ 105, 43, 47, 786, 226, 108, 224, 541, 36, 151, - /* 850 */ 513, 230, 521, 228, 512, 511, 518, 231, 233, 236, - /* 860 */ 515, 509, 234, 239, 558, 237, 510, 507, 498, 528, - /* 870 */ 240, 527, 526, 246, 77, 456, 48, 477, 253, 476, - /* 880 */ 470, 49, 475, 474, 473, 472, 471, 469, 685, 468, - /* 890 */ 467, 466, 465, 464, 671, 672, 463, 462, 461, 272, - /* 900 */ 273, 684, 679, 276, 277, + /* 0 */ 152, 236, 277, 871, 844, 252, 252, 167, 186, 784, + /* 10 */ 847, 844, 31, 29, 27, 26, 25, 846, 844, 209, + /* 20 */ 787, 787, 309, 308, 846, 31, 29, 27, 26, 25, + /* 30 */ 746, 236, 151, 871, 106, 826, 39, 824, 251, 844, + /* 40 */ 145, 957, 238, 61, 236, 856, 871, 782, 57, 857, + /* 50 */ 860, 896, 910, 145, 956, 154, 892, 969, 955, 187, + /* 60 */ 164, 610, 213, 832, 239, 166, 930, 10, 826, 907, + /* 70 */ 824, 251, 301, 300, 299, 298, 297, 296, 295, 294, + /* 80 */ 293, 292, 291, 290, 289, 288, 287, 286, 285, 599, + /* 90 */ 31, 29, 27, 26, 25, 24, 109, 23, 159, 228, + /* 100 */ 628, 629, 630, 631, 632, 633, 634, 636, 637, 638, + /* 110 */ 23, 159, 39, 628, 629, 630, 631, 632, 633, 634, + /* 120 */ 636, 637, 638, 783, 542, 275, 274, 273, 546, 272, + /* 130 */ 548, 549, 271, 551, 268, 165, 557, 265, 559, 560, + /* 140 */ 262, 259, 236, 54, 871, 694, 251, 789, 70, 252, + /* 150 */ 844, 65, 249, 238, 779, 224, 856, 208, 214, 56, + /* 160 */ 857, 860, 896, 229, 787, 601, 144, 892, 775, 205, + /* 170 */ 692, 693, 695, 696, 220, 10, 910, 82, 957, 31, + /* 180 */ 29, 27, 26, 25, 215, 210, 223, 170, 871, 64, + /* 190 */ 826, 81, 824, 906, 844, 955, 600, 238, 773, 826, + /* 200 */ 856, 825, 224, 57, 857, 860, 896, 187, 62, 910, + /* 210 */ 154, 892, 76, 723, 724, 27, 26, 25, 102, 903, + /* 220 */ 219, 220, 218, 284, 105, 957, 905, 729, 610, 82, + /* 230 */ 201, 923, 87, 223, 21, 871, 64, 284, 81, 227, + /* 240 */ 75, 844, 955, 635, 238, 104, 639, 856, 490, 86, + /* 250 */ 57, 857, 860, 896, 197, 62, 190, 154, 892, 76, + /* 260 */ 173, 68, 236, 278, 871, 78, 903, 904, 127, 908, + /* 270 */ 844, 817, 40, 238, 252, 84, 856, 250, 924, 57, + /* 280 */ 857, 860, 896, 957, 9, 8, 154, 892, 969, 787, + /* 290 */ 236, 48, 871, 178, 30, 28, 81, 953, 844, 206, + /* 300 */ 955, 238, 780, 590, 856, 833, 239, 57, 857, 860, + /* 310 */ 896, 588, 6, 161, 154, 892, 969, 30, 28, 670, + /* 320 */ 169, 99, 12, 790, 70, 914, 590, 31, 29, 27, + /* 330 */ 26, 25, 789, 70, 588, 774, 161, 189, 490, 236, + /* 340 */ 602, 871, 1, 677, 646, 12, 53, 844, 491, 492, + /* 350 */ 238, 50, 224, 856, 30, 28, 133, 857, 860, 252, + /* 360 */ 599, 253, 122, 590, 252, 1, 226, 172, 915, 665, + /* 370 */ 235, 588, 590, 161, 787, 957, 589, 591, 594, 787, + /* 380 */ 588, 171, 12, 926, 253, 281, 30, 28, 81, 280, + /* 390 */ 669, 665, 955, 789, 70, 590, 82, 9, 8, 589, + /* 400 */ 591, 594, 1, 588, 282, 161, 691, 96, 236, 195, + /* 410 */ 871, 130, 193, 59, 94, 196, 844, 134, 71, 238, + /* 420 */ 91, 253, 856, 279, 221, 58, 857, 860, 896, 625, + /* 430 */ 253, 83, 895, 892, 7, 872, 589, 591, 594, 108, + /* 440 */ 236, 2, 871, 597, 174, 589, 591, 594, 844, 772, + /* 450 */ 231, 238, 188, 253, 856, 38, 640, 58, 857, 860, + /* 460 */ 896, 726, 727, 32, 234, 892, 30, 28, 589, 591, + /* 470 */ 594, 85, 30, 28, 237, 590, 236, 603, 871, 607, + /* 480 */ 191, 590, 150, 588, 844, 161, 32, 238, 82, 588, + /* 490 */ 856, 161, 198, 72, 857, 860, 30, 28, 20, 281, + /* 500 */ 598, 668, 604, 280, 602, 590, 207, 82, 31, 29, + /* 510 */ 27, 26, 25, 588, 7, 161, 232, 199, 282, 927, + /* 520 */ 7, 851, 242, 92, 236, 937, 871, 583, 849, 594, + /* 530 */ 225, 970, 844, 253, 32, 238, 160, 279, 856, 253, + /* 540 */ 114, 138, 857, 860, 1, 204, 936, 112, 589, 591, + /* 550 */ 594, 244, 95, 119, 589, 591, 594, 236, 66, 871, + /* 560 */ 67, 5, 153, 253, 917, 844, 217, 98, 238, 203, + /* 570 */ 74, 856, 4, 63, 58, 857, 860, 896, 589, 591, + /* 580 */ 594, 665, 893, 236, 220, 871, 535, 100, 601, 530, + /* 590 */ 911, 844, 33, 68, 238, 202, 59, 856, 101, 64, + /* 600 */ 138, 857, 860, 236, 155, 871, 563, 972, 233, 567, + /* 610 */ 954, 844, 572, 257, 238, 107, 67, 856, 62, 68, + /* 620 */ 137, 857, 860, 17, 230, 236, 831, 871, 79, 903, + /* 630 */ 904, 878, 908, 844, 245, 47, 238, 49, 240, 856, + /* 640 */ 241, 69, 72, 857, 860, 236, 830, 871, 67, 163, + /* 650 */ 126, 216, 246, 844, 116, 788, 238, 158, 236, 856, + /* 660 */ 871, 255, 138, 857, 860, 247, 844, 128, 123, 238, + /* 670 */ 162, 312, 856, 125, 185, 138, 857, 860, 184, 597, + /* 680 */ 971, 60, 129, 183, 22, 182, 142, 305, 143, 838, + /* 690 */ 124, 236, 749, 871, 31, 29, 27, 26, 25, 844, + /* 700 */ 176, 177, 238, 837, 179, 856, 836, 835, 136, 857, + /* 710 */ 860, 181, 180, 55, 778, 236, 120, 871, 777, 748, + /* 720 */ 745, 740, 735, 844, 776, 501, 238, 747, 739, 856, + /* 730 */ 738, 734, 139, 857, 860, 236, 733, 871, 192, 732, + /* 740 */ 828, 175, 248, 844, 200, 41, 238, 194, 88, 856, + /* 750 */ 89, 90, 131, 857, 860, 236, 3, 871, 32, 14, + /* 760 */ 93, 36, 690, 844, 73, 97, 238, 211, 42, 856, + /* 770 */ 212, 684, 140, 857, 860, 236, 683, 871, 849, 15, + /* 780 */ 19, 34, 11, 844, 662, 43, 238, 44, 236, 856, + /* 790 */ 871, 712, 132, 857, 860, 661, 844, 711, 156, 238, + /* 800 */ 35, 716, 856, 717, 103, 141, 857, 860, 80, 715, + /* 810 */ 157, 16, 236, 8, 871, 110, 608, 13, 18, 113, + /* 820 */ 844, 111, 688, 238, 115, 236, 856, 871, 827, 868, + /* 830 */ 857, 860, 117, 844, 626, 45, 238, 243, 236, 856, + /* 840 */ 871, 118, 867, 857, 860, 46, 844, 50, 592, 238, + /* 850 */ 37, 848, 856, 121, 220, 866, 857, 860, 254, 256, + /* 860 */ 236, 564, 871, 168, 258, 260, 561, 261, 844, 64, + /* 870 */ 558, 238, 263, 236, 856, 871, 264, 148, 857, 860, + /* 880 */ 552, 844, 266, 267, 238, 550, 269, 856, 62, 270, + /* 890 */ 147, 857, 860, 236, 556, 871, 555, 222, 77, 903, + /* 900 */ 904, 844, 908, 554, 238, 541, 553, 856, 276, 51, + /* 910 */ 149, 857, 860, 236, 52, 871, 571, 570, 569, 499, + /* 920 */ 283, 844, 520, 519, 238, 518, 744, 856, 517, 516, + /* 930 */ 146, 857, 860, 236, 515, 871, 514, 513, 512, 511, + /* 940 */ 510, 844, 509, 508, 238, 303, 507, 856, 506, 505, + /* 950 */ 135, 857, 860, 504, 302, 304, 737, 306, 307, 736, + /* 960 */ 731, 310, 311, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 152, 154, 171, 172, 157, 0, 159, 158, 152, 161, - /* 10 */ 162, 144, 12, 13, 14, 15, 16, 161, 162, 155, - /* 20 */ 140, 157, 140, 156, 157, 12, 13, 14, 15, 16, - /* 30 */ 0, 167, 155, 140, 157, 155, 143, 37, 161, 162, - /* 40 */ 163, 36, 140, 166, 167, 143, 169, 170, 155, 169, - /* 50 */ 37, 174, 175, 176, 2, 161, 162, 155, 58, 179, - /* 60 */ 180, 181, 185, 183, 12, 13, 14, 15, 16, 39, - /* 70 */ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - /* 80 */ 50, 51, 52, 53, 54, 55, 14, 15, 16, 31, - /* 90 */ 90, 91, 31, 93, 94, 95, 96, 97, 98, 99, - /* 100 */ 100, 101, 102, 90, 91, 4, 93, 94, 95, 96, - /* 110 */ 97, 98, 99, 100, 101, 102, 137, 138, 67, 68, - /* 120 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 142, - /* 130 */ 79, 80, 81, 82, 83, 84, 155, 155, 157, 157, - /* 140 */ 153, 160, 161, 162, 163, 108, 139, 166, 167, 167, - /* 150 */ 169, 170, 155, 0, 157, 174, 175, 150, 161, 162, - /* 160 */ 163, 19, 104, 166, 167, 168, 169, 186, 154, 27, - /* 170 */ 31, 157, 155, 159, 157, 33, 156, 157, 161, 162, - /* 180 */ 163, 200, 36, 166, 167, 204, 169, 170, 155, 36, - /* 190 */ 157, 174, 175, 176, 161, 162, 163, 31, 56, 166, - /* 200 */ 167, 59, 169, 170, 157, 188, 159, 174, 175, 176, - /* 210 */ 109, 194, 195, 186, 155, 36, 157, 31, 185, 57, - /* 220 */ 161, 162, 163, 57, 62, 166, 167, 200, 169, 170, - /* 230 */ 155, 204, 157, 174, 175, 176, 161, 162, 163, 12, - /* 240 */ 13, 166, 167, 135, 169, 170, 142, 3, 21, 174, - /* 250 */ 175, 176, 145, 149, 195, 148, 29, 153, 31, 31, - /* 260 */ 185, 12, 13, 14, 37, 155, 37, 157, 160, 31, - /* 270 */ 21, 161, 162, 163, 108, 58, 166, 167, 29, 169, - /* 280 */ 31, 155, 65, 157, 57, 57, 37, 161, 162, 163, - /* 290 */ 104, 139, 166, 167, 186, 169, 170, 1, 2, 147, - /* 300 */ 174, 175, 150, 76, 140, 21, 57, 143, 200, 199, - /* 310 */ 63, 144, 204, 29, 87, 88, 89, 0, 65, 155, - /* 320 */ 155, 92, 157, 156, 157, 76, 161, 162, 163, 106, - /* 330 */ 107, 166, 167, 168, 169, 108, 87, 88, 89, 155, - /* 340 */ 140, 157, 207, 143, 160, 161, 162, 163, 12, 13, - /* 350 */ 166, 167, 198, 169, 58, 155, 164, 21, 113, 114, - /* 360 */ 115, 191, 12, 13, 47, 29, 65, 31, 51, 125, - /* 370 */ 186, 21, 140, 37, 182, 143, 164, 140, 105, 29, - /* 380 */ 107, 31, 129, 66, 200, 165, 144, 155, 204, 155, - /* 390 */ 140, 157, 155, 57, 182, 161, 162, 163, 156, 157, - /* 400 */ 166, 167, 85, 169, 170, 155, 169, 57, 174, 175, - /* 410 */ 160, 21, 76, 1, 2, 178, 179, 180, 181, 169, - /* 420 */ 183, 31, 32, 87, 88, 89, 76, 58, 127, 179, - /* 430 */ 180, 181, 14, 183, 65, 164, 186, 87, 88, 89, - /* 440 */ 184, 201, 12, 13, 14, 140, 12, 13, 143, 31, - /* 450 */ 200, 21, 157, 182, 204, 21, 133, 134, 108, 29, - /* 460 */ 155, 31, 155, 29, 157, 31, 90, 187, 161, 162, - /* 470 */ 163, 12, 13, 166, 167, 99, 169, 170, 102, 137, - /* 480 */ 21, 20, 175, 31, 23, 92, 21, 57, 29, 58, - /* 490 */ 31, 57, 165, 155, 29, 157, 65, 117, 116, 161, - /* 500 */ 162, 163, 58, 197, 166, 167, 76, 169, 196, 65, - /* 510 */ 76, 118, 119, 120, 121, 122, 57, 87, 88, 89, - /* 520 */ 57, 87, 88, 89, 58, 89, 155, 64, 157, 58, - /* 530 */ 162, 65, 161, 162, 163, 76, 65, 166, 167, 168, - /* 540 */ 169, 76, 197, 205, 206, 0, 87, 88, 89, 155, - /* 550 */ 162, 157, 87, 88, 89, 161, 162, 163, 58, 196, - /* 560 */ 166, 167, 162, 169, 155, 65, 157, 124, 193, 123, - /* 570 */ 161, 162, 163, 58, 190, 166, 167, 58, 169, 155, - /* 580 */ 65, 157, 110, 192, 65, 161, 162, 163, 111, 107, - /* 590 */ 166, 167, 47, 169, 189, 155, 51, 157, 58, 31, - /* 600 */ 206, 161, 162, 163, 155, 65, 166, 167, 58, 169, - /* 610 */ 155, 66, 157, 31, 164, 65, 161, 162, 163, 103, - /* 620 */ 57, 166, 167, 132, 169, 155, 173, 157, 177, 208, - /* 630 */ 85, 161, 162, 163, 128, 203, 166, 167, 155, 169, - /* 640 */ 157, 202, 31, 126, 161, 162, 163, 140, 140, 166, - /* 650 */ 167, 155, 169, 157, 142, 142, 31, 161, 162, 163, - /* 660 */ 155, 136, 166, 167, 136, 169, 155, 57, 157, 148, - /* 670 */ 139, 151, 161, 162, 163, 140, 139, 166, 167, 155, - /* 680 */ 169, 157, 136, 65, 146, 161, 162, 163, 146, 141, - /* 690 */ 166, 167, 65, 169, 155, 112, 157, 58, 58, 57, - /* 700 */ 161, 162, 163, 65, 58, 166, 167, 155, 169, 157, - /* 710 */ 57, 57, 57, 161, 162, 163, 58, 58, 166, 167, - /* 720 */ 155, 169, 157, 29, 57, 65, 161, 162, 163, 64, - /* 730 */ 58, 166, 167, 65, 169, 155, 112, 157, 58, 64, - /* 740 */ 26, 161, 162, 163, 30, 31, 166, 167, 34, 169, - /* 750 */ 105, 155, 65, 157, 64, 2, 92, 161, 162, 163, - /* 760 */ 58, 58, 166, 167, 65, 169, 140, 53, 112, 4, - /* 770 */ 29, 29, 29, 29, 60, 61, 12, 13, 14, 15, - /* 780 */ 16, 155, 64, 29, 18, 29, 57, 0, 22, 0, - /* 790 */ 24, 25, 0, 0, 19, 169, 64, 0, 53, 0, - /* 800 */ 86, 35, 27, 2, 0, 179, 180, 181, 33, 183, - /* 810 */ 0, 0, 0, 12, 13, 14, 15, 16, 12, 13, - /* 820 */ 14, 15, 16, 0, 38, 0, 12, 13, 14, 15, - /* 830 */ 16, 56, 0, 0, 59, 0, 0, 21, 0, 21, - /* 840 */ 19, 57, 62, 64, 29, 64, 63, 21, 57, 29, - /* 850 */ 78, 29, 58, 57, 78, 78, 58, 57, 29, 29, - /* 860 */ 58, 58, 57, 29, 58, 57, 78, 58, 21, 29, - /* 870 */ 57, 29, 21, 66, 108, 38, 57, 29, 37, 29, - /* 880 */ 21, 57, 29, 29, 29, 29, 29, 29, 0, 29, - /* 890 */ 29, 29, 29, 29, 130, 131, 29, 29, 29, 29, - /* 900 */ 28, 0, 0, 21, 20, 209, 209, 209, 209, 209, - /* 910 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 920 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 930 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 940 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 950 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 960 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 970 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 980 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 990 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 1000 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 1010 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 1020 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - /* 1030 */ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + /* 0 */ 157, 160, 163, 162, 168, 145, 145, 157, 148, 148, + /* 10 */ 174, 168, 12, 13, 14, 15, 16, 174, 168, 178, + /* 20 */ 160, 160, 142, 143, 174, 12, 13, 14, 15, 16, + /* 30 */ 0, 160, 159, 162, 216, 162, 147, 164, 31, 168, + /* 40 */ 40, 196, 171, 154, 160, 174, 162, 158, 177, 178, + /* 50 */ 179, 180, 175, 40, 209, 184, 185, 186, 213, 39, + /* 60 */ 167, 61, 178, 170, 171, 159, 195, 60, 162, 192, + /* 70 */ 164, 31, 42, 43, 44, 45, 46, 47, 48, 49, + /* 80 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 31, + /* 90 */ 12, 13, 14, 15, 16, 181, 182, 97, 98, 68, + /* 100 */ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 97, 98, 147, 100, 101, 102, 103, 104, 105, 106, + /* 120 */ 107, 108, 109, 158, 70, 71, 72, 73, 74, 75, + /* 130 */ 76, 77, 78, 79, 80, 149, 82, 83, 84, 85, + /* 140 */ 86, 87, 160, 144, 162, 99, 31, 161, 162, 145, + /* 150 */ 168, 152, 148, 171, 155, 173, 174, 92, 31, 177, + /* 160 */ 178, 179, 180, 132, 160, 31, 184, 185, 0, 123, + /* 170 */ 124, 125, 126, 127, 145, 60, 175, 114, 196, 12, + /* 180 */ 13, 14, 15, 16, 119, 120, 160, 159, 162, 160, + /* 190 */ 162, 209, 164, 192, 168, 213, 31, 171, 0, 162, + /* 200 */ 174, 164, 173, 177, 178, 179, 180, 39, 179, 175, + /* 210 */ 184, 185, 186, 135, 136, 14, 15, 16, 189, 190, + /* 220 */ 191, 145, 193, 39, 198, 196, 192, 140, 61, 114, + /* 230 */ 204, 205, 19, 160, 97, 162, 160, 39, 209, 3, + /* 240 */ 27, 168, 213, 106, 171, 111, 109, 174, 21, 36, + /* 250 */ 177, 178, 179, 180, 61, 179, 29, 184, 185, 186, + /* 260 */ 173, 68, 160, 66, 162, 189, 190, 191, 150, 193, + /* 270 */ 168, 153, 59, 171, 145, 62, 174, 148, 205, 177, + /* 280 */ 178, 179, 180, 196, 1, 2, 184, 185, 186, 160, + /* 290 */ 160, 144, 162, 145, 12, 13, 209, 195, 168, 207, + /* 300 */ 213, 171, 155, 21, 174, 170, 171, 177, 178, 179, + /* 310 */ 180, 29, 34, 31, 184, 185, 186, 12, 13, 14, + /* 320 */ 149, 201, 40, 161, 162, 195, 21, 12, 13, 14, + /* 330 */ 15, 16, 161, 162, 29, 0, 31, 142, 21, 160, + /* 340 */ 31, 162, 60, 14, 61, 40, 60, 168, 31, 32, + /* 350 */ 171, 65, 173, 174, 12, 13, 177, 178, 179, 145, + /* 360 */ 31, 79, 148, 21, 145, 60, 130, 148, 112, 113, + /* 370 */ 40, 29, 21, 31, 160, 196, 94, 95, 96, 160, + /* 380 */ 29, 149, 40, 176, 79, 50, 12, 13, 209, 54, + /* 390 */ 4, 113, 213, 161, 162, 21, 114, 1, 2, 94, + /* 400 */ 95, 96, 60, 29, 69, 31, 61, 61, 160, 20, + /* 410 */ 162, 18, 23, 68, 68, 22, 168, 24, 25, 171, + /* 420 */ 111, 79, 174, 88, 194, 177, 178, 179, 180, 99, + /* 430 */ 79, 38, 184, 185, 60, 162, 94, 95, 96, 210, + /* 440 */ 160, 197, 162, 31, 145, 94, 95, 96, 168, 0, + /* 450 */ 68, 171, 145, 79, 174, 147, 61, 177, 178, 179, + /* 460 */ 180, 138, 139, 68, 184, 185, 12, 13, 94, 95, + /* 470 */ 96, 147, 12, 13, 14, 21, 160, 31, 162, 61, + /* 480 */ 141, 21, 141, 29, 168, 31, 68, 171, 114, 29, + /* 490 */ 174, 31, 160, 177, 178, 179, 12, 13, 2, 50, + /* 500 */ 31, 115, 31, 54, 31, 21, 122, 114, 12, 13, + /* 510 */ 14, 15, 16, 29, 60, 31, 134, 165, 69, 176, + /* 520 */ 60, 60, 121, 169, 160, 206, 162, 61, 67, 96, + /* 530 */ 214, 215, 168, 79, 68, 171, 172, 88, 174, 79, + /* 540 */ 61, 177, 178, 179, 60, 168, 206, 68, 94, 95, + /* 550 */ 96, 61, 169, 61, 94, 95, 96, 160, 68, 162, + /* 560 */ 68, 129, 168, 79, 203, 168, 128, 202, 171, 117, + /* 570 */ 200, 174, 116, 160, 177, 178, 179, 180, 94, 95, + /* 580 */ 96, 113, 185, 160, 145, 162, 61, 199, 31, 61, + /* 590 */ 175, 168, 110, 68, 171, 172, 68, 174, 187, 160, + /* 600 */ 177, 178, 179, 160, 137, 162, 61, 217, 133, 61, + /* 610 */ 212, 168, 61, 68, 171, 211, 68, 174, 179, 68, + /* 620 */ 177, 178, 179, 60, 131, 160, 169, 162, 189, 190, + /* 630 */ 191, 183, 193, 168, 91, 144, 171, 60, 168, 174, + /* 640 */ 168, 61, 177, 178, 179, 160, 169, 162, 68, 168, + /* 650 */ 153, 208, 166, 168, 160, 160, 171, 172, 160, 174, + /* 660 */ 162, 156, 177, 178, 179, 165, 168, 145, 144, 171, + /* 670 */ 172, 141, 174, 19, 26, 177, 178, 179, 30, 31, + /* 680 */ 215, 27, 146, 35, 2, 37, 151, 33, 151, 0, + /* 690 */ 36, 160, 0, 162, 12, 13, 14, 15, 16, 168, + /* 700 */ 56, 67, 171, 0, 56, 174, 0, 0, 177, 178, + /* 710 */ 179, 63, 64, 59, 0, 160, 62, 162, 0, 0, + /* 720 */ 0, 0, 0, 168, 0, 41, 171, 0, 0, 174, + /* 730 */ 0, 0, 177, 178, 179, 160, 0, 162, 21, 0, + /* 740 */ 0, 93, 88, 168, 90, 60, 171, 21, 19, 174, + /* 750 */ 34, 89, 177, 178, 179, 160, 68, 162, 68, 118, + /* 760 */ 61, 68, 61, 168, 60, 60, 171, 29, 60, 174, + /* 770 */ 68, 61, 177, 178, 179, 160, 61, 162, 67, 118, + /* 780 */ 68, 112, 118, 168, 61, 60, 171, 4, 160, 174, + /* 790 */ 162, 29, 177, 178, 179, 61, 168, 29, 29, 171, + /* 800 */ 68, 29, 174, 61, 67, 177, 178, 179, 67, 29, + /* 810 */ 29, 68, 160, 2, 162, 67, 61, 60, 60, 60, + /* 820 */ 168, 61, 61, 171, 60, 160, 174, 162, 0, 177, + /* 830 */ 178, 179, 34, 168, 99, 60, 171, 92, 160, 174, + /* 840 */ 162, 89, 177, 178, 179, 60, 168, 65, 21, 171, + /* 850 */ 60, 67, 174, 67, 145, 177, 178, 179, 66, 29, + /* 860 */ 160, 61, 162, 29, 60, 29, 61, 60, 168, 160, + /* 870 */ 61, 171, 29, 160, 174, 162, 60, 177, 178, 179, + /* 880 */ 61, 168, 29, 60, 171, 61, 29, 174, 179, 60, + /* 890 */ 177, 178, 179, 160, 81, 162, 81, 188, 189, 190, + /* 900 */ 191, 168, 193, 81, 171, 21, 81, 174, 69, 60, + /* 910 */ 177, 178, 179, 160, 60, 162, 29, 29, 21, 41, + /* 920 */ 40, 168, 29, 29, 171, 29, 0, 174, 29, 29, + /* 930 */ 177, 178, 179, 160, 29, 162, 29, 21, 29, 29, + /* 940 */ 29, 168, 29, 29, 171, 27, 29, 174, 29, 29, + /* 950 */ 177, 178, 179, 29, 29, 34, 0, 29, 28, 0, + /* 960 */ 0, 21, 20, 218, 218, 218, 218, 218, 218, 218, + /* 970 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 980 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 990 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1000 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1010 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1020 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1030 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1040 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1050 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1060 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1070 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1080 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1090 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + /* 1100 */ 218, 218, 218, }; -#define YY_SHIFT_COUNT (278) +#define YY_SHIFT_COUNT (312) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (902) +#define YY_SHIFT_MAX (960) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 766, 227, 249, 336, 336, 336, 336, 350, 336, 336, - /* 10 */ 166, 434, 459, 430, 459, 459, 459, 459, 459, 459, - /* 20 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, - /* 30 */ 459, 459, 228, 228, 228, 465, 465, 61, 61, 37, - /* 40 */ 139, 139, 146, 238, 139, 139, 238, 139, 238, 238, - /* 50 */ 238, 139, 179, 0, 13, 13, 465, 390, 58, 58, - /* 60 */ 58, 5, 153, 238, 238, 247, 51, 714, 764, 393, - /* 70 */ 245, 186, 273, 223, 273, 418, 244, 101, 284, 452, - /* 80 */ 380, 382, 436, 436, 380, 382, 436, 443, 446, 477, - /* 90 */ 472, 482, 568, 582, 516, 563, 491, 506, 517, 238, - /* 100 */ 611, 146, 611, 146, 625, 625, 247, 179, 568, 610, - /* 110 */ 611, 179, 625, 905, 905, 905, 30, 52, 801, 806, - /* 120 */ 814, 814, 814, 814, 814, 814, 814, 142, 317, 545, - /* 130 */ 775, 296, 376, 72, 72, 72, 72, 217, 369, 412, - /* 140 */ 431, 229, 323, 301, 253, 444, 463, 461, 466, 471, - /* 150 */ 500, 515, 519, 540, 550, 162, 618, 627, 583, 639, - /* 160 */ 640, 642, 638, 646, 653, 654, 658, 655, 659, 694, - /* 170 */ 660, 665, 667, 668, 624, 672, 680, 675, 645, 687, - /* 180 */ 690, 753, 664, 702, 703, 699, 656, 765, 741, 742, - /* 190 */ 743, 744, 754, 756, 718, 729, 787, 789, 792, 793, - /* 200 */ 745, 732, 797, 799, 804, 810, 811, 812, 823, 786, - /* 210 */ 825, 832, 833, 835, 836, 816, 838, 818, 821, 784, - /* 220 */ 780, 779, 781, 826, 791, 783, 794, 815, 820, 796, - /* 230 */ 798, 822, 800, 802, 829, 805, 803, 830, 808, 809, - /* 240 */ 834, 813, 772, 776, 777, 788, 847, 807, 819, 824, - /* 250 */ 840, 842, 851, 837, 841, 848, 850, 853, 854, 855, - /* 260 */ 856, 857, 859, 858, 860, 861, 862, 863, 864, 867, - /* 270 */ 868, 869, 888, 870, 872, 901, 902, 882, 884, + /* 0 */ 393, 282, 305, 342, 342, 342, 342, 374, 342, 342, + /* 10 */ 115, 454, 484, 460, 454, 454, 454, 454, 454, 454, + /* 20 */ 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, + /* 30 */ 454, 454, 454, 7, 7, 7, 351, 351, 40, 40, + /* 40 */ 20, 58, 127, 127, 63, 165, 58, 40, 40, 58, + /* 50 */ 40, 58, 58, 58, 40, 184, 0, 13, 13, 351, + /* 60 */ 317, 168, 134, 134, 134, 198, 165, 58, 58, 197, + /* 70 */ 54, 648, 78, 46, 65, 227, 309, 256, 278, 256, + /* 80 */ 329, 236, 386, 412, 20, 412, 20, 446, 446, 469, + /* 90 */ 471, 473, 384, 401, 433, 384, 401, 433, 432, 438, + /* 100 */ 452, 456, 468, 469, 557, 482, 467, 475, 493, 563, + /* 110 */ 58, 401, 433, 433, 401, 433, 543, 469, 471, 197, + /* 120 */ 184, 469, 577, 412, 184, 446, 963, 963, 963, 30, + /* 130 */ 654, 496, 682, 167, 213, 315, 315, 315, 315, 315, + /* 140 */ 315, 315, 335, 449, 283, 137, 201, 201, 201, 201, + /* 150 */ 389, 193, 345, 346, 396, 323, 31, 382, 395, 330, + /* 160 */ 418, 461, 466, 479, 490, 492, 525, 528, 545, 548, + /* 170 */ 551, 580, 286, 689, 692, 703, 706, 644, 634, 707, + /* 180 */ 714, 718, 719, 720, 721, 722, 724, 684, 727, 728, + /* 190 */ 730, 731, 736, 717, 739, 726, 729, 740, 685, 716, + /* 200 */ 662, 688, 690, 641, 699, 693, 701, 704, 705, 710, + /* 210 */ 708, 715, 738, 702, 711, 725, 712, 661, 723, 734, + /* 220 */ 737, 669, 732, 741, 742, 743, 664, 783, 762, 768, + /* 230 */ 769, 772, 780, 781, 811, 735, 748, 755, 757, 758, + /* 240 */ 760, 761, 759, 764, 745, 775, 828, 798, 752, 785, + /* 250 */ 782, 784, 786, 827, 790, 792, 800, 830, 834, 804, + /* 260 */ 805, 836, 807, 809, 843, 816, 819, 853, 823, 824, + /* 270 */ 857, 829, 813, 815, 822, 825, 884, 839, 849, 854, + /* 280 */ 887, 888, 897, 878, 880, 893, 894, 896, 899, 900, + /* 290 */ 905, 907, 916, 909, 910, 911, 913, 914, 917, 919, + /* 300 */ 920, 924, 926, 925, 918, 921, 956, 928, 930, 959, + /* 310 */ 960, 940, 942, }; -#define YY_REDUCE_COUNT (115) -#define YY_REDUCE_MIN (-169) -#define YY_REDUCE_MAX (626) +#define YY_REDUCE_COUNT (128) +#define YY_REDUCE_MIN (-182) +#define YY_REDUCE_MAX (773) static const short yy_reduce_ofst[] = { - /* 0 */ 108, -19, 17, 59, -123, 33, 75, 184, 126, 234, - /* 10 */ 250, 307, 338, -3, 165, 110, 371, 394, 409, 424, - /* 20 */ 440, 455, 470, 483, 496, 511, 524, 539, 552, 565, - /* 30 */ 580, 596, 237, -120, 626, -152, -144, -136, -18, 27, - /* 40 */ -107, -98, 104, -133, 164, 200, -153, 232, 167, 14, - /* 50 */ 242, 305, 152, -169, -169, -169, -106, -21, 192, 212, - /* 60 */ 271, -13, 7, 20, 47, 107, -151, -118, 135, 154, - /* 70 */ 170, 220, 256, 256, 256, 295, 240, 280, 342, 327, - /* 80 */ 306, 312, 368, 388, 345, 363, 400, 375, 391, 384, - /* 90 */ 405, 256, 449, 450, 451, 453, 421, 432, 439, 295, - /* 100 */ 507, 512, 508, 513, 525, 528, 521, 531, 505, 520, - /* 110 */ 535, 537, 546, 538, 542, 548, + /* 0 */ 87, -18, 26, 73, -129, 102, 130, 179, 248, 280, + /* 10 */ 29, 316, 397, 364, 423, 443, 465, 485, 498, 531, + /* 20 */ 555, 575, 595, 615, 628, 652, 665, 678, 700, 713, + /* 30 */ 733, 753, 773, 709, 76, 439, -157, -150, -140, -139, + /* 40 */ -111, -127, -159, -116, -155, -107, -14, 4, 129, -94, + /* 50 */ 214, 171, 28, 232, 219, -1, -86, -86, -86, -164, + /* 60 */ -120, -35, -123, 1, 34, 147, 135, 162, 37, 118, + /* 70 */ -161, 148, -182, 92, 120, 195, 207, 230, 230, 230, + /* 80 */ 273, 229, 244, 299, 308, 307, 324, 339, 341, 332, + /* 90 */ 352, 343, 319, 354, 377, 340, 383, 394, 361, 365, + /* 100 */ 370, 388, 230, 413, 415, 411, 390, 398, 404, 448, + /* 110 */ 273, 457, 470, 472, 477, 481, 486, 494, 500, 497, + /* 120 */ 491, 495, 505, 522, 524, 530, 535, 537, 536, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 10 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 20 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 30 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 40 */ 676, 676, 699, 676, 676, 676, 676, 676, 676, 676, - /* 50 */ 676, 676, 697, 676, 835, 676, 676, 676, 846, 846, - /* 60 */ 846, 699, 697, 676, 676, 762, 676, 676, 910, 676, - /* 70 */ 870, 862, 838, 852, 839, 676, 895, 855, 676, 676, - /* 80 */ 877, 875, 676, 676, 877, 875, 676, 889, 885, 868, - /* 90 */ 866, 852, 676, 676, 676, 676, 913, 901, 897, 676, - /* 100 */ 676, 699, 676, 699, 676, 676, 676, 697, 676, 731, - /* 110 */ 676, 697, 676, 765, 765, 700, 676, 676, 676, 676, - /* 120 */ 888, 887, 812, 811, 810, 806, 807, 676, 676, 676, - /* 130 */ 676, 676, 676, 801, 802, 800, 799, 676, 676, 836, - /* 140 */ 676, 676, 676, 898, 902, 676, 788, 676, 676, 676, - /* 150 */ 676, 676, 676, 676, 676, 676, 859, 869, 676, 676, - /* 160 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 170 */ 676, 788, 676, 886, 676, 845, 841, 676, 676, 837, - /* 180 */ 676, 831, 676, 676, 676, 896, 676, 676, 676, 676, - /* 190 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 200 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 210 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 220 */ 676, 787, 676, 676, 676, 676, 676, 676, 676, 759, - /* 230 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 240 */ 676, 676, 744, 742, 741, 740, 676, 737, 676, 676, - /* 250 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 260 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - /* 270 */ 676, 676, 676, 676, 676, 676, 676, 676, 676, + /* 0 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 10 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 20 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 30 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 40 */ 753, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 50 */ 728, 728, 728, 728, 728, 751, 728, 898, 728, 728, + /* 60 */ 728, 753, 909, 909, 909, 751, 728, 728, 728, 816, + /* 70 */ 728, 728, 973, 728, 933, 728, 925, 901, 915, 902, + /* 80 */ 728, 958, 918, 728, 753, 728, 753, 728, 728, 728, + /* 90 */ 728, 728, 940, 938, 728, 940, 938, 728, 952, 948, + /* 100 */ 931, 929, 915, 728, 728, 728, 976, 964, 960, 728, + /* 110 */ 728, 938, 728, 728, 938, 728, 829, 728, 728, 728, + /* 120 */ 751, 728, 785, 728, 751, 728, 819, 819, 754, 728, + /* 130 */ 728, 728, 728, 728, 728, 870, 951, 950, 869, 875, + /* 140 */ 874, 873, 728, 728, 728, 728, 864, 865, 863, 862, + /* 150 */ 728, 728, 728, 728, 899, 728, 961, 965, 728, 728, + /* 160 */ 728, 850, 728, 728, 728, 728, 728, 728, 728, 728, + /* 170 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 180 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 190 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 200 */ 728, 922, 932, 728, 728, 728, 728, 728, 728, 728, + /* 210 */ 728, 728, 728, 728, 850, 728, 949, 728, 908, 904, + /* 220 */ 728, 728, 900, 728, 728, 959, 728, 728, 728, 728, + /* 230 */ 728, 728, 728, 728, 894, 728, 728, 728, 728, 728, + /* 240 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 250 */ 728, 849, 728, 728, 728, 728, 728, 728, 728, 813, + /* 260 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 270 */ 728, 728, 798, 796, 795, 794, 728, 791, 728, 728, + /* 280 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 290 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 300 */ 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + /* 310 */ 728, 728, 728, }; /********** End of lemon-generated parsing tables *****************************/ @@ -626,182 +646,191 @@ static const char *const yyTokenName[] = { /* 30 */ "DNODES", /* 31 */ "NK_ID", /* 32 */ "NK_IPTOKEN", - /* 33 */ "DATABASE", - /* 34 */ "DATABASES", - /* 35 */ "USE", - /* 36 */ "IF", - /* 37 */ "NOT", - /* 38 */ "EXISTS", - /* 39 */ "BLOCKS", - /* 40 */ "CACHE", - /* 41 */ "CACHELAST", - /* 42 */ "COMP", - /* 43 */ "DAYS", - /* 44 */ "FSYNC", - /* 45 */ "MAXROWS", - /* 46 */ "MINROWS", - /* 47 */ "KEEP", - /* 48 */ "PRECISION", - /* 49 */ "QUORUM", - /* 50 */ "REPLICA", - /* 51 */ "TTL", - /* 52 */ "WAL", - /* 53 */ "VGROUPS", - /* 54 */ "SINGLE_STABLE", - /* 55 */ "STREAM_MODE", - /* 56 */ "TABLE", - /* 57 */ "NK_LP", - /* 58 */ "NK_RP", - /* 59 */ "STABLE", - /* 60 */ "TABLES", - /* 61 */ "STABLES", - /* 62 */ "USING", - /* 63 */ "TAGS", - /* 64 */ "NK_DOT", - /* 65 */ "NK_COMMA", - /* 66 */ "COMMENT", - /* 67 */ "BOOL", - /* 68 */ "TINYINT", - /* 69 */ "SMALLINT", - /* 70 */ "INT", - /* 71 */ "INTEGER", - /* 72 */ "BIGINT", - /* 73 */ "FLOAT", - /* 74 */ "DOUBLE", - /* 75 */ "BINARY", - /* 76 */ "TIMESTAMP", - /* 77 */ "NCHAR", - /* 78 */ "UNSIGNED", - /* 79 */ "JSON", - /* 80 */ "VARCHAR", - /* 81 */ "MEDIUMBLOB", - /* 82 */ "BLOB", - /* 83 */ "VARBINARY", - /* 84 */ "DECIMAL", - /* 85 */ "SMA", - /* 86 */ "MNODES", - /* 87 */ "NK_FLOAT", - /* 88 */ "NK_BOOL", - /* 89 */ "NK_VARIABLE", - /* 90 */ "BETWEEN", - /* 91 */ "IS", - /* 92 */ "NULL", - /* 93 */ "NK_LT", - /* 94 */ "NK_GT", - /* 95 */ "NK_LE", - /* 96 */ "NK_GE", - /* 97 */ "NK_NE", - /* 98 */ "NK_EQ", - /* 99 */ "LIKE", - /* 100 */ "MATCH", - /* 101 */ "NMATCH", - /* 102 */ "IN", - /* 103 */ "FROM", - /* 104 */ "AS", - /* 105 */ "JOIN", - /* 106 */ "ON", - /* 107 */ "INNER", - /* 108 */ "SELECT", - /* 109 */ "DISTINCT", - /* 110 */ "WHERE", - /* 111 */ "PARTITION", - /* 112 */ "BY", - /* 113 */ "SESSION", - /* 114 */ "STATE_WINDOW", - /* 115 */ "INTERVAL", - /* 116 */ "SLIDING", - /* 117 */ "FILL", - /* 118 */ "VALUE", - /* 119 */ "NONE", - /* 120 */ "PREV", - /* 121 */ "LINEAR", - /* 122 */ "NEXT", - /* 123 */ "GROUP", - /* 124 */ "HAVING", - /* 125 */ "ORDER", - /* 126 */ "SLIMIT", - /* 127 */ "SOFFSET", - /* 128 */ "LIMIT", - /* 129 */ "OFFSET", - /* 130 */ "ASC", - /* 131 */ "DESC", - /* 132 */ "NULLS", - /* 133 */ "FIRST", - /* 134 */ "LAST", - /* 135 */ "cmd", - /* 136 */ "user_name", - /* 137 */ "dnode_endpoint", - /* 138 */ "dnode_host_name", - /* 139 */ "not_exists_opt", - /* 140 */ "db_name", - /* 141 */ "db_options", - /* 142 */ "exists_opt", - /* 143 */ "full_table_name", - /* 144 */ "column_def_list", - /* 145 */ "tags_def_opt", - /* 146 */ "table_options", - /* 147 */ "multi_create_clause", - /* 148 */ "tags_def", - /* 149 */ "multi_drop_clause", - /* 150 */ "create_subtable_clause", - /* 151 */ "specific_tags_opt", - /* 152 */ "literal_list", - /* 153 */ "drop_table_clause", - /* 154 */ "col_name_list", - /* 155 */ "table_name", - /* 156 */ "column_def", - /* 157 */ "column_name", - /* 158 */ "type_name", - /* 159 */ "col_name", - /* 160 */ "query_expression", - /* 161 */ "literal", - /* 162 */ "duration_literal", - /* 163 */ "function_name", - /* 164 */ "table_alias", - /* 165 */ "column_alias", - /* 166 */ "expression", - /* 167 */ "column_reference", - /* 168 */ "expression_list", - /* 169 */ "subquery", - /* 170 */ "predicate", - /* 171 */ "compare_op", - /* 172 */ "in_op", - /* 173 */ "in_predicate_value", - /* 174 */ "boolean_value_expression", - /* 175 */ "boolean_primary", - /* 176 */ "common_expression", - /* 177 */ "from_clause", - /* 178 */ "table_reference_list", - /* 179 */ "table_reference", - /* 180 */ "table_primary", - /* 181 */ "joined_table", - /* 182 */ "alias_opt", - /* 183 */ "parenthesized_joined_table", - /* 184 */ "join_type", - /* 185 */ "search_condition", - /* 186 */ "query_specification", - /* 187 */ "set_quantifier_opt", - /* 188 */ "select_list", - /* 189 */ "where_clause_opt", - /* 190 */ "partition_by_clause_opt", - /* 191 */ "twindow_clause_opt", - /* 192 */ "group_by_clause_opt", - /* 193 */ "having_clause_opt", - /* 194 */ "select_sublist", - /* 195 */ "select_item", - /* 196 */ "sliding_opt", - /* 197 */ "fill_opt", - /* 198 */ "fill_mode", - /* 199 */ "group_by_list", - /* 200 */ "query_expression_body", - /* 201 */ "order_by_clause_opt", - /* 202 */ "slimit_clause_opt", - /* 203 */ "limit_clause_opt", - /* 204 */ "query_primary", - /* 205 */ "sort_specification_list", - /* 206 */ "sort_specification", - /* 207 */ "ordering_specification_opt", - /* 208 */ "null_ordering_opt", + /* 33 */ "QNODE", + /* 34 */ "ON", + /* 35 */ "QNODES", + /* 36 */ "DATABASE", + /* 37 */ "DATABASES", + /* 38 */ "USE", + /* 39 */ "IF", + /* 40 */ "NOT", + /* 41 */ "EXISTS", + /* 42 */ "BLOCKS", + /* 43 */ "CACHE", + /* 44 */ "CACHELAST", + /* 45 */ "COMP", + /* 46 */ "DAYS", + /* 47 */ "FSYNC", + /* 48 */ "MAXROWS", + /* 49 */ "MINROWS", + /* 50 */ "KEEP", + /* 51 */ "PRECISION", + /* 52 */ "QUORUM", + /* 53 */ "REPLICA", + /* 54 */ "TTL", + /* 55 */ "WAL", + /* 56 */ "VGROUPS", + /* 57 */ "SINGLE_STABLE", + /* 58 */ "STREAM_MODE", + /* 59 */ "TABLE", + /* 60 */ "NK_LP", + /* 61 */ "NK_RP", + /* 62 */ "STABLE", + /* 63 */ "TABLES", + /* 64 */ "STABLES", + /* 65 */ "USING", + /* 66 */ "TAGS", + /* 67 */ "NK_DOT", + /* 68 */ "NK_COMMA", + /* 69 */ "COMMENT", + /* 70 */ "BOOL", + /* 71 */ "TINYINT", + /* 72 */ "SMALLINT", + /* 73 */ "INT", + /* 74 */ "INTEGER", + /* 75 */ "BIGINT", + /* 76 */ "FLOAT", + /* 77 */ "DOUBLE", + /* 78 */ "BINARY", + /* 79 */ "TIMESTAMP", + /* 80 */ "NCHAR", + /* 81 */ "UNSIGNED", + /* 82 */ "JSON", + /* 83 */ "VARCHAR", + /* 84 */ "MEDIUMBLOB", + /* 85 */ "BLOB", + /* 86 */ "VARBINARY", + /* 87 */ "DECIMAL", + /* 88 */ "SMA", + /* 89 */ "INDEX", + /* 90 */ "FULLTEXT", + /* 91 */ "FUNCTION", + /* 92 */ "INTERVAL", + /* 93 */ "MNODES", + /* 94 */ "NK_FLOAT", + /* 95 */ "NK_BOOL", + /* 96 */ "NK_VARIABLE", + /* 97 */ "BETWEEN", + /* 98 */ "IS", + /* 99 */ "NULL", + /* 100 */ "NK_LT", + /* 101 */ "NK_GT", + /* 102 */ "NK_LE", + /* 103 */ "NK_GE", + /* 104 */ "NK_NE", + /* 105 */ "NK_EQ", + /* 106 */ "LIKE", + /* 107 */ "MATCH", + /* 108 */ "NMATCH", + /* 109 */ "IN", + /* 110 */ "FROM", + /* 111 */ "AS", + /* 112 */ "JOIN", + /* 113 */ "INNER", + /* 114 */ "SELECT", + /* 115 */ "DISTINCT", + /* 116 */ "WHERE", + /* 117 */ "PARTITION", + /* 118 */ "BY", + /* 119 */ "SESSION", + /* 120 */ "STATE_WINDOW", + /* 121 */ "SLIDING", + /* 122 */ "FILL", + /* 123 */ "VALUE", + /* 124 */ "NONE", + /* 125 */ "PREV", + /* 126 */ "LINEAR", + /* 127 */ "NEXT", + /* 128 */ "GROUP", + /* 129 */ "HAVING", + /* 130 */ "ORDER", + /* 131 */ "SLIMIT", + /* 132 */ "SOFFSET", + /* 133 */ "LIMIT", + /* 134 */ "OFFSET", + /* 135 */ "ASC", + /* 136 */ "DESC", + /* 137 */ "NULLS", + /* 138 */ "FIRST", + /* 139 */ "LAST", + /* 140 */ "cmd", + /* 141 */ "user_name", + /* 142 */ "dnode_endpoint", + /* 143 */ "dnode_host_name", + /* 144 */ "not_exists_opt", + /* 145 */ "db_name", + /* 146 */ "db_options", + /* 147 */ "exists_opt", + /* 148 */ "full_table_name", + /* 149 */ "column_def_list", + /* 150 */ "tags_def_opt", + /* 151 */ "table_options", + /* 152 */ "multi_create_clause", + /* 153 */ "tags_def", + /* 154 */ "multi_drop_clause", + /* 155 */ "create_subtable_clause", + /* 156 */ "specific_tags_opt", + /* 157 */ "literal_list", + /* 158 */ "drop_table_clause", + /* 159 */ "col_name_list", + /* 160 */ "table_name", + /* 161 */ "column_def", + /* 162 */ "column_name", + /* 163 */ "type_name", + /* 164 */ "col_name", + /* 165 */ "index_name", + /* 166 */ "index_options", + /* 167 */ "func_list", + /* 168 */ "duration_literal", + /* 169 */ "sliding_opt", + /* 170 */ "func", + /* 171 */ "function_name", + /* 172 */ "expression_list", + /* 173 */ "query_expression", + /* 174 */ "literal", + /* 175 */ "table_alias", + /* 176 */ "column_alias", + /* 177 */ "expression", + /* 178 */ "column_reference", + /* 179 */ "subquery", + /* 180 */ "predicate", + /* 181 */ "compare_op", + /* 182 */ "in_op", + /* 183 */ "in_predicate_value", + /* 184 */ "boolean_value_expression", + /* 185 */ "boolean_primary", + /* 186 */ "common_expression", + /* 187 */ "from_clause", + /* 188 */ "table_reference_list", + /* 189 */ "table_reference", + /* 190 */ "table_primary", + /* 191 */ "joined_table", + /* 192 */ "alias_opt", + /* 193 */ "parenthesized_joined_table", + /* 194 */ "join_type", + /* 195 */ "search_condition", + /* 196 */ "query_specification", + /* 197 */ "set_quantifier_opt", + /* 198 */ "select_list", + /* 199 */ "where_clause_opt", + /* 200 */ "partition_by_clause_opt", + /* 201 */ "twindow_clause_opt", + /* 202 */ "group_by_clause_opt", + /* 203 */ "having_clause_opt", + /* 204 */ "select_sublist", + /* 205 */ "select_item", + /* 206 */ "fill_opt", + /* 207 */ "fill_mode", + /* 208 */ "group_by_list", + /* 209 */ "query_expression_body", + /* 210 */ "order_by_clause_opt", + /* 211 */ "slimit_clause_opt", + /* 212 */ "limit_clause_opt", + /* 213 */ "query_primary", + /* 214 */ "sort_specification_list", + /* 215 */ "sort_specification", + /* 216 */ "ordering_specification_opt", + /* 217 */ "null_ordering_opt", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -822,230 +851,241 @@ static const char *const yyRuleName[] = { /* 10 */ "dnode_endpoint ::= NK_STRING", /* 11 */ "dnode_host_name ::= NK_ID", /* 12 */ "dnode_host_name ::= NK_IPTOKEN", - /* 13 */ "cmd ::= CREATE DATABASE not_exists_opt db_name db_options", - /* 14 */ "cmd ::= DROP DATABASE exists_opt db_name", - /* 15 */ "cmd ::= SHOW DATABASES", - /* 16 */ "cmd ::= USE db_name", - /* 17 */ "not_exists_opt ::= IF NOT EXISTS", - /* 18 */ "not_exists_opt ::=", - /* 19 */ "exists_opt ::= IF EXISTS", - /* 20 */ "exists_opt ::=", - /* 21 */ "db_options ::=", - /* 22 */ "db_options ::= db_options BLOCKS NK_INTEGER", - /* 23 */ "db_options ::= db_options CACHE NK_INTEGER", - /* 24 */ "db_options ::= db_options CACHELAST NK_INTEGER", - /* 25 */ "db_options ::= db_options COMP NK_INTEGER", - /* 26 */ "db_options ::= db_options DAYS NK_INTEGER", - /* 27 */ "db_options ::= db_options FSYNC NK_INTEGER", - /* 28 */ "db_options ::= db_options MAXROWS NK_INTEGER", - /* 29 */ "db_options ::= db_options MINROWS NK_INTEGER", - /* 30 */ "db_options ::= db_options KEEP NK_INTEGER", - /* 31 */ "db_options ::= db_options PRECISION NK_STRING", - /* 32 */ "db_options ::= db_options QUORUM NK_INTEGER", - /* 33 */ "db_options ::= db_options REPLICA NK_INTEGER", - /* 34 */ "db_options ::= db_options TTL NK_INTEGER", - /* 35 */ "db_options ::= db_options WAL NK_INTEGER", - /* 36 */ "db_options ::= db_options VGROUPS NK_INTEGER", - /* 37 */ "db_options ::= db_options SINGLE_STABLE NK_INTEGER", - /* 38 */ "db_options ::= db_options STREAM_MODE NK_INTEGER", - /* 39 */ "cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options", - /* 40 */ "cmd ::= CREATE TABLE multi_create_clause", - /* 41 */ "cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options", - /* 42 */ "cmd ::= DROP TABLE multi_drop_clause", - /* 43 */ "cmd ::= DROP STABLE exists_opt full_table_name", - /* 44 */ "cmd ::= SHOW TABLES", - /* 45 */ "cmd ::= SHOW STABLES", - /* 46 */ "multi_create_clause ::= create_subtable_clause", - /* 47 */ "multi_create_clause ::= multi_create_clause create_subtable_clause", - /* 48 */ "create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP", - /* 49 */ "multi_drop_clause ::= drop_table_clause", - /* 50 */ "multi_drop_clause ::= multi_drop_clause drop_table_clause", - /* 51 */ "drop_table_clause ::= exists_opt full_table_name", - /* 52 */ "specific_tags_opt ::=", - /* 53 */ "specific_tags_opt ::= NK_LP col_name_list NK_RP", - /* 54 */ "full_table_name ::= table_name", - /* 55 */ "full_table_name ::= db_name NK_DOT table_name", - /* 56 */ "column_def_list ::= column_def", - /* 57 */ "column_def_list ::= column_def_list NK_COMMA column_def", - /* 58 */ "column_def ::= column_name type_name", - /* 59 */ "column_def ::= column_name type_name COMMENT NK_STRING", - /* 60 */ "type_name ::= BOOL", - /* 61 */ "type_name ::= TINYINT", - /* 62 */ "type_name ::= SMALLINT", - /* 63 */ "type_name ::= INT", - /* 64 */ "type_name ::= INTEGER", - /* 65 */ "type_name ::= BIGINT", - /* 66 */ "type_name ::= FLOAT", - /* 67 */ "type_name ::= DOUBLE", - /* 68 */ "type_name ::= BINARY NK_LP NK_INTEGER NK_RP", - /* 69 */ "type_name ::= TIMESTAMP", - /* 70 */ "type_name ::= NCHAR NK_LP NK_INTEGER NK_RP", - /* 71 */ "type_name ::= TINYINT UNSIGNED", - /* 72 */ "type_name ::= SMALLINT UNSIGNED", - /* 73 */ "type_name ::= INT UNSIGNED", - /* 74 */ "type_name ::= BIGINT UNSIGNED", - /* 75 */ "type_name ::= JSON", - /* 76 */ "type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP", - /* 77 */ "type_name ::= MEDIUMBLOB", - /* 78 */ "type_name ::= BLOB", - /* 79 */ "type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP", - /* 80 */ "type_name ::= DECIMAL", - /* 81 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP", - /* 82 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP", - /* 83 */ "tags_def_opt ::=", - /* 84 */ "tags_def_opt ::= tags_def", - /* 85 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP", - /* 86 */ "table_options ::=", - /* 87 */ "table_options ::= table_options COMMENT NK_STRING", - /* 88 */ "table_options ::= table_options KEEP NK_INTEGER", - /* 89 */ "table_options ::= table_options TTL NK_INTEGER", - /* 90 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP", - /* 91 */ "col_name_list ::= col_name", - /* 92 */ "col_name_list ::= col_name_list NK_COMMA col_name", - /* 93 */ "col_name ::= column_name", - /* 94 */ "cmd ::= SHOW VGROUPS", - /* 95 */ "cmd ::= SHOW db_name NK_DOT VGROUPS", - /* 96 */ "cmd ::= SHOW MNODES", - /* 97 */ "cmd ::= query_expression", - /* 98 */ "literal ::= NK_INTEGER", - /* 99 */ "literal ::= NK_FLOAT", - /* 100 */ "literal ::= NK_STRING", - /* 101 */ "literal ::= NK_BOOL", - /* 102 */ "literal ::= TIMESTAMP NK_STRING", - /* 103 */ "literal ::= duration_literal", - /* 104 */ "duration_literal ::= NK_VARIABLE", - /* 105 */ "literal_list ::= literal", - /* 106 */ "literal_list ::= literal_list NK_COMMA literal", - /* 107 */ "db_name ::= NK_ID", - /* 108 */ "table_name ::= NK_ID", - /* 109 */ "column_name ::= NK_ID", - /* 110 */ "function_name ::= NK_ID", - /* 111 */ "table_alias ::= NK_ID", - /* 112 */ "column_alias ::= NK_ID", - /* 113 */ "user_name ::= NK_ID", - /* 114 */ "expression ::= literal", - /* 115 */ "expression ::= column_reference", - /* 116 */ "expression ::= function_name NK_LP expression_list NK_RP", - /* 117 */ "expression ::= function_name NK_LP NK_STAR NK_RP", - /* 118 */ "expression ::= subquery", - /* 119 */ "expression ::= NK_LP expression NK_RP", - /* 120 */ "expression ::= NK_PLUS expression", - /* 121 */ "expression ::= NK_MINUS expression", - /* 122 */ "expression ::= expression NK_PLUS expression", - /* 123 */ "expression ::= expression NK_MINUS expression", - /* 124 */ "expression ::= expression NK_STAR expression", - /* 125 */ "expression ::= expression NK_SLASH expression", - /* 126 */ "expression ::= expression NK_REM expression", - /* 127 */ "expression_list ::= expression", - /* 128 */ "expression_list ::= expression_list NK_COMMA expression", - /* 129 */ "column_reference ::= column_name", - /* 130 */ "column_reference ::= table_name NK_DOT column_name", - /* 131 */ "predicate ::= expression compare_op expression", - /* 132 */ "predicate ::= expression BETWEEN expression AND expression", - /* 133 */ "predicate ::= expression NOT BETWEEN expression AND expression", - /* 134 */ "predicate ::= expression IS NULL", - /* 135 */ "predicate ::= expression IS NOT NULL", - /* 136 */ "predicate ::= expression in_op in_predicate_value", - /* 137 */ "compare_op ::= NK_LT", - /* 138 */ "compare_op ::= NK_GT", - /* 139 */ "compare_op ::= NK_LE", - /* 140 */ "compare_op ::= NK_GE", - /* 141 */ "compare_op ::= NK_NE", - /* 142 */ "compare_op ::= NK_EQ", - /* 143 */ "compare_op ::= LIKE", - /* 144 */ "compare_op ::= NOT LIKE", - /* 145 */ "compare_op ::= MATCH", - /* 146 */ "compare_op ::= NMATCH", - /* 147 */ "in_op ::= IN", - /* 148 */ "in_op ::= NOT IN", - /* 149 */ "in_predicate_value ::= NK_LP expression_list NK_RP", - /* 150 */ "boolean_value_expression ::= boolean_primary", - /* 151 */ "boolean_value_expression ::= NOT boolean_primary", - /* 152 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", - /* 153 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", - /* 154 */ "boolean_primary ::= predicate", - /* 155 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", - /* 156 */ "common_expression ::= expression", - /* 157 */ "common_expression ::= boolean_value_expression", - /* 158 */ "from_clause ::= FROM table_reference_list", - /* 159 */ "table_reference_list ::= table_reference", - /* 160 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", - /* 161 */ "table_reference ::= table_primary", - /* 162 */ "table_reference ::= joined_table", - /* 163 */ "table_primary ::= table_name alias_opt", - /* 164 */ "table_primary ::= db_name NK_DOT table_name alias_opt", - /* 165 */ "table_primary ::= subquery alias_opt", - /* 166 */ "table_primary ::= parenthesized_joined_table", - /* 167 */ "alias_opt ::=", - /* 168 */ "alias_opt ::= table_alias", - /* 169 */ "alias_opt ::= AS table_alias", - /* 170 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", - /* 171 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", - /* 172 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", - /* 173 */ "join_type ::=", - /* 174 */ "join_type ::= INNER", - /* 175 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt", - /* 176 */ "set_quantifier_opt ::=", - /* 177 */ "set_quantifier_opt ::= DISTINCT", - /* 178 */ "set_quantifier_opt ::= ALL", - /* 179 */ "select_list ::= NK_STAR", - /* 180 */ "select_list ::= select_sublist", - /* 181 */ "select_sublist ::= select_item", - /* 182 */ "select_sublist ::= select_sublist NK_COMMA select_item", - /* 183 */ "select_item ::= common_expression", - /* 184 */ "select_item ::= common_expression column_alias", - /* 185 */ "select_item ::= common_expression AS column_alias", - /* 186 */ "select_item ::= table_name NK_DOT NK_STAR", - /* 187 */ "where_clause_opt ::=", - /* 188 */ "where_clause_opt ::= WHERE search_condition", - /* 189 */ "partition_by_clause_opt ::=", - /* 190 */ "partition_by_clause_opt ::= PARTITION BY expression_list", - /* 191 */ "twindow_clause_opt ::=", - /* 192 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA NK_INTEGER NK_RP", - /* 193 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP column_reference NK_RP", - /* 194 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", - /* 195 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", - /* 196 */ "sliding_opt ::=", - /* 197 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", - /* 198 */ "fill_opt ::=", - /* 199 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", - /* 200 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP", - /* 201 */ "fill_mode ::= NONE", - /* 202 */ "fill_mode ::= PREV", - /* 203 */ "fill_mode ::= NULL", - /* 204 */ "fill_mode ::= LINEAR", - /* 205 */ "fill_mode ::= NEXT", - /* 206 */ "group_by_clause_opt ::=", - /* 207 */ "group_by_clause_opt ::= GROUP BY group_by_list", - /* 208 */ "group_by_list ::= expression", - /* 209 */ "group_by_list ::= group_by_list NK_COMMA expression", - /* 210 */ "having_clause_opt ::=", - /* 211 */ "having_clause_opt ::= HAVING search_condition", - /* 212 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt", - /* 213 */ "query_expression_body ::= query_primary", - /* 214 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body", - /* 215 */ "query_primary ::= query_specification", - /* 216 */ "order_by_clause_opt ::=", - /* 217 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", - /* 218 */ "slimit_clause_opt ::=", - /* 219 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", - /* 220 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", - /* 221 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 222 */ "limit_clause_opt ::=", - /* 223 */ "limit_clause_opt ::= LIMIT NK_INTEGER", - /* 224 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", - /* 225 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 226 */ "subquery ::= NK_LP query_expression NK_RP", - /* 227 */ "search_condition ::= common_expression", - /* 228 */ "sort_specification_list ::= sort_specification", - /* 229 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", - /* 230 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt", - /* 231 */ "ordering_specification_opt ::=", - /* 232 */ "ordering_specification_opt ::= ASC", - /* 233 */ "ordering_specification_opt ::= DESC", - /* 234 */ "null_ordering_opt ::=", - /* 235 */ "null_ordering_opt ::= NULLS FIRST", - /* 236 */ "null_ordering_opt ::= NULLS LAST", + /* 13 */ "cmd ::= CREATE QNODE ON DNODE NK_INTEGER", + /* 14 */ "cmd ::= SHOW QNODES", + /* 15 */ "cmd ::= CREATE DATABASE not_exists_opt db_name db_options", + /* 16 */ "cmd ::= DROP DATABASE exists_opt db_name", + /* 17 */ "cmd ::= SHOW DATABASES", + /* 18 */ "cmd ::= USE db_name", + /* 19 */ "not_exists_opt ::= IF NOT EXISTS", + /* 20 */ "not_exists_opt ::=", + /* 21 */ "exists_opt ::= IF EXISTS", + /* 22 */ "exists_opt ::=", + /* 23 */ "db_options ::=", + /* 24 */ "db_options ::= db_options BLOCKS NK_INTEGER", + /* 25 */ "db_options ::= db_options CACHE NK_INTEGER", + /* 26 */ "db_options ::= db_options CACHELAST NK_INTEGER", + /* 27 */ "db_options ::= db_options COMP NK_INTEGER", + /* 28 */ "db_options ::= db_options DAYS NK_INTEGER", + /* 29 */ "db_options ::= db_options FSYNC NK_INTEGER", + /* 30 */ "db_options ::= db_options MAXROWS NK_INTEGER", + /* 31 */ "db_options ::= db_options MINROWS NK_INTEGER", + /* 32 */ "db_options ::= db_options KEEP NK_INTEGER", + /* 33 */ "db_options ::= db_options PRECISION NK_STRING", + /* 34 */ "db_options ::= db_options QUORUM NK_INTEGER", + /* 35 */ "db_options ::= db_options REPLICA NK_INTEGER", + /* 36 */ "db_options ::= db_options TTL NK_INTEGER", + /* 37 */ "db_options ::= db_options WAL NK_INTEGER", + /* 38 */ "db_options ::= db_options VGROUPS NK_INTEGER", + /* 39 */ "db_options ::= db_options SINGLE_STABLE NK_INTEGER", + /* 40 */ "db_options ::= db_options STREAM_MODE NK_INTEGER", + /* 41 */ "cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options", + /* 42 */ "cmd ::= CREATE TABLE multi_create_clause", + /* 43 */ "cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options", + /* 44 */ "cmd ::= DROP TABLE multi_drop_clause", + /* 45 */ "cmd ::= DROP STABLE exists_opt full_table_name", + /* 46 */ "cmd ::= SHOW TABLES", + /* 47 */ "cmd ::= SHOW STABLES", + /* 48 */ "multi_create_clause ::= create_subtable_clause", + /* 49 */ "multi_create_clause ::= multi_create_clause create_subtable_clause", + /* 50 */ "create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP", + /* 51 */ "multi_drop_clause ::= drop_table_clause", + /* 52 */ "multi_drop_clause ::= multi_drop_clause drop_table_clause", + /* 53 */ "drop_table_clause ::= exists_opt full_table_name", + /* 54 */ "specific_tags_opt ::=", + /* 55 */ "specific_tags_opt ::= NK_LP col_name_list NK_RP", + /* 56 */ "full_table_name ::= table_name", + /* 57 */ "full_table_name ::= db_name NK_DOT table_name", + /* 58 */ "column_def_list ::= column_def", + /* 59 */ "column_def_list ::= column_def_list NK_COMMA column_def", + /* 60 */ "column_def ::= column_name type_name", + /* 61 */ "column_def ::= column_name type_name COMMENT NK_STRING", + /* 62 */ "type_name ::= BOOL", + /* 63 */ "type_name ::= TINYINT", + /* 64 */ "type_name ::= SMALLINT", + /* 65 */ "type_name ::= INT", + /* 66 */ "type_name ::= INTEGER", + /* 67 */ "type_name ::= BIGINT", + /* 68 */ "type_name ::= FLOAT", + /* 69 */ "type_name ::= DOUBLE", + /* 70 */ "type_name ::= BINARY NK_LP NK_INTEGER NK_RP", + /* 71 */ "type_name ::= TIMESTAMP", + /* 72 */ "type_name ::= NCHAR NK_LP NK_INTEGER NK_RP", + /* 73 */ "type_name ::= TINYINT UNSIGNED", + /* 74 */ "type_name ::= SMALLINT UNSIGNED", + /* 75 */ "type_name ::= INT UNSIGNED", + /* 76 */ "type_name ::= BIGINT UNSIGNED", + /* 77 */ "type_name ::= JSON", + /* 78 */ "type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP", + /* 79 */ "type_name ::= MEDIUMBLOB", + /* 80 */ "type_name ::= BLOB", + /* 81 */ "type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP", + /* 82 */ "type_name ::= DECIMAL", + /* 83 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP", + /* 84 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP", + /* 85 */ "tags_def_opt ::=", + /* 86 */ "tags_def_opt ::= tags_def", + /* 87 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP", + /* 88 */ "table_options ::=", + /* 89 */ "table_options ::= table_options COMMENT NK_STRING", + /* 90 */ "table_options ::= table_options KEEP NK_INTEGER", + /* 91 */ "table_options ::= table_options TTL NK_INTEGER", + /* 92 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP", + /* 93 */ "col_name_list ::= col_name", + /* 94 */ "col_name_list ::= col_name_list NK_COMMA col_name", + /* 95 */ "col_name ::= column_name", + /* 96 */ "cmd ::= CREATE SMA INDEX index_name ON table_name index_options", + /* 97 */ "cmd ::= CREATE FULLTEXT INDEX index_name ON table_name NK_LP col_name_list NK_RP", + /* 98 */ "index_options ::=", + /* 99 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt", + /* 100 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt", + /* 101 */ "func_list ::= func", + /* 102 */ "func_list ::= func_list NK_COMMA func", + /* 103 */ "func ::= function_name NK_LP expression_list NK_RP", + /* 104 */ "cmd ::= SHOW VGROUPS", + /* 105 */ "cmd ::= SHOW db_name NK_DOT VGROUPS", + /* 106 */ "cmd ::= SHOW MNODES", + /* 107 */ "cmd ::= query_expression", + /* 108 */ "literal ::= NK_INTEGER", + /* 109 */ "literal ::= NK_FLOAT", + /* 110 */ "literal ::= NK_STRING", + /* 111 */ "literal ::= NK_BOOL", + /* 112 */ "literal ::= TIMESTAMP NK_STRING", + /* 113 */ "literal ::= duration_literal", + /* 114 */ "duration_literal ::= NK_VARIABLE", + /* 115 */ "literal_list ::= literal", + /* 116 */ "literal_list ::= literal_list NK_COMMA literal", + /* 117 */ "db_name ::= NK_ID", + /* 118 */ "table_name ::= NK_ID", + /* 119 */ "column_name ::= NK_ID", + /* 120 */ "function_name ::= NK_ID", + /* 121 */ "table_alias ::= NK_ID", + /* 122 */ "column_alias ::= NK_ID", + /* 123 */ "user_name ::= NK_ID", + /* 124 */ "index_name ::= NK_ID", + /* 125 */ "expression ::= literal", + /* 126 */ "expression ::= column_reference", + /* 127 */ "expression ::= function_name NK_LP expression_list NK_RP", + /* 128 */ "expression ::= function_name NK_LP NK_STAR NK_RP", + /* 129 */ "expression ::= subquery", + /* 130 */ "expression ::= NK_LP expression NK_RP", + /* 131 */ "expression ::= NK_PLUS expression", + /* 132 */ "expression ::= NK_MINUS expression", + /* 133 */ "expression ::= expression NK_PLUS expression", + /* 134 */ "expression ::= expression NK_MINUS expression", + /* 135 */ "expression ::= expression NK_STAR expression", + /* 136 */ "expression ::= expression NK_SLASH expression", + /* 137 */ "expression ::= expression NK_REM expression", + /* 138 */ "expression_list ::= expression", + /* 139 */ "expression_list ::= expression_list NK_COMMA expression", + /* 140 */ "column_reference ::= column_name", + /* 141 */ "column_reference ::= table_name NK_DOT column_name", + /* 142 */ "predicate ::= expression compare_op expression", + /* 143 */ "predicate ::= expression BETWEEN expression AND expression", + /* 144 */ "predicate ::= expression NOT BETWEEN expression AND expression", + /* 145 */ "predicate ::= expression IS NULL", + /* 146 */ "predicate ::= expression IS NOT NULL", + /* 147 */ "predicate ::= expression in_op in_predicate_value", + /* 148 */ "compare_op ::= NK_LT", + /* 149 */ "compare_op ::= NK_GT", + /* 150 */ "compare_op ::= NK_LE", + /* 151 */ "compare_op ::= NK_GE", + /* 152 */ "compare_op ::= NK_NE", + /* 153 */ "compare_op ::= NK_EQ", + /* 154 */ "compare_op ::= LIKE", + /* 155 */ "compare_op ::= NOT LIKE", + /* 156 */ "compare_op ::= MATCH", + /* 157 */ "compare_op ::= NMATCH", + /* 158 */ "in_op ::= IN", + /* 159 */ "in_op ::= NOT IN", + /* 160 */ "in_predicate_value ::= NK_LP expression_list NK_RP", + /* 161 */ "boolean_value_expression ::= boolean_primary", + /* 162 */ "boolean_value_expression ::= NOT boolean_primary", + /* 163 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", + /* 164 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", + /* 165 */ "boolean_primary ::= predicate", + /* 166 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", + /* 167 */ "common_expression ::= expression", + /* 168 */ "common_expression ::= boolean_value_expression", + /* 169 */ "from_clause ::= FROM table_reference_list", + /* 170 */ "table_reference_list ::= table_reference", + /* 171 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", + /* 172 */ "table_reference ::= table_primary", + /* 173 */ "table_reference ::= joined_table", + /* 174 */ "table_primary ::= table_name alias_opt", + /* 175 */ "table_primary ::= db_name NK_DOT table_name alias_opt", + /* 176 */ "table_primary ::= subquery alias_opt", + /* 177 */ "table_primary ::= parenthesized_joined_table", + /* 178 */ "alias_opt ::=", + /* 179 */ "alias_opt ::= table_alias", + /* 180 */ "alias_opt ::= AS table_alias", + /* 181 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", + /* 182 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", + /* 183 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", + /* 184 */ "join_type ::=", + /* 185 */ "join_type ::= INNER", + /* 186 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt", + /* 187 */ "set_quantifier_opt ::=", + /* 188 */ "set_quantifier_opt ::= DISTINCT", + /* 189 */ "set_quantifier_opt ::= ALL", + /* 190 */ "select_list ::= NK_STAR", + /* 191 */ "select_list ::= select_sublist", + /* 192 */ "select_sublist ::= select_item", + /* 193 */ "select_sublist ::= select_sublist NK_COMMA select_item", + /* 194 */ "select_item ::= common_expression", + /* 195 */ "select_item ::= common_expression column_alias", + /* 196 */ "select_item ::= common_expression AS column_alias", + /* 197 */ "select_item ::= table_name NK_DOT NK_STAR", + /* 198 */ "where_clause_opt ::=", + /* 199 */ "where_clause_opt ::= WHERE search_condition", + /* 200 */ "partition_by_clause_opt ::=", + /* 201 */ "partition_by_clause_opt ::= PARTITION BY expression_list", + /* 202 */ "twindow_clause_opt ::=", + /* 203 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA NK_INTEGER NK_RP", + /* 204 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP column_reference NK_RP", + /* 205 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", + /* 206 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", + /* 207 */ "sliding_opt ::=", + /* 208 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", + /* 209 */ "fill_opt ::=", + /* 210 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", + /* 211 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP", + /* 212 */ "fill_mode ::= NONE", + /* 213 */ "fill_mode ::= PREV", + /* 214 */ "fill_mode ::= NULL", + /* 215 */ "fill_mode ::= LINEAR", + /* 216 */ "fill_mode ::= NEXT", + /* 217 */ "group_by_clause_opt ::=", + /* 218 */ "group_by_clause_opt ::= GROUP BY group_by_list", + /* 219 */ "group_by_list ::= expression", + /* 220 */ "group_by_list ::= group_by_list NK_COMMA expression", + /* 221 */ "having_clause_opt ::=", + /* 222 */ "having_clause_opt ::= HAVING search_condition", + /* 223 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt", + /* 224 */ "query_expression_body ::= query_primary", + /* 225 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body", + /* 226 */ "query_primary ::= query_specification", + /* 227 */ "order_by_clause_opt ::=", + /* 228 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", + /* 229 */ "slimit_clause_opt ::=", + /* 230 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", + /* 231 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", + /* 232 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 233 */ "limit_clause_opt ::=", + /* 234 */ "limit_clause_opt ::= LIMIT NK_INTEGER", + /* 235 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", + /* 236 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 237 */ "subquery ::= NK_LP query_expression NK_RP", + /* 238 */ "search_condition ::= common_expression", + /* 239 */ "sort_specification_list ::= sort_specification", + /* 240 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", + /* 241 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt", + /* 242 */ "ordering_specification_opt ::=", + /* 243 */ "ordering_specification_opt ::= ASC", + /* 244 */ "ordering_specification_opt ::= DESC", + /* 245 */ "null_ordering_opt ::=", + /* 246 */ "null_ordering_opt ::= NULLS FIRST", + /* 247 */ "null_ordering_opt ::= NULLS LAST", }; #endif /* NDEBUG */ @@ -1172,124 +1212,120 @@ static void yy_destructor( */ /********* Begin destructor definitions ***************************************/ /* Default NON-TERMINAL Destructor */ - case 135: /* cmd */ - case 143: /* full_table_name */ - case 150: /* create_subtable_clause */ - case 153: /* drop_table_clause */ - case 156: /* column_def */ - case 159: /* col_name */ - case 160: /* query_expression */ - case 161: /* literal */ - case 162: /* duration_literal */ - case 166: /* expression */ - case 167: /* column_reference */ - case 169: /* subquery */ - case 170: /* predicate */ - case 173: /* in_predicate_value */ - case 174: /* boolean_value_expression */ - case 175: /* boolean_primary */ - case 176: /* common_expression */ - case 177: /* from_clause */ - case 178: /* table_reference_list */ - case 179: /* table_reference */ - case 180: /* table_primary */ - case 181: /* joined_table */ - case 183: /* parenthesized_joined_table */ - case 185: /* search_condition */ - case 186: /* query_specification */ - case 189: /* where_clause_opt */ - case 191: /* twindow_clause_opt */ - case 193: /* having_clause_opt */ - case 195: /* select_item */ - case 196: /* sliding_opt */ - case 197: /* fill_opt */ - case 200: /* query_expression_body */ - case 202: /* slimit_clause_opt */ - case 203: /* limit_clause_opt */ - case 204: /* query_primary */ - case 206: /* sort_specification */ + case 140: /* cmd */ + case 146: /* db_options */ + case 148: /* full_table_name */ + case 151: /* table_options */ + case 155: /* create_subtable_clause */ + case 158: /* drop_table_clause */ + case 161: /* column_def */ + case 164: /* col_name */ + case 166: /* index_options */ + case 168: /* duration_literal */ + case 169: /* sliding_opt */ + case 170: /* func */ + case 173: /* query_expression */ + case 174: /* literal */ + case 177: /* expression */ + case 178: /* column_reference */ + case 179: /* subquery */ + case 180: /* predicate */ + case 183: /* in_predicate_value */ + case 184: /* boolean_value_expression */ + case 185: /* boolean_primary */ + case 186: /* common_expression */ + case 187: /* from_clause */ + case 188: /* table_reference_list */ + case 189: /* table_reference */ + case 190: /* table_primary */ + case 191: /* joined_table */ + case 193: /* parenthesized_joined_table */ + case 195: /* search_condition */ + case 196: /* query_specification */ + case 199: /* where_clause_opt */ + case 201: /* twindow_clause_opt */ + case 203: /* having_clause_opt */ + case 205: /* select_item */ + case 206: /* fill_opt */ + case 209: /* query_expression_body */ + case 211: /* slimit_clause_opt */ + case 212: /* limit_clause_opt */ + case 213: /* query_primary */ + case 215: /* sort_specification */ { - nodesDestroyNode((yypminor->yy256)); + nodesDestroyNode((yypminor->yy68)); } break; - case 136: /* user_name */ - case 137: /* dnode_endpoint */ - case 138: /* dnode_host_name */ - case 140: /* db_name */ - case 155: /* table_name */ - case 157: /* column_name */ - case 163: /* function_name */ - case 164: /* table_alias */ - case 165: /* column_alias */ - case 182: /* alias_opt */ + case 141: /* user_name */ + case 142: /* dnode_endpoint */ + case 143: /* dnode_host_name */ + case 145: /* db_name */ + case 160: /* table_name */ + case 162: /* column_name */ + case 165: /* index_name */ + case 171: /* function_name */ + case 175: /* table_alias */ + case 176: /* column_alias */ + case 192: /* alias_opt */ { } break; - case 139: /* not_exists_opt */ - case 142: /* exists_opt */ - case 187: /* set_quantifier_opt */ + case 144: /* not_exists_opt */ + case 147: /* exists_opt */ + case 197: /* set_quantifier_opt */ { } break; - case 141: /* db_options */ + case 149: /* column_def_list */ + case 150: /* tags_def_opt */ + case 152: /* multi_create_clause */ + case 153: /* tags_def */ + case 154: /* multi_drop_clause */ + case 156: /* specific_tags_opt */ + case 157: /* literal_list */ + case 159: /* col_name_list */ + case 167: /* func_list */ + case 172: /* expression_list */ + case 198: /* select_list */ + case 200: /* partition_by_clause_opt */ + case 202: /* group_by_clause_opt */ + case 204: /* select_sublist */ + case 208: /* group_by_list */ + case 210: /* order_by_clause_opt */ + case 214: /* sort_specification_list */ { - tfree((yypminor->yy391)); + nodesDestroyList((yypminor->yy40)); } break; - case 144: /* column_def_list */ - case 145: /* tags_def_opt */ - case 147: /* multi_create_clause */ - case 148: /* tags_def */ - case 149: /* multi_drop_clause */ - case 151: /* specific_tags_opt */ - case 152: /* literal_list */ - case 154: /* col_name_list */ - case 168: /* expression_list */ - case 188: /* select_list */ - case 190: /* partition_by_clause_opt */ - case 192: /* group_by_clause_opt */ - case 194: /* select_sublist */ - case 199: /* group_by_list */ - case 201: /* order_by_clause_opt */ - case 205: /* sort_specification_list */ -{ - nodesDestroyList((yypminor->yy46)); -} - break; - case 146: /* table_options */ -{ - tfree((yypminor->yy340)); -} - break; - case 158: /* type_name */ + case 163: /* type_name */ { } break; - case 171: /* compare_op */ - case 172: /* in_op */ + case 181: /* compare_op */ + case 182: /* in_op */ { } break; - case 184: /* join_type */ + case 194: /* join_type */ { } break; - case 198: /* fill_mode */ + case 207: /* fill_mode */ { } break; - case 207: /* ordering_specification_opt */ + case 216: /* ordering_specification_opt */ { } break; - case 208: /* null_ordering_opt */ + case 217: /* null_ordering_opt */ { } @@ -1588,243 +1624,254 @@ static const struct { YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ signed char nrhs; /* Negative of the number of RHS symbols in the rule */ } yyRuleInfo[] = { - { 135, -5 }, /* (0) cmd ::= CREATE USER user_name PASS NK_STRING */ - { 135, -5 }, /* (1) cmd ::= ALTER USER user_name PASS NK_STRING */ - { 135, -5 }, /* (2) cmd ::= ALTER USER user_name PRIVILEGE NK_STRING */ - { 135, -3 }, /* (3) cmd ::= DROP USER user_name */ - { 135, -2 }, /* (4) cmd ::= SHOW USERS */ - { 135, -3 }, /* (5) cmd ::= CREATE DNODE dnode_endpoint */ - { 135, -5 }, /* (6) cmd ::= CREATE DNODE dnode_host_name PORT NK_INTEGER */ - { 135, -3 }, /* (7) cmd ::= DROP DNODE NK_INTEGER */ - { 135, -3 }, /* (8) cmd ::= DROP DNODE dnode_endpoint */ - { 135, -2 }, /* (9) cmd ::= SHOW DNODES */ - { 137, -1 }, /* (10) dnode_endpoint ::= NK_STRING */ - { 138, -1 }, /* (11) dnode_host_name ::= NK_ID */ - { 138, -1 }, /* (12) dnode_host_name ::= NK_IPTOKEN */ - { 135, -5 }, /* (13) cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ - { 135, -4 }, /* (14) cmd ::= DROP DATABASE exists_opt db_name */ - { 135, -2 }, /* (15) cmd ::= SHOW DATABASES */ - { 135, -2 }, /* (16) cmd ::= USE db_name */ - { 139, -3 }, /* (17) not_exists_opt ::= IF NOT EXISTS */ - { 139, 0 }, /* (18) not_exists_opt ::= */ - { 142, -2 }, /* (19) exists_opt ::= IF EXISTS */ - { 142, 0 }, /* (20) exists_opt ::= */ - { 141, 0 }, /* (21) db_options ::= */ - { 141, -3 }, /* (22) db_options ::= db_options BLOCKS NK_INTEGER */ - { 141, -3 }, /* (23) db_options ::= db_options CACHE NK_INTEGER */ - { 141, -3 }, /* (24) db_options ::= db_options CACHELAST NK_INTEGER */ - { 141, -3 }, /* (25) db_options ::= db_options COMP NK_INTEGER */ - { 141, -3 }, /* (26) db_options ::= db_options DAYS NK_INTEGER */ - { 141, -3 }, /* (27) db_options ::= db_options FSYNC NK_INTEGER */ - { 141, -3 }, /* (28) db_options ::= db_options MAXROWS NK_INTEGER */ - { 141, -3 }, /* (29) db_options ::= db_options MINROWS NK_INTEGER */ - { 141, -3 }, /* (30) db_options ::= db_options KEEP NK_INTEGER */ - { 141, -3 }, /* (31) db_options ::= db_options PRECISION NK_STRING */ - { 141, -3 }, /* (32) db_options ::= db_options QUORUM NK_INTEGER */ - { 141, -3 }, /* (33) db_options ::= db_options REPLICA NK_INTEGER */ - { 141, -3 }, /* (34) db_options ::= db_options TTL NK_INTEGER */ - { 141, -3 }, /* (35) db_options ::= db_options WAL NK_INTEGER */ - { 141, -3 }, /* (36) db_options ::= db_options VGROUPS NK_INTEGER */ - { 141, -3 }, /* (37) db_options ::= db_options SINGLE_STABLE NK_INTEGER */ - { 141, -3 }, /* (38) db_options ::= db_options STREAM_MODE NK_INTEGER */ - { 135, -9 }, /* (39) cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ - { 135, -3 }, /* (40) cmd ::= CREATE TABLE multi_create_clause */ - { 135, -9 }, /* (41) cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ - { 135, -3 }, /* (42) cmd ::= DROP TABLE multi_drop_clause */ - { 135, -4 }, /* (43) cmd ::= DROP STABLE exists_opt full_table_name */ - { 135, -2 }, /* (44) cmd ::= SHOW TABLES */ - { 135, -2 }, /* (45) cmd ::= SHOW STABLES */ - { 147, -1 }, /* (46) multi_create_clause ::= create_subtable_clause */ - { 147, -2 }, /* (47) multi_create_clause ::= multi_create_clause create_subtable_clause */ - { 150, -9 }, /* (48) create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP */ - { 149, -1 }, /* (49) multi_drop_clause ::= drop_table_clause */ - { 149, -2 }, /* (50) multi_drop_clause ::= multi_drop_clause drop_table_clause */ - { 153, -2 }, /* (51) drop_table_clause ::= exists_opt full_table_name */ - { 151, 0 }, /* (52) specific_tags_opt ::= */ - { 151, -3 }, /* (53) specific_tags_opt ::= NK_LP col_name_list NK_RP */ - { 143, -1 }, /* (54) full_table_name ::= table_name */ - { 143, -3 }, /* (55) full_table_name ::= db_name NK_DOT table_name */ - { 144, -1 }, /* (56) column_def_list ::= column_def */ - { 144, -3 }, /* (57) column_def_list ::= column_def_list NK_COMMA column_def */ - { 156, -2 }, /* (58) column_def ::= column_name type_name */ - { 156, -4 }, /* (59) column_def ::= column_name type_name COMMENT NK_STRING */ - { 158, -1 }, /* (60) type_name ::= BOOL */ - { 158, -1 }, /* (61) type_name ::= TINYINT */ - { 158, -1 }, /* (62) type_name ::= SMALLINT */ - { 158, -1 }, /* (63) type_name ::= INT */ - { 158, -1 }, /* (64) type_name ::= INTEGER */ - { 158, -1 }, /* (65) type_name ::= BIGINT */ - { 158, -1 }, /* (66) type_name ::= FLOAT */ - { 158, -1 }, /* (67) type_name ::= DOUBLE */ - { 158, -4 }, /* (68) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ - { 158, -1 }, /* (69) type_name ::= TIMESTAMP */ - { 158, -4 }, /* (70) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ - { 158, -2 }, /* (71) type_name ::= TINYINT UNSIGNED */ - { 158, -2 }, /* (72) type_name ::= SMALLINT UNSIGNED */ - { 158, -2 }, /* (73) type_name ::= INT UNSIGNED */ - { 158, -2 }, /* (74) type_name ::= BIGINT UNSIGNED */ - { 158, -1 }, /* (75) type_name ::= JSON */ - { 158, -4 }, /* (76) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ - { 158, -1 }, /* (77) type_name ::= MEDIUMBLOB */ - { 158, -1 }, /* (78) type_name ::= BLOB */ - { 158, -4 }, /* (79) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ - { 158, -1 }, /* (80) type_name ::= DECIMAL */ - { 158, -4 }, /* (81) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ - { 158, -6 }, /* (82) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ - { 145, 0 }, /* (83) tags_def_opt ::= */ - { 145, -1 }, /* (84) tags_def_opt ::= tags_def */ - { 148, -4 }, /* (85) tags_def ::= TAGS NK_LP column_def_list NK_RP */ - { 146, 0 }, /* (86) table_options ::= */ - { 146, -3 }, /* (87) table_options ::= table_options COMMENT NK_STRING */ - { 146, -3 }, /* (88) table_options ::= table_options KEEP NK_INTEGER */ - { 146, -3 }, /* (89) table_options ::= table_options TTL NK_INTEGER */ - { 146, -5 }, /* (90) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ - { 154, -1 }, /* (91) col_name_list ::= col_name */ - { 154, -3 }, /* (92) col_name_list ::= col_name_list NK_COMMA col_name */ - { 159, -1 }, /* (93) col_name ::= column_name */ - { 135, -2 }, /* (94) cmd ::= SHOW VGROUPS */ - { 135, -4 }, /* (95) cmd ::= SHOW db_name NK_DOT VGROUPS */ - { 135, -2 }, /* (96) cmd ::= SHOW MNODES */ - { 135, -1 }, /* (97) cmd ::= query_expression */ - { 161, -1 }, /* (98) literal ::= NK_INTEGER */ - { 161, -1 }, /* (99) literal ::= NK_FLOAT */ - { 161, -1 }, /* (100) literal ::= NK_STRING */ - { 161, -1 }, /* (101) literal ::= NK_BOOL */ - { 161, -2 }, /* (102) literal ::= TIMESTAMP NK_STRING */ - { 161, -1 }, /* (103) literal ::= duration_literal */ - { 162, -1 }, /* (104) duration_literal ::= NK_VARIABLE */ - { 152, -1 }, /* (105) literal_list ::= literal */ - { 152, -3 }, /* (106) literal_list ::= literal_list NK_COMMA literal */ - { 140, -1 }, /* (107) db_name ::= NK_ID */ - { 155, -1 }, /* (108) table_name ::= NK_ID */ - { 157, -1 }, /* (109) column_name ::= NK_ID */ - { 163, -1 }, /* (110) function_name ::= NK_ID */ - { 164, -1 }, /* (111) table_alias ::= NK_ID */ - { 165, -1 }, /* (112) column_alias ::= NK_ID */ - { 136, -1 }, /* (113) user_name ::= NK_ID */ - { 166, -1 }, /* (114) expression ::= literal */ - { 166, -1 }, /* (115) expression ::= column_reference */ - { 166, -4 }, /* (116) expression ::= function_name NK_LP expression_list NK_RP */ - { 166, -4 }, /* (117) expression ::= function_name NK_LP NK_STAR NK_RP */ - { 166, -1 }, /* (118) expression ::= subquery */ - { 166, -3 }, /* (119) expression ::= NK_LP expression NK_RP */ - { 166, -2 }, /* (120) expression ::= NK_PLUS expression */ - { 166, -2 }, /* (121) expression ::= NK_MINUS expression */ - { 166, -3 }, /* (122) expression ::= expression NK_PLUS expression */ - { 166, -3 }, /* (123) expression ::= expression NK_MINUS expression */ - { 166, -3 }, /* (124) expression ::= expression NK_STAR expression */ - { 166, -3 }, /* (125) expression ::= expression NK_SLASH expression */ - { 166, -3 }, /* (126) expression ::= expression NK_REM expression */ - { 168, -1 }, /* (127) expression_list ::= expression */ - { 168, -3 }, /* (128) expression_list ::= expression_list NK_COMMA expression */ - { 167, -1 }, /* (129) column_reference ::= column_name */ - { 167, -3 }, /* (130) column_reference ::= table_name NK_DOT column_name */ - { 170, -3 }, /* (131) predicate ::= expression compare_op expression */ - { 170, -5 }, /* (132) predicate ::= expression BETWEEN expression AND expression */ - { 170, -6 }, /* (133) predicate ::= expression NOT BETWEEN expression AND expression */ - { 170, -3 }, /* (134) predicate ::= expression IS NULL */ - { 170, -4 }, /* (135) predicate ::= expression IS NOT NULL */ - { 170, -3 }, /* (136) predicate ::= expression in_op in_predicate_value */ - { 171, -1 }, /* (137) compare_op ::= NK_LT */ - { 171, -1 }, /* (138) compare_op ::= NK_GT */ - { 171, -1 }, /* (139) compare_op ::= NK_LE */ - { 171, -1 }, /* (140) compare_op ::= NK_GE */ - { 171, -1 }, /* (141) compare_op ::= NK_NE */ - { 171, -1 }, /* (142) compare_op ::= NK_EQ */ - { 171, -1 }, /* (143) compare_op ::= LIKE */ - { 171, -2 }, /* (144) compare_op ::= NOT LIKE */ - { 171, -1 }, /* (145) compare_op ::= MATCH */ - { 171, -1 }, /* (146) compare_op ::= NMATCH */ - { 172, -1 }, /* (147) in_op ::= IN */ - { 172, -2 }, /* (148) in_op ::= NOT IN */ - { 173, -3 }, /* (149) in_predicate_value ::= NK_LP expression_list NK_RP */ - { 174, -1 }, /* (150) boolean_value_expression ::= boolean_primary */ - { 174, -2 }, /* (151) boolean_value_expression ::= NOT boolean_primary */ - { 174, -3 }, /* (152) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - { 174, -3 }, /* (153) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - { 175, -1 }, /* (154) boolean_primary ::= predicate */ - { 175, -3 }, /* (155) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - { 176, -1 }, /* (156) common_expression ::= expression */ - { 176, -1 }, /* (157) common_expression ::= boolean_value_expression */ - { 177, -2 }, /* (158) from_clause ::= FROM table_reference_list */ - { 178, -1 }, /* (159) table_reference_list ::= table_reference */ - { 178, -3 }, /* (160) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - { 179, -1 }, /* (161) table_reference ::= table_primary */ - { 179, -1 }, /* (162) table_reference ::= joined_table */ - { 180, -2 }, /* (163) table_primary ::= table_name alias_opt */ - { 180, -4 }, /* (164) table_primary ::= db_name NK_DOT table_name alias_opt */ - { 180, -2 }, /* (165) table_primary ::= subquery alias_opt */ - { 180, -1 }, /* (166) table_primary ::= parenthesized_joined_table */ - { 182, 0 }, /* (167) alias_opt ::= */ - { 182, -1 }, /* (168) alias_opt ::= table_alias */ - { 182, -2 }, /* (169) alias_opt ::= AS table_alias */ - { 183, -3 }, /* (170) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - { 183, -3 }, /* (171) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - { 181, -6 }, /* (172) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - { 184, 0 }, /* (173) join_type ::= */ - { 184, -1 }, /* (174) join_type ::= INNER */ - { 186, -9 }, /* (175) query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ - { 187, 0 }, /* (176) set_quantifier_opt ::= */ - { 187, -1 }, /* (177) set_quantifier_opt ::= DISTINCT */ - { 187, -1 }, /* (178) set_quantifier_opt ::= ALL */ - { 188, -1 }, /* (179) select_list ::= NK_STAR */ - { 188, -1 }, /* (180) select_list ::= select_sublist */ - { 194, -1 }, /* (181) select_sublist ::= select_item */ - { 194, -3 }, /* (182) select_sublist ::= select_sublist NK_COMMA select_item */ - { 195, -1 }, /* (183) select_item ::= common_expression */ - { 195, -2 }, /* (184) select_item ::= common_expression column_alias */ - { 195, -3 }, /* (185) select_item ::= common_expression AS column_alias */ - { 195, -3 }, /* (186) select_item ::= table_name NK_DOT NK_STAR */ - { 189, 0 }, /* (187) where_clause_opt ::= */ - { 189, -2 }, /* (188) where_clause_opt ::= WHERE search_condition */ - { 190, 0 }, /* (189) partition_by_clause_opt ::= */ - { 190, -3 }, /* (190) partition_by_clause_opt ::= PARTITION BY expression_list */ - { 191, 0 }, /* (191) twindow_clause_opt ::= */ - { 191, -6 }, /* (192) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA NK_INTEGER NK_RP */ - { 191, -4 }, /* (193) twindow_clause_opt ::= STATE_WINDOW NK_LP column_reference NK_RP */ - { 191, -6 }, /* (194) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - { 191, -8 }, /* (195) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - { 196, 0 }, /* (196) sliding_opt ::= */ - { 196, -4 }, /* (197) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - { 197, 0 }, /* (198) fill_opt ::= */ - { 197, -4 }, /* (199) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - { 197, -6 }, /* (200) fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ - { 198, -1 }, /* (201) fill_mode ::= NONE */ - { 198, -1 }, /* (202) fill_mode ::= PREV */ - { 198, -1 }, /* (203) fill_mode ::= NULL */ - { 198, -1 }, /* (204) fill_mode ::= LINEAR */ - { 198, -1 }, /* (205) fill_mode ::= NEXT */ - { 192, 0 }, /* (206) group_by_clause_opt ::= */ - { 192, -3 }, /* (207) group_by_clause_opt ::= GROUP BY group_by_list */ - { 199, -1 }, /* (208) group_by_list ::= expression */ - { 199, -3 }, /* (209) group_by_list ::= group_by_list NK_COMMA expression */ - { 193, 0 }, /* (210) having_clause_opt ::= */ - { 193, -2 }, /* (211) having_clause_opt ::= HAVING search_condition */ - { 160, -4 }, /* (212) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ - { 200, -1 }, /* (213) query_expression_body ::= query_primary */ - { 200, -4 }, /* (214) query_expression_body ::= query_expression_body UNION ALL query_expression_body */ - { 204, -1 }, /* (215) query_primary ::= query_specification */ - { 201, 0 }, /* (216) order_by_clause_opt ::= */ - { 201, -3 }, /* (217) order_by_clause_opt ::= ORDER BY sort_specification_list */ - { 202, 0 }, /* (218) slimit_clause_opt ::= */ - { 202, -2 }, /* (219) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - { 202, -4 }, /* (220) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - { 202, -4 }, /* (221) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - { 203, 0 }, /* (222) limit_clause_opt ::= */ - { 203, -2 }, /* (223) limit_clause_opt ::= LIMIT NK_INTEGER */ - { 203, -4 }, /* (224) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - { 203, -4 }, /* (225) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - { 169, -3 }, /* (226) subquery ::= NK_LP query_expression NK_RP */ - { 185, -1 }, /* (227) search_condition ::= common_expression */ - { 205, -1 }, /* (228) sort_specification_list ::= sort_specification */ - { 205, -3 }, /* (229) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - { 206, -3 }, /* (230) sort_specification ::= expression ordering_specification_opt null_ordering_opt */ - { 207, 0 }, /* (231) ordering_specification_opt ::= */ - { 207, -1 }, /* (232) ordering_specification_opt ::= ASC */ - { 207, -1 }, /* (233) ordering_specification_opt ::= DESC */ - { 208, 0 }, /* (234) null_ordering_opt ::= */ - { 208, -2 }, /* (235) null_ordering_opt ::= NULLS FIRST */ - { 208, -2 }, /* (236) null_ordering_opt ::= NULLS LAST */ + { 140, -5 }, /* (0) cmd ::= CREATE USER user_name PASS NK_STRING */ + { 140, -5 }, /* (1) cmd ::= ALTER USER user_name PASS NK_STRING */ + { 140, -5 }, /* (2) cmd ::= ALTER USER user_name PRIVILEGE NK_STRING */ + { 140, -3 }, /* (3) cmd ::= DROP USER user_name */ + { 140, -2 }, /* (4) cmd ::= SHOW USERS */ + { 140, -3 }, /* (5) cmd ::= CREATE DNODE dnode_endpoint */ + { 140, -5 }, /* (6) cmd ::= CREATE DNODE dnode_host_name PORT NK_INTEGER */ + { 140, -3 }, /* (7) cmd ::= DROP DNODE NK_INTEGER */ + { 140, -3 }, /* (8) cmd ::= DROP DNODE dnode_endpoint */ + { 140, -2 }, /* (9) cmd ::= SHOW DNODES */ + { 142, -1 }, /* (10) dnode_endpoint ::= NK_STRING */ + { 143, -1 }, /* (11) dnode_host_name ::= NK_ID */ + { 143, -1 }, /* (12) dnode_host_name ::= NK_IPTOKEN */ + { 140, -5 }, /* (13) cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ + { 140, -2 }, /* (14) cmd ::= SHOW QNODES */ + { 140, -5 }, /* (15) cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ + { 140, -4 }, /* (16) cmd ::= DROP DATABASE exists_opt db_name */ + { 140, -2 }, /* (17) cmd ::= SHOW DATABASES */ + { 140, -2 }, /* (18) cmd ::= USE db_name */ + { 144, -3 }, /* (19) not_exists_opt ::= IF NOT EXISTS */ + { 144, 0 }, /* (20) not_exists_opt ::= */ + { 147, -2 }, /* (21) exists_opt ::= IF EXISTS */ + { 147, 0 }, /* (22) exists_opt ::= */ + { 146, 0 }, /* (23) db_options ::= */ + { 146, -3 }, /* (24) db_options ::= db_options BLOCKS NK_INTEGER */ + { 146, -3 }, /* (25) db_options ::= db_options CACHE NK_INTEGER */ + { 146, -3 }, /* (26) db_options ::= db_options CACHELAST NK_INTEGER */ + { 146, -3 }, /* (27) db_options ::= db_options COMP NK_INTEGER */ + { 146, -3 }, /* (28) db_options ::= db_options DAYS NK_INTEGER */ + { 146, -3 }, /* (29) db_options ::= db_options FSYNC NK_INTEGER */ + { 146, -3 }, /* (30) db_options ::= db_options MAXROWS NK_INTEGER */ + { 146, -3 }, /* (31) db_options ::= db_options MINROWS NK_INTEGER */ + { 146, -3 }, /* (32) db_options ::= db_options KEEP NK_INTEGER */ + { 146, -3 }, /* (33) db_options ::= db_options PRECISION NK_STRING */ + { 146, -3 }, /* (34) db_options ::= db_options QUORUM NK_INTEGER */ + { 146, -3 }, /* (35) db_options ::= db_options REPLICA NK_INTEGER */ + { 146, -3 }, /* (36) db_options ::= db_options TTL NK_INTEGER */ + { 146, -3 }, /* (37) db_options ::= db_options WAL NK_INTEGER */ + { 146, -3 }, /* (38) db_options ::= db_options VGROUPS NK_INTEGER */ + { 146, -3 }, /* (39) db_options ::= db_options SINGLE_STABLE NK_INTEGER */ + { 146, -3 }, /* (40) db_options ::= db_options STREAM_MODE NK_INTEGER */ + { 140, -9 }, /* (41) cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ + { 140, -3 }, /* (42) cmd ::= CREATE TABLE multi_create_clause */ + { 140, -9 }, /* (43) cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ + { 140, -3 }, /* (44) cmd ::= DROP TABLE multi_drop_clause */ + { 140, -4 }, /* (45) cmd ::= DROP STABLE exists_opt full_table_name */ + { 140, -2 }, /* (46) cmd ::= SHOW TABLES */ + { 140, -2 }, /* (47) cmd ::= SHOW STABLES */ + { 152, -1 }, /* (48) multi_create_clause ::= create_subtable_clause */ + { 152, -2 }, /* (49) multi_create_clause ::= multi_create_clause create_subtable_clause */ + { 155, -9 }, /* (50) create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP */ + { 154, -1 }, /* (51) multi_drop_clause ::= drop_table_clause */ + { 154, -2 }, /* (52) multi_drop_clause ::= multi_drop_clause drop_table_clause */ + { 158, -2 }, /* (53) drop_table_clause ::= exists_opt full_table_name */ + { 156, 0 }, /* (54) specific_tags_opt ::= */ + { 156, -3 }, /* (55) specific_tags_opt ::= NK_LP col_name_list NK_RP */ + { 148, -1 }, /* (56) full_table_name ::= table_name */ + { 148, -3 }, /* (57) full_table_name ::= db_name NK_DOT table_name */ + { 149, -1 }, /* (58) column_def_list ::= column_def */ + { 149, -3 }, /* (59) column_def_list ::= column_def_list NK_COMMA column_def */ + { 161, -2 }, /* (60) column_def ::= column_name type_name */ + { 161, -4 }, /* (61) column_def ::= column_name type_name COMMENT NK_STRING */ + { 163, -1 }, /* (62) type_name ::= BOOL */ + { 163, -1 }, /* (63) type_name ::= TINYINT */ + { 163, -1 }, /* (64) type_name ::= SMALLINT */ + { 163, -1 }, /* (65) type_name ::= INT */ + { 163, -1 }, /* (66) type_name ::= INTEGER */ + { 163, -1 }, /* (67) type_name ::= BIGINT */ + { 163, -1 }, /* (68) type_name ::= FLOAT */ + { 163, -1 }, /* (69) type_name ::= DOUBLE */ + { 163, -4 }, /* (70) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + { 163, -1 }, /* (71) type_name ::= TIMESTAMP */ + { 163, -4 }, /* (72) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + { 163, -2 }, /* (73) type_name ::= TINYINT UNSIGNED */ + { 163, -2 }, /* (74) type_name ::= SMALLINT UNSIGNED */ + { 163, -2 }, /* (75) type_name ::= INT UNSIGNED */ + { 163, -2 }, /* (76) type_name ::= BIGINT UNSIGNED */ + { 163, -1 }, /* (77) type_name ::= JSON */ + { 163, -4 }, /* (78) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + { 163, -1 }, /* (79) type_name ::= MEDIUMBLOB */ + { 163, -1 }, /* (80) type_name ::= BLOB */ + { 163, -4 }, /* (81) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + { 163, -1 }, /* (82) type_name ::= DECIMAL */ + { 163, -4 }, /* (83) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + { 163, -6 }, /* (84) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + { 150, 0 }, /* (85) tags_def_opt ::= */ + { 150, -1 }, /* (86) tags_def_opt ::= tags_def */ + { 153, -4 }, /* (87) tags_def ::= TAGS NK_LP column_def_list NK_RP */ + { 151, 0 }, /* (88) table_options ::= */ + { 151, -3 }, /* (89) table_options ::= table_options COMMENT NK_STRING */ + { 151, -3 }, /* (90) table_options ::= table_options KEEP NK_INTEGER */ + { 151, -3 }, /* (91) table_options ::= table_options TTL NK_INTEGER */ + { 151, -5 }, /* (92) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + { 159, -1 }, /* (93) col_name_list ::= col_name */ + { 159, -3 }, /* (94) col_name_list ::= col_name_list NK_COMMA col_name */ + { 164, -1 }, /* (95) col_name ::= column_name */ + { 140, -7 }, /* (96) cmd ::= CREATE SMA INDEX index_name ON table_name index_options */ + { 140, -9 }, /* (97) cmd ::= CREATE FULLTEXT INDEX index_name ON table_name NK_LP col_name_list NK_RP */ + { 166, 0 }, /* (98) index_options ::= */ + { 166, -9 }, /* (99) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt */ + { 166, -11 }, /* (100) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt */ + { 167, -1 }, /* (101) func_list ::= func */ + { 167, -3 }, /* (102) func_list ::= func_list NK_COMMA func */ + { 170, -4 }, /* (103) func ::= function_name NK_LP expression_list NK_RP */ + { 140, -2 }, /* (104) cmd ::= SHOW VGROUPS */ + { 140, -4 }, /* (105) cmd ::= SHOW db_name NK_DOT VGROUPS */ + { 140, -2 }, /* (106) cmd ::= SHOW MNODES */ + { 140, -1 }, /* (107) cmd ::= query_expression */ + { 174, -1 }, /* (108) literal ::= NK_INTEGER */ + { 174, -1 }, /* (109) literal ::= NK_FLOAT */ + { 174, -1 }, /* (110) literal ::= NK_STRING */ + { 174, -1 }, /* (111) literal ::= NK_BOOL */ + { 174, -2 }, /* (112) literal ::= TIMESTAMP NK_STRING */ + { 174, -1 }, /* (113) literal ::= duration_literal */ + { 168, -1 }, /* (114) duration_literal ::= NK_VARIABLE */ + { 157, -1 }, /* (115) literal_list ::= literal */ + { 157, -3 }, /* (116) literal_list ::= literal_list NK_COMMA literal */ + { 145, -1 }, /* (117) db_name ::= NK_ID */ + { 160, -1 }, /* (118) table_name ::= NK_ID */ + { 162, -1 }, /* (119) column_name ::= NK_ID */ + { 171, -1 }, /* (120) function_name ::= NK_ID */ + { 175, -1 }, /* (121) table_alias ::= NK_ID */ + { 176, -1 }, /* (122) column_alias ::= NK_ID */ + { 141, -1 }, /* (123) user_name ::= NK_ID */ + { 165, -1 }, /* (124) index_name ::= NK_ID */ + { 177, -1 }, /* (125) expression ::= literal */ + { 177, -1 }, /* (126) expression ::= column_reference */ + { 177, -4 }, /* (127) expression ::= function_name NK_LP expression_list NK_RP */ + { 177, -4 }, /* (128) expression ::= function_name NK_LP NK_STAR NK_RP */ + { 177, -1 }, /* (129) expression ::= subquery */ + { 177, -3 }, /* (130) expression ::= NK_LP expression NK_RP */ + { 177, -2 }, /* (131) expression ::= NK_PLUS expression */ + { 177, -2 }, /* (132) expression ::= NK_MINUS expression */ + { 177, -3 }, /* (133) expression ::= expression NK_PLUS expression */ + { 177, -3 }, /* (134) expression ::= expression NK_MINUS expression */ + { 177, -3 }, /* (135) expression ::= expression NK_STAR expression */ + { 177, -3 }, /* (136) expression ::= expression NK_SLASH expression */ + { 177, -3 }, /* (137) expression ::= expression NK_REM expression */ + { 172, -1 }, /* (138) expression_list ::= expression */ + { 172, -3 }, /* (139) expression_list ::= expression_list NK_COMMA expression */ + { 178, -1 }, /* (140) column_reference ::= column_name */ + { 178, -3 }, /* (141) column_reference ::= table_name NK_DOT column_name */ + { 180, -3 }, /* (142) predicate ::= expression compare_op expression */ + { 180, -5 }, /* (143) predicate ::= expression BETWEEN expression AND expression */ + { 180, -6 }, /* (144) predicate ::= expression NOT BETWEEN expression AND expression */ + { 180, -3 }, /* (145) predicate ::= expression IS NULL */ + { 180, -4 }, /* (146) predicate ::= expression IS NOT NULL */ + { 180, -3 }, /* (147) predicate ::= expression in_op in_predicate_value */ + { 181, -1 }, /* (148) compare_op ::= NK_LT */ + { 181, -1 }, /* (149) compare_op ::= NK_GT */ + { 181, -1 }, /* (150) compare_op ::= NK_LE */ + { 181, -1 }, /* (151) compare_op ::= NK_GE */ + { 181, -1 }, /* (152) compare_op ::= NK_NE */ + { 181, -1 }, /* (153) compare_op ::= NK_EQ */ + { 181, -1 }, /* (154) compare_op ::= LIKE */ + { 181, -2 }, /* (155) compare_op ::= NOT LIKE */ + { 181, -1 }, /* (156) compare_op ::= MATCH */ + { 181, -1 }, /* (157) compare_op ::= NMATCH */ + { 182, -1 }, /* (158) in_op ::= IN */ + { 182, -2 }, /* (159) in_op ::= NOT IN */ + { 183, -3 }, /* (160) in_predicate_value ::= NK_LP expression_list NK_RP */ + { 184, -1 }, /* (161) boolean_value_expression ::= boolean_primary */ + { 184, -2 }, /* (162) boolean_value_expression ::= NOT boolean_primary */ + { 184, -3 }, /* (163) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + { 184, -3 }, /* (164) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + { 185, -1 }, /* (165) boolean_primary ::= predicate */ + { 185, -3 }, /* (166) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + { 186, -1 }, /* (167) common_expression ::= expression */ + { 186, -1 }, /* (168) common_expression ::= boolean_value_expression */ + { 187, -2 }, /* (169) from_clause ::= FROM table_reference_list */ + { 188, -1 }, /* (170) table_reference_list ::= table_reference */ + { 188, -3 }, /* (171) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + { 189, -1 }, /* (172) table_reference ::= table_primary */ + { 189, -1 }, /* (173) table_reference ::= joined_table */ + { 190, -2 }, /* (174) table_primary ::= table_name alias_opt */ + { 190, -4 }, /* (175) table_primary ::= db_name NK_DOT table_name alias_opt */ + { 190, -2 }, /* (176) table_primary ::= subquery alias_opt */ + { 190, -1 }, /* (177) table_primary ::= parenthesized_joined_table */ + { 192, 0 }, /* (178) alias_opt ::= */ + { 192, -1 }, /* (179) alias_opt ::= table_alias */ + { 192, -2 }, /* (180) alias_opt ::= AS table_alias */ + { 193, -3 }, /* (181) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + { 193, -3 }, /* (182) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + { 191, -6 }, /* (183) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + { 194, 0 }, /* (184) join_type ::= */ + { 194, -1 }, /* (185) join_type ::= INNER */ + { 196, -9 }, /* (186) query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + { 197, 0 }, /* (187) set_quantifier_opt ::= */ + { 197, -1 }, /* (188) set_quantifier_opt ::= DISTINCT */ + { 197, -1 }, /* (189) set_quantifier_opt ::= ALL */ + { 198, -1 }, /* (190) select_list ::= NK_STAR */ + { 198, -1 }, /* (191) select_list ::= select_sublist */ + { 204, -1 }, /* (192) select_sublist ::= select_item */ + { 204, -3 }, /* (193) select_sublist ::= select_sublist NK_COMMA select_item */ + { 205, -1 }, /* (194) select_item ::= common_expression */ + { 205, -2 }, /* (195) select_item ::= common_expression column_alias */ + { 205, -3 }, /* (196) select_item ::= common_expression AS column_alias */ + { 205, -3 }, /* (197) select_item ::= table_name NK_DOT NK_STAR */ + { 199, 0 }, /* (198) where_clause_opt ::= */ + { 199, -2 }, /* (199) where_clause_opt ::= WHERE search_condition */ + { 200, 0 }, /* (200) partition_by_clause_opt ::= */ + { 200, -3 }, /* (201) partition_by_clause_opt ::= PARTITION BY expression_list */ + { 201, 0 }, /* (202) twindow_clause_opt ::= */ + { 201, -6 }, /* (203) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA NK_INTEGER NK_RP */ + { 201, -4 }, /* (204) twindow_clause_opt ::= STATE_WINDOW NK_LP column_reference NK_RP */ + { 201, -6 }, /* (205) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + { 201, -8 }, /* (206) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + { 169, 0 }, /* (207) sliding_opt ::= */ + { 169, -4 }, /* (208) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + { 206, 0 }, /* (209) fill_opt ::= */ + { 206, -4 }, /* (210) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + { 206, -6 }, /* (211) fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ + { 207, -1 }, /* (212) fill_mode ::= NONE */ + { 207, -1 }, /* (213) fill_mode ::= PREV */ + { 207, -1 }, /* (214) fill_mode ::= NULL */ + { 207, -1 }, /* (215) fill_mode ::= LINEAR */ + { 207, -1 }, /* (216) fill_mode ::= NEXT */ + { 202, 0 }, /* (217) group_by_clause_opt ::= */ + { 202, -3 }, /* (218) group_by_clause_opt ::= GROUP BY group_by_list */ + { 208, -1 }, /* (219) group_by_list ::= expression */ + { 208, -3 }, /* (220) group_by_list ::= group_by_list NK_COMMA expression */ + { 203, 0 }, /* (221) having_clause_opt ::= */ + { 203, -2 }, /* (222) having_clause_opt ::= HAVING search_condition */ + { 173, -4 }, /* (223) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ + { 209, -1 }, /* (224) query_expression_body ::= query_primary */ + { 209, -4 }, /* (225) query_expression_body ::= query_expression_body UNION ALL query_expression_body */ + { 213, -1 }, /* (226) query_primary ::= query_specification */ + { 210, 0 }, /* (227) order_by_clause_opt ::= */ + { 210, -3 }, /* (228) order_by_clause_opt ::= ORDER BY sort_specification_list */ + { 211, 0 }, /* (229) slimit_clause_opt ::= */ + { 211, -2 }, /* (230) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + { 211, -4 }, /* (231) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + { 211, -4 }, /* (232) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + { 212, 0 }, /* (233) limit_clause_opt ::= */ + { 212, -2 }, /* (234) limit_clause_opt ::= LIMIT NK_INTEGER */ + { 212, -4 }, /* (235) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + { 212, -4 }, /* (236) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + { 179, -3 }, /* (237) subquery ::= NK_LP query_expression NK_RP */ + { 195, -1 }, /* (238) search_condition ::= common_expression */ + { 214, -1 }, /* (239) sort_specification_list ::= sort_specification */ + { 214, -3 }, /* (240) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + { 215, -3 }, /* (241) sort_specification ::= expression ordering_specification_opt null_ordering_opt */ + { 216, 0 }, /* (242) ordering_specification_opt ::= */ + { 216, -1 }, /* (243) ordering_specification_opt ::= ASC */ + { 216, -1 }, /* (244) ordering_specification_opt ::= DESC */ + { 217, 0 }, /* (245) null_ordering_opt ::= */ + { 217, -2 }, /* (246) null_ordering_opt ::= NULLS FIRST */ + { 217, -2 }, /* (247) null_ordering_opt ::= NULLS LAST */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -1912,31 +1959,31 @@ static YYACTIONTYPE yy_reduce( /********** Begin reduce actions **********************************************/ YYMINORTYPE yylhsminor; case 0: /* cmd ::= CREATE USER user_name PASS NK_STRING */ -{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-2].minor.yy129, &yymsp[0].minor.yy0);} +{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-2].minor.yy5, &yymsp[0].minor.yy0);} break; case 1: /* cmd ::= ALTER USER user_name PASS NK_STRING */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy129, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0);} +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy5, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0);} break; case 2: /* cmd ::= ALTER USER user_name PRIVILEGE NK_STRING */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy129, TSDB_ALTER_USER_PRIVILEGES, &yymsp[0].minor.yy0);} +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy5, TSDB_ALTER_USER_PRIVILEGES, &yymsp[0].minor.yy0);} break; case 3: /* cmd ::= DROP USER user_name */ -{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy129); } +{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy5); } break; case 4: /* cmd ::= SHOW USERS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_USERS_STMT, NULL); } break; case 5: /* cmd ::= CREATE DNODE dnode_endpoint */ -{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy129, NULL);} +{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy5, NULL);} break; case 6: /* cmd ::= CREATE DNODE dnode_host_name PORT NK_INTEGER */ -{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy129, &yymsp[0].minor.yy0);} +{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy5, &yymsp[0].minor.yy0);} break; case 7: /* cmd ::= DROP DNODE NK_INTEGER */ { pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy0);} break; case 8: /* cmd ::= DROP DNODE dnode_endpoint */ -{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy129);} +{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy5);} break; case 9: /* cmd ::= SHOW DNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DNODES_STMT, NULL); } @@ -1944,716 +1991,742 @@ static YYACTIONTYPE yy_reduce( case 10: /* dnode_endpoint ::= NK_STRING */ case 11: /* dnode_host_name ::= NK_ID */ yytestcase(yyruleno==11); case 12: /* dnode_host_name ::= NK_IPTOKEN */ yytestcase(yyruleno==12); - case 107: /* db_name ::= NK_ID */ yytestcase(yyruleno==107); - case 108: /* table_name ::= NK_ID */ yytestcase(yyruleno==108); - case 109: /* column_name ::= NK_ID */ yytestcase(yyruleno==109); - case 110: /* function_name ::= NK_ID */ yytestcase(yyruleno==110); - case 111: /* table_alias ::= NK_ID */ yytestcase(yyruleno==111); - case 112: /* column_alias ::= NK_ID */ yytestcase(yyruleno==112); - case 113: /* user_name ::= NK_ID */ yytestcase(yyruleno==113); -{ yylhsminor.yy129 = yymsp[0].minor.yy0; } - yymsp[0].minor.yy129 = yylhsminor.yy129; + case 117: /* db_name ::= NK_ID */ yytestcase(yyruleno==117); + case 118: /* table_name ::= NK_ID */ yytestcase(yyruleno==118); + case 119: /* column_name ::= NK_ID */ yytestcase(yyruleno==119); + case 120: /* function_name ::= NK_ID */ yytestcase(yyruleno==120); + case 121: /* table_alias ::= NK_ID */ yytestcase(yyruleno==121); + case 122: /* column_alias ::= NK_ID */ yytestcase(yyruleno==122); + case 123: /* user_name ::= NK_ID */ yytestcase(yyruleno==123); + case 124: /* index_name ::= NK_ID */ yytestcase(yyruleno==124); +{ yylhsminor.yy5 = yymsp[0].minor.yy0; } + yymsp[0].minor.yy5 = yylhsminor.yy5; break; - case 13: /* cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ -{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy129, yymsp[0].minor.yy391);} + case 13: /* cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ +{ pCxt->pRootNode = createCreateQnodeStmt(pCxt, &yymsp[0].minor.yy0); } break; - case 14: /* cmd ::= DROP DATABASE exists_opt db_name */ -{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy185, &yymsp[0].minor.yy129); } + case 14: /* cmd ::= SHOW QNODES */ +{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT, NULL); } break; - case 15: /* cmd ::= SHOW DATABASES */ + case 15: /* cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ +{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy25, &yymsp[-1].minor.yy5, yymsp[0].minor.yy68);} + break; + case 16: /* cmd ::= DROP DATABASE exists_opt db_name */ +{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy25, &yymsp[0].minor.yy5); } + break; + case 17: /* cmd ::= SHOW DATABASES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT, NULL); } break; - case 16: /* cmd ::= USE db_name */ -{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy129);} + case 18: /* cmd ::= USE db_name */ +{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy5);} break; - case 17: /* not_exists_opt ::= IF NOT EXISTS */ -{ yymsp[-2].minor.yy185 = true; } + case 19: /* not_exists_opt ::= IF NOT EXISTS */ +{ yymsp[-2].minor.yy25 = true; } break; - case 18: /* not_exists_opt ::= */ - case 20: /* exists_opt ::= */ yytestcase(yyruleno==20); - case 176: /* set_quantifier_opt ::= */ yytestcase(yyruleno==176); -{ yymsp[1].minor.yy185 = false; } + case 20: /* not_exists_opt ::= */ + case 22: /* exists_opt ::= */ yytestcase(yyruleno==22); + case 187: /* set_quantifier_opt ::= */ yytestcase(yyruleno==187); +{ yymsp[1].minor.yy25 = false; } break; - case 19: /* exists_opt ::= IF EXISTS */ -{ yymsp[-1].minor.yy185 = true; } + case 21: /* exists_opt ::= IF EXISTS */ +{ yymsp[-1].minor.yy25 = true; } break; - case 21: /* db_options ::= */ -{ yymsp[1].minor.yy391 = createDefaultDatabaseOptions(pCxt); } + case 23: /* db_options ::= */ +{ yymsp[1].minor.yy68 = createDefaultDatabaseOptions(pCxt); } break; - case 22: /* db_options ::= db_options BLOCKS NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_BLOCKS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 24: /* db_options ::= db_options BLOCKS NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_BLOCKS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 23: /* db_options ::= db_options CACHE NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_CACHE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 25: /* db_options ::= db_options CACHE NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_CACHE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 24: /* db_options ::= db_options CACHELAST NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_CACHELAST, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 26: /* db_options ::= db_options CACHELAST NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_CACHELAST, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 25: /* db_options ::= db_options COMP NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_COMP, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 27: /* db_options ::= db_options COMP NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_COMP, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 26: /* db_options ::= db_options DAYS NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 28: /* db_options ::= db_options DAYS NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 27: /* db_options ::= db_options FSYNC NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 29: /* db_options ::= db_options FSYNC NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 28: /* db_options ::= db_options MAXROWS NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 30: /* db_options ::= db_options MAXROWS NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 29: /* db_options ::= db_options MINROWS NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 31: /* db_options ::= db_options MINROWS NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 30: /* db_options ::= db_options KEEP NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_KEEP, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 32: /* db_options ::= db_options KEEP NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_KEEP, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 31: /* db_options ::= db_options PRECISION NK_STRING */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 33: /* db_options ::= db_options PRECISION NK_STRING */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 32: /* db_options ::= db_options QUORUM NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_QUORUM, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 34: /* db_options ::= db_options QUORUM NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_QUORUM, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 33: /* db_options ::= db_options REPLICA NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 35: /* db_options ::= db_options REPLICA NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 34: /* db_options ::= db_options TTL NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_TTL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 36: /* db_options ::= db_options TTL NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_TTL, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 35: /* db_options ::= db_options WAL NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_WAL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 37: /* db_options ::= db_options WAL NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_WAL, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 36: /* db_options ::= db_options VGROUPS NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 38: /* db_options ::= db_options VGROUPS NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 37: /* db_options ::= db_options SINGLE_STABLE NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_SINGLESTABLE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 39: /* db_options ::= db_options SINGLE_STABLE NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_SINGLESTABLE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 38: /* db_options ::= db_options STREAM_MODE NK_INTEGER */ -{ yylhsminor.yy391 = setDatabaseOption(pCxt, yymsp[-2].minor.yy391, DB_OPTION_STREAMMODE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy391 = yylhsminor.yy391; + case 40: /* db_options ::= db_options STREAM_MODE NK_INTEGER */ +{ yylhsminor.yy68 = setDatabaseOption(pCxt, yymsp[-2].minor.yy68, DB_OPTION_STREAMMODE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 39: /* cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ - case 41: /* cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ yytestcase(yyruleno==41); -{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy185, yymsp[-5].minor.yy256, yymsp[-3].minor.yy46, yymsp[-1].minor.yy46, yymsp[0].minor.yy340);} + case 41: /* cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ + case 43: /* cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ yytestcase(yyruleno==43); +{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy25, yymsp[-5].minor.yy68, yymsp[-3].minor.yy40, yymsp[-1].minor.yy40, yymsp[0].minor.yy68);} break; - case 40: /* cmd ::= CREATE TABLE multi_create_clause */ -{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy46);} + case 42: /* cmd ::= CREATE TABLE multi_create_clause */ +{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy40);} break; - case 42: /* cmd ::= DROP TABLE multi_drop_clause */ -{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy46); } + case 44: /* cmd ::= DROP TABLE multi_drop_clause */ +{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy40); } break; - case 43: /* cmd ::= DROP STABLE exists_opt full_table_name */ -{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy185, yymsp[0].minor.yy256); } + case 45: /* cmd ::= DROP STABLE exists_opt full_table_name */ +{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy25, yymsp[0].minor.yy68); } break; - case 44: /* cmd ::= SHOW TABLES */ + case 46: /* cmd ::= SHOW TABLES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TABLES_STMT, NULL); } break; - case 45: /* cmd ::= SHOW STABLES */ + case 47: /* cmd ::= SHOW STABLES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STABLES_STMT, NULL); } break; - case 46: /* multi_create_clause ::= create_subtable_clause */ - case 49: /* multi_drop_clause ::= drop_table_clause */ yytestcase(yyruleno==49); - case 56: /* column_def_list ::= column_def */ yytestcase(yyruleno==56); - case 91: /* col_name_list ::= col_name */ yytestcase(yyruleno==91); - case 181: /* select_sublist ::= select_item */ yytestcase(yyruleno==181); - case 228: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==228); -{ yylhsminor.yy46 = createNodeList(pCxt, yymsp[0].minor.yy256); } - yymsp[0].minor.yy46 = yylhsminor.yy46; + case 48: /* multi_create_clause ::= create_subtable_clause */ + case 51: /* multi_drop_clause ::= drop_table_clause */ yytestcase(yyruleno==51); + case 58: /* column_def_list ::= column_def */ yytestcase(yyruleno==58); + case 93: /* col_name_list ::= col_name */ yytestcase(yyruleno==93); + case 101: /* func_list ::= func */ yytestcase(yyruleno==101); + case 192: /* select_sublist ::= select_item */ yytestcase(yyruleno==192); + case 239: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==239); +{ yylhsminor.yy40 = createNodeList(pCxt, yymsp[0].minor.yy68); } + yymsp[0].minor.yy40 = yylhsminor.yy40; break; - case 47: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ - case 50: /* multi_drop_clause ::= multi_drop_clause drop_table_clause */ yytestcase(yyruleno==50); -{ yylhsminor.yy46 = addNodeToList(pCxt, yymsp[-1].minor.yy46, yymsp[0].minor.yy256); } - yymsp[-1].minor.yy46 = yylhsminor.yy46; + case 49: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ + case 52: /* multi_drop_clause ::= multi_drop_clause drop_table_clause */ yytestcase(yyruleno==52); +{ yylhsminor.yy40 = addNodeToList(pCxt, yymsp[-1].minor.yy40, yymsp[0].minor.yy68); } + yymsp[-1].minor.yy40 = yylhsminor.yy40; break; - case 48: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP */ -{ yylhsminor.yy256 = createCreateSubTableClause(pCxt, yymsp[-8].minor.yy185, yymsp[-7].minor.yy256, yymsp[-5].minor.yy256, yymsp[-4].minor.yy46, yymsp[-1].minor.yy46); } - yymsp[-8].minor.yy256 = yylhsminor.yy256; + case 50: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP */ +{ yylhsminor.yy68 = createCreateSubTableClause(pCxt, yymsp[-8].minor.yy25, yymsp[-7].minor.yy68, yymsp[-5].minor.yy68, yymsp[-4].minor.yy40, yymsp[-1].minor.yy40); } + yymsp[-8].minor.yy68 = yylhsminor.yy68; break; - case 51: /* drop_table_clause ::= exists_opt full_table_name */ -{ yylhsminor.yy256 = createDropTableClause(pCxt, yymsp[-1].minor.yy185, yymsp[0].minor.yy256); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + case 53: /* drop_table_clause ::= exists_opt full_table_name */ +{ yylhsminor.yy68 = createDropTableClause(pCxt, yymsp[-1].minor.yy25, yymsp[0].minor.yy68); } + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 52: /* specific_tags_opt ::= */ - case 83: /* tags_def_opt ::= */ yytestcase(yyruleno==83); - case 189: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==189); - case 206: /* group_by_clause_opt ::= */ yytestcase(yyruleno==206); - case 216: /* order_by_clause_opt ::= */ yytestcase(yyruleno==216); -{ yymsp[1].minor.yy46 = NULL; } + case 54: /* specific_tags_opt ::= */ + case 85: /* tags_def_opt ::= */ yytestcase(yyruleno==85); + case 200: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==200); + case 217: /* group_by_clause_opt ::= */ yytestcase(yyruleno==217); + case 227: /* order_by_clause_opt ::= */ yytestcase(yyruleno==227); +{ yymsp[1].minor.yy40 = NULL; } break; - case 53: /* specific_tags_opt ::= NK_LP col_name_list NK_RP */ -{ yymsp[-2].minor.yy46 = yymsp[-1].minor.yy46; } + case 55: /* specific_tags_opt ::= NK_LP col_name_list NK_RP */ +{ yymsp[-2].minor.yy40 = yymsp[-1].minor.yy40; } break; - case 54: /* full_table_name ::= table_name */ -{ yylhsminor.yy256 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy129, NULL); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 56: /* full_table_name ::= table_name */ +{ yylhsminor.yy68 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy5, NULL); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 55: /* full_table_name ::= db_name NK_DOT table_name */ -{ yylhsminor.yy256 = createRealTableNode(pCxt, &yymsp[-2].minor.yy129, &yymsp[0].minor.yy129, NULL); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 57: /* full_table_name ::= db_name NK_DOT table_name */ +{ yylhsminor.yy68 = createRealTableNode(pCxt, &yymsp[-2].minor.yy5, &yymsp[0].minor.yy5, NULL); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 57: /* column_def_list ::= column_def_list NK_COMMA column_def */ - case 92: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==92); - case 182: /* select_sublist ::= select_sublist NK_COMMA select_item */ yytestcase(yyruleno==182); - case 229: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==229); -{ yylhsminor.yy46 = addNodeToList(pCxt, yymsp[-2].minor.yy46, yymsp[0].minor.yy256); } - yymsp[-2].minor.yy46 = yylhsminor.yy46; + case 59: /* column_def_list ::= column_def_list NK_COMMA column_def */ + case 94: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==94); + case 102: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==102); + case 193: /* select_sublist ::= select_sublist NK_COMMA select_item */ yytestcase(yyruleno==193); + case 240: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==240); +{ yylhsminor.yy40 = addNodeToList(pCxt, yymsp[-2].minor.yy40, yymsp[0].minor.yy68); } + yymsp[-2].minor.yy40 = yylhsminor.yy40; break; - case 58: /* column_def ::= column_name type_name */ -{ yylhsminor.yy256 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy129, yymsp[0].minor.yy70, NULL); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + case 60: /* column_def ::= column_name type_name */ +{ yylhsminor.yy68 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy5, yymsp[0].minor.yy372, NULL); } + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 59: /* column_def ::= column_name type_name COMMENT NK_STRING */ -{ yylhsminor.yy256 = createColumnDefNode(pCxt, &yymsp[-3].minor.yy129, yymsp[-2].minor.yy70, &yymsp[0].minor.yy0); } - yymsp[-3].minor.yy256 = yylhsminor.yy256; + case 61: /* column_def ::= column_name type_name COMMENT NK_STRING */ +{ yylhsminor.yy68 = createColumnDefNode(pCxt, &yymsp[-3].minor.yy5, yymsp[-2].minor.yy372, &yymsp[0].minor.yy0); } + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 60: /* type_name ::= BOOL */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_BOOL); } + case 62: /* type_name ::= BOOL */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_BOOL); } break; - case 61: /* type_name ::= TINYINT */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_TINYINT); } + case 63: /* type_name ::= TINYINT */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_TINYINT); } break; - case 62: /* type_name ::= SMALLINT */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_SMALLINT); } + case 64: /* type_name ::= SMALLINT */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_SMALLINT); } break; - case 63: /* type_name ::= INT */ - case 64: /* type_name ::= INTEGER */ yytestcase(yyruleno==64); -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_INT); } + case 65: /* type_name ::= INT */ + case 66: /* type_name ::= INTEGER */ yytestcase(yyruleno==66); +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_INT); } break; - case 65: /* type_name ::= BIGINT */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_BIGINT); } + case 67: /* type_name ::= BIGINT */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_BIGINT); } break; - case 66: /* type_name ::= FLOAT */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_FLOAT); } + case 68: /* type_name ::= FLOAT */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_FLOAT); } break; - case 67: /* type_name ::= DOUBLE */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_DOUBLE); } + case 69: /* type_name ::= DOUBLE */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_DOUBLE); } break; - case 68: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy70 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } + case 70: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ +{ yymsp[-3].minor.yy372 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } break; - case 69: /* type_name ::= TIMESTAMP */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } + case 71: /* type_name ::= TIMESTAMP */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } break; - case 70: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy70 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } + case 72: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ +{ yymsp[-3].minor.yy372 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } break; - case 71: /* type_name ::= TINYINT UNSIGNED */ -{ yymsp[-1].minor.yy70 = createDataType(TSDB_DATA_TYPE_UTINYINT); } + case 73: /* type_name ::= TINYINT UNSIGNED */ +{ yymsp[-1].minor.yy372 = createDataType(TSDB_DATA_TYPE_UTINYINT); } break; - case 72: /* type_name ::= SMALLINT UNSIGNED */ -{ yymsp[-1].minor.yy70 = createDataType(TSDB_DATA_TYPE_USMALLINT); } + case 74: /* type_name ::= SMALLINT UNSIGNED */ +{ yymsp[-1].minor.yy372 = createDataType(TSDB_DATA_TYPE_USMALLINT); } break; - case 73: /* type_name ::= INT UNSIGNED */ -{ yymsp[-1].minor.yy70 = createDataType(TSDB_DATA_TYPE_UINT); } + case 75: /* type_name ::= INT UNSIGNED */ +{ yymsp[-1].minor.yy372 = createDataType(TSDB_DATA_TYPE_UINT); } break; - case 74: /* type_name ::= BIGINT UNSIGNED */ -{ yymsp[-1].minor.yy70 = createDataType(TSDB_DATA_TYPE_UBIGINT); } + case 76: /* type_name ::= BIGINT UNSIGNED */ +{ yymsp[-1].minor.yy372 = createDataType(TSDB_DATA_TYPE_UBIGINT); } break; - case 75: /* type_name ::= JSON */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_JSON); } + case 77: /* type_name ::= JSON */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_JSON); } break; - case 76: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy70 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } + case 78: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ +{ yymsp[-3].minor.yy372 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } break; - case 77: /* type_name ::= MEDIUMBLOB */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } + case 79: /* type_name ::= MEDIUMBLOB */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } break; - case 78: /* type_name ::= BLOB */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_BLOB); } + case 80: /* type_name ::= BLOB */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_BLOB); } break; - case 79: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy70 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } + case 81: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ +{ yymsp[-3].minor.yy372 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } break; - case 80: /* type_name ::= DECIMAL */ -{ yymsp[0].minor.yy70 = createDataType(TSDB_DATA_TYPE_DECIMAL); } + case 82: /* type_name ::= DECIMAL */ +{ yymsp[0].minor.yy372 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; - case 81: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy70 = createDataType(TSDB_DATA_TYPE_DECIMAL); } + case 83: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ +{ yymsp[-3].minor.yy372 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; - case 82: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ -{ yymsp[-5].minor.yy70 = createDataType(TSDB_DATA_TYPE_DECIMAL); } + case 84: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ +{ yymsp[-5].minor.yy372 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; - case 84: /* tags_def_opt ::= tags_def */ - case 180: /* select_list ::= select_sublist */ yytestcase(yyruleno==180); -{ yylhsminor.yy46 = yymsp[0].minor.yy46; } - yymsp[0].minor.yy46 = yylhsminor.yy46; + case 86: /* tags_def_opt ::= tags_def */ + case 191: /* select_list ::= select_sublist */ yytestcase(yyruleno==191); +{ yylhsminor.yy40 = yymsp[0].minor.yy40; } + yymsp[0].minor.yy40 = yylhsminor.yy40; break; - case 85: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ -{ yymsp[-3].minor.yy46 = yymsp[-1].minor.yy46; } + case 87: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ +{ yymsp[-3].minor.yy40 = yymsp[-1].minor.yy40; } break; - case 86: /* table_options ::= */ -{ yymsp[1].minor.yy340 = createDefaultTableOptions(pCxt);} + case 88: /* table_options ::= */ +{ yymsp[1].minor.yy68 = createDefaultTableOptions(pCxt);} break; - case 87: /* table_options ::= table_options COMMENT NK_STRING */ -{ yylhsminor.yy340 = setTableOption(pCxt, yymsp[-2].minor.yy340, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy340 = yylhsminor.yy340; + case 89: /* table_options ::= table_options COMMENT NK_STRING */ +{ yylhsminor.yy68 = setTableOption(pCxt, yymsp[-2].minor.yy68, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 88: /* table_options ::= table_options KEEP NK_INTEGER */ -{ yylhsminor.yy340 = setTableOption(pCxt, yymsp[-2].minor.yy340, TABLE_OPTION_KEEP, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy340 = yylhsminor.yy340; + case 90: /* table_options ::= table_options KEEP NK_INTEGER */ +{ yylhsminor.yy68 = setTableOption(pCxt, yymsp[-2].minor.yy68, TABLE_OPTION_KEEP, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 89: /* table_options ::= table_options TTL NK_INTEGER */ -{ yylhsminor.yy340 = setTableOption(pCxt, yymsp[-2].minor.yy340, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy340 = yylhsminor.yy340; + case 91: /* table_options ::= table_options TTL NK_INTEGER */ +{ yylhsminor.yy68 = setTableOption(pCxt, yymsp[-2].minor.yy68, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 90: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ -{ yylhsminor.yy340 = setTableSmaOption(pCxt, yymsp[-4].minor.yy340, yymsp[-1].minor.yy46); } - yymsp[-4].minor.yy340 = yylhsminor.yy340; + case 92: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ +{ yylhsminor.yy68 = setTableSmaOption(pCxt, yymsp[-4].minor.yy68, yymsp[-1].minor.yy40); } + yymsp[-4].minor.yy68 = yylhsminor.yy68; break; - case 93: /* col_name ::= column_name */ -{ yylhsminor.yy256 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy129); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 95: /* col_name ::= column_name */ +{ yylhsminor.yy68 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy5); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 94: /* cmd ::= SHOW VGROUPS */ + case 96: /* cmd ::= CREATE SMA INDEX index_name ON table_name index_options */ +{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, &yymsp[-3].minor.yy5, &yymsp[-1].minor.yy5, NULL, yymsp[0].minor.yy68); } + break; + case 97: /* cmd ::= CREATE FULLTEXT INDEX index_name ON table_name NK_LP col_name_list NK_RP */ +{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_FULLTEXT, &yymsp[-5].minor.yy5, &yymsp[-3].minor.yy5, yymsp[-1].minor.yy40, NULL); } + break; + case 98: /* index_options ::= */ + case 198: /* where_clause_opt ::= */ yytestcase(yyruleno==198); + case 202: /* twindow_clause_opt ::= */ yytestcase(yyruleno==202); + case 207: /* sliding_opt ::= */ yytestcase(yyruleno==207); + case 209: /* fill_opt ::= */ yytestcase(yyruleno==209); + case 221: /* having_clause_opt ::= */ yytestcase(yyruleno==221); + case 229: /* slimit_clause_opt ::= */ yytestcase(yyruleno==229); + case 233: /* limit_clause_opt ::= */ yytestcase(yyruleno==233); +{ yymsp[1].minor.yy68 = NULL; } + break; + case 99: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt */ +{ yymsp[-8].minor.yy68 = createIndexOption(pCxt, yymsp[-6].minor.yy40, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), NULL, yymsp[0].minor.yy68); } + break; + case 100: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt */ +{ yymsp[-10].minor.yy68 = createIndexOption(pCxt, yymsp[-8].minor.yy40, releaseRawExprNode(pCxt, yymsp[-4].minor.yy68), releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), yymsp[0].minor.yy68); } + break; + case 103: /* func ::= function_name NK_LP expression_list NK_RP */ +{ yylhsminor.yy68 = createFunctionNode(pCxt, &yymsp[-3].minor.yy5, yymsp[-1].minor.yy40); } + yymsp[-3].minor.yy68 = yylhsminor.yy68; + break; + case 104: /* cmd ::= SHOW VGROUPS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, NULL); } break; - case 95: /* cmd ::= SHOW db_name NK_DOT VGROUPS */ -{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, &yymsp[-2].minor.yy129); } + case 105: /* cmd ::= SHOW db_name NK_DOT VGROUPS */ +{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, &yymsp[-2].minor.yy5); } break; - case 96: /* cmd ::= SHOW MNODES */ + case 106: /* cmd ::= SHOW MNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT, NULL); } break; - case 97: /* cmd ::= query_expression */ -{ pCxt->pRootNode = yymsp[0].minor.yy256; } + case 107: /* cmd ::= query_expression */ +{ pCxt->pRootNode = yymsp[0].minor.yy68; } break; - case 98: /* literal ::= NK_INTEGER */ -{ yylhsminor.yy256 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 108: /* literal ::= NK_INTEGER */ +{ yylhsminor.yy68 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 99: /* literal ::= NK_FLOAT */ -{ yylhsminor.yy256 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 109: /* literal ::= NK_FLOAT */ +{ yylhsminor.yy68 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 100: /* literal ::= NK_STRING */ -{ yylhsminor.yy256 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 110: /* literal ::= NK_STRING */ +{ yylhsminor.yy68 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 101: /* literal ::= NK_BOOL */ -{ yylhsminor.yy256 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 111: /* literal ::= NK_BOOL */ +{ yylhsminor.yy68 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 102: /* literal ::= TIMESTAMP NK_STRING */ -{ yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + case 112: /* literal ::= TIMESTAMP NK_STRING */ +{ yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 103: /* literal ::= duration_literal */ - case 114: /* expression ::= literal */ yytestcase(yyruleno==114); - case 115: /* expression ::= column_reference */ yytestcase(yyruleno==115); - case 118: /* expression ::= subquery */ yytestcase(yyruleno==118); - case 150: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==150); - case 154: /* boolean_primary ::= predicate */ yytestcase(yyruleno==154); - case 156: /* common_expression ::= expression */ yytestcase(yyruleno==156); - case 157: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==157); - case 159: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==159); - case 161: /* table_reference ::= table_primary */ yytestcase(yyruleno==161); - case 162: /* table_reference ::= joined_table */ yytestcase(yyruleno==162); - case 166: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==166); - case 213: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==213); - case 215: /* query_primary ::= query_specification */ yytestcase(yyruleno==215); -{ yylhsminor.yy256 = yymsp[0].minor.yy256; } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 113: /* literal ::= duration_literal */ + case 125: /* expression ::= literal */ yytestcase(yyruleno==125); + case 126: /* expression ::= column_reference */ yytestcase(yyruleno==126); + case 129: /* expression ::= subquery */ yytestcase(yyruleno==129); + case 161: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==161); + case 165: /* boolean_primary ::= predicate */ yytestcase(yyruleno==165); + case 167: /* common_expression ::= expression */ yytestcase(yyruleno==167); + case 168: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==168); + case 170: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==170); + case 172: /* table_reference ::= table_primary */ yytestcase(yyruleno==172); + case 173: /* table_reference ::= joined_table */ yytestcase(yyruleno==173); + case 177: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==177); + case 224: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==224); + case 226: /* query_primary ::= query_specification */ yytestcase(yyruleno==226); +{ yylhsminor.yy68 = yymsp[0].minor.yy68; } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 104: /* duration_literal ::= NK_VARIABLE */ -{ yylhsminor.yy256 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 114: /* duration_literal ::= NK_VARIABLE */ +{ yylhsminor.yy68 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 105: /* literal_list ::= literal */ - case 127: /* expression_list ::= expression */ yytestcase(yyruleno==127); -{ yylhsminor.yy46 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy256)); } - yymsp[0].minor.yy46 = yylhsminor.yy46; + case 115: /* literal_list ::= literal */ + case 138: /* expression_list ::= expression */ yytestcase(yyruleno==138); +{ yylhsminor.yy40 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy68)); } + yymsp[0].minor.yy40 = yylhsminor.yy40; break; - case 106: /* literal_list ::= literal_list NK_COMMA literal */ - case 128: /* expression_list ::= expression_list NK_COMMA expression */ yytestcase(yyruleno==128); -{ yylhsminor.yy46 = addNodeToList(pCxt, yymsp[-2].minor.yy46, releaseRawExprNode(pCxt, yymsp[0].minor.yy256)); } - yymsp[-2].minor.yy46 = yylhsminor.yy46; + case 116: /* literal_list ::= literal_list NK_COMMA literal */ + case 139: /* expression_list ::= expression_list NK_COMMA expression */ yytestcase(yyruleno==139); +{ yylhsminor.yy40 = addNodeToList(pCxt, yymsp[-2].minor.yy40, releaseRawExprNode(pCxt, yymsp[0].minor.yy68)); } + yymsp[-2].minor.yy40 = yylhsminor.yy40; break; - case 116: /* expression ::= function_name NK_LP expression_list NK_RP */ -{ yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy129, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy129, yymsp[-1].minor.yy46)); } - yymsp[-3].minor.yy256 = yylhsminor.yy256; + case 127: /* expression ::= function_name NK_LP expression_list NK_RP */ +{ yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy5, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy5, yymsp[-1].minor.yy40)); } + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 117: /* expression ::= function_name NK_LP NK_STAR NK_RP */ -{ yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy129, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy129, createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[-1].minor.yy0)))); } - yymsp[-3].minor.yy256 = yylhsminor.yy256; + case 128: /* expression ::= function_name NK_LP NK_STAR NK_RP */ +{ yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy5, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy5, createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[-1].minor.yy0)))); } + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 119: /* expression ::= NK_LP expression NK_RP */ - case 155: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==155); -{ yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy256)); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 130: /* expression ::= NK_LP expression NK_RP */ + case 166: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==166); +{ yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy68)); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 120: /* expression ::= NK_PLUS expression */ + case 131: /* expression ::= NK_PLUS expression */ { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy256)); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy68)); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 121: /* expression ::= NK_MINUS expression */ + case 132: /* expression ::= NK_MINUS expression */ { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[0].minor.yy256), NULL)); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[0].minor.yy68), NULL)); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 122: /* expression ::= expression NK_PLUS expression */ + case 133: /* expression ::= expression NK_PLUS expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 123: /* expression ::= expression NK_MINUS expression */ + case 134: /* expression ::= expression NK_MINUS expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 124: /* expression ::= expression NK_STAR expression */ + case 135: /* expression ::= expression NK_STAR expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 125: /* expression ::= expression NK_SLASH expression */ + case 136: /* expression ::= expression NK_SLASH expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 126: /* expression ::= expression NK_REM expression */ + case 137: /* expression ::= expression NK_REM expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MOD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MOD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 129: /* column_reference ::= column_name */ -{ yylhsminor.yy256 = createRawExprNode(pCxt, &yymsp[0].minor.yy129, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy129)); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 140: /* column_reference ::= column_name */ +{ yylhsminor.yy68 = createRawExprNode(pCxt, &yymsp[0].minor.yy5, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy5)); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 130: /* column_reference ::= table_name NK_DOT column_name */ -{ yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy129, &yymsp[0].minor.yy129, createColumnNode(pCxt, &yymsp[-2].minor.yy129, &yymsp[0].minor.yy129)); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 141: /* column_reference ::= table_name NK_DOT column_name */ +{ yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy5, &yymsp[0].minor.yy5, createColumnNode(pCxt, &yymsp[-2].minor.yy5, &yymsp[0].minor.yy5)); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 131: /* predicate ::= expression compare_op expression */ - case 136: /* predicate ::= expression in_op in_predicate_value */ yytestcase(yyruleno==136); + case 142: /* predicate ::= expression compare_op expression */ + case 147: /* predicate ::= expression in_op in_predicate_value */ yytestcase(yyruleno==147); { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy326, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy416, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 132: /* predicate ::= expression BETWEEN expression AND expression */ + case 143: /* predicate ::= expression BETWEEN expression AND expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy256), releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy68), releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-4].minor.yy256 = yylhsminor.yy256; + yymsp[-4].minor.yy68 = yylhsminor.yy68; break; - case 133: /* predicate ::= expression NOT BETWEEN expression AND expression */ + case 144: /* predicate ::= expression NOT BETWEEN expression AND expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[-5].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[-5].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-5].minor.yy256 = yylhsminor.yy256; + yymsp[-5].minor.yy68 = yylhsminor.yy68; break; - case 134: /* predicate ::= expression IS NULL */ + case 145: /* predicate ::= expression IS NULL */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), NULL)); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), NULL)); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 135: /* predicate ::= expression IS NOT NULL */ + case 146: /* predicate ::= expression IS NOT NULL */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy256), NULL)); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy68), NULL)); } - yymsp[-3].minor.yy256 = yylhsminor.yy256; + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 137: /* compare_op ::= NK_LT */ -{ yymsp[0].minor.yy326 = OP_TYPE_LOWER_THAN; } + case 148: /* compare_op ::= NK_LT */ +{ yymsp[0].minor.yy416 = OP_TYPE_LOWER_THAN; } break; - case 138: /* compare_op ::= NK_GT */ -{ yymsp[0].minor.yy326 = OP_TYPE_GREATER_THAN; } + case 149: /* compare_op ::= NK_GT */ +{ yymsp[0].minor.yy416 = OP_TYPE_GREATER_THAN; } break; - case 139: /* compare_op ::= NK_LE */ -{ yymsp[0].minor.yy326 = OP_TYPE_LOWER_EQUAL; } + case 150: /* compare_op ::= NK_LE */ +{ yymsp[0].minor.yy416 = OP_TYPE_LOWER_EQUAL; } break; - case 140: /* compare_op ::= NK_GE */ -{ yymsp[0].minor.yy326 = OP_TYPE_GREATER_EQUAL; } + case 151: /* compare_op ::= NK_GE */ +{ yymsp[0].minor.yy416 = OP_TYPE_GREATER_EQUAL; } break; - case 141: /* compare_op ::= NK_NE */ -{ yymsp[0].minor.yy326 = OP_TYPE_NOT_EQUAL; } + case 152: /* compare_op ::= NK_NE */ +{ yymsp[0].minor.yy416 = OP_TYPE_NOT_EQUAL; } break; - case 142: /* compare_op ::= NK_EQ */ -{ yymsp[0].minor.yy326 = OP_TYPE_EQUAL; } + case 153: /* compare_op ::= NK_EQ */ +{ yymsp[0].minor.yy416 = OP_TYPE_EQUAL; } break; - case 143: /* compare_op ::= LIKE */ -{ yymsp[0].minor.yy326 = OP_TYPE_LIKE; } + case 154: /* compare_op ::= LIKE */ +{ yymsp[0].minor.yy416 = OP_TYPE_LIKE; } break; - case 144: /* compare_op ::= NOT LIKE */ -{ yymsp[-1].minor.yy326 = OP_TYPE_NOT_LIKE; } + case 155: /* compare_op ::= NOT LIKE */ +{ yymsp[-1].minor.yy416 = OP_TYPE_NOT_LIKE; } break; - case 145: /* compare_op ::= MATCH */ -{ yymsp[0].minor.yy326 = OP_TYPE_MATCH; } + case 156: /* compare_op ::= MATCH */ +{ yymsp[0].minor.yy416 = OP_TYPE_MATCH; } break; - case 146: /* compare_op ::= NMATCH */ -{ yymsp[0].minor.yy326 = OP_TYPE_NMATCH; } + case 157: /* compare_op ::= NMATCH */ +{ yymsp[0].minor.yy416 = OP_TYPE_NMATCH; } break; - case 147: /* in_op ::= IN */ -{ yymsp[0].minor.yy326 = OP_TYPE_IN; } + case 158: /* in_op ::= IN */ +{ yymsp[0].minor.yy416 = OP_TYPE_IN; } break; - case 148: /* in_op ::= NOT IN */ -{ yymsp[-1].minor.yy326 = OP_TYPE_NOT_IN; } + case 159: /* in_op ::= NOT IN */ +{ yymsp[-1].minor.yy416 = OP_TYPE_NOT_IN; } break; - case 149: /* in_predicate_value ::= NK_LP expression_list NK_RP */ -{ yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy46)); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 160: /* in_predicate_value ::= NK_LP expression_list NK_RP */ +{ yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy40)); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 151: /* boolean_value_expression ::= NOT boolean_primary */ + case 162: /* boolean_value_expression ::= NOT boolean_primary */ { - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy256), NULL)); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy68), NULL)); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 152: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + case 163: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 153: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + case 164: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy256); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy68); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 158: /* from_clause ::= FROM table_reference_list */ - case 188: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==188); - case 211: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==211); -{ yymsp[-1].minor.yy256 = yymsp[0].minor.yy256; } + case 169: /* from_clause ::= FROM table_reference_list */ + case 199: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==199); + case 222: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==222); +{ yymsp[-1].minor.yy68 = yymsp[0].minor.yy68; } break; - case 160: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ -{ yylhsminor.yy256 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy256, yymsp[0].minor.yy256, NULL); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 171: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ +{ yylhsminor.yy68 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy68, yymsp[0].minor.yy68, NULL); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 163: /* table_primary ::= table_name alias_opt */ -{ yylhsminor.yy256 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy129, &yymsp[0].minor.yy129); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + case 174: /* table_primary ::= table_name alias_opt */ +{ yylhsminor.yy68 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy5, &yymsp[0].minor.yy5); } + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 164: /* table_primary ::= db_name NK_DOT table_name alias_opt */ -{ yylhsminor.yy256 = createRealTableNode(pCxt, &yymsp[-3].minor.yy129, &yymsp[-1].minor.yy129, &yymsp[0].minor.yy129); } - yymsp[-3].minor.yy256 = yylhsminor.yy256; + case 175: /* table_primary ::= db_name NK_DOT table_name alias_opt */ +{ yylhsminor.yy68 = createRealTableNode(pCxt, &yymsp[-3].minor.yy5, &yymsp[-1].minor.yy5, &yymsp[0].minor.yy5); } + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 165: /* table_primary ::= subquery alias_opt */ -{ yylhsminor.yy256 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy256), &yymsp[0].minor.yy129); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + case 176: /* table_primary ::= subquery alias_opt */ +{ yylhsminor.yy68 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy68), &yymsp[0].minor.yy5); } + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 167: /* alias_opt ::= */ -{ yymsp[1].minor.yy129 = nil_token; } + case 178: /* alias_opt ::= */ +{ yymsp[1].minor.yy5 = nil_token; } break; - case 168: /* alias_opt ::= table_alias */ -{ yylhsminor.yy129 = yymsp[0].minor.yy129; } - yymsp[0].minor.yy129 = yylhsminor.yy129; + case 179: /* alias_opt ::= table_alias */ +{ yylhsminor.yy5 = yymsp[0].minor.yy5; } + yymsp[0].minor.yy5 = yylhsminor.yy5; break; - case 169: /* alias_opt ::= AS table_alias */ -{ yymsp[-1].minor.yy129 = yymsp[0].minor.yy129; } + case 180: /* alias_opt ::= AS table_alias */ +{ yymsp[-1].minor.yy5 = yymsp[0].minor.yy5; } break; - case 170: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - case 171: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==171); -{ yymsp[-2].minor.yy256 = yymsp[-1].minor.yy256; } + case 181: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + case 182: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==182); +{ yymsp[-2].minor.yy68 = yymsp[-1].minor.yy68; } break; - case 172: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ -{ yylhsminor.yy256 = createJoinTableNode(pCxt, yymsp[-4].minor.yy266, yymsp[-5].minor.yy256, yymsp[-2].minor.yy256, yymsp[0].minor.yy256); } - yymsp[-5].minor.yy256 = yylhsminor.yy256; + case 183: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ +{ yylhsminor.yy68 = createJoinTableNode(pCxt, yymsp[-4].minor.yy92, yymsp[-5].minor.yy68, yymsp[-2].minor.yy68, yymsp[0].minor.yy68); } + yymsp[-5].minor.yy68 = yylhsminor.yy68; break; - case 173: /* join_type ::= */ -{ yymsp[1].minor.yy266 = JOIN_TYPE_INNER; } + case 184: /* join_type ::= */ +{ yymsp[1].minor.yy92 = JOIN_TYPE_INNER; } break; - case 174: /* join_type ::= INNER */ -{ yymsp[0].minor.yy266 = JOIN_TYPE_INNER; } + case 185: /* join_type ::= INNER */ +{ yymsp[0].minor.yy92 = JOIN_TYPE_INNER; } break; - case 175: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + case 186: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ { - yymsp[-8].minor.yy256 = createSelectStmt(pCxt, yymsp[-7].minor.yy185, yymsp[-6].minor.yy46, yymsp[-5].minor.yy256); - yymsp[-8].minor.yy256 = addWhereClause(pCxt, yymsp[-8].minor.yy256, yymsp[-4].minor.yy256); - yymsp[-8].minor.yy256 = addPartitionByClause(pCxt, yymsp[-8].minor.yy256, yymsp[-3].minor.yy46); - yymsp[-8].minor.yy256 = addWindowClauseClause(pCxt, yymsp[-8].minor.yy256, yymsp[-2].minor.yy256); - yymsp[-8].minor.yy256 = addGroupByClause(pCxt, yymsp[-8].minor.yy256, yymsp[-1].minor.yy46); - yymsp[-8].minor.yy256 = addHavingClause(pCxt, yymsp[-8].minor.yy256, yymsp[0].minor.yy256); + yymsp[-8].minor.yy68 = createSelectStmt(pCxt, yymsp[-7].minor.yy25, yymsp[-6].minor.yy40, yymsp[-5].minor.yy68); + yymsp[-8].minor.yy68 = addWhereClause(pCxt, yymsp[-8].minor.yy68, yymsp[-4].minor.yy68); + yymsp[-8].minor.yy68 = addPartitionByClause(pCxt, yymsp[-8].minor.yy68, yymsp[-3].minor.yy40); + yymsp[-8].minor.yy68 = addWindowClauseClause(pCxt, yymsp[-8].minor.yy68, yymsp[-2].minor.yy68); + yymsp[-8].minor.yy68 = addGroupByClause(pCxt, yymsp[-8].minor.yy68, yymsp[-1].minor.yy40); + yymsp[-8].minor.yy68 = addHavingClause(pCxt, yymsp[-8].minor.yy68, yymsp[0].minor.yy68); } break; - case 177: /* set_quantifier_opt ::= DISTINCT */ -{ yymsp[0].minor.yy185 = true; } + case 188: /* set_quantifier_opt ::= DISTINCT */ +{ yymsp[0].minor.yy25 = true; } break; - case 178: /* set_quantifier_opt ::= ALL */ -{ yymsp[0].minor.yy185 = false; } + case 189: /* set_quantifier_opt ::= ALL */ +{ yymsp[0].minor.yy25 = false; } break; - case 179: /* select_list ::= NK_STAR */ -{ yymsp[0].minor.yy46 = NULL; } + case 190: /* select_list ::= NK_STAR */ +{ yymsp[0].minor.yy40 = NULL; } break; - case 183: /* select_item ::= common_expression */ + case 194: /* select_item ::= common_expression */ { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy256); - yylhsminor.yy256 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy256), &t); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy68); + yylhsminor.yy68 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy68), &t); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 184: /* select_item ::= common_expression column_alias */ -{ yylhsminor.yy256 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy256), &yymsp[0].minor.yy129); } - yymsp[-1].minor.yy256 = yylhsminor.yy256; + case 195: /* select_item ::= common_expression column_alias */ +{ yylhsminor.yy68 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy68), &yymsp[0].minor.yy5); } + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 185: /* select_item ::= common_expression AS column_alias */ -{ yylhsminor.yy256 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), &yymsp[0].minor.yy129); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 196: /* select_item ::= common_expression AS column_alias */ +{ yylhsminor.yy68 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), &yymsp[0].minor.yy5); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 186: /* select_item ::= table_name NK_DOT NK_STAR */ -{ yylhsminor.yy256 = createColumnNode(pCxt, &yymsp[-2].minor.yy129, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 197: /* select_item ::= table_name NK_DOT NK_STAR */ +{ yylhsminor.yy68 = createColumnNode(pCxt, &yymsp[-2].minor.yy5, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 187: /* where_clause_opt ::= */ - case 191: /* twindow_clause_opt ::= */ yytestcase(yyruleno==191); - case 196: /* sliding_opt ::= */ yytestcase(yyruleno==196); - case 198: /* fill_opt ::= */ yytestcase(yyruleno==198); - case 210: /* having_clause_opt ::= */ yytestcase(yyruleno==210); - case 218: /* slimit_clause_opt ::= */ yytestcase(yyruleno==218); - case 222: /* limit_clause_opt ::= */ yytestcase(yyruleno==222); -{ yymsp[1].minor.yy256 = NULL; } + case 201: /* partition_by_clause_opt ::= PARTITION BY expression_list */ + case 218: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==218); + case 228: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==228); +{ yymsp[-2].minor.yy40 = yymsp[0].minor.yy40; } break; - case 190: /* partition_by_clause_opt ::= PARTITION BY expression_list */ - case 207: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==207); - case 217: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==217); -{ yymsp[-2].minor.yy46 = yymsp[0].minor.yy46; } + case 203: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA NK_INTEGER NK_RP */ +{ yymsp[-5].minor.yy68 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy68), &yymsp[-1].minor.yy0); } break; - case 192: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA NK_INTEGER NK_RP */ -{ yymsp[-5].minor.yy256 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy256), &yymsp[-1].minor.yy0); } + case 204: /* twindow_clause_opt ::= STATE_WINDOW NK_LP column_reference NK_RP */ +{ yymsp[-3].minor.yy68 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy68)); } break; - case 193: /* twindow_clause_opt ::= STATE_WINDOW NK_LP column_reference NK_RP */ -{ yymsp[-3].minor.yy256 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy256)); } + case 205: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ +{ yymsp[-5].minor.yy68 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy68), NULL, yymsp[-1].minor.yy68, yymsp[0].minor.yy68); } break; - case 194: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ -{ yymsp[-5].minor.yy256 = createIntervalWindowNode(pCxt, yymsp[-3].minor.yy256, NULL, yymsp[-1].minor.yy256, yymsp[0].minor.yy256); } + case 206: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ +{ yymsp[-7].minor.yy68 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy68), releaseRawExprNode(pCxt, yymsp[-3].minor.yy68), yymsp[-1].minor.yy68, yymsp[0].minor.yy68); } break; - case 195: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ -{ yymsp[-7].minor.yy256 = createIntervalWindowNode(pCxt, yymsp[-5].minor.yy256, yymsp[-3].minor.yy256, yymsp[-1].minor.yy256, yymsp[0].minor.yy256); } + case 208: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ +{ yymsp[-3].minor.yy68 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy68); } break; - case 197: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ -{ yymsp[-3].minor.yy256 = yymsp[-1].minor.yy256; } + case 210: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ +{ yymsp[-3].minor.yy68 = createFillNode(pCxt, yymsp[-1].minor.yy94, NULL); } break; - case 199: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ -{ yymsp[-3].minor.yy256 = createFillNode(pCxt, yymsp[-1].minor.yy360, NULL); } + case 211: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ +{ yymsp[-5].minor.yy68 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy40)); } break; - case 200: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ -{ yymsp[-5].minor.yy256 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy46)); } + case 212: /* fill_mode ::= NONE */ +{ yymsp[0].minor.yy94 = FILL_MODE_NONE; } break; - case 201: /* fill_mode ::= NONE */ -{ yymsp[0].minor.yy360 = FILL_MODE_NONE; } + case 213: /* fill_mode ::= PREV */ +{ yymsp[0].minor.yy94 = FILL_MODE_PREV; } break; - case 202: /* fill_mode ::= PREV */ -{ yymsp[0].minor.yy360 = FILL_MODE_PREV; } + case 214: /* fill_mode ::= NULL */ +{ yymsp[0].minor.yy94 = FILL_MODE_NULL; } break; - case 203: /* fill_mode ::= NULL */ -{ yymsp[0].minor.yy360 = FILL_MODE_NULL; } + case 215: /* fill_mode ::= LINEAR */ +{ yymsp[0].minor.yy94 = FILL_MODE_LINEAR; } break; - case 204: /* fill_mode ::= LINEAR */ -{ yymsp[0].minor.yy360 = FILL_MODE_LINEAR; } + case 216: /* fill_mode ::= NEXT */ +{ yymsp[0].minor.yy94 = FILL_MODE_NEXT; } break; - case 205: /* fill_mode ::= NEXT */ -{ yymsp[0].minor.yy360 = FILL_MODE_NEXT; } + case 219: /* group_by_list ::= expression */ +{ yylhsminor.yy40 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } + yymsp[0].minor.yy40 = yylhsminor.yy40; break; - case 208: /* group_by_list ::= expression */ -{ yylhsminor.yy46 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); } - yymsp[0].minor.yy46 = yylhsminor.yy46; + case 220: /* group_by_list ::= group_by_list NK_COMMA expression */ +{ yylhsminor.yy40 = addNodeToList(pCxt, yymsp[-2].minor.yy40, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy68))); } + yymsp[-2].minor.yy40 = yylhsminor.yy40; break; - case 209: /* group_by_list ::= group_by_list NK_COMMA expression */ -{ yylhsminor.yy46 = addNodeToList(pCxt, yymsp[-2].minor.yy46, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy256))); } - yymsp[-2].minor.yy46 = yylhsminor.yy46; - break; - case 212: /* query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ + case 223: /* query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ { - yylhsminor.yy256 = addOrderByClause(pCxt, yymsp[-3].minor.yy256, yymsp[-2].minor.yy46); - yylhsminor.yy256 = addSlimitClause(pCxt, yylhsminor.yy256, yymsp[-1].minor.yy256); - yylhsminor.yy256 = addLimitClause(pCxt, yylhsminor.yy256, yymsp[0].minor.yy256); + yylhsminor.yy68 = addOrderByClause(pCxt, yymsp[-3].minor.yy68, yymsp[-2].minor.yy40); + yylhsminor.yy68 = addSlimitClause(pCxt, yylhsminor.yy68, yymsp[-1].minor.yy68); + yylhsminor.yy68 = addLimitClause(pCxt, yylhsminor.yy68, yymsp[0].minor.yy68); } - yymsp[-3].minor.yy256 = yylhsminor.yy256; + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 214: /* query_expression_body ::= query_expression_body UNION ALL query_expression_body */ -{ yylhsminor.yy256 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy256, yymsp[0].minor.yy256); } - yymsp[-3].minor.yy256 = yylhsminor.yy256; + case 225: /* query_expression_body ::= query_expression_body UNION ALL query_expression_body */ +{ yylhsminor.yy68 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy68, yymsp[0].minor.yy68); } + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 219: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ - case 223: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==223); -{ yymsp[-1].minor.yy256 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } + case 230: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ + case 234: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==234); +{ yymsp[-1].minor.yy68 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } break; - case 220: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - case 224: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==224); -{ yymsp[-3].minor.yy256 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } + case 231: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + case 235: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==235); +{ yymsp[-3].minor.yy68 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 221: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - case 225: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==225); -{ yymsp[-3].minor.yy256 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } + case 232: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + case 236: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==236); +{ yymsp[-3].minor.yy68 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } break; - case 226: /* subquery ::= NK_LP query_expression NK_RP */ -{ yylhsminor.yy256 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy256); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 237: /* subquery ::= NK_LP query_expression NK_RP */ +{ yylhsminor.yy68 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy68); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 227: /* search_condition ::= common_expression */ -{ yylhsminor.yy256 = releaseRawExprNode(pCxt, yymsp[0].minor.yy256); } - yymsp[0].minor.yy256 = yylhsminor.yy256; + case 238: /* search_condition ::= common_expression */ +{ yylhsminor.yy68 = releaseRawExprNode(pCxt, yymsp[0].minor.yy68); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 230: /* sort_specification ::= expression ordering_specification_opt null_ordering_opt */ -{ yylhsminor.yy256 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy256), yymsp[-1].minor.yy202, yymsp[0].minor.yy147); } - yymsp[-2].minor.yy256 = yylhsminor.yy256; + case 241: /* sort_specification ::= expression ordering_specification_opt null_ordering_opt */ +{ yylhsminor.yy68 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy68), yymsp[-1].minor.yy54, yymsp[0].minor.yy53); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 231: /* ordering_specification_opt ::= */ -{ yymsp[1].minor.yy202 = ORDER_ASC; } + case 242: /* ordering_specification_opt ::= */ +{ yymsp[1].minor.yy54 = ORDER_ASC; } break; - case 232: /* ordering_specification_opt ::= ASC */ -{ yymsp[0].minor.yy202 = ORDER_ASC; } + case 243: /* ordering_specification_opt ::= ASC */ +{ yymsp[0].minor.yy54 = ORDER_ASC; } break; - case 233: /* ordering_specification_opt ::= DESC */ -{ yymsp[0].minor.yy202 = ORDER_DESC; } + case 244: /* ordering_specification_opt ::= DESC */ +{ yymsp[0].minor.yy54 = ORDER_DESC; } break; - case 234: /* null_ordering_opt ::= */ -{ yymsp[1].minor.yy147 = NULL_ORDER_DEFAULT; } + case 245: /* null_ordering_opt ::= */ +{ yymsp[1].minor.yy53 = NULL_ORDER_DEFAULT; } break; - case 235: /* null_ordering_opt ::= NULLS FIRST */ -{ yymsp[-1].minor.yy147 = NULL_ORDER_FIRST; } + case 246: /* null_ordering_opt ::= NULLS FIRST */ +{ yymsp[-1].minor.yy53 = NULL_ORDER_FIRST; } break; - case 236: /* null_ordering_opt ::= NULLS LAST */ -{ yymsp[-1].minor.yy147 = NULL_ORDER_LAST; } + case 247: /* null_ordering_opt ::= NULLS LAST */ +{ yymsp[-1].minor.yy53 = NULL_ORDER_LAST; } break; default: break; diff --git a/source/libs/parser/test/parserAstTest.cpp b/source/libs/parser/test/parserAstTest.cpp index f9a2bafe10..259c4712ba 100644 --- a/source/libs/parser/test/parserAstTest.cpp +++ b/source/libs/parser/test/parserAstTest.cpp @@ -183,6 +183,13 @@ TEST_F(ParserTest, selectClause) { ASSERT_TRUE(run()); } +TEST_F(ParserTest, selectWindow) { + setDatabase("root", "test"); + + bind("SELECT count(*) FROM t1 interval(10s)"); + ASSERT_TRUE(run()); +} + TEST_F(ParserTest, selectSyntaxError) { setDatabase("root", "test"); @@ -391,3 +398,17 @@ TEST_F(ParserTest, createTable) { ); ASSERT_TRUE(run()); } + +TEST_F(ParserTest, createSmaIndex) { + setDatabase("root", "test"); + + bind("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)"); + ASSERT_TRUE(run()); +} + +TEST_F(ParserTest, createQnode) { + setDatabase("root", "test"); + + bind("create qnode on dnode 1"); + ASSERT_TRUE(run()); +} diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index a93985e8ba..3fae580de9 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -304,6 +304,53 @@ static SLogicNode* createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSel return (SLogicNode*)pAgg; } +static SLogicNode* createWindowLogicNodeByInterval(SLogicPlanContext* pCxt, SIntervalWindowNode* pInterval, SSelectStmt* pSelect) { + SWindowLogicNode* pWindow = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW); + CHECK_ALLOC(pWindow, NULL); + pWindow->node.id = pCxt->planNodeId++; + + pWindow->winType = WINDOW_TYPE_INTERVAL; + SValueNode* pIntervalNode = (SValueNode*)((SRawExprNode*)(pInterval->pInterval))->pNode; + + pWindow->interval = pIntervalNode->datum.i; + pWindow->offset = (NULL != pInterval->pOffset ? ((SValueNode*)pInterval->pOffset)->datum.i : 0); + pWindow->sliding = (NULL != pInterval->pSliding ? ((SValueNode*)pInterval->pSliding)->datum.i : pWindow->interval); + + if (NULL != pInterval->pFill) { + pWindow->pFill = nodesCloneNode(pInterval->pFill); + CHECK_ALLOC(pWindow->pFill, (SLogicNode*)pWindow); + } + + SNodeList* pFuncs = NULL; + CHECK_CODE(nodesCollectFuncs(pSelect, fmIsAggFunc, &pFuncs), NULL); + if (NULL != pFuncs) { + pWindow->pFuncs = nodesCloneList(pFuncs); + CHECK_ALLOC(pWindow->pFuncs, (SLogicNode*)pWindow); + } + + CHECK_CODE(rewriteExpr(pWindow->node.id, 1, pWindow->pFuncs, pSelect, SQL_CLAUSE_WINDOW), (SLogicNode*)pWindow); + + pWindow->node.pTargets = createColumnByRewriteExps(pCxt, pWindow->pFuncs); + CHECK_ALLOC(pWindow->node.pTargets, (SLogicNode*)pWindow); + + return (SLogicNode*)pWindow; +} + +static SLogicNode* createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect) { + if (NULL == pSelect->pWindow) { + return NULL; + } + + switch (nodeType(pSelect->pWindow)) { + case QUERY_NODE_INTERVAL_WINDOW: + return createWindowLogicNodeByInterval(pCxt, (SIntervalWindowNode*)pSelect->pWindow, pSelect); + default: + break; + } + + return NULL; +} + static SNodeList* createColumnByProjections(SLogicPlanContext* pCxt, SNodeList* pExprs) { SNodeList* pList = nodesMakeList(); CHECK_ALLOC(pList, NULL); @@ -345,6 +392,9 @@ static SLogicNode* createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* p pRoot->pConditions = nodesCloneNode(pSelect->pWhere); CHECK_ALLOC(pRoot->pConditions, pRoot); } + if (TSDB_CODE_SUCCESS == pCxt->errCode) { + pRoot = pushLogicNode(pCxt, pRoot, createWindowLogicNode(pCxt, pSelect)); + } if (TSDB_CODE_SUCCESS == pCxt->errCode) { pRoot = pushLogicNode(pCxt, pRoot, createAggLogicNode(pCxt, pSelect)); } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 5af26b3e32..0affd93f4d 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -473,14 +473,61 @@ static SPhysiNode* createExchangePhysiNode(SPhysiPlanContext* pCxt, SExchangeLog return (SPhysiNode*)pExchange; } +static SPhysiNode* createIntervalPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SWindowLogicNode* pWindowLogicNode) { + SIntervalPhysiNode* pInterval = (SIntervalPhysiNode*)makePhysiNode(pCxt, QUERY_NODE_PHYSICAL_PLAN_INTERVAL); + CHECK_ALLOC(pInterval, NULL); + + pInterval->interval = pWindowLogicNode->interval; + pInterval->offset = pWindowLogicNode->offset; + pInterval->sliding = pWindowLogicNode->sliding; + pInterval->intervalUnit = pWindowLogicNode->intervalUnit; + pInterval->slidingUnit = pWindowLogicNode->slidingUnit; + + pInterval->pFill = nodesCloneNode(pWindowLogicNode->pFill); + + SNodeList* pPrecalcExprs = NULL; + SNodeList* pFuncs = NULL; + CHECK_CODE(rewritePrecalcExprs(pCxt, pWindowLogicNode->pFuncs, &pPrecalcExprs, &pFuncs), (SPhysiNode*)pInterval); + + SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc); + // push down expression to pOutputDataBlockDesc of child node + if (NULL != pPrecalcExprs) { + pInterval->pExprs = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pPrecalcExprs); + CHECK_ALLOC(pInterval->pExprs, (SPhysiNode*)pInterval); + CHECK_CODE(addDataBlockDesc(pCxt, pInterval->pExprs, pChildTupe), (SPhysiNode*)pInterval); + } + + if (NULL != pFuncs) { + pInterval->pFuncs = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFuncs); + CHECK_ALLOC(pInterval->pFuncs, (SPhysiNode*)pInterval); + CHECK_CODE(addDataBlockDesc(pCxt, pInterval->pFuncs, pInterval->node.pOutputDataBlockDesc), (SPhysiNode*)pInterval); + } + + CHECK_CODE(setSlotOutput(pCxt, pWindowLogicNode->node.pTargets, pInterval->node.pOutputDataBlockDesc), (SPhysiNode*)pInterval); + + return (SPhysiNode*)pInterval; +} + +static SPhysiNode* createWindowPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SWindowLogicNode* pWindowLogicNode) { + switch (pWindowLogicNode->winType) { + case WINDOW_TYPE_INTERVAL: + return createIntervalPhysiNode(pCxt, pChildren, pWindowLogicNode); + case WINDOW_TYPE_SESSION: + case WINDOW_TYPE_STATE: + break; + default: + break; + } + return NULL; +} + static SPhysiNode* createPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SLogicNode* pLogicPlan) { SNodeList* pChildren = nodesMakeList(); CHECK_ALLOC(pChildren, NULL); SNode* pLogicChild; FOREACH(pLogicChild, pLogicPlan->pChildren) { - SNode* pChildPhyNode = (SNode*)createPhysiNode(pCxt, pSubplan, (SLogicNode*)pLogicChild); - if (TSDB_CODE_SUCCESS != nodesListAppend(pChildren, pChildPhyNode)) { + if (TSDB_CODE_SUCCESS != nodesListStrictAppend(pChildren, createPhysiNode(pCxt, pSubplan, (SLogicNode*)pLogicChild))) { pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; nodesDestroyList(pChildren); return NULL; @@ -504,6 +551,9 @@ static SPhysiNode* createPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, case QUERY_NODE_LOGIC_PLAN_EXCHANGE: pPhyNode = createExchangePhysiNode(pCxt, (SExchangeLogicNode*)pLogicPlan); break; + case QUERY_NODE_LOGIC_PLAN_WINDOW: + pPhyNode = createWindowPhysiNode(pCxt, pChildren, (SWindowLogicNode*)pLogicPlan); + break; default: break; } diff --git a/source/libs/planner/test/plannerTest.cpp b/source/libs/planner/test/plannerTest.cpp index 1af89d71c9..8baa64d8fb 100644 --- a/source/libs/planner/test/plannerTest.cpp +++ b/source/libs/planner/test/plannerTest.cpp @@ -166,3 +166,10 @@ TEST_F(PlannerTest, subquery) { bind("SELECT count(*) FROM (SELECT c1 + c3 a, c1 + count(*) b FROM t1 where c2 = 'abc' GROUP BY c1, c3) where a > 100 group by b"); ASSERT_TRUE(run()); } + +TEST_F(PlannerTest, interval) { + setDatabase("root", "test"); + + bind("SELECT count(*) FROM t1 interval(10s)"); + ASSERT_TRUE(run()); +} diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index ebe70ca401..6b1ca25d93 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -13,26 +13,21 @@ * along with this program. If not, see . */ +#include "catalog.h" +#include "query.h" #include "schedulerInt.h" #include "tmsg.h" -#include "query.h" -#include "catalog.h" #include "tref.h" SSchedulerMgmt schMgmt = {0}; -FORCE_INLINE SSchJob *schAcquireJob(int64_t refId) { - return (SSchJob *)taosAcquireRef(schMgmt.jobRef, refId); -} +FORCE_INLINE SSchJob *schAcquireJob(int64_t refId) { return (SSchJob *)taosAcquireRef(schMgmt.jobRef, refId); } -FORCE_INLINE int32_t schReleaseJob(int64_t refId) { - return taosReleaseRef(schMgmt.jobRef, refId); -} +FORCE_INLINE int32_t schReleaseJob(int64_t refId) { return taosReleaseRef(schMgmt.jobRef, refId); } -uint64_t schGenTaskId(void) { - return atomic_add_fetch_64(&schMgmt.taskId, 1); -} +uint64_t schGenTaskId(void) { return atomic_add_fetch_64(&schMgmt.taskId, 1); } +#if 0 uint64_t schGenUUID(void) { static uint64_t hashId = 0; static int32_t requestSerialId = 0; @@ -54,11 +49,11 @@ uint64_t schGenUUID(void) { uint64_t id = ((hashId & 0x0FFF) << 52) | ((pid & 0x0FFF) << 40) | ((ts & 0xFFFFFF) << 16) | (val & 0xFFFF); return id; } +#endif - -int32_t schInitTask(SSchJob* pJob, SSchTask *pTask, SSubplan* pPlan, SSchLevel *pLevel) { - pTask->plan = pPlan; - pTask->level = pLevel; +int32_t schInitTask(SSchJob *pJob, SSchTask *pTask, SSubplan *pPlan, SSchLevel *pLevel) { + pTask->plan = pPlan; + pTask->level = pLevel; SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_NOT_START); pTask->taskId = schGenTaskId(); pTask->execAddrs = taosArrayInit(SCH_MAX_CANDIDATE_EP_NUM, sizeof(SQueryNodeAddr)); @@ -70,7 +65,7 @@ int32_t schInitTask(SSchJob* pJob, SSchTask *pTask, SSubplan* pPlan, SSchLevel * return TSDB_CODE_SUCCESS; } -void schFreeTask(SSchTask* pTask) { +void schFreeTask(SSchTask *pTask) { if (pTask->candidateAddrs) { taosArrayDestroy(pTask->candidateAddrs); } @@ -90,22 +85,20 @@ void schFreeTask(SSchTask* pTask) { } } - static FORCE_INLINE bool schJobNeedToStop(SSchJob *pJob, int8_t *pStatus) { int8_t status = SCH_GET_JOB_STATUS(pJob); if (pStatus) { *pStatus = status; } - return (status == JOB_TASK_STATUS_FAILED || status == JOB_TASK_STATUS_CANCELLED - || status == JOB_TASK_STATUS_CANCELLING || status == JOB_TASK_STATUS_DROPPING - || status == JOB_TASK_STATUS_SUCCEED); + return (status == JOB_TASK_STATUS_FAILED || status == JOB_TASK_STATUS_CANCELLED || + status == JOB_TASK_STATUS_CANCELLING || status == JOB_TASK_STATUS_DROPPING || + status == JOB_TASK_STATUS_SUCCEED); } - int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgType) { int32_t lastMsgType = SCH_GET_TASK_LASTMSG_TYPE(pTask); - + switch (msgType) { case TDMT_VND_CREATE_TABLE_RSP: case TDMT_VND_SUBMIT_RSP: @@ -114,19 +107,22 @@ int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t m case TDMT_VND_FETCH_RSP: case TDMT_VND_DROP_TASK: if (lastMsgType != (msgType - 1)) { - SCH_TASK_ELOG("rsp msg type mis-match, last sent msgType:%s, rspType:%s", TMSG_INFO(lastMsgType), TMSG_INFO(msgType)); + SCH_TASK_ELOG("rsp msg type mis-match, last sent msgType:%s, rspType:%s", TMSG_INFO(lastMsgType), + TMSG_INFO(msgType)); SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); } - if (SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_EXECUTING && SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_PARTIAL_SUCCEED) { - SCH_TASK_ELOG("rsp msg conflicted with task status, status:%d, rspType:%s", SCH_GET_TASK_STATUS(pTask), TMSG_INFO(msgType)); + if (SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_EXECUTING && + SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_PARTIAL_SUCCEED) { + SCH_TASK_ELOG("rsp msg conflicted with task status, status:%d, rspType:%s", SCH_GET_TASK_STATUS(pTask), + TMSG_INFO(msgType)); SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); } break; default: SCH_TASK_ELOG("unknown rsp msg, type:%s, status:%d", TMSG_INFO(msgType), SCH_GET_TASK_STATUS(pTask)); - + SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } @@ -135,7 +131,6 @@ int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t m return TSDB_CODE_SUCCESS; } - int32_t schCheckAndUpdateJobStatus(SSchJob *pJob, int8_t newStatus) { int32_t code = 0; @@ -147,37 +142,34 @@ int32_t schCheckAndUpdateJobStatus(SSchJob *pJob, int8_t newStatus) { if (oriStatus == newStatus) { SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); } - + switch (oriStatus) { case JOB_TASK_STATUS_NULL: if (newStatus != JOB_TASK_STATUS_NOT_START) { SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); } - + break; case JOB_TASK_STATUS_NOT_START: if (newStatus != JOB_TASK_STATUS_EXECUTING) { SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); } - + break; case JOB_TASK_STATUS_EXECUTING: - if (newStatus != JOB_TASK_STATUS_PARTIAL_SUCCEED - && newStatus != JOB_TASK_STATUS_FAILED - && newStatus != JOB_TASK_STATUS_CANCELLING - && newStatus != JOB_TASK_STATUS_CANCELLED - && newStatus != JOB_TASK_STATUS_DROPPING) { + if (newStatus != JOB_TASK_STATUS_PARTIAL_SUCCEED && newStatus != JOB_TASK_STATUS_FAILED && + newStatus != JOB_TASK_STATUS_CANCELLING && newStatus != JOB_TASK_STATUS_CANCELLED && + newStatus != JOB_TASK_STATUS_DROPPING) { SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); } - + break; case JOB_TASK_STATUS_PARTIAL_SUCCEED: - if (newStatus != JOB_TASK_STATUS_FAILED - && newStatus != JOB_TASK_STATUS_SUCCEED - && newStatus != JOB_TASK_STATUS_DROPPING) { + if (newStatus != JOB_TASK_STATUS_FAILED && newStatus != JOB_TASK_STATUS_SUCCEED && + newStatus != JOB_TASK_STATUS_DROPPING) { SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); } - + break; case JOB_TASK_STATUS_SUCCEED: case JOB_TASK_STATUS_FAILED: @@ -185,13 +177,13 @@ int32_t schCheckAndUpdateJobStatus(SSchJob *pJob, int8_t newStatus) { if (newStatus != JOB_TASK_STATUS_DROPPING) { SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); } - + break; case JOB_TASK_STATUS_CANCELLED: case JOB_TASK_STATUS_DROPPING: SCH_ERR_JRET(TSDB_CODE_QRY_JOB_FREED); break; - + default: SCH_JOB_ELOG("invalid job status:%d", oriStatus); SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); @@ -211,27 +203,26 @@ int32_t schCheckAndUpdateJobStatus(SSchJob *pJob, int8_t newStatus) { _return: SCH_JOB_ELOG("invalid job status update, from %d to %d", oriStatus, newStatus); - + SCH_ERR_RET(code); } - int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) { for (int32_t i = 0; i < pJob->levelNum; ++i) { SSchLevel *pLevel = taosArrayGet(pJob->levels, i); - + for (int32_t m = 0; m < pLevel->taskNum; ++m) { SSchTask *pTask = taosArrayGet(pLevel->subTasks, m); SSubplan *pPlan = pTask->plan; - int32_t childNum = pPlan->pChildren ? (int32_t)LIST_LENGTH(pPlan->pChildren) : 0; - int32_t parentNum = pPlan->pParents ? (int32_t)LIST_LENGTH(pPlan->pParents) : 0; + int32_t childNum = pPlan->pChildren ? (int32_t)LIST_LENGTH(pPlan->pChildren) : 0; + int32_t parentNum = pPlan->pParents ? (int32_t)LIST_LENGTH(pPlan->pParents) : 0; if (childNum > 0) { if (pJob->levelIdx == pLevel->level) { SCH_JOB_ELOG("invalid query plan, lowest level, childNum:%d", childNum); SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); } - + pTask->children = taosArrayInit(childNum, POINTER_BYTES); if (NULL == pTask->children) { SCH_TASK_ELOG("taosArrayInit %d children failed", childNum); @@ -240,7 +231,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) { } for (int32_t n = 0; n < childNum; ++n) { - SSubplan *child = (SSubplan*)nodesListGetNode(pPlan->pChildren, n); + SSubplan *child = (SSubplan *)nodesListGetNode(pPlan->pChildren, n); SSchTask **childTask = taosHashGet(planToTask, &child, POINTER_BYTES); if (NULL == childTask || NULL == *childTask) { SCH_TASK_ELOG("subplan children relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n); @@ -258,7 +249,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) { SCH_TASK_ELOG("invalid task info, level:0, parentNum:%d", parentNum); SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); } - + pTask->parents = taosArrayInit(parentNum, POINTER_BYTES); if (NULL == pTask->parents) { SCH_TASK_ELOG("taosArrayInit %d parents failed", parentNum); @@ -272,7 +263,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) { } for (int32_t n = 0; n < parentNum; ++n) { - SSubplan *parent = (SSubplan*)nodesListGetNode(pPlan->pParents, n); + SSubplan *parent = (SSubplan *)nodesListGetNode(pPlan->pParents, n); SSchTask **parentTask = taosHashGet(planToTask, &parent, POINTER_BYTES); if (NULL == parentTask || NULL == *parentTask) { SCH_TASK_ELOG("subplan parent relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n); @@ -283,7 +274,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) { SCH_TASK_ELOG("taosArrayPush parentTask failed, level:%d, taskIdx:%d, childIdx:%d", i, m, n); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - } + } SCH_TASK_DLOG("level:%d, parentNum:%d, childNum:%d", i, parentNum, childNum); } @@ -298,11 +289,11 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) { return TSDB_CODE_SUCCESS; } - int32_t schRecordTaskSucceedNode(SSchJob *pJob, SSchTask *pTask) { SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); if (NULL == addr) { - SCH_TASK_ELOG("taosArrayGet candidate addr failed, idx:%d, size:%d", pTask->candidateIdx, (int32_t)taosArrayGetSize(pTask->candidateAddrs)); + SCH_TASK_ELOG("taosArrayGet candidate addr failed, idx:%d, size:%d", pTask->candidateIdx, + (int32_t)taosArrayGetSize(pTask->candidateAddrs)); SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); } @@ -311,7 +302,6 @@ int32_t schRecordTaskSucceedNode(SSchJob *pJob, SSchTask *pTask) { return TSDB_CODE_SUCCESS; } - int32_t schRecordTaskExecNode(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr) { if (NULL == taosArrayPush(pTask->execAddrs, addr)) { SCH_TASK_ELOG("taosArrayPush addr to execAddr list failed, errno:%d", errno); @@ -321,23 +311,25 @@ int32_t schRecordTaskExecNode(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *ad return TSDB_CODE_SUCCESS; } - int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) { int32_t code = 0; pJob->queryId = pDag->queryId; - + if (pDag->numOfSubplans <= 0) { SCH_JOB_ELOG("invalid subplan num:%d", pDag->numOfSubplans); SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - + int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans); if (levelNum <= 0) { SCH_JOB_ELOG("invalid level num:%d", levelNum); SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - SHashObj *planToTask = taosHashInit(SCHEDULE_DEFAULT_MAX_TASK_NUM, taosGetDefaultHashFunction(POINTER_BYTES == sizeof(int64_t) ? TSDB_DATA_TYPE_BIGINT : TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); + SHashObj *planToTask = taosHashInit( + SCHEDULE_DEFAULT_MAX_TASK_NUM, + taosGetDefaultHashFunction(POINTER_BYTES == sizeof(int64_t) ? TSDB_DATA_TYPE_BIGINT : TSDB_DATA_TYPE_INT), false, + HASH_NO_LOCK); if (NULL == planToTask) { SCH_JOB_ELOG("taosHashInit %d failed", SCHEDULE_DEFAULT_MAX_TASK_NUM); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -354,10 +346,10 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) { pJob->subPlans = pDag->pSubplans; - SSchLevel level = {0}; + SSchLevel level = {0}; SNodeListNode *plans = NULL; - int32_t taskNum = 0; - SSchLevel *pLevel = NULL; + int32_t taskNum = 0; + SSchLevel *pLevel = NULL; level.status = JOB_TASK_STATUS_NOT_START; @@ -369,8 +361,8 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) { pLevel = taosArrayGet(pJob->levels, i); pLevel->level = i; - - plans = (SNodeListNode*)nodesListGetNode(pDag->pSubplans, i); + + plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i); if (NULL == plans) { SCH_JOB_ELOG("empty level plan, level:%d", i); SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); @@ -383,15 +375,15 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) { } pLevel->taskNum = taskNum; - + pLevel->subTasks = taosArrayInit(taskNum, sizeof(SSchTask)); if (NULL == pLevel->subTasks) { SCH_JOB_ELOG("taosArrayInit %d failed", taskNum); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - + for (int32_t n = 0; n < taskNum; ++n) { - SSubplan *plan = (SSubplan*)nodesListGetNode(plans->pNodeList, n); + SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n); SCH_SET_JOB_TYPE(pJob, plan->subplanType); @@ -399,13 +391,13 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) { SSchTask *pTask = &task; SCH_ERR_JRET(schInitTask(pJob, &task, plan, pLevel)); - + void *p = taosArrayPush(pLevel->subTasks, &task); if (NULL == p) { SCH_TASK_ELOG("taosArrayPush task to level failed, level:%d, taskIdx:%d", pLevel->level, n); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - + if (0 != taosHashPut(planToTask, &plan, POINTER_BYTES, &p, POINTER_BYTES)) { SCH_TASK_ELOG("taosHashPut to planToTaks failed, taskIdx:%d", n); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -452,10 +444,10 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) { int32_t nodeNum = 0; if (pJob->nodeList) { nodeNum = taosArrayGetSize(pJob->nodeList); - + for (int32_t i = 0; i < nodeNum && addNum < SCH_MAX_CANDIDATE_EP_NUM; ++i) { SQueryNodeAddr *naddr = taosArrayGet(pJob->nodeList, i); - + if (NULL == taosArrayPush(pTask->candidateAddrs, naddr)) { SCH_TASK_ELOG("taosArrayPush execNode to candidate addrs failed, addNum:%d, errno:%d", addNum, errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -470,14 +462,14 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) { return TSDB_CODE_QRY_INVALID_INPUT; } -/* - for (int32_t i = 0; i < job->dataSrcEps.numOfEps && addNum < SCH_MAX_CANDIDATE_EP_NUM; ++i) { - strncpy(epSet->fqdn[epSet->numOfEps], job->dataSrcEps.fqdn[i], sizeof(job->dataSrcEps.fqdn[i])); - epSet->port[epSet->numOfEps] = job->dataSrcEps.port[i]; - - ++epSet->numOfEps; - } -*/ + /* + for (int32_t i = 0; i < job->dataSrcEps.numOfEps && addNum < SCH_MAX_CANDIDATE_EP_NUM; ++i) { + strncpy(epSet->fqdn[epSet->numOfEps], job->dataSrcEps.fqdn[i], sizeof(job->dataSrcEps.fqdn[i])); + epSet->port[epSet->numOfEps] = job->dataSrcEps.port[i]; + + ++epSet->numOfEps; + } + */ return TSDB_CODE_SUCCESS; } @@ -489,7 +481,7 @@ int32_t schPushTaskToExecList(SSchJob *pJob, SSchTask *pTask) { SCH_TASK_ELOG("task already in execTask list, code:%x", code); SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); } - + SCH_TASK_ELOG("taosHashPut task to execTask list failed, errno:%d", errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -510,11 +502,11 @@ int32_t schMoveTaskToSuccList(SSchJob *pJob, SSchTask *pTask, bool *moved) { if (0 != code) { if (HASH_NODE_EXIST(code)) { *moved = true; - + SCH_TASK_ELOG("task already in succTask list, status:%d", SCH_GET_TASK_STATUS(pTask)); SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); } - + SCH_TASK_ELOG("taosHashPut task to succTask list failed, errno:%d", errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -522,13 +514,13 @@ int32_t schMoveTaskToSuccList(SSchJob *pJob, SSchTask *pTask, bool *moved) { *moved = true; SCH_TASK_DLOG("task moved to succTask list, numOfTasks:%d", taosHashGetSize(pJob->succTasks)); - + return TSDB_CODE_SUCCESS; } int32_t schMoveTaskToFailList(SSchJob *pJob, SSchTask *pTask, bool *moved) { *moved = false; - + if (0 != taosHashRemove(pJob->execTasks, &pTask->taskId, sizeof(pTask->taskId))) { SCH_TASK_WLOG("remove task from execTask list failed, may not exist, status:%d", SCH_GET_TASK_STATUS(pTask)); } @@ -537,11 +529,11 @@ int32_t schMoveTaskToFailList(SSchJob *pJob, SSchTask *pTask, bool *moved) { if (0 != code) { if (HASH_NODE_EXIST(code)) { *moved = true; - + SCH_TASK_WLOG("task already in failTask list, status:%d", SCH_GET_TASK_STATUS(pTask)); SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); } - + SCH_TASK_ELOG("taosHashPut task to failTask list failed, errno:%d", errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -549,11 +541,10 @@ int32_t schMoveTaskToFailList(SSchJob *pJob, SSchTask *pTask, bool *moved) { *moved = true; SCH_TASK_DLOG("task moved to failTask list, numOfTasks:%d", taosHashGetSize(pJob->failTasks)); - + return TSDB_CODE_SUCCESS; } - int32_t schMoveTaskToExecList(SSchJob *pJob, SSchTask *pTask, bool *moved) { if (0 != taosHashRemove(pJob->succTasks, &pTask->taskId, sizeof(pTask->taskId))) { SCH_TASK_WLOG("remove task from succTask list failed, may not exist, status:%d", SCH_GET_TASK_STATUS(pTask)); @@ -563,11 +554,11 @@ int32_t schMoveTaskToExecList(SSchJob *pJob, SSchTask *pTask, bool *moved) { if (0 != code) { if (HASH_NODE_EXIST(code)) { *moved = true; - + SCH_TASK_ELOG("task already in execTask list, status:%d", SCH_GET_TASK_STATUS(pTask)); SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); } - + SCH_TASK_ELOG("taosHashPut task to execTask list failed, errno:%d", errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -575,11 +566,10 @@ int32_t schMoveTaskToExecList(SSchJob *pJob, SSchTask *pTask, bool *moved) { *moved = true; SCH_TASK_DLOG("task moved to execTask list, numOfTasks:%d", taosHashGetSize(pJob->execTasks)); - + return TSDB_CODE_SUCCESS; } - int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bool *needRetry) { // TODO set retry or not based on task type/errCode/retry times/job status/available eps... @@ -587,20 +577,17 @@ int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bo return TSDB_CODE_SUCCESS; - //TODO CHECK epList/condidateList + // TODO CHECK epList/condidateList if (SCH_IS_DATA_SRC_TASK(pTask)) { - } else { int32_t candidateNum = taosArrayGetSize(pTask->candidateAddrs); - + if ((pTask->candidateIdx + 1) >= candidateNum) { return TSDB_CODE_SUCCESS; } ++pTask->candidateIdx; } - - } int32_t schHandleTaskRetry(SSchJob *pJob, SSchTask *pTask) { @@ -623,9 +610,9 @@ int32_t schHandleTaskRetry(SSchJob *pJob, SSchTask *pTask) { } int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchHbTrans *trans) { - int32_t code = 0; + int32_t code = 0; SSchHbTrans *hb = NULL; - + while (true) { hb = taosHashGet(schMgmt.hbConnections, epId, sizeof(SQueryNodeEpId)); if (NULL == hb) { @@ -639,9 +626,11 @@ int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchHbTrans *trans) { SCH_ERR_RET(code); } - qDebug("hb connection updated, seqId:%" PRIx64 ", sId:%" PRIx64 ", nodeId:%d, fqdn:%s, port:%d, instance:%p, connection:%p", - trans->seqId, schMgmt.sId, epId->nodeId, epId->ep.fqdn, epId->ep.port, trans->trans.transInst, trans->trans.transHandle); - + qDebug("hb connection updated, seqId:%" PRIx64 ", sId:%" PRIx64 + ", nodeId:%d, fqdn:%s, port:%d, instance:%p, connection:%p", + trans->seqId, schMgmt.sId, epId->nodeId, epId->ep.fqdn, epId->ep.port, trans->trans.transInst, + trans->trans.transHandle); + return TSDB_CODE_SUCCESS; } @@ -649,11 +638,11 @@ int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchHbTrans *trans) { } SCH_LOCK(SCH_WRITE, &hb->lock); - + if (hb->seqId >= trans->seqId) { - qDebug("hb trans seqId is old, seqId:%" PRId64 ", currentId:%" PRId64 ", nodeId:%d, fqdn:%s, port:%d", - trans->seqId, hb->seqId, epId->nodeId, epId->ep.fqdn, epId->ep.port); - + qDebug("hb trans seqId is old, seqId:%" PRId64 ", currentId:%" PRId64 ", nodeId:%d, fqdn:%s, port:%d", trans->seqId, + hb->seqId, epId->nodeId, epId->ep.fqdn, epId->ep.port); + SCH_UNLOCK(SCH_WRITE, &hb->lock); return TSDB_CODE_SUCCESS; } @@ -663,16 +652,18 @@ int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchHbTrans *trans) { SCH_UNLOCK(SCH_WRITE, &hb->lock); - qDebug("hb connection updated, seqId:%" PRIx64 ", sId:%" PRIx64 ", nodeId:%d, fqdn:%s, port:%d, instance:%p, connection:%p", - trans->seqId, schMgmt.sId, epId->nodeId, epId->ep.fqdn, epId->ep.port, trans->trans.transInst, trans->trans.transHandle); - + qDebug("hb connection updated, seqId:%" PRIx64 ", sId:%" PRIx64 + ", nodeId:%d, fqdn:%s, port:%d, instance:%p, connection:%p", + trans->seqId, schMgmt.sId, epId->nodeId, epId->ep.fqdn, epId->ep.port, trans->trans.transInst, + trans->trans.transHandle); + return TSDB_CODE_SUCCESS; } int32_t schProcessOnJobFailureImpl(SSchJob *pJob, int32_t status, int32_t errCode) { // if already FAILED, no more processing SCH_ERR_RET(schCheckAndUpdateJobStatus(pJob, status)); - + if (errCode) { atomic_store_32(&pJob->errCode, errCode); } @@ -684,11 +675,10 @@ int32_t schProcessOnJobFailureImpl(SSchJob *pJob, int32_t status, int32_t errCod int32_t code = atomic_load_32(&pJob->errCode); SCH_JOB_DLOG("job failed with error: %s", tstrerror(code)); - + SCH_RET(code); } - // Note: no more task error processing, handled in function internal int32_t schProcessOnJobFailure(SSchJob *pJob, int32_t errCode) { SCH_RET(schProcessOnJobFailureImpl(pJob, JOB_TASK_STATUS_FAILED, errCode)); @@ -699,18 +689,16 @@ int32_t schProcessOnJobDropped(SSchJob *pJob, int32_t errCode) { SCH_RET(schProcessOnJobFailureImpl(pJob, JOB_TASK_STATUS_DROPPING, errCode)); } - - // Note: no more task error processing, handled in function internal int32_t schProcessOnJobPartialSuccess(SSchJob *pJob) { int32_t code = 0; - + SCH_ERR_RET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_PARTIAL_SUCCEED)); if (pJob->attr.syncSchedule) { tsem_post(&pJob->rspSem); } - + if (atomic_load_8(&pJob->userFetch)) { SCH_ERR_JRET(schFetchFromRemote(pJob)); } @@ -730,22 +718,22 @@ int32_t schProcessOnDataFetched(SSchJob *job) { // Note: no more task error processing, handled in function internal int32_t schProcessOnTaskFailure(SSchJob *pJob, SSchTask *pTask, int32_t errCode) { int8_t status = 0; - + if (schJobNeedToStop(pJob, &status)) { SCH_TASK_DLOG("task failed not processed cause of job status, job status:%d", status); - + SCH_RET(atomic_load_32(&pJob->errCode)); } - bool needRetry = false; - bool moved = false; + bool needRetry = false; + bool moved = false; int32_t taskDone = 0; int32_t code = 0; SCH_TASK_DLOG("taskOnFailure, code:%s", tstrerror(errCode)); - + SCH_ERR_JRET(schTaskCheckSetRetry(pJob, pTask, errCode, &needRetry)); - + if (!needRetry) { SCH_TASK_ELOG("task failed and no more retry, code:%s", tstrerror(errCode)); @@ -757,7 +745,7 @@ int32_t schProcessOnTaskFailure(SSchJob *pJob, SSchTask *pTask, int32_t errCode) } SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_FAILED); - + if (SCH_TASK_NEED_WAIT_ALL(pTask)) { SCH_LOCK(SCH_WRITE, &pTask->level->lock); pTask->level->taskFailed++; @@ -765,7 +753,7 @@ int32_t schProcessOnTaskFailure(SSchJob *pJob, SSchTask *pTask, int32_t errCode) SCH_UNLOCK(SCH_WRITE, &pTask->level->lock); atomic_store_32(&pJob->errCode, errCode); - + if (taskDone < pTask->level->taskNum) { SCH_TASK_DLOG("not all tasks done, done:%d, all:%d", taskDone, pTask->level->taskNum); SCH_ERR_RET(errCode); @@ -773,7 +761,7 @@ int32_t schProcessOnTaskFailure(SSchJob *pJob, SSchTask *pTask, int32_t errCode) } } else { SCH_ERR_JRET(schHandleTaskRetry(pJob, pTask)); - + return TSDB_CODE_SUCCESS; } @@ -784,7 +772,7 @@ _return: // Note: no more task error processing, handled in function internal int32_t schProcessOnTaskSuccess(SSchJob *pJob, SSchTask *pTask) { - bool moved = false; + bool moved = false; int32_t code = 0; SCH_TASK_DLOG("taskOnSuccess, status:%d", SCH_GET_TASK_STATUS(pTask)); @@ -796,17 +784,17 @@ int32_t schProcessOnTaskSuccess(SSchJob *pJob, SSchTask *pTask) { SCH_ERR_JRET(schRecordTaskSucceedNode(pJob, pTask)); SCH_ERR_JRET(schLaunchTasksInFlowCtrlList(pJob, pTask)); - + int32_t parentNum = pTask->parents ? (int32_t)taosArrayGetSize(pTask->parents) : 0; if (parentNum == 0) { int32_t taskDone = 0; - + if (SCH_TASK_NEED_WAIT_ALL(pTask)) { SCH_LOCK(SCH_WRITE, &pTask->level->lock); pTask->level->taskSucceed++; taskDone = pTask->level->taskSucceed + pTask->level->taskFailed; SCH_UNLOCK(SCH_WRITE, &pTask->level->lock); - + if (taskDone < pTask->level->taskNum) { SCH_TASK_DLOG("wait all tasks, done:%d, all:%d", taskDone, pTask->level->taskNum); return TSDB_CODE_SUCCESS; @@ -826,28 +814,31 @@ int32_t schProcessOnTaskSuccess(SSchJob *pJob, SSchTask *pTask) { pJob->fetchTask = pTask; SCH_ERR_JRET(schMoveTaskToExecList(pJob, pTask, &moved)); - + SCH_RET(schProcessOnJobPartialSuccess(pJob)); } -/* - if (SCH_IS_DATA_SRC_TASK(task) && job->dataSrcEps.numOfEps < SCH_MAX_CANDIDATE_EP_NUM) { - strncpy(job->dataSrcEps.fqdn[job->dataSrcEps.numOfEps], task->execAddr.fqdn, sizeof(task->execAddr.fqdn)); - job->dataSrcEps.port[job->dataSrcEps.numOfEps] = task->execAddr.port; + /* + if (SCH_IS_DATA_SRC_TASK(task) && job->dataSrcEps.numOfEps < SCH_MAX_CANDIDATE_EP_NUM) { + strncpy(job->dataSrcEps.fqdn[job->dataSrcEps.numOfEps], task->execAddr.fqdn, sizeof(task->execAddr.fqdn)); + job->dataSrcEps.port[job->dataSrcEps.numOfEps] = task->execAddr.port; - ++job->dataSrcEps.numOfEps; - } -*/ + ++job->dataSrcEps.numOfEps; + } + */ for (int32_t i = 0; i < parentNum; ++i) { SSchTask *par = *(SSchTask **)taosArrayGet(pTask->parents, i); - int32_t readyNum = atomic_add_fetch_32(&par->childReady, 1); + int32_t readyNum = atomic_add_fetch_32(&par->childReady, 1); SCH_LOCK(SCH_WRITE, &par->lock); - SDownstreamSourceNode source = {.type = QUERY_NODE_DOWNSTREAM_SOURCE, .taskId = pTask->taskId, .schedId = schMgmt.sId, .addr = pTask->succeedAddr}; + SDownstreamSourceNode source = {.type = QUERY_NODE_DOWNSTREAM_SOURCE, + .taskId = pTask->taskId, + .schedId = schMgmt.sId, + .addr = pTask->succeedAddr}; qSetSubplanExecutionNode(par->plan, pTask->plan->id.groupId, &source); SCH_UNLOCK(SCH_WRITE, &par->lock); - + if (SCH_TASK_READY_TO_LUNCH(readyNum, par)) { SCH_ERR_RET(schLaunchTaskImpl(pJob, par)); } @@ -860,11 +851,10 @@ _return: SCH_RET(schProcessOnJobFailure(pJob, code)); } - // Note: no more error processing, handled in function internal int32_t schFetchFromRemote(SSchJob *pJob) { int32_t code = 0; - + if (atomic_val_compare_exchange_32(&pJob->remoteFetch, 0, 1) != 0) { SCH_JOB_ELOG("prior fetching not finished, remoteFetch:%d", atomic_load_32(&pJob->remoteFetch)); return TSDB_CODE_SUCCESS; @@ -881,7 +871,7 @@ int32_t schFetchFromRemote(SSchJob *pJob) { SCH_ERR_JRET(schBuildAndSendMsg(pJob, pJob->fetchTask, &pJob->resNode, TDMT_VND_FETCH)); return TSDB_CODE_SUCCESS; - + _return: atomic_val_compare_exchange_32(&pJob->remoteFetch, 1, 0); @@ -889,15 +879,15 @@ _return: SCH_RET(schProcessOnTaskFailure(pJob, pJob->fetchTask, code)); } - // Note: no more task error processing, handled in function internal -int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, char *msg, int32_t msgSize, int32_t rspCode) { +int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, char *msg, int32_t msgSize, + int32_t rspCode) { int32_t code = 0; - int8_t status = 0; - + int8_t status = 0; + if (schJobNeedToStop(pJob, &status)) { SCH_TASK_ELOG("rsp not processed cause of job status, job status:%d", status); - + SCH_RET(atomic_load_32(&pJob->errCode)); } @@ -905,13 +895,13 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch switch (msgType) { case TDMT_VND_CREATE_TABLE_RSP: { - SCH_ERR_JRET(rspCode); - SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); + SCH_ERR_JRET(rspCode); + SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); - break; - } + break; + } case TDMT_VND_SUBMIT_RSP: { - #if 0 //TODO OPEN THIS +#if 0 // TODO OPEN THIS SShellSubmitRspMsg *rsp = (SShellSubmitRspMsg *)msg; if (rspCode != TSDB_CODE_SUCCESS || NULL == msg || rsp->code != TSDB_CODE_SUCCESS) { @@ -919,77 +909,77 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch } pJob->resNumOfRows += rsp->affectedRows; - #else - SCH_ERR_JRET(rspCode); +#else + SCH_ERR_JRET(rspCode); - SSubmitRsp *rsp = (SSubmitRsp *)msg; - if (rsp) { - pJob->resNumOfRows += rsp->affectedRows; - } - #endif - - SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); - - break; + SSubmitRsp *rsp = (SSubmitRsp *)msg; + if (rsp) { + pJob->resNumOfRows += rsp->affectedRows; } +#endif + + SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); + + break; + } case TDMT_VND_QUERY_RSP: { - SQueryTableRsp *rsp = (SQueryTableRsp *)msg; - - SCH_ERR_JRET(rspCode); - if (NULL == msg) { - SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); - } - SCH_ERR_JRET(rsp->code); - - SCH_ERR_JRET(schBuildAndSendMsg(pJob, pTask, NULL, TDMT_VND_RES_READY)); - - break; + SQueryTableRsp *rsp = (SQueryTableRsp *)msg; + + SCH_ERR_JRET(rspCode); + if (NULL == msg) { + SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); } + SCH_ERR_JRET(rsp->code); + + SCH_ERR_JRET(schBuildAndSendMsg(pJob, pTask, NULL, TDMT_VND_RES_READY)); + + break; + } case TDMT_VND_RES_READY_RSP: { - SResReadyRsp *rsp = (SResReadyRsp *)msg; - - SCH_ERR_JRET(rspCode); - if (NULL == msg) { - SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); - } - SCH_ERR_JRET(rsp->code); - - SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); - - break; + SResReadyRsp *rsp = (SResReadyRsp *)msg; + + SCH_ERR_JRET(rspCode); + if (NULL == msg) { + SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); } + SCH_ERR_JRET(rsp->code); + + SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); + + break; + } case TDMT_VND_FETCH_RSP: { - SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)msg; + SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)msg; - SCH_ERR_JRET(rspCode); - if (NULL == msg) { - SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); - } - - if (pJob->res) { - SCH_TASK_ELOG("got fetch rsp while res already exists, res:%p", pJob->res); - tfree(rsp); - SCH_ERR_JRET(TSDB_CODE_SCH_STATUS_ERROR); - } - - atomic_store_ptr(&pJob->res, rsp); - atomic_add_fetch_32(&pJob->resNumOfRows, htonl(rsp->numOfRows)); - - if (rsp->completed) { - SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_SUCCEED); - } - - SCH_TASK_DLOG("got fetch rsp, rows:%d, complete:%d", htonl(rsp->numOfRows), rsp->completed); - - schProcessOnDataFetched(pJob); - break; + SCH_ERR_JRET(rspCode); + if (NULL == msg) { + SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); } + + if (pJob->res) { + SCH_TASK_ELOG("got fetch rsp while res already exists, res:%p", pJob->res); + tfree(rsp); + SCH_ERR_JRET(TSDB_CODE_SCH_STATUS_ERROR); + } + + atomic_store_ptr(&pJob->res, rsp); + atomic_add_fetch_32(&pJob->resNumOfRows, htonl(rsp->numOfRows)); + + if (rsp->completed) { + SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_SUCCEED); + } + + SCH_TASK_DLOG("got fetch rsp, rows:%d, complete:%d", htonl(rsp->numOfRows), rsp->completed); + + schProcessOnDataFetched(pJob); + break; + } case TDMT_VND_DROP_TASK_RSP: { - // SHOULD NEVER REACH HERE - SCH_TASK_ELOG("invalid status to handle drop task rsp, refId:%" PRIx64, pJob->refId); - SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); - break; - } + // SHOULD NEVER REACH HERE + SCH_TASK_ELOG("invalid status to handle drop task rsp, refId:%" PRIx64, pJob->refId); + SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); + break; + } default: SCH_TASK_ELOG("unknown rsp msg, type:%d, status:%d", msgType, SCH_GET_TASK_STATUS(pTask)); SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); @@ -1002,15 +992,15 @@ _return: SCH_RET(schProcessOnTaskFailure(pJob, pTask, code)); } - -int32_t schHandleCallback(void* param, const SDataBuf* pMsg, int32_t msgType, int32_t rspCode) { - int32_t code = 0; +int32_t schHandleCallback(void *param, const SDataBuf *pMsg, int32_t msgType, int32_t rspCode) { + int32_t code = 0; SSchCallbackParam *pParam = (SSchCallbackParam *)param; - SSchTask *pTask = NULL; - + SSchTask *pTask = NULL; + SSchJob *pJob = schAcquireJob(pParam->refId); if (NULL == pJob) { - qError("QID:0x%" PRIx64 ",TID:0x%" PRIx64 "taosAcquireRef job failed, may be dropped, refId:%" PRIx64, pParam->queryId, pParam->taskId, pParam->refId); + qError("QID:0x%" PRIx64 ",TID:0x%" PRIx64 "taosAcquireRef job failed, may be dropped, refId:%" PRIx64, + pParam->queryId, pParam->taskId, pParam->refId); SCH_ERR_JRET(TSDB_CODE_QRY_JOB_FREED); } @@ -1028,8 +1018,8 @@ int32_t schHandleCallback(void* param, const SDataBuf* pMsg, int32_t msgType, in pTask = *task; SCH_TASK_DLOG("rsp msg received, type:%s, code:%s", TMSG_INFO(msgType), tstrerror(rspCode)); - - pTask->handle = pMsg->handle; + + pTask->handle = pMsg->handle; SCH_ERR_JRET(schHandleResponseMsg(pJob, pTask, msgType, pMsg->pData, pMsg->len, rspCode)); _return: @@ -1042,42 +1032,41 @@ _return: SCH_RET(code); } -int32_t schHandleSubmitCallback(void* param, const SDataBuf* pMsg, int32_t code) { +int32_t schHandleSubmitCallback(void *param, const SDataBuf *pMsg, int32_t code) { return schHandleCallback(param, pMsg, TDMT_VND_SUBMIT_RSP, code); } -int32_t schHandleCreateTableCallback(void* param, const SDataBuf* pMsg, int32_t code) { +int32_t schHandleCreateTableCallback(void *param, const SDataBuf *pMsg, int32_t code) { return schHandleCallback(param, pMsg, TDMT_VND_CREATE_TABLE_RSP, code); } -int32_t schHandleQueryCallback(void* param, const SDataBuf* pMsg, int32_t code) { +int32_t schHandleQueryCallback(void *param, const SDataBuf *pMsg, int32_t code) { return schHandleCallback(param, pMsg, TDMT_VND_QUERY_RSP, code); } -int32_t schHandleFetchCallback(void* param, const SDataBuf* pMsg, int32_t code) { +int32_t schHandleFetchCallback(void *param, const SDataBuf *pMsg, int32_t code) { return schHandleCallback(param, pMsg, TDMT_VND_FETCH_RSP, code); } -int32_t schHandleReadyCallback(void* param, const SDataBuf* pMsg, int32_t code) { +int32_t schHandleReadyCallback(void *param, const SDataBuf *pMsg, int32_t code) { return schHandleCallback(param, pMsg, TDMT_VND_RES_READY_RSP, code); } -int32_t schHandleDropCallback(void* param, const SDataBuf* pMsg, int32_t code) { +int32_t schHandleDropCallback(void *param, const SDataBuf *pMsg, int32_t code) { SSchCallbackParam *pParam = (SSchCallbackParam *)param; - qDebug("QID:%"PRIx64",TID:%"PRIx64" drop task rsp received, code:%x", pParam->queryId, pParam->taskId, code); + qDebug("QID:%" PRIx64 ",TID:%" PRIx64 " drop task rsp received, code:%x", pParam->queryId, pParam->taskId, code); } - -int32_t schHandleHbCallback(void* param, const SDataBuf* pMsg, int32_t code) { +int32_t schHandleHbCallback(void *param, const SDataBuf *pMsg, int32_t code) { if (code) { qError("hb rsp error:%s", tstrerror(code)); SCH_ERR_RET(code); } - + SSchedulerHbRsp rsp = {0}; SSchCallbackParam *pParam = (SSchCallbackParam *)param; - + if (tDeserializeSSchedulerHbRsp(pMsg->pData, pMsg->len, &rsp)) { qError("invalid hb rsp msg, size:%d", pMsg->len); SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); @@ -1088,21 +1077,22 @@ int32_t schHandleHbCallback(void* param, const SDataBuf* pMsg, int32_t code) { trans.seqId = rsp.seqId; trans.trans.transInst = pParam->transport; trans.trans.transHandle = pMsg->handle; - + SCH_RET(schUpdateHbConnection(&rsp.epId, &trans)); } int32_t taskNum = (int32_t)taosArrayGetSize(rsp.taskStatus); for (int32_t i = 0; i < taskNum; ++i) { STaskStatus *taskStatus = taosArrayGet(rsp.taskStatus, i); - + SSchJob *pJob = schAcquireJob(taskStatus->refId); if (NULL == pJob) { - qWarn("job not found, refId:0x%" PRIx64 ",QID:0x%" PRIx64 ",TID:0x%" PRIx64, taskStatus->refId, taskStatus->queryId, taskStatus->taskId); - //TODO DROP TASK FROM SERVER!!!! + qWarn("job not found, refId:0x%" PRIx64 ",QID:0x%" PRIx64 ",TID:0x%" PRIx64, taskStatus->refId, + taskStatus->queryId, taskStatus->taskId); + // TODO DROP TASK FROM SERVER!!!! continue; } - + // TODO schReleaseJob(taskStatus->refId); @@ -1115,22 +1105,21 @@ _return: SCH_RET(code); } - int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) { switch (msgType) { case TDMT_VND_CREATE_TABLE: *fp = schHandleCreateTableCallback; break; - case TDMT_VND_SUBMIT: + case TDMT_VND_SUBMIT: *fp = schHandleSubmitCallback; break; - case TDMT_VND_QUERY: + case TDMT_VND_QUERY: *fp = schHandleQueryCallback; break; - case TDMT_VND_RES_READY: + case TDMT_VND_RES_READY: *fp = schHandleReadyCallback; break; - case TDMT_VND_FETCH: + case TDMT_VND_FETCH: *fp = schHandleFetchCallback; break; case TDMT_VND_DROP_TASK: @@ -1147,13 +1136,13 @@ int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) { return TSDB_CODE_SUCCESS; } - -int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet* epSet, int32_t msgType, void *msg, uint32_t msgSize) { +int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet *epSet, int32_t msgType, void *msg, + uint32_t msgSize) { int32_t code = 0; SSchTrans *trans = (SSchTrans *)transport; - SMsgSendInfo* pMsgSendInfo = calloc(1, sizeof(SMsgSendInfo)); + SMsgSendInfo *pMsgSendInfo = calloc(1, sizeof(SMsgSendInfo)); if (NULL == pMsgSendInfo) { SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SMsgSendInfo)); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -1173,15 +1162,14 @@ int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet* param->taskId = SCH_TASK_ID(pTask); param->transport = trans->transInst; - pMsgSendInfo->param = param; pMsgSendInfo->msgInfo.pData = msg; pMsgSendInfo->msgInfo.len = msgSize; - pMsgSendInfo->msgInfo.handle = trans->transHandle; + pMsgSendInfo->msgInfo.handle = trans->transHandle; pMsgSendInfo->msgType = msgType; pMsgSendInfo->fp = fp; - - int64_t transporterId = 0; + + int64_t transporterId = 0; code = asyncSendMsgToServer(trans->transInst, epSet, &transporterId, pMsgSendInfo); if (code) { SCH_ERR_JRET(code); @@ -1191,7 +1179,7 @@ int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet* return TSDB_CODE_SUCCESS; _return: - + tfree(param); tfree(pMsgSendInfo); SCH_RET(code); @@ -1199,9 +1187,9 @@ _return: int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, int32_t msgType) { uint32_t msgSize = 0; - void *msg = NULL; - int32_t code = 0; - bool isCandidateAddr = false; + void *msg = NULL; + int32_t code = 0; + bool isCandidateAddr = false; if (NULL == addr) { addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); isCandidateAddr = true; @@ -1235,13 +1223,13 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, SSubQueryMsg *pMsg = msg; pMsg->header.vgId = htonl(addr->nodeId); - pMsg->sId = htobe64(schMgmt.sId); - pMsg->queryId = htobe64(pJob->queryId); - pMsg->taskId = htobe64(pTask->taskId); - pMsg->refId = htobe64(pJob->refId); - pMsg->taskType = TASK_TYPE_TEMP; - pMsg->phyLen = htonl(pTask->msgLen); - pMsg->sqlLen = htonl(len); + pMsg->sId = htobe64(schMgmt.sId); + pMsg->queryId = htobe64(pJob->queryId); + pMsg->taskId = htobe64(pTask->taskId); + pMsg->refId = htobe64(pJob->refId); + pMsg->taskType = TASK_TYPE_TEMP; + pMsg->phyLen = htonl(pTask->msgLen); + pMsg->sqlLen = htonl(len); memcpy(pMsg->msg, pJob->sql, len); memcpy(pMsg->msg + len, pTask->msg, pTask->msgLen); @@ -1257,12 +1245,12 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, } SResReadyReq *pMsg = msg; - - pMsg->header.vgId = htonl(addr->nodeId); - - pMsg->sId = htobe64(schMgmt.sId); + + pMsg->header.vgId = htonl(addr->nodeId); + + pMsg->sId = htobe64(schMgmt.sId); pMsg->queryId = htobe64(pJob->queryId); - pMsg->taskId = htobe64(pTask->taskId); + pMsg->taskId = htobe64(pTask->taskId); break; } case TDMT_VND_FETCH: { @@ -1272,32 +1260,32 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, SCH_TASK_ELOG("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - + SResFetchReq *pMsg = msg; - - pMsg->header.vgId = htonl(addr->nodeId); - - pMsg->sId = htobe64(schMgmt.sId); + + pMsg->header.vgId = htonl(addr->nodeId); + + pMsg->sId = htobe64(schMgmt.sId); pMsg->queryId = htobe64(pJob->queryId); - pMsg->taskId = htobe64(pTask->taskId); + pMsg->taskId = htobe64(pTask->taskId); break; } - case TDMT_VND_DROP_TASK:{ + case TDMT_VND_DROP_TASK: { msgSize = sizeof(STaskDropReq); msg = calloc(1, msgSize); if (NULL == msg) { SCH_TASK_ELOG("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - + STaskDropReq *pMsg = msg; - - pMsg->header.vgId = htonl(addr->nodeId); - - pMsg->sId = htobe64(schMgmt.sId); + + pMsg->header.vgId = htonl(addr->nodeId); + + pMsg->sId = htobe64(schMgmt.sId); pMsg->queryId = htobe64(pJob->queryId); - pMsg->taskId = htobe64(pTask->taskId); - pMsg->refId = htobe64(pJob->refId); + pMsg->taskId = htobe64(pTask->taskId); + pMsg->refId = htobe64(pJob->refId); break; } case TDMT_VND_QUERY_HEARTBEAT: { @@ -1337,24 +1325,24 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, if (isCandidateAddr) { SCH_ERR_RET(schRecordTaskExecNode(pJob, pTask, addr)); } - + return TSDB_CODE_SUCCESS; _return: SCH_SET_TASK_LASTMSG_TYPE(pTask, -1); - + tfree(msg); SCH_RET(code); } int32_t schEnsureHbConnection(SSchJob *pJob, SSchTask *pTask) { SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); - SQueryNodeEpId epId = {0}; + SQueryNodeEpId epId = {0}; epId.nodeId = addr->nodeId; memcpy(&epId.ep, SCH_GET_CUR_EP(addr), sizeof(SEp)); - + SSchHbTrans *hb = taosHashGet(schMgmt.hbConnections, &epId, sizeof(SQueryNodeEpId)); if (NULL == hb) { SCH_ERR_RET(schBuildAndSendMsg(pJob, NULL, addr, TDMT_VND_QUERY_HEARTBEAT)); @@ -1364,29 +1352,30 @@ int32_t schEnsureHbConnection(SSchJob *pJob, SSchTask *pTask) { } int32_t schLaunchTaskImpl(SSchJob *pJob, SSchTask *pTask) { - int8_t status = 0; + int8_t status = 0; int32_t code = 0; atomic_add_fetch_32(&pTask->level->taskLaunchedNum, 1); - + if (schJobNeedToStop(pJob, &status)) { SCH_TASK_DLOG("no need to launch task cause of job status, job status:%d", status); - + SCH_RET(atomic_load_32(&pJob->errCode)); } - + SSubplan *plan = pTask->plan; - if (NULL == pTask->msg) { // TODO add more detailed reason for failure + if (NULL == pTask->msg) { // TODO add more detailed reason for failure code = qSubPlanToString(plan, &pTask->msg, &pTask->msgLen); if (TSDB_CODE_SUCCESS != code) { - SCH_TASK_ELOG("failed to create physical plan, code:%s, msg:%p, len:%d", tstrerror(code), pTask->msg, pTask->msgLen); + SCH_TASK_ELOG("failed to create physical plan, code:%s, msg:%p, len:%d", tstrerror(code), pTask->msg, + pTask->msgLen); SCH_ERR_RET(code); } else { SCH_TASK_DLOG("physical plan len:%d, %s", pTask->msgLen, pTask->msg); } } - + SCH_ERR_RET(schSetTaskCandidateAddrs(pJob, pTask)); // NOTE: race condition: the task should be put into the hash table before send msg to server @@ -1398,15 +1387,15 @@ int32_t schLaunchTaskImpl(SSchJob *pJob, SSchTask *pTask) { if (SCH_IS_QUERY_JOB(pJob)) { SCH_ERR_RET(schEnsureHbConnection(pJob, pTask)); } - + SCH_ERR_RET(schBuildAndSendMsg(pJob, pTask, NULL, plan->msgType)); - + return TSDB_CODE_SUCCESS; } // Note: no more error processing, handled in function internal int32_t schLaunchTask(SSchJob *pJob, SSchTask *pTask) { - bool enough = false; + bool enough = false; int32_t code = 0; if (SCH_TASK_NEED_FLOW_CTRL(pJob, pTask)) { @@ -1436,11 +1425,9 @@ int32_t schLaunchLevelTasks(SSchJob *pJob, SSchLevel *level) { return TSDB_CODE_SUCCESS; } - - int32_t schLaunchJob(SSchJob *pJob) { SSchLevel *level = taosArrayGet(pJob->levels, pJob->levelIdx); - + SCH_ERR_RET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_EXECUTING)); SCH_ERR_RET(schCheckJobNeedFlowCtrl(pJob, level)); @@ -1457,7 +1444,7 @@ void schDropTaskOnExecutedNode(SSchJob *pJob, SSchTask *pTask) { } int32_t size = (int32_t)taosArrayGetSize(pTask->execAddrs); - + if (size <= 0) { SCH_TASK_DLOG("task has no exec address, no need to drop it, status:%d", SCH_GET_TASK_STATUS(pTask)); return; @@ -1481,9 +1468,9 @@ void schDropTaskInHashList(SSchJob *pJob, SHashObj *list) { if (!SCH_TASK_NO_NEED_DROP(pTask)) { schDropTaskOnExecutedNode(pJob, pTask); } - + pIter = taosHashIterate(list, pIter); - } + } } void schDropJobAllTasks(SSchJob *pJob) { @@ -1493,10 +1480,9 @@ void schDropJobAllTasks(SSchJob *pJob) { } int32_t schCancelJob(SSchJob *pJob) { - //TODO - - //TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST + // TODO + // TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST } void schFreeJobImpl(void *job) { @@ -1506,7 +1492,7 @@ void schFreeJobImpl(void *job) { SSchJob *pJob = job; uint64_t queryId = pJob->queryId; - int64_t refId = pJob->refId; + int64_t refId = pJob->refId; if (pJob->status == JOB_TASK_STATUS_EXECUTING) { schCancelJob(pJob); @@ -1514,55 +1500,55 @@ void schFreeJobImpl(void *job) { schDropJobAllTasks(pJob); - pJob->subPlans = NULL; // it is a reference to pDag->pSubplans - + pJob->subPlans = NULL; // it is a reference to pDag->pSubplans + int32_t numOfLevels = taosArrayGetSize(pJob->levels); - for(int32_t i = 0; i < numOfLevels; ++i) { + for (int32_t i = 0; i < numOfLevels; ++i) { SSchLevel *pLevel = taosArrayGet(pJob->levels, i); schFreeFlowCtrl(pLevel); - + int32_t numOfTasks = taosArrayGetSize(pLevel->subTasks); - for(int32_t j = 0; j < numOfTasks; ++j) { - SSchTask* pTask = taosArrayGet(pLevel->subTasks, j); + for (int32_t j = 0; j < numOfTasks; ++j) { + SSchTask *pTask = taosArrayGet(pLevel->subTasks, j); schFreeTask(pTask); } taosArrayDestroy(pLevel->subTasks); } - + taosHashCleanup(pJob->execTasks); taosHashCleanup(pJob->failTasks); taosHashCleanup(pJob->succTasks); - + taosArrayDestroy(pJob->levels); taosArrayDestroy(pJob->nodeList); tfree(pJob->res); - + tfree(pJob); - qDebug("QID:0x%"PRIx64" job freed, refId:%" PRIx64 ", pointer:%p", queryId, refId, pJob); + qDebug("QID:0x%" PRIx64 " job freed, refId:%" PRIx64 ", pointer:%p", queryId, refId, pJob); } - -static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan* pDag, int64_t *job, const char* sql, bool syncSchedule) { - qDebug("QID:0x%"PRIx64" job started", pDag->queryId); +static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan *pDag, int64_t *job, const char *sql, + bool syncSchedule) { + qDebug("QID:0x%" PRIx64 " job started", pDag->queryId); if (pNodeList == NULL || (pNodeList && taosArrayGetSize(pNodeList) <= 0)) { - qDebug("QID:0x%"PRIx64" input exec nodeList is empty", pDag->queryId); + qDebug("QID:0x%" PRIx64 " input exec nodeList is empty", pDag->queryId); } - int32_t code = 0; + int32_t code = 0; SSchJob *pJob = calloc(1, sizeof(SSchJob)); if (NULL == pJob) { - qError("QID:%"PRIx64" calloc %d failed", pDag->queryId, (int32_t)sizeof(SSchJob)); + qError("QID:%" PRIx64 " calloc %d failed", pDag->queryId, (int32_t)sizeof(SSchJob)); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } pJob->attr.syncSchedule = syncSchedule; pJob->transport = transport; - pJob->sql = sql; + pJob->sql = sql; if (pNodeList != NULL) { pJob->nodeList = taosArrayDup(pNodeList); @@ -1570,19 +1556,22 @@ static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan* pD SCH_ERR_JRET(schValidateAndBuildJob(pDag, pJob)); - pJob->execTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); + pJob->execTasks = + taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); if (NULL == pJob->execTasks) { SCH_JOB_ELOG("taosHashInit %d execTasks failed", pDag->numOfSubplans); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - pJob->succTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); + pJob->succTasks = + taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); if (NULL == pJob->succTasks) { SCH_JOB_ELOG("taosHashInit %d succTasks failed", pDag->numOfSubplans); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - pJob->failTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); + pJob->failTasks = + taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); if (NULL == pJob->failTasks) { SCH_JOB_ELOG("taosHashInit %d failTasks failed", pDag->numOfSubplans); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -1602,9 +1591,9 @@ static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan* pD SCH_ERR_JRET(schLaunchJob(pJob)); schAcquireJob(pJob->refId); - + *job = pJob->refId; - + if (syncSchedule) { SCH_JOB_DLOG("will wait for rsp now, job status:%d", SCH_GET_JOB_STATUS(pJob)); tsem_wait(&pJob->rspSem); @@ -1613,7 +1602,7 @@ static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan* pD SCH_JOB_DLOG("job exec done, job status:%d", SCH_GET_JOB_STATUS(pJob)); schReleaseJob(pJob->refId); - + return TSDB_CODE_SUCCESS; _return: @@ -1622,7 +1611,6 @@ _return: SCH_RET(code); } - int32_t schedulerInit(SSchedulerCfg *cfg) { if (schMgmt.jobRef) { qError("scheduler already initialized"); @@ -1631,7 +1619,7 @@ int32_t schedulerInit(SSchedulerCfg *cfg) { if (cfg) { schMgmt.cfg = *cfg; - + if (schMgmt.cfg.maxJobNum == 0) { schMgmt.cfg.maxJobNum = SCHEDULE_DEFAULT_MAX_JOB_NUM; } @@ -1642,7 +1630,7 @@ int32_t schedulerInit(SSchedulerCfg *cfg) { schMgmt.cfg.maxJobNum = SCHEDULE_DEFAULT_MAX_JOB_NUM; schMgmt.cfg.maxNodeTableNum = SCHEDULE_DEFAULT_MAX_NODE_TABLE_NUM; } - + schMgmt.jobRef = taosOpenRef(schMgmt.cfg.maxJobNum, schFreeJobImpl); if (schMgmt.jobRef < 0) { qError("init schduler jobRef failed, num:%u", schMgmt.cfg.maxJobNum); @@ -1660,12 +1648,13 @@ int32_t schedulerInit(SSchedulerCfg *cfg) { SCH_ERR_RET(TSDB_CODE_QRY_SYS_ERROR); } - qInfo("scheduler %"PRIx64" initizlized, maxJob:%u", schMgmt.sId, schMgmt.cfg.maxJobNum); - + qInfo("scheduler %" PRIx64 " initizlized, maxJob:%u", schMgmt.sId, schMgmt.cfg.maxJobNum); + return TSDB_CODE_SUCCESS; } -int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan* pDag, int64_t *pJob, const char* sql, SQueryResult *pRes) { +int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan *pDag, int64_t *pJob, const char *sql, + SQueryResult *pRes) { if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob || NULL == pRes) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } @@ -1676,20 +1665,21 @@ int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan* pDag, in pRes->code = atomic_load_32(&job->errCode); pRes->numOfRows = job->resNumOfRows; schReleaseJob(*pJob); - + return TSDB_CODE_SUCCESS; } -int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryPlan* pDag, const char* sql, int64_t *pJob) { +int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryPlan *pDag, const char *sql, int64_t *pJob) { if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } SCH_ERR_RET(schExecJobImpl(transport, pNodeList, pDag, pJob, sql, false)); - + return TSDB_CODE_SUCCESS; } +#if 0 int32_t schedulerConvertDagToTaskList(SQueryPlan* pDag, SArray **pTasks) { if (NULL == pDag || pDag->numOfSubplans <= 0 || LIST_LENGTH(pDag->pSubplans) == 0) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); @@ -1810,14 +1800,14 @@ _return: SCH_RET(code); } +#endif - -int32_t schedulerFetchRows(int64_t job, void** pData) { +int32_t schedulerFetchRows(int64_t job, void **pData) { if (NULL == pData) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - int32_t code = 0; + int32_t code = 0; SSchJob *pJob = schAcquireJob(job); if (NULL == pJob) { qError("acquire job from jobRef list failed, may be dropped, refId:%" PRIx64, job); @@ -1861,12 +1851,11 @@ int32_t schedulerFetchRows(int64_t job, void** pData) { SCH_JOB_ELOG("job failed or dropping, status:%d", status); SCH_ERR_JRET(atomic_load_32(&pJob->errCode)); } - + if (pJob->res && ((SRetrieveTableRsp *)pJob->res)->completed) { SCH_ERR_JRET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_SUCCEED)); } - while (true) { *pData = atomic_load_ptr(&pJob->res); if (*pData != atomic_val_compare_exchange_ptr(&pJob->res, *pData, NULL)) { @@ -1891,7 +1880,7 @@ int32_t schedulerFetchRows(int64_t job, void** pData) { _return: atomic_val_compare_exchange_8(&pJob->userFetch, 1, 0); - + schReleaseJob(job); SCH_RET(code); @@ -1944,17 +1933,17 @@ void schedulerFreeTaskList(SArray *taskList) { taosArrayDestroy(taskList); } - + void schedulerDestroy(void) { if (schMgmt.jobRef) { SSchJob *pJob = taosIterateRef(schMgmt.jobRef, 0); - + while (pJob) { taosRemoveRef(schMgmt.jobRef, pJob->refId); - + pJob = taosIterateRef(schMgmt.jobRef, pJob->refId); } - + taosCloseRef(schMgmt.jobRef); schMgmt.jobRef = 0; } diff --git a/source/libs/sync/inc/syncElection.h b/source/libs/sync/inc/syncElection.h index 019c291efc..85a82dcfb7 100644 --- a/source/libs/sync/inc/syncElection.h +++ b/source/libs/sync/inc/syncElection.h @@ -39,7 +39,6 @@ extern "C" { // /\ UNCHANGED <> // int32_t syncNodeRequestVotePeers(SSyncNode* pSyncNode); - int32_t syncNodeElect(SSyncNode* pSyncNode); int32_t syncNodeRequestVote(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncRequestVote* pMsg); diff --git a/source/libs/sync/inc/syncEnv.h b/source/libs/sync/inc/syncEnv.h index 9fbea03265..40ff79287b 100644 --- a/source/libs/sync/inc/syncEnv.h +++ b/source/libs/sync/inc/syncEnv.h @@ -29,6 +29,7 @@ extern "C" { #include "ttimer.h" #define TIMER_MAX_MS 0x7FFFFFFF +#define ENV_TICK_TIMER_MS 1000 #define PING_TIMER_MS 1000 #define ELECT_TIMER_MS_MIN 150 #define ELECT_TIMER_MS_MAX 300 @@ -38,17 +39,28 @@ extern "C" { #define EMPTY_RAFT_ID ((SRaftId){.addr = 0, .vgId = 0}) typedef struct SSyncEnv { - tmr_h pEnvTickTimer; + // tick timer + tmr_h pEnvTickTimer; + int32_t envTickTimerMS; + uint64_t envTickTimerLogicClock; // if use queue, should pass logic clock into queue item + uint64_t envTickTimerLogicClockUser; + TAOS_TMR_CALLBACK FpEnvTickTimer; // Timer Fp + uint64_t envTickTimerCounter; + + // timer manager tmr_h pTimerManager; - char name[128]; + + // other resources shared by SyncNodes + // ... + } SSyncEnv; extern SSyncEnv* gSyncEnv; int32_t syncEnvStart(); int32_t syncEnvStop(); -tmr_h syncEnvStartTimer(TAOS_TMR_CALLBACK fp, int mseconds, void* param); -void syncEnvStopTimer(tmr_h* pTimer); +int32_t syncEnvStartTimer(); +int32_t syncEnvStopTimer(); #ifdef __cplusplus } diff --git a/source/libs/sync/inc/syncIO.h b/source/libs/sync/inc/syncIO.h index 160fefd086..09e93fda1c 100644 --- a/source/libs/sync/inc/syncIO.h +++ b/source/libs/sync/inc/syncIO.h @@ -29,22 +29,28 @@ extern "C" { #include "tqueue.h" #include "trpc.h" +#define TICK_Q_TIMER_MS 1000 +#define TICK_Ping_TIMER_MS 1000 + typedef struct SSyncIO { STaosQueue *pMsgQ; - STaosQset * pQset; + STaosQset *pQset; pthread_t consumerTid; - void * serverRpc; - void * clientRpc; + void *serverRpc; + void *clientRpc; SEpSet myAddr; - void *ioTimerTickQ; - void *ioTimerTickPing; - void *ioTimerManager; + tmr_h qTimer; + int32_t qTimerMS; + tmr_h pingTimer; + int32_t pingTimerMS; + tmr_h timerMgr; void *pSyncNode; int32_t (*FpOnSyncPing)(SSyncNode *pSyncNode, SyncPing *pMsg); int32_t (*FpOnSyncPingReply)(SSyncNode *pSyncNode, SyncPingReply *pMsg); + int32_t (*FpOnSyncClientRequest)(SSyncNode *pSyncNode, SyncClientRequest *pMsg); int32_t (*FpOnSyncRequestVote)(SSyncNode *pSyncNode, SyncRequestVote *pMsg); int32_t (*FpOnSyncRequestVoteReply)(SSyncNode *pSyncNode, SyncRequestVoteReply *pMsg); int32_t (*FpOnSyncAppendEntries)(SSyncNode *pSyncNode, SyncAppendEntries *pMsg); @@ -59,11 +65,14 @@ extern SSyncIO *gSyncIO; int32_t syncIOStart(char *host, uint16_t port); int32_t syncIOStop(); -int32_t syncIOTickQ(); -int32_t syncIOTickPing(); int32_t syncIOSendMsg(void *clientRpc, const SEpSet *pEpSet, SRpcMsg *pMsg); int32_t syncIOEqMsg(void *queue, SRpcMsg *pMsg); +int32_t syncIOQTimerStart(); +int32_t syncIOQTimerStop(); +int32_t syncIOPingTimerStart(); +int32_t syncIOPingTimerStop(); + #ifdef __cplusplus } #endif diff --git a/source/libs/sync/inc/syncInt.h b/source/libs/sync/inc/syncInt.h index df277e2d7e..5a9af83827 100644 --- a/source/libs/sync/inc/syncInt.h +++ b/source/libs/sync/inc/syncInt.h @@ -67,12 +67,12 @@ extern "C" { } \ } -struct SRaft; -typedef struct SRaft SRaft; - struct SyncTimeout; typedef struct SyncTimeout SyncTimeout; +struct SyncClientRequest; +typedef struct SyncClientRequest SyncClientRequest; + struct SyncPing; typedef struct SyncPing SyncPing; @@ -117,8 +117,10 @@ typedef struct SSyncNode { SSyncCfg syncCfg; char path[TSDB_FILENAME_LEN]; char raftStorePath[TSDB_FILENAME_LEN * 2]; - SWal* pWal; - void* rpcClient; + + // sync io + SWal* pWal; + void* rpcClient; int32_t (*FpSendMsg)(void* rpcClient, const SEpSet* pEpSet, SRpcMsg* pMsg); void* queue; int32_t (*FpEqMsg)(void* queue, SRpcMsg* pMsg); @@ -164,7 +166,7 @@ typedef struct SSyncNode { int32_t pingTimerMS; uint64_t pingTimerLogicClock; uint64_t pingTimerLogicClockUser; - TAOS_TMR_CALLBACK FpPingTimer; // Timer Fp + TAOS_TMR_CALLBACK FpPingTimerCB; // Timer Fp uint64_t pingTimerCounter; // elect timer @@ -172,7 +174,7 @@ typedef struct SSyncNode { int32_t electTimerMS; uint64_t electTimerLogicClock; uint64_t electTimerLogicClockUser; - TAOS_TMR_CALLBACK FpElectTimer; // Timer Fp + TAOS_TMR_CALLBACK FpElectTimerCB; // Timer Fp uint64_t electTimerCounter; // heartbeat timer @@ -180,12 +182,13 @@ typedef struct SSyncNode { int32_t heartbeatTimerMS; uint64_t heartbeatTimerLogicClock; uint64_t heartbeatTimerLogicClockUser; - TAOS_TMR_CALLBACK FpHeartbeatTimer; // Timer Fp + TAOS_TMR_CALLBACK FpHeartbeatTimerCB; // Timer Fp uint64_t heartbeatTimerCounter; // callback int32_t (*FpOnPing)(SSyncNode* ths, SyncPing* pMsg); int32_t (*FpOnPingReply)(SSyncNode* ths, SyncPingReply* pMsg); + int32_t (*FpOnClientRequest)(SSyncNode* ths, SyncClientRequest* pMsg); int32_t (*FpOnRequestVote)(SSyncNode* ths, SyncRequestVote* pMsg); int32_t (*FpOnRequestVoteReply)(SSyncNode* ths, SyncRequestVoteReply* pMsg); int32_t (*FpOnAppendEntries)(SSyncNode* ths, SyncAppendEntries* pMsg); @@ -194,26 +197,47 @@ typedef struct SSyncNode { } SSyncNode; +// open/close -------------- SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo); void syncNodeClose(SSyncNode* pSyncNode); -int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, SRpcMsg* pMsg); -int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg); +// ping -------------- int32_t syncNodePing(SSyncNode* pSyncNode, const SRaftId* destRaftId, SyncPing* pMsg); -int32_t syncNodePingAll(SSyncNode* pSyncNode); -int32_t syncNodePingPeers(SSyncNode* pSyncNode); int32_t syncNodePingSelf(SSyncNode* pSyncNode); +int32_t syncNodePingPeers(SSyncNode* pSyncNode); +int32_t syncNodePingAll(SSyncNode* pSyncNode); +// timer control -------------- int32_t syncNodeStartPingTimer(SSyncNode* pSyncNode); int32_t syncNodeStopPingTimer(SSyncNode* pSyncNode); int32_t syncNodeStartElectTimer(SSyncNode* pSyncNode, int32_t ms); int32_t syncNodeStopElectTimer(SSyncNode* pSyncNode); int32_t syncNodeRestartElectTimer(SSyncNode* pSyncNode, int32_t ms); +int32_t syncNodeResetElectTimer(SSyncNode* pSyncNode); int32_t syncNodeStartHeartbeatTimer(SSyncNode* pSyncNode); int32_t syncNodeStopHeartbeatTimer(SSyncNode* pSyncNode); + +// utils -------------- +int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, SRpcMsg* pMsg); +int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg); cJSON* syncNode2Json(const SSyncNode* pSyncNode); char* syncNode2Str(const SSyncNode* pSyncNode); +// raft state change -------------- +void syncNodeUpdateTerm(SSyncNode* pSyncNode, SyncTerm term); +void syncNodeBecomeFollower(SSyncNode* pSyncNode); +void syncNodeBecomeLeader(SSyncNode* pSyncNode); + +void syncNodeCandidate2Leader(SSyncNode* pSyncNode); +void syncNodeFollower2Candidate(SSyncNode* pSyncNode); +void syncNodeLeader2Follower(SSyncNode* pSyncNode); +void syncNodeCandidate2Follower(SSyncNode* pSyncNode); + +// raft vote -------------- +void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId); +void syncNodeVoteForSelf(SSyncNode* pSyncNode); +void syncNodeMaybeAdvanceCommitIndex(SSyncNode* pSyncNode); + // for debug -------------- void syncNodePrint(SSyncNode* pObj); void syncNodePrint2(char* s, SSyncNode* pObj); diff --git a/source/libs/sync/inc/syncMessage.h b/source/libs/sync/inc/syncMessage.h index 2876577410..5785089a20 100644 --- a/source/libs/sync/inc/syncMessage.h +++ b/source/libs/sync/inc/syncMessage.h @@ -39,6 +39,7 @@ typedef enum ESyncMessageType { SYNC_REQUEST_VOTE_REPLY = 111, SYNC_APPEND_ENTRIES = 113, SYNC_APPEND_ENTRIES_REPLY = 115, + SYNC_RESPONSE = 119, } ESyncMessageType; @@ -195,7 +196,7 @@ typedef struct SyncRequestVote { SRaftId srcId; SRaftId destId; // private data - SyncTerm currentTerm; + SyncTerm term; SyncIndex lastLogIndex; SyncTerm lastLogTerm; } SyncRequestVote; @@ -254,6 +255,7 @@ typedef struct SyncAppendEntries { SRaftId srcId; SRaftId destId; // private data + SyncTerm term; SyncIndex prevLogIndex; SyncTerm prevLogTerm; SyncIndex commitIndex; @@ -286,6 +288,7 @@ typedef struct SyncAppendEntriesReply { SRaftId srcId; SRaftId destId; // private data + SyncTerm term; bool success; SyncIndex matchIndex; } SyncAppendEntriesReply; diff --git a/source/libs/sync/inc/syncRaftLog.h b/source/libs/sync/inc/syncRaftLog.h index 59b5fa94db..d979e0df15 100644 --- a/source/libs/sync/inc/syncRaftLog.h +++ b/source/libs/sync/inc/syncRaftLog.h @@ -27,6 +27,9 @@ extern "C" { #include "syncRaftEntry.h" #include "taosdef.h" +#define SYNC_INDEX_BEGIN 0 +#define SYNC_INDEX_INVALID -1 + typedef struct SSyncLogStoreData { SSyncNode* pSyncNode; SWal* pWal; diff --git a/source/libs/sync/inc/syncRaftStore.h b/source/libs/sync/inc/syncRaftStore.h index 4058d3bd1c..30f7c5d9f7 100644 --- a/source/libs/sync/inc/syncRaftStore.h +++ b/source/libs/sync/inc/syncRaftStore.h @@ -43,6 +43,12 @@ int32_t raftStorePersist(SRaftStore *pRaftStore); int32_t raftStoreSerialize(SRaftStore *pRaftStore, char *buf, size_t len); int32_t raftStoreDeserialize(SRaftStore *pRaftStore, char *buf, size_t len); +bool raftStoreHasVoted(SRaftStore *pRaftStore); +void raftStoreVote(SRaftStore *pRaftStore, SRaftId *pRaftId); +void raftStoreClearVote(SRaftStore *pRaftStore); +void raftStoreNextTerm(SRaftStore *pRaftStore); +void raftStoreSetTerm(SRaftStore *pRaftStore, SyncTerm term); + // for debug ------------------- void raftStorePrint(SRaftStore *pObj); void raftStorePrint2(char *s, SRaftStore *pObj); diff --git a/source/libs/sync/inc/syncReplication.h b/source/libs/sync/inc/syncReplication.h index aca6205b9d..6fe18dae38 100644 --- a/source/libs/sync/inc/syncReplication.h +++ b/source/libs/sync/inc/syncReplication.h @@ -52,7 +52,6 @@ extern "C" { // /\ UNCHANGED <> // int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode); - int32_t syncNodeReplicate(SSyncNode* pSyncNode); int32_t syncNodeAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncAppendEntries* pMsg); diff --git a/source/libs/sync/inc/syncUtil.h b/source/libs/sync/inc/syncUtil.h index 2bbc1948dd..1b702c2528 100644 --- a/source/libs/sync/inc/syncUtil.h +++ b/source/libs/sync/inc/syncUtil.h @@ -34,6 +34,7 @@ void syncUtilnodeInfo2EpSet(const SNodeInfo* pNodeInfo, SEpSet* pEpSet); void syncUtilraftId2EpSet(const SRaftId* raftId, SEpSet* pEpSet); void syncUtilnodeInfo2raftId(const SNodeInfo* pNodeInfo, SyncGroupId vgId, SRaftId* raftId); bool syncUtilSameId(const SRaftId* pId1, const SRaftId* pId2); +bool syncUtilEmptyId(const SRaftId* pId); // ---- SSyncBuffer ---- void syncUtilbufBuild(SSyncBuffer* syncBuf, size_t len); @@ -52,6 +53,8 @@ const char* syncUtilState2String(ESyncState state); bool syncUtilCanPrint(char c); char* syncUtilprintBin(char* ptr, uint32_t len); char* syncUtilprintBin2(char* ptr, uint32_t len); +SyncIndex syncUtilMinIndex(SyncIndex a, SyncIndex b); +SyncIndex syncUtilMaxIndex(SyncIndex a, SyncIndex b); #ifdef __cplusplus } diff --git a/source/libs/sync/src/syncAppendEntries.c b/source/libs/sync/src/syncAppendEntries.c index ba10234a1d..87d6669f59 100644 --- a/source/libs/sync/src/syncAppendEntries.c +++ b/source/libs/sync/src/syncAppendEntries.c @@ -14,6 +14,11 @@ */ #include "syncAppendEntries.h" +#include "syncInt.h" +#include "syncRaftLog.h" +#include "syncRaftStore.h" +#include "syncUtil.h" +#include "syncVoteMgr.h" // TLA+ Spec // HandleAppendEntriesRequest(i, j, m) == @@ -80,4 +85,121 @@ // /\ UNCHANGED <> // /\ UNCHANGED <> // -int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {} +int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) { + int32_t ret = 0; + syncAppendEntriesLog2("==syncNodeOnAppendEntriesCb==", pMsg); + + if (pMsg->term > ths->pRaftStore->currentTerm) { + syncNodeUpdateTerm(ths, pMsg->term); + } + assert(pMsg->term <= ths->pRaftStore->currentTerm); + + if (pMsg->term == ths->pRaftStore->currentTerm) { + ths->leaderCache = pMsg->srcId; + syncNodeResetElectTimer(ths); + } + assert(pMsg->dataLen >= 0); + + SyncTerm localPreLogTerm = 0; + if (pMsg->prevLogTerm >= SYNC_INDEX_BEGIN && pMsg->prevLogTerm <= ths->pLogStore->getLastIndex(ths->pLogStore)) { + SSyncRaftEntry* pEntry = logStoreGetEntry(ths->pLogStore, pMsg->prevLogTerm); + assert(pEntry != NULL); + localPreLogTerm = pEntry->term; + syncEntryDestory(pEntry); + } + + bool logOK = + (pMsg->prevLogIndex == SYNC_INDEX_INVALID) || + ((pMsg->prevLogIndex >= SYNC_INDEX_BEGIN) && + (pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) && (pMsg->prevLogIndex == localPreLogTerm)); + + // reject + if ((pMsg->term < ths->pRaftStore->currentTerm) || + ((pMsg->term == ths->pRaftStore->currentTerm) && (ths->state == TAOS_SYNC_STATE_FOLLOWER) && !logOK)) { + SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(); + pReply->srcId = ths->myRaftId; + pReply->destId = pMsg->srcId; + pReply->term = ths->pRaftStore->currentTerm; + pReply->success = false; + pReply->matchIndex = SYNC_INDEX_INVALID; + + SRpcMsg rpcMsg; + syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg); + syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg); + syncAppendEntriesReplyDestroy(pReply); + + return ret; + } + + // return to follower state + if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_CANDIDATE) { + syncNodeBecomeFollower(ths); + } + + // accept request + if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_FOLLOWER && logOK) { + bool matchSuccess = false; + if (pMsg->prevLogIndex == SYNC_INDEX_INVALID && + ths->pLogStore->getLastIndex(ths->pLogStore) == SYNC_INDEX_INVALID) { + matchSuccess = true; + } + if (pMsg->prevLogIndex >= SYNC_INDEX_BEGIN && pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) { + SSyncRaftEntry* pEntry = logStoreGetEntry(ths->pLogStore, pMsg->prevLogTerm); + assert(pEntry != NULL); + if (pMsg->prevLogTerm == pEntry->term) { + matchSuccess = true; + } + syncEntryDestory(pEntry); + } + + if (matchSuccess) { + // delete conflict entries + if (ths->pLogStore->getLastIndex(ths->pLogStore) > pMsg->prevLogIndex) { + SyncIndex fromIndex = pMsg->prevLogIndex + 1; + ths->pLogStore->truncate(ths->pLogStore, fromIndex); + } + + // append one entry + if (pMsg->dataLen > 0) { + SSyncRaftEntry* pEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen); + ths->pLogStore->appendEntry(ths->pLogStore, pEntry); + syncEntryDestory(pEntry); + } + + SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(); + pReply->srcId = ths->myRaftId; + pReply->destId = pMsg->srcId; + pReply->term = ths->pRaftStore->currentTerm; + pReply->success = true; + pReply->matchIndex = pMsg->prevLogIndex + 1; + + SRpcMsg rpcMsg; + syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg); + syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg); + + syncAppendEntriesReplyDestroy(pReply); + } else { + SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(); + pReply->srcId = ths->myRaftId; + pReply->destId = pMsg->srcId; + pReply->term = ths->pRaftStore->currentTerm; + pReply->success = false; + pReply->matchIndex = SYNC_INDEX_INVALID; + + SRpcMsg rpcMsg; + syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg); + syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg); + syncAppendEntriesReplyDestroy(pReply); + } + + if (pMsg->commitIndex > ths->commitIndex) { + if (pMsg->commitIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) { + // commit + ths->commitIndex = pMsg->commitIndex; + ths->pLogStore->updateCommitIndex(ths->pLogStore, ths->commitIndex); + } + } + } + + return ret; +} diff --git a/source/libs/sync/src/syncAppendEntriesReply.c b/source/libs/sync/src/syncAppendEntriesReply.c index 0a5120c8dc..61eb4884e2 100644 --- a/source/libs/sync/src/syncAppendEntriesReply.c +++ b/source/libs/sync/src/syncAppendEntriesReply.c @@ -14,6 +14,12 @@ */ #include "syncAppendEntriesReply.h" +#include "syncIndexMgr.h" +#include "syncInt.h" +#include "syncRaftLog.h" +#include "syncRaftStore.h" +#include "syncUtil.h" +#include "syncVoteMgr.h" // TLA+ Spec // HandleAppendEntriesResponse(i, j, m) == @@ -28,4 +34,41 @@ // /\ Discard(m) // /\ UNCHANGED <> // -int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {} +int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) { + int32_t ret = 0; + syncAppendEntriesReplyLog2("==syncNodeOnAppendEntriesReplyCb==", pMsg); + + if (pMsg->term < ths->pRaftStore->currentTerm) { + sTrace("DropStaleResponse, receive term:%lu, current term:%lu", pMsg->term, ths->pRaftStore->currentTerm); + return ret; + } + + // no need this code, because if I receive reply.term, then I must have sent for that term. + // if (pMsg->term > ths->pRaftStore->currentTerm) { + // syncNodeUpdateTerm(ths, pMsg->term); + // } + + assert(pMsg->term == ths->pRaftStore->currentTerm); + + if (pMsg->success) { + // nextIndex = reply.matchIndex + 1 + syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), pMsg->matchIndex + 1); + + // matchIndex = reply.matchIndex + syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), pMsg->matchIndex); + + // maybe commit + syncNodeMaybeAdvanceCommitIndex(ths); + + } else { + SyncIndex nextIndex = syncIndexMgrGetIndex(ths->pNextIndex, &(pMsg->srcId)); + if (nextIndex > SYNC_INDEX_BEGIN) { + --nextIndex; + } else { + nextIndex = SYNC_INDEX_BEGIN; + } + syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), nextIndex); + } + + return ret; +} diff --git a/source/libs/sync/src/syncElection.c b/source/libs/sync/src/syncElection.c index 223431336e..77c3d07698 100644 --- a/source/libs/sync/src/syncElection.c +++ b/source/libs/sync/src/syncElection.c @@ -16,6 +16,7 @@ #include "syncElection.h" #include "syncMessage.h" #include "syncRaftStore.h" +#include "syncVoteMgr.h" // TLA+ Spec // RequestVote(i, j) == @@ -37,7 +38,7 @@ int32_t syncNodeRequestVotePeers(SSyncNode* pSyncNode) { SyncRequestVote* pMsg = syncRequestVoteBuild(); pMsg->srcId = pSyncNode->myRaftId; pMsg->destId = pSyncNode->peersId[i]; - pMsg->currentTerm = pSyncNode->pRaftStore->currentTerm; + pMsg->term = pSyncNode->pRaftStore->currentTerm; pMsg->lastLogIndex = pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore); pMsg->lastLogTerm = pSyncNode->pLogStore->getLastTerm(pSyncNode->pLogStore); @@ -49,10 +50,22 @@ int32_t syncNodeRequestVotePeers(SSyncNode* pSyncNode) { } int32_t syncNodeElect(SSyncNode* pSyncNode) { + if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER) { + syncNodeFollower2Candidate(pSyncNode); + } assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); // start election + raftStoreNextTerm(pSyncNode->pRaftStore); + raftStoreClearVote(pSyncNode->pRaftStore); + voteGrantedReset(pSyncNode->pVotesGranted, pSyncNode->pRaftStore->currentTerm); + votesRespondReset(pSyncNode->pVotesRespond, pSyncNode->pRaftStore->currentTerm); + + syncNodeVoteForSelf(pSyncNode); int32_t ret = syncNodeRequestVotePeers(pSyncNode); + assert(ret == 0); + syncNodeResetElectTimer(pSyncNode); + return ret; } diff --git a/source/libs/sync/src/syncEnv.c b/source/libs/sync/src/syncEnv.c index cb38b3f6f8..dd7161800d 100644 --- a/source/libs/sync/src/syncEnv.c +++ b/source/libs/sync/src/syncEnv.c @@ -19,19 +19,18 @@ SSyncEnv *gSyncEnv = NULL; // local function ----------------- -static void syncEnvTick(void *param, void *tmrId); -static int32_t doSyncEnvStart(SSyncEnv *pSyncEnv); -static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv); -static tmr_h doSyncEnvStartTimer(SSyncEnv *pSyncEnv, TAOS_TMR_CALLBACK fp, int mseconds, void *param); -static void doSyncEnvStopTimer(SSyncEnv *pSyncEnv, tmr_h *pTimer); +static SSyncEnv *doSyncEnvStart(); +static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv); +static int32_t doSyncEnvStartTimer(SSyncEnv *pSyncEnv); +static int32_t doSyncEnvStopTimer(SSyncEnv *pSyncEnv); +static void syncEnvTick(void *param, void *tmrId); // -------------------------------- int32_t syncEnvStart() { - int32_t ret; + int32_t ret = 0; taosSeedRand(taosGetTimestampSec()); - gSyncEnv = (SSyncEnv *)malloc(sizeof(SSyncEnv)); + gSyncEnv = doSyncEnvStart(gSyncEnv); assert(gSyncEnv != NULL); - ret = doSyncEnvStart(gSyncEnv); return ret; } @@ -40,31 +39,52 @@ int32_t syncEnvStop() { return ret; } -tmr_h syncEnvStartTimer(TAOS_TMR_CALLBACK fp, int mseconds, void *param) { - return doSyncEnvStartTimer(gSyncEnv, fp, mseconds, param); +int32_t syncEnvStartTimer() { + int32_t ret = doSyncEnvStartTimer(gSyncEnv); + return ret; } -void syncEnvStopTimer(tmr_h *pTimer) { doSyncEnvStopTimer(gSyncEnv, pTimer); } +int32_t syncEnvStopTimer() { + int32_t ret = doSyncEnvStopTimer(gSyncEnv); + return ret; +} // local function ----------------- static void syncEnvTick(void *param, void *tmrId) { SSyncEnv *pSyncEnv = (SSyncEnv *)param; - sTrace("syncEnvTick ... name:%s ", pSyncEnv->name); + if (atomic_load_64(&pSyncEnv->envTickTimerLogicClockUser) <= atomic_load_64(&pSyncEnv->envTickTimerLogicClock)) { + ++(pSyncEnv->envTickTimerCounter); + sTrace( + "syncEnvTick do ... envTickTimerLogicClockUser:%lu, envTickTimerLogicClock:%lu, envTickTimerCounter:%lu, " + "envTickTimerMS:%d, tmrId:%p", + pSyncEnv->envTickTimerLogicClockUser, pSyncEnv->envTickTimerLogicClock, pSyncEnv->envTickTimerCounter, + pSyncEnv->envTickTimerMS, tmrId); - pSyncEnv->pEnvTickTimer = taosTmrStart(syncEnvTick, 1000, pSyncEnv, pSyncEnv->pTimerManager); + // do something, tick ... + taosTmrReset(syncEnvTick, pSyncEnv->envTickTimerMS, pSyncEnv, pSyncEnv->pTimerManager, &pSyncEnv->pEnvTickTimer); + } else { + sTrace( + "syncEnvTick pass ... envTickTimerLogicClockUser:%lu, envTickTimerLogicClock:%lu, envTickTimerCounter:%lu, " + "envTickTimerMS:%d, tmrId:%p", + pSyncEnv->envTickTimerLogicClockUser, pSyncEnv->envTickTimerLogicClock, pSyncEnv->envTickTimerCounter, + pSyncEnv->envTickTimerMS, tmrId); + } } -static int32_t doSyncEnvStart(SSyncEnv *pSyncEnv) { - snprintf(pSyncEnv->name, sizeof(pSyncEnv->name), "SyncEnv_%p", pSyncEnv); +static SSyncEnv *doSyncEnvStart() { + SSyncEnv *pSyncEnv = (SSyncEnv *)malloc(sizeof(SSyncEnv)); + assert(pSyncEnv != NULL); + memset(pSyncEnv, 0, sizeof(pSyncEnv)); + + pSyncEnv->envTickTimerCounter = 0; + pSyncEnv->envTickTimerMS = ENV_TICK_TIMER_MS; + pSyncEnv->FpEnvTickTimer = syncEnvTick; + atomic_store_64(&pSyncEnv->envTickTimerLogicClock, 0); + atomic_store_64(&pSyncEnv->envTickTimerLogicClockUser, 0); // start tmr thread pSyncEnv->pTimerManager = taosTmrInit(1000, 50, 10000, "SYNC-ENV"); - - // pSyncEnv->pEnvTickTimer = taosTmrStart(syncEnvTick, 1000, pSyncEnv, pSyncEnv->pTimerManager); - - sTrace("SyncEnv start ok, name:%s", pSyncEnv->name); - - return 0; + return pSyncEnv; } static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv) { @@ -72,8 +92,18 @@ static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv) { return 0; } -static tmr_h doSyncEnvStartTimer(SSyncEnv *pSyncEnv, TAOS_TMR_CALLBACK fp, int mseconds, void *param) { - return taosTmrStart(fp, mseconds, pSyncEnv, pSyncEnv->pTimerManager); +static int32_t doSyncEnvStartTimer(SSyncEnv *pSyncEnv) { + int32_t ret = 0; + taosTmrReset(pSyncEnv->FpEnvTickTimer, pSyncEnv->envTickTimerMS, pSyncEnv, pSyncEnv->pTimerManager, + &pSyncEnv->pEnvTickTimer); + atomic_store_64(&pSyncEnv->envTickTimerLogicClock, pSyncEnv->envTickTimerLogicClockUser); + return ret; } -static void doSyncEnvStopTimer(SSyncEnv *pSyncEnv, tmr_h *pTimer) {} +static int32_t doSyncEnvStopTimer(SSyncEnv *pSyncEnv) { + int32_t ret = 0; + atomic_add_fetch_64(&pSyncEnv->envTickTimerLogicClockUser, 1); + taosTmrStop(pSyncEnv->pEnvTickTimer); + pSyncEnv->pEnvTickTimer = NULL; + return ret; +} diff --git a/source/libs/sync/src/syncIO.c b/source/libs/sync/src/syncIO.c index af97c4663c..8176ac417a 100644 --- a/source/libs/sync/src/syncIO.c +++ b/source/libs/sync/src/syncIO.c @@ -16,6 +16,7 @@ #include "syncIO.h" #include #include "syncMessage.h" +#include "syncUtil.h" #include "tglobal.h" #include "ttimer.h" #include "tutil.h" @@ -23,33 +24,36 @@ SSyncIO *gSyncIO = NULL; // local function ------------ -static int32_t syncIOStartInternal(SSyncIO *io); -static int32_t syncIOStopInternal(SSyncIO *io); static SSyncIO *syncIOCreate(char *host, uint16_t port); static int32_t syncIODestroy(SSyncIO *io); +static int32_t syncIOStartInternal(SSyncIO *io); +static int32_t syncIOStopInternal(SSyncIO *io); -static void *syncIOConsumerFunc(void *param); -static int syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey); -static void syncIOProcessRequest(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet); -static void syncIOProcessReply(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet); +static void *syncIOConsumerFunc(void *param); +static void syncIOProcessRequest(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet); +static void syncIOProcessReply(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet); +static int32_t syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey); -static int32_t syncIOTickQInternal(SSyncIO *io); -static void syncIOTickQFunc(void *param, void *tmrId); -static int32_t syncIOTickPingInternal(SSyncIO *io); -static void syncIOTickPingFunc(void *param, void *tmrId); +static int32_t syncIOStartQ(SSyncIO *io); +static int32_t syncIOStopQ(SSyncIO *io); +static int32_t syncIOStartPing(SSyncIO *io); +static int32_t syncIOStopPing(SSyncIO *io); +static void syncIOTickQ(void *param, void *tmrId); +static void syncIOTickPing(void *param, void *tmrId); // ---------------------------- // public function ------------ int32_t syncIOStart(char *host, uint16_t port) { + int32_t ret = 0; gSyncIO = syncIOCreate(host, port); assert(gSyncIO != NULL); taosSeedRand(taosGetTimestampSec()); - int32_t ret = syncIOStartInternal(gSyncIO); + ret = syncIOStartInternal(gSyncIO); assert(ret == 0); - sTrace("syncIOStart ok, gSyncIO:%p gSyncIO->clientRpc:%p", gSyncIO, gSyncIO->clientRpc); - return 0; + sTrace("syncIOStart ok, gSyncIO:%p", gSyncIO); + return ret; } int32_t syncIOStop() { @@ -61,37 +65,25 @@ int32_t syncIOStop() { return ret; } -int32_t syncIOTickQ() { - int32_t ret = syncIOTickQInternal(gSyncIO); - assert(ret == 0); - return ret; -} - -int32_t syncIOTickPing() { - int32_t ret = syncIOTickPingInternal(gSyncIO); - assert(ret == 0); - return ret; -} - int32_t syncIOSendMsg(void *clientRpc, const SEpSet *pEpSet, SRpcMsg *pMsg) { - sTrace( - "<--- syncIOSendMsg ---> clientRpc:%p, numOfEps:%d, inUse:%d, destAddr:%s-%u, pMsg->ahandle:%p, pMsg->handle:%p, " - "pMsg->msgType:%d, pMsg->contLen:%d", - clientRpc, pEpSet->numOfEps, pEpSet->inUse, pEpSet->eps[0].fqdn, pEpSet->eps[0].port, pMsg->ahandle, pMsg->handle, - pMsg->msgType, pMsg->contLen); - { - cJSON *pJson = syncRpcMsg2Json(pMsg); - char * serialized = cJSON_Print(pJson); - sTrace("process syncMessage send: pMsg:%s ", serialized); - free(serialized); - cJSON_Delete(pJson); - } + assert(pEpSet->inUse == 0); + assert(pEpSet->numOfEps == 1); + + int32_t ret = 0; + char logBuf[256]; + snprintf(logBuf, sizeof(logBuf), "==syncIOSendMsg== %s:%d", pEpSet->eps[0].fqdn, pEpSet->eps[0].port); + syncRpcMsgPrint2(logBuf, pMsg); + pMsg->handle = NULL; rpcSendRequest(clientRpc, pEpSet, pMsg, NULL); - return 0; + return ret; } int32_t syncIOEqMsg(void *queue, SRpcMsg *pMsg) { + int32_t ret = 0; + char logBuf[128]; + syncRpcMsgPrint2((char *)"==syncIOEqMsg==", pMsg); + SRpcMsg *pTemp; pTemp = taosAllocateQitem(sizeof(SRpcMsg)); memcpy(pTemp, pMsg, sizeof(SRpcMsg)); @@ -99,11 +91,75 @@ int32_t syncIOEqMsg(void *queue, SRpcMsg *pMsg) { STaosQueue *pMsgQ = queue; taosWriteQitem(pMsgQ, pTemp); - return 0; + return ret; +} + +int32_t syncIOQTimerStart() { + int32_t ret = syncIOStartQ(gSyncIO); + assert(ret == 0); + return ret; +} + +int32_t syncIOQTimerStop() { + int32_t ret = syncIOStopQ(gSyncIO); + assert(ret == 0); + return ret; +} + +int32_t syncIOPingTimerStart() { + int32_t ret = syncIOStartPing(gSyncIO); + assert(ret == 0); + return ret; +} + +int32_t syncIOPingTimerStop() { + int32_t ret = syncIOStopPing(gSyncIO); + assert(ret == 0); + return ret; } // local function ------------ +static SSyncIO *syncIOCreate(char *host, uint16_t port) { + SSyncIO *io = (SSyncIO *)malloc(sizeof(SSyncIO)); + memset(io, 0, sizeof(*io)); + + io->pMsgQ = taosOpenQueue(); + io->pQset = taosOpenQset(); + taosAddIntoQset(io->pQset, io->pMsgQ, NULL); + + io->myAddr.inUse = 0; + io->myAddr.numOfEps = 0; + addEpIntoEpSet(&io->myAddr, host, port); + + io->qTimerMS = TICK_Q_TIMER_MS; + io->pingTimerMS = TICK_Ping_TIMER_MS; + + return io; +} + +static int32_t syncIODestroy(SSyncIO *io) { + int32_t ret = 0; + int8_t start = atomic_load_8(&io->isStart); + assert(start == 0); + + if (io->serverRpc != NULL) { + rpcClose(io->serverRpc); + io->serverRpc = NULL; + } + + if (io->clientRpc != NULL) { + rpcClose(io->clientRpc); + io->clientRpc = NULL; + } + + taosCloseQueue(io->pMsgQ); + taosCloseQset(io->pQset); + + return ret; +} + static int32_t syncIOStartInternal(SSyncIO *io) { + int32_t ret = 0; taosBlockSIGPIPE(); rpcInit(); @@ -163,58 +219,24 @@ static int32_t syncIOStartInternal(SSyncIO *io) { } // start tmr thread - io->ioTimerManager = taosTmrInit(1000, 50, 10000, "SYNC"); + io->timerMgr = taosTmrInit(1000, 50, 10000, "SYNC-IO"); - return 0; + atomic_store_8(&io->isStart, 1); + return ret; } static int32_t syncIOStopInternal(SSyncIO *io) { + int32_t ret = 0; atomic_store_8(&io->isStart, 0); pthread_join(io->consumerTid, NULL); - return 0; -} - -static SSyncIO *syncIOCreate(char *host, uint16_t port) { - SSyncIO *io = (SSyncIO *)malloc(sizeof(SSyncIO)); - memset(io, 0, sizeof(*io)); - - io->pMsgQ = taosOpenQueue(); - io->pQset = taosOpenQset(); - taosAddIntoQset(io->pQset, io->pMsgQ, NULL); - - io->myAddr.inUse = 0; - addEpIntoEpSet(&io->myAddr, host, port); - - return io; -} - -static int32_t syncIODestroy(SSyncIO *io) { - int8_t start = atomic_load_8(&io->isStart); - assert(start == 0); - - if (io->serverRpc != NULL) { - free(io->serverRpc); - io->serverRpc = NULL; - } - - if (io->clientRpc != NULL) { - free(io->clientRpc); - io->clientRpc = NULL; - } - - taosCloseQueue(io->pMsgQ); - taosCloseQset(io->pQset); - - return 0; + taosTmrCleanUp(io->timerMgr); + return ret; } static void *syncIOConsumerFunc(void *param) { - SSyncIO *io = param; - + SSyncIO *io = param; STaosQall *qall; - SRpcMsg * pRpcMsg, rpcMsg; - int type; - + SRpcMsg *pRpcMsg, rpcMsg; qall = taosAllocateQall(); while (1) { @@ -226,77 +248,74 @@ static void *syncIOConsumerFunc(void *param) { for (int i = 0; i < numOfMsgs; ++i) { taosGetQitem(qall, (void **)&pRpcMsg); + syncRpcMsgLog2((char *)"==syncIOConsumerFunc==", pRpcMsg); - char *s = syncRpcMsg2Str(pRpcMsg); - sTrace("syncIOConsumerFunc get item from queue: msgType:%d contLen:%d msg:%s", pRpcMsg->msgType, pRpcMsg->contLen, - s); - free(s); - + // use switch case instead of if else if (pRpcMsg->msgType == SYNC_PING) { if (io->FpOnSyncPing != NULL) { - SyncPing *pSyncMsg; + SyncPing *pSyncMsg = syncPingFromRpcMsg2(pRpcMsg); + assert(pSyncMsg != NULL); + io->FpOnSyncPing(io->pSyncNode, pSyncMsg); + syncPingDestroy(pSyncMsg); + /* pSyncMsg = syncPingBuild(pRpcMsg->contLen); syncPingFromRpcMsg(pRpcMsg, pSyncMsg); // memcpy(pSyncMsg, tmpRpcMsg.pCont, tmpRpcMsg.contLen); io->FpOnSyncPing(io->pSyncNode, pSyncMsg); syncPingDestroy(pSyncMsg); + */ } } else if (pRpcMsg->msgType == SYNC_PING_REPLY) { if (io->FpOnSyncPingReply != NULL) { - SyncPingReply *pSyncMsg; - pSyncMsg = syncPingReplyBuild(pRpcMsg->contLen); - syncPingReplyFromRpcMsg(pRpcMsg, pSyncMsg); + SyncPingReply *pSyncMsg = syncPingReplyFromRpcMsg2(pRpcMsg); io->FpOnSyncPingReply(io->pSyncNode, pSyncMsg); syncPingReplyDestroy(pSyncMsg); } + } else if (pRpcMsg->msgType == SYNC_CLIENT_REQUEST) { + if (io->FpOnSyncClientRequest != NULL) { + SyncClientRequest *pSyncMsg = syncClientRequestFromRpcMsg2(pRpcMsg); + io->FpOnSyncClientRequest(io->pSyncNode, pSyncMsg); + syncClientRequestDestroy(pSyncMsg); + } + } else if (pRpcMsg->msgType == SYNC_REQUEST_VOTE) { if (io->FpOnSyncRequestVote != NULL) { - SyncRequestVote *pSyncMsg; - pSyncMsg = syncRequestVoteBuild(pRpcMsg->contLen); - syncRequestVoteFromRpcMsg(pRpcMsg, pSyncMsg); + SyncRequestVote *pSyncMsg = syncRequestVoteFromRpcMsg2(pRpcMsg); io->FpOnSyncRequestVote(io->pSyncNode, pSyncMsg); syncRequestVoteDestroy(pSyncMsg); } } else if (pRpcMsg->msgType == SYNC_REQUEST_VOTE_REPLY) { if (io->FpOnSyncRequestVoteReply != NULL) { - SyncRequestVoteReply *pSyncMsg; - pSyncMsg = syncRequestVoteReplyBuild(); - syncRequestVoteReplyFromRpcMsg(pRpcMsg, pSyncMsg); + SyncRequestVoteReply *pSyncMsg = syncRequestVoteReplyFromRpcMsg2(pRpcMsg); io->FpOnSyncRequestVoteReply(io->pSyncNode, pSyncMsg); syncRequestVoteReplyDestroy(pSyncMsg); } } else if (pRpcMsg->msgType == SYNC_APPEND_ENTRIES) { if (io->FpOnSyncAppendEntries != NULL) { - SyncAppendEntries *pSyncMsg; - pSyncMsg = syncAppendEntriesBuild(pRpcMsg->contLen); - syncAppendEntriesFromRpcMsg(pRpcMsg, pSyncMsg); + SyncAppendEntries *pSyncMsg = syncAppendEntriesFromRpcMsg2(pRpcMsg); io->FpOnSyncAppendEntries(io->pSyncNode, pSyncMsg); syncAppendEntriesDestroy(pSyncMsg); } } else if (pRpcMsg->msgType == SYNC_APPEND_ENTRIES_REPLY) { if (io->FpOnSyncAppendEntriesReply != NULL) { - SyncAppendEntriesReply *pSyncMsg; - pSyncMsg = syncAppendEntriesReplyBuild(); - syncAppendEntriesReplyFromRpcMsg(pRpcMsg, pSyncMsg); + SyncAppendEntriesReply *pSyncMsg = syncAppendEntriesReplyFromRpcMsg2(pRpcMsg); io->FpOnSyncAppendEntriesReply(io->pSyncNode, pSyncMsg); syncAppendEntriesReplyDestroy(pSyncMsg); } } else if (pRpcMsg->msgType == SYNC_TIMEOUT) { if (io->FpOnSyncTimeout != NULL) { - SyncTimeout *pSyncMsg; - pSyncMsg = syncTimeoutBuild(); - syncTimeoutFromRpcMsg(pRpcMsg, pSyncMsg); + SyncTimeout *pSyncMsg = syncTimeoutFromRpcMsg2(pRpcMsg); io->FpOnSyncTimeout(io->pSyncNode, pSyncMsg); syncTimeoutDestroy(pSyncMsg); } } else { - ; + sTrace("unknown msgType:%d, no operator", pRpcMsg->msgType); } } @@ -306,15 +325,16 @@ static void *syncIOConsumerFunc(void *param) { rpcFreeCont(pRpcMsg->pCont); if (pRpcMsg->handle != NULL) { - int msgSize = 128; + int msgSize = 32; memset(&rpcMsg, 0, sizeof(rpcMsg)); + rpcMsg.msgType = SYNC_RESPONSE; rpcMsg.pCont = rpcMallocCont(msgSize); rpcMsg.contLen = msgSize; snprintf(rpcMsg.pCont, rpcMsg.contLen, "%s", "give a reply"); rpcMsg.handle = pRpcMsg->handle; rpcMsg.code = 0; - sTrace("syncIOConsumerFunc rpcSendResponse ... msgType:%d contLen:%d", pRpcMsg->msgType, rpcMsg.contLen); + syncRpcMsgPrint2((char *)"syncIOConsumerFunc rpcSendResponse --> ", &rpcMsg); rpcSendResponse(&rpcMsg); } @@ -326,71 +346,95 @@ static void *syncIOConsumerFunc(void *param) { return NULL; } -static int syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey) { - // app shall retrieve the auth info based on meterID from DB or a data file - // demo code here only for simple demo - int ret = 0; - return ret; -} - static void syncIOProcessRequest(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet) { - sTrace("<-- syncIOProcessRequest --> type:%d, contLen:%d, cont:%s", pMsg->msgType, pMsg->contLen, - (char *)pMsg->pCont); - + syncRpcMsgPrint2((char *)"==syncIOProcessRequest==", pMsg); SSyncIO *io = pParent; SRpcMsg *pTemp; - pTemp = taosAllocateQitem(sizeof(SRpcMsg)); memcpy(pTemp, pMsg, sizeof(SRpcMsg)); - taosWriteQitem(io->pMsgQ, pTemp); } static void syncIOProcessReply(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet) { - sTrace("syncIOProcessReply: type:%d, contLen:%d msg:%s", pMsg->msgType, pMsg->contLen, (char *)pMsg->pCont); + if (pMsg->msgType == SYNC_RESPONSE) { + sTrace("==syncIOProcessReply=="); + } else { + syncRpcMsgPrint2((char *)"==syncIOProcessReply==", pMsg); + } rpcFreeCont(pMsg->pCont); } -static int32_t syncIOTickQInternal(SSyncIO *io) { - io->ioTimerTickQ = taosTmrStart(syncIOTickQFunc, 1000, io, io->ioTimerManager); - return 0; +static int32_t syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey) { + // app shall retrieve the auth info based on meterID from DB or a data file + // demo code here only for simple demo + int32_t ret = 0; + return ret; } -static void syncIOTickQFunc(void *param, void *tmrId) { +static int32_t syncIOStartQ(SSyncIO *io) { + int32_t ret = 0; + taosTmrReset(syncIOTickQ, io->qTimerMS, io, io->timerMgr, &io->qTimer); + return ret; +} + +static int32_t syncIOStopQ(SSyncIO *io) { + int32_t ret = 0; + taosTmrStop(io->qTimer); + io->qTimer = NULL; + return ret; +} + +static int32_t syncIOStartPing(SSyncIO *io) { + int32_t ret = 0; + taosTmrReset(syncIOTickPing, io->pingTimerMS, io, io->timerMgr, &io->pingTimer); + return ret; +} + +static int32_t syncIOStopPing(SSyncIO *io) { + int32_t ret = 0; + taosTmrStop(io->pingTimer); + io->pingTimer = NULL; + return ret; +} + +static void syncIOTickQ(void *param, void *tmrId) { SSyncIO *io = (SSyncIO *)param; - sTrace("<-- syncIOTickQFunc -->"); + + SRaftId srcId, destId; + srcId.addr = syncUtilAddr2U64(io->myAddr.eps[0].fqdn, io->myAddr.eps[0].port); + srcId.vgId = -1; + destId.addr = syncUtilAddr2U64(io->myAddr.eps[0].fqdn, io->myAddr.eps[0].port); + destId.vgId = -1; + SyncPingReply *pMsg = syncPingReplyBuild2(&srcId, &destId, "syncIOTickQ"); SRpcMsg rpcMsg; - rpcMsg.contLen = 64; - rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen); - snprintf(rpcMsg.pCont, rpcMsg.contLen, "%s", "syncIOTickQ"); - rpcMsg.handle = NULL; - rpcMsg.msgType = 55; - + syncPingReply2RpcMsg(pMsg, &rpcMsg); SRpcMsg *pTemp; pTemp = taosAllocateQitem(sizeof(SRpcMsg)); memcpy(pTemp, &rpcMsg, sizeof(SRpcMsg)); - + syncRpcMsgPrint2((char *)"==syncIOTickQ==", &rpcMsg); taosWriteQitem(io->pMsgQ, pTemp); - taosTmrReset(syncIOTickQFunc, 1000, io, io->ioTimerManager, &io->ioTimerTickQ); + syncPingReplyDestroy(pMsg); + + taosTmrReset(syncIOTickQ, io->qTimerMS, io, io->timerMgr, &io->qTimer); } -static int32_t syncIOTickPingInternal(SSyncIO *io) { - io->ioTimerTickPing = taosTmrStart(syncIOTickPingFunc, 1000, io, io->ioTimerManager); - return 0; -} - -static void syncIOTickPingFunc(void *param, void *tmrId) { +static void syncIOTickPing(void *param, void *tmrId) { SSyncIO *io = (SSyncIO *)param; - sTrace("<-- syncIOTickPingFunc -->"); + + SRaftId srcId, destId; + srcId.addr = syncUtilAddr2U64(io->myAddr.eps[0].fqdn, io->myAddr.eps[0].port); + srcId.vgId = -1; + destId.addr = syncUtilAddr2U64(io->myAddr.eps[0].fqdn, io->myAddr.eps[0].port); + destId.vgId = -1; + SyncPing *pMsg = syncPingBuild2(&srcId, &destId, "syncIOTickPing"); + // SyncPing *pMsg = syncPingBuild3(&srcId, &destId); SRpcMsg rpcMsg; - rpcMsg.contLen = 64; - rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen); - snprintf(rpcMsg.pCont, rpcMsg.contLen, "%s", "syncIOTickPing"); - rpcMsg.handle = NULL; - rpcMsg.msgType = 77; - + syncPing2RpcMsg(pMsg, &rpcMsg); + syncRpcMsgPrint2((char *)"==syncIOTickPing==", &rpcMsg); rpcSendRequest(io->clientRpc, &io->myAddr, &rpcMsg, NULL); - taosTmrReset(syncIOTickPingFunc, 1000, io, io->ioTimerManager, &io->ioTimerTickPing); + syncPingDestroy(pMsg); + + taosTmrReset(syncIOTickPing, io->pingTimerMS, io, io->timerMgr, &io->pingTimer); } \ No newline at end of file diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c index 860dd96cdf..dd2c142104 100644 --- a/source/libs/sync/src/syncMain.c +++ b/source/libs/sync/src/syncMain.c @@ -17,11 +17,14 @@ #include "sync.h" #include "syncAppendEntries.h" #include "syncAppendEntriesReply.h" +#include "syncElection.h" #include "syncEnv.h" #include "syncIndexMgr.h" #include "syncInt.h" +#include "syncMessage.h" #include "syncRaftLog.h" #include "syncRaftStore.h" +#include "syncReplication.h" #include "syncRequestVote.h" #include "syncRequestVoteReply.h" #include "syncTimeout.h" @@ -31,33 +34,32 @@ static int32_t tsNodeRefId = -1; // ------ local funciton --------- +// enqueue message ---- static void syncNodeEqPingTimer(void* param, void* tmrId); static void syncNodeEqElectTimer(void* param, void* tmrId); static void syncNodeEqHeartbeatTimer(void* param, void* tmrId); +// on message ---- static int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg); static int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg); - -static void UpdateTerm(SSyncNode* pSyncNode, SyncTerm term); -static void syncNodeBecomeFollower(SSyncNode* pSyncNode); -static void syncNodeBecomeLeader(SSyncNode* pSyncNode); -static void syncNodeFollower2Candidate(SSyncNode* pSyncNode); -static void syncNodeCandidate2Leader(SSyncNode* pSyncNode); -static void syncNodeLeader2Follower(SSyncNode* pSyncNode); -static void syncNodeCandidate2Follower(SSyncNode* pSyncNode); +static int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg); // --------------------------------- int32_t syncInit() { - sTrace("syncInit ok"); - return 0; + int32_t ret = syncEnvStart(); + return ret; } -void syncCleanUp() { sTrace("syncCleanUp ok"); } +void syncCleanUp() { + int32_t ret = syncEnvStop(); + assert(ret == 0); +} int64_t syncStart(const SSyncInfo* pSyncInfo) { + int32_t ret = 0; SSyncNode* pSyncNode = syncNodeOpen(pSyncInfo); assert(pSyncNode != NULL); - return 0; + return ret; } void syncStop(int64_t rid) { @@ -65,9 +67,13 @@ void syncStop(int64_t rid) { syncNodeClose(pSyncNode); } -int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg) { return 0; } +int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg) { + int32_t ret = 0; + return ret; +} int32_t syncForwardToPeer(int64_t rid, const SRpcMsg* pMsg, bool isWeak) { + int32_t ret = 0; SSyncNode* pSyncNode = NULL; // get pointer from rid if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) { SyncClientRequest* pSyncMsg = syncClientRequestBuild2(pMsg, 0, isWeak); @@ -75,11 +81,13 @@ int32_t syncForwardToPeer(int64_t rid, const SRpcMsg* pMsg, bool isWeak) { syncClientRequest2RpcMsg(pSyncMsg, &rpcMsg); pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg); syncClientRequestDestroy(pSyncMsg); + ret = 0; + } else { sTrace("syncForwardToPeer not leader, %s", syncUtilState2String(pSyncNode->state)); - return -1; // need define err code !! + ret = -1; // need define err code !! } - return 0; + return ret; } ESyncState syncGetMyRole(int64_t rid) { @@ -89,6 +97,7 @@ ESyncState syncGetMyRole(int64_t rid) { void syncGetNodesRole(int64_t rid, SNodesRole* pNodeRole) {} +// open/close -------------- SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) { SSyncNode* pSyncNode = (SSyncNode*)malloc(sizeof(SSyncNode)); assert(pSyncNode != NULL); @@ -162,7 +171,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) { pSyncNode->pingTimerMS = PING_TIMER_MS; atomic_store_64(&pSyncNode->pingTimerLogicClock, 0); atomic_store_64(&pSyncNode->pingTimerLogicClockUser, 0); - pSyncNode->FpPingTimer = syncNodeEqPingTimer; + pSyncNode->FpPingTimerCB = syncNodeEqPingTimer; pSyncNode->pingTimerCounter = 0; // init elect timer @@ -170,7 +179,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) { pSyncNode->electTimerMS = syncUtilElectRandomMS(); atomic_store_64(&pSyncNode->electTimerLogicClock, 0); atomic_store_64(&pSyncNode->electTimerLogicClockUser, 0); - pSyncNode->FpElectTimer = syncNodeEqElectTimer; + pSyncNode->FpElectTimerCB = syncNodeEqElectTimer; pSyncNode->electTimerCounter = 0; // init heartbeat timer @@ -178,12 +187,13 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) { pSyncNode->heartbeatTimerMS = HEARTBEAT_TIMER_MS; atomic_store_64(&pSyncNode->heartbeatTimerLogicClock, 0); atomic_store_64(&pSyncNode->heartbeatTimerLogicClockUser, 0); - pSyncNode->FpHeartbeatTimer = syncNodeEqHeartbeatTimer; + pSyncNode->FpHeartbeatTimerCB = syncNodeEqHeartbeatTimer; pSyncNode->heartbeatTimerCounter = 0; // init callback pSyncNode->FpOnPing = syncNodeOnPingCb; pSyncNode->FpOnPingReply = syncNodeOnPingReplyCb; + pSyncNode->FpOnClientRequest = syncNodeOnClientRequestCb; pSyncNode->FpOnRequestVote = syncNodeOnRequestVoteCb; pSyncNode->FpOnRequestVoteReply = syncNodeOnRequestVoteReplyCb; pSyncNode->FpOnAppendEntries = syncNodeOnAppendEntriesCb; @@ -194,10 +204,153 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) { } void syncNodeClose(SSyncNode* pSyncNode) { + int32_t ret; assert(pSyncNode != NULL); + + ret = raftStoreClose(pSyncNode->pRaftStore); + assert(ret == 0); + + voteGrantedDestroy(pSyncNode->pVotesGranted); + votesRespondDestory(pSyncNode->pVotesRespond); + syncIndexMgrDestroy(pSyncNode->pNextIndex); + syncIndexMgrDestroy(pSyncNode->pMatchIndex); + logStoreDestory(pSyncNode->pLogStore); + + syncNodeStopPingTimer(pSyncNode); + syncNodeStopElectTimer(pSyncNode); + syncNodeStopHeartbeatTimer(pSyncNode); + free(pSyncNode); } +// ping -------------- +int32_t syncNodePing(SSyncNode* pSyncNode, const SRaftId* destRaftId, SyncPing* pMsg) { + syncPingLog2((char*)"==syncNodePing==", pMsg); + int32_t ret = 0; + + SRpcMsg rpcMsg; + syncPing2RpcMsg(pMsg, &rpcMsg); + syncRpcMsgLog2((char*)"==syncNodePing==", &rpcMsg); + + ret = syncNodeSendMsgById(destRaftId, pSyncNode, &rpcMsg); + return ret; +} + +int32_t syncNodePingSelf(SSyncNode* pSyncNode) { + int32_t ret = 0; + SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &pSyncNode->myRaftId); + ret = syncNodePing(pSyncNode, &pMsg->destId, pMsg); + assert(ret == 0); + + syncPingDestroy(pMsg); + return ret; +} + +int32_t syncNodePingPeers(SSyncNode* pSyncNode) { + int32_t ret = 0; + for (int i = 0; i < pSyncNode->peersNum; ++i) { + SRaftId destId; + syncUtilnodeInfo2raftId(&pSyncNode->peersNodeInfo[i], pSyncNode->vgId, &destId); + SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &destId); + ret = syncNodePing(pSyncNode, &destId, pMsg); + assert(ret == 0); + syncPingDestroy(pMsg); + } + return ret; +} + +int32_t syncNodePingAll(SSyncNode* pSyncNode) { + int32_t ret = 0; + for (int i = 0; i < pSyncNode->syncCfg.replicaNum; ++i) { + SRaftId destId; + syncUtilnodeInfo2raftId(&pSyncNode->syncCfg.nodeInfo[i], pSyncNode->vgId, &destId); + SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &destId); + ret = syncNodePing(pSyncNode, &destId, pMsg); + assert(ret == 0); + syncPingDestroy(pMsg); + } + return ret; +} + +// timer control -------------- +int32_t syncNodeStartPingTimer(SSyncNode* pSyncNode) { + int32_t ret = 0; + taosTmrReset(pSyncNode->FpPingTimerCB, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager, + &pSyncNode->pPingTimer); + atomic_store_64(&pSyncNode->pingTimerLogicClock, pSyncNode->pingTimerLogicClockUser); + return ret; +} + +int32_t syncNodeStopPingTimer(SSyncNode* pSyncNode) { + int32_t ret = 0; + atomic_add_fetch_64(&pSyncNode->pingTimerLogicClockUser, 1); + taosTmrStop(pSyncNode->pPingTimer); + pSyncNode->pPingTimer = NULL; + return ret; +} + +int32_t syncNodeStartElectTimer(SSyncNode* pSyncNode, int32_t ms) { + int32_t ret = 0; + pSyncNode->electTimerMS = ms; + taosTmrReset(pSyncNode->FpElectTimerCB, pSyncNode->electTimerMS, pSyncNode, gSyncEnv->pTimerManager, + &pSyncNode->pElectTimer); + atomic_store_64(&pSyncNode->electTimerLogicClock, pSyncNode->electTimerLogicClockUser); + return ret; +} + +int32_t syncNodeStopElectTimer(SSyncNode* pSyncNode) { + int32_t ret = 0; + atomic_add_fetch_64(&pSyncNode->electTimerLogicClockUser, 1); + taosTmrStop(pSyncNode->pElectTimer); + pSyncNode->pElectTimer = NULL; + return ret; +} + +int32_t syncNodeRestartElectTimer(SSyncNode* pSyncNode, int32_t ms) { + int32_t ret = 0; + syncNodeStopElectTimer(pSyncNode); + syncNodeStartElectTimer(pSyncNode, ms); + return ret; +} + +int32_t syncNodeResetElectTimer(SSyncNode* pSyncNode) { + int32_t ret = 0; + int32_t electMS = syncUtilElectRandomMS(); + ret = syncNodeRestartElectTimer(pSyncNode, electMS); + return ret; +} + +int32_t syncNodeStartHeartbeatTimer(SSyncNode* pSyncNode) { + int32_t ret = 0; + taosTmrReset(pSyncNode->FpHeartbeatTimerCB, pSyncNode->heartbeatTimerMS, pSyncNode, gSyncEnv->pTimerManager, + &pSyncNode->pHeartbeatTimer); + atomic_store_64(&pSyncNode->heartbeatTimerLogicClock, pSyncNode->heartbeatTimerLogicClockUser); + return ret; +} + +int32_t syncNodeStopHeartbeatTimer(SSyncNode* pSyncNode) { + int32_t ret = 0; + atomic_add_fetch_64(&pSyncNode->heartbeatTimerLogicClockUser, 1); + taosTmrStop(pSyncNode->pHeartbeatTimer); + pSyncNode->pHeartbeatTimer = NULL; + return ret; +} + +// utils -------------- +int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, SRpcMsg* pMsg) { + SEpSet epSet; + syncUtilraftId2EpSet(destRaftId, &epSet); + pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, pMsg); + return 0; +} + +int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg) { + SEpSet epSet; + syncUtilnodeInfo2EpSet(nodeInfo, &epSet); + pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, pMsg); + return 0; +} + cJSON* syncNode2Json(const SSyncNode* pSyncNode) { char u64buf[128]; cJSON* pRoot = cJSON_CreateObject(); @@ -253,12 +406,22 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) { // tla+ server vars cJSON_AddNumberToObject(pRoot, "state", pSyncNode->state); cJSON_AddStringToObject(pRoot, "state_str", syncUtilState2String(pSyncNode->state)); + char tmpBuf[RAFT_STORE_BLOCK_SIZE]; + raftStoreSerialize(pSyncNode->pRaftStore, tmpBuf, sizeof(tmpBuf)); + cJSON_AddStringToObject(pRoot, "pRaftStore", tmpBuf); // tla+ candidate vars + cJSON_AddItemToObject(pRoot, "pVotesGranted", voteGranted2Json(pSyncNode->pVotesGranted)); + cJSON_AddItemToObject(pRoot, "pVotesRespond", votesRespond2Json(pSyncNode->pVotesRespond)); // tla+ leader vars + cJSON_AddItemToObject(pRoot, "pNextIndex", syncIndexMgr2Json(pSyncNode->pNextIndex)); + cJSON_AddItemToObject(pRoot, "pMatchIndex", syncIndexMgr2Json(pSyncNode->pMatchIndex)); // tla+ log vars + cJSON_AddItemToObject(pRoot, "pLogStore", logStore2Json(pSyncNode->pLogStore)); + snprintf(u64buf, sizeof(u64buf), "%ld", pSyncNode->commitIndex); + cJSON_AddStringToObject(pRoot, "commitIndex", u64buf); // ping timer snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->pPingTimer); @@ -268,8 +431,8 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) { cJSON_AddStringToObject(pRoot, "pingTimerLogicClock", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->pingTimerLogicClockUser); cJSON_AddStringToObject(pRoot, "pingTimerLogicClockUser", u64buf); - snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpPingTimer); - cJSON_AddStringToObject(pRoot, "FpPingTimer", u64buf); + snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpPingTimerCB); + cJSON_AddStringToObject(pRoot, "FpPingTimerCB", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->pingTimerCounter); cJSON_AddStringToObject(pRoot, "pingTimerCounter", u64buf); @@ -281,8 +444,8 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) { cJSON_AddStringToObject(pRoot, "electTimerLogicClock", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->electTimerLogicClockUser); cJSON_AddStringToObject(pRoot, "electTimerLogicClockUser", u64buf); - snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpElectTimer); - cJSON_AddStringToObject(pRoot, "FpElectTimer", u64buf); + snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpElectTimerCB); + cJSON_AddStringToObject(pRoot, "FpElectTimerCB", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->electTimerCounter); cJSON_AddStringToObject(pRoot, "electTimerCounter", u64buf); @@ -294,8 +457,8 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) { cJSON_AddStringToObject(pRoot, "heartbeatTimerLogicClock", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->heartbeatTimerLogicClockUser); cJSON_AddStringToObject(pRoot, "heartbeatTimerLogicClockUser", u64buf); - snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpHeartbeatTimer); - cJSON_AddStringToObject(pRoot, "FpHeartbeatTimer", u64buf); + snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpHeartbeatTimerCB); + cJSON_AddStringToObject(pRoot, "FpHeartbeatTimerCB", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->heartbeatTimerCounter); cJSON_AddStringToObject(pRoot, "heartbeatTimerCounter", u64buf); @@ -327,6 +490,107 @@ char* syncNode2Str(const SSyncNode* pSyncNode) { return serialized; } +// raft state change -------------- +void syncNodeUpdateTerm(SSyncNode* pSyncNode, SyncTerm term) { + if (term > pSyncNode->pRaftStore->currentTerm) { + raftStoreSetTerm(pSyncNode->pRaftStore, term); + syncNodeBecomeFollower(pSyncNode); + raftStoreClearVote(pSyncNode->pRaftStore); + } +} + +void syncNodeBecomeFollower(SSyncNode* pSyncNode) { + if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) { + pSyncNode->leaderCache = EMPTY_RAFT_ID; + } + + pSyncNode->state = TAOS_SYNC_STATE_FOLLOWER; + syncNodeStopHeartbeatTimer(pSyncNode); + + int32_t electMS = syncUtilElectRandomMS(); + syncNodeRestartElectTimer(pSyncNode, electMS); +} + +// TLA+ Spec +// \* Candidate i transitions to leader. +// BecomeLeader(i) == +// /\ state[i] = Candidate +// /\ votesGranted[i] \in Quorum +// /\ state' = [state EXCEPT ![i] = Leader] +// /\ nextIndex' = [nextIndex EXCEPT ![i] = +// [j \in Server |-> Len(log[i]) + 1]] +// /\ matchIndex' = [matchIndex EXCEPT ![i] = +// [j \in Server |-> 0]] +// /\ elections' = elections \cup +// {[eterm |-> currentTerm[i], +// eleader |-> i, +// elog |-> log[i], +// evotes |-> votesGranted[i], +// evoterLog |-> voterLog[i]]} +// /\ UNCHANGED <> +// +void syncNodeBecomeLeader(SSyncNode* pSyncNode) { + pSyncNode->state = TAOS_SYNC_STATE_LEADER; + pSyncNode->leaderCache = pSyncNode->myRaftId; + + for (int i = 0; i < pSyncNode->pNextIndex->replicaNum; ++i) { + pSyncNode->pNextIndex->index[i] = pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore) + 1; + } + + for (int i = 0; i < pSyncNode->pMatchIndex->replicaNum; ++i) { + pSyncNode->pMatchIndex->index[i] = SYNC_INDEX_INVALID; + } + + syncNodeStopElectTimer(pSyncNode); + syncNodeStartHeartbeatTimer(pSyncNode); + syncNodeReplicate(pSyncNode); +} + +void syncNodeCandidate2Leader(SSyncNode* pSyncNode) { + assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); + assert(voteGrantedMajority(pSyncNode->pVotesGranted)); + syncNodeBecomeLeader(pSyncNode); +} + +void syncNodeFollower2Candidate(SSyncNode* pSyncNode) { + assert(pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER); + pSyncNode->state = TAOS_SYNC_STATE_CANDIDATE; +} + +void syncNodeLeader2Follower(SSyncNode* pSyncNode) { + assert(pSyncNode->state == TAOS_SYNC_STATE_LEADER); + syncNodeBecomeFollower(pSyncNode); +} + +void syncNodeCandidate2Follower(SSyncNode* pSyncNode) { + assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); + syncNodeBecomeFollower(pSyncNode); +} + +// raft vote -------------- +void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId) { + assert(term == pSyncNode->pRaftStore->currentTerm); + assert(!raftStoreHasVoted(pSyncNode->pRaftStore)); + + raftStoreVote(pSyncNode->pRaftStore, pRaftId); +} + +void syncNodeVoteForSelf(SSyncNode* pSyncNode) { + syncNodeVoteForTerm(pSyncNode, pSyncNode->pRaftStore->currentTerm, &(pSyncNode->myRaftId)); + + SyncRequestVoteReply* pMsg = syncRequestVoteReplyBuild(); + pMsg->srcId = pSyncNode->myRaftId; + pMsg->destId = pSyncNode->myRaftId; + pMsg->term = pSyncNode->pRaftStore->currentTerm; + pMsg->voteGranted = true; + + voteGrantedVote(pSyncNode->pVotesGranted, pMsg); + votesRespondAdd(pSyncNode->pVotesRespond, pMsg); + syncRequestVoteReplyDestroy(pMsg); +} + +void syncNodeMaybeAdvanceCommitIndex(SSyncNode* pSyncNode) {} + // for debug -------------- void syncNodePrint(SSyncNode* pObj) { char* serialized = syncNode2Str(pObj); @@ -354,199 +618,24 @@ void syncNodeLog2(char* s, SSyncNode* pObj) { free(serialized); } -int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, SRpcMsg* pMsg) { - SEpSet epSet; - syncUtilraftId2EpSet(destRaftId, &epSet); - pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, pMsg); - return 0; -} - -int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg) { - SEpSet epSet; - syncUtilnodeInfo2EpSet(nodeInfo, &epSet); - pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, pMsg); - return 0; -} - -int32_t syncNodePing(SSyncNode* pSyncNode, const SRaftId* destRaftId, SyncPing* pMsg) { - sTrace("syncNodePing pSyncNode:%p ", pSyncNode); - int32_t ret = 0; - - SRpcMsg rpcMsg; - syncPing2RpcMsg(pMsg, &rpcMsg); - syncNodeSendMsgById(destRaftId, pSyncNode, &rpcMsg); - - { - cJSON* pJson = syncPing2Json(pMsg); - char* serialized = cJSON_Print(pJson); - sTrace("syncNodePing pMsg:%s ", serialized); - free(serialized); - cJSON_Delete(pJson); - } - - { - SyncPing* pMsg2 = rpcMsg.pCont; - cJSON* pJson = syncPing2Json(pMsg2); - char* serialized = cJSON_Print(pJson); - sTrace("syncNodePing rpcMsg.pCont:%s ", serialized); - free(serialized); - cJSON_Delete(pJson); - } - - return ret; -} - -int32_t syncNodePingAll(SSyncNode* pSyncNode) { - sTrace("syncNodePingAll pSyncNode:%p ", pSyncNode); - int32_t ret = 0; - for (int i = 0; i < pSyncNode->syncCfg.replicaNum; ++i) { - SRaftId destId; - syncUtilnodeInfo2raftId(&pSyncNode->syncCfg.nodeInfo[i], pSyncNode->vgId, &destId); - SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &destId); - ret = syncNodePing(pSyncNode, &destId, pMsg); - assert(ret == 0); - syncPingDestroy(pMsg); - } -} - -int32_t syncNodePingPeers(SSyncNode* pSyncNode) { - int32_t ret = 0; - for (int i = 0; i < pSyncNode->peersNum; ++i) { - SRaftId destId; - syncUtilnodeInfo2raftId(&pSyncNode->peersNodeInfo[i], pSyncNode->vgId, &destId); - SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &destId); - ret = syncNodePing(pSyncNode, &destId, pMsg); - assert(ret == 0); - syncPingDestroy(pMsg); - } -} - -int32_t syncNodePingSelf(SSyncNode* pSyncNode) { - int32_t ret; - SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &pSyncNode->myRaftId); - ret = syncNodePing(pSyncNode, &pMsg->destId, pMsg); - assert(ret == 0); - syncPingDestroy(pMsg); -} - -int32_t syncNodeStartPingTimer(SSyncNode* pSyncNode) { - atomic_store_64(&pSyncNode->pingTimerLogicClock, pSyncNode->pingTimerLogicClockUser); - pSyncNode->pingTimerMS = PING_TIMER_MS; - if (pSyncNode->pPingTimer == NULL) { - pSyncNode->pPingTimer = - taosTmrStart(pSyncNode->FpPingTimer, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager); - } else { - taosTmrReset(pSyncNode->FpPingTimer, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager, - &pSyncNode->pPingTimer); - } - return 0; -} - -int32_t syncNodeStopPingTimer(SSyncNode* pSyncNode) { - atomic_add_fetch_64(&pSyncNode->pingTimerLogicClockUser, 1); - pSyncNode->pingTimerMS = TIMER_MAX_MS; - return 0; -} - -int32_t syncNodeStartElectTimer(SSyncNode* pSyncNode, int32_t ms) { - pSyncNode->electTimerMS = ms; - atomic_store_64(&pSyncNode->electTimerLogicClock, pSyncNode->electTimerLogicClockUser); - if (pSyncNode->pElectTimer == NULL) { - pSyncNode->pElectTimer = - taosTmrStart(pSyncNode->FpElectTimer, pSyncNode->electTimerMS, pSyncNode, gSyncEnv->pTimerManager); - } else { - taosTmrReset(pSyncNode->FpElectTimer, pSyncNode->electTimerMS, pSyncNode, gSyncEnv->pTimerManager, - &pSyncNode->pElectTimer); - } - return 0; -} - -int32_t syncNodeStopElectTimer(SSyncNode* pSyncNode) { - atomic_add_fetch_64(&pSyncNode->electTimerLogicClockUser, 1); - pSyncNode->electTimerMS = TIMER_MAX_MS; - return 0; -} - -int32_t syncNodeRestartElectTimer(SSyncNode* pSyncNode, int32_t ms) { - syncNodeStopElectTimer(pSyncNode); - syncNodeStartElectTimer(pSyncNode, ms); - return 0; -} - -int32_t syncNodeStartHeartbeatTimer(SSyncNode* pSyncNode) { - atomic_store_64(&pSyncNode->heartbeatTimerLogicClock, pSyncNode->heartbeatTimerLogicClockUser); - if (pSyncNode->pHeartbeatTimer == NULL) { - pSyncNode->pHeartbeatTimer = - taosTmrStart(pSyncNode->FpHeartbeatTimer, pSyncNode->heartbeatTimerMS, pSyncNode, gSyncEnv->pTimerManager); - } else { - taosTmrReset(pSyncNode->FpHeartbeatTimer, pSyncNode->heartbeatTimerMS, pSyncNode, gSyncEnv->pTimerManager, - &pSyncNode->pHeartbeatTimer); - } - return 0; -} - -int32_t syncNodeStopHeartbeatTimer(SSyncNode* pSyncNode) { - atomic_add_fetch_64(&pSyncNode->heartbeatTimerLogicClockUser, 1); - pSyncNode->heartbeatTimerMS = TIMER_MAX_MS; - return 0; -} - // ------ local funciton --------- -static int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg) { - int32_t ret = 0; - sTrace("<-- syncNodeOnPingCb -->"); - - { - cJSON* pJson = syncPing2Json(pMsg); - char* serialized = cJSON_Print(pJson); - sTrace("process syncMessage recv: syncNodeOnPingCb pMsg:%s ", serialized); - free(serialized); - cJSON_Delete(pJson); - } - - SyncPingReply* pMsgReply = syncPingReplyBuild3(&ths->myRaftId, &pMsg->srcId); - SRpcMsg rpcMsg; - syncPingReply2RpcMsg(pMsgReply, &rpcMsg); - syncNodeSendMsgById(&pMsgReply->destId, ths, &rpcMsg); - - return ret; -} - -static int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg) { - int32_t ret = 0; - sTrace("<-- syncNodeOnPingReplyCb -->"); - - { - cJSON* pJson = syncPingReply2Json(pMsg); - char* serialized = cJSON_Print(pJson); - sTrace("process syncMessage recv: syncNodeOnPingReplyCb pMsg:%s ", serialized); - free(serialized); - cJSON_Delete(pJson); - } - - return ret; -} - +// enqueue message ---- static void syncNodeEqPingTimer(void* param, void* tmrId) { - sTrace("<-- syncNodeEqPingTimer -->"); - SSyncNode* pSyncNode = (SSyncNode*)param; if (atomic_load_64(&pSyncNode->pingTimerLogicClockUser) <= atomic_load_64(&pSyncNode->pingTimerLogicClock)) { SyncTimeout* pSyncMsg = syncTimeoutBuild2(SYNC_TIMEOUT_PING, atomic_load_64(&pSyncNode->pingTimerLogicClock), pSyncNode->pingTimerMS, pSyncNode); SRpcMsg rpcMsg; syncTimeout2RpcMsg(pSyncMsg, &rpcMsg); + syncRpcMsgLog2((char*)"==syncNodeEqPingTimer==", &rpcMsg); pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg); syncTimeoutDestroy(pSyncMsg); - // reset timer ms - // pSyncNode->pingTimerMS += 100; - taosTmrReset(syncNodeEqPingTimer, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager, &pSyncNode->pPingTimer); } else { - sTrace("syncNodeEqPingTimer: pingTimerLogicClock:%lu, pingTimerLogicClockUser:%lu", pSyncNode->pingTimerLogicClock, - pSyncNode->pingTimerLogicClockUser); + sTrace("==syncNodeEqPingTimer== pingTimerLogicClock:%lu, pingTimerLogicClockUser:%lu", + pSyncNode->pingTimerLogicClock, pSyncNode->pingTimerLogicClockUser); } } @@ -555,19 +644,18 @@ static void syncNodeEqElectTimer(void* param, void* tmrId) { if (atomic_load_64(&pSyncNode->electTimerLogicClockUser) <= atomic_load_64(&pSyncNode->electTimerLogicClock)) { SyncTimeout* pSyncMsg = syncTimeoutBuild2(SYNC_TIMEOUT_ELECTION, atomic_load_64(&pSyncNode->electTimerLogicClock), pSyncNode->electTimerMS, pSyncNode); - - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncTimeout2RpcMsg(pSyncMsg, &rpcMsg); + syncRpcMsgLog2((char*)"==syncNodeEqElectTimer==", &rpcMsg); pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg); syncTimeoutDestroy(pSyncMsg); // reset timer ms pSyncNode->electTimerMS = syncUtilElectRandomMS(); - taosTmrReset(syncNodeEqPingTimer, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager, &pSyncNode->pPingTimer); } else { - sTrace("syncNodeEqElectTimer: electTimerLogicClock:%lu, electTimerLogicClockUser:%lu", + sTrace("==syncNodeEqElectTimer== electTimerLogicClock:%lu, electTimerLogicClockUser:%lu", pSyncNode->electTimerLogicClock, pSyncNode->electTimerLogicClockUser); } } @@ -579,80 +667,50 @@ static void syncNodeEqHeartbeatTimer(void* param, void* tmrId) { SyncTimeout* pSyncMsg = syncTimeoutBuild2(SYNC_TIMEOUT_HEARTBEAT, atomic_load_64(&pSyncNode->heartbeatTimerLogicClock), pSyncNode->heartbeatTimerMS, pSyncNode); - SRpcMsg rpcMsg; syncTimeout2RpcMsg(pSyncMsg, &rpcMsg); + syncRpcMsgLog2((char*)"==syncNodeEqHeartbeatTimer==", &rpcMsg); pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg); syncTimeoutDestroy(pSyncMsg); - // reset timer ms - // pSyncNode->heartbeatTimerMS += 100; - taosTmrReset(syncNodeEqHeartbeatTimer, pSyncNode->heartbeatTimerMS, pSyncNode, gSyncEnv->pTimerManager, &pSyncNode->pHeartbeatTimer); } else { - sTrace("syncNodeEqHeartbeatTimer: heartbeatTimerLogicClock:%lu, heartbeatTimerLogicClockUser:%lu", + sTrace("==syncNodeEqHeartbeatTimer== heartbeatTimerLogicClock:%lu, heartbeatTimerLogicClockUser:%lu", pSyncNode->heartbeatTimerLogicClock, pSyncNode->heartbeatTimerLogicClockUser); } } -static void UpdateTerm(SSyncNode* pSyncNode, SyncTerm term) { - if (term > pSyncNode->pRaftStore->currentTerm) { - pSyncNode->pRaftStore->currentTerm = term; - pSyncNode->pRaftStore->voteFor = EMPTY_RAFT_ID; - raftStorePersist(pSyncNode->pRaftStore); - syncNodeBecomeFollower(pSyncNode); - } +// on message ---- +static int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg) { + int32_t ret = 0; + syncPingLog2("==syncNodeOnPingCb==", pMsg); + SyncPingReply* pMsgReply = syncPingReplyBuild3(&ths->myRaftId, &pMsg->srcId); + SRpcMsg rpcMsg; + syncPingReply2RpcMsg(pMsgReply, &rpcMsg); + syncNodeSendMsgById(&pMsgReply->destId, ths, &rpcMsg); + + return ret; } -static void syncNodeBecomeFollower(SSyncNode* pSyncNode) { - if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) { - pSyncNode->leaderCache = EMPTY_RAFT_ID; +static int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg) { + int32_t ret = 0; + syncPingReplyLog2("==syncNodeOnPingReplyCb==", pMsg); + return ret; +} + +static int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg) { + int32_t ret = 0; + syncClientRequestLog2("==syncNodeOnClientRequestCb==", pMsg); + + if (ths->state == TAOS_SYNC_STATE_LEADER) { + SSyncRaftEntry* pEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen); + ths->pLogStore->appendEntry(ths->pLogStore, pEntry); + syncNodeReplicate(ths); + syncEntryDestory(pEntry); + } else { + // ths->pFsm->FpCommitCb(-1) } - syncNodeStopHeartbeatTimer(pSyncNode); - int32_t electMS = syncUtilElectRandomMS(); - syncNodeStartElectTimer(pSyncNode, electMS); -} - -// TLA+ Spec -// \* Candidate i transitions to leader. -// BecomeLeader(i) == -// /\ state[i] = Candidate -// /\ votesGranted[i] \in Quorum -// /\ state' = [state EXCEPT ![i] = Leader] -// /\ nextIndex' = [nextIndex EXCEPT ![i] = -// [j \in Server |-> Len(log[i]) + 1]] -// /\ matchIndex' = [matchIndex EXCEPT ![i] = -// [j \in Server |-> 0]] -// /\ elections' = elections \cup -// {[eterm |-> currentTerm[i], -// eleader |-> i, -// elog |-> log[i], -// evotes |-> votesGranted[i], -// evoterLog |-> voterLog[i]]} -// /\ UNCHANGED <> -// -static void syncNodeBecomeLeader(SSyncNode* pSyncNode) { - pSyncNode->state = TAOS_SYNC_STATE_LEADER; - pSyncNode->leaderCache = pSyncNode->myRaftId; - - // next Index +=1 - // match Index = 0; - - syncNodeStopElectTimer(pSyncNode); - syncNodeStartHeartbeatTimer(pSyncNode); - - // appendEntries; -} - -static void syncNodeFollower2Candidate(SSyncNode* pSyncNode) { - assert(pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER); - pSyncNode->state = TAOS_SYNC_STATE_CANDIDATE; -} - -static void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {} - -static void syncNodeLeader2Follower(SSyncNode* pSyncNode) {} - -static void syncNodeCandidate2Follower(SSyncNode* pSyncNode) {} + return ret; +} \ No newline at end of file diff --git a/source/libs/sync/src/syncMessage.c b/source/libs/sync/src/syncMessage.c index 5a55bbc11f..509ede274b 100644 --- a/source/libs/sync/src/syncMessage.c +++ b/source/libs/sync/src/syncMessage.c @@ -65,10 +65,32 @@ cJSON* syncRpcMsg2Json(SRpcMsg* pRpcMsg) { pRoot = syncAppendEntriesReply2Json(pSyncMsg); syncAppendEntriesReplyDestroy(pSyncMsg); + } else if (pRpcMsg->msgType == SYNC_RESPONSE) { + pRoot = cJSON_CreateObject(); + char* s; + s = syncUtilprintBin((char*)(pRpcMsg->pCont), pRpcMsg->contLen); + cJSON_AddStringToObject(pRoot, "pCont", s); + free(s); + s = syncUtilprintBin2((char*)(pRpcMsg->pCont), pRpcMsg->contLen); + cJSON_AddStringToObject(pRoot, "pCont2", s); + free(s); + } else { pRoot = syncRpcUnknownMsg2Json(); + char* s; + s = syncUtilprintBin((char*)(pRpcMsg->pCont), pRpcMsg->contLen); + cJSON_AddStringToObject(pRoot, "pCont", s); + free(s); + s = syncUtilprintBin2((char*)(pRpcMsg->pCont), pRpcMsg->contLen); + cJSON_AddStringToObject(pRoot, "pCont2", s); + free(s); } + cJSON_AddNumberToObject(pRoot, "msgType", pRpcMsg->msgType); + cJSON_AddNumberToObject(pRoot, "contLen", pRpcMsg->contLen); + cJSON_AddNumberToObject(pRoot, "code", pRpcMsg->code); + // cJSON_AddNumberToObject(pRoot, "persist", pRpcMsg->persist); + cJSON* pJson = cJSON_CreateObject(); cJSON_AddItemToObject(pJson, "RpcMsg", pRoot); return pJson; @@ -77,7 +99,7 @@ cJSON* syncRpcMsg2Json(SRpcMsg* pRpcMsg) { cJSON* syncRpcUnknownMsg2Json() { cJSON* pRoot = cJSON_CreateObject(); cJSON_AddNumberToObject(pRoot, "msgType", SYNC_UNKNOWN); - cJSON_AddStringToObject(pRoot, "data", "known message"); + cJSON_AddStringToObject(pRoot, "data", "unknown message"); cJSON* pJson = cJSON_CreateObject(); cJSON_AddItemToObject(pJson, "SyncUnknown", pRoot); @@ -798,8 +820,8 @@ cJSON* syncRequestVote2Json(const SyncRequestVote* pMsg) { cJSON_AddNumberToObject(pDestId, "vgId", pMsg->destId.vgId); cJSON_AddItemToObject(pRoot, "destId", pDestId); - snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->currentTerm); - cJSON_AddStringToObject(pRoot, "currentTerm", u64buf); + snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->term); + cJSON_AddStringToObject(pRoot, "term", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->lastLogIndex); cJSON_AddStringToObject(pRoot, "lastLogIndex", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->lastLogTerm); @@ -1086,6 +1108,9 @@ cJSON* syncAppendEntries2Json(const SyncAppendEntries* pMsg) { cJSON_AddNumberToObject(pDestId, "vgId", pMsg->destId.vgId); cJSON_AddItemToObject(pRoot, "destId", pDestId); + snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->term); + cJSON_AddStringToObject(pRoot, "term", u64buf); + snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->prevLogIndex); cJSON_AddStringToObject(pRoot, "pre_log_index", u64buf); @@ -1242,9 +1267,11 @@ cJSON* syncAppendEntriesReply2Json(const SyncAppendEntriesReply* pMsg) { cJSON_AddNumberToObject(pDestId, "vgId", pMsg->destId.vgId); cJSON_AddItemToObject(pRoot, "destId", pDestId); + snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->term); + cJSON_AddStringToObject(pRoot, "term", u64buf); cJSON_AddNumberToObject(pRoot, "success", pMsg->success); snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->matchIndex); - cJSON_AddStringToObject(pRoot, "match_index", u64buf); + cJSON_AddStringToObject(pRoot, "matchIndex", u64buf); cJSON* pJson = cJSON_CreateObject(); cJSON_AddItemToObject(pJson, "SyncAppendEntriesReply", pRoot); @@ -1283,4 +1310,4 @@ void syncAppendEntriesReplyLog2(char* s, const SyncAppendEntriesReply* pMsg) { char* serialized = syncAppendEntriesReply2Str(pMsg); sTrace("syncAppendEntriesReplyLog2 | len:%lu | %s | %s", strlen(serialized), s, serialized); free(serialized); -} \ No newline at end of file +} diff --git a/source/libs/sync/src/syncRaftLog.c b/source/libs/sync/src/syncRaftLog.c index 27c8a26154..6ebeba1991 100644 --- a/source/libs/sync/src/syncRaftLog.c +++ b/source/libs/sync/src/syncRaftLog.c @@ -130,7 +130,7 @@ cJSON* logStore2Json(SSyncLogStore* pLogStore) { cJSON_AddStringToObject(pRoot, "pSyncNode", u64buf); snprintf(u64buf, sizeof(u64buf), "%p", pData->pWal); cJSON_AddStringToObject(pRoot, "pWal", u64buf); - snprintf(u64buf, sizeof(u64buf), "%lu", logStoreLastIndex(pLogStore)); + snprintf(u64buf, sizeof(u64buf), "%ld", logStoreLastIndex(pLogStore)); cJSON_AddStringToObject(pRoot, "LastIndex", u64buf); snprintf(u64buf, sizeof(u64buf), "%lu", logStoreLastTerm(pLogStore)); cJSON_AddStringToObject(pRoot, "LastTerm", u64buf); diff --git a/source/libs/sync/src/syncRaftStore.c b/source/libs/sync/src/syncRaftStore.c index 3a26caa161..5ad618b9c0 100644 --- a/source/libs/sync/src/syncRaftStore.c +++ b/source/libs/sync/src/syncRaftStore.c @@ -15,6 +15,8 @@ #include "syncRaftStore.h" #include "cJSON.h" +#include "syncEnv.h" +#include "syncUtil.h" // private function static int32_t raftStoreInit(SRaftStore *pRaftStore); @@ -135,6 +137,33 @@ int32_t raftStoreDeserialize(SRaftStore *pRaftStore, char *buf, size_t len) { return 0; } +bool raftStoreHasVoted(SRaftStore *pRaftStore) { + bool b = syncUtilEmptyId(&(pRaftStore->voteFor)); + return b; +} + +void raftStoreVote(SRaftStore *pRaftStore, SRaftId *pRaftId) { + assert(!raftStoreHasVoted(pRaftStore)); + assert(!syncUtilEmptyId(pRaftId)); + pRaftStore->voteFor = *pRaftId; + raftStorePersist(pRaftStore); +} + +void raftStoreClearVote(SRaftStore *pRaftStore) { + pRaftStore->voteFor = EMPTY_RAFT_ID; + raftStorePersist(pRaftStore); +} + +void raftStoreNextTerm(SRaftStore *pRaftStore) { + ++(pRaftStore->currentTerm); + raftStorePersist(pRaftStore); +} + +void raftStoreSetTerm(SRaftStore *pRaftStore, SyncTerm term) { + pRaftStore->currentTerm = term; + raftStorePersist(pRaftStore); +} + // for debug ------------------- void raftStorePrint(SRaftStore *pObj) { char serialized[RAFT_STORE_BLOCK_SIZE]; diff --git a/source/libs/sync/src/syncReplication.c b/source/libs/sync/src/syncReplication.c index dfbe5db0ed..b935943a1d 100644 --- a/source/libs/sync/src/syncReplication.c +++ b/source/libs/sync/src/syncReplication.c @@ -14,7 +14,11 @@ */ #include "syncReplication.h" +#include "syncIndexMgr.h" #include "syncMessage.h" +#include "syncRaftEntry.h" +#include "syncRaftLog.h" +#include "syncUtil.h" // TLA+ Spec // AppendEntries(i, j) == @@ -42,7 +46,39 @@ // /\ UNCHANGED <> // int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode) { + assert(pSyncNode->state == TAOS_SYNC_STATE_LEADER); + int32_t ret = 0; + for (int i = 0; i < pSyncNode->peersNum; ++i) { + SRaftId* pDestId = &(pSyncNode->peersId[i]); + SyncIndex nextIndex = syncIndexMgrGetIndex(pSyncNode->pNextIndex, pDestId); + + SyncIndex preLogIndex = nextIndex - 1; + + SyncTerm preLogTerm = 0; + if (preLogIndex >= SYNC_INDEX_BEGIN) { + SSyncRaftEntry* pPreEntry = pSyncNode->pLogStore->getEntry(pSyncNode->pLogStore, preLogIndex); + preLogTerm = pPreEntry->term; + } + + SyncIndex lastIndex = syncUtilMinIndex(pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore), nextIndex); + assert(nextIndex == lastIndex); + + SSyncRaftEntry* pEntry = logStoreGetEntry(pSyncNode->pLogStore, nextIndex); + assert(pEntry != NULL); + + SyncAppendEntries* pMsg = syncAppendEntriesBuild(pEntry->bytes); + pMsg->srcId = pSyncNode->myRaftId; + pMsg->destId = *pDestId; + pMsg->prevLogIndex = preLogIndex; + pMsg->prevLogTerm = preLogTerm; + pMsg->commitIndex = pSyncNode->commitIndex; + pMsg->dataLen = pEntry->bytes; + // add pEntry into msg + + syncNodeAppendEntries(pSyncNode, pDestId, pMsg); + } + return ret; } diff --git a/source/libs/sync/src/syncRequestVote.c b/source/libs/sync/src/syncRequestVote.c index 354c559a90..be4f40aaad 100644 --- a/source/libs/sync/src/syncRequestVote.c +++ b/source/libs/sync/src/syncRequestVote.c @@ -14,6 +14,10 @@ */ #include "syncRequestVote.h" +#include "syncInt.h" +#include "syncRaftStore.h" +#include "syncUtil.h" +#include "syncVoteMgr.h" // TLA+ Spec // HandleRequestVoteRequest(i, j, m) == @@ -37,4 +41,34 @@ // m) // /\ UNCHANGED <> // -int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg) {} +int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg) { + int32_t ret = 0; + syncRequestVoteLog2("==syncNodeOnRequestVoteCb==", pMsg); + + if (pMsg->term > ths->pRaftStore->currentTerm) { + syncNodeUpdateTerm(ths, pMsg->term); + } + assert(pMsg->term <= ths->pRaftStore->currentTerm); + + bool logOK = (pMsg->lastLogTerm > ths->pLogStore->getLastTerm(ths->pLogStore)) || + ((pMsg->lastLogTerm == ths->pLogStore->getLastTerm(ths->pLogStore)) && + (pMsg->lastLogIndex >= ths->pLogStore->getLastIndex(ths->pLogStore))); + bool grant = (pMsg->term == ths->pRaftStore->currentTerm) && logOK && + ((!raftStoreHasVoted(ths->pRaftStore)) || (syncUtilSameId(&(ths->pRaftStore->voteFor), &(pMsg->srcId)))); + if (grant) { + raftStoreVote(ths->pRaftStore, &(pMsg->srcId)); + } + + SyncRequestVoteReply* pReply = syncRequestVoteReplyBuild(); + pReply->srcId = ths->myRaftId; + pReply->destId = pMsg->srcId; + pReply->term = ths->pRaftStore->currentTerm; + pReply->voteGranted = grant; + + SRpcMsg rpcMsg; + syncRequestVoteReply2RpcMsg(pReply, &rpcMsg); + syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg); + syncRequestVoteReplyDestroy(pReply); + + return ret; +} diff --git a/source/libs/sync/src/syncRequestVoteReply.c b/source/libs/sync/src/syncRequestVoteReply.c index 72223ea83c..7cdeace166 100644 --- a/source/libs/sync/src/syncRequestVoteReply.c +++ b/source/libs/sync/src/syncRequestVoteReply.c @@ -14,6 +14,10 @@ */ #include "syncRequestVoteReply.h" +#include "syncInt.h" +#include "syncRaftStore.h" +#include "syncUtil.h" +#include "syncVoteMgr.h" // TLA+ Spec // HandleRequestVoteResponse(i, j, m) == @@ -32,4 +36,33 @@ // /\ Discard(m) // /\ UNCHANGED <> // -int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) {} +int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) { + int32_t ret = 0; + syncRequestVoteReplyLog2("==syncNodeOnRequestVoteReplyCb==", pMsg); + + if (pMsg->term < ths->pRaftStore->currentTerm) { + sTrace("DropStaleResponse, receive term:%lu, current term:%lu", pMsg->term, ths->pRaftStore->currentTerm); + return ret; + } + + // no need this code, because if I receive reply.term, then I must have sent for that term. + // if (pMsg->term > ths->pRaftStore->currentTerm) { + // syncNodeUpdateTerm(ths, pMsg->term); + // } + + assert(pMsg->term == ths->pRaftStore->currentTerm); + + if (ths->state == TAOS_SYNC_STATE_CANDIDATE) { + votesRespondAdd(ths->pVotesRespond, pMsg); + if (pMsg->voteGranted) { + voteGrantedVote(ths->pVotesGranted, pMsg); + if (voteGrantedMajority(ths->pVotesGranted)) { + if (ths->pVotesGranted->toLeader) { + syncNodeCandidate2Leader(ths); + ths->pVotesGranted->toLeader = true; + } + } + } + } + return ret; +} diff --git a/source/libs/sync/src/syncTimeout.c b/source/libs/sync/src/syncTimeout.c index 7cbfd6d40a..3a48b0cbb3 100644 --- a/source/libs/sync/src/syncTimeout.c +++ b/source/libs/sync/src/syncTimeout.c @@ -19,15 +19,7 @@ int32_t syncNodeOnTimeoutCb(SSyncNode* ths, SyncTimeout* pMsg) { int32_t ret = 0; - sTrace("<-- syncNodeOnTimeoutCb -->"); - - { - cJSON* pJson = syncTimeout2Json(pMsg); - char* serialized = cJSON_Print(pJson); - sTrace("process syncMessage recv: syncNodeOnTimeoutCb pMsg:%s ", serialized); - free(serialized); - cJSON_Delete(pJson); - } + syncTimeoutLog2("==syncNodeOnTimeoutCb==", pMsg); if (pMsg->timeoutType == SYNC_TIMEOUT_PING) { if (atomic_load_64(&ths->pingTimerLogicClockUser) <= pMsg->logicClock) { diff --git a/source/libs/sync/src/syncUtil.c b/source/libs/sync/src/syncUtil.c index b78971bf37..ba8a76c190 100644 --- a/source/libs/sync/src/syncUtil.c +++ b/source/libs/sync/src/syncUtil.c @@ -74,6 +74,8 @@ bool syncUtilSameId(const SRaftId* pId1, const SRaftId* pId2) { return ret; } +bool syncUtilEmptyId(const SRaftId* pId) { return (pId->addr == 0 && pId->vgId == 0); } + // ---- SSyncBuffer ----- void syncUtilbufBuild(SSyncBuffer* syncBuf, size_t len) { syncBuf->len = len; @@ -184,4 +186,14 @@ char* syncUtilprintBin2(char* ptr, uint32_t len) { p += n; } return s; +} + +SyncIndex syncUtilMinIndex(SyncIndex a, SyncIndex b) { + SyncIndex r = a < b ? a : b; + return r; +} + +SyncIndex syncUtilMaxIndex(SyncIndex a, SyncIndex b) { + SyncIndex r = a > b ? a : b; + return r; } \ No newline at end of file diff --git a/source/libs/sync/test/CMakeLists.txt b/source/libs/sync/test/CMakeLists.txt index 2a47b53945..6ade78936d 100644 --- a/source/libs/sync/test/CMakeLists.txt +++ b/source/libs/sync/test/CMakeLists.txt @@ -4,8 +4,8 @@ add_executable(syncPingTimerTest "") add_executable(syncIOTickQTest "") add_executable(syncIOTickPingTest "") add_executable(syncIOSendMsgTest "") -add_executable(syncIOSendMsgClientTest "") -add_executable(syncIOSendMsgServerTest "") +add_executable(syncIOClientTest "") +add_executable(syncIOServerTest "") add_executable(syncRaftStoreTest "") add_executable(syncEnqTest "") add_executable(syncIndexTest "") @@ -51,13 +51,13 @@ target_sources(syncIOSendMsgTest PRIVATE "syncIOSendMsgTest.cpp" ) -target_sources(syncIOSendMsgClientTest +target_sources(syncIOClientTest PRIVATE - "syncIOSendMsgClientTest.cpp" + "syncIOClientTest.cpp" ) -target_sources(syncIOSendMsgServerTest +target_sources(syncIOServerTest PRIVATE - "syncIOSendMsgServerTest.cpp" + "syncIOServerTest.cpp" ) target_sources(syncRaftStoreTest PRIVATE @@ -167,12 +167,12 @@ target_include_directories(syncIOSendMsgTest "${CMAKE_SOURCE_DIR}/include/libs/sync" "${CMAKE_CURRENT_SOURCE_DIR}/../inc" ) -target_include_directories(syncIOSendMsgClientTest +target_include_directories(syncIOClientTest PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/sync" "${CMAKE_CURRENT_SOURCE_DIR}/../inc" ) -target_include_directories(syncIOSendMsgServerTest +target_include_directories(syncIOServerTest PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/sync" "${CMAKE_CURRENT_SOURCE_DIR}/../inc" @@ -298,11 +298,11 @@ target_link_libraries(syncIOSendMsgTest sync gtest_main ) -target_link_libraries(syncIOSendMsgClientTest +target_link_libraries(syncIOClientTest sync gtest_main ) -target_link_libraries(syncIOSendMsgServerTest +target_link_libraries(syncIOServerTest sync gtest_main ) diff --git a/source/libs/sync/test/syncEnqTest.cpp b/source/libs/sync/test/syncEnqTest.cpp index e1706bb40b..57315f40ec 100644 --- a/source/libs/sync/test/syncEnqTest.cpp +++ b/source/libs/sync/test/syncEnqTest.cpp @@ -1,9 +1,10 @@ +#include #include #include "syncEnv.h" #include "syncIO.h" #include "syncInt.h" -#include "syncMessage.h" #include "syncRaftStore.h" +#include "syncUtil.h" void logTest() { sTrace("--- sync log test: trace"); @@ -14,64 +15,69 @@ void logTest() { sFatal("--- sync log test: fatal"); } -uint16_t ports[3] = {7010, 7110, 7210}; +uint16_t ports[] = {7010, 7110, 7210, 7310, 7410}; +int32_t replicaNum = 5; +int32_t myIndex = 0; -SSyncNode* doSync(int myIndex) { - SSyncFSM* pFsm; +SRaftId ids[TSDB_MAX_REPLICA]; +SSyncInfo syncInfo; +SSyncFSM* pFsm; - SSyncInfo syncInfo; - syncInfo.vgId = 1; +SSyncNode* syncNodeInit() { + syncInfo.vgId = 1234; syncInfo.rpcClient = gSyncIO->clientRpc; syncInfo.FpSendMsg = syncIOSendMsg; syncInfo.queue = gSyncIO->pMsgQ; syncInfo.FpEqMsg = syncIOEqMsg; syncInfo.pFsm = pFsm; - snprintf(syncInfo.path, sizeof(syncInfo.path), "%s", "./test_sync_ping"); + snprintf(syncInfo.path, sizeof(syncInfo.path), "%s", "./"); SSyncCfg* pCfg = &syncInfo.syncCfg; pCfg->myIndex = myIndex; - pCfg->replicaNum = 3; + pCfg->replicaNum = replicaNum; - pCfg->nodeInfo[0].nodePort = ports[0]; - snprintf(pCfg->nodeInfo[0].nodeFqdn, sizeof(pCfg->nodeInfo[0].nodeFqdn), "%s", "127.0.0.1"); - // taosGetFqdn(pCfg->nodeInfo[0].nodeFqdn); - - pCfg->nodeInfo[1].nodePort = ports[1]; - snprintf(pCfg->nodeInfo[1].nodeFqdn, sizeof(pCfg->nodeInfo[1].nodeFqdn), "%s", "127.0.0.1"); - // taosGetFqdn(pCfg->nodeInfo[1].nodeFqdn); - - pCfg->nodeInfo[2].nodePort = ports[2]; - snprintf(pCfg->nodeInfo[2].nodeFqdn, sizeof(pCfg->nodeInfo[2].nodeFqdn), "%s", "127.0.0.1"); - // taosGetFqdn(pCfg->nodeInfo[2].nodeFqdn); + for (int i = 0; i < replicaNum; ++i) { + pCfg->nodeInfo[i].nodePort = ports[i]; + snprintf(pCfg->nodeInfo[i].nodeFqdn, sizeof(pCfg->nodeInfo[i].nodeFqdn), "%s", "127.0.0.1"); + // taosGetFqdn(pCfg->nodeInfo[0].nodeFqdn); + } SSyncNode* pSyncNode = syncNodeOpen(&syncInfo); assert(pSyncNode != NULL); gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing; + gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply; + gSyncIO->FpOnSyncRequestVote = pSyncNode->FpOnRequestVote; + gSyncIO->FpOnSyncRequestVoteReply = pSyncNode->FpOnRequestVoteReply; + gSyncIO->FpOnSyncAppendEntries = pSyncNode->FpOnAppendEntries; + gSyncIO->FpOnSyncAppendEntriesReply = pSyncNode->FpOnAppendEntriesReply; + gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing; + gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply; + gSyncIO->FpOnSyncTimeout = pSyncNode->FpOnTimeout; gSyncIO->pSyncNode = pSyncNode; return pSyncNode; } -void timerPingAll(void* param, void* tmrId) { - SSyncNode* pSyncNode = (SSyncNode*)param; - syncNodePingAll(pSyncNode); +SSyncNode* syncInitTest() { return syncNodeInit(); } + +void initRaftId(SSyncNode* pSyncNode) { + for (int i = 0; i < replicaNum; ++i) { + ids[i] = pSyncNode->replicasId[i]; + char* s = syncUtilRaftId2Str(&ids[i]); + printf("raftId[%d] : %s\n", i, s); + free(s); + } } int main(int argc, char** argv) { - // taosInitLog((char*)"syncPingTest.log", 100000, 10); + // taosInitLog((char *)"syncTest.log", 100000, 10); tsAsyncLog = 0; sDebugFlag = 143 + 64; - logTest(); - - int myIndex = 0; + myIndex = 0; if (argc >= 2) { myIndex = atoi(argv[1]); - if (myIndex > 2 || myIndex < 0) { - fprintf(stderr, "myIndex:%d error. should be 0 - 2", myIndex); - return 1; - } } int32_t ret = syncIOStart((char*)"127.0.0.1", ports[myIndex]); @@ -80,21 +86,22 @@ int main(int argc, char** argv) { ret = syncEnvStart(); assert(ret == 0); - SSyncNode* pSyncNode = doSync(myIndex); - gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing; - gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply; + SSyncNode* pSyncNode = syncInitTest(); + assert(pSyncNode != NULL); + + syncNodePrint2((char*)"syncInitTest", pSyncNode); + + initRaftId(pSyncNode); + + //-------------------------------------------------------------- for (int i = 0; i < 10; ++i) { - SyncPingReply* pSyncMsg = syncPingReplyBuild3(&pSyncNode->myRaftId, &pSyncNode->myRaftId); + SyncPingReply* pSyncMsg = syncPingReplyBuild2(&pSyncNode->myRaftId, &pSyncNode->myRaftId, "syncEnqTest"); SRpcMsg rpcMsg; syncPingReply2RpcMsg(pSyncMsg, &rpcMsg); pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg); taosMsleep(1000); } - while (1) { - taosMsleep(1000); - } - return 0; } diff --git a/source/libs/sync/test/syncEnvTest.cpp b/source/libs/sync/test/syncEnvTest.cpp index 101c0efe9a..a7a819e046 100644 --- a/source/libs/sync/test/syncEnvTest.cpp +++ b/source/libs/sync/test/syncEnvTest.cpp @@ -14,15 +14,6 @@ void logTest() { sFatal("--- sync log test: fatal"); } -void *pTimer = NULL; -void *pTimerMgr = NULL; -int g = 300; - -static void timerFp(void *param, void *tmrId) { - printf("param:%p, tmrId:%p, pTimer:%p, pTimerMgr:%p \n", param, tmrId, pTimer, pTimerMgr); - taosTmrReset(timerFp, 1000, param, pTimerMgr, &pTimer); -} - int main() { // taosInitLog((char*)"syncEnvTest.log", 100000, 10); tsAsyncLog = 0; @@ -34,13 +25,20 @@ int main() { ret = syncEnvStart(); assert(ret == 0); - // timer - pTimerMgr = taosTmrInit(1000, 50, 10000, "SYNC-ENV-TEST"); - taosTmrStart(timerFp, 1000, &g, pTimerMgr); + for (int i = 0; i < 5; ++i) { + ret = syncEnvStartTimer(); + assert(ret == 0); - while (1) { - taosMsleep(1000); + taosMsleep(5000); + + ret = syncEnvStopTimer(); + assert(ret == 0); + + taosMsleep(5000); } + ret = syncEnvStop(); + assert(ret == 0); + return 0; } diff --git a/source/libs/sync/test/syncIOSendMsgClientTest.cpp b/source/libs/sync/test/syncIOClientTest.cpp similarity index 62% rename from source/libs/sync/test/syncIOSendMsgClientTest.cpp rename to source/libs/sync/test/syncIOClientTest.cpp index 250054fd5a..dffa8b5cb9 100644 --- a/source/libs/sync/test/syncIOSendMsgClientTest.cpp +++ b/source/libs/sync/test/syncIOClientTest.cpp @@ -2,7 +2,8 @@ #include #include "syncIO.h" #include "syncInt.h" -#include "syncRaftStore.h" +#include "syncMessage.h" +#include "syncUtil.h" void logTest() { sTrace("--- sync log test: trace"); @@ -22,7 +23,7 @@ int main() { int32_t ret; - ret = syncIOStart((char *)"127.0.0.1", 7010); + ret = syncIOStart((char*)"127.0.0.1", 7010); assert(ret == 0); for (int i = 0; i < 10; ++i) { @@ -31,20 +32,19 @@ int main() { epSet.numOfEps = 0; addEpIntoEpSet(&epSet, "127.0.0.1", 7030); - SRpcMsg rpcMsg; - rpcMsg.contLen = 64; - rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen); - snprintf((char *)rpcMsg.pCont, rpcMsg.contLen, "%s", "syncIOSendMsgTest"); - rpcMsg.handle = NULL; - rpcMsg.msgType = 77; + SRaftId srcId, destId; + srcId.addr = syncUtilAddr2U64("127.0.0.1", 1234); + srcId.vgId = 100; + destId.addr = syncUtilAddr2U64("127.0.0.1", 5678); + destId.vgId = 100; + + SyncPingReply* pSyncMsg = syncPingReplyBuild2(&srcId, &destId, "syncIOClientTest"); + SRpcMsg rpcMsg; + syncPingReply2RpcMsg(pSyncMsg, &rpcMsg); syncIOSendMsg(gSyncIO->clientRpc, &epSet, &rpcMsg); taosSsleep(1); } - while (1) { - taosSsleep(1); - } - return 0; } diff --git a/source/libs/sync/test/syncIOSendMsgTest.cpp b/source/libs/sync/test/syncIOSendMsgTest.cpp index ed88fbb03e..0fc3ebfe4c 100644 --- a/source/libs/sync/test/syncIOSendMsgTest.cpp +++ b/source/libs/sync/test/syncIOSendMsgTest.cpp @@ -1,8 +1,10 @@ #include #include +#include "syncEnv.h" #include "syncIO.h" #include "syncInt.h" #include "syncRaftStore.h" +#include "syncUtil.h" void logTest() { sTrace("--- sync log test: trace"); @@ -13,37 +15,96 @@ void logTest() { sFatal("--- sync log test: fatal"); } -int main() { +uint16_t ports[] = {7010, 7110, 7210, 7310, 7410}; +int32_t replicaNum = 5; +int32_t myIndex = 0; + +SRaftId ids[TSDB_MAX_REPLICA]; +SSyncInfo syncInfo; +SSyncFSM* pFsm; + +SSyncNode* syncNodeInit() { + syncInfo.vgId = 1234; + syncInfo.rpcClient = gSyncIO->clientRpc; + syncInfo.FpSendMsg = syncIOSendMsg; + syncInfo.queue = gSyncIO->pMsgQ; + syncInfo.FpEqMsg = syncIOEqMsg; + syncInfo.pFsm = pFsm; + snprintf(syncInfo.path, sizeof(syncInfo.path), "%s", "./"); + + SSyncCfg* pCfg = &syncInfo.syncCfg; + pCfg->myIndex = myIndex; + pCfg->replicaNum = replicaNum; + + for (int i = 0; i < replicaNum; ++i) { + pCfg->nodeInfo[i].nodePort = ports[i]; + snprintf(pCfg->nodeInfo[i].nodeFqdn, sizeof(pCfg->nodeInfo[i].nodeFqdn), "%s", "127.0.0.1"); + // taosGetFqdn(pCfg->nodeInfo[0].nodeFqdn); + } + + SSyncNode* pSyncNode = syncNodeOpen(&syncInfo); + assert(pSyncNode != NULL); + + gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing; + gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply; + gSyncIO->FpOnSyncRequestVote = pSyncNode->FpOnRequestVote; + gSyncIO->FpOnSyncRequestVoteReply = pSyncNode->FpOnRequestVoteReply; + gSyncIO->FpOnSyncAppendEntries = pSyncNode->FpOnAppendEntries; + gSyncIO->FpOnSyncAppendEntriesReply = pSyncNode->FpOnAppendEntriesReply; + gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing; + gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply; + gSyncIO->FpOnSyncTimeout = pSyncNode->FpOnTimeout; + gSyncIO->pSyncNode = pSyncNode; + + return pSyncNode; +} + +SSyncNode* syncInitTest() { return syncNodeInit(); } + +void initRaftId(SSyncNode* pSyncNode) { + for (int i = 0; i < replicaNum; ++i) { + ids[i] = pSyncNode->replicasId[i]; + char* s = syncUtilRaftId2Str(&ids[i]); + printf("raftId[%d] : %s\n", i, s); + free(s); + } +} + +int main(int argc, char** argv) { // taosInitLog((char *)"syncTest.log", 100000, 10); tsAsyncLog = 0; sDebugFlag = 143 + 64; - logTest(); - - int32_t ret; - - ret = syncIOStart((char *)"127.0.0.1", 7010); - assert(ret == 0); - - for (int i = 0; i < 10; ++i) { - SEpSet epSet; - epSet.inUse = 0; - epSet.numOfEps = 0; - addEpIntoEpSet(&epSet, "127.0.0.1", 7010); - - SRpcMsg rpcMsg; - rpcMsg.contLen = 64; - rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen); - snprintf((char *)rpcMsg.pCont, rpcMsg.contLen, "%s", "syncIOSendMsgTest"); - rpcMsg.handle = NULL; - rpcMsg.msgType = 77; - - syncIOSendMsg(gSyncIO->clientRpc, &epSet, &rpcMsg); - taosSsleep(1); + myIndex = 0; + if (argc >= 2) { + myIndex = atoi(argv[1]); } - while (1) { - taosSsleep(1); + int32_t ret = syncIOStart((char*)"127.0.0.1", ports[myIndex]); + assert(ret == 0); + + ret = syncEnvStart(); + assert(ret == 0); + + SSyncNode* pSyncNode = syncInitTest(); + assert(pSyncNode != NULL); + + syncNodePrint2((char*)"syncInitTest", pSyncNode); + + initRaftId(pSyncNode); + + //-------------------------------------------------------------- + + for (int i = 0; i < 10; ++i) { + SyncPingReply* pSyncMsg = syncPingReplyBuild2(&pSyncNode->myRaftId, &pSyncNode->myRaftId, "syncIOSendMsgTest"); + SRpcMsg rpcMsg; + syncPingReply2RpcMsg(pSyncMsg, &rpcMsg); + + SEpSet epSet; + syncUtilnodeInfo2EpSet(&pSyncNode->myNodeInfo, &epSet); + pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, &rpcMsg); + + taosMsleep(1000); } return 0; diff --git a/source/libs/sync/test/syncIOSendMsgServerTest.cpp b/source/libs/sync/test/syncIOServerTest.cpp similarity index 100% rename from source/libs/sync/test/syncIOSendMsgServerTest.cpp rename to source/libs/sync/test/syncIOServerTest.cpp diff --git a/source/libs/sync/test/syncIOTickPingTest.cpp b/source/libs/sync/test/syncIOTickPingTest.cpp index 8be93e6fc0..9c2342828e 100644 --- a/source/libs/sync/test/syncIOTickPingTest.cpp +++ b/source/libs/sync/test/syncIOTickPingTest.cpp @@ -25,8 +25,15 @@ int main() { ret = syncIOStart((char*)"127.0.0.1", 7010); assert(ret == 0); - ret = syncIOTickPing(); - assert(ret == 0); + for (int i = 0; i < 3; ++i) { + ret = syncIOPingTimerStart(); + assert(ret == 0); + taosMsleep(5000); + + ret = syncIOPingTimerStop(); + assert(ret == 0); + taosMsleep(5000); + } while (1) { taosSsleep(1); diff --git a/source/libs/sync/test/syncIOTickQTest.cpp b/source/libs/sync/test/syncIOTickQTest.cpp index 76f5e33e82..64b65f25c8 100644 --- a/source/libs/sync/test/syncIOTickQTest.cpp +++ b/source/libs/sync/test/syncIOTickQTest.cpp @@ -25,11 +25,18 @@ int main() { ret = syncIOStart((char*)"127.0.0.1", 7010); assert(ret == 0); - ret = syncIOTickQ(); + for (int i = 0; i < 3; ++i) { + ret = syncIOQTimerStart(); + assert(ret == 0); + taosMsleep(5000); + + ret = syncIOQTimerStop(); + assert(ret == 0); + taosMsleep(5000); + } + + ret = syncIOStop(); assert(ret == 0); - while (1) { - taosSsleep(1); - } return 0; } diff --git a/source/libs/sync/test/syncLogStoreTest.cpp b/source/libs/sync/test/syncLogStoreTest.cpp index 602fdee8c2..1b05f76fa2 100644 --- a/source/libs/sync/test/syncLogStoreTest.cpp +++ b/source/libs/sync/test/syncLogStoreTest.cpp @@ -81,7 +81,10 @@ SSyncNode* syncNodeInit() { SSyncNode* syncInitTest() { return syncNodeInit(); } void logStoreTest() { - logStorePrint(pSyncNode->pLogStore); + logStorePrint2((char*)"logStoreTest2", pSyncNode->pLogStore); + + assert(pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore) == SYNC_INDEX_INVALID); + for (int i = 0; i < 5; ++i) { int32_t dataLen = 10; SSyncRaftEntry* pEntry = syncEntryBuild(dataLen); @@ -97,6 +100,10 @@ void logStoreTest() { // syncEntryPrint2((char*)"write entry:", pEntry); pSyncNode->pLogStore->appendEntry(pSyncNode->pLogStore, pEntry); syncEntryDestory(pEntry); + + if (i == 0) { + assert(pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore) == SYNC_INDEX_BEGIN); + } } logStorePrint(pSyncNode->pLogStore); @@ -129,6 +136,8 @@ int main(int argc, char** argv) { ret = syncEnvStart(); assert(ret == 0); + taosRemoveDir("./wal_test"); + pSyncNode = syncInitTest(); assert(pSyncNode != NULL); diff --git a/source/libs/sync/test/syncRequestVoteTest.cpp b/source/libs/sync/test/syncRequestVoteTest.cpp index 7f75ee937b..22f47046de 100644 --- a/source/libs/sync/test/syncRequestVoteTest.cpp +++ b/source/libs/sync/test/syncRequestVoteTest.cpp @@ -20,7 +20,7 @@ SyncRequestVote *createMsg() { pMsg->srcId.vgId = 100; pMsg->destId.addr = syncUtilAddr2U64("127.0.0.1", 5678); pMsg->destId.vgId = 100; - pMsg->currentTerm = 11; + pMsg->term = 11; pMsg->lastLogIndex = 22; pMsg->lastLogTerm = 33; return pMsg; diff --git a/source/libs/sync/test/syncRpcMsgTest.cpp b/source/libs/sync/test/syncRpcMsgTest.cpp index 0331a29f22..ee6f6c0800 100644 --- a/source/libs/sync/test/syncRpcMsgTest.cpp +++ b/source/libs/sync/test/syncRpcMsgTest.cpp @@ -57,7 +57,7 @@ SyncRequestVote *createSyncRequestVote() { pMsg->srcId.vgId = 100; pMsg->destId.addr = syncUtilAddr2U64("127.0.0.1", 5678); pMsg->destId.vgId = 100; - pMsg->currentTerm = 11; + pMsg->term = 11; pMsg->lastLogIndex = 22; pMsg->lastLogTerm = 33; return pMsg; @@ -100,7 +100,7 @@ SyncAppendEntriesReply *createSyncAppendEntriesReply() { void test1() { SyncTimeout *pMsg = createSyncTimeout(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncTimeout2RpcMsg(pMsg, &rpcMsg); syncRpcMsgPrint2((char *)"test1", &rpcMsg); syncTimeoutDestroy(pMsg); @@ -108,7 +108,7 @@ void test1() { void test2() { SyncPing *pMsg = createSyncPing(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncPing2RpcMsg(pMsg, &rpcMsg); syncRpcMsgPrint2((char *)"test2", &rpcMsg); syncPingDestroy(pMsg); @@ -116,7 +116,7 @@ void test2() { void test3() { SyncPingReply *pMsg = createSyncPingReply(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncPingReply2RpcMsg(pMsg, &rpcMsg); syncRpcMsgPrint2((char *)"test3", &rpcMsg); syncPingReplyDestroy(pMsg); @@ -132,7 +132,7 @@ void test4() { void test5() { SyncRequestVoteReply *pMsg = createSyncRequestVoteReply(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncRequestVoteReply2RpcMsg(pMsg, &rpcMsg); syncRpcMsgPrint2((char *)"test5", &rpcMsg); syncRequestVoteReplyDestroy(pMsg); @@ -140,7 +140,7 @@ void test5() { void test6() { SyncAppendEntries *pMsg = createSyncAppendEntries(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncAppendEntries2RpcMsg(pMsg, &rpcMsg); syncRpcMsgPrint2((char *)"test6", &rpcMsg); syncAppendEntriesDestroy(pMsg); @@ -148,7 +148,7 @@ void test6() { void test7() { SyncAppendEntriesReply *pMsg = createSyncAppendEntriesReply(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncAppendEntriesReply2RpcMsg(pMsg, &rpcMsg); syncRpcMsgPrint2((char *)"test7", &rpcMsg); syncAppendEntriesReplyDestroy(pMsg); @@ -156,7 +156,7 @@ void test7() { void test8() { SyncClientRequest *pMsg = createSyncClientRequest(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncClientRequest2RpcMsg(pMsg, &rpcMsg); syncRpcMsgPrint2((char *)"test8", &rpcMsg); syncClientRequestDestroy(pMsg); diff --git a/source/libs/sync/test/syncUtilTest.cpp b/source/libs/sync/test/syncUtilTest.cpp index 9a1c113620..663db3a7b3 100644 --- a/source/libs/sync/test/syncUtilTest.cpp +++ b/source/libs/sync/test/syncUtilTest.cpp @@ -26,6 +26,7 @@ int main() { tsAsyncLog = 0; sDebugFlag = 143 + 64; logTest(); + electRandomMSTest(); return 0; diff --git a/source/libs/transport/CMakeLists.txt b/source/libs/transport/CMakeLists.txt index 5cc436cf32..20dd3f7ad2 100644 --- a/source/libs/transport/CMakeLists.txt +++ b/source/libs/transport/CMakeLists.txt @@ -12,7 +12,7 @@ target_link_libraries( PUBLIC os PUBLIC util PUBLIC common - PUBLIC zlib + PUBLIC zlibstatic ) if (${BUILD_WITH_UV_TRANS}) if (${BUILD_WITH_UV}) diff --git a/source/libs/transport/inc/transComm.h b/source/libs/transport/inc/transComm.h index f2ac77fe61..99f890d3a0 100644 --- a/source/libs/transport/inc/transComm.h +++ b/source/libs/transport/inc/transComm.h @@ -120,6 +120,10 @@ typedef struct { // SEpSet* pSet; // for synchronous API } SRpcReqContext; +typedef SRpcMsg STransMsg; +typedef SRpcInfo STrans; +typedef SRpcConnInfo STransHandleInfo; + typedef struct { SEpSet epSet; // ip list provided by app void* ahandle; // handle provided by app @@ -134,8 +138,8 @@ typedef struct { int8_t connType; // connection type int64_t rid; // refId returned by taosAddRef - SRpcMsg* pRsp; // for synchronous API - tsem_t* pSem; // for synchronous API + STransMsg* pRsp; // for synchronous API + tsem_t* pSem; // for synchronous API int hThrdIdx; char* ip; @@ -249,4 +253,15 @@ void transUnrefSrvHandle(void* handle); void transRefCliHandle(void* handle); void transUnrefCliHandle(void* handle); +void transSendRequest(void* shandle, const char* ip, uint32_t port, STransMsg* pMsg); +void transSendRecv(void* shandle, const char* ip, uint32_t port, STransMsg* pMsg, STransMsg* pRsp); +void transSendResponse(const STransMsg* pMsg); +int transGetConnInfo(void* thandle, STransHandleInfo* pInfo); + +void* transInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle); +void* transInitClient(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle); + +void transCloseClient(void* arg); +void transCloseServer(void* arg); + #endif diff --git a/source/libs/transport/inc/transportInt.h b/source/libs/transport/inc/transportInt.h index 4e4dcf7aa4..3924a5cf1a 100644 --- a/source/libs/transport/inc/transportInt.h +++ b/source/libs/transport/inc/transportInt.h @@ -64,6 +64,7 @@ typedef struct { void (*cfp)(void* parent, SRpcMsg*, SEpSet*); int (*afp)(void* parent, char* user, char* spi, char* encrypt, char* secret, char* ckey); bool (*pfp)(void* parent, tmsg_t msgType); + void* (*mfp)(void* parent, tmsg_t msgType); int32_t refCount; void* parent; diff --git a/source/libs/transport/src/trans.c b/source/libs/transport/src/trans.c index 4d244665c7..58809ee3be 100644 --- a/source/libs/transport/src/trans.c +++ b/source/libs/transport/src/trans.c @@ -18,8 +18,9 @@ #include "transComm.h" void* (*taosInitHandle[])(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle) = { - taosInitServer, taosInitClient}; -void (*taosCloseHandle[])(void* arg) = {taosCloseServer, taosCloseClient}; + transInitServer, transInitClient}; + +void (*taosCloseHandle[])(void* arg) = {transCloseServer, transCloseClient}; void* rpcOpen(const SRpcInit* pInit) { SRpcInfo* pRpc = calloc(1, sizeof(SRpcInfo)); @@ -34,11 +35,12 @@ void* rpcOpen(const SRpcInit* pInit) { pRpc->cfp = pInit->cfp; pRpc->afp = pInit->afp; pRpc->pfp = pInit->pfp; + pRpc->mfp = pInit->mfp; if (pInit->connType == TAOS_CONN_SERVER) { pRpc->numOfThreads = pInit->numOfThreads > TSDB_MAX_RPC_THREADS ? TSDB_MAX_RPC_THREADS : pInit->numOfThreads; } else { - pRpc->numOfThreads = pInit->numOfThreads; + pRpc->numOfThreads = pInit->numOfThreads > TSDB_MAX_RPC_THREADS ? TSDB_MAX_RPC_THREADS : pInit->numOfThreads; } pRpc->connType = pInit->connType; @@ -51,7 +53,6 @@ void* rpcOpen(const SRpcInit* pInit) { if (pInit->secret) { memcpy(pRpc->secret, pInit->secret, strlen(pInit->secret)); } - return pRpc; } void rpcClose(void* arg) { @@ -111,16 +112,19 @@ void rpcSendRedirectRsp(void* thandle, const SEpSet* pEpSet) { int rpcReportProgress(void* pConn, char* pCont, int contLen) { return -1; } void rpcCancelRequest(int64_t rid) { return; } -int32_t rpcInit() { - // impl later - return 0; +void rpcSendRequest(void* shandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* pRid) { + char* ip = (char*)(pEpSet->eps[pEpSet->inUse].fqdn); + uint32_t port = pEpSet->eps[pEpSet->inUse].port; + transSendRequest(shandle, ip, port, pMsg); +} +void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pMsg, SRpcMsg* pRsp) { + char* ip = (char*)(pEpSet->eps[pEpSet->inUse].fqdn); + uint32_t port = pEpSet->eps[pEpSet->inUse].port; + transSendRecv(shandle, ip, port, pMsg, pRsp); } -void rpcCleanup(void) { - // impl later - // - return; -} +void rpcSendResponse(const SRpcMsg* pMsg) { transSendResponse(pMsg); } +int rpcGetConnInfo(void* thandle, SRpcConnInfo* pInfo) { return transGetConnInfo((void*)thandle, pInfo); } void (*taosRefHandle[])(void* handle) = {transRefSrvHandle, transRefCliHandle}; void (*taosUnRefHandle[])(void* handle) = {transUnrefSrvHandle, transUnrefCliHandle}; @@ -129,9 +133,19 @@ void rpcRefHandle(void* handle, int8_t type) { assert(type == TAOS_CONN_SERVER || type == TAOS_CONN_CLIENT); (*taosRefHandle[type])(handle); } + void rpcUnrefHandle(void* handle, int8_t type) { assert(type == TAOS_CONN_SERVER || type == TAOS_CONN_CLIENT); (*taosUnRefHandle[type])(handle); } +int32_t rpcInit() { + // impl later + return 0; +} +void rpcCleanup(void) { + // impl later + return; +} + #endif diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index 727845b7a9..2f6ff3763f 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -42,7 +42,7 @@ typedef struct SCliConn { typedef struct SCliMsg { STransConnCtx* ctx; - SRpcMsg msg; + STransMsg msg; queue q; uint64_t st; } SCliMsg; @@ -84,7 +84,7 @@ static void addConnToPool(void* pool, char* ip, uint32_t port, SCliConn* co // register timer in each thread to clear expire conn static void cliTimeoutCb(uv_timer_t* handle); // alloc buf for recv -static void cliAllocBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); +static void cliAllocRecvBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); // callback after read nbytes from socket static void cliRecvCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf); // callback after write data to socket @@ -105,9 +105,9 @@ static void cliHandleExcept(SCliConn* conn); static void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd); static void cliHandleQuit(SCliMsg* pMsg, SCliThrdObj* pThrd); static void cliSendQuit(SCliThrdObj* thrd); -static void destroyUserdata(SRpcMsg* userdata); +static void destroyUserdata(STransMsg* userdata); -static int cliRBChoseIdx(SRpcInfo* pTransInst); +static int cliRBChoseIdx(STrans* pTransInst); static void destroyCmsg(SCliMsg* cmsg); static void transDestroyConnCtx(STransConnCtx* ctx); @@ -118,11 +118,11 @@ static void destroyThrdObj(SCliThrdObj* pThrd); #define CONN_HOST_THREAD_INDEX(conn) (conn ? ((SCliConn*)conn)->hThrdIdx : -1) #define CONN_PERSIST_TIME(para) (para * 1000 * 10) -#define CONN_GET_INST_LABEL(conn) (((SRpcInfo*)(((SCliThrdObj*)conn->hostThrd)->pTransInst))->label) +#define CONN_GET_INST_LABEL(conn) (((STrans*)(((SCliThrdObj*)conn->hostThrd)->pTransInst))->label) #define CONN_HANDLE_THREAD_QUIT(conn, thrd) \ do { \ if (thrd->quit) { \ - cliHandleExcept(conn); \ + cliHandleExcept(conn); \ goto _RETURE; \ } \ } while (0) @@ -130,62 +130,76 @@ static void destroyThrdObj(SCliThrdObj* pThrd); #define CONN_HANDLE_BROKEN(conn) \ do { \ if (conn->broken) { \ - cliHandleExcept(conn); \ + cliHandleExcept(conn); \ goto _RETURE; \ } \ } while (0); +#define CONN_SET_PERSIST_BY_APP(conn) \ + do { \ + if (conn->persist == false) { \ + conn->persist = true; \ + transRefCliHandle(conn); \ + } \ + } while (0) +#define CONN_NO_PERSIST_BY_APP(conn) ((conn)->persist == false) + static void* cliWorkThread(void* arg); -static void* cliNotifyApp() {} -static void cliHandleResp(SCliConn* conn) { - SCliMsg* pMsg = conn->data; - STransConnCtx* pCtx = pMsg->ctx; - +void cliHandleResp(SCliConn* conn) { SCliThrdObj* pThrd = conn->hostThrd; - SRpcInfo* pTransInst = pThrd->pTransInst; + STrans* pTransInst = pThrd->pTransInst; STransMsgHead* pHead = (STransMsgHead*)(conn->readBuf.buf); pHead->code = htonl(pHead->code); pHead->msgLen = htonl(pHead->msgLen); - // buf's mem alread translated to rpcMsg.pCont + STransMsg transMsg = {0}; + transMsg.contLen = transContLenFromMsg(pHead->msgLen); + transMsg.pCont = transContFromHead((char*)pHead); + transMsg.code = pHead->code; + transMsg.msgType = pHead->msgType; + transMsg.ahandle = NULL; + + SCliMsg* pMsg = conn->data; + STransConnCtx* pCtx = pMsg ? pMsg->ctx : NULL; + if (pMsg == NULL && !CONN_NO_PERSIST_BY_APP(conn)) { + transMsg.ahandle = pTransInst->mfp ? (*pTransInst->mfp)(pTransInst->parent, transMsg.msgType) : NULL; + } else { + transMsg.ahandle = pCtx ? pCtx->ahandle : NULL; + } + // if (rpcMsg.ahandle == NULL) { + // tDebug("%s cli conn %p handle except", CONN_GET_INST_LABEL(conn), conn); + // return; + //} + + // buf's mem alread translated to transMsg.pCont transClearBuffer(&conn->readBuf); - SRpcMsg rpcMsg = {0}; - rpcMsg.contLen = transContLenFromMsg(pHead->msgLen); - rpcMsg.pCont = transContFromHead((char*)pHead); - rpcMsg.code = pHead->code; - rpcMsg.msgType = pHead->msgType; - rpcMsg.ahandle = pCtx->ahandle; - - if (pTransInst->pfp != NULL && (pTransInst->pfp)(pTransInst->parent, rpcMsg.msgType)) { - rpcMsg.handle = conn; - transRefCliHandle(conn); - - conn->persist = 1; - tDebug("cli conn %p persist by app", conn); + if (pTransInst->pfp != NULL && (*pTransInst->pfp)(pTransInst->parent, transMsg.msgType)) { + transMsg.handle = conn; + CONN_SET_PERSIST_BY_APP(conn); + tDebug("%s cli conn %p ref by app", CONN_GET_INST_LABEL(conn), conn); } tDebug("%s cli conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", pTransInst->label, conn, TMSG_INFO(pHead->msgType), inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port), - inet_ntoa(conn->locaddr.sin_addr), ntohs(conn->locaddr.sin_port), rpcMsg.contLen); + inet_ntoa(conn->locaddr.sin_addr), ntohs(conn->locaddr.sin_port), transMsg.contLen); conn->secured = pHead->secured; - if (pCtx->pSem == NULL) { + if (pCtx == NULL || pCtx->pSem == NULL) { tTrace("%s cli conn %p handle resp", pTransInst->label, conn); - (pTransInst->cfp)(pTransInst->parent, &rpcMsg, NULL); + (pTransInst->cfp)(pTransInst->parent, &transMsg, NULL); } else { tTrace("%s cli conn(sync) %p handle resp", pTransInst->label, conn); - memcpy((char*)pCtx->pRsp, (char*)&rpcMsg, sizeof(rpcMsg)); + memcpy((char*)pCtx->pRsp, (char*)&transMsg, sizeof(transMsg)); tsem_post(pCtx->pSem); } - uv_read_start((uv_stream_t*)conn->stream, cliAllocBufferCb, cliRecvCb); + uv_read_start((uv_stream_t*)conn->stream, cliAllocRecvBufferCb, cliRecvCb); - // user owns conn->persist = 1 - if (conn->persist == 0) { + if (CONN_NO_PERSIST_BY_APP(conn)) { addConnToPool(pThrd->pool, pCtx->ip, pCtx->port, conn); } destroyCmsg(conn->data); @@ -196,29 +210,37 @@ static void cliHandleResp(SCliConn* conn) { // uv_timer_start((uv_timer_t*)&pThrd->timer, cliTimeoutCb, CONN_PERSIST_TIME(pRpc->idleTime) / 2, 0); } } -static void cliHandleExcept(SCliConn* pConn) { + +void cliHandleExcept(SCliConn* pConn) { if (pConn->data == NULL) { - // handle conn except in conn pool - transUnrefCliHandle(pConn); - return; + if (pConn->broken == true || CONN_NO_PERSIST_BY_APP(pConn)) { + transUnrefCliHandle(pConn); + return; + } } SCliThrdObj* pThrd = pConn->hostThrd; - SRpcInfo* pTransInst = pThrd->pTransInst; + STrans* pTransInst = pThrd->pTransInst; SCliMsg* pMsg = pConn->data; - STransConnCtx* pCtx = pMsg->ctx; + STransConnCtx* pCtx = pMsg ? pMsg->ctx : NULL; - SRpcMsg rpcMsg = {0}; - rpcMsg.ahandle = pCtx->ahandle; - rpcMsg.code = TSDB_CODE_RPC_NETWORK_UNAVAIL; - rpcMsg.msgType = pMsg->msg.msgType + 1; + STransMsg transMsg = {0}; + transMsg.code = TSDB_CODE_RPC_NETWORK_UNAVAIL; + transMsg.msgType = pMsg ? pMsg->msg.msgType + 1 : 0; + transMsg.ahandle = NULL; - if (pCtx->pSem == NULL) { + if (pMsg == NULL && !CONN_NO_PERSIST_BY_APP(pConn)) { + transMsg.ahandle = pTransInst->mfp ? (*pTransInst->mfp)(pTransInst->parent, transMsg.msgType) : NULL; + } else { + transMsg.ahandle = pCtx ? pCtx->ahandle : NULL; + } + + if (pCtx == NULL || pCtx->pSem == NULL) { tTrace("%s cli conn %p handle resp", pTransInst->label, pConn); - (pTransInst->cfp)(pTransInst->parent, &rpcMsg, NULL); + (pTransInst->cfp)(pTransInst->parent, &transMsg, NULL); } else { tTrace("%s cli conn(sync) %p handle resp", pTransInst->label, pConn); - memcpy((char*)(pCtx->pRsp), (char*)(&rpcMsg), sizeof(rpcMsg)); + memcpy((char*)(pCtx->pRsp), (char*)(&transMsg), sizeof(transMsg)); tsem_post(pCtx->pSem); } destroyCmsg(pConn->data); @@ -228,11 +250,11 @@ static void cliHandleExcept(SCliConn* pConn) { transUnrefCliHandle(pConn); } -static void cliTimeoutCb(uv_timer_t* handle) { +void cliTimeoutCb(uv_timer_t* handle) { SCliThrdObj* pThrd = handle->data; - SRpcInfo* pRpc = pThrd->pTransInst; + STrans* pTransInst = pThrd->pTransInst; int64_t currentTime = pThrd->nextTimeout; - tTrace("%s, cli conn timeout, try to remove expire conn from conn pool", pRpc->label); + tTrace("%s, cli conn timeout, try to remove expire conn from conn pool", pTransInst->label); SConnList* p = taosHashIterate((SHashObj*)pThrd->pool, NULL); while (p != NULL) { @@ -249,14 +271,15 @@ static void cliTimeoutCb(uv_timer_t* handle) { p = taosHashIterate((SHashObj*)pThrd->pool, p); } - pThrd->nextTimeout = taosGetTimestampMs() + CONN_PERSIST_TIME(pRpc->idleTime); - uv_timer_start(handle, cliTimeoutCb, CONN_PERSIST_TIME(pRpc->idleTime) / 2, 0); + pThrd->nextTimeout = taosGetTimestampMs() + CONN_PERSIST_TIME(pTransInst->idleTime); + uv_timer_start(handle, cliTimeoutCb, CONN_PERSIST_TIME(pTransInst->idleTime) / 2, 0); } -static void* createConnPool(int size) { + +void* createConnPool(int size) { // thread local, no lock return taosHashInit(size, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); } -static void* destroyConnPool(void* pool) { +void* destroyConnPool(void* pool) { SConnList* connList = taosHashIterate((SHashObj*)pool, NULL); while (connList != NULL) { while (!QUEUE_IS_EMPTY(&connList->conn)) { @@ -301,15 +324,15 @@ static void addConnToPool(void* pool, char* ip, uint32_t port, SCliConn* conn) { tstrncpy(key + strlen(key), (char*)(&port), sizeof(port)); tTrace("cli conn %p added to conn pool, read buf cap: %d", conn, conn->readBuf.cap); - SRpcInfo* pRpc = ((SCliThrdObj*)conn->hostThrd)->pTransInst; + STrans* pTransInst = ((SCliThrdObj*)conn->hostThrd)->pTransInst; - conn->expireTime = taosGetTimestampMs() + CONN_PERSIST_TIME(pRpc->idleTime); + conn->expireTime = taosGetTimestampMs() + CONN_PERSIST_TIME(pTransInst->idleTime); SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key)); // list already create before assert(plist != NULL); QUEUE_PUSH(&plist->conn, &conn->conn); } -static void cliAllocBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { +static void cliAllocRecvBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { SCliConn* conn = handle->data; SConnBuffer* pBuf = &conn->readBuf; transAllocBuffer(pBuf, buf); @@ -358,6 +381,7 @@ static SCliConn* cliCreateConn(SCliThrdObj* pThrd) { QUEUE_INIT(&conn->conn); conn->hostThrd = pThrd; + conn->persist = false; conn->broken = false; transRefCliHandle(conn); return conn; @@ -392,19 +416,19 @@ static void cliSendCb(uv_write_t* req, int status) { cliHandleExcept(pConn); return; } - uv_read_start((uv_stream_t*)pConn->stream, cliAllocBufferCb, cliRecvCb); + uv_read_start((uv_stream_t*)pConn->stream, cliAllocRecvBufferCb, cliRecvCb); } -static void cliSend(SCliConn* pConn) { +void cliSend(SCliConn* pConn) { CONN_HANDLE_BROKEN(pConn); SCliMsg* pCliMsg = pConn->data; STransConnCtx* pCtx = pCliMsg->ctx; SCliThrdObj* pThrd = pConn->hostThrd; - SRpcInfo* pTransInst = pThrd->pTransInst; + STrans* pTransInst = pThrd->pTransInst; - SRpcMsg* pMsg = (SRpcMsg*)(&pCliMsg->msg); + STransMsg* pMsg = (STransMsg*)(&pCliMsg->msg); STransMsgHead* pHead = transHeadFromCont(pMsg->pCont); int msgLen = transMsgLenFromCont(pMsg->contLen); @@ -442,7 +466,8 @@ static void cliSend(SCliConn* pConn) { _RETURE: return; } -static void cliConnCb(uv_connect_t* req, int status) { + +void cliConnCb(uv_connect_t* req, int status) { // impl later SCliConn* pConn = req->data; if (status != 0) { @@ -472,11 +497,11 @@ static void cliHandleQuit(SCliMsg* pMsg, SCliThrdObj* pThrd) { pThrd->quit = true; uv_stop(pThrd->loop); } -static SCliConn* cliGetConn(SCliMsg* pMsg, SCliThrdObj* pThrd) { + +SCliConn* cliGetConn(SCliMsg* pMsg, SCliThrdObj* pThrd) { SCliConn* conn = NULL; if (pMsg->msg.handle != NULL) { conn = (SCliConn*)(pMsg->msg.handle); - transUnrefCliHandle(conn); if (conn != NULL) { tTrace("%s cli conn %p reused", CONN_GET_INST_LABEL(conn), conn); } @@ -487,13 +512,14 @@ static SCliConn* cliGetConn(SCliMsg* pMsg, SCliThrdObj* pThrd) { } return conn; } -static void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) { + +void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) { uint64_t et = taosGetTimestampUs(); uint64_t el = et - pMsg->st; - tTrace("%s cli msg tran time cost: %" PRIu64 "us", ((SRpcInfo*)pThrd->pTransInst)->label, el); + tTrace("%s cli msg tran time cost: %" PRIu64 "us", ((STrans*)pThrd->pTransInst)->label, el); STransConnCtx* pCtx = pMsg->ctx; - SRpcInfo* pTransInst = pThrd->pTransInst; + STrans* pTransInst = pThrd->pTransInst; SCliConn* conn = cliGetConn(pMsg, pThrd); if (conn != NULL) { @@ -514,6 +540,7 @@ static void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) { tTrace("%s cli conn %p try to connect to %s:%d", pTransInst->label, conn, pMsg->ctx->ip, pMsg->ctx->port); uv_tcp_connect(&conn->connReq, (uv_tcp_t*)(conn->stream), (const struct sockaddr*)&addr, cliConnCb); } + conn->hThrdIdx = pCtx->hThrdIdx; } static void cliAsyncCb(uv_async_t* handle) { @@ -522,7 +549,7 @@ static void cliAsyncCb(uv_async_t* handle) { SCliMsg* pMsg = NULL; // batch process to avoid to lock/unlock frequently - queue wq; + queue wq; pthread_mutex_lock(&item->mtx); QUEUE_MOVE(&item->qmsg, &wq); pthread_mutex_unlock(&item->mtx); @@ -551,17 +578,17 @@ static void* cliWorkThread(void* arg) { uv_run(pThrd->loop, UV_RUN_DEFAULT); } -void* taosInitClient(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle) { +void* transInitClient(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle) { SCliObj* cli = calloc(1, sizeof(SCliObj)); - SRpcInfo* pRpc = shandle; + STrans* pTransInst = shandle; memcpy(cli->label, label, strlen(label)); cli->numOfThreads = numOfThreads; cli->pThreadObj = (SCliThrdObj**)calloc(cli->numOfThreads, sizeof(SCliThrdObj*)); for (int i = 0; i < cli->numOfThreads; i++) { SCliThrdObj* pThrd = createThrdObj(); - pThrd->nextTimeout = taosGetTimestampMs() + CONN_PERSIST_TIME(pRpc->idleTime); + pThrd->nextTimeout = taosGetTimestampMs() + CONN_PERSIST_TIME(pTransInst->idleTime); pThrd->pTransInst = shandle; int err = pthread_create(&pThrd->thread, NULL, cliWorkThread, (void*)(pThrd)); @@ -573,7 +600,7 @@ void* taosInitClient(uint32_t ip, uint32_t port, char* label, int numOfThreads, return cli; } -static void destroyUserdata(SRpcMsg* userdata) { +static void destroyUserdata(STransMsg* userdata) { if (userdata->pCont == NULL) { return; } @@ -629,12 +656,20 @@ static void transDestroyConnCtx(STransConnCtx* ctx) { free(ctx); } // -static void cliSendQuit(SCliThrdObj* thrd) { +void cliSendQuit(SCliThrdObj* thrd) { // cli can stop gracefully SCliMsg* msg = calloc(1, sizeof(SCliMsg)); transSendAsync(thrd->asyncPool, &msg->q); } -void taosCloseClient(void* arg) { +int cliRBChoseIdx(STrans* pTransInst) { + int64_t index = pTransInst->index; + if (pTransInst->index++ >= pTransInst->numOfThreads) { + pTransInst->index = 0; + } + return index % pTransInst->numOfThreads; +} + +void transCloseClient(void* arg) { SCliObj* cli = arg; for (int i = 0; i < cli->numOfThreads; i++) { cliSendQuit(cli->pThreadObj[i]); @@ -643,13 +678,6 @@ void taosCloseClient(void* arg) { free(cli->pThreadObj); free(cli); } -static int cliRBChoseIdx(SRpcInfo* pTransInst) { - int64_t index = pTransInst->index; - if (pTransInst->index++ >= pTransInst->numOfThreads) { - pTransInst->index = 0; - } - return index % pTransInst->numOfThreads; -} void transRefCliHandle(void* handle) { if (handle == NULL) { return; @@ -665,17 +693,11 @@ void transUnrefCliHandle(void* handle) { if (ref == 0) { cliDestroyConn((SCliConn*)handle, true); } - - // unref cli handle } -void rpcSendRequest(void* shandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* pRid) { - // impl later - char* ip = (char*)(pEpSet->eps[pEpSet->inUse].fqdn); - uint32_t port = pEpSet->eps[pEpSet->inUse].port; - SRpcInfo* pTransInst = (SRpcInfo*)shandle; - - int index = CONN_HOST_THREAD_INDEX(pMsg->handle); +void transSendRequest(void* shandle, const char* ip, uint32_t port, STransMsg* pMsg) { + STrans* pTransInst = (STrans*)shandle; + int index = CONN_HOST_THREAD_INDEX((SCliConn*)pMsg->handle); if (index == -1) { index = cliRBChoseIdx(pTransInst); } @@ -683,6 +705,7 @@ void rpcSendRequest(void* shandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* if (transCompressMsg(pMsg->pCont, pMsg->contLen, &flen)) { // imp later } + tDebug("send request at thread:%d %p", index, pMsg); STransConnCtx* pCtx = calloc(1, sizeof(STransConnCtx)); pCtx->ahandle = pMsg->ahandle; pCtx->msgType = pMsg->msgType; @@ -701,14 +724,9 @@ void rpcSendRequest(void* shandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[index]; transSendAsync(thrd->asyncPool, &(cliMsg->q)); } - -void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pReq, SRpcMsg* pRsp) { - char* ip = (char*)(pEpSet->eps[pEpSet->inUse].fqdn); - uint32_t port = pEpSet->eps[pEpSet->inUse].port; - - SRpcInfo* pTransInst = (SRpcInfo*)shandle; - - int index = CONN_HOST_THREAD_INDEX(pReq->handle); +void transSendRecv(void* shandle, const char* ip, uint32_t port, STransMsg* pReq, STransMsg* pRsp) { + STrans* pTransInst = (STrans*)shandle; + int index = CONN_HOST_THREAD_INDEX(pReq->handle); if (index == -1) { index = cliRBChoseIdx(pTransInst); } @@ -734,7 +752,6 @@ void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pReq, SRpcMsg* pRsp) { tsem_wait(pSem); tsem_destroy(pSem); free(pSem); - - return; } + #endif diff --git a/source/libs/transport/src/transComm.c b/source/libs/transport/src/transComm.c index c83f76c2ec..367cb33fc9 100644 --- a/source/libs/transport/src/transComm.c +++ b/source/libs/transport/src/transComm.c @@ -16,20 +16,6 @@ #include "transComm.h" -int rpcAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey) { - T_MD5_CTX context; - int ret = -1; - - tMD5Init(&context); - tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN); - tMD5Update(&context, (uint8_t*)pMsg, msgLen); - tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN); - tMD5Final(&context); - - if (memcmp(context.digest, pAuth, sizeof(context.digest)) == 0) ret = 0; - - return ret; -} int transAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey) { T_MD5_CTX context; int ret = -1; @@ -44,17 +30,7 @@ int transAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey) { return ret; } -void rpcBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey) { - T_MD5_CTX context; - tMD5Init(&context); - tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN); - tMD5Update(&context, (uint8_t*)pMsg, msgLen); - tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN); - tMD5Final(&context); - - memcpy(pAuth, context.digest, sizeof(context.digest)); -} void transBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey) { T_MD5_CTX context; @@ -67,45 +43,6 @@ void transBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey) { memcpy(pAuth, context.digest, sizeof(context.digest)); } -int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen) { - SRpcHead* pHead = rpcHeadFromCont(pCont); - int32_t finalLen = 0; - int overhead = sizeof(SRpcComp); - - if (!NEEDTO_COMPRESSS_MSG(contLen)) { - return contLen; - } - - char* buf = malloc(contLen + overhead + 8); // 8 extra bytes - if (buf == NULL) { - tError("failed to allocate memory for rpc msg compression, contLen:%d", contLen); - return contLen; - } - - int32_t compLen = LZ4_compress_default(pCont, buf, contLen, contLen + overhead); - tDebug("compress rpc msg, before:%d, after:%d, overhead:%d", contLen, compLen, overhead); - - /* - * only the compressed size is less than the value of contLen - overhead, the compression is applied - * The first four bytes is set to 0, the second four bytes are utilized to keep the original length of message - */ - if (compLen > 0 && compLen < contLen - overhead) { - SRpcComp* pComp = (SRpcComp*)pCont; - pComp->reserved = 0; - pComp->contLen = htonl(contLen); - memcpy(pCont + overhead, buf, compLen); - - pHead->comp = 1; - tDebug("compress rpc msg, before:%d, after:%d", contLen, compLen); - finalLen = compLen + overhead; - } else { - finalLen = contLen; - } - - free(buf); - return finalLen; -} - bool transCompressMsg(char* msg, int32_t len, int32_t* flen) { return false; // SRpcHead* pHead = rpcHeadFromCont(pCont); @@ -154,39 +91,6 @@ bool transDecompressMsg(char* msg, int32_t len, int32_t* flen) { return false; } -SRpcHead* rpcDecompressRpcMsg(SRpcHead* pHead) { - int overhead = sizeof(SRpcComp); - SRpcHead* pNewHead = NULL; - uint8_t* pCont = pHead->content; - SRpcComp* pComp = (SRpcComp*)pHead->content; - - if (pHead->comp) { - // decompress the content - assert(pComp->reserved == 0); - int contLen = htonl(pComp->contLen); - - // prepare the temporary buffer to decompress message - char* temp = (char*)malloc(contLen + RPC_MSG_OVERHEAD); - pNewHead = (SRpcHead*)(temp + sizeof(SRpcReqContext)); // reserve SRpcReqContext - - if (pNewHead) { - int compLen = rpcContLenFromMsg(pHead->msgLen) - overhead; - int origLen = LZ4_decompress_safe((char*)(pCont + overhead), (char*)pNewHead->content, compLen, contLen); - assert(origLen == contLen); - - memcpy(pNewHead, pHead, sizeof(SRpcHead)); - pNewHead->msgLen = rpcMsgLenFromCont(origLen); - /// rpcFreeMsg(pHead); // free the compressed message buffer - pHead = pNewHead; - tTrace("decomp malloc mem:%p", temp); - } else { - tError("failed to allocate memory to decompress msg, contLen:%d", contLen); - } - } - - return pHead; -} - void transConnCtxDestroy(STransConnCtx* ctx) { free(ctx->ip); free(ctx); @@ -315,7 +219,7 @@ int transSendAsync(SAsyncPool* pool, queue* q) { if (el > 50) { // tInfo("lock and unlock cost: %d", (int)el); } - return uv_async_send(async); } + #endif diff --git a/source/libs/transport/src/transSrv.c b/source/libs/transport/src/transSrv.c index 1abca9ad97..cb3bbaefec 100644 --- a/source/libs/transport/src/transSrv.c +++ b/source/libs/transport/src/transSrv.c @@ -37,8 +37,7 @@ typedef struct SSrvConn { struct sockaddr_in addr; struct sockaddr_in locaddr; - // SRpcMsg sendMsg; - // del later + char secured; int spi; char info[64]; @@ -49,7 +48,7 @@ typedef struct SSrvConn { typedef struct SSrvMsg { SSrvConn* pConn; - SRpcMsg msg; + STransMsg msg; queue q; } SSrvMsg; @@ -59,12 +58,13 @@ typedef struct SWorkThrdObj { uv_os_fd_t fd; uv_loop_t* loop; SAsyncPool* asyncPool; - // uv_async_t* workerAsync; // + queue msg; - queue conn; pthread_mutex_t msgMtx; - void* pTransInst; - bool quit; + + queue conn; + void* pTransInst; + bool quit; } SWorkThrdObj; typedef struct SServerObj { @@ -91,7 +91,7 @@ static int transAddAuthPart(SSrvConn* pConn, char* msg, int msgLen); static int uvAuthMsg(SSrvConn* pConn, char* msg, int msgLen); static void uvAllocConnBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); -static void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); +static void uvAllocRecvBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); static void uvOnRecvCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf); static void uvOnTimeoutCb(uv_timer_t* handle); static void uvOnSendCb(uv_write_t* req, int status); @@ -121,7 +121,7 @@ static void* acceptThread(void* arg); static bool addHandleToWorkloop(void* arg); static bool addHandleToAcceptloop(void* arg); -void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { +void uvAllocRecvBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { SSrvConn* conn = handle->data; SConnBuffer* pBuf = &conn->readBuf; transAllocBuffer(pBuf, buf); @@ -163,7 +163,7 @@ static int uvAuthMsg(SSrvConn* pConn, char* msg, int len) { tWarn("%s, time diff:%d is too big, msg discarded", pConn->info, delta); code = TSDB_CODE_RPC_INVALID_TIME_STAMP; } else { - if (rpcAuthenticateMsg(pHead, len - TSDB_AUTH_LEN, pDigest->auth, pConn->secret) < 0) { + if (transAuthenticateMsg(pHead, len - TSDB_AUTH_LEN, pDigest->auth, pConn->secret) < 0) { // tDebug("%s, authentication failed, msg discarded", pConn->info); code = TSDB_CODE_RPC_AUTH_FAILURE; } else { @@ -204,37 +204,36 @@ static void uvHandleReq(SSrvConn* pConn) { memcpy(pConn->user, uMsg->user, tListLen(uMsg->user)); memcpy(pConn->secret, uMsg->secret, tListLen(uMsg->secret)); } - - pConn->inType = pHead->msgType; - - SRpcInfo* pRpc = (SRpcInfo*)p->shandle; pHead->code = htonl(pHead->code); int32_t dlen = 0; if (transDecompressMsg(NULL, 0, NULL)) { // add compress later - // pHead = rpcDecompressRpcMsg(pHead); + // pHead = rpcDecompresSTransMsg(pHead); } else { pHead->msgLen = htonl(pHead->msgLen); // impl later // } - SRpcMsg rpcMsg; - rpcMsg.contLen = transContLenFromMsg(pHead->msgLen); - rpcMsg.pCont = pHead->content; - rpcMsg.msgType = pHead->msgType; - rpcMsg.code = pHead->code; - rpcMsg.ahandle = NULL; - rpcMsg.handle = pConn; + STransMsg transMsg; + transMsg.contLen = transContLenFromMsg(pHead->msgLen); + transMsg.pCont = pHead->content; + transMsg.msgType = pHead->msgType; + transMsg.code = pHead->code; + transMsg.ahandle = NULL; + transMsg.handle = pConn; transClearBuffer(&pConn->readBuf); - + pConn->inType = pHead->msgType; transRefSrvHandle(pConn); - tDebug("server conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", pConn, TMSG_INFO(rpcMsg.msgType), + + tDebug("server conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", pConn, TMSG_INFO(transMsg.msgType), inet_ntoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), inet_ntoa(pConn->locaddr.sin_addr), - ntohs(pConn->locaddr.sin_port), rpcMsg.contLen); - (*(pRpc->cfp))(pRpc->parent, &rpcMsg, NULL); + ntohs(pConn->locaddr.sin_port), transMsg.contLen); + + STrans* pTransInst = (STrans*)p->shandle; + (*((STrans*)p->shandle)->cfp)(pTransInst->parent, &transMsg, NULL); // uv_timer_start(&pConn->pTimer, uvHandleActivityTimeout, pRpc->idleTime * 10000, 0); // auth // validate msg type @@ -260,7 +259,7 @@ void uvOnRecvCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) { } tError("server conn %p read error: %s", conn, uv_err_name(nread)); - if (nread < 0 || nread == UV_EOF) { + if (nread < 0) { conn->broken = true; transUnrefSrvHandle(conn); @@ -318,8 +317,8 @@ static void uvPrepareSendData(SSrvMsg* smsg, uv_buf_t* wb) { // impl later; tTrace("server conn %p prepare to send resp", smsg->pConn); - SSrvConn* pConn = smsg->pConn; - SRpcMsg* pMsg = &smsg->msg; + SSrvConn* pConn = smsg->pConn; + STransMsg* pMsg = &smsg->msg; if (pMsg->pCont == 0) { pMsg->pCont = (void*)rpcMallocCont(0); pMsg->contLen = 0; @@ -526,7 +525,7 @@ void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) { return; } - uv_read_start((uv_stream_t*)(pConn->pTcp), uvAllocReadBufferCb, uvOnRecvCb); + uv_read_start((uv_stream_t*)(pConn->pTcp), uvAllocRecvBufferCb, uvOnRecvCb); } else { tDebug("failed to create new connection"); @@ -547,7 +546,6 @@ static bool addHandleToWorkloop(void* arg) { return false; } - // SRpcInfo* pRpc = pThrd->shandle; uv_pipe_init(pThrd->loop, pThrd->pipe, 1); uv_pipe_open(pThrd->pipe, pThrd->fd); @@ -668,7 +666,7 @@ static int transAddAuthPart(SSrvConn* pConn, char* msg, int msgLen) { return msgLen; } -void* taosInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle) { +void* transInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle) { SServerObj* srv = calloc(1, sizeof(SServerObj)); srv->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); srv->numOfThreads = numOfThreads; @@ -720,7 +718,7 @@ void* taosInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, return srv; End: - taosCloseServer(srv); + transCloseServer(srv); return NULL; } @@ -740,7 +738,7 @@ void sendQuitToWorkThrd(SWorkThrdObj* pThrd) { transSendAsync(pThrd->asyncPool, &srvMsg->q); } -void taosCloseServer(void* arg) { +void transCloseServer(void* arg) { // impl later SServerObj* srv = arg; for (int i = 0; i < srv->numOfThreads; i++) { @@ -786,7 +784,7 @@ void transUnrefSrvHandle(void* handle) { } // unref srv handle } -void rpcSendResponse(const SRpcMsg* pMsg) { +void transSendResponse(const STransMsg* pMsg) { if (pMsg->handle == NULL) { return; } @@ -799,14 +797,12 @@ void rpcSendResponse(const SRpcMsg* pMsg) { tTrace("server conn %p start to send resp", pConn); transSendAsync(pThrd->asyncPool, &srvMsg->q); } - -int rpcGetConnInfo(void* thandle, SRpcConnInfo* pInfo) { - SSrvConn* pConn = thandle; - +int transGetConnInfo(void* thandle, STransHandleInfo* pInfo) { + SSrvConn* pConn = thandle; struct sockaddr_in addr = pConn->addr; + pInfo->clientIp = (uint32_t)(addr.sin_addr.s_addr); pInfo->clientPort = ntohs(addr.sin_port); - tstrncpy(pInfo->user, pConn->user, sizeof(pInfo->user)); return 0; } diff --git a/source/libs/transport/test/transUT.cc b/source/libs/transport/test/transUT.cc index 5edddb006b..fa20327003 100644 --- a/source/libs/transport/test/transUT.cc +++ b/source/libs/transport/test/transUT.cc @@ -29,24 +29,25 @@ const char *ckey = "ckey"; class Server; int port = 7000; // server process +typedef void (*CB)(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet); static void processReq(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet); // client process; static void processResp(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet); class Client { public: void Init(int nThread) { - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = 0; - rpcInit.label = (char *)label; - rpcInit.numOfThreads = nThread; - rpcInit.cfp = processResp; - rpcInit.user = (char *)user; - rpcInit.secret = (char *)secret; - rpcInit.ckey = (char *)ckey; - rpcInit.spi = 1; - rpcInit.parent = this; - rpcInit.connType = TAOS_CONN_CLIENT; - this->transCli = rpcOpen(&rpcInit); + memset(&rpcInit_, 0, sizeof(rpcInit_)); + rpcInit_.localPort = 0; + rpcInit_.label = (char *)label; + rpcInit_.numOfThreads = nThread; + rpcInit_.cfp = processResp; + rpcInit_.user = (char *)user; + rpcInit_.secret = (char *)secret; + rpcInit_.ckey = (char *)ckey; + rpcInit_.spi = 1; + rpcInit_.parent = this; + rpcInit_.connType = TAOS_CONN_CLIENT; + this->transCli = rpcOpen(&rpcInit_); tsem_init(&this->sem, 0, 0); } void SetResp(SRpcMsg *pMsg) { @@ -55,9 +56,27 @@ class Client { } SRpcMsg *Resp() { return &this->resp; } - void Restart() { + void Restart(CB cb) { rpcClose(this->transCli); - this->transCli = rpcOpen(&rpcInit); + rpcInit_.cfp = cb; + this->transCli = rpcOpen(&rpcInit_); + } + void setPersistFP(bool (*pfp)(void *parent, tmsg_t msgType)) { + rpcClose(this->transCli); + rpcInit_.pfp = pfp; + this->transCli = rpcOpen(&rpcInit_); + } + void setConstructFP(void *(*mfp)(void *parent, tmsg_t msgType)) { + rpcClose(this->transCli); + rpcInit_.mfp = mfp; + this->transCli = rpcOpen(&rpcInit_); + } + void setPAndMFp(bool (*pfp)(void *parent, tmsg_t msgType), void *(*mfp)(void *parent, tmsg_t msgType)) { + rpcClose(this->transCli); + + rpcInit_.pfp = pfp; + rpcInit_.mfp = mfp; + this->transCli = rpcOpen(&rpcInit_); } void SendAndRecv(SRpcMsg *req, SRpcMsg *resp) { @@ -79,7 +98,7 @@ class Client { private: tsem_t sem; - SRpcInit rpcInit; + SRpcInit rpcInit_; void * transCli; SRpcMsg resp; }; @@ -133,39 +152,56 @@ static void processResp(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) { client->SetResp(pMsg); client->SemPost(); } + +static void initEnv() { + dDebugFlag = 143; + vDebugFlag = 0; + mDebugFlag = 143; + cDebugFlag = 0; + jniDebugFlag = 0; + tmrDebugFlag = 143; + uDebugFlag = 143; + rpcDebugFlag = 143; + qDebugFlag = 0; + wDebugFlag = 0; + sDebugFlag = 0; + tsdbDebugFlag = 0; + tsLogEmbedded = 1; + tsAsyncLog = 0; + + std::string path = "/tmp/transport"; + taosRemoveDir(path.c_str()); + taosMkDir(path.c_str()); + + tstrncpy(tsLogDir, path.c_str(), PATH_MAX); + if (taosInitLog("taosdlog", 1) != 0) { + printf("failed to init log file\n"); + } +} class TransObj { public: TransObj() { - dDebugFlag = 143; - vDebugFlag = 0; - mDebugFlag = 143; - cDebugFlag = 0; - jniDebugFlag = 0; - tmrDebugFlag = 143; - uDebugFlag = 143; - rpcDebugFlag = 143; - qDebugFlag = 0; - wDebugFlag = 0; - sDebugFlag = 0; - tsdbDebugFlag = 0; - tsLogEmbedded = 1; - tsAsyncLog = 0; - - std::string path = "/tmp/transport"; - taosRemoveDir(path.c_str()); - taosMkDir(path.c_str()); - - tstrncpy(tsLogDir, path.c_str(), PATH_MAX); - if (taosInitLog("taosdlog", 1) != 0) { - printf("failed to init log file\n"); - } + initEnv(); cli = new Client; cli->Init(1); srv = new Server; srv->Start(); } - void RestartCli() { cli->Restart(); } + + void RestartCli(CB cb) { cli->Restart(cb); } void StopSrv() { srv->Stop(); } + void SetCliPersistFp(bool (*pfp)(void *parent, tmsg_t msgType)) { + // do nothing + cli->setPersistFP(pfp); + } + void SetCliMFp(void *(*mfp)(void *parent, tmsg_t msgType)) { + // do nothing + cli->setConstructFP(mfp); + } + void SetMAndPFp(bool (*pfp)(void *parent, tmsg_t msgType), void *(*mfp)(void *parent, tmsg_t msgType)) { + // do nothing + cli->setPAndMFp(pfp, mfp); + } void RestartSrv() { srv->Restart(); } void cliSendAndRecv(SRpcMsg *req, SRpcMsg *resp) { cli->SendAndRecv(req, resp); } ~TransObj() { @@ -191,16 +227,16 @@ class TransEnv : public ::testing::Test { TransObj *tr = NULL; }; -// TEST_F(TransEnv, 01sendAndRec) { -// for (int i = 0; i < 1; i++) { -// SRpcMsg req = {0}, resp = {0}; -// req.msgType = 0; -// req.pCont = rpcMallocCont(10); -// req.contLen = 10; -// tr->cliSendAndRecv(&req, &resp); -// assert(resp.code == 0); -// } -//} +TEST_F(TransEnv, 01sendAndRec) { + for (int i = 0; i < 1; i++) { + SRpcMsg req = {0}, resp = {0}; + req.msgType = 0; + req.pCont = rpcMallocCont(10); + req.contLen = 10; + tr->cliSendAndRecv(&req, &resp); + assert(resp.code == 0); + } +} TEST_F(TransEnv, 02StopServer) { for (int i = 0; i < 1; i++) { @@ -218,6 +254,31 @@ TEST_F(TransEnv, 02StopServer) { tr->StopSrv(); // tr->RestartSrv(); tr->cliSendAndRecv(&req, &resp); - assert(resp.code != 0); } +TEST_F(TransEnv, clientUserDefined) {} + +TEST_F(TransEnv, cliPersistHandle) { + // impl late +} +TEST_F(TransEnv, srvPersistHandle) { + // impl later +} + +TEST_F(TransEnv, srvPersisHandleExcept) { + // conn breken + // +} +TEST_F(TransEnv, cliPersisHandleExcept) { + // conn breken +} + +TEST_F(TransEnv, multiCliPersisHandleExcept) { + // conn breken +} +TEST_F(TransEnv, multiSrvPersisHandleExcept) { + // conn breken +} +TEST_F(TransEnv, queryExcept) { + // query and conn is broken +} diff --git a/source/os/src/osLocale.c b/source/os/src/osLocale.c index 47546f7deb..e9d6ed7c54 100644 --- a/source/os/src/osLocale.c +++ b/source/os/src/osLocale.c @@ -13,6 +13,7 @@ * along with this program. If not, see . */ +#define ALLOW_FORBID_FUNC #define _DEFAULT_SOURCE #include "osLocale.h" diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 7b348787ec..688e8ebe7f 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -350,6 +350,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_AVAIL_DISK, "No available disk") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_MESSED_MSG, "TSDB messed message") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVLD_TAG_VAL, "TSDB invalid tag value") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_CACHE_LAST_ROW, "TSDB no cache last row data") +TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_SMA_INDEX_IN_META, "No sma index in meta") // query TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_QHANDLE, "Invalid handle") diff --git a/source/util/src/tjson.c b/source/util/src/tjson.c index 634cfcb026..0a4a1a07a6 100644 --- a/source/util/src/tjson.c +++ b/source/util/src/tjson.c @@ -26,6 +26,14 @@ SJson* tjsonCreateObject() { return pJson; } +SJson* tjsonCreateArray() { + SJson* pJson = cJSON_CreateArray(); + if (pJson == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + } + return pJson; +} + void tjsonDelete(SJson* pJson) { if (pJson != NULL) { cJSON_Delete((cJSON*)pJson); diff --git a/source/util/src/tuuid.c b/source/util/src/tuuid.c new file mode 100644 index 0000000000..ceca33436a --- /dev/null +++ b/source/util/src/tuuid.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "tuuid.h" + +static int64_t hashId = 0; +static int32_t SerialNo = 0; + +int32_t tGenIdPI32(void) { + if (hashId == 0) { + char uid[64]; + int32_t code = taosGetSystemUUID(uid, tListLen(uid)); + if (code != TSDB_CODE_SUCCESS) { + terrno = TAOS_SYSTEM_ERROR(errno); + } else { + hashId = MurmurHash3_32(uid, strlen(uid)); + } + } + + int64_t ts = taosGetTimestampMs(); + uint64_t pid = taosGetPId(); + int32_t val = atomic_add_fetch_32(&SerialNo, 1); + + int32_t id = ((hashId & 0x1F) << 26) | ((pid & 0x3F) << 20) | ((ts & 0xFFF) << 8) | (val & 0xFF); + return id; +} + +int64_t tGenIdPI64(void) { + if (hashId == 0) { + char uid[64]; + int32_t code = taosGetSystemUUID(uid, tListLen(uid)); + if (code != TSDB_CODE_SUCCESS) { + terrno = TAOS_SYSTEM_ERROR(errno); + } else { + hashId = MurmurHash3_32(uid, strlen(uid)); + } + } + + int64_t ts = taosGetTimestampMs(); + uint64_t pid = taosGetPId(); + int32_t val = atomic_add_fetch_32(&SerialNo, 1); + + int64_t id = ((hashId & 0x07FF) << 52) | ((pid & 0x0FFF) << 40) | ((ts & 0xFFFFFF) << 16) | (val & 0xFFFF); + return id; +} diff --git a/source/util/src/tworker.c b/source/util/src/tworker.c index 1657a85ee8..1fa70da870 100644 --- a/source/util/src/tworker.c +++ b/source/util/src/tworker.c @@ -188,7 +188,7 @@ void tFWorkerFreeQueue(SFWorkerPool *pool, STaosQueue *queue) { tQWorkerFreeQueu int32_t tWWorkerInit(SWWorkerPool *pool) { pool->nextId = 0; - pool->workers = calloc(sizeof(SWWorker), pool->max); + pool->workers = calloc(pool->max, sizeof(SWWorker)); if (pool->workers == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index b934272806..cafca76761 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -16,4 +16,6 @@ # ---- dnode ./test.sh -f tsim/dnode/basic1.sim +# ---- insert +./test.sh -f tsim/insert/basic0.sim #======================b1-end=============== diff --git a/tests/script/sh/massiveTable/compileVersion.sh b/tests/script/sh/massiveTable/compileVersion.sh index 787da09b85..c6c92bf724 100755 --- a/tests/script/sh/massiveTable/compileVersion.sh +++ b/tests/script/sh/massiveTable/compileVersion.sh @@ -45,10 +45,6 @@ function gitPullBranchInfo () { git pull origin $branch_name ||: echo "==== git pull $branch_name end ====" git pull --recurse-submodules - cd tests - git checkout $branch_name - git pull - cd .. } function compileTDengineVersion() { diff --git a/tests/script/tsim/db/basic6.sim b/tests/script/tsim/db/basic6.sim index eb12da2ccb..08ce9955b8 100644 --- a/tests/script/tsim/db/basic6.sim +++ b/tests/script/tsim/db/basic6.sim @@ -14,13 +14,19 @@ $st = $stPrefix . $i $tb = $tbPrefix . $i print =============== step1 -sql create database $db replica 1 days 20 keep 2000 cache 16 vgroups 4 +# quorum presicion +sql create database $db vgroups 8 replica 1 days 20 keep 3650 cache 32 blocks 12 minrows 80 maxrows 10000 wal 2 fsync 1000 comp 0 cachelast 2 precision 'us' sql show databases -print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 +print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1 $data5_1 $data6_1 $data7_1 $data8_1 $data9_1 +print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09 + +if $rows != 1 then + return -1 +endi if $data00 != $db then return -1 endi -if $data02 != 4 then +if $data02 != 8 then return -1 endi if $data03 != 0 then @@ -32,16 +38,23 @@ endi if $data06 != 20 then return -1 endi -if $data08 != 16 then +if $data07 != 3650,3650,3650 then + return -1 +endi +if $data08 != 32 then + return -1 +endi +if $data09 != 12 then return -1 endi print =============== step2 -sql create database $db +sql_error create database $db +sql create database if not exists $db sql show databases if $rows != 1 then return -1 -endi +endi print =============== step3 sql drop database $db diff --git a/tests/script/tsim/insert/basic0.sim b/tests/script/tsim/insert/basic0.sim new file mode 100644 index 0000000000..eb4780caac --- /dev/null +++ b/tests/script/tsim/insert/basic0.sim @@ -0,0 +1,334 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print =============== create database +sql create database d0 +sql show databases +if $rows != 1 then + return -1 +endi + +print $data00 $data01 $data02 + +sql use d0 + +print =============== create super table, include column type for count/sum/min/max/first +sql create table if not exists stb (ts timestamp, c1 int, c2 float, c3 double) tags (t1 int unsigned) + +sql show stables +if $rows != 1 then + return -1 +endi + +print =============== create child table +sql create table ct1 using stb tags(1000) +sql create table ct2 using stb tags(2000) + +sql show tables +if $rows != 2 then + return -1 +endi + + +print =============== insert data, mode1: one row one table in sql +print =============== insert data, mode1: mulit rows one table in sql +print =============== insert data, mode1: one rows mulit table in sql +print =============== insert data, mode1: mulit rows mulit table in sql +sql insert into ct1 values(now+0s, 10, 2.0, 3.0) +sql insert into ct1 values(now+1s, 11, 2.1, 3.1)(now+2s, 12, 2.2, 3.2)(now+3s, 13, 2.3, 3.3) +sql insert into ct2 values(now+0s, 10, 2.0, 3.0) +sql insert into ct2 values(now+1s, 11, 2.1, 3.1)(now+2s, 12, 2.2, 3.2)(now+3s, 13, 2.3, 3.3) +# after fix bug, modify sql_error to sql +sql_error insert into ct1 values(now+4s, -14, -2.4, -3.4) ct2 values(now+4s, -14, -2.4, -3.4) +sql_error insert into ct1 values(now+5s, -15, -2.5, -3.5)(now+6s, -16, -2.6, -3.6) ct2 values(now+5s, -15, -2.5, -3.5)(now+6s, -16, -2.6, -3.6) + +#=================================================================== +#=================================================================== +print =============== query data from child table +sql select * from ct1 +if $rows != 4 then # after fix bug, modify 4 to 7 + return -1 +endi +if $data01 != 10 then + return -1 +endi +if $data02 != 2.00000 then + return -1 +endi +if $data03 != 3.000000000 then + return -1 +endi +#if $data41 != -14 then +# return -1 +#endi +#if $data42 != -2.40000 then +# return -1 +#endi +#if $data43 != -3.400000000 then +# return -1 +#endi + + +print =============== select count(*) from child table +sql select count(*) from ct1 +if $rows != 1 then + return -1 +endi + +print $data00 $data01 $data02 +if $data00 != 4 then + return -1 +endi + +print =============== select count(column) from child table +sql select count(ts), count(c1), count(c2), count(c3) from ct1 +print $data00 $data01 $data02 $data03 +if $data00 != 4 then + return -1 +endi +if $data01 != 4 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data03 != 4 then + return -1 +endi + +#print =============== select first(*)/first(column) from child table +#sql select first(*) from ct1 +#sql select first(ts), first(c1), first(c2), first(c3) from ct1 + +print =============== select min(column) from child table +sql select min(c1), min(c2), min(c3) from ct1 +print $data00 $data01 $data02 $data03 +if $rows != 1 then + return -1 +endi +if $data00 != 10 then + return -1 +endi +if $data01 != 2.00000 then + return -1 +endi +if $data02 != 3.000000000 then + return -1 +endi + +print =============== select max(column) from child table +sql select max(c1), max(c2), max(c3) from ct1 +print $data00 $data01 $data02 $data03 +if $rows != 1 then + return -1 +endi +if $data00 != 13 then + return -1 +endi +if $data01 != 2.30000 then + return -1 +endi +if $data02 != 3.300000000 then + return -1 +endi + +print =============== select sum(column) from child table +sql select sum(c1), sum(c2), sum(c3) from ct1 +print $data00 $data01 $data02 $data03 +if $rows != 1 then + return -1 +endi +if $data00 != 46 then + return -1 +endi +if $data01 != 8.599999905 then + return -1 +endi +if $data02 != 12.600000000 then + return -1 +endi + +print =============== select column, from child table +sql select c1, c2, c3 from ct1 +print $data00 $data01 $data02 +#if $rows != 4 then +# return -1 +#endi +#if $data00 != 10 then +# return -1 +#endi +#if $data01 != 2.00000 then +# return -1 +#endi +#if $data02 != 3.000000000 then +# return -1 +#endi +#if $data10 != 11 then +# return -1 +#endi +#if $data11 != 2.10000 then +# return -1 +#endi +#if $data12 != 3.100000000 then +# return -1 +#endi +#if $data30 != 13 then +# return -1 +#endi +#if $data31 != 2.30000 then +# return -1 +#endi +#if $data32 != 3.300000000 then +# return -1 +#endi +#=================================================================== +#=================================================================== + +#print =============== query data from stb +#sql select * from stb +#if $rows != 4 then +# return -1 +#endi +#print =============== select count(*) from supter table +#sql select count(*) from stb +#if $rows != 1 then +# return -1 +#endi +# +#print $data00 $data01 $data02 +#if $data00 != 8 then +# return -1 +#endi +# +#print =============== select count(column) from supter table +#sql select count(ts), count(c1), count(c2), count(c3) from stb +#print $data00 $data01 $data02 $data03 +#if $data00 != 8 then +# return -1 +#endi +#if $data01 != 8 then +# return -1 +#endi +#if $data02 != 8 then +# return -1 +#endi +#if $data03 != 8 then +# return -1 +#endi + + +#=================================================================== +#=================================================================== + +print =============== stop and restart taosd, then again do query above +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode1 -s start + +sleep 2000 +sql select * from ct1 +if $rows != 4 then # after fix bug, modify 4 to 7 + return -1 +endi +if $data01 != 10 then + return -1 +endi +if $data02 != 2.00000 then + return -1 +endi +if $data03 != 3.000000000 then + return -1 +endi +#if $data41 != -14 then +# return -1 +#endi +#if $data42 != -2.40000 then +# return -1 +#endi +#if $data43 != -3.400000000 then +# return -1 +#endi + + +print =============== select count(*) from child table +sql select count(*) from ct1 +if $rows != 1 then + return -1 +endi + +print $data00 $data01 $data02 +if $data00 != 4 then + return -1 +endi + +print =============== select count(column) from child table +sql select count(ts), count(c1), count(c2), count(c3) from ct1 +print $data00 $data01 $data02 $data03 +if $data00 != 4 then + return -1 +endi +if $data01 != 4 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data03 != 4 then + return -1 +endi + +#print =============== select first(*)/first(column) from child table +#sql select first(*) from ct1 +#sql select first(ts), first(c1), first(c2), first(c3) from ct1 + +print =============== select min(column) from child table +sql select min(c1), min(c2), min(c3) from ct1 +print $data00 $data01 $data02 $data03 +if $rows != 1 then + return -1 +endi +if $data00 != 10 then + return -1 +endi +if $data01 != 2.00000 then + return -1 +endi +if $data02 != 3.000000000 then + return -1 +endi + +print =============== select max(column) from child table +sql select max(c1), max(c2), max(c3) from ct1 +print $data00 $data01 $data02 $data03 +if $rows != 1 then + return -1 +endi +if $data00 != 13 then + return -1 +endi +if $data01 != 2.30000 then + return -1 +endi +if $data02 != 3.300000000 then + return -1 +endi + +print =============== select sum(column) from child table +sql select sum(c1), sum(c2), sum(c3) from ct1 +print $data00 $data01 $data02 $data03 +if $rows != 1 then + return -1 +endi +if $data00 != 46 then + return -1 +endi +if $data01 != 8.599999905 then + return -1 +endi +if $data02 != 12.600000000 then + return -1 +endi + +#system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/table/basic1.sim b/tests/script/tsim/table/basic1.sim index 9e94c3a311..257c264159 100644 --- a/tests/script/tsim/table/basic1.sim +++ b/tests/script/tsim/table/basic1.sim @@ -61,10 +61,50 @@ if $rows != 7 then endi print $data00 $data01 $data02 -print $data10 $data11 $data22 -print $data20 $data11 $data22 +print $data10 $data11 $data12 +print $data20 $data21 $data22 + +print =============== create normal table +sql create database ndb +sql use ndb +sql create table nt0 (ts timestamp, i int) +sql create table if not exists nt0 (ts timestamp, i int) +sql create table nt1 (ts timestamp, i int) +sql create table if not exists nt1 (ts timestamp, i int) +sql create table if not exists nt3 (ts timestamp, i int) + +sql show tables +if $rows != 3 then + return -1 +endi + +sql insert into nt0 values(now+1s, 1)(now+2s, 2)(now+3s, 3) +sql insert into nt1 values(now+1s, 1)(now+2s, 2)(now+3s, 3) + +sql select * from nt1 +if $rows != 3 then + return -1 +endi + +print $data00 $data01 +print $data10 $data11 +print $data20 $data21 + +if $data01 != 1 then + return -1 +endi + +if $data11 != 2 then + return -1 +endi + +if $data21 != 3 then + return -1 +endi + print =============== insert data +sql use d1 sql insert into c1 values(now+1s, 1) sql insert into c1 values(now+2s, 2) sql insert into c1 values(now+3s, 3) @@ -95,7 +135,7 @@ endi print $data00 $data01 print $data10 $data11 -print $data20 $data11 +print $data20 $data21 if $data01 != 1 then return -1 @@ -160,7 +200,7 @@ endi print $data00 $data01 print $data10 $data11 -print $data20 $data11 +print $data20 $data21 if $data01 != 1 then return -1 @@ -210,4 +250,28 @@ if $rows != 21 then return -1 endi +print =============== query data from normal table after restart dnode +sql use ndb +sql select * from nt1 +if $rows != 3 then + print expect 3, actual: $rows + return -1 +endi + +print $data00 $data01 +print $data10 $data11 +print $data20 $data21 + +if $data01 != 1 then + return -1 +endi + +if $data11 != 2 then + return -1 +endi + +if $data21 != 3 then + return -1 +endi + system sh/exec.sh -n dnode1 -s stop -x SIGINT