Merge branch '3.0' into feature/tq
This commit is contained in:
commit
0cce6ba628
|
@ -227,6 +227,9 @@ int32_t blockDataTrimFirstNRows(SSDataBlock* pBlock, size_t n);
|
|||
|
||||
SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData);
|
||||
|
||||
void blockCompressEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols, int8_t needCompress);
|
||||
const char* blockCompressDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t numOfRows, const char* pData);
|
||||
|
||||
void blockDebugShowData(const SArray* dataBlocks);
|
||||
|
||||
int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks, STSchema* pTSchema, int32_t vgId,
|
||||
|
@ -246,54 +249,6 @@ static FORCE_INLINE int32_t blockCompressColData(SColumnInfoData* pColRes, int32
|
|||
colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void blockCompressEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols,
|
||||
int8_t needCompress) {
|
||||
int32_t* actualLen = (int32_t*)data;
|
||||
data += sizeof(int32_t);
|
||||
|
||||
uint64_t* groupId = (uint64_t*)data;
|
||||
data += sizeof(uint64_t);
|
||||
|
||||
int32_t* colSizes = (int32_t*)data;
|
||||
data += numOfCols * sizeof(int32_t);
|
||||
|
||||
*dataLen = (numOfCols * sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t));
|
||||
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
for (int32_t col = 0; col < numOfCols; ++col) {
|
||||
SColumnInfoData* pColRes = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, col);
|
||||
|
||||
// copy the null bitmap
|
||||
if (IS_VAR_DATA_TYPE(pColRes->info.type)) {
|
||||
size_t metaSize = numOfRows * sizeof(int32_t);
|
||||
memcpy(data, pColRes->varmeta.offset, metaSize);
|
||||
data += metaSize;
|
||||
(*dataLen) += metaSize;
|
||||
} else {
|
||||
int32_t len = BitmapLen(numOfRows);
|
||||
memcpy(data, pColRes->nullbitmap, len);
|
||||
data += len;
|
||||
(*dataLen) += len;
|
||||
}
|
||||
|
||||
if (needCompress) {
|
||||
colSizes[col] = blockCompressColData(pColRes, numOfRows, data, needCompress);
|
||||
data += colSizes[col];
|
||||
(*dataLen) += colSizes[col];
|
||||
} else {
|
||||
colSizes[col] = colDataGetLength(pColRes, numOfRows);
|
||||
(*dataLen) += colSizes[col];
|
||||
memmove(data, pColRes->pData, colSizes[col]);
|
||||
data += colSizes[col];
|
||||
}
|
||||
|
||||
colSizes[col] = htonl(colSizes[col]);
|
||||
}
|
||||
|
||||
*actualLen = *dataLen;
|
||||
*groupId = pBlock->info.groupId;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,8 @@ extern bool tsEnableSlaveQuery;
|
|||
extern bool tsPrintAuth;
|
||||
extern int64_t tsTickPerMin[3];
|
||||
|
||||
extern int32_t tsCountAlwaysReturnValue;
|
||||
|
||||
// multi-process
|
||||
extern int32_t tsMultiProcess;
|
||||
extern int32_t tsMnodeShmSize;
|
||||
|
@ -102,7 +104,6 @@ extern int32_t tsMaxStreamComputDelay;
|
|||
extern int32_t tsStreamCompStartDelay;
|
||||
extern int32_t tsRetryStreamCompDelay;
|
||||
extern float tsStreamComputDelayRatio; // the delayed computing ration of the whole time window
|
||||
extern int32_t tsProjectExecInterval;
|
||||
extern int64_t tsMaxRetentWindow;
|
||||
|
||||
// build info
|
||||
|
|
|
@ -571,13 +571,6 @@ int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pR
|
|||
int32_t tDeserializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp);
|
||||
void tFreeSGetUserAuthRsp(SGetUserAuthRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
int16_t colId; // column id
|
||||
int16_t colIndex; // column index in colList if it is a normal column or index in tagColList if a tag
|
||||
int16_t flag; // denote if it is a tag or a normal column
|
||||
char name[TSDB_DB_FNAME_LEN];
|
||||
} SColIndex;
|
||||
|
||||
typedef struct {
|
||||
int16_t lowerRelOptr;
|
||||
int16_t upperRelOptr;
|
||||
|
@ -779,6 +772,7 @@ typedef struct {
|
|||
int8_t cacheLastRow;
|
||||
int32_t numOfRetensions;
|
||||
SArray* pRetensions;
|
||||
int8_t schemaless;
|
||||
} SDbCfgRsp;
|
||||
|
||||
int32_t tSerializeSDbCfgRsp(void* buf, int32_t bufLen, const SDbCfgRsp* pRsp);
|
||||
|
@ -1127,6 +1121,14 @@ typedef struct {
|
|||
SSchema* pSchemas;
|
||||
} STableMetaRsp;
|
||||
|
||||
typedef struct {
|
||||
STableMetaRsp* pMeta;
|
||||
} SMAlterStbRsp;
|
||||
|
||||
int32_t tEncodeSMAlterStbRsp(SEncoder *pEncoder, const SMAlterStbRsp *pRsp);
|
||||
int32_t tDecodeSMAlterStbRsp(SDecoder *pDecoder, SMAlterStbRsp *pRsp);
|
||||
void tFreeSMAlterStbRsp(SMAlterStbRsp* pRsp);
|
||||
|
||||
int32_t tSerializeSTableMetaRsp(void* buf, int32_t bufLen, STableMetaRsp* pRsp);
|
||||
int32_t tDeserializeSTableMetaRsp(void* buf, int32_t bufLen, STableMetaRsp* pRsp);
|
||||
void tFreeSTableMetaRsp(STableMetaRsp* pRsp);
|
||||
|
@ -1880,7 +1882,8 @@ int32_t tEncodeSVAlterTbReq(SEncoder* pEncoder, const SVAlterTbReq* pReq);
|
|||
int32_t tDecodeSVAlterTbReq(SDecoder* pDecoder, SVAlterTbReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
int32_t code;
|
||||
int32_t code;
|
||||
STableMetaRsp* pMeta;
|
||||
} SVAlterTbRsp;
|
||||
|
||||
int32_t tEncodeSVAlterTbRsp(SEncoder* pEncoder, const SVAlterTbRsp* pRsp);
|
||||
|
@ -2344,19 +2347,19 @@ typedef struct {
|
|||
STSma* tSma;
|
||||
} STSmaWrapper;
|
||||
|
||||
static FORCE_INLINE void tdDestroyTSma(STSma* pSma) {
|
||||
static FORCE_INLINE void tDestroyTSma(STSma* pSma) {
|
||||
if (pSma) {
|
||||
taosMemoryFreeClear(pSma->expr);
|
||||
taosMemoryFreeClear(pSma->tagsFilter);
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tdDestroyTSmaWrapper(STSmaWrapper* pSW, bool deepCopy) {
|
||||
static FORCE_INLINE void tDestroyTSmaWrapper(STSmaWrapper* pSW, bool deepCopy) {
|
||||
if (pSW) {
|
||||
if (pSW->tSma) {
|
||||
if (deepCopy) {
|
||||
for (uint32_t i = 0; i < pSW->number; ++i) {
|
||||
tdDestroyTSma(pSW->tSma + i);
|
||||
tDestroyTSma(pSW->tSma + i);
|
||||
}
|
||||
}
|
||||
taosMemoryFreeClear(pSW->tSma);
|
||||
|
@ -2364,8 +2367,8 @@ static FORCE_INLINE void tdDestroyTSmaWrapper(STSmaWrapper* pSW, bool deepCopy)
|
|||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tdFreeTSmaWrapper(STSmaWrapper* pSW, bool deepCopy) {
|
||||
tdDestroyTSmaWrapper(pSW, deepCopy);
|
||||
static FORCE_INLINE void* tFreeTSmaWrapper(STSmaWrapper* pSW, bool deepCopy) {
|
||||
tDestroyTSmaWrapper(pSW, deepCopy);
|
||||
taosMemoryFreeClear(pSW);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2392,6 +2395,17 @@ static int32_t tDecodeTSmaWrapper(SDecoder* pDecoder, STSmaWrapper* pReq) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int64_t tsmaIndexUid;
|
||||
STimeWindow queryWindow;
|
||||
} SVGetTsmaExpWndsReq;
|
||||
|
||||
typedef struct {
|
||||
int64_t tsmaIndexUid;
|
||||
int32_t numExpWnds;
|
||||
TSKEY* expWndsStartTs;
|
||||
} SVGetTsmaExpWndsRsp;
|
||||
|
||||
typedef struct {
|
||||
int idx;
|
||||
} SMCreateFullTextReq;
|
||||
|
|
|
@ -205,6 +205,7 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_VND_CANCEL_SMA, "vnode-cancel-sma", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_DROP_SMA, "vnode-drop-sma", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SUBMIT_RSMA, "vnode-submit-rsma", SSubmitReq, SSubmitRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_GET_TSMA_EXP_WNDS, "vnode-get-tsma-expired-windows", SVGetTsmaExpWndsReq, SVGetTsmaExpWndsRsp)
|
||||
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_TIMEOUT, "vnode-sync-timeout", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_PING, "vnode-sync-ping", NULL, NULL)
|
||||
|
|
|
@ -183,7 +183,7 @@ int32_t catalogGetTableMeta(SCatalog* pCatalog, void * pTransporter, const SEpSe
|
|||
*/
|
||||
int32_t catalogGetSTableMeta(SCatalog* pCatalog, void * pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta);
|
||||
|
||||
int32_t catalogUpdateSTableMeta(SCatalog* pCatalog, STableMetaRsp *rspMsg);
|
||||
int32_t catalogUpdateTableMeta(SCatalog* pCatalog, STableMetaRsp *rspMsg);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -156,18 +156,6 @@ int64_t qGetQueriedTableUid(qTaskInfo_t tinfo);
|
|||
*/
|
||||
int32_t qGetQualifiedTableIdList(void* pTableList, const char* tagCond, int32_t tagCondLen, SArray* pTableIdList);
|
||||
|
||||
/**
|
||||
* Create the table group according to the group by tags info
|
||||
* @param pTableIdList
|
||||
* @param skey
|
||||
* @param groupInfo
|
||||
* @param groupByIndex
|
||||
* @param numOfIndex
|
||||
* @return
|
||||
*/
|
||||
// int32_t qCreateTableGroupByGroupExpr(SArray* pTableIdList, TSKEY skey, STableGroupInfo groupInfo, SColIndex*
|
||||
// groupByIndex, int32_t numOfIndex);
|
||||
|
||||
/**
|
||||
* Update the table id list of a given query.
|
||||
* @param uid child table uid
|
||||
|
|
|
@ -61,56 +61,9 @@ typedef struct SFileBlockInfo {
|
|||
#define TSDB_BLOCK_DIST_STEP_ROWS 8
|
||||
#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
|
||||
|
||||
#define FUNCTION_TYPE_SCALAR 1
|
||||
#define FUNCTION_TYPE_AGG 2
|
||||
|
||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||
#define FUNCTIONS_NAME_MAX_LENGTH 16
|
||||
|
||||
#define FUNCTION_INVALID_ID -1
|
||||
#define FUNCTION_COUNT 0
|
||||
#define FUNCTION_SUM 1
|
||||
#define FUNCTION_AVG 2
|
||||
#define FUNCTION_MIN 3
|
||||
#define FUNCTION_MAX 4
|
||||
#define FUNCTION_STDDEV 5
|
||||
#define FUNCTION_PERCT 6
|
||||
#define FUNCTION_APERCT 7
|
||||
#define FUNCTION_FIRST 8
|
||||
#define FUNCTION_LAST 9
|
||||
#define FUNCTION_LAST_ROW 10
|
||||
#define FUNCTION_TOP 11
|
||||
#define FUNCTION_BOTTOM 12
|
||||
#define FUNCTION_SPREAD 13
|
||||
#define FUNCTION_TWA 14
|
||||
#define FUNCTION_LEASTSQR 15
|
||||
|
||||
#define FUNCTION_TS 16
|
||||
#define FUNCTION_TS_DUMMY 17
|
||||
#define FUNCTION_TAG_DUMMY 18
|
||||
#define FUNCTION_TS_COMP 19
|
||||
|
||||
#define FUNCTION_TAG 20
|
||||
#define FUNCTION_PRJ 21
|
||||
|
||||
#define FUNCTION_TAGPRJ 22
|
||||
#define FUNCTION_ARITHM 23
|
||||
#define FUNCTION_DIFF 24
|
||||
|
||||
#define FUNCTION_FIRST_DST 25
|
||||
#define FUNCTION_LAST_DST 26
|
||||
#define FUNCTION_STDDEV_DST 27
|
||||
#define FUNCTION_INTERP 28
|
||||
|
||||
#define FUNCTION_RATE 29
|
||||
#define FUNCTION_IRATE 30
|
||||
#define FUNCTION_TID_TAG 31
|
||||
#define FUNCTION_DERIVATIVE 32
|
||||
#define FUNCTION_BLKINFO 33
|
||||
|
||||
|
||||
#define FUNCTION_COV 38
|
||||
|
||||
typedef struct SResultRowEntryInfo {
|
||||
bool initialized:1; // output buffer has been initialized
|
||||
bool complete:1; // query has completed
|
||||
|
@ -180,10 +133,9 @@ typedef struct SqlFunctionCtx {
|
|||
char *pOutput; // final result output buffer, point to sdata->data
|
||||
int32_t numOfParams;
|
||||
SFunctParam *param; // input parameter, e.g., top(k, 20), the number of results for top query is kept in param
|
||||
int64_t *ptsList; // corresponding timestamp array list
|
||||
int64_t *ptsList; // corresponding timestamp array list, todo remove it
|
||||
SColumnInfoData *pTsOutput; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
|
||||
int32_t offset;
|
||||
SVariant tag;
|
||||
struct SResultRowEntryInfo *resultInfo;
|
||||
SSubsidiaryResInfo subsidiaries;
|
||||
SPoint1 start;
|
||||
|
@ -210,9 +162,6 @@ enum {
|
|||
typedef struct tExprNode {
|
||||
int32_t nodeType;
|
||||
union {
|
||||
SSchema *pSchema;// column node
|
||||
struct SVariant *pVal; // value node
|
||||
|
||||
struct {// function node
|
||||
char functionName[FUNCTIONS_NAME_MAX_LENGTH]; // todo refactor
|
||||
int32_t functionId;
|
||||
|
@ -255,47 +204,23 @@ struct SScalarParam {
|
|||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
|
||||
bool isSuperTable);
|
||||
|
||||
bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId);
|
||||
|
||||
void resetResultRowEntryResult(SqlFunctionCtx* pCtx, int32_t num);
|
||||
void cleanupResultRowEntry(struct SResultRowEntryInfo* pCell);
|
||||
int32_t getNumOfResult(SqlFunctionCtx* pCtx, int32_t num, SSDataBlock* pResBlock);
|
||||
bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry);
|
||||
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// fill api
|
||||
struct SFillInfo;
|
||||
struct SFillColInfo;
|
||||
|
||||
typedef struct SPoint {
|
||||
int64_t key;
|
||||
void * val;
|
||||
} SPoint;
|
||||
|
||||
//void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey);
|
||||
//void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp);
|
||||
//void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
||||
//struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, const SValueNode* val);
|
||||
//bool taosFillHasMoreResults(struct SFillInfo* pFillInfo);
|
||||
//
|
||||
//struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
|
||||
// SInterval* pInterval, int32_t fillType,
|
||||
// struct SFillColInfo* pCol, const char* id);
|
||||
//
|
||||
//void* taosDestroyFillInfo(struct SFillInfo *pFillInfo);
|
||||
//int64_t taosFillResultDataBlock(struct SFillInfo* pFillInfo, void** output, int32_t capacity);
|
||||
//int64_t getFillInfoStart(struct SFillInfo *pFillInfo);
|
||||
|
||||
int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint* point1, SPoint* point2, int32_t inputType);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// udf api
|
||||
struct SUdfInfo;
|
||||
|
||||
void qAddUdfInfo(uint64_t id, struct SUdfInfo* pUdfInfo);
|
||||
void qRemoveUdfInfo(uint64_t id, struct SUdfInfo* pUdfInfo);
|
||||
|
||||
/**
|
||||
* create udfd proxy, called once in process that call doSetupUdf/callUdfxxx/doTeardownUdf
|
||||
* @return error code
|
||||
|
|
|
@ -331,8 +331,8 @@ typedef struct SQuery {
|
|||
int8_t precision;
|
||||
SCmdMsgInfo* pCmdMsg;
|
||||
int32_t msgType;
|
||||
SArray* pDbList;
|
||||
SArray* pTableList;
|
||||
SArray* pDbList;
|
||||
bool showRewrite;
|
||||
int32_t placeholderNum;
|
||||
SArray* pPlaceholderValues;
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct SParseContext {
|
|||
const char* pUser;
|
||||
bool isSuperUser;
|
||||
bool async;
|
||||
int8_t schemalessType;
|
||||
} SParseContext;
|
||||
|
||||
int32_t qParseSql(SParseContext* pCxt, SQuery** pQuery);
|
||||
|
|
|
@ -56,6 +56,11 @@ typedef struct STableComInfo {
|
|||
int32_t rowSize; // row size of the schema
|
||||
} STableComInfo;
|
||||
|
||||
typedef struct SQueryExecRes {
|
||||
int32_t msgType;
|
||||
void* res;
|
||||
} SQueryExecRes;
|
||||
|
||||
typedef struct SIndexMeta {
|
||||
#ifdef WINDOWS
|
||||
size_t avoidCompilationErrors;
|
||||
|
@ -192,6 +197,7 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp* msg, bool isSuperTable, STabl
|
|||
char* jobTaskStatusStr(int32_t status);
|
||||
|
||||
SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* name);
|
||||
void destroyQueryExecRes(SQueryExecRes* pRes);
|
||||
|
||||
extern int32_t (*queryBuildMsg[TDMT_MAX])(void *input, char **msg, int32_t msgSize, int32_t *msgLen, void*(*mallocFp)(int32_t));
|
||||
extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t msgSize);
|
||||
|
@ -204,7 +210,8 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
|||
#define NEED_CLIENT_RM_TBLMETA_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_PAR_TABLE_NOT_EXIST || (_code) == TSDB_CODE_VND_TB_NOT_EXIST || \
|
||||
(_code) == TSDB_CODE_PAR_INVALID_COLUMNS_NUM || (_code) == TSDB_CODE_PAR_INVALID_COLUMN || \
|
||||
(_code) == TSDB_CODE_PAR_TAGS_NOT_MATCHED || (_code == TSDB_CODE_PAR_VALUE_TOO_LONG))
|
||||
(_code) == TSDB_CODE_PAR_TAGS_NOT_MATCHED || (_code == TSDB_CODE_PAR_VALUE_TOO_LONG) || \
|
||||
(_code == TSDB_CODE_PAR_INVALID_DROP_COL))
|
||||
#define NEED_CLIENT_REFRESH_VG_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_VND_HASH_MISMATCH || (_code) == TSDB_CODE_VND_INVALID_VGROUP_ID)
|
||||
#define NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code) ((_code) == TSDB_CODE_TDB_TABLE_RECREATED)
|
||||
|
|
|
@ -56,7 +56,7 @@ typedef struct SQueryProfileSummary {
|
|||
typedef struct SQueryResult {
|
||||
int32_t code;
|
||||
uint64_t numOfRows;
|
||||
void *res;
|
||||
SQueryExecRes res;
|
||||
} SQueryResult;
|
||||
|
||||
typedef struct STaskInfo {
|
||||
|
|
|
@ -675,6 +675,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_SML_INVALID_PROTOCOL_TYPE TAOS_DEF_ERROR_CODE(0, 0x3000)
|
||||
#define TSDB_CODE_SML_INVALID_PRECISION_TYPE TAOS_DEF_ERROR_CODE(0, 0x3001)
|
||||
#define TSDB_CODE_SML_INVALID_DATA TAOS_DEF_ERROR_CODE(0, 0x3002)
|
||||
#define TSDB_CODE_SML_INVALID_DB_CONF TAOS_DEF_ERROR_CODE(0, 0x3003)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ int32_t tdListAppend(SList *list, void *data);
|
|||
SListNode *tdListPopHead(SList *list);
|
||||
SListNode *tdListPopTail(SList *list);
|
||||
SListNode *tdListGetHead(SList *list);
|
||||
SListNode *tsListGetTail(SList *list);
|
||||
SListNode *tdListGetTail(SList *list);
|
||||
SListNode *tdListPopNode(SList *list, SListNode *node);
|
||||
void tdListMove(SList *src, SList *dst);
|
||||
void tdListDiscard(SList *list);
|
||||
|
|
|
@ -151,6 +151,7 @@ typedef struct STscObj {
|
|||
int32_t numOfReqs; // number of sqlObj bound to this connection
|
||||
SAppInstInfo* pAppInfo;
|
||||
SHashObj* pRequests;
|
||||
int8_t schemalessType;
|
||||
} STscObj;
|
||||
|
||||
typedef struct SResultColumn {
|
||||
|
@ -162,6 +163,7 @@ typedef struct SResultColumn {
|
|||
} SResultColumn;
|
||||
|
||||
typedef struct SReqResultInfo {
|
||||
SQueryExecRes execRes;
|
||||
const char* pRspMsg;
|
||||
const char* pData;
|
||||
TAOS_FIELD* fields; // todo, column names are not needed.
|
||||
|
@ -319,7 +321,7 @@ void hbMgrInitMqHbRspHandle();
|
|||
|
||||
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery, void** res);
|
||||
int32_t getQueryPlan(SRequestObj* pRequest, SQuery* pQuery, SArray** pNodeList);
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList, void** res);
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList);
|
||||
int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest);
|
||||
int32_t updateQnodeList(SAppInstInfo* pInfo, SArray* pNodeList);
|
||||
|
||||
|
|
|
@ -161,6 +161,7 @@ void *createTscObj(const char *user, const char *auth, const char *db, int32_t c
|
|||
|
||||
taosThreadMutexInit(&pObj->mutex, NULL);
|
||||
pObj->id = taosAddRef(clientConnRefPool, pObj);
|
||||
pObj->schemalessType = 0;
|
||||
|
||||
tscDebug("connObj created, 0x%" PRIx64, pObj->id);
|
||||
return pObj;
|
||||
|
@ -234,6 +235,8 @@ static void doDestroyRequest(void *p) {
|
|||
taosArrayDestroy(pRequest->tableList);
|
||||
taosArrayDestroy(pRequest->dbList);
|
||||
|
||||
destroyQueryExecRes(&pRequest->body.resInfo.execRes);
|
||||
|
||||
deregisterRequest(pRequest);
|
||||
taosMemoryFreeClear(pRequest);
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ static int32_t hbProcessStbInfoRsp(void *value, int32_t valueLen, struct SCatalo
|
|||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
catalogUpdateSTableMeta(pCatalog, rsp);
|
||||
catalogUpdateTableMeta(pCatalog, rsp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@ int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtC
|
|||
.pTransporter = pTscObj->pAppInfo->pTransporter,
|
||||
.pStmtCb = pStmtCb,
|
||||
.pUser = pTscObj->user,
|
||||
.schemalessType = pTscObj->schemalessType,
|
||||
.isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER))};
|
||||
|
||||
cxt.mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
|
||||
|
@ -340,22 +341,23 @@ void setResPrecision(SReqResultInfo* pResInfo, int32_t precision) {
|
|||
pResInfo->precision = precision;
|
||||
}
|
||||
|
||||
int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList, void** pRes) {
|
||||
int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
|
||||
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
|
||||
|
||||
tsem_init(&schdRspSem, 0, 0);
|
||||
|
||||
SQueryResult res = {.code = 0, .numOfRows = 0};
|
||||
int32_t code = schedulerAsyncExecJob(pTransporter, pNodeList, pDag, &pRequest->body.queryJob, pRequest->sqlstr,
|
||||
pRequest->metric.start, schdExecCallback, &res);
|
||||
while (true) {
|
||||
pRequest->metric.start, schdExecCallback, &res);
|
||||
|
||||
pRequest->body.resInfo.execRes = res.res;
|
||||
|
||||
while (true) {
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
if (pRequest->body.queryJob != 0) {
|
||||
schedulerFreeJob(pRequest->body.queryJob);
|
||||
}
|
||||
|
||||
*pRes = res.res;
|
||||
|
||||
pRequest->code = code;
|
||||
terrno = code;
|
||||
return pRequest->code;
|
||||
|
@ -378,26 +380,25 @@ int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNod
|
|||
}
|
||||
}
|
||||
|
||||
*pRes = res.res;
|
||||
|
||||
pRequest->code = res.code;
|
||||
terrno = res.code;
|
||||
return pRequest->code;
|
||||
}
|
||||
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList, void** pRes) {
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
|
||||
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
|
||||
|
||||
SQueryResult res = {.code = 0, .numOfRows = 0};
|
||||
int32_t code = schedulerExecJob(pTransporter, pNodeList, pDag, &pRequest->body.queryJob, pRequest->sqlstr,
|
||||
pRequest->metric.start, &res);
|
||||
|
||||
pRequest->body.resInfo.execRes = res.res;
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
if (pRequest->body.queryJob != 0) {
|
||||
schedulerFreeJob(pRequest->body.queryJob);
|
||||
}
|
||||
|
||||
*pRes = res.res;
|
||||
|
||||
pRequest->code = code;
|
||||
terrno = code;
|
||||
return pRequest->code;
|
||||
|
@ -411,8 +412,6 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList
|
|||
}
|
||||
}
|
||||
|
||||
*pRes = res.res;
|
||||
|
||||
pRequest->code = res.code;
|
||||
terrno = res.code;
|
||||
return pRequest->code;
|
||||
|
@ -422,80 +421,109 @@ int32_t getQueryPlan(SRequestObj* pRequest, SQuery* pQuery, SArray** pNodeList)
|
|||
return getPlan(pRequest, pQuery, &pRequest->body.pDag, pNodeList);
|
||||
}
|
||||
|
||||
int32_t validateSversion(SRequestObj* pRequest, void* res) {
|
||||
SArray* pArray = NULL;
|
||||
int32_t handleSubmitExecRes(SRequestObj* pRequest, void* res, SCatalog* pCatalog, SEpSet *epset) {
|
||||
int32_t code = 0;
|
||||
|
||||
if (TDMT_VND_SUBMIT == pRequest->type) {
|
||||
SSubmitRsp* pRsp = (SSubmitRsp*)res;
|
||||
if (pRsp->nBlocks <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pArray = taosArrayInit(pRsp->nBlocks, sizeof(STbSVersion));
|
||||
if (NULL == pArray) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pRsp->nBlocks; ++i) {
|
||||
SSubmitBlkRsp* blk = pRsp->pBlocks + i;
|
||||
if (NULL == blk->tblFName || 0 == blk->tblFName[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
STbSVersion tbSver = {.tbFName = blk->tblFName, .sver = blk->sver};
|
||||
taosArrayPush(pArray, &tbSver);
|
||||
}
|
||||
} else if (TDMT_VND_QUERY == pRequest->type) {
|
||||
SArray* pTbArray = (SArray*)res;
|
||||
int32_t tbNum = taosArrayGetSize(pTbArray);
|
||||
if (tbNum <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pArray = taosArrayInit(tbNum, sizeof(STbSVersion));
|
||||
if (NULL == pArray) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < tbNum; ++i) {
|
||||
STbVerInfo* tbInfo = taosArrayGet(pTbArray, i);
|
||||
STbSVersion tbSver = {.tbFName = tbInfo->tbFName, .sver = tbInfo->sversion, .tver = tbInfo->tversion};
|
||||
taosArrayPush(pArray, &tbSver);
|
||||
SArray* pArray = NULL;
|
||||
SSubmitRsp* pRsp = (SSubmitRsp*)res;
|
||||
if (pRsp->nBlocks <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pArray = taosArrayInit(pRsp->nBlocks, sizeof(STbSVersion));
|
||||
if (NULL == pArray) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pRsp->nBlocks; ++i) {
|
||||
SSubmitBlkRsp* blk = pRsp->pBlocks + i;
|
||||
if (NULL == blk->tblFName || 0 == blk->tblFName[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
STbSVersion tbSver = {.tbFName = blk->tblFName, .sver = blk->sver};
|
||||
taosArrayPush(pArray, &tbSver);
|
||||
}
|
||||
|
||||
SCatalog* pCatalog = NULL;
|
||||
CHECK_CODE_GOTO(catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog), _return);
|
||||
|
||||
SEpSet epset = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp);
|
||||
|
||||
code = catalogChkTbMetaVersion(pCatalog, pRequest->pTscObj->pAppInfo->pTransporter, &epset, pArray);
|
||||
code = catalogChkTbMetaVersion(pCatalog, pRequest->pTscObj->pAppInfo->pTransporter, epset, pArray);
|
||||
|
||||
_return:
|
||||
|
||||
taosArrayDestroy(pArray);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t handleQueryExecRes(SRequestObj* pRequest, void* res, SCatalog* pCatalog, SEpSet *epset) {
|
||||
int32_t code = 0;
|
||||
SArray* pArray = NULL;
|
||||
SArray* pTbArray = (SArray*)res;
|
||||
int32_t tbNum = taosArrayGetSize(pTbArray);
|
||||
if (tbNum <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pArray = taosArrayInit(tbNum, sizeof(STbSVersion));
|
||||
if (NULL == pArray) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < tbNum; ++i) {
|
||||
STbVerInfo* tbInfo = taosArrayGet(pTbArray, i);
|
||||
STbSVersion tbSver = {.tbFName = tbInfo->tbFName, .sver = tbInfo->sversion, .tver = tbInfo->tversion};
|
||||
taosArrayPush(pArray, &tbSver);
|
||||
}
|
||||
|
||||
code = catalogChkTbMetaVersion(pCatalog, pRequest->pTscObj->pAppInfo->pTransporter, epset, pArray);
|
||||
|
||||
_return:
|
||||
|
||||
taosArrayDestroy(pArray);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t handleAlterTbExecRes(void* res, SCatalog* pCatalog) {
|
||||
return catalogUpdateTableMeta(pCatalog, (STableMetaRsp*)res);
|
||||
}
|
||||
|
||||
int32_t handleExecRes(SRequestObj* pRequest) {
|
||||
if (NULL == pRequest->body.resInfo.execRes.res) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SCatalog* pCatalog = NULL;
|
||||
code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
|
||||
if (code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
SEpSet epset = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp);
|
||||
SQueryExecRes* pRes = &pRequest->body.resInfo.execRes;
|
||||
|
||||
switch (pRes->msgType) {
|
||||
case TDMT_VND_ALTER_TABLE:
|
||||
case TDMT_MND_ALTER_STB: {
|
||||
code = handleAlterTbExecRes(pRes->res, pCatalog);
|
||||
break;
|
||||
}
|
||||
case TDMT_VND_SUBMIT: {
|
||||
code = handleSubmitExecRes(pRequest, pRes->res, pCatalog, &epset);
|
||||
break;
|
||||
}
|
||||
case TDMT_VND_QUERY: {
|
||||
code = handleQueryExecRes(pRequest, pRes->res, pCatalog, &epset);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
tscError("invalid exec result for request type %d", pRequest->type);
|
||||
return TSDB_CODE_APP_ERROR;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void freeRequestRes(SRequestObj* pRequest, void* res) {
|
||||
if (NULL == pRequest || NULL == res) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TDMT_VND_SUBMIT == pRequest->type) {
|
||||
tFreeSSubmitRsp((SSubmitRsp*)res);
|
||||
} else if (TDMT_VND_QUERY == pRequest->type) {
|
||||
taosArrayDestroy((SArray*)res);
|
||||
}
|
||||
}
|
||||
|
||||
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery, void** res) {
|
||||
void* pRes = NULL;
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
switch (pQuery->execMode) {
|
||||
case QUERY_EXEC_MODE_LOCAL:
|
||||
|
@ -508,10 +536,7 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code
|
|||
SArray* pNodeList = NULL;
|
||||
code = getPlan(pRequest, pQuery, &pRequest->body.pDag, &pNodeList);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = scheduleQuery(pRequest, pRequest->body.pDag, pNodeList, &pRes);
|
||||
if (NULL != pRes) {
|
||||
code = validateSversion(pRequest, pRes);
|
||||
}
|
||||
code = scheduleQuery(pRequest, pRequest->body.pDag, pNodeList);
|
||||
}
|
||||
taosArrayDestroy(pNodeList);
|
||||
break;
|
||||
|
@ -528,15 +553,15 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code
|
|||
qDestroyQuery(pQuery);
|
||||
}
|
||||
|
||||
handleExecRes(pRequest);
|
||||
|
||||
if (NULL != pRequest && TSDB_CODE_SUCCESS != code) {
|
||||
pRequest->code = terrno;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
*res = pRes;
|
||||
} else {
|
||||
freeRequestRes(pRequest, pRes);
|
||||
pRes = NULL;
|
||||
*res = pRequest->body.resInfo.execRes.res;
|
||||
pRequest->body.resInfo.execRes.res = NULL;
|
||||
}
|
||||
|
||||
return pRequest;
|
||||
|
|
|
@ -223,10 +223,33 @@ int32_t processDropDbRsp(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t processAlterStbRsp(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
SRequestObj* pRequest = param;
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
setErrno(pRequest, code);
|
||||
tsem_post(&pRequest->body.rspSem);
|
||||
return code;
|
||||
}
|
||||
|
||||
SMAlterStbRsp alterRsp = {0};
|
||||
SDecoder coder = {0};
|
||||
tDecoderInit(&coder, pMsg->pData, pMsg->len);
|
||||
tDecodeSMAlterStbRsp(&coder, &alterRsp);
|
||||
tDecoderClear(&coder);
|
||||
|
||||
pRequest->body.resInfo.execRes.msgType = TDMT_MND_ALTER_STB;
|
||||
pRequest->body.resInfo.execRes.res = alterRsp.pMeta;
|
||||
|
||||
tsem_post(&pRequest->body.rspSem);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void initMsgHandleFp() {
|
||||
handleRequestRspFp[TMSG_INDEX(TDMT_MND_CONNECT)] = processConnectRsp;
|
||||
handleRequestRspFp[TMSG_INDEX(TDMT_MND_CREATE_DB)] = processCreateDbRsp;
|
||||
handleRequestRspFp[TMSG_INDEX(TDMT_MND_USE_DB)] = processUseDbRsp;
|
||||
handleRequestRspFp[TMSG_INDEX(TDMT_MND_CREATE_STB)] = processCreateTableRsp;
|
||||
handleRequestRspFp[TMSG_INDEX(TDMT_MND_DROP_DB)] = processDropDbRsp;
|
||||
handleRequestRspFp[TMSG_INDEX(TDMT_MND_ALTER_STB)] = processAlterStbRsp;
|
||||
}
|
||||
|
|
|
@ -960,10 +960,10 @@ static int32_t smlParseInfluxString(const char* sql, SSmlLineInfo *elements, SSm
|
|||
return TSDB_CODE_SML_INVALID_DATA;
|
||||
}
|
||||
elements->colsLen = sql - elements->cols;
|
||||
if(elements->colsLen == 0) {
|
||||
smlBuildInvalidDataMsg(msg, "cols is empty", NULL);
|
||||
return TSDB_CODE_SML_INVALID_DATA;
|
||||
}
|
||||
// if(elements->colsLen == 0) {
|
||||
// smlBuildInvalidDataMsg(msg, "cols is empty", NULL);
|
||||
// return TSDB_CODE_SML_INVALID_DATA;
|
||||
// }
|
||||
|
||||
// parse timestamp
|
||||
JUMP_SPACE(sql)
|
||||
|
@ -1124,7 +1124,7 @@ static int32_t smlParseTelnetString(SSmlHandle *info, const char* sql, SSmlTable
|
|||
}
|
||||
|
||||
static int32_t smlParseCols(const char* data, int32_t len, SArray *cols, char *childTableName, bool isTag, SHashObj *dumplicateKey, SSmlMsgBuf *msg){
|
||||
if(isTag && len == 0){
|
||||
if(len == 0){
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2318,6 +2318,28 @@ cleanup:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t isSchemalessDb(SSmlHandle* info){
|
||||
SName name;
|
||||
tNameSetDbName(&name, info->taos->acctId, info->taos->db, strlen(info->taos->db));
|
||||
char dbFname[TSDB_DB_FNAME_LEN] = {0};
|
||||
tNameGetFullDbName(&name, dbFname);
|
||||
SDbCfgInfo pInfo = {0};
|
||||
SEpSet ep = getEpSet_s(&info->taos->pAppInfo->mgmtEp);
|
||||
|
||||
int32_t code = catalogGetDBCfg(info->pCatalog, info->taos->pAppInfo->pTransporter, &ep, dbFname, &pInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
info->pRequest->code = code;
|
||||
smlBuildInvalidDataMsg(&info->msgBuf, "catalogGetDBCfg error, code:", tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
if (!pInfo.schemaless){
|
||||
info->pRequest->code = TSDB_CODE_SML_INVALID_DB_CONF;
|
||||
smlBuildInvalidDataMsg(&info->msgBuf, "can not insert into schemaless db:", dbFname);
|
||||
return TSDB_CODE_SML_INVALID_DB_CONF;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* taos_schemaless_insert() parse and insert data points into database according to
|
||||
* different protocol.
|
||||
|
@ -2351,6 +2373,19 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr
|
|||
return (TAOS_RES*)request;
|
||||
}
|
||||
|
||||
info->taos->schemalessType = 1;
|
||||
if(request->pDb == NULL){
|
||||
request->code = TSDB_CODE_PAR_DB_NOT_SPECIFIED;
|
||||
smlBuildInvalidDataMsg(&info->msgBuf, "Database not specified", NULL);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(isSchemalessDb(info) != TSDB_CODE_SUCCESS){
|
||||
request->code = TSDB_CODE_SML_INVALID_DB_CONF;
|
||||
smlBuildInvalidDataMsg(&info->msgBuf, "Cannot write data to a non schemaless database", NULL);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!lines) {
|
||||
request->code = TSDB_CODE_SML_INVALID_DATA;
|
||||
smlBuildInvalidDataMsg(&info->msgBuf, "lines is null", NULL);
|
||||
|
@ -2372,6 +2407,7 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr
|
|||
info->pRequest->code = smlProcess(info, lines, numLines);
|
||||
|
||||
end:
|
||||
uDebug("result:%s", info->msgBuf.buf);
|
||||
smlDestroyInfo(info);
|
||||
return (TAOS_RES*)request;
|
||||
}
|
||||
|
|
|
@ -567,6 +567,7 @@ TEST(testCase, insert_test) {
|
|||
taos_free_result(pRes);
|
||||
taos_close(pConn);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(testCase, projection_query_tables) {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
|
@ -625,23 +626,23 @@ TEST(testCase, projection_query_tables) {
|
|||
|
||||
printf("start to insert next table\n");
|
||||
|
||||
for(int32_t i = 0; i < 1000000; i += 20) {
|
||||
char sql[1024] = {0};
|
||||
sprintf(sql,
|
||||
"insert into tu2 values(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)"
|
||||
"(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)"
|
||||
"(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)"
|
||||
"(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)",
|
||||
i, i, i + 1, i + 1, i + 2, i + 2, i + 3, i + 3, i + 4, i + 4, i + 5, i + 5, i + 6, i + 6, i + 7, i + 7,
|
||||
i + 8, i + 8, i + 9, i + 9, i + 10, i + 10, i + 11, i + 11, i + 12, i + 12, i + 13, i + 13, i + 14, i + 14,
|
||||
i + 15, i + 15, i + 16, i + 16, i + 17, i + 17, i + 18, i + 18, i + 19, i + 19);
|
||||
TAOS_RES* p = taos_query(pConn, sql);
|
||||
if (taos_errno(p) != 0) {
|
||||
printf("failed to insert data, reason:%s\n", taos_errstr(p));
|
||||
}
|
||||
|
||||
taos_free_result(p);
|
||||
}
|
||||
// for(int32_t i = 0; i < 1000000; i += 20) {
|
||||
// char sql[1024] = {0};
|
||||
// sprintf(sql,
|
||||
// "insert into tu2 values(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)"
|
||||
// "(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)"
|
||||
// "(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)"
|
||||
// "(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)",
|
||||
// i, i, i + 1, i + 1, i + 2, i + 2, i + 3, i + 3, i + 4, i + 4, i + 5, i + 5, i + 6, i + 6, i + 7, i + 7,
|
||||
// i + 8, i + 8, i + 9, i + 9, i + 10, i + 10, i + 11, i + 11, i + 12, i + 12, i + 13, i + 13, i + 14, i + 14,
|
||||
// i + 15, i + 15, i + 16, i + 16, i + 17, i + 17, i + 18, i + 18, i + 19, i + 19);
|
||||
// TAOS_RES* p = taos_query(pConn, sql);
|
||||
// if (taos_errno(p) != 0) {
|
||||
// printf("failed to insert data, reason:%s\n", taos_errstr(p));
|
||||
// }
|
||||
//
|
||||
// taos_free_result(p);
|
||||
// }
|
||||
|
||||
// pRes = taos_query(pConn, "select * from tu");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
|
@ -663,7 +664,7 @@ TEST(testCase, projection_query_tables) {
|
|||
// taos_free_result(pRes);
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(testCase, projection_query_stables) {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT_NE(pConn, nullptr);
|
||||
|
@ -692,8 +693,6 @@ TEST(testCase, projection_query_stables) {
|
|||
taos_close(pConn);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(testCase, agg_query_tables) {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT_NE(pConn, nullptr);
|
||||
|
@ -734,5 +733,6 @@ TEST(testCase, agg_query_tables) {
|
|||
taos_free_result(pRes);
|
||||
taos_close(pConn);
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
|
|
@ -1258,4 +1258,26 @@ TEST(testCase, sml_TD15742_Test) {
|
|||
|
||||
destroyRequest(request);
|
||||
smlDestroyInfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(testCase, sml_params_Test) {
|
||||
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT_NE(taos, nullptr);
|
||||
|
||||
TAOS_RES* pRes = taos_query(taos, "create database if not exists param");
|
||||
taos_free_result(pRes);
|
||||
|
||||
const char *sql[] = {
|
||||
"test_ms,t0=t c0=f 1626006833641",
|
||||
};
|
||||
TAOS_RES* res = taos_schemaless_insert(taos, (char**)sql, 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS);
|
||||
ASSERT_EQ(taos_errno(res), TSDB_CODE_PAR_DB_NOT_SPECIFIED);
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(taos, "use param");
|
||||
taos_free_result(pRes);
|
||||
|
||||
res = taos_schemaless_insert(taos, (char**)sql, 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS);
|
||||
ASSERT_EQ(taos_errno(res), TSDB_CODE_SML_INVALID_DB_CONF);
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,8 @@ static const SSysDbTableSchema userDBSchema[] = {
|
|||
{.name = "precision", .bytes = 2 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "single_stable", .bytes = 1, .type = TSDB_DATA_TYPE_TINYINT},
|
||||
{.name = "status", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "schemaless", .bytes = 1, .type = TSDB_DATA_TYPE_TINYINT},
|
||||
|
||||
// {.name = "update", .bytes = 1, .type = TSDB_DATA_TYPE_TINYINT}, // disable update
|
||||
};
|
||||
|
||||
|
|
|
@ -355,14 +355,19 @@ int32_t blockDataUpdateTsWindow(SSDataBlock* pDataBlock, int32_t tsColumnIndex)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t index = (tsColumnIndex == -1) ? 0 : tsColumnIndex;
|
||||
int32_t index = (tsColumnIndex == -1) ? 0 : tsColumnIndex;
|
||||
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, index);
|
||||
if (pColInfoData->info.type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pDataBlock->info.window.skey = *(TSKEY*)colDataGetData(pColInfoData, 0);
|
||||
pDataBlock->info.window.ekey = *(TSKEY*)colDataGetData(pColInfoData, (pDataBlock->info.rows - 1));
|
||||
TSKEY skey = *(TSKEY*)colDataGetData(pColInfoData, 0);
|
||||
TSKEY ekey = *(TSKEY*)colDataGetData(pColInfoData, (pDataBlock->info.rows - 1));
|
||||
|
||||
pDataBlock->info.window.skey = TMIN(skey, ekey);
|
||||
pDataBlock->info.window.ekey = TMAX(skey, ekey);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1273,25 +1278,39 @@ static void doShiftBitmap(char* nullBitmap, size_t n, size_t total) {
|
|||
memmove(nullBitmap, nullBitmap + n / 8, newLen);
|
||||
} else {
|
||||
int32_t tail = n % 8;
|
||||
int32_t i = 0;
|
||||
|
||||
int32_t i = 0;
|
||||
uint8_t* p = (uint8_t*)nullBitmap;
|
||||
while (i < len) {
|
||||
uint8_t v = p[i];
|
||||
|
||||
p[i] = 0;
|
||||
p[i] = (v << tail);
|
||||
if (n < 8) {
|
||||
while (i < len) {
|
||||
uint8_t v = p[i]; // source bitmap value
|
||||
p[i] = (v << tail);
|
||||
|
||||
if (i < len - 1) {
|
||||
uint8_t next = p[i + 1];
|
||||
p[i] |= (next >> (8 - tail));
|
||||
if (i < len - 1) {
|
||||
uint8_t next = p[i + 1];
|
||||
p[i] |= (next >> (8 - tail));
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
} else if (n > 8) {
|
||||
int32_t gap = len - newLen;
|
||||
while(i < newLen) {
|
||||
uint8_t v = p[i + gap];
|
||||
p[i] = (v << tail);
|
||||
|
||||
i += 1;
|
||||
if (i < newLen - 1) {
|
||||
uint8_t next = p[i + gap + 1];
|
||||
p[i] |= (next >> (8 - tail));
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void colDataTrimFirstNRows(SColumnInfoData* pColInfoData, size_t n, size_t total) {
|
||||
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||
memmove(pColInfoData->varmeta.offset, &pColInfoData->varmeta.offset[n], (total - n) * sizeof(int32_t));
|
||||
|
@ -1803,3 +1822,99 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
|
|||
taosArrayDestroy(tagArray);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void blockCompressEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols, int8_t needCompress) {
|
||||
int32_t* actualLen = (int32_t*)data;
|
||||
data += sizeof(int32_t);
|
||||
|
||||
uint64_t* groupId = (uint64_t*)data;
|
||||
data += sizeof(uint64_t);
|
||||
|
||||
int32_t* colSizes = (int32_t*)data;
|
||||
data += numOfCols * sizeof(int32_t);
|
||||
|
||||
*dataLen = (numOfCols * sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t));
|
||||
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
for (int32_t col = 0; col < numOfCols; ++col) {
|
||||
SColumnInfoData* pColRes = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, col);
|
||||
|
||||
// copy the null bitmap
|
||||
if (IS_VAR_DATA_TYPE(pColRes->info.type)) {
|
||||
size_t metaSize = numOfRows * sizeof(int32_t);
|
||||
memcpy(data, pColRes->varmeta.offset, metaSize);
|
||||
data += metaSize;
|
||||
(*dataLen) += metaSize;
|
||||
} else {
|
||||
int32_t len = BitmapLen(numOfRows);
|
||||
memcpy(data, pColRes->nullbitmap, len);
|
||||
data += len;
|
||||
(*dataLen) += len;
|
||||
}
|
||||
|
||||
if (needCompress) {
|
||||
colSizes[col] = blockCompressColData(pColRes, numOfRows, data, needCompress);
|
||||
data += colSizes[col];
|
||||
(*dataLen) += colSizes[col];
|
||||
} else {
|
||||
colSizes[col] = colDataGetLength(pColRes, numOfRows);
|
||||
(*dataLen) += colSizes[col];
|
||||
memmove(data, pColRes->pData, colSizes[col]);
|
||||
data += colSizes[col];
|
||||
}
|
||||
|
||||
colSizes[col] = htonl(colSizes[col]);
|
||||
}
|
||||
|
||||
*actualLen = *dataLen;
|
||||
*groupId = pBlock->info.groupId;
|
||||
}
|
||||
|
||||
const char* blockCompressDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t numOfRows, const char* pData) {
|
||||
blockDataEnsureCapacity(pBlock, numOfRows);
|
||||
const char* pStart = pData;
|
||||
|
||||
int32_t dataLen = *(int32_t*)pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
|
||||
pBlock->info.groupId = *(uint64_t*)pStart;
|
||||
pStart += sizeof(uint64_t);
|
||||
|
||||
int32_t* colLen = (int32_t*)pStart;
|
||||
pStart += sizeof(int32_t) * numOfCols;
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
colLen[i] = htonl(colLen[i]);
|
||||
ASSERT(colLen[i] >= 0);
|
||||
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||
pColInfoData->varmeta.length = colLen[i];
|
||||
pColInfoData->varmeta.allocLen = colLen[i];
|
||||
|
||||
memcpy(pColInfoData->varmeta.offset, pStart, sizeof(int32_t) * numOfRows);
|
||||
pStart += sizeof(int32_t) * numOfRows;
|
||||
|
||||
if (colLen[i] > 0) {
|
||||
taosMemoryFreeClear(pColInfoData->pData);
|
||||
pColInfoData->pData = taosMemoryMalloc(colLen[i]);
|
||||
}
|
||||
} else {
|
||||
memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
|
||||
pStart += BitmapLen(numOfRows);
|
||||
}
|
||||
|
||||
if (colLen[i] > 0) {
|
||||
memcpy(pColInfoData->pData, pStart, colLen[i]);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// setting this flag to true temporarily so aggregate function on stable will
|
||||
// examine NULL value for non-primary key column
|
||||
pColInfoData->hasNull = true;
|
||||
pStart += colLen[i];
|
||||
}
|
||||
|
||||
ASSERT(pStart - pData == dataLen);
|
||||
return pStart;
|
||||
}
|
|
@ -109,8 +109,11 @@ int32_t tsCompressColData = -1;
|
|||
*/
|
||||
int32_t tsCompatibleModel = 1;
|
||||
|
||||
// count/hyperloglog function always return values in case of all NULL data or Empty data set.
|
||||
int32_t tsCountAlwaysReturnValue = 1;
|
||||
|
||||
// 10 ms for sliding time, the value will changed in case of time precision changed
|
||||
int32_t tsMinSlidingTime = 10;
|
||||
int32_t tsMinSlidingTime = 10;
|
||||
|
||||
// the maxinum number of distict query result
|
||||
int32_t tsMaxNumOfDistinctResults = 1000 * 10000;
|
||||
|
@ -130,7 +133,6 @@ int32_t tsRetryStreamCompDelay = 10 * 1000;
|
|||
// The delayed computing ration. 10% of the whole computing time window by default.
|
||||
float tsStreamComputDelayRatio = 0.1f;
|
||||
|
||||
int32_t tsProjectExecInterval = 10000; // every 10sec, the projection will be executed once
|
||||
int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance
|
||||
|
||||
// the maximum allowed query buffer size during query processing for each data node.
|
||||
|
@ -374,6 +376,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddInt32(pCfg, "minSlidingTime", tsMinSlidingTime, 10, 1000000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "minIntervalTime", tsMinIntervalTime, 1, 1000000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "maxNumOfDistinctRes", tsMaxNumOfDistinctResults, 10 * 10000, 10000 * 10000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "countAlwaysReturnValue", tsCountAlwaysReturnValue, 0, 1, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "maxStreamCompDelay", tsMaxStreamComputDelay, 10, 1000000000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "maxFirstStreamCompDelay", tsStreamCompStartDelay, 1000, 1000000000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "retryStreamCompDelay", tsRetryStreamCompDelay, 10, 1000000000, 0) != 0) return -1;
|
||||
|
@ -567,6 +570,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
|
|||
tsMinSlidingTime = cfgGetItem(pCfg, "minSlidingTime")->i32;
|
||||
tsMinIntervalTime = cfgGetItem(pCfg, "minIntervalTime")->i32;
|
||||
tsMaxNumOfDistinctResults = cfgGetItem(pCfg, "maxNumOfDistinctRes")->i32;
|
||||
tsCountAlwaysReturnValue = cfgGetItem(pCfg, "countAlwaysReturnValue")->i32;
|
||||
tsMaxStreamComputDelay = cfgGetItem(pCfg, "maxStreamCompDelay")->i32;
|
||||
tsStreamCompStartDelay = cfgGetItem(pCfg, "maxFirstStreamCompDelay")->i32;
|
||||
tsRetryStreamCompDelay = cfgGetItem(pCfg, "retryStreamCompDelay")->i32;
|
||||
|
|
|
@ -693,6 +693,7 @@ void tFreeSMAltertbReq(SMAlterStbReq *pReq) {
|
|||
pReq->pFields = NULL;
|
||||
}
|
||||
|
||||
|
||||
int32_t tSerializeSEpSet(void *buf, int32_t bufLen, const SEpSet *pEpset) {
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, buf, bufLen);
|
||||
|
@ -2277,6 +2278,7 @@ int32_t tSerializeSDbCfgRsp(void *buf, int32_t bufLen, const SDbCfgRsp *pRsp) {
|
|||
if (tEncodeI8(&encoder, pRetension->freqUnit) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRetension->keepUnit) < 0) return -1;
|
||||
}
|
||||
if (tEncodeI8(&encoder, pRsp->schemaless) < 0) return -1;
|
||||
tEndEncode(&encoder);
|
||||
|
||||
int32_t tlen = encoder.pos;
|
||||
|
@ -2325,6 +2327,7 @@ int32_t tDeserializeSDbCfgRsp(void *buf, int32_t bufLen, SDbCfgRsp *pRsp) {
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
if (tDecodeI8(&decoder, &pRsp->schemaless) < 0) return -1;
|
||||
tEndDecode(&decoder);
|
||||
|
||||
tDecoderClear(&decoder);
|
||||
|
@ -4347,13 +4350,96 @@ int32_t tDecodeSVAlterTbReq(SDecoder *pDecoder, SVAlterTbReq *pReq) {
|
|||
int32_t tEncodeSVAlterTbRsp(SEncoder *pEncoder, const SVAlterTbRsp *pRsp) {
|
||||
if (tStartEncode(pEncoder) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->code) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->pMeta ? 1 : 0) < 0) return -1;
|
||||
if (pRsp->pMeta) {
|
||||
if (tEncodeSTableMetaRsp(pEncoder, pRsp->pMeta) < 0) return -1;
|
||||
}
|
||||
tEndEncode(pEncoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSVAlterTbRsp(SDecoder *pDecoder, SVAlterTbRsp *pRsp) {
|
||||
int32_t meta = 0;
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->code) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &meta) < 0) return -1;
|
||||
if (meta) {
|
||||
pRsp->pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
|
||||
if (NULL == pRsp->pMeta) return -1;
|
||||
if (tDecodeSTableMetaRsp(pDecoder, pRsp->pMeta) < 0) return -1;
|
||||
}
|
||||
tEndDecode(pDecoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDeserializeSVAlterTbRsp(void *buf, int32_t bufLen, SVAlterTbRsp *pRsp) {
|
||||
int32_t meta = 0;
|
||||
SDecoder decoder = {0};
|
||||
tDecoderInit(&decoder, buf, bufLen);
|
||||
|
||||
if (tStartDecode(&decoder) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pRsp->code) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &meta) < 0) return -1;
|
||||
if (meta) {
|
||||
pRsp->pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
|
||||
if (NULL == pRsp->pMeta) return -1;
|
||||
if (tDecodeSTableMetaRsp(&decoder, pRsp->pMeta) < 0) return -1;
|
||||
}
|
||||
tEndDecode(&decoder);
|
||||
tDecoderClear(&decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSMAlterStbRsp(SEncoder *pEncoder, const SMAlterStbRsp *pRsp) {
|
||||
if (tStartEncode(pEncoder) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->pMeta->pSchemas ? 1 : 0) < 0) return -1;
|
||||
if (pRsp->pMeta->pSchemas) {
|
||||
if (tEncodeSTableMetaRsp(pEncoder, pRsp->pMeta) < 0) return -1;
|
||||
}
|
||||
tEndEncode(pEncoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSMAlterStbRsp(SDecoder *pDecoder, SMAlterStbRsp *pRsp) {
|
||||
int32_t meta = 0;
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &meta) < 0) return -1;
|
||||
if (meta) {
|
||||
pRsp->pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
|
||||
if (NULL == pRsp->pMeta) return -1;
|
||||
if (tDecodeSTableMetaRsp(pDecoder, pRsp->pMeta) < 0) return -1;
|
||||
}
|
||||
tEndDecode(pDecoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDeserializeSMAlterStbRsp(void *buf, int32_t bufLen, SMAlterStbRsp *pRsp) {
|
||||
int32_t meta = 0;
|
||||
SDecoder decoder = {0};
|
||||
tDecoderInit(&decoder, buf, bufLen);
|
||||
|
||||
if (tStartDecode(&decoder) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &meta) < 0) return -1;
|
||||
if (meta) {
|
||||
pRsp->pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
|
||||
if (NULL == pRsp->pMeta) return -1;
|
||||
if (tDecodeSTableMetaRsp(&decoder, pRsp->pMeta) < 0) return -1;
|
||||
}
|
||||
tEndDecode(&decoder);
|
||||
tDecoderClear(&decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tFreeSMAlterStbRsp(SMAlterStbRsp* pRsp) {
|
||||
if (NULL == pRsp) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pRsp->pMeta) {
|
||||
taosMemoryFree(pRsp->pMeta->pSchemas);
|
||||
taosMemoryFree(pRsp->pMeta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -180,6 +180,24 @@ static void vmGenerateWrapperCfg(SVnodeMgmt *pMgmt, SCreateVnodeReq *pCreate, SW
|
|||
snprintf(pCfg->path, sizeof(pCfg->path), "%s%svnode%d", pMgmt->path, TD_DIRSEP, pCreate->vgId);
|
||||
}
|
||||
|
||||
static int32_t vmTsmaAdjustDays(SVnodeCfg *pCfg, SCreateVnodeReq *pReq) {
|
||||
if (pReq->isTsma) {
|
||||
SMsgHead *smaMsg = pReq->pTsma;
|
||||
uint32_t contLen = (uint32_t)(htonl(smaMsg->contLen) - sizeof(SMsgHead));
|
||||
return smaGetTSmaDays(pCfg, POINTER_SHIFT(smaMsg, sizeof(SMsgHead)), contLen, &pCfg->tsdbCfg.days);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t vmTsmaProcessCreate(SVnode *pVnode, SCreateVnodeReq *pReq) {
|
||||
if (pReq->isTsma) {
|
||||
SMsgHead *smaMsg = pReq->pTsma;
|
||||
uint32_t contLen = (uint32_t)(htonl(smaMsg->contLen) - sizeof(SMsgHead));
|
||||
return vnodeProcessCreateTSma(pVnode, POINTER_SHIFT(smaMsg, sizeof(SMsgHead)), contLen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||
SCreateVnodeReq createReq = {0};
|
||||
SVnodeCfg vnodeCfg = {0};
|
||||
|
@ -195,6 +213,13 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
dDebug("vgId:%d, create vnode req is received, tsma:%d standby:%d", createReq.vgId, createReq.isTsma,
|
||||
createReq.standby);
|
||||
vmGenerateVnodeCfg(&createReq, &vnodeCfg);
|
||||
|
||||
if (vmTsmaAdjustDays(&vnodeCfg, &createReq) < 0) {
|
||||
dError("vgId:%d, failed to adjust tsma days since %s", createReq.vgId, terrstr());
|
||||
code = terrno;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
vmGenerateWrapperCfg(pMgmt, &createReq, &wrapperCfg);
|
||||
|
||||
SVnodeObj *pVnode = vmAcquireVnode(pMgmt, createReq.vgId);
|
||||
|
@ -203,14 +228,16 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
tFreeSCreateVnodeReq(&createReq);
|
||||
vmReleaseVnode(pMgmt, pVnode);
|
||||
terrno = TSDB_CODE_NODE_ALREADY_DEPLOYED;
|
||||
return -1;
|
||||
code = terrno;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vnodeCfg.vgId);
|
||||
if (vnodeCreate(path, &vnodeCfg, pMgmt->pTfs) < 0) {
|
||||
tFreeSCreateVnodeReq(&createReq);
|
||||
dError("vgId:%d, failed to create vnode since %s", createReq.vgId, terrstr());
|
||||
return -1;
|
||||
code = terrno;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
SVnode *pImpl = vnodeOpen(path, pMgmt->pTfs, pMgmt->msgCb);
|
||||
|
@ -227,14 +254,11 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (createReq.isTsma) {
|
||||
SMsgHead *smaMsg = createReq.pTsma;
|
||||
uint32_t contLen = (uint32_t)(htonl(smaMsg->contLen) - sizeof(SMsgHead));
|
||||
if (vnodeProcessCreateTSma(pImpl, POINTER_SHIFT(smaMsg, sizeof(SMsgHead)), contLen) < 0) {
|
||||
dError("vgId:%d, failed to create tsma since %s", createReq.vgId, terrstr());
|
||||
code = terrno;
|
||||
goto _OVER;
|
||||
};
|
||||
code = vmTsmaProcessCreate(pImpl, &createReq);
|
||||
if (code != 0) {
|
||||
dError("vgId:%d, failed to create tsma since %s", createReq.vgId, terrstr());
|
||||
code = terrno;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = vnodeStart(pImpl);
|
||||
|
|
|
@ -255,6 +255,7 @@ typedef struct {
|
|||
int8_t hashMethod; // default is 1
|
||||
int32_t numOfRetensions;
|
||||
SArray* pRetensions;
|
||||
int8_t schemaless;
|
||||
} SDbCfg;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -115,6 +115,7 @@ static SSdbRaw *mndDbActionEncode(SDbObj *pDb) {
|
|||
SDB_SET_INT8(pRaw, dataPos, pRetension->freqUnit, _OVER)
|
||||
SDB_SET_INT8(pRaw, dataPos, pRetension->keepUnit, _OVER)
|
||||
}
|
||||
SDB_SET_INT8(pRaw, dataPos, pDb->cfg.schemaless, _OVER)
|
||||
|
||||
SDB_SET_RESERVE(pRaw, dataPos, DB_RESERVE_SIZE, _OVER)
|
||||
SDB_SET_DATALEN(pRaw, dataPos, _OVER)
|
||||
|
@ -192,6 +193,7 @@ static SSdbRow *mndDbActionDecode(SSdbRaw *pRaw) {
|
|||
}
|
||||
}
|
||||
}
|
||||
SDB_GET_INT8(pRaw, dataPos, &pDb->cfg.schemaless, _OVER)
|
||||
|
||||
SDB_GET_RESERVE(pRaw, dataPos, DB_RESERVE_SIZE, _OVER)
|
||||
taosInitRWLatch(&pDb->lock);
|
||||
|
@ -380,6 +382,7 @@ static int32_t mndCheckDbCfg(SMnode *pMnode, SDbCfg *pCfg) {
|
|||
if (pCfg->replications < TSDB_MIN_DB_REPLICA || pCfg->replications > TSDB_MAX_DB_REPLICA) return -1;
|
||||
if (pCfg->replications != 1 && pCfg->replications != 3) return -1;
|
||||
if (pCfg->strict < TSDB_DB_STRICT_OFF || pCfg->strict > TSDB_DB_STRICT_ON) return -1;
|
||||
if (pCfg->schemaless < TSDB_DB_SCHEMALESS_OFF || pCfg->schemaless > TSDB_DB_SCHEMALESS_ON) return -1;
|
||||
if (pCfg->cacheLastRow < TSDB_MIN_DB_CACHE_LAST_ROW || pCfg->cacheLastRow > TSDB_MAX_DB_CACHE_LAST_ROW) return -1;
|
||||
if (pCfg->hashMethod != 1) return -1;
|
||||
if (pCfg->replications > mndGetDnodeSize(pMnode)) {
|
||||
|
@ -411,6 +414,8 @@ static void mndSetDefaultDbCfg(SDbCfg *pCfg) {
|
|||
if (pCfg->strict < 0) pCfg->strict = TSDB_DEFAULT_DB_STRICT;
|
||||
if (pCfg->cacheLastRow < 0) pCfg->cacheLastRow = TSDB_DEFAULT_CACHE_LAST_ROW;
|
||||
if (pCfg->numOfRetensions < 0) pCfg->numOfRetensions = 0;
|
||||
if (pCfg->schemaless < 0) pCfg->schemaless = TSDB_DB_SCHEMALESS_OFF;
|
||||
|
||||
}
|
||||
|
||||
static int32_t mndSetCreateDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroups) {
|
||||
|
@ -521,6 +526,7 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate,
|
|||
.strict = pCreate->strict,
|
||||
.cacheLastRow = pCreate->cacheLastRow,
|
||||
.hashMethod = 1,
|
||||
.schemaless = pCreate->schemaless,
|
||||
};
|
||||
|
||||
dbObj.cfg.numOfRetensions = pCreate->numOfRetensions;
|
||||
|
@ -899,6 +905,7 @@ static int32_t mndProcessGetDbCfgReq(SRpcMsg *pReq) {
|
|||
cfgRsp.cacheLastRow = pDb->cfg.cacheLastRow;
|
||||
cfgRsp.numOfRetensions = pDb->cfg.numOfRetensions;
|
||||
cfgRsp.pRetensions = pDb->cfg.pRetensions;
|
||||
cfgRsp.schemaless = pDb->cfg.schemaless;
|
||||
|
||||
int32_t contLen = tSerializeSDbCfgRsp(NULL, 0, &cfgRsp);
|
||||
void *pRsp = rpcMallocCont(contLen);
|
||||
|
@ -1542,8 +1549,11 @@ static void dumpDbInfoData(SSDataBlock *pBlock, SDbObj *pDb, SShowObj *pShow, in
|
|||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, rows, (const char *)&pDb->cfg.numOfStables, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, rows, (const char *)statusB, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
|
||||
colDataAppend(pColInfo, rows, (const char *)&pDb->cfg.schemaless, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1207,13 +1207,125 @@ static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
|
||||
taosRLockLatch(&pStb->lock);
|
||||
|
||||
int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
|
||||
pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema));
|
||||
if (pRsp->pSchemas == NULL) {
|
||||
taosRUnLockLatch(&pStb->lock);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(pRsp->dbFName, pStb->db);
|
||||
strcpy(pRsp->tbName, tbName);
|
||||
strcpy(pRsp->stbName, tbName);
|
||||
pRsp->dbId = pDb->uid;
|
||||
pRsp->numOfTags = pStb->numOfTags;
|
||||
pRsp->numOfColumns = pStb->numOfColumns;
|
||||
pRsp->precision = pDb->cfg.precision;
|
||||
pRsp->tableType = TSDB_SUPER_TABLE;
|
||||
pRsp->sversion = pStb->colVer;
|
||||
pRsp->tversion = pStb->tagVer;
|
||||
pRsp->suid = pStb->uid;
|
||||
pRsp->tuid = pStb->uid;
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
|
||||
SSchema *pSchema = &pRsp->pSchemas[i];
|
||||
SSchema *pSrcSchema = &pStb->pColumns[i];
|
||||
memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
|
||||
pSchema->type = pSrcSchema->type;
|
||||
pSchema->colId = pSrcSchema->colId;
|
||||
pSchema->bytes = pSrcSchema->bytes;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfTags; ++i) {
|
||||
SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
|
||||
SSchema *pSrcSchema = &pStb->pTags[i];
|
||||
memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
|
||||
pSchema->type = pSrcSchema->type;
|
||||
pSchema->colId = pSrcSchema->colId;
|
||||
pSchema->bytes = pSrcSchema->bytes;
|
||||
}
|
||||
|
||||
taosRUnLockLatch(&pStb->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp) {
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);
|
||||
|
||||
SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
|
||||
if (pStb == NULL) {
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
terrno = TSDB_CODE_MND_INVALID_STB;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, const SMAlterStbReq *pAlter, SStbObj *pObj, void **pCont, int32_t *pLen) {
|
||||
int ret;
|
||||
SEncoder ec = {0};
|
||||
uint32_t contLen = 0;
|
||||
SMAlterStbRsp alterRsp = {0};
|
||||
SName name = {0};
|
||||
tNameFromString(&name, pAlter->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
||||
alterRsp.pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
|
||||
if (NULL == alterRsp.pMeta) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mndBuildStbSchemaImp(pDb, pObj, name.tname, alterRsp.pMeta);
|
||||
if (ret) {
|
||||
tFreeSMAlterStbRsp(&alterRsp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tEncodeSize(tEncodeSMAlterStbRsp, &alterRsp, contLen, ret);
|
||||
if (ret) {
|
||||
tFreeSMAlterStbRsp(&alterRsp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* cont = taosMemoryMalloc(contLen);
|
||||
tEncoderInit(&ec, cont, contLen);
|
||||
tEncodeSMAlterStbRsp(&ec, &alterRsp);
|
||||
tEncoderClear(&ec);
|
||||
|
||||
tFreeSMAlterStbRsp(&alterRsp);
|
||||
|
||||
*pCont = cont;
|
||||
*pLen = contLen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
|
||||
bool needRsp = true;
|
||||
SStbObj stbObj = {0};
|
||||
taosRLockLatch(&pOld->lock);
|
||||
memcpy(&stbObj, pOld, sizeof(SStbObj));
|
||||
stbObj.pColumns = NULL;
|
||||
stbObj.pTags = NULL;
|
||||
stbObj.updateTime = taosGetTimestampMs();
|
||||
stbObj.lock = 0;
|
||||
taosRUnLockLatch(&pOld->lock);
|
||||
|
||||
int32_t code = -1;
|
||||
|
@ -1247,9 +1359,11 @@ static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *p
|
|||
code = mndAlterStbColumnBytes(pOld, &stbObj, pField0);
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
|
||||
needRsp = false;
|
||||
code = mndUpdateStbCommentAndTTL(pOld, &stbObj, pAlter->comment, pAlter->commentLen, pAlter->ttl);
|
||||
break;
|
||||
default:
|
||||
needRsp = false;
|
||||
terrno = TSDB_CODE_OPS_NOT_SUPPORT;
|
||||
break;
|
||||
}
|
||||
|
@ -1263,6 +1377,13 @@ static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *p
|
|||
mDebug("trans:%d, used to alter stb:%s", pTrans->id, pAlter->name);
|
||||
mndTransSetDbName(pTrans, pDb->name);
|
||||
|
||||
if (needRsp) {
|
||||
void* pCont = NULL;
|
||||
int32_t contLen = 0;
|
||||
if (mndBuildSMAlterStbRsp(pDb, pAlter, &stbObj, &pCont, &contLen)) goto _OVER;
|
||||
mndTransSetRpcRsp(pTrans, pCont, contLen);
|
||||
}
|
||||
|
||||
if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
|
||||
if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
|
||||
if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
|
||||
|
@ -1483,75 +1604,6 @@ static int32_t mndProcessVDropStbRsp(SRpcMsg *pRsp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
|
||||
taosRLockLatch(&pStb->lock);
|
||||
|
||||
int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
|
||||
pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema));
|
||||
if (pRsp->pSchemas == NULL) {
|
||||
taosRUnLockLatch(&pStb->lock);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(pRsp->dbFName, pStb->db);
|
||||
strcpy(pRsp->tbName, tbName);
|
||||
strcpy(pRsp->stbName, tbName);
|
||||
pRsp->dbId = pDb->uid;
|
||||
pRsp->numOfTags = pStb->numOfTags;
|
||||
pRsp->numOfColumns = pStb->numOfColumns;
|
||||
pRsp->precision = pDb->cfg.precision;
|
||||
pRsp->tableType = TSDB_SUPER_TABLE;
|
||||
pRsp->sversion = pStb->colVer;
|
||||
pRsp->tversion = pStb->tagVer;
|
||||
pRsp->suid = pStb->uid;
|
||||
pRsp->tuid = pStb->uid;
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
|
||||
SSchema *pSchema = &pRsp->pSchemas[i];
|
||||
SSchema *pSrcSchema = &pStb->pColumns[i];
|
||||
memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
|
||||
pSchema->type = pSrcSchema->type;
|
||||
pSchema->colId = pSrcSchema->colId;
|
||||
pSchema->bytes = pSrcSchema->bytes;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfTags; ++i) {
|
||||
SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
|
||||
SSchema *pSrcSchema = &pStb->pTags[i];
|
||||
memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
|
||||
pSchema->type = pSrcSchema->type;
|
||||
pSchema->colId = pSrcSchema->colId;
|
||||
pSchema->bytes = pSrcSchema->bytes;
|
||||
}
|
||||
|
||||
taosRUnLockLatch(&pStb->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp) {
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);
|
||||
|
||||
SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
|
||||
if (pStb == NULL) {
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
terrno = TSDB_CODE_MND_INVALID_STB;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
int32_t code = -1;
|
||||
|
|
|
@ -32,7 +32,7 @@ target_sources(
|
|||
"src/sma/smaEnv.c"
|
||||
"src/sma/smaOpen.c"
|
||||
"src/sma/smaRollup.c"
|
||||
"src/sma/smaTimeRange.c"
|
||||
"src/sma/smaTimeRange2.c"
|
||||
|
||||
# tsdb
|
||||
"src/tsdb/tsdbCommit.c"
|
||||
|
|
|
@ -147,6 +147,9 @@ bool tqNextDataBlockFilterOut(STqReadHandle *pHandle, SHashObj *filterOutUids
|
|||
int32_t tqRetrieveDataBlock(SArray **ppCols, STqReadHandle *pHandle, uint64_t *pGroupId, uint64_t *pUid,
|
||||
int32_t *pNumOfRows, int16_t *pNumOfCols);
|
||||
|
||||
// sma
|
||||
int32_t smaGetTSmaDays(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days);
|
||||
|
||||
// need to reposition
|
||||
|
||||
// structs
|
||||
|
|
|
@ -223,6 +223,8 @@ int32_t tdUpdateExpiredWindowImpl(SSma *pSma, const SSubmitReq *pMsg, int64_t ve
|
|||
// TODO: This is the basic params, and should wrap the params to a queryHandle.
|
||||
int32_t tdGetTSmaDataImpl(SSma *pSma, char *pData, int64_t indexUid, TSKEY querySKey, int32_t nMaxResult);
|
||||
|
||||
int32_t tdGetTSmaDaysImpl(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -87,7 +87,7 @@ int metaAlterSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* p
|
|||
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq);
|
||||
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq);
|
||||
int metaDropTable(SMeta* pMeta, int64_t version, SVDropTbReq* pReq, SArray* tbUids);
|
||||
int metaAlterTable(SMeta* pMeta, int64_t version, SVAlterTbReq* pReq);
|
||||
int metaAlterTable(SMeta* pMeta, int64_t version, SVAlterTbReq* pReq, STableMetaRsp *pMetaRsp);
|
||||
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, bool isinline);
|
||||
STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver);
|
||||
int metaGetTableEntryByName(SMetaReader* pReader, const char* name);
|
||||
|
|
|
@ -464,7 +464,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid, bool deepCopy) {
|
|||
_err:
|
||||
metaReaderClear(&mr);
|
||||
taosArrayDestroy(pSmaIds);
|
||||
tdFreeTSmaWrapper(pSW, deepCopy);
|
||||
tFreeTSmaWrapper(pSW, deepCopy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,24 @@ static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME);
|
|||
static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry);
|
||||
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type);
|
||||
|
||||
static int metaUpdateMetaRsp(tb_uid_t uid, char* tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
|
||||
pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
|
||||
if (NULL == pMetaRsp->pSchemas) {
|
||||
terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(pMetaRsp->tbName, tbName);
|
||||
pMetaRsp->numOfColumns = pSchema->nCols;
|
||||
pMetaRsp->tableType = TSDB_NORMAL_TABLE;
|
||||
pMetaRsp->sversion = pSchema->version;
|
||||
pMetaRsp->tuid = uid;
|
||||
|
||||
memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
||||
SMetaEntry me = {0};
|
||||
int kLen = 0;
|
||||
|
@ -323,8 +341,8 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
|
||||
void *pVal = NULL;
|
||||
static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq, STableMetaRsp *pMetaRsp) {
|
||||
void * pVal = NULL;
|
||||
int nVal = 0;
|
||||
const void *pData = NULL;
|
||||
int nData = 0;
|
||||
|
@ -463,6 +481,8 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
|
|||
|
||||
metaULock(pMeta);
|
||||
|
||||
metaUpdateMetaRsp(uid, pAlterTbReq->tbName, pSchema, pMetaRsp);
|
||||
|
||||
if (pNewSchema) taosMemoryFree(pNewSchema);
|
||||
tDecoderClear(&dc);
|
||||
tdbTbcClose(pTbDbc);
|
||||
|
@ -584,7 +604,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
|
|||
}
|
||||
taosArrayPush(pTagArray, &val);
|
||||
} else {
|
||||
STagVal val = {0};
|
||||
STagVal val = {.cid = pCol->colId};
|
||||
if (tTagGet(pOldTag, &val)) {
|
||||
taosArrayPush(pTagArray, &val);
|
||||
}
|
||||
|
@ -629,13 +649,13 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p
|
|||
return 0;
|
||||
}
|
||||
|
||||
int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
|
||||
int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pMetaRsp) {
|
||||
switch (pReq->action) {
|
||||
case TSDB_ALTER_TABLE_ADD_COLUMN:
|
||||
case TSDB_ALTER_TABLE_DROP_COLUMN:
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
|
||||
return metaAlterTableColumn(pMeta, version, pReq);
|
||||
return metaAlterTableColumn(pMeta, version, pReq, pMetaRsp);
|
||||
case TSDB_ALTER_TABLE_UPDATE_TAG_VAL:
|
||||
return metaUpdateTableTagVal(pMeta, version, pReq);
|
||||
case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
|
||||
|
|
|
@ -51,3 +51,11 @@ int32_t tdGetTSmaData(SSma* pSma, char* pData, int64_t indexUid, TSKEY querySKey
|
|||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t smaGetTSmaDays(SVnodeCfg* pCfg, void* pCont, uint32_t contLen, int32_t *days) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if ((code = tdGetTSmaDaysImpl(pCfg, pCont, contLen, days)) < 0) {
|
||||
smaWarn("vgId:%d get tSma days failed since %s", pCfg->vgId, tstrerror(terrno));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ static int32_t tdInitSmaStat(SSmaStat **pSmaStat, int8_t smaType) {
|
|||
|
||||
void *tdFreeSmaStatItem(SSmaStatItem *pSmaStatItem) {
|
||||
if (pSmaStatItem) {
|
||||
tdDestroyTSma(pSmaStatItem->pTSma);
|
||||
tDestroyTSma(pSmaStatItem->pTSma);
|
||||
taosMemoryFreeClear(pSmaStatItem->pTSma);
|
||||
taosHashCleanup(pSmaStatItem->expiredWindows);
|
||||
taosMemoryFreeClear(pSmaStatItem);
|
||||
|
|
|
@ -828,7 +828,7 @@ int32_t tdDropTSma(SSma *pSma, char *pMsg) {
|
|||
|
||||
// TODO: send msg to stream computing to drop tSma
|
||||
// if ((send msg to stream computing) < 0) {
|
||||
// tdDestroyTSma(&vCreateSmaReq);
|
||||
// tDestroyTSma(&vCreateSmaReq);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
|
@ -982,25 +982,25 @@ int32_t tdUpdateExpiredWindowImpl(SSma *pSma, const SSubmitReq *pMsg, int64_t ve
|
|||
|
||||
SSubmitBlkIter blkIter = {0};
|
||||
if (tInitSubmitBlkIter(&msgIter, pBlock, &blkIter) < 0) {
|
||||
pSW = tdFreeTSmaWrapper(pSW, false);
|
||||
pSW = tFreeTSmaWrapper(pSW, false);
|
||||
break;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
STSRow *row = tGetSubmitBlkNext(&blkIter);
|
||||
if (!row) {
|
||||
pSW = tdFreeTSmaWrapper(pSW, false);
|
||||
pSW = tFreeTSmaWrapper(pSW, false);
|
||||
break;
|
||||
}
|
||||
if (!pSW || (pTSma && (pTSma->tableUid != msgIter.suid))) {
|
||||
if (pSW) {
|
||||
pSW = tdFreeTSmaWrapper(pSW, false);
|
||||
pSW = tFreeTSmaWrapper(pSW, false);
|
||||
}
|
||||
if (!(pSW = metaGetSmaInfoByTable(SMA_META(pSma), msgIter.suid, false))) {
|
||||
break;
|
||||
}
|
||||
if ((pSW->number) <= 0 || !pSW->tSma) {
|
||||
pSW = tdFreeTSmaWrapper(pSW, false);
|
||||
pSW = tFreeTSmaWrapper(pSW, false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1020,7 +1020,7 @@ int32_t tdUpdateExpiredWindowImpl(SSma *pSma, const SSubmitReq *pMsg, int64_t ve
|
|||
if (lastWinSKey != winSKey) {
|
||||
lastWinSKey = winSKey;
|
||||
if (tdSetExpiredWindow(pSma, pItemsHash, pTSma->indexUid, winSKey, version) < 0) {
|
||||
pSW = tdFreeTSmaWrapper(pSW, false);
|
||||
pSW = tFreeTSmaWrapper(pSW, false);
|
||||
tdUnRefSmaStat(pSma, pStat);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -251,6 +251,13 @@ void smaHandleRes(void *pVnode, int64_t smaId, const SArray *data) {
|
|||
tdProcessTSmaInsert(((SVnode *)pVnode)->pSma, smaId, (const char *)data);
|
||||
}
|
||||
|
||||
void vnodeUpdateMetaRsp(SVnode *pVnode, STableMetaRsp *pMetaRsp) {
|
||||
strcpy(pMetaRsp->dbFName, pVnode->config.dbname);
|
||||
pMetaRsp->dbId = pVnode->config.dbId;
|
||||
pMetaRsp->vgId = TD_VID(pVnode);
|
||||
pMetaRsp->precision = pVnode->config.tsdbCfg.precision;
|
||||
}
|
||||
|
||||
int vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
||||
int32_t ret = TAOS_SYNC_PROPOSE_OTHER_ERROR;
|
||||
|
||||
|
@ -520,12 +527,13 @@ _exit:
|
|||
}
|
||||
|
||||
static int vnodeProcessAlterTbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
SVAlterTbReq vAlterTbReq = {0};
|
||||
SVAlterTbRsp vAlterTbRsp = {0};
|
||||
SDecoder dc = {0};
|
||||
int rcode = 0;
|
||||
int ret;
|
||||
SEncoder ec = {0};
|
||||
SVAlterTbReq vAlterTbReq = {0};
|
||||
SVAlterTbRsp vAlterTbRsp = {0};
|
||||
SDecoder dc = {0};
|
||||
int rcode = 0;
|
||||
int ret;
|
||||
SEncoder ec = {0};
|
||||
STableMetaRsp vMetaRsp = {0};
|
||||
|
||||
pRsp->msgType = TDMT_VND_ALTER_TABLE_RSP;
|
||||
pRsp->pCont = NULL;
|
||||
|
@ -543,7 +551,7 @@ static int vnodeProcessAlterTbReq(SVnode *pVnode, int64_t version, void *pReq, i
|
|||
}
|
||||
|
||||
// process
|
||||
if (metaAlterTable(pVnode->pMeta, version, &vAlterTbReq) < 0) {
|
||||
if (metaAlterTable(pVnode->pMeta, version, &vAlterTbReq, &vMetaRsp) < 0) {
|
||||
vAlterTbRsp.code = TSDB_CODE_INVALID_MSG;
|
||||
tDecoderClear(&dc);
|
||||
rcode = -1;
|
||||
|
@ -551,6 +559,11 @@ static int vnodeProcessAlterTbReq(SVnode *pVnode, int64_t version, void *pReq, i
|
|||
}
|
||||
tDecoderClear(&dc);
|
||||
|
||||
if (NULL != vMetaRsp.pSchemas) {
|
||||
vnodeUpdateMetaRsp(pVnode, &vMetaRsp);
|
||||
vAlterTbRsp.pMeta = &vMetaRsp;
|
||||
}
|
||||
|
||||
_exit:
|
||||
tEncodeSize(tEncodeSVAlterTbRsp, &vAlterTbRsp, pRsp->contLen, ret);
|
||||
pRsp->pCont = rpcMallocCont(pRsp->contLen);
|
||||
|
|
|
@ -147,8 +147,8 @@ TEST(testCase, tSma_Meta_Encode_Decode_Test) {
|
|||
|
||||
// resource release
|
||||
taosMemoryFreeClear(pSW);
|
||||
tdDestroyTSma(&tSma);
|
||||
tdDestroyTSmaWrapper(&dstTSmaWrapper);
|
||||
tDestroyTSma(&tSma);
|
||||
tDestroyTSmaWrapper(&dstTSmaWrapper);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -218,7 +218,7 @@ TEST(testCase, tSma_metaDB_Put_Get_Del_Test) {
|
|||
printf("tagsFilter1 = %s\n", qSmaCfg->tagsFilter != NULL ? qSmaCfg->tagsFilter : "");
|
||||
EXPECT_STRCASEEQ(qSmaCfg->indexName, smaIndexName1);
|
||||
EXPECT_EQ(qSmaCfg->tableUid, tSma.tableUid);
|
||||
tdDestroyTSma(qSmaCfg);
|
||||
tDestroyTSma(qSmaCfg);
|
||||
taosMemoryFreeClear(qSmaCfg);
|
||||
|
||||
qSmaCfg = metaGetSmaInfoByIndex(pMeta, indexUid2, true);
|
||||
|
@ -229,7 +229,7 @@ TEST(testCase, tSma_metaDB_Put_Get_Del_Test) {
|
|||
printf("tagsFilter2 = %s\n", qSmaCfg->tagsFilter != NULL ? qSmaCfg->tagsFilter : "");
|
||||
EXPECT_STRCASEEQ(qSmaCfg->indexName, smaIndexName2);
|
||||
EXPECT_EQ(qSmaCfg->interval, tSma.interval);
|
||||
tdDestroyTSma(qSmaCfg);
|
||||
tDestroyTSma(qSmaCfg);
|
||||
taosMemoryFreeClear(qSmaCfg);
|
||||
|
||||
// get index name by table uid
|
||||
|
@ -265,7 +265,7 @@ TEST(testCase, tSma_metaDB_Put_Get_Del_Test) {
|
|||
EXPECT_EQ((pSW->tSma + 1)->indexUid, indexUid2);
|
||||
EXPECT_EQ((pSW->tSma + 1)->tableUid, tbUid);
|
||||
|
||||
tdDestroyTSmaWrapper(pSW);
|
||||
tDestroyTSmaWrapper(pSW);
|
||||
taosMemoryFreeClear(pSW);
|
||||
|
||||
// get all sma table uids
|
||||
|
@ -282,7 +282,7 @@ TEST(testCase, tSma_metaDB_Put_Get_Del_Test) {
|
|||
metaRemoveSmaFromDb(pMeta, indexUid1);
|
||||
metaRemoveSmaFromDb(pMeta, indexUid2);
|
||||
|
||||
tdDestroyTSma(&tSma);
|
||||
tDestroyTSma(&tSma);
|
||||
metaClose(pMeta);
|
||||
}
|
||||
#endif
|
||||
|
@ -576,7 +576,7 @@ TEST(testCase, tSma_Data_Insert_Query_Test) {
|
|||
taosArrayDestroy(pDataBlocks);
|
||||
|
||||
// release meta
|
||||
tdDestroyTSma(&tSma);
|
||||
tDestroyTSma(&tSma);
|
||||
tfsClose(pTsdb->pTfs);
|
||||
tsdbClose(pTsdb);
|
||||
metaClose(pMeta);
|
||||
|
|
|
@ -302,7 +302,7 @@ typedef struct SCtgUpdateEpsetMsg {
|
|||
typedef struct SCtgCacheOperation {
|
||||
int32_t opId;
|
||||
void *data;
|
||||
bool syncReq;
|
||||
bool syncOp;
|
||||
uint64_t seqId;
|
||||
} SCtgCacheOperation;
|
||||
|
||||
|
|
|
@ -314,6 +314,36 @@ _return:
|
|||
CTG_RET(code);
|
||||
}
|
||||
|
||||
int32_t ctgUpdateTbMeta(SCatalog* pCtg, STableMetaRsp *rspMsg, bool syncOp) {
|
||||
STableMetaOutput *output = taosMemoryCalloc(1, sizeof(STableMetaOutput));
|
||||
if (NULL == output) {
|
||||
ctgError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
|
||||
CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
|
||||
strcpy(output->dbFName, rspMsg->dbFName);
|
||||
strcpy(output->tbName, rspMsg->tbName);
|
||||
|
||||
output->dbId = rspMsg->dbId;
|
||||
|
||||
SET_META_TYPE_TABLE(output->metaType);
|
||||
|
||||
CTG_ERR_JRET(queryCreateTableMetaFromMsg(rspMsg, rspMsg->tableType == TSDB_SUPER_TABLE, &output->tbMeta));
|
||||
|
||||
CTG_ERR_JRET(ctgUpdateTbMetaEnqueue(pCtg, output, syncOp));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
taosMemoryFreeClear(output->tbMeta);
|
||||
taosMemoryFreeClear(output);
|
||||
|
||||
CTG_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t ctgChkAuth(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps, const char* user, const char* dbFName, AUTH_TYPE type, bool *pass) {
|
||||
bool inCache = false;
|
||||
|
@ -779,38 +809,17 @@ int32_t catalogGetSTableMeta(SCatalog* pCtg, void * pTrans, const SEpSet* pMgmtE
|
|||
CTG_API_LEAVE(ctgGetTbMeta(CTG_PARAMS_LIST(), &ctx, pTableMeta));
|
||||
}
|
||||
|
||||
int32_t catalogUpdateSTableMeta(SCatalog* pCtg, STableMetaRsp *rspMsg) {
|
||||
int32_t catalogUpdateTableMeta(SCatalog* pCtg, STableMetaRsp *pMsg) {
|
||||
CTG_API_ENTER();
|
||||
|
||||
if (NULL == pCtg || NULL == rspMsg) {
|
||||
if (NULL == pCtg || NULL == pMsg) {
|
||||
CTG_API_LEAVE(TSDB_CODE_CTG_INVALID_INPUT);
|
||||
}
|
||||
|
||||
STableMetaOutput *output = taosMemoryCalloc(1, sizeof(STableMetaOutput));
|
||||
if (NULL == output) {
|
||||
ctgError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
|
||||
CTG_API_LEAVE(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
|
||||
strcpy(output->dbFName, rspMsg->dbFName);
|
||||
strcpy(output->tbName, rspMsg->tbName);
|
||||
|
||||
output->dbId = rspMsg->dbId;
|
||||
|
||||
SET_META_TYPE_TABLE(output->metaType);
|
||||
|
||||
CTG_ERR_JRET(queryCreateTableMetaFromMsg(rspMsg, true, &output->tbMeta));
|
||||
|
||||
CTG_ERR_JRET(ctgUpdateTbMetaEnqueue(pCtg, output, false));
|
||||
|
||||
CTG_API_LEAVE(code);
|
||||
CTG_ERR_JRET(ctgUpdateTbMeta(pCtg, pMsg, true));
|
||||
|
||||
_return:
|
||||
|
||||
taosMemoryFreeClear(output->tbMeta);
|
||||
taosMemoryFreeClear(output);
|
||||
|
||||
CTG_API_LEAVE(code);
|
||||
}
|
||||
|
|
|
@ -552,7 +552,7 @@ int32_t ctgEnqueue(SCatalog* pCtg, SCtgCacheOperation *operation) {
|
|||
|
||||
ctgDebug("action [%s] added into queue", gCtgCacheOperation[operation->opId].name);
|
||||
|
||||
if (operation->syncReq) {
|
||||
if (operation->syncOp) {
|
||||
ctgWaitOpDone(operation);
|
||||
}
|
||||
|
||||
|
@ -591,9 +591,9 @@ _return:
|
|||
}
|
||||
|
||||
|
||||
int32_t ctgDropStbMetaEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *stbName, uint64_t suid, bool syncReq) {
|
||||
int32_t ctgDropStbMetaEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *stbName, uint64_t suid, bool syncOp) {
|
||||
int32_t code = 0;
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_DROP_STB_META, .syncReq = syncReq};
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_DROP_STB_META, .syncOp = syncOp};
|
||||
SCtgRemoveStbMsg *msg = taosMemoryMalloc(sizeof(SCtgRemoveStbMsg));
|
||||
if (NULL == msg) {
|
||||
ctgError("malloc %d failed", (int32_t)sizeof(SCtgRemoveStbMsg));
|
||||
|
@ -620,9 +620,9 @@ _return:
|
|||
|
||||
|
||||
|
||||
int32_t ctgDropTbMetaEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *tbName, bool syncReq) {
|
||||
int32_t ctgDropTbMetaEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *tbName, bool syncOp) {
|
||||
int32_t code = 0;
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_DROP_TB_META, .syncReq = syncReq};
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_DROP_TB_META, .syncOp = syncOp};
|
||||
SCtgRemoveTblMsg *msg = taosMemoryMalloc(sizeof(SCtgRemoveTblMsg));
|
||||
if (NULL == msg) {
|
||||
ctgError("malloc %d failed", (int32_t)sizeof(SCtgRemoveTblMsg));
|
||||
|
@ -646,9 +646,9 @@ _return:
|
|||
CTG_RET(code);
|
||||
}
|
||||
|
||||
int32_t ctgUpdateVgroupEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, SDBVgInfo* dbInfo, bool syncReq) {
|
||||
int32_t ctgUpdateVgroupEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, SDBVgInfo* dbInfo, bool syncOp) {
|
||||
int32_t code = 0;
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_VGROUP, .syncReq = syncReq};
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_VGROUP, .syncOp = syncOp};
|
||||
SCtgUpdateVgMsg *msg = taosMemoryMalloc(sizeof(SCtgUpdateVgMsg));
|
||||
if (NULL == msg) {
|
||||
ctgError("malloc %d failed", (int32_t)sizeof(SCtgUpdateVgMsg));
|
||||
|
@ -679,9 +679,9 @@ _return:
|
|||
CTG_RET(code);
|
||||
}
|
||||
|
||||
int32_t ctgUpdateTbMetaEnqueue(SCatalog* pCtg, STableMetaOutput *output, bool syncReq) {
|
||||
int32_t ctgUpdateTbMetaEnqueue(SCatalog* pCtg, STableMetaOutput *output, bool syncOp) {
|
||||
int32_t code = 0;
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_TB_META, .syncReq = syncReq};
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_TB_META, .syncOp = syncOp};
|
||||
SCtgUpdateTblMsg *msg = taosMemoryMalloc(sizeof(SCtgUpdateTblMsg));
|
||||
if (NULL == msg) {
|
||||
ctgError("malloc %d failed", (int32_t)sizeof(SCtgUpdateTblMsg));
|
||||
|
@ -738,9 +738,9 @@ _return:
|
|||
|
||||
|
||||
|
||||
int32_t ctgUpdateUserEnqueue(SCatalog* pCtg, SGetUserAuthRsp *pAuth, bool syncReq) {
|
||||
int32_t ctgUpdateUserEnqueue(SCatalog* pCtg, SGetUserAuthRsp *pAuth, bool syncOp) {
|
||||
int32_t code = 0;
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_USER, .syncReq = syncReq};
|
||||
SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_USER, .syncOp = syncOp};
|
||||
SCtgUpdateUserMsg *msg = taosMemoryMalloc(sizeof(SCtgUpdateUserMsg));
|
||||
if (NULL == msg) {
|
||||
ctgError("malloc %d failed", (int32_t)sizeof(SCtgUpdateUserMsg));
|
||||
|
@ -1574,7 +1574,7 @@ void* ctgUpdateThreadFunc(void* param) {
|
|||
|
||||
gCtgMgmt.queue.seqDone = operation->seqId;
|
||||
|
||||
if (operation->syncReq) {
|
||||
if (operation->syncOp) {
|
||||
tsem_post(&gCtgMgmt.queue.rspSem);
|
||||
}
|
||||
|
||||
|
|
|
@ -1380,7 +1380,7 @@ TEST(tableMeta, updateStbMeta) {
|
|||
STableMetaRsp rsp = {0};
|
||||
ctgTestBuildSTableMetaRsp(&rsp);
|
||||
|
||||
code = catalogUpdateSTableMeta(pCtg, &rsp);
|
||||
code = catalogUpdateTableMeta(pCtg, &rsp);
|
||||
ASSERT_EQ(code, 0);
|
||||
taosMemoryFreeClear(rsp.pSchemas);
|
||||
|
||||
|
|
|
@ -75,15 +75,15 @@ typedef struct SResultRowInfo {
|
|||
int32_t size; // number of result set
|
||||
int32_t capacity; // max capacity
|
||||
SResultRowPosition cur;
|
||||
SList* openWindow;
|
||||
} SResultRowInfo;
|
||||
|
||||
struct SqlFunctionCtx;
|
||||
|
||||
size_t getResultRowSize(struct SqlFunctionCtx* pCtx, int32_t numOfOutput);
|
||||
size_t getResultRowSize(struct SqlFunctionCtx* pCtx, int32_t numOfOutput);
|
||||
int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size);
|
||||
void cleanupResultRowInfo(SResultRowInfo* pResultRowInfo);
|
||||
|
||||
int32_t numOfClosedResultRows(SResultRowInfo* pResultRowInfo);
|
||||
void closeAllResultRows(SResultRowInfo* pResultRowInfo);
|
||||
|
||||
void initResultRow(SResultRow *pResultRow);
|
||||
|
@ -92,15 +92,6 @@ bool isResultRowClosed(SResultRow* pResultRow);
|
|||
|
||||
struct SResultRowEntryInfo* getResultCell(const SResultRow* pRow, int32_t index, const int32_t* offset);
|
||||
|
||||
static FORCE_INLINE SResultRow *getResultRow(SDiskbasedBuf* pBuf, SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||
ASSERT(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
||||
SResultRowPosition* pos = &pResultRowInfo->pPosition[slot];
|
||||
|
||||
SFilePage* bufPage = (SFilePage*) getBufPage(pBuf, pos->pageId);
|
||||
SResultRow* pRow = (SResultRow*)((char*)bufPage + pos->offset);
|
||||
return pRow;
|
||||
}
|
||||
|
||||
static FORCE_INLINE SResultRow *getResultRowByPos(SDiskbasedBuf* pBuf, SResultRowPosition* pos) {
|
||||
SFilePage* bufPage = (SFilePage*) getBufPage(pBuf, pos->pageId);
|
||||
SResultRow* pRow = (SResultRow*)((char*)bufPage + pos->offset);
|
||||
|
|
|
@ -454,13 +454,14 @@ typedef struct SIntervalAggOperatorInfo {
|
|||
STimeWindow win; // query time range
|
||||
bool timeWindowInterpo; // interpolation needed or not
|
||||
char** pRow; // previous row/tuple of already processed datablock
|
||||
SArray* pInterpCols; // interpolation columns
|
||||
STableQueryInfo* pCurrent; // current tableQueryInfo struct
|
||||
int32_t order; // current SSDataBlock scan order
|
||||
EOPTR_EXEC_MODEL execModel; // operator execution model [batch model|stream model]
|
||||
SArray* pUpdatedWindow; // updated time window due to the input data block from the downstream operator.
|
||||
STimeWindowAggSupp twAggSup;
|
||||
struct SFillInfo* pFillInfo; // fill info
|
||||
bool invertible;
|
||||
SArray* pPrevValues; // SArray<SGroupKeys> used to keep the previous not null value for interpolation.
|
||||
} SIntervalAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamFinalIntervalOperatorInfo {
|
||||
|
@ -832,7 +833,7 @@ int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimary
|
|||
int32_t order);
|
||||
int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order);
|
||||
int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, const char* pKey);
|
||||
SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize);
|
||||
SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize);
|
||||
SResultWindowInfo* getSessionTimeWindow(SArray* pWinInfos, TSKEY ts, int64_t gap,
|
||||
int32_t* pIndex);
|
||||
int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pTs, int32_t rows,
|
||||
|
|
|
@ -101,20 +101,8 @@ void resetResultRowInfo(STaskRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRow
|
|||
pResultRowInfo->size = 0;
|
||||
}
|
||||
|
||||
int32_t numOfClosedResultRows(SResultRowInfo *pResultRowInfo) {
|
||||
int32_t i = 0;
|
||||
// while (i < pResultRowInfo->size && pResultRowInfo->pResult[i]->closed) {
|
||||
// ++i;
|
||||
// }
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void closeAllResultRows(SResultRowInfo *pResultRowInfo) {
|
||||
assert(pResultRowInfo->size >= 0 && pResultRowInfo->capacity >= pResultRowInfo->size);
|
||||
|
||||
for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
|
||||
}
|
||||
// do nothing
|
||||
}
|
||||
|
||||
bool isResultRowClosed(SResultRow* pRow) {
|
||||
|
@ -258,32 +246,6 @@ int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo) {
|
|||
return (int32_t) taosArrayGetSize(pGroupResInfo->pRows);
|
||||
}
|
||||
|
||||
static int64_t getNumOfResultWindowRes(STaskRuntimeEnv* pRuntimeEnv, SResultRowPosition *pos, int32_t* rowCellInfoOffset) {
|
||||
STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||
ASSERT(0);
|
||||
|
||||
for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) {
|
||||
int32_t functionId = 0;//pQueryAttr->pExpr1[j].base.functionId;
|
||||
|
||||
/*
|
||||
* ts, tag, tagprj function can not decide the output number of current query
|
||||
* the number of output result is decided by main output
|
||||
*/
|
||||
if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// SResultRowEntryInfo *pResultInfo = getResultCell(pResultRow, j, rowCellInfoOffset);
|
||||
// assert(pResultInfo != NULL);
|
||||
//
|
||||
// if (pResultInfo->numOfRes > 0) {
|
||||
// return pResultInfo->numOfRes;
|
||||
// }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tableResultComparFn(const void *pLeft, const void *pRight, void *param) {
|
||||
int32_t left = *(int32_t *)pLeft;
|
||||
int32_t right = *(int32_t *)pRight;
|
||||
|
@ -381,7 +343,7 @@ static int32_t mergeIntoGroupResultImplRv(STaskRuntimeEnv *pRuntimeEnv, SGroupRe
|
|||
}
|
||||
|
||||
|
||||
int64_t num = getNumOfResultWindowRes(pRuntimeEnv, &pResultRowCell->pos, rowCellInfoOffset);
|
||||
int64_t num = 0;//getNumOfResultWindowRes(pRuntimeEnv, &pResultRowCell->pos, rowCellInfoOffset);
|
||||
if (num <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -239,36 +239,6 @@ static bool hasNull(SColumn* pColumn, SColumnDataAgg* pStatis) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, jmp_buf env) {
|
||||
int64_t newCapacity = 0;
|
||||
|
||||
// more than the capacity, reallocate the resources
|
||||
if (pResultRowInfo->size < pResultRowInfo->capacity) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pResultRowInfo->capacity > 10000) {
|
||||
newCapacity = (int64_t)(pResultRowInfo->capacity * 1.25);
|
||||
} else {
|
||||
newCapacity = (int64_t)(pResultRowInfo->capacity * 1.5);
|
||||
}
|
||||
|
||||
if (newCapacity <= pResultRowInfo->capacity) {
|
||||
newCapacity += 4;
|
||||
}
|
||||
|
||||
char* p = taosMemoryRealloc(pResultRowInfo->pPosition, newCapacity * sizeof(SResultRowPosition));
|
||||
if (p == NULL) {
|
||||
longjmp(env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
pResultRowInfo->pPosition = (SResultRowPosition*)p;
|
||||
|
||||
int32_t inc = (int32_t)newCapacity - pResultRowInfo->capacity;
|
||||
memset(&pResultRowInfo->pPosition[pResultRowInfo->capacity], 0, sizeof(SResultRowPosition) * inc);
|
||||
pResultRowInfo->capacity = (int32_t)newCapacity;
|
||||
}
|
||||
|
||||
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
|
||||
int16_t bytes, bool masterscan, uint64_t uid) {
|
||||
bool existed = false;
|
||||
|
@ -306,7 +276,7 @@ static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pR
|
|||
return p1 != NULL;
|
||||
}
|
||||
|
||||
SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) {
|
||||
SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) {
|
||||
SFilePage* pData = NULL;
|
||||
|
||||
// in the first scan, new space needed for results
|
||||
|
@ -375,6 +345,8 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
|||
// In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the
|
||||
// pResultRowInfo object.
|
||||
if (p1 != NULL) {
|
||||
|
||||
// todo
|
||||
pResult = getResultRowByPos(pResultBuf, p1);
|
||||
ASSERT(pResult->pageId == p1->pageId && pResult->offset == p1->offset);
|
||||
}
|
||||
|
@ -383,34 +355,28 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
|||
// 1. close current opened time window
|
||||
if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId &&
|
||||
pResult->offset != pResultRowInfo->cur.offset))) {
|
||||
// todo extract function
|
||||
SResultRowPosition pos = pResultRowInfo->cur;
|
||||
SFilePage* pPage = getBufPage(pResultBuf, pos.pageId);
|
||||
SResultRow* pRow = (SResultRow*)((char*)pPage + pos.offset);
|
||||
closeResultRow(pRow);
|
||||
SFilePage* pPage = getBufPage(pResultBuf, pos.pageId);
|
||||
releaseBufPage(pResultBuf, pPage);
|
||||
}
|
||||
|
||||
// allocate a new buffer page
|
||||
prepareResultListBuffer(pResultRowInfo, pTaskInfo->env);
|
||||
if (pResult == NULL) {
|
||||
ASSERT(pSup->resultRowSize > 0);
|
||||
pResult = getNewResultRow_rv(pResultBuf, groupId, pSup->resultRowSize);
|
||||
pResult = getNewResultRow(pResultBuf, groupId, pSup->resultRowSize);
|
||||
|
||||
initResultRow(pResult);
|
||||
|
||||
// add a new result set for a new group
|
||||
SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
|
||||
taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos,
|
||||
sizeof(SResultRowPosition));
|
||||
taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos, sizeof(SResultRowPosition));
|
||||
}
|
||||
|
||||
// 2. set the new time window to be the new active time window
|
||||
pResultRowInfo->pPosition[pResultRowInfo->size++] =
|
||||
(SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
|
||||
pResultRowInfo->cur = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
|
||||
|
||||
// too many time window in query
|
||||
if (pResultRowInfo->size > MAX_INTERVAL_TIME_WINDOW) {
|
||||
if (taosHashGetSize(pSup->pResultRowHashTable) > MAX_INTERVAL_TIME_WINDOW) {
|
||||
longjmp(pTaskInfo->env, TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW);
|
||||
}
|
||||
|
||||
|
@ -585,11 +551,13 @@ void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow
|
|||
colDataAppendInt64(pColData, 4, &pQueryWindow->ekey);
|
||||
}
|
||||
|
||||
|
||||
void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow* pWin,
|
||||
SColumnInfoData* pTimeWindowData, int32_t offset, int32_t forwardStep, TSKEY* tsCol,
|
||||
int32_t numOfTotal, int32_t numOfOutput, int32_t order) {
|
||||
for (int32_t k = 0; k < numOfOutput; ++k) {
|
||||
// keep it temporarily
|
||||
// todo no need this??
|
||||
bool hasAgg = pCtx[k].input.colDataAggIsSet;
|
||||
int32_t numOfRows = pCtx[k].input.numOfRows;
|
||||
int32_t startOffset = pCtx[k].input.startRowIndex;
|
||||
|
@ -609,7 +577,8 @@ void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow
|
|||
|
||||
if (fmIsWindowPseudoColumnFunc(pCtx[k].functionId)) {
|
||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pCtx[k]);
|
||||
char* p = GET_ROWCELL_INTERBUF(pEntryInfo);
|
||||
|
||||
char* p = GET_ROWCELL_INTERBUF(pEntryInfo);
|
||||
|
||||
SColumnInfoData idata = {0};
|
||||
idata.info.type = TSDB_DATA_TYPE_BIGINT;
|
||||
|
@ -620,22 +589,23 @@ void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow
|
|||
SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData};
|
||||
pCtx[k].sfp.process(&tw, 1, &out);
|
||||
pEntryInfo->numOfRes = 1;
|
||||
continue;
|
||||
}
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (functionNeedToExecute(&pCtx[k]) && pCtx[k].fpSet.process != NULL) {
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s apply functions error, code: %s", GET_TASKID(taskInfo), tstrerror(code));
|
||||
taskInfo->code = code;
|
||||
longjmp(taskInfo->env, code);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (functionNeedToExecute(&pCtx[k]) && pCtx[k].fpSet.process != NULL) {
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
|
||||
// restore it
|
||||
pCtx[k].input.colDataAggIsSet = hasAgg;
|
||||
pCtx[k].input.startRowIndex = startOffset;
|
||||
pCtx[k].input.numOfRows = numOfRows;
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s apply functions error, code: %s", GET_TASKID(taskInfo), tstrerror(code));
|
||||
taskInfo->code = code;
|
||||
longjmp(taskInfo->env, code);
|
||||
}
|
||||
}
|
||||
|
||||
// restore it
|
||||
pCtx[k].input.colDataAggIsSet = hasAgg;
|
||||
pCtx[k].input.startRowIndex = startOffset;
|
||||
pCtx[k].input.numOfRows = numOfRows;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -774,12 +744,14 @@ static int32_t doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunct
|
|||
for (int32_t k = 0; k < pOperator->numOfExprs; ++k) {
|
||||
if (functionNeedToExecute(&pCtx[k])) {
|
||||
// todo add a dummy funtion to avoid process check
|
||||
if (pCtx[k].fpSet.process != NULL) {
|
||||
int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
if (pCtx[k].fpSet.process == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1218,7 +1190,6 @@ static void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
|||
taosVariantDestroy(&pCtx[i].param[j].param);
|
||||
}
|
||||
|
||||
taosVariantDestroy(&pCtx[i].tag);
|
||||
taosMemoryFreeClear(pCtx[i].subsidiaries.pCtx);
|
||||
taosMemoryFree(pCtx[i].input.pData);
|
||||
taosMemoryFree(pCtx[i].input.pColumnDataAgg);
|
||||
|
@ -1248,9 +1219,9 @@ void setTaskKilled(SExecTaskInfo* pTaskInfo) { pTaskInfo->code = TSDB_CODE_TSC_Q
|
|||
static bool isCachedLastQuery(STaskAttr* pQueryAttr) {
|
||||
for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
||||
int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
|
||||
if (functionId == FUNCTION_LAST || functionId == FUNCTION_LAST_DST) {
|
||||
continue;
|
||||
}
|
||||
// if (functionId == FUNCTION_LAST || functionId == FUNCTION_LAST_DST) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1300,7 +1271,7 @@ static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
|
|||
|
||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||
int32_t functionId = getExprFunctionId(&pQuery->pExpr1[i]);
|
||||
|
||||
#if 0
|
||||
if (functionId == FUNCTION_TS || functionId == FUNCTION_TS_DUMMY || functionId == FUNCTION_TAG ||
|
||||
functionId == FUNCTION_TAG_DUMMY) {
|
||||
continue;
|
||||
|
@ -1311,6 +1282,8 @@ static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
|
|||
} else {
|
||||
hasOtherFunc = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (hasFirstLastFunc && status == BLK_DATA_NOT_LOAD) {
|
||||
|
@ -1786,41 +1759,13 @@ void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t* bufCapacity, int32_t numOf
|
|||
|
||||
// set the correct pointer after the memory buffer reallocated.
|
||||
int32_t functionId = pBInfo->pCtx[i].functionId;
|
||||
|
||||
#if 0
|
||||
if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF ||
|
||||
functionId == FUNCTION_DERIVATIVE) {
|
||||
// if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
||||
bool needCopyTs = false;
|
||||
int32_t tsNum = 0;
|
||||
char* src = NULL;
|
||||
for (int32_t i = 0; i < numOfOutput; i++) {
|
||||
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) {
|
||||
SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i - 1); // find ts data
|
||||
src = pColRes->pData;
|
||||
}
|
||||
} else if (functionId == FUNCTION_TS_DUMMY) {
|
||||
tsNum++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!needCopyTs) return;
|
||||
if (tsNum < 2) return;
|
||||
if (src == NULL) return;
|
||||
|
||||
for (int32_t i = 0; i < numOfOutput; i++) {
|
||||
int32_t functionId = pCtx[i].functionId;
|
||||
if (functionId == FUNCTION_TS_DUMMY) {
|
||||
SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i);
|
||||
memcpy(pColRes->pData, src, pColRes->info.bytes * pRes->info.rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2577,47 +2522,7 @@ int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadI
|
|||
int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
|
||||
SArray* pColList) {
|
||||
if (pColList == NULL) { // data from other sources
|
||||
blockDataEnsureCapacity(pRes, numOfRows);
|
||||
|
||||
int32_t dataLen = *(int32_t*)pData;
|
||||
pData += sizeof(int32_t);
|
||||
|
||||
pRes->info.groupId = *(uint64_t*)pData;
|
||||
pData += sizeof(uint64_t);
|
||||
|
||||
int32_t* colLen = (int32_t*)pData;
|
||||
|
||||
char* pStart = pData + sizeof(int32_t) * numOfOutput;
|
||||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||
colLen[i] = htonl(colLen[i]);
|
||||
ASSERT(colLen[i] >= 0);
|
||||
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, i);
|
||||
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||
pColInfoData->varmeta.length = colLen[i];
|
||||
pColInfoData->varmeta.allocLen = colLen[i];
|
||||
|
||||
memcpy(pColInfoData->varmeta.offset, pStart, sizeof(int32_t) * numOfRows);
|
||||
pStart += sizeof(int32_t) * numOfRows;
|
||||
|
||||
if (colLen[i] > 0) {
|
||||
taosMemoryFreeClear(pColInfoData->pData);
|
||||
pColInfoData->pData = taosMemoryMalloc(colLen[i]);
|
||||
}
|
||||
} else {
|
||||
memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
|
||||
pStart += BitmapLen(numOfRows);
|
||||
}
|
||||
|
||||
if (colLen[i] > 0) {
|
||||
memcpy(pColInfoData->pData, pStart, colLen[i]);
|
||||
}
|
||||
|
||||
// TODO setting this flag to true temporarily so aggregate function on stable will
|
||||
// examine NULL value for non-primary key column
|
||||
pColInfoData->hasNull = true;
|
||||
pStart += colLen[i];
|
||||
}
|
||||
blockCompressDecode(pRes, numOfOutput, numOfRows, pData);
|
||||
} else { // extract data according to pColList
|
||||
ASSERT(numOfOutput == taosArrayGetSize(pColList));
|
||||
char* pStart = pData;
|
||||
|
@ -3587,7 +3492,7 @@ int32_t aggDecodeResultRow(SOperatorInfo* pOperator, char* result) {
|
|||
offset += sizeof(int32_t);
|
||||
|
||||
uint64_t tableGroupId = *(uint64_t*)(result + offset);
|
||||
SResultRow* resultRow = getNewResultRow_rv(pSup->pResultBuf, tableGroupId, pSup->resultRowSize);
|
||||
SResultRow* resultRow = getNewResultRow(pSup->pResultBuf, tableGroupId, pSup->resultRowSize);
|
||||
if (!resultRow) {
|
||||
return TSDB_CODE_TSC_INVALID_INPUT;
|
||||
}
|
||||
|
@ -3610,10 +3515,6 @@ int32_t aggDecodeResultRow(SOperatorInfo* pOperator, char* result) {
|
|||
offset += valueLen;
|
||||
|
||||
initResultRow(resultRow);
|
||||
prepareResultListBuffer(&pInfo->resultRowInfo, pOperator->pTaskInfo->env);
|
||||
// pInfo->resultRowInfo.cur = pInfo->resultRowInfo.size;
|
||||
// pInfo->resultRowInfo.pPosition[pInfo->resultRowInfo.size++] =
|
||||
// (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
|
||||
pInfo->resultRowInfo.cur = (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
|
||||
}
|
||||
|
||||
|
@ -3905,18 +3806,6 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator) {
|
|||
}
|
||||
}
|
||||
|
||||
// todo set the attribute of query scan count
|
||||
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) {
|
||||
for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
||||
int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
|
||||
if (functionId == FUNCTION_STDDEV || functionId == FUNCTION_PERCT) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void destroyOperatorInfo(SOperatorInfo* pOperator) {
|
||||
if (pOperator == NULL) {
|
||||
return;
|
||||
|
|
|
@ -110,9 +110,11 @@ static bool groupKeyCompare(SArray* pGroupCols, SArray* pGroupColVals, SSDataBlo
|
|||
return true;
|
||||
}
|
||||
|
||||
static void recordNewGroupKeys(SArray* pGroupCols, SArray* pGroupColVals, SSDataBlock* pBlock, int32_t rowIndex, int32_t numOfGroupCols) {
|
||||
static void recordNewGroupKeys(SArray* pGroupCols, SArray* pGroupColVals, SSDataBlock* pBlock, int32_t rowIndex) {
|
||||
SColumnDataAgg* pColAgg = NULL;
|
||||
|
||||
size_t numOfGroupCols = taosArrayGetSize(pGroupCols);
|
||||
|
||||
for (int32_t i = 0; i < numOfGroupCols; ++i) {
|
||||
SColumn* pCol = taosArrayGet(pGroupCols, i);
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pCol->slotId);
|
||||
|
@ -208,7 +210,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
|||
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
|
||||
// Compare with the previous row of this column, and do not set the output buffer again if they are identical.
|
||||
if (!pInfo->isInit) {
|
||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j, numOfGroupCols);
|
||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j);
|
||||
pInfo->isInit = true;
|
||||
num++;
|
||||
continue;
|
||||
|
@ -223,7 +225,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
|||
// The first row of a new block does not belongs to the previous existed group
|
||||
if (j == 0) {
|
||||
num++;
|
||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j, numOfGroupCols);
|
||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -238,7 +240,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
|||
|
||||
// assign the group keys or user input constant values if required
|
||||
doAssignGroupKeys(pCtx, pOperator->numOfExprs, pBlock->info.rows, rowIndex);
|
||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j, numOfGroupCols);
|
||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j);
|
||||
num = 1;
|
||||
}
|
||||
|
||||
|
@ -409,7 +411,7 @@ static void doHashPartition(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
|||
|
||||
int32_t numOfGroupCols = taosArrayGetSize(pInfo->pGroupCols);
|
||||
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
|
||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j, numOfGroupCols);
|
||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j);
|
||||
int32_t len = buildGroupKeys(pInfo->keyBuf, pInfo->pGroupColVals);
|
||||
|
||||
SDataGroupInfo* pGInfo = NULL;
|
||||
|
|
|
@ -531,7 +531,7 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode,
|
|||
}
|
||||
|
||||
pInfo->scanInfo = (SScanInfo){.numOfAsc = pTableScanNode->scanSeq[0], .numOfDesc = pTableScanNode->scanSeq[1]};
|
||||
// pInfo->scanInfo = (SScanInfo){.numOfAsc = 0, .numOfDesc = 1}; // for debug purpose
|
||||
// pInfo->scanInfo = (SScanInfo){.numOfAsc = 0, .numOfDesc = 1}; // for debug purpose
|
||||
|
||||
pInfo->readHandle = *readHandle;
|
||||
pInfo->interval = extractIntervalInfo(pTableScanNode);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "function.h"
|
||||
#include "executorimpl.h"
|
||||
#include "functionMgt.h"
|
||||
#include "tdatablock.h"
|
||||
|
@ -11,6 +12,11 @@ typedef enum SResultTsInterpType {
|
|||
static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator);
|
||||
static SSDataBlock* doStreamSessionWindowAgg(SOperatorInfo* pOperator);
|
||||
|
||||
static int64_t* extractTsCol(SSDataBlock* pBlock, const SIntervalAggOperatorInfo* pInfo);
|
||||
|
||||
static SResultRowPosition addToOpenWindowList(SResultRowInfo* pResultRowInfo, const SResultRow* pResult);
|
||||
static void doCloseWindow(SResultRowInfo* pResultRowInfo, const SIntervalAggOperatorInfo* pInfo, SResultRow* pResult);
|
||||
|
||||
/*
|
||||
* There are two cases to handle:
|
||||
*
|
||||
|
@ -21,47 +27,11 @@ static SSDataBlock* doStreamSessionWindowAgg(SOperatorInfo* pOperator);
|
|||
* is a previous result generated or not.
|
||||
*/
|
||||
static void setIntervalQueryRange(STableQueryInfo* pTableQueryInfo, TSKEY key, STimeWindow* pQRange) {
|
||||
// SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
|
||||
// if (pResultRowInfo->curPos != -1) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// pTableQueryInfo->win.skey = key;
|
||||
// STimeWindow win = {.skey = key, .ekey = pQRange->ekey};
|
||||
|
||||
/**
|
||||
* In handling the both ascending and descending order super table query, we need to find the first qualified
|
||||
* timestamp of this table, and then set the first qualified start timestamp.
|
||||
* In ascending query, the key is the first qualified timestamp. However, in the descending order query, additional
|
||||
* operations involve.
|
||||
*/
|
||||
// STimeWindow w = TSWINDOW_INITIALIZER;
|
||||
//
|
||||
// TSKEY sk = TMIN(win.skey, win.ekey);
|
||||
// TSKEY ek = TMAX(win.skey, win.ekey);
|
||||
// getAlignQueryTimeWindow(pQueryAttr, win.skey, sk, ek, &w);
|
||||
|
||||
// if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
|
||||
// if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||
// assert(win.ekey == pQueryAttr->window.ekey);
|
||||
// }
|
||||
//
|
||||
// pResultRowInfo->prevSKey = w.skey;
|
||||
// }
|
||||
|
||||
// pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols, int32_t rows, bool ascQuery) {
|
||||
TSKEY ts = TSKEY_INITIAL_VAL;
|
||||
if (tsCols == NULL) {
|
||||
ts = ascQuery ? win->skey : win->ekey;
|
||||
} else {
|
||||
// int32_t offset = ascQuery ? 0 : rows - 1;
|
||||
ts = tsCols[0];
|
||||
}
|
||||
|
||||
return ts;
|
||||
static TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols) {
|
||||
return tsCols == NULL? win->skey:tsCols[0];
|
||||
}
|
||||
|
||||
static void getInitialStartTimeWindow(SInterval* pInterval, int32_t precision, TSKEY ts, STimeWindow* w,
|
||||
|
@ -134,8 +104,10 @@ static int32_t setTimeWindowOutputBuf(SResultRowInfo* pResultRowInfo, STimeWindo
|
|||
|
||||
// set time window for current result
|
||||
pResultRow->win = (*win);
|
||||
|
||||
*pResult = pResultRow;
|
||||
setResultRowInitCtx(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -163,38 +135,38 @@ static void doKeepNewWindowStartInfo(SWindowRowsSup* pRowSup, const int64_t* tsL
|
|||
|
||||
static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey,
|
||||
int16_t pos, int16_t order, int64_t* pData) {
|
||||
int32_t forwardStep = 0;
|
||||
int32_t forwardRows = 0;
|
||||
|
||||
if (order == TSDB_ORDER_ASC) {
|
||||
int32_t end = searchFn((char*)&pData[pos], numOfRows - pos, ekey, order);
|
||||
if (end >= 0) {
|
||||
forwardStep = end;
|
||||
forwardRows = end;
|
||||
|
||||
if (pData[end + pos] == ekey) {
|
||||
forwardStep += 1;
|
||||
forwardRows += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int32_t end = searchFn((char*)&pData[pos], numOfRows - pos, ekey, order);
|
||||
if (end >= 0) {
|
||||
forwardStep = end;
|
||||
forwardRows = end;
|
||||
|
||||
if (pData[end + pos] == ekey) {
|
||||
forwardStep += 1;
|
||||
forwardRows += 1;
|
||||
}
|
||||
}
|
||||
// int32_t end = searchFn((char*)pData, pos + 1, ekey, order);
|
||||
// if (end >= 0) {
|
||||
// forwardStep = pos - end;
|
||||
// forwardRows = pos - end;
|
||||
//
|
||||
// if (pData[end] == ekey) {
|
||||
// forwardStep += 1;
|
||||
// forwardRows += 1;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
assert(forwardStep >= 0);
|
||||
return forwardStep;
|
||||
assert(forwardRows >= 0);
|
||||
return forwardRows;
|
||||
}
|
||||
|
||||
int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
|
||||
|
@ -339,34 +311,40 @@ static void getNextTimeWindow(SInterval* pInterval, int32_t precision, int32_t o
|
|||
tw->ekey -= 1;
|
||||
}
|
||||
|
||||
void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, SArray* pDataBlock, TSKEY prevTs,
|
||||
void doTimeWindowInterpolation(SIntervalAggOperatorInfo *pInfo, int32_t numOfExprs, SArray* pDataBlock, TSKEY prevTs,
|
||||
int32_t prevRowIndex, TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type) {
|
||||
SExprInfo* pExpr = pOperator->pExpr;
|
||||
SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
|
||||
|
||||
SqlFunctionCtx* pCtx = pInfo->pCtx;
|
||||
int32_t index = 1;
|
||||
for (int32_t k = 0; k < numOfExprs; ++k) {
|
||||
|
||||
for (int32_t k = 0; k < pOperator->numOfExprs; ++k) {
|
||||
int32_t functionId = pCtx[k].functionId;
|
||||
if (functionId != FUNCTION_TWA && functionId != FUNCTION_INTERP) {
|
||||
// todo use flag instead of function name
|
||||
if (strcmp(pCtx[k].pExpr->pExpr->_function.functionName, "twa") != 0) {
|
||||
pCtx[k].start.key = INT64_MIN;
|
||||
continue;
|
||||
}
|
||||
|
||||
SColIndex* pColIndex = NULL /*&pExpr[k].base.colInfo*/;
|
||||
int16_t index = pColIndex->colIndex;
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, index);
|
||||
// if (functionId != FUNCTION_TWA && functionId != FUNCTION_INTERP) {
|
||||
// pCtx[k].start.key = INT64_MIN;
|
||||
// continue;
|
||||
// }
|
||||
|
||||
SFunctParam* pParam = &pCtx[k].param[0];
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, pParam->pCol->slotId);
|
||||
|
||||
ASSERT(pColInfo->info.colId == pParam->pCol->colId && curTs != windowKey);
|
||||
|
||||
// assert(pColInfo->info.colId == pColIndex->info.colId && curTs != windowKey);
|
||||
double v1 = 0, v2 = 0, v = 0;
|
||||
|
||||
if (prevRowIndex == -1) {
|
||||
// GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pRuntimeEnv->prevRow[index]);
|
||||
SGroupKeys* p = taosArrayGet(pInfo->pPrevValues, index);
|
||||
GET_TYPED_DATA(v1, double, pColInfo->info.type, p->pData);
|
||||
} else {
|
||||
GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pColInfo->pData + prevRowIndex * pColInfo->info.bytes);
|
||||
GET_TYPED_DATA(v1, double, pColInfo->info.type, colDataGetData(pColInfo, prevRowIndex));
|
||||
}
|
||||
|
||||
GET_TYPED_DATA(v2, double, pColInfo->info.type, (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes);
|
||||
GET_TYPED_DATA(v2, double, pColInfo->info.type, colDataGetData(pColInfo, curRowIndex));
|
||||
|
||||
#if 0
|
||||
if (functionId == FUNCTION_INTERP) {
|
||||
if (type == RESULT_ROW_START_INTERP) {
|
||||
pCtx[k].start.key = prevTs;
|
||||
|
@ -386,6 +364,8 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
|
|||
}
|
||||
}
|
||||
} else if (functionId == FUNCTION_TWA) {
|
||||
#endif
|
||||
|
||||
SPoint point1 = (SPoint){.key = prevTs, .val = &v1};
|
||||
SPoint point2 = (SPoint){.key = curTs, .val = &v2};
|
||||
SPoint point = (SPoint){.key = windowKey, .val = &v};
|
||||
|
@ -399,8 +379,13 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
|
|||
pCtx[k].end.key = point.key;
|
||||
pCtx[k].end.val = v;
|
||||
}
|
||||
|
||||
index += 1;
|
||||
}
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void setNotInterpoWindowKey(SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t type) {
|
||||
|
@ -415,62 +400,59 @@ static void setNotInterpoWindowKey(SqlFunctionCtx* pCtx, int32_t numOfOutput, in
|
|||
}
|
||||
}
|
||||
|
||||
static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t pos,
|
||||
int32_t numOfRows, SArray* pDataBlock, const TSKEY* tsCols,
|
||||
STimeWindow* win) {
|
||||
bool ascQuery = true;
|
||||
static bool setTimeWindowInterpolationStartTs(SIntervalAggOperatorInfo *pInfo, SqlFunctionCtx* pCtx, int32_t numOfExprs, int32_t pos,
|
||||
SSDataBlock* pBlock, const TSKEY* tsCols, STimeWindow* win) {
|
||||
bool ascQuery = (pInfo->order == TSDB_ORDER_ASC);
|
||||
|
||||
TSKEY curTs = tsCols[pos];
|
||||
TSKEY lastTs = 0; //*(TSKEY*)pRuntimeEnv->prevRow[0];
|
||||
|
||||
SGroupKeys* pTsKey = taosArrayGet(pInfo->pPrevValues, 0);
|
||||
TSKEY lastTs = *(int64_t*) pTsKey->pData;
|
||||
|
||||
// lastTs == INT64_MIN and pos == 0 means this is the first time window, interpolation is not needed.
|
||||
// start exactly from this point, no need to do interpolation
|
||||
TSKEY key = ascQuery ? win->skey : win->ekey;
|
||||
if (key == curTs) {
|
||||
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_START_INTERP);
|
||||
setNotInterpoWindowKey(pCtx, numOfExprs, RESULT_ROW_START_INTERP);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lastTs == INT64_MIN && ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery))) {
|
||||
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_START_INTERP);
|
||||
return true;
|
||||
// it is the first time window, no need to do interpolation
|
||||
if (pTsKey->isNull && pos == 0) {
|
||||
setNotInterpoWindowKey(pCtx, numOfExprs, RESULT_ROW_START_INTERP);
|
||||
} else {
|
||||
TSKEY prevTs = ((pos == 0) ? lastTs : tsCols[pos - 1]);
|
||||
doTimeWindowInterpolation(pInfo, numOfExprs, pBlock->pDataBlock, prevTs, pos - 1, curTs, pos, key,
|
||||
RESULT_ROW_START_INTERP);
|
||||
}
|
||||
|
||||
int32_t step = 1; // GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
|
||||
TSKEY prevTs = ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery)) ? lastTs : tsCols[pos - step];
|
||||
|
||||
doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, prevTs, pos - step, curTs, pos, key,
|
||||
RESULT_ROW_START_INTERP);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t endRowIndex,
|
||||
SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey,
|
||||
STimeWindow* win) {
|
||||
int32_t order = TSDB_ORDER_ASC;
|
||||
int32_t numOfOutput = pOperatorInfo->numOfExprs;
|
||||
static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo *pInfo, SqlFunctionCtx* pCtx, int32_t numOfExprs, int32_t endRowIndex,
|
||||
SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey, STimeWindow* win) {
|
||||
int32_t order = pInfo->order;
|
||||
|
||||
TSKEY actualEndKey = tsCols[endRowIndex];
|
||||
TSKEY key = order ? win->ekey : win->skey;
|
||||
TSKEY key = (order == TSDB_ORDER_ASC) ? win->ekey : win->skey;
|
||||
|
||||
// not ended in current data block, do not invoke interpolation
|
||||
if ((key > blockEkey /*&& QUERY_IS_ASC_QUERY(pQueryAttr)*/) ||
|
||||
(key < blockEkey /*&& !QUERY_IS_ASC_QUERY(pQueryAttr)*/)) {
|
||||
setNotInterpoWindowKey(pCtx, numOfOutput, RESULT_ROW_END_INTERP);
|
||||
if ((key > blockEkey && (order == TSDB_ORDER_ASC)) || (key < blockEkey && (order == TSDB_ORDER_DESC))) {
|
||||
setNotInterpoWindowKey(pCtx, numOfExprs, RESULT_ROW_END_INTERP);
|
||||
return false;
|
||||
}
|
||||
|
||||
// there is actual end point of current time window, no interpolation need
|
||||
// there is actual end point of current time window, no interpolation needs
|
||||
if (key == actualEndKey) {
|
||||
setNotInterpoWindowKey(pCtx, numOfOutput, RESULT_ROW_END_INTERP);
|
||||
setNotInterpoWindowKey(pCtx, numOfExprs, RESULT_ROW_END_INTERP);
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
int32_t nextRowIndex = endRowIndex + step;
|
||||
int32_t nextRowIndex = endRowIndex + 1;
|
||||
assert(nextRowIndex >= 0);
|
||||
|
||||
TSKEY nextKey = tsCols[nextRowIndex];
|
||||
doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, actualEndKey, endRowIndex, nextKey,
|
||||
doTimeWindowInterpolation(pInfo, numOfExprs, pDataBlock, actualEndKey, endRowIndex, nextKey,
|
||||
nextRowIndex, key, RESULT_ROW_END_INTERP);
|
||||
return true;
|
||||
}
|
||||
|
@ -542,8 +524,8 @@ static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext,
|
|||
return startPos;
|
||||
}
|
||||
|
||||
static bool resultRowInterpolated(SResultRow* pResult, SResultTsInterpType type) {
|
||||
assert(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
|
||||
static bool isResultRowInterpolated(SResultRow* pResult, SResultTsInterpType type) {
|
||||
ASSERT(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
|
||||
if (type == RESULT_ROW_START_INTERP) {
|
||||
return pResult->startInterp == true;
|
||||
} else {
|
||||
|
@ -560,34 +542,29 @@ static void setResultRowInterpo(SResultRow* pResult, SResultTsInterpType type) {
|
|||
}
|
||||
}
|
||||
|
||||
static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlock, SqlFunctionCtx* pCtx,
|
||||
SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardStep,
|
||||
int32_t order, bool timeWindowInterpo) {
|
||||
if (!timeWindowInterpo) {
|
||||
static void doWindowBorderInterpolation(SIntervalAggOperatorInfo *pInfo, SSDataBlock* pBlock, int32_t numOfExprs, SqlFunctionCtx* pCtx,
|
||||
SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardRows) {
|
||||
if (!pInfo->timeWindowInterpo) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pBlock != NULL);
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
|
||||
ASSERT(pBlock != NULL);
|
||||
if (pBlock->pDataBlock == NULL) {
|
||||
// tscError("pBlock->pDataBlock == NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
|
||||
TSKEY* tsCols = (TSKEY*)(pColInfo->pData);
|
||||
bool done = resultRowInterpolated(pResult, RESULT_ROW_START_INTERP);
|
||||
bool done = isResultRowInterpolated(pResult, RESULT_ROW_START_INTERP);
|
||||
if (!done) { // it is not interpolated, now start to generated the interpolated value
|
||||
int32_t startRowIndex = startPos;
|
||||
bool interp = setTimeWindowInterpolationStartTs(pOperatorInfo, pCtx, startRowIndex, pBlock->info.rows,
|
||||
pBlock->pDataBlock, tsCols, win);
|
||||
bool interp = setTimeWindowInterpolationStartTs(pInfo, pCtx, numOfExprs, startPos, pBlock, tsCols, win);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||
}
|
||||
} else {
|
||||
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_START_INTERP);
|
||||
setNotInterpoWindowKey(pCtx, numOfExprs, RESULT_ROW_START_INTERP);
|
||||
}
|
||||
|
||||
// point interpolation does not require the end key time window interpolation.
|
||||
|
@ -596,29 +573,106 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc
|
|||
// }
|
||||
|
||||
// interpolation query does not generate the time window end interpolation
|
||||
done = resultRowInterpolated(pResult, RESULT_ROW_END_INTERP);
|
||||
done = isResultRowInterpolated(pResult, RESULT_ROW_END_INTERP);
|
||||
if (!done) {
|
||||
int32_t endRowIndex = startPos + (forwardStep - 1) * step;
|
||||
int32_t endRowIndex = startPos + forwardRows - 1;
|
||||
|
||||
TSKEY endKey = (order == TSDB_ORDER_ASC) ? pBlock->info.window.ekey : pBlock->info.window.skey;
|
||||
TSKEY endKey = (pInfo->order == TSDB_ORDER_ASC) ? pBlock->info.window.ekey : pBlock->info.window.skey;
|
||||
bool interp =
|
||||
setTimeWindowInterpolationEndTs(pOperatorInfo, pCtx, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win);
|
||||
setTimeWindowInterpolationEndTs(pInfo, pCtx, numOfExprs, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
}
|
||||
} else {
|
||||
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_END_INTERP);
|
||||
setNotInterpoWindowKey(pCtx, numOfExprs, RESULT_ROW_END_INTERP);
|
||||
}
|
||||
}
|
||||
|
||||
static void saveDataBlockLastRow(char** pRow, SArray* pDataBlock, int32_t rowIndex, int32_t numOfCols) {
|
||||
if (pDataBlock == NULL) {
|
||||
static void saveDataBlockLastRow(SArray* pPrevKeys, const SSDataBlock* pBlock, SArray* pCols) {
|
||||
if (pBlock->pDataBlock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t k = 0; k < numOfCols; ++k) {
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, k);
|
||||
memcpy(pRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * rowIndex), pColInfo->info.bytes);
|
||||
size_t num = taosArrayGetSize(pPrevKeys);
|
||||
for (int32_t k = 0; k < num; ++k) {
|
||||
SColumn* pc = taosArrayGet(pCols, k);
|
||||
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, pc->slotId);
|
||||
|
||||
SGroupKeys* pkey = taosArrayGet(pPrevKeys, k);
|
||||
for(int32_t i = pBlock->info.rows - 1; i >= 0; --i) {
|
||||
if (colDataIsNull_s(pColInfo, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char* val = colDataGetData(pColInfo, i);
|
||||
if (IS_VAR_DATA_TYPE(pkey->type)) {
|
||||
memcpy(pkey->pData, val, varDataTLen(val));
|
||||
ASSERT(varDataTLen(val) <= pkey->bytes);
|
||||
} else {
|
||||
memcpy(pkey->pData, val, pkey->bytes);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t numOfExprs, SResultRowInfo* pResultRowInfo,
|
||||
SSDataBlock* pBlock, int32_t scanFlag, int64_t* tsCols, SResultRowPosition* p) {
|
||||
SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
|
||||
|
||||
SIntervalAggOperatorInfo* pInfo = (SIntervalAggOperatorInfo*)pOperatorInfo->info;
|
||||
|
||||
int32_t startPos = 0;
|
||||
int32_t numOfOutput = pOperatorInfo->numOfExprs;
|
||||
uint64_t groupId = pBlock->info.groupId;
|
||||
|
||||
SResultRow* pResult = NULL;
|
||||
|
||||
while (1) {
|
||||
SListNode* pn = tdListGetHead(pResultRowInfo->openWindow);
|
||||
|
||||
SResultRowPosition* p1 = (SResultRowPosition*)pn->data;
|
||||
if (p->pageId == p1->pageId && p->offset == p1->offset) {
|
||||
break;
|
||||
}
|
||||
|
||||
SResultRow* pr = getResultRowByPos(pInfo->aggSup.pResultBuf, p1);
|
||||
ASSERT(pr->offset == p1->offset && pr->pageId == p1->pageId);
|
||||
|
||||
if (pr->closed) {
|
||||
ASSERT(isResultRowInterpolated(pr, RESULT_ROW_START_INTERP) && isResultRowInterpolated(pr, RESULT_ROW_END_INTERP));
|
||||
tdListPopHead(pResultRowInfo->openWindow);
|
||||
continue;
|
||||
}
|
||||
|
||||
STimeWindow w = pr->win;
|
||||
int32_t ret = setTimeWindowOutputBuf(pResultRowInfo, &w, (scanFlag == MAIN_SCAN), &pResult, groupId, pInfo->binfo.pCtx,
|
||||
numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
ASSERT(!isResultRowInterpolated(pResult, RESULT_ROW_END_INTERP));
|
||||
|
||||
SGroupKeys *pTsKey = taosArrayGet(pInfo->pPrevValues, 0);
|
||||
int64_t prevTs = *(int64_t*) pTsKey->pData;
|
||||
doTimeWindowInterpolation(pInfo, numOfOutput, pBlock->pDataBlock, prevTs, -1, tsCols[startPos], startPos,
|
||||
w.ekey, RESULT_ROW_END_INTERP);
|
||||
|
||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
setNotInterpoWindowKey(pInfo->binfo.pCtx, numOfExprs, RESULT_ROW_START_INTERP);
|
||||
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &w, &pInfo->twAggSup.timeWindowData, startPos, 0, tsCols,
|
||||
pBlock->info.rows, numOfExprs, pInfo->order);
|
||||
|
||||
if (isResultRowInterpolated(pResult, RESULT_ROW_END_INTERP)) {
|
||||
closeResultRow(pr);
|
||||
tdListPopHead(pResultRowInfo->openWindow);
|
||||
} else { // the remains are can not be closed yet.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -698,7 +752,7 @@ static int32_t saveResult(SResultRow* result, uint64_t groupId, SArray* pUpdated
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SResKeyPos* newPos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
|
||||
if (newPos == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -713,36 +767,23 @@ static int32_t saveResult(SResultRow* result, uint64_t groupId, SArray* pUpdated
|
|||
}
|
||||
|
||||
static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pBlock,
|
||||
uint64_t tableGroupId, SArray* pUpdated) {
|
||||
int32_t scanFlag, SArray* pUpdated) {
|
||||
SIntervalAggOperatorInfo* pInfo = (SIntervalAggOperatorInfo*)pOperatorInfo->info;
|
||||
|
||||
SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
|
||||
int32_t numOfOutput = pOperatorInfo->numOfExprs;
|
||||
|
||||
int32_t step = 1;
|
||||
bool ascScan = (pInfo->order == TSDB_ORDER_ASC);
|
||||
|
||||
// int32_t prevIndex = pResultRowInfo->curPos;
|
||||
|
||||
TSKEY* tsCols = NULL;
|
||||
if (pBlock->pDataBlock != NULL) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
tsCols = (int64_t*)pColDataInfo->pData;
|
||||
|
||||
if (tsCols != NULL) {
|
||||
blockDataUpdateTsWindow(pBlock, pInfo->primaryTsIndex);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t startPos = 0;
|
||||
TSKEY ts = getStartTsKey(&pBlock->info.window, tsCols, pBlock->info.rows, ascScan);
|
||||
int32_t startPos = 0;
|
||||
int32_t numOfOutput = pOperatorInfo->numOfExprs;
|
||||
int64_t *tsCols = extractTsCol(pBlock, pInfo);
|
||||
uint64_t tableGroupId = pBlock->info.groupId;
|
||||
bool ascScan = (pInfo->order == TSDB_ORDER_ASC);
|
||||
TSKEY ts = getStartTsKey(&pBlock->info.window, tsCols);
|
||||
SResultRow* pResult = NULL;
|
||||
|
||||
STimeWindow win = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval,
|
||||
pInfo->interval.precision, &pInfo->win);
|
||||
bool masterScan = true;
|
||||
SResultRow* pResult = NULL;
|
||||
|
||||
int32_t ret = setTimeWindowOutputBuf(pResultRowInfo, &win, masterScan, &pResult, tableGroupId, pInfo->binfo.pCtx,
|
||||
int32_t ret = setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pInfo->binfo.pCtx,
|
||||
numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
|
@ -758,63 +799,35 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
|||
}
|
||||
}
|
||||
|
||||
int32_t forwardStep = 0;
|
||||
TSKEY ekey = ascScan? win.ekey:win.skey;
|
||||
forwardStep =
|
||||
getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, pInfo->order);
|
||||
ASSERT(forwardStep > 0);
|
||||
int32_t forwardRows = getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, pInfo->order);
|
||||
ASSERT(forwardRows > 0);
|
||||
|
||||
// prev time window not interpolation yet.
|
||||
// int32_t curIndex = pResultRowInfo->curPos;
|
||||
|
||||
#if 0
|
||||
if (prevIndex != -1 && prevIndex < curIndex && pInfo->timeWindowInterpo) {
|
||||
for (int32_t j = prevIndex; j < curIndex; ++j) { // previous time window may be all closed already.
|
||||
SResultRow* pRes = getResultRow(pResultRowInfo, j);
|
||||
if (pRes->closed) {
|
||||
assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && resultRowInterpolated(pRes, RESULT_ROW_END_INTERP));
|
||||
continue;
|
||||
}
|
||||
|
||||
STimeWindow w = pRes->win;
|
||||
ret = setTimeWindowOutputBuf(pResultRowInfo, pBlock->info.uid, &w, masterScan, &pResult, 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);
|
||||
}
|
||||
|
||||
assert(!resultRowInterpolated(pResult, RESULT_ROW_END_INTERP));
|
||||
doTimeWindowInterpolation(pOperatorInfo, &pInfo->binfo, pBlock->pDataBlock, *(TSKEY*)pInfo->pRow[0], -1,
|
||||
tsCols[startPos], startPos, w.ekey, RESULT_ROW_END_INTERP);
|
||||
|
||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_START_INTERP);
|
||||
|
||||
doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
if (pInfo->timeWindowInterpo) {
|
||||
SResultRowPosition pos = addToOpenWindowList(pResultRowInfo, pResult);
|
||||
doInterpUnclosedTimeWindow(pOperatorInfo, numOfOutput, pResultRowInfo, pBlock, scanFlag, tsCols, &pos);
|
||||
|
||||
// restore current time window
|
||||
ret = setTimeWindowOutputBuf(pResultRowInfo, pBlock->info.uid, &win, masterScan, &pResult, tableGroupId,
|
||||
pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
|
||||
pTaskInfo);
|
||||
ret = setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, 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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// window start key interpolation
|
||||
doWindowBorderInterpolation(pOperatorInfo, pBlock, pInfo->binfo.pCtx, pResult, &win, startPos, forwardStep,
|
||||
pInfo->order, false);
|
||||
// window start key interpolation
|
||||
doWindowBorderInterpolation(pInfo, pBlock, numOfOutput, pInfo->binfo.pCtx, pResult, &win, startPos, forwardRows);
|
||||
}
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &win, true);
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &win, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
|
||||
pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &win, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, tsCols,
|
||||
pBlock->info.rows, numOfOutput, pInfo->order);
|
||||
|
||||
doCloseWindow(pResultRowInfo, pInfo, pResult);
|
||||
|
||||
STimeWindow nextWin = win;
|
||||
while (1) {
|
||||
int32_t prevEndPos = (forwardStep - 1) * step + startPos;
|
||||
int32_t prevEndPos = forwardRows - 1 + startPos;
|
||||
startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pBlock->info, tsCols, prevEndPos, pInfo->order);
|
||||
if (startPos < 0) {
|
||||
break;
|
||||
|
@ -822,12 +835,13 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
|||
|
||||
// null data, failed to allocate more memory buffer
|
||||
int32_t code =
|
||||
setTimeWindowOutputBuf(pResultRowInfo, &nextWin, masterScan, &pResult, tableGroupId, pInfo->binfo.pCtx,
|
||||
setTimeWindowOutputBuf(pResultRowInfo, &nextWin, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, 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);
|
||||
}
|
||||
|
||||
|
||||
if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE ||
|
||||
pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE_SMA) {
|
||||
|
@ -839,24 +853,59 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
|||
}
|
||||
|
||||
ekey = ascScan? nextWin.ekey:nextWin.skey;
|
||||
forwardStep =
|
||||
forwardRows =
|
||||
getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, pInfo->order);
|
||||
|
||||
// window start(end) key interpolation
|
||||
doWindowBorderInterpolation(pOperatorInfo, pBlock, pInfo->binfo.pCtx, pResult, &nextWin, startPos, forwardStep,
|
||||
pInfo->order, false);
|
||||
doWindowBorderInterpolation(pInfo, pBlock, numOfOutput, pInfo->binfo.pCtx, pResult, &nextWin, startPos, forwardRows);
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true);
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
|
||||
pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, tsCols,
|
||||
pBlock->info.rows, numOfOutput, pInfo->order);
|
||||
doCloseWindow(pResultRowInfo, pInfo, pResult);
|
||||
}
|
||||
|
||||
if (pInfo->timeWindowInterpo) {
|
||||
int32_t rowIndex = ascScan ? (pBlock->info.rows - 1) : 0;
|
||||
saveDataBlockLastRow(pInfo->pRow, pBlock->pDataBlock, rowIndex, pBlock->info.numOfCols);
|
||||
saveDataBlockLastRow(pInfo->pPrevValues, pBlock, pInfo->pInterpCols);
|
||||
}
|
||||
}
|
||||
|
||||
void doCloseWindow(SResultRowInfo* pResultRowInfo, const SIntervalAggOperatorInfo* pInfo, SResultRow* pResult) {
|
||||
// current result is done in computing final results.
|
||||
if (pInfo->timeWindowInterpo && isResultRowInterpolated(pResult, RESULT_ROW_END_INTERP)) {
|
||||
closeResultRow(pResult);
|
||||
tdListPopHead(pResultRowInfo->openWindow);
|
||||
}
|
||||
}
|
||||
|
||||
SResultRowPosition addToOpenWindowList(SResultRowInfo* pResultRowInfo, const SResultRow* pResult) {
|
||||
SResultRowPosition pos = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
|
||||
SListNode* pn = tdListGetTail(pResultRowInfo->openWindow);
|
||||
if (pn == NULL) {
|
||||
tdListAppend(pResultRowInfo->openWindow, &pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
// updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false);
|
||||
SResultRowPosition* px = (SResultRowPosition*)pn->data;
|
||||
if (px->pageId != pos.pageId || px->offset != pos.offset) {
|
||||
tdListAppend(pResultRowInfo->openWindow, &pos);
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
int64_t* extractTsCol(SSDataBlock* pBlock, const SIntervalAggOperatorInfo* pInfo) {
|
||||
TSKEY* tsCols = NULL;
|
||||
if (pBlock->pDataBlock != NULL) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
tsCols = (int64_t*)pColDataInfo->pData;
|
||||
|
||||
if (tsCols != NULL) {
|
||||
blockDataUpdateTsWindow(pBlock, pInfo->primaryTsIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return tsCols;
|
||||
}
|
||||
|
||||
static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
|
||||
|
@ -885,7 +934,7 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
|
|||
STableQueryInfo* pTableQueryInfo = pInfo->pCurrent;
|
||||
|
||||
setIntervalQueryRange(pTableQueryInfo, pBlock->info.window.skey, &pTaskInfo->window);
|
||||
hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, pBlock->info.groupId, NULL);
|
||||
hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, scanFlag, NULL);
|
||||
|
||||
#if 0 // test for encode/decode result info
|
||||
if(pOperator->fpSet.encodeResultRow){
|
||||
|
@ -1016,8 +1065,9 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
SStateWindowOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
|
||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
doBuildResultDatablock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf);
|
||||
|
@ -1126,8 +1176,7 @@ static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type
|
|||
}
|
||||
}
|
||||
|
||||
void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf,
|
||||
SOptrBasicInfo* pBinfo, int32_t numOfOutput) {
|
||||
void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf, SOptrBasicInfo* pBinfo, int32_t numOfOutput) {
|
||||
SResultRow* pResult = getResultRowByPos(pResultBuf, p1);
|
||||
SqlFunctionCtx* pCtx = pBinfo->pCtx;
|
||||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||
|
@ -1243,7 +1292,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
break;
|
||||
}
|
||||
|
||||
// The timewindows that overlaps the timestamps of the input pBlock need to be recalculated and return to the
|
||||
// The timewindow that overlaps the timestamps of the input pBlock need to be recalculated and return to the
|
||||
// caller. Note that all the time window are not close till now.
|
||||
// the pDataBlock are always the same one, no need to call this again
|
||||
setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, pInfo->order, MAIN_SCAN, true);
|
||||
|
@ -1258,9 +1307,10 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
continue;
|
||||
}
|
||||
|
||||
hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, pBlock->info.groupId, pUpdated);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, MAIN_SCAN, pUpdated);
|
||||
}
|
||||
|
||||
closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup,
|
||||
&pInfo->interval, pClosed);
|
||||
finalizeUpdatedResult(pOperator->numOfExprs, pInfo->aggSup.pResultBuf, pClosed,
|
||||
|
@ -1269,9 +1319,9 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE_SMA) {
|
||||
taosArrayAddAll(pUpdated, pClosed);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pClosed);
|
||||
finalizeUpdatedResult(pOperator->numOfExprs, pInfo->aggSup.pResultBuf, pUpdated,
|
||||
pInfo->binfo.rowCellInfoOffset);
|
||||
finalizeUpdatedResult(pOperator->numOfExprs, pInfo->aggSup.pResultBuf, pUpdated, pInfo->binfo.rowCellInfoOffset);
|
||||
|
||||
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
@ -1309,7 +1359,7 @@ void destroyStreamFinalIntervalOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
}
|
||||
}
|
||||
|
||||
bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) {
|
||||
static bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) {
|
||||
for (int32_t i = 0; i < numOfCols; i++) {
|
||||
if (!fmIsInvertible(pFCtx[i].functionId)) {
|
||||
return false;
|
||||
|
@ -1318,6 +1368,50 @@ bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool timeWindowinterpNeeded(SqlFunctionCtx* pCtx, int32_t numOfCols, SIntervalAggOperatorInfo* pInfo) {
|
||||
// the primary timestamp column
|
||||
bool needed = false;
|
||||
pInfo->pInterpCols = taosArrayInit(4, sizeof(SColumn));
|
||||
pInfo->pPrevValues = taosArrayInit(4, sizeof(SGroupKeys));
|
||||
|
||||
{ // ts column
|
||||
SColumn c = {0};
|
||||
c.colId = 1;
|
||||
c.slotId = pInfo->primaryTsIndex;
|
||||
c.type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
c.bytes = sizeof(int64_t);
|
||||
taosArrayPush(pInfo->pInterpCols, &c);
|
||||
|
||||
SGroupKeys key = {0};
|
||||
key.bytes = c.bytes;
|
||||
key.type = c.type;
|
||||
key.isNull = true; // to denote no value is assigned yet
|
||||
key.pData = taosMemoryCalloc(1, c.bytes);
|
||||
taosArrayPush(pInfo->pPrevValues, &key);
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
SExprInfo* pExpr = pCtx[i].pExpr;
|
||||
|
||||
if (strcmp(pExpr->pExpr->_function.functionName, "twa") == 0) {
|
||||
SFunctParam* pParam = &pExpr->base.pParam[0];
|
||||
|
||||
SColumn c = *pParam->pCol;
|
||||
taosArrayPush(pInfo->pInterpCols, &c);
|
||||
needed = true;
|
||||
|
||||
SGroupKeys key = {0};
|
||||
key.bytes = c.bytes;
|
||||
key.type = c.type;
|
||||
key.isNull = false;
|
||||
key.pData = taosMemoryCalloc(1, c.bytes);
|
||||
taosArrayPush(pInfo->pPrevValues, &key);
|
||||
}
|
||||
}
|
||||
|
||||
return needed;
|
||||
}
|
||||
|
||||
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
|
||||
STimeWindowAggSupp* pTwAggSupp, SExecTaskInfo* pTaskInfo) {
|
||||
|
@ -1327,11 +1421,12 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->order = TSDB_ORDER_ASC;
|
||||
pInfo->interval = *pInterval;
|
||||
pInfo->win = pTaskInfo->window;
|
||||
pInfo->order = TSDB_ORDER_ASC;
|
||||
pInfo->interval = *pInterval;
|
||||
pInfo->execModel = pTaskInfo->execModel;
|
||||
pInfo->win = pTaskInfo->window;
|
||||
pInfo->twAggSup = *pTwAggSupp;
|
||||
pInfo->twAggSup = *pTwAggSupp;
|
||||
|
||||
pInfo->primaryTsIndex = primaryTsSlotId;
|
||||
|
||||
size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
|
||||
|
@ -1341,23 +1436,30 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->win);
|
||||
|
||||
pInfo->invertible = allInvertible(pInfo->binfo.pCtx, numOfCols);
|
||||
pInfo->invertible = false; // Todo(liuyao): Dependent TSDB API
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pInfo->timeWindowInterpo = timeWindowinterpNeeded(pInfo->binfo.pCtx, numOfCols, pInfo);
|
||||
if (pInfo->timeWindowInterpo) {
|
||||
pInfo->binfo.resultRowInfo.openWindow = tdListNew(sizeof(SResultRowPosition));
|
||||
}
|
||||
|
||||
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
|
||||
if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1);
|
||||
|
||||
pOperator->name = "TimeIntervalAggOperator";
|
||||
pOperator->name = "TimeIntervalAggOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
|
||||
pOperator->blocking = true;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->numOfExprs = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->blocking = true;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->numOfExprs = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doBuildIntervalResult, doStreamIntervalAgg, NULL,
|
||||
destroyIntervalOperatorInfo, aggEncodeResultRow, aggDecodeResultRow, NULL);
|
||||
|
@ -1816,7 +1918,7 @@ static SArray* doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataB
|
|||
bool ascScan = true;
|
||||
TSKEY* tsCols = NULL;
|
||||
SResultRow* pResult = NULL;
|
||||
int32_t forwardStep = 0;
|
||||
int32_t forwardRows = 0;
|
||||
|
||||
if (pSDataBlock->pDataBlock != NULL) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
|
@ -1826,7 +1928,7 @@ static SArray* doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataB
|
|||
}
|
||||
|
||||
int32_t startPos = ascScan ? 0 : (pSDataBlock->info.rows - 1);
|
||||
TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols, pSDataBlock->info.rows, ascScan);
|
||||
TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols);
|
||||
STimeWindow nextWin = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts,
|
||||
&pInfo->interval, pInfo->interval.precision, NULL);
|
||||
while (1) {
|
||||
|
@ -1841,15 +1943,15 @@ static SArray* doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataB
|
|||
pos->pos = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
|
||||
*(int64_t*)pos->key = pResult->win.skey;
|
||||
taosArrayPush(pUpdated, &pos);
|
||||
forwardStep =
|
||||
forwardRows =
|
||||
getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
|
||||
// window start(end) key interpolation
|
||||
doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &nextWin, startPos, forwardStep,
|
||||
pInfo->order, false);
|
||||
// disable it temporarily
|
||||
// doWindowBorderInterpolation(pInfo, pSDataBlock, numOfOutput, pInfo->binfo.pCtx, pResult, &nextWin, startPos, forwardRows);
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true);
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, tsCols,
|
||||
pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
int32_t prevEndPos = (forwardStep - 1) * step + startPos;
|
||||
int32_t prevEndPos = (forwardRows - 1) * step + startPos;
|
||||
startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, pInfo->order);
|
||||
if (startPos < 0) {
|
||||
break;
|
||||
|
@ -2165,7 +2267,7 @@ static int32_t setWindowOutputBuf(SResultWindowInfo* pWinInfo, SResultRow** pRes
|
|||
}
|
||||
|
||||
if (pWinInfo->pos.pageId == -1) {
|
||||
*pResult = getNewResultRow_rv(pAggSup->pResultBuf, groupId, pAggSup->resultRowSize);
|
||||
*pResult = getNewResultRow(pAggSup->pResultBuf, groupId, pAggSup->resultRowSize);
|
||||
if (*pResult == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -2300,7 +2402,7 @@ static void doStreamSessionWindowAggImpl(SOperatorInfo* pOperator,
|
|||
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
// window start(end) key interpolation
|
||||
// doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &nextWin, startPos, forwardStep,
|
||||
// doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &nextWin, startPos, forwardRows,
|
||||
// pInfo->order, false);
|
||||
int32_t winNum = getNumCompactWindow(pAggSup->pResultRows, winIndex, gap);
|
||||
if (winNum > 0) {
|
||||
|
@ -2497,7 +2599,7 @@ static SSDataBlock* doStreamSessionWindowAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
// restore the value
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
|
||||
|
||||
SArray* pClosed = taosArrayInit(16, POINTER_BYTES);
|
||||
closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pClosed,
|
||||
pInfo->twAggSup.calTrigger);
|
||||
|
|
|
@ -140,6 +140,10 @@ bool uniqueFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo)
|
|||
int32_t uniqueFunction(SqlFunctionCtx *pCtx);
|
||||
//int32_t uniqueFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
|
||||
bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
bool twaFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
int32_t twaFunction(SqlFunctionCtx *pCtx);
|
||||
int32_t twaFinalize(struct SqlFunctionCtx *pCtx, SSDataBlock* pBlock);
|
||||
|
||||
bool getSelectivityFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
|
||||
|
|
|
@ -52,13 +52,6 @@ typedef struct SInterpInfoDetail {
|
|||
int8_t primaryCol;
|
||||
} SInterpInfoDetail;
|
||||
|
||||
typedef struct STwaInfo {
|
||||
int8_t hasResult; // flag to denote has value
|
||||
double dOutput;
|
||||
SPoint1 p;
|
||||
STimeWindow win;
|
||||
} STwaInfo;
|
||||
|
||||
bool topbot_datablock_filter(SqlFunctionCtx *pCtx, const char *minval, const char *maxval);
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "querynodes.h"
|
||||
#include "scalar.h"
|
||||
#include "taoserror.h"
|
||||
#include "tdatablock.h"
|
||||
|
||||
static int32_t buildFuncErrMsg(char* pErrBuf, int32_t len, int32_t errCode, const char* pFormat, ...) {
|
||||
va_list vArgList;
|
||||
|
@ -362,7 +361,7 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -456,7 +455,7 @@ static int32_t translateHLL(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
"The input parameter of HYPERLOGLOG function can only be column");
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_UBIGINT].bytes, .type = TSDB_DATA_TYPE_UBIGINT};
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1312,6 +1311,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.finalizeFunc = firstLastFinalize,
|
||||
.combineFunc = lastCombine,
|
||||
},
|
||||
{
|
||||
.name = "twa",
|
||||
.type = FUNCTION_TYPE_TWA,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateInNumOutDou,
|
||||
.getEnvFunc = getTwaFuncEnv,
|
||||
.initFunc = twaFunctionSetup,
|
||||
.processFunc = twaFunction,
|
||||
.finalizeFunc = twaFinalize
|
||||
},
|
||||
{
|
||||
.name = "histogram",
|
||||
.type = FUNCTION_TYPE_HISTOGRAM,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include "builtinsimpl.h"
|
||||
#include "tglobal.h"
|
||||
#include "cJSON.h"
|
||||
#include "function.h"
|
||||
#include "querynodes.h"
|
||||
|
@ -300,7 +301,7 @@ int32_t functionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
//pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
||||
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
||||
|
||||
char* in = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
colDataAppend(pCol, pBlock->info.rows, in, pResInfo->isNullRes);
|
||||
|
@ -357,7 +358,7 @@ bool getCountFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t getNumofElem(SqlFunctionCtx* pCtx) {
|
||||
static FORCE_INLINE int32_t getNumOfElems(SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfElem = 0;
|
||||
|
||||
/*
|
||||
|
@ -392,11 +393,12 @@ static FORCE_INLINE int32_t getNumofElem(SqlFunctionCtx* pCtx) {
|
|||
* count function does not use the pCtx->interResBuf to keep the intermediate buffer
|
||||
*/
|
||||
int32_t countFunction(SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfElem = getNumofElem(pCtx);
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
int32_t numOfElem = getNumOfElems(pCtx);
|
||||
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
int32_t type = pInput->pData[0]->info.type;
|
||||
|
||||
int32_t type = pInput->pData[0]->info.type;
|
||||
|
||||
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
if (IS_NULL_TYPE(type)) {
|
||||
|
@ -407,12 +409,17 @@ int32_t countFunction(SqlFunctionCtx* pCtx) {
|
|||
*((int64_t*)buf) += numOfElem;
|
||||
}
|
||||
|
||||
SET_VAL(pResInfo, numOfElem, 1);
|
||||
if (tsCountAlwaysReturnValue) {
|
||||
pResInfo->numOfRes = 1;
|
||||
} else {
|
||||
SET_VAL(pResInfo, 1, 1);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t countInvertFunction(SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfElem = getNumofElem(pCtx);
|
||||
int32_t numOfElem = getNumOfElems(pCtx);
|
||||
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
@ -829,8 +836,10 @@ int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
|||
|
||||
int32_t avgFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
int32_t type = pInput->pData[0]->info.type;
|
||||
SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
||||
int32_t type = pInput->pData[0]->info.type;
|
||||
SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
||||
if (IS_INTEGER_TYPE(type)) {
|
||||
pAvgRes->result = pAvgRes->sum.isum / ((double)pAvgRes->count);
|
||||
} else {
|
||||
|
@ -1832,7 +1841,7 @@ bool percentileFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultI
|
|||
}
|
||||
|
||||
int32_t percentileFunction(SqlFunctionCtx* pCtx) {
|
||||
int32_t notNullElems = 0;
|
||||
int32_t numOfElems = 0;
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
|
@ -1910,11 +1919,11 @@ int32_t percentileFunction(SqlFunctionCtx* pCtx) {
|
|||
}
|
||||
|
||||
char* data = colDataGetData(pCol, i);
|
||||
notNullElems += 1;
|
||||
numOfElems += 1;
|
||||
tMemBucketPut(pInfo->pMemBucket, data, 1);
|
||||
}
|
||||
|
||||
SET_VAL(pResInfo, notNullElems, 1);
|
||||
SET_VAL(pResInfo, numOfElems, 1);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -1988,7 +1997,7 @@ bool apercentileFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResult
|
|||
}
|
||||
|
||||
int32_t apercentileFunction(SqlFunctionCtx* pCtx) {
|
||||
int32_t notNullElems = 0;
|
||||
int32_t numOfElems = 0;
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
|
@ -2005,7 +2014,7 @@ int32_t apercentileFunction(SqlFunctionCtx* pCtx) {
|
|||
if (colDataIsNull_f(pCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
notNullElems += 1;
|
||||
numOfElems += 1;
|
||||
char* data = colDataGetData(pCol, i);
|
||||
|
||||
double v = 0; // value
|
||||
|
@ -2018,7 +2027,7 @@ int32_t apercentileFunction(SqlFunctionCtx* pCtx) {
|
|||
if (colDataIsNull_f(pCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
notNullElems += 1;
|
||||
numOfElems += 1;
|
||||
char* data = colDataGetData(pCol, i);
|
||||
|
||||
double v = 0;
|
||||
|
@ -2027,7 +2036,7 @@ int32_t apercentileFunction(SqlFunctionCtx* pCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
SET_VAL(pResInfo, notNullElems, 1);
|
||||
SET_VAL(pResInfo, numOfElems, 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3240,13 +3249,13 @@ static uint64_t hllCountCnt(uint8_t *buckets) {
|
|||
z += buckethisto[j];
|
||||
z *= 0.5;
|
||||
}
|
||||
|
||||
z += m * hllSigma(buckethisto[0]/(double)m);
|
||||
double E = (double)llroundl(HLL_ALPHA_INF*m*m/z);
|
||||
|
||||
return (uint64_t) E;
|
||||
}
|
||||
|
||||
|
||||
int32_t hllFunction(SqlFunctionCtx *pCtx) {
|
||||
SHLLInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
||||
|
@ -3279,7 +3288,6 @@ int32_t hllFunction(SqlFunctionCtx *pCtx) {
|
|||
if (count > oldcount) {
|
||||
pInfo->buckets[index] = count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
||||
|
@ -3287,9 +3295,13 @@ int32_t hllFunction(SqlFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
int32_t hllFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SHLLInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
SResultRowEntryInfo *pInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
pInfo->result = hllCountCnt(pInfo->buckets);
|
||||
SHLLInfo* pHllInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
pHllInfo->result = hllCountCnt(pHllInfo->buckets);
|
||||
if (tsCountAlwaysReturnValue && pHllInfo->result == 0) {
|
||||
pInfo->numOfRes = 1;
|
||||
}
|
||||
|
||||
return functionFinalize(pCtx, pBlock);
|
||||
}
|
||||
|
@ -3695,7 +3707,6 @@ int32_t sampleFunction(SqlFunctionCtx* pCtx) {
|
|||
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
||||
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
SColumnInfoData* pTsOutput = pCtx->pTsOutput;
|
||||
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
||||
|
||||
int32_t startOffset = pCtx->offset;
|
||||
|
@ -3718,24 +3729,6 @@ int32_t sampleFunction(SqlFunctionCtx* pCtx) {
|
|||
return pInfo->numSampled;
|
||||
}
|
||||
|
||||
//int32_t sampleFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
// SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
// SSampleInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
// int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||
// SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
//
|
||||
// //int32_t currentRow = pBlock->info.rows;
|
||||
// pResInfo->numOfRes = pInfo->numSampled;
|
||||
//
|
||||
// for (int32_t i = 0; i < pInfo->numSampled; ++i) {
|
||||
// colDataAppend(pCol, i, pInfo->data + i * pInfo->colBytes, false);
|
||||
// //TODO: handle ts output
|
||||
// }
|
||||
//
|
||||
// return pResInfo->numOfRes;
|
||||
//}
|
||||
|
||||
|
||||
bool getTailFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||
SColumnNode* pCol = (SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1);
|
||||
|
@ -3812,7 +3805,6 @@ int32_t tailFunction(SqlFunctionCtx* pCtx) {
|
|||
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
||||
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
SColumnInfoData* pTsOutput = pCtx->pTsOutput;
|
||||
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
||||
|
||||
int32_t startOffset = pCtx->offset;
|
||||
|
@ -3879,7 +3871,6 @@ bool uniqueFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo) {
|
|||
pInfo->numOfPoints = 0;
|
||||
pInfo->colType = pCtx->resDataInfo.type;
|
||||
pInfo->colBytes = pCtx->resDataInfo.bytes;
|
||||
pInfo->hasNull = false;
|
||||
if (pInfo->pHash != NULL) {
|
||||
taosHashClear(pInfo->pHash);
|
||||
} else {
|
||||
|
@ -3917,8 +3908,6 @@ static void doUniqueAdd(SUniqueInfo* pInfo, char *data, TSKEY ts, bool isNull) {
|
|||
} else if (pHashItem->timestamp > ts) {
|
||||
pHashItem->timestamp = ts;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t uniqueFunction(SqlFunctionCtx* pCtx) {
|
||||
|
@ -3960,7 +3949,7 @@ int32_t uniqueFunction(SqlFunctionCtx* pCtx) {
|
|||
|
||||
int32_t uniqueFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SUniqueInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
SUniqueInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
|
@ -3973,3 +3962,260 @@ int32_t uniqueFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return pResInfo->numOfRes;
|
||||
}
|
||||
|
||||
typedef struct STwaInfo {
|
||||
double dOutput;
|
||||
SPoint1 p;
|
||||
STimeWindow win;
|
||||
} STwaInfo;
|
||||
|
||||
bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||
pEnv->calcMemSize = sizeof(STwaInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool twaFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||
if (!functionSetup(pCtx, pResultInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
pInfo->p.key = INT64_MIN;
|
||||
pInfo->win = TSWINDOW_INITIALIZER;
|
||||
return true;
|
||||
}
|
||||
|
||||
static double twa_get_area(SPoint1 s, SPoint1 e) {
|
||||
if ((s.val >= 0 && e.val >= 0)|| (s.val <=0 && e.val <= 0)) {
|
||||
return (s.val + e.val) * (e.key - s.key) / 2;
|
||||
}
|
||||
|
||||
double x = (s.key * e.val - e.key * s.val)/(e.val - s.val);
|
||||
double val = (s.val * (x - s.key) + e.val * (e.key - x)) / 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
#define INIT_INTP_POINT(_p, _k, _v) \
|
||||
do { \
|
||||
(_p).key = (_k); \
|
||||
(_p).val = (_v); \
|
||||
} while (0)
|
||||
|
||||
int32_t twaFunction(SqlFunctionCtx* pCtx) {
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
|
||||
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
||||
|
||||
SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
SPoint1 *last = &pInfo->p;
|
||||
int32_t numOfElems = 0;
|
||||
|
||||
int32_t i = pInput->startRowIndex;
|
||||
if (pCtx->start.key != INT64_MIN) {
|
||||
ASSERT((pCtx->start.key < tsList[i] && pCtx->order == TSDB_ORDER_ASC) ||
|
||||
(pCtx->start.key > tsList[i] && pCtx->order == TSDB_ORDER_DESC));
|
||||
|
||||
ASSERT(last->key == INT64_MIN);
|
||||
last->key = tsList[i];
|
||||
|
||||
GET_TYPED_DATA(last->val, double, pInputCol->info.type, colDataGetData(pInputCol, i));
|
||||
|
||||
pInfo->dOutput += twa_get_area(pCtx->start, *last);
|
||||
pInfo->win.skey = pCtx->start.key;
|
||||
numOfElems++;
|
||||
i += 1;
|
||||
} else if (pInfo->p.key == INT64_MIN) {
|
||||
last->key = tsList[i];
|
||||
GET_TYPED_DATA(last->val, double, pInputCol->info.type, colDataGetData(pInputCol, i));
|
||||
|
||||
pInfo->win.skey = last->key;
|
||||
numOfElems++;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
SPoint1 st = {0};
|
||||
|
||||
// calculate the value of
|
||||
switch(pInputCol->info.type) {
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t *val = (int8_t*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t *val = (int16_t*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t *val = (int32_t*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t *val = (int64_t*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float *val = (float*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double *val = (double*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
uint8_t *val = (uint8_t*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_USMALLINT: {
|
||||
uint16_t *val = (uint16_t*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
uint32_t *val = (uint32_t*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
uint64_t *val = (uint64_t*) colDataGetData(pInputCol, 0);
|
||||
for (; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_INTP_POINT(st, tsList[i], val[i]);
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, st);
|
||||
pInfo->p = st;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: ASSERT(0);
|
||||
}
|
||||
|
||||
// the last interpolated time window value
|
||||
if (pCtx->end.key != INT64_MIN) {
|
||||
pInfo->dOutput += twa_get_area(pInfo->p, pCtx->end);
|
||||
pInfo->p = pCtx->end;
|
||||
}
|
||||
|
||||
pInfo->win.ekey = pInfo->p.key;
|
||||
|
||||
SET_VAL(pResInfo, numOfElems, 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* To copy the input to interResBuf to avoid the input buffer space be over writen
|
||||
* by next input data. The TWA function only applies to each table, so no merge procedure
|
||||
* is required, we simply copy to the resut ot interResBuffer.
|
||||
*/
|
||||
//void twa_function_copy(SQLFunctionCtx *pCtx) {
|
||||
// assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
|
||||
// SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
//
|
||||
// memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes);
|
||||
// pResInfo->hasResult = ((STwaInfo *)pCtx->pInput)->hasResult;
|
||||
//}
|
||||
|
||||
int32_t twaFinalize(struct SqlFunctionCtx *pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = (STwaInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
if (pResInfo->numOfRes == 0) {
|
||||
pResInfo->isNullRes = 1;
|
||||
} else {
|
||||
// assert(pInfo->win.ekey == pInfo->p.key && pInfo->hasResult == pResInfo->hasResult);
|
||||
if (pInfo->win.ekey == pInfo->win.skey) {
|
||||
pInfo->dOutput = pInfo->p.val;
|
||||
} else {
|
||||
pInfo->dOutput = pInfo->dOutput / (pInfo->win.ekey - pInfo->win.skey);
|
||||
}
|
||||
|
||||
pResInfo->numOfRes = 1;
|
||||
}
|
||||
|
||||
return functionFinalize(pCtx, pBlock);
|
||||
}
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry) {
|
|||
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry) {
|
||||
return pEntry->initialized;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
|
||||
bool isSuperTable/*, SUdfInfo* pUdfInfo*/) {
|
||||
if (!isValidDataType(dataType)) {
|
||||
|
@ -470,6 +470,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool function_setup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||
if (pResultInfo->initialized) {
|
||||
|
|
|
@ -36,12 +36,7 @@ void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) {
|
|||
|
||||
if (pNode->nodeType == TEXPR_BINARYEXPR_NODE || pNode->nodeType == TEXPR_UNARYEXPR_NODE) {
|
||||
doExprTreeDestroy(&pNode, fp);
|
||||
} else if (pNode->nodeType == TEXPR_VALUE_NODE) {
|
||||
taosVariantDestroy(pNode->pVal);
|
||||
} else if (pNode->nodeType == TEXPR_COL_NODE) {
|
||||
taosMemoryFreeClear(pNode->pSchema);
|
||||
}
|
||||
|
||||
taosMemoryFree(pNode);
|
||||
}
|
||||
|
||||
|
@ -49,15 +44,6 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
|
|||
if (*pExpr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t type = (*pExpr)->nodeType;
|
||||
if (type == TEXPR_VALUE_NODE) {
|
||||
taosVariantDestroy((*pExpr)->pVal);
|
||||
taosMemoryFree((*pExpr)->pVal);
|
||||
} else if (type == TEXPR_COL_NODE) {
|
||||
taosMemoryFree((*pExpr)->pSchema);
|
||||
}
|
||||
|
||||
taosMemoryFree(*pExpr);
|
||||
*pExpr = NULL;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ int32_t authenticate(SParseContext* pParseCxt, SQuery* pQuery);
|
|||
int32_t translate(SParseContext* pParseCxt, SQuery* pQuery);
|
||||
int32_t extractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema);
|
||||
int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery);
|
||||
int32_t isNotSchemalessDb(SParseContext* pContext, char *dbName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ typedef struct SInsertParseContext {
|
|||
SHashObj* pSubTableHashObj; // global
|
||||
SArray* pVgDataBlocks; // global
|
||||
SHashObj* pTableNameHashObj; // global
|
||||
SHashObj* pDbFNameHashObj; // global
|
||||
int32_t totalNum;
|
||||
SVnodeModifOpStmt* pOutput;
|
||||
SStmtCallback* pStmtCb;
|
||||
|
@ -1153,6 +1154,10 @@ static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (TK_NK_RP == sToken.type) {
|
||||
return generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
|
||||
}
|
||||
|
||||
if (isParseBindParam) {
|
||||
return buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and values");
|
||||
}
|
||||
|
@ -1271,6 +1276,7 @@ static void destroyInsertParseContext(SInsertParseContext* pCxt) {
|
|||
taosHashCleanup(pCxt->pVgroupsHashObj);
|
||||
taosHashCleanup(pCxt->pSubTableHashObj);
|
||||
taosHashCleanup(pCxt->pTableNameHashObj);
|
||||
taosHashCleanup(pCxt->pDbFNameHashObj);
|
||||
|
||||
destroyBlockHashmap(pCxt->pTableBlockHashObj);
|
||||
destroyBlockArrayList(pCxt->pVgDataBlocks);
|
||||
|
@ -1329,8 +1335,13 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|||
SName name;
|
||||
CHECK_CODE(createSName(&name, &tbnameToken, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg));
|
||||
|
||||
CHECK_CODE(isNotSchemalessDb(pCxt->pComCxt, name.dbname));
|
||||
|
||||
tNameExtractFullName(&name, tbFName);
|
||||
CHECK_CODE(taosHashPut(pCxt->pTableNameHashObj, tbFName, strlen(tbFName), &name, sizeof(SName)));
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
tNameGetFullDbName(&name, dbFName);
|
||||
CHECK_CODE(taosHashPut(pCxt->pDbFNameHashObj, dbFName, strlen(dbFName), dbFName, sizeof(dbFName)));
|
||||
|
||||
// USING clause
|
||||
if (TK_USING == sToken.type) {
|
||||
|
@ -1338,8 +1349,6 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
autoCreateTbl = true;
|
||||
} else {
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
tNameGetFullDbName(&name, dbFName);
|
||||
CHECK_CODE(getTableMeta(pCxt, &name, dbFName));
|
||||
}
|
||||
|
||||
|
@ -1404,6 +1413,23 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|||
return buildOutput(pCxt);
|
||||
}
|
||||
|
||||
int32_t isNotSchemalessDb(SParseContext* pContext, char *dbName){
|
||||
SName name;
|
||||
tNameSetDbName(&name, pContext->acctId, dbName, strlen(dbName));
|
||||
char dbFname[TSDB_DB_FNAME_LEN] = {0};
|
||||
tNameGetFullDbName(&name, dbFname);
|
||||
SDbCfgInfo pInfo = {0};
|
||||
int32_t code = catalogGetDBCfg(pContext->pCatalog, pContext->pTransporter, &pContext->mgmtEpSet, dbFname, &pInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
parserError("catalogGetDBCfg error, code:%s, dbFName:%s", tstrerror(code), dbFname);
|
||||
return code;
|
||||
}
|
||||
if (pInfo.schemaless){
|
||||
parserError("can not insert into schemaless db:%s", dbFname);
|
||||
return TSDB_CODE_SML_INVALID_DB_CONF;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
// INSERT INTO
|
||||
// tb_name
|
||||
// [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)]
|
||||
|
@ -1418,6 +1444,7 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|||
.pTableMeta = NULL,
|
||||
.pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK),
|
||||
.pTableNameHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK),
|
||||
.pDbFNameHashObj = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK),
|
||||
.totalNum = 0,
|
||||
.pOutput = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT),
|
||||
.pStmtCb = pContext->pStmtCb};
|
||||
|
@ -1432,7 +1459,7 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|||
}
|
||||
|
||||
if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj || NULL == context.pSubTableHashObj ||
|
||||
NULL == context.pTableNameHashObj || NULL == context.pOutput) {
|
||||
NULL == context.pTableNameHashObj || NULL == context.pDbFNameHashObj || NULL == context.pOutput) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -1458,6 +1485,13 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|||
}
|
||||
}
|
||||
|
||||
if (NULL == (*pQuery)->pDbList) {
|
||||
(*pQuery)->pDbList = taosArrayInit(taosHashGetSize(context.pDbFNameHashObj), TSDB_DB_FNAME_LEN);
|
||||
if (NULL == (*pQuery)->pDbList) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
context.pOutput->payloadType = PAYLOAD_TYPE_KV;
|
||||
|
||||
int32_t code = skipInsertInto(&context.pSql, &context.msg);
|
||||
|
@ -1470,6 +1504,12 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|||
taosArrayPush((*pQuery)->pTableList, pTable);
|
||||
pTable = taosHashIterate(context.pTableNameHashObj, pTable);
|
||||
}
|
||||
|
||||
char* pDb = taosHashIterate(context.pDbFNameHashObj, NULL);
|
||||
while (NULL != pDb) {
|
||||
taosArrayPush((*pQuery)->pDbList, pDb);
|
||||
pDb = taosHashIterate(context.pDbFNameHashObj, pDb);
|
||||
}
|
||||
}
|
||||
destroyInsertParseContext(&context);
|
||||
return code;
|
||||
|
|
|
@ -2646,6 +2646,11 @@ static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkTableSchema(pCxt, pStmt);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if(pCxt->pParseCxt->schemalessType == 0){
|
||||
code = isNotSchemalessDb(pCxt->pParseCxt, pStmt->dbName);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -4424,6 +4429,7 @@ static SArray* serializeVgroupsCreateTableBatch(int32_t acctId, SHashObj* pVgrou
|
|||
}
|
||||
|
||||
static int32_t rewriteCreateMultiTable(STranslateContext* pCxt, SQuery* pQuery) {
|
||||
|
||||
SCreateMultiTableStmt* pStmt = (SCreateMultiTableStmt*)pQuery->pRoot;
|
||||
|
||||
SHashObj* pVgroupHashmap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||
|
@ -4434,6 +4440,10 @@ static int32_t rewriteCreateMultiTable(STranslateContext* pCxt, SQuery* pQuery)
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pStmt->pSubTables) {
|
||||
if(pCxt->pParseCxt->schemalessType == 0 &&
|
||||
(code = isNotSchemalessDb(pCxt->pParseCxt, ((SCreateSubTableClause*)pNode)->dbName)) != TSDB_CODE_SUCCESS){
|
||||
return code;
|
||||
}
|
||||
code = rewriteCreateSubTable(pCxt, (SCreateSubTableClause*)pNode, pVgroupHashmap);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
taosHashCleanup(pVgroupHashmap);
|
||||
|
@ -4845,9 +4855,14 @@ static int32_t buildModifyVnodeArray(STranslateContext* pCxt, SAlterTableStmt* p
|
|||
|
||||
static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) {
|
||||
SAlterTableStmt* pStmt = (SAlterTableStmt*)pQuery->pRoot;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if(pCxt->pParseCxt->schemalessType == 0 &&
|
||||
(code = isNotSchemalessDb(pCxt->pParseCxt, pStmt->dbName)) != TSDB_CODE_SUCCESS){
|
||||
return code;
|
||||
}
|
||||
|
||||
STableMeta* pTableMeta = NULL;
|
||||
int32_t code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta);
|
||||
code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
|
@ -4936,6 +4951,47 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t toMsgType(ENodeType type) {
|
||||
switch (type) {
|
||||
case QUERY_NODE_CREATE_TABLE_STMT:
|
||||
return TDMT_VND_CREATE_TABLE;
|
||||
case QUERY_NODE_ALTER_TABLE_STMT:
|
||||
return TDMT_VND_ALTER_TABLE;
|
||||
case QUERY_NODE_DROP_TABLE_STMT:
|
||||
return TDMT_VND_DROP_TABLE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TDMT_VND_CREATE_TABLE;
|
||||
}
|
||||
|
||||
static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery) {
|
||||
if (NULL != pCxt->pDbs) {
|
||||
pQuery->pDbList = taosArrayInit(taosHashGetSize(pCxt->pDbs), TSDB_DB_FNAME_LEN);
|
||||
if (NULL == pQuery->pDbList) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
SFullDatabaseName* pDb = taosHashIterate(pCxt->pDbs, NULL);
|
||||
while (NULL != pDb) {
|
||||
taosArrayPush(pQuery->pDbList, pDb->fullDbName);
|
||||
pDb = taosHashIterate(pCxt->pDbs, pDb);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != pCxt->pTables) {
|
||||
pQuery->pTableList = taosArrayInit(taosHashGetSize(pCxt->pTables), sizeof(SName));
|
||||
if (NULL == pQuery->pTableList) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
SName* pTable = taosHashIterate(pCxt->pTables, NULL);
|
||||
while (NULL != pTable) {
|
||||
taosArrayPush(pQuery->pTableList, pTable);
|
||||
pTable = taosHashIterate(pCxt->pTables, pTable);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
||||
switch (nodeType(pQuery->pRoot)) {
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
|
@ -4947,7 +5003,7 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
|||
break;
|
||||
case QUERY_NODE_VNODE_MODIF_STMT:
|
||||
pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE;
|
||||
pQuery->msgType = TDMT_VND_CREATE_TABLE;
|
||||
pQuery->msgType = toMsgType(((SVnodeModifOpStmt*)pQuery->pRoot)->sqlNodeType);
|
||||
break;
|
||||
case QUERY_NODE_DESCRIBE_STMT:
|
||||
pQuery->execMode = QUERY_EXEC_MODE_LOCAL;
|
||||
|
@ -4975,30 +5031,6 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
|||
}
|
||||
}
|
||||
|
||||
if (NULL != pCxt->pDbs) {
|
||||
pQuery->pDbList = taosArrayInit(taosHashGetSize(pCxt->pDbs), TSDB_DB_FNAME_LEN);
|
||||
if (NULL == pQuery->pDbList) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
SFullDatabaseName* pDb = taosHashIterate(pCxt->pDbs, NULL);
|
||||
while (NULL != pDb) {
|
||||
taosArrayPush(pQuery->pDbList, pDb->fullDbName);
|
||||
pDb = taosHashIterate(pCxt->pDbs, pDb);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != pCxt->pTables) {
|
||||
pQuery->pTableList = taosArrayInit(taosHashGetSize(pCxt->pTables), sizeof(SName));
|
||||
if (NULL == pQuery->pTableList) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
SName* pTable = taosHashIterate(pCxt->pTables, NULL);
|
||||
while (NULL != pTable) {
|
||||
taosArrayPush(pQuery->pTableList, pTable);
|
||||
pTable = taosHashIterate(pCxt->pTables, pTable);
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -5018,6 +5050,7 @@ int32_t translate(SParseContext* pParseCxt, SQuery* pQuery) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = setQuery(&cxt, pQuery);
|
||||
}
|
||||
setRefreshMate(&cxt, pQuery);
|
||||
destroyTranslateContext(&cxt);
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -199,3 +199,30 @@ SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* nam
|
|||
tstrncpy(s.name, name, tListLen(s.name));
|
||||
return s;
|
||||
}
|
||||
|
||||
void destroyQueryExecRes(SQueryExecRes* pRes) {
|
||||
if (NULL == pRes || NULL == pRes->res) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (pRes->msgType) {
|
||||
case TDMT_VND_ALTER_TABLE:
|
||||
case TDMT_MND_ALTER_STB: {
|
||||
tFreeSTableMetaRsp((STableMetaRsp *)pRes->res);
|
||||
taosMemoryFreeClear(pRes->res);
|
||||
break;
|
||||
}
|
||||
case TDMT_VND_SUBMIT: {
|
||||
tFreeSSubmitRsp((SSubmitRsp*)pRes->res);
|
||||
break;
|
||||
}
|
||||
case TDMT_VND_QUERY: {
|
||||
taosArrayDestroy((SArray*)pRes->res);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qError("invalid exec result for request type %d", pRes->msgType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -273,7 +273,7 @@ static int32_t queryConvertTableMetaMsg(STableMetaRsp *pMetaMsg) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t queryCreateTableMetaFromMsg(STableMetaRsp *msg, bool isSuperTable, STableMeta **pMeta) {
|
||||
int32_t queryCreateTableMetaFromMsg(STableMetaRsp *msg, bool isStb, STableMeta **pMeta) {
|
||||
int32_t total = msg->numOfColumns + msg->numOfTags;
|
||||
int32_t metaSize = sizeof(STableMeta) + sizeof(SSchema) * total;
|
||||
|
||||
|
@ -283,14 +283,14 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp *msg, bool isSuperTable, STabl
|
|||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pTableMeta->vgId = isSuperTable ? 0 : msg->vgId;
|
||||
pTableMeta->tableType = isSuperTable ? TSDB_SUPER_TABLE : msg->tableType;
|
||||
pTableMeta->uid = isSuperTable ? msg->suid : msg->tuid;
|
||||
pTableMeta->vgId = isStb ? 0 : msg->vgId;
|
||||
pTableMeta->tableType = isStb ? TSDB_SUPER_TABLE : msg->tableType;
|
||||
pTableMeta->uid = isStb ? msg->suid : msg->tuid;
|
||||
pTableMeta->suid = msg->suid;
|
||||
pTableMeta->sversion = msg->sversion;
|
||||
pTableMeta->tversion = msg->tversion;
|
||||
|
||||
if (isSuperTable) {
|
||||
if (isStb) {
|
||||
qDebug("stable %s meta returned, suid:%" PRIx64, msg->stbName, pTableMeta->suid);
|
||||
}
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ typedef struct SSchJob {
|
|||
SSchTask *fetchTask;
|
||||
int32_t errCode;
|
||||
SRWLatch resLock;
|
||||
void *queryRes;
|
||||
SQueryExecRes execRes;
|
||||
void *resData; //TODO free it or not
|
||||
int32_t resNumOfRows;
|
||||
SSchResInfo userRes;
|
||||
|
|
|
@ -773,8 +773,8 @@ _return:
|
|||
int32_t schSetJobQueryRes(SSchJob* pJob, SQueryResult* pRes) {
|
||||
pRes->code = atomic_load_32(&pJob->errCode);
|
||||
pRes->numOfRows = pJob->resNumOfRows;
|
||||
pRes->res = pJob->queryRes;
|
||||
pJob->queryRes = NULL;
|
||||
pRes->res = pJob->execRes;
|
||||
pJob->execRes.res = NULL;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1107,9 +1107,9 @@ int32_t schProcessOnExplainDone(SSchJob *pJob, SSchTask *pTask, SRetrieveTableRs
|
|||
|
||||
int32_t schSaveJobQueryRes(SSchJob *pJob, SQueryTableRsp *rsp) {
|
||||
if (rsp->tbFName[0]) {
|
||||
if (NULL == pJob->queryRes) {
|
||||
pJob->queryRes = taosArrayInit(pJob->taskNum, sizeof(STbVerInfo));
|
||||
if (NULL == pJob->queryRes) {
|
||||
if (NULL == pJob->execRes.res) {
|
||||
pJob->execRes.res = taosArrayInit(pJob->taskNum, sizeof(STbVerInfo));
|
||||
if (NULL == pJob->execRes.res) {
|
||||
SCH_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
@ -1119,7 +1119,8 @@ int32_t schSaveJobQueryRes(SSchJob *pJob, SQueryTableRsp *rsp) {
|
|||
tbInfo.sversion = rsp->sversion;
|
||||
tbInfo.tversion = rsp->tversion;
|
||||
|
||||
taosArrayPush((SArray *)pJob->queryRes, &tbInfo);
|
||||
taosArrayPush((SArray *)pJob->execRes.res, &tbInfo);
|
||||
pJob->execRes.msgType = TDMT_VND_QUERY;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -1349,11 +1350,7 @@ void schFreeJobImpl(void *job) {
|
|||
|
||||
qExplainFreeCtx(pJob->explainCtx);
|
||||
|
||||
if (SCH_IS_QUERY_JOB(pJob)) {
|
||||
taosArrayDestroy((SArray *)pJob->queryRes);
|
||||
} else {
|
||||
tFreeSSubmitRsp((SSubmitRsp*)pJob->queryRes);
|
||||
}
|
||||
destroyQueryExecRes(&pJob->execRes);
|
||||
|
||||
taosMemoryFreeClear(pJob->userRes.queryRes);
|
||||
taosMemoryFreeClear(pJob->resData);
|
||||
|
|
|
@ -162,6 +162,9 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
tDecoderClear(&coder);
|
||||
SCH_ERR_JRET(code);
|
||||
SCH_ERR_JRET(rsp.code);
|
||||
|
||||
pJob->execRes.res = rsp.pMeta;
|
||||
pJob->execRes.msgType = TDMT_VND_ALTER_TABLE;
|
||||
}
|
||||
|
||||
SCH_ERR_JRET(rspCode);
|
||||
|
@ -204,8 +207,8 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
SCH_TASK_DLOG("submit succeed, affectedRows:%d", rsp->affectedRows);
|
||||
|
||||
SCH_LOCK(SCH_WRITE, &pJob->resLock);
|
||||
if (pJob->queryRes) {
|
||||
SSubmitRsp *sum = pJob->queryRes;
|
||||
if (pJob->execRes.res) {
|
||||
SSubmitRsp *sum = pJob->execRes.res;
|
||||
sum->affectedRows += rsp->affectedRows;
|
||||
sum->nBlocks += rsp->nBlocks;
|
||||
sum->pBlocks = taosMemoryRealloc(sum->pBlocks, sum->nBlocks * sizeof(*sum->pBlocks));
|
||||
|
@ -213,7 +216,8 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
taosMemoryFree(rsp->pBlocks);
|
||||
taosMemoryFree(rsp);
|
||||
} else {
|
||||
pJob->queryRes = rsp;
|
||||
pJob->execRes.res = rsp;
|
||||
pJob->execRes.msgType = TDMT_VND_SUBMIT;
|
||||
}
|
||||
SCH_UNLOCK(SCH_WRITE, &pJob->resLock);
|
||||
}
|
||||
|
|
|
@ -470,6 +470,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_OUTPUT_TYPE, "udf invalid output ty
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_SML_INVALID_PROTOCOL_TYPE, "Invalid line protocol type")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SML_INVALID_PRECISION_TYPE, "Invalid timestamp precision type")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SML_INVALID_DATA, "Invalid data type")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SML_INVALID_DB_CONF, "Invalid schemaless db config")
|
||||
|
||||
#ifdef TAOS_ERROR_C
|
||||
};
|
||||
|
|
|
@ -95,7 +95,7 @@ SListNode *tdListPopTail(SList *list) {
|
|||
|
||||
SListNode *tdListGetHead(SList *list) { return TD_DLIST_HEAD(list); }
|
||||
|
||||
SListNode *tsListGetTail(SList *list) { return TD_DLIST_TAIL(list); }
|
||||
SListNode *tdListGetTail(SList *list) { return TD_DLIST_TAIL(list); }
|
||||
|
||||
SListNode *tdListPopNode(SList *list, SListNode *node) {
|
||||
TD_DLIST_POP(list, node);
|
||||
|
|
|
@ -136,4 +136,7 @@
|
|||
./test.sh -f tsim/sync/oneReplica1VgElect.sim
|
||||
./test.sh -f tsim/sync/oneReplica5VgElect.sim
|
||||
|
||||
# --- catalog
|
||||
./test.sh -f tsim/catalog/alterInCurrent.sim
|
||||
|
||||
#======================b1-end===============
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
|
||||
print ========= start dnode1 as LEADER
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sql connect
|
||||
|
||||
print ======== drop column in normal table
|
||||
sql drop database if exists db1;
|
||||
sql create database db1;
|
||||
sql use db1;
|
||||
sql create table t1 (ts timestamp, f1 int, f2 int);
|
||||
sql insert into t1 values (1591060628000, 1, 2);
|
||||
sql alter table t1 drop column f2;
|
||||
sql insert into t1 values (1591060628001, 2);
|
||||
|
||||
print ======== add column in normal table
|
||||
sql drop database db1;
|
||||
sql create database db1;
|
||||
sql use db1;
|
||||
sql create table t1 (ts timestamp, f1 int);
|
||||
sql insert into t1 values (1591060628000, 1);
|
||||
sql alter table t1 add column f2 int;
|
||||
sql insert into t1 values (1591060628001, 2, 2);
|
||||
|
||||
|
||||
print ======== drop column in super table
|
||||
sql drop database db1;
|
||||
sql create database db1;
|
||||
sql use db1;
|
||||
sql create stable st1 (ts timestamp, f1 int, f2 int) tags (t1 int);
|
||||
sql create table t1 using st1 tags(1);
|
||||
sql insert into t1 values (1591060628000, 1, 2);
|
||||
sql alter table st1 drop column f2;
|
||||
sql insert into t1 values (1591060628001, 2);
|
||||
|
||||
|
||||
print ======== add column in super table
|
||||
sql drop database db1;
|
||||
sql create database db1;
|
||||
sql use db1;
|
||||
sql create stable st1 (ts timestamp, f1 int) tags (t1 int);
|
||||
sql create table t1 using st1 tags(1);
|
||||
sql insert into t1 values (1591060628000, 1);
|
||||
sql alter table st1 add column f2 int;
|
||||
sql insert into t1 values (1591060628001, 2, 2);
|
||||
|
||||
|
||||
print ======== add tag in super table
|
||||
sql drop database db1;
|
||||
sql create database db1;
|
||||
sql use db1;
|
||||
sql create stable st1 (ts timestamp, f1 int) tags (t1 int);
|
||||
sql create table t1 using st1 tags(1);
|
||||
sql insert into t1 values (1591060628000, 1);
|
||||
sql alter table st1 add tag t2 int;
|
||||
sql create table t2 using st1 tags(2, 2);
|
||||
|
||||
|
||||
print ======== drop tag in super table
|
||||
sql drop database db1;
|
||||
sql create database db1;
|
||||
sql use db1;
|
||||
sql create stable st1 (ts timestamp, f1 int) tags (t1 int, t2 int);
|
||||
sql create table t1 using st1 tags(1, 1);
|
||||
sql insert into t1 values (1591060628000, 1);
|
||||
sql alter table st1 drop tag t2;
|
||||
sql create table t2 using st1 tags(2);
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|
@ -129,7 +129,8 @@ endi
|
|||
|
||||
print ========== step2 drop column c5
|
||||
sql alter table db.stb drop column c5
|
||||
sql insert into db.ctb values(now+2s, 1, 2, 3, 4, 5)
|
||||
sql_error insert into db.ctb values(now+2s, 1, 2, 3, 4, 5)
|
||||
sql insert into db.ctb values(now+2s, 1, 2, 3, 4)
|
||||
sql insert into db.ctb values(now+3s, 1, 2, 3, 4)
|
||||
sql_error insert into db.ctb values(now+2s, 1, 2, 3, 4, 5)
|
||||
|
||||
|
@ -206,4 +207,4 @@ if $data[7][0] != t3 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
|
|
@ -63,7 +63,8 @@ if $data02 != 234 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 234 then
|
||||
if $data03 != 234 then
|
||||
print expect 234, actual $data03
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -33,10 +33,10 @@ class TDTestCase:
|
|||
def createDb(self, name="test", db_update_tag=0):
|
||||
if db_update_tag == 0:
|
||||
tdSql.execute(f"drop database if exists {name}")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ms'")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ms' schemaless 1")
|
||||
else:
|
||||
tdSql.execute(f"drop database if exists {name}")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ms' update 1")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ms' update 1 schemaless 1")
|
||||
tdSql.execute(f'use {name}')
|
||||
|
||||
def timeTrans(self, time_value, ts_type):
|
||||
|
|
|
@ -36,10 +36,10 @@ class TDTestCase:
|
|||
|
||||
if db_update_tag == 0:
|
||||
tdSql.execute(f"drop database if exists {name}")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ms'")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ms' schemaless 1")
|
||||
else:
|
||||
tdSql.execute(f"drop database if exists {name}")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ms' update 1")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ms' update 1 schemaless 1")
|
||||
tdSql.execute(f'use {name}')
|
||||
|
||||
def timeTrans(self, time_value):
|
||||
|
@ -535,7 +535,7 @@ class TDTestCase:
|
|||
# check result
|
||||
#! bug
|
||||
tdSql.execute(f"drop database if exists test_ts")
|
||||
tdSql.execute(f"create database if not exists test_ts precision 'ms'")
|
||||
tdSql.execute(f"create database if not exists test_ts precision 'ms' schemaless 1")
|
||||
tdSql.execute("use test_ts")
|
||||
input_json = [{"metric": "test_ms", "timestamp": {"value": 1626006833640, "type": "ms"}, "value": True, "tags": {"t0": True}},
|
||||
{"metric": "test_ms", "timestamp": {"value": 1626006833641, "type": "ms"}, "value": False, "tags": {"t0": True}}]
|
||||
|
@ -545,7 +545,7 @@ class TDTestCase:
|
|||
tdSql.checkEqual(str(res[1][0]), "2021-07-11 20:33:53.641000")
|
||||
|
||||
tdSql.execute(f"drop database if exists test_ts")
|
||||
tdSql.execute(f"create database if not exists test_ts precision 'us'")
|
||||
tdSql.execute(f"create database if not exists test_ts precision 'us' schemaless 1")
|
||||
tdSql.execute("use test_ts")
|
||||
input_json = [{"metric": "test_us", "timestamp": {"value": 1626006833639000, "type": "us"}, "value": True, "tags": {"t0": True}},
|
||||
{"metric": "test_us", "timestamp": {"value": 1626006833639001, "type": "us"}, "value": False, "tags": {"t0": True}}]
|
||||
|
@ -555,7 +555,7 @@ class TDTestCase:
|
|||
tdSql.checkEqual(str(res[1][0]), "2021-07-11 20:33:53.639001")
|
||||
|
||||
tdSql.execute(f"drop database if exists test_ts")
|
||||
tdSql.execute(f"create database if not exists test_ts precision 'ns'")
|
||||
tdSql.execute(f"create database if not exists test_ts precision 'ns' schemaless 1")
|
||||
tdSql.execute("use test_ts")
|
||||
input_json = [{"metric": "test_ns", "timestamp": {"value": 1626006833639000000, "type": "ns"}, "value": True, "tags": {"t0": True}},
|
||||
{"metric": "test_ns", "timestamp": {"value": 1626006833639000001, "type": "ns"}, "value": False, "tags": {"t0": True}}]
|
||||
|
|
|
@ -36,10 +36,10 @@ class TDTestCase:
|
|||
|
||||
if db_update_tag == 0:
|
||||
tdSql.execute(f"drop database if exists {name}")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'us'")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'us' schemaless 1")
|
||||
else:
|
||||
tdSql.execute(f"drop database if exists {name}")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ns' update 1")
|
||||
tdSql.execute(f"create database if not exists {name} precision 'ns' update 1 schemaless 1")
|
||||
tdSql.execute(f'use {name}')
|
||||
|
||||
def timeTrans(self, time_value, ts_type):
|
||||
|
@ -393,7 +393,7 @@ class TDTestCase:
|
|||
self.resCmp(input_sql, stb_name, ts_type=TDSmlTimestampType.SECOND.value)
|
||||
|
||||
tdSql.execute(f"drop database if exists test_ts")
|
||||
tdSql.execute(f"create database if not exists test_ts precision 'ms'")
|
||||
tdSql.execute(f"create database if not exists test_ts precision 'ms' schemaless 1")
|
||||
tdSql.execute("use test_ts")
|
||||
input_sql = ['test_ms 1626006833640 t t0=t', 'test_ms 1626006833641 f t0=t']
|
||||
self._conn.schemaless_insert(input_sql, TDSmlProtocolType.TELNET.value, None)
|
||||
|
|
|
@ -288,15 +288,18 @@ class TDTestCase:
|
|||
else:
|
||||
tdSql.query(f"select {col} from {table_expr} {re.sub('limit [0-9]*|offset [0-9]*','',condition)}")
|
||||
offset_val = condition.split("offset")[1].split(" ")[1] if "offset" in condition else 0
|
||||
pre_result = np.array(tdSql.queryResult)[np.array(tdSql.queryResult) != None]
|
||||
pre_mavg = pre_mavg = np.convolve(pre_result, np.ones(k), "valid")[offset_val:]/k
|
||||
tdSql.query(self.mavg_query_form(
|
||||
sel=sel, func=func, col=col, m_comm=m_comm, k=k, r_comm=r_comm, alias=alias, fr=fr,
|
||||
table_expr=table_expr, condition=condition
|
||||
))
|
||||
for i in range(tdSql.queryRows):
|
||||
print(f"case in {line}: ", end='')
|
||||
tdSql.checkData(i, 0, pre_mavg[i])
|
||||
# print(f"select {col} from {table_expr} {re.sub('limit [0-9]*|offset [0-9]*','',condition)}")
|
||||
if not tdSql.queryResult:
|
||||
pre_result = np.array(tdSql.queryResult)[np.array(tdSql.queryResult) != None]
|
||||
|
||||
pre_mavg = pre_mavg = np.convolve(pre_result, np.ones(k), "valid")[offset_val:]/k
|
||||
tdSql.query(self.mavg_query_form(
|
||||
sel=sel, func=func, col=col, m_comm=m_comm, k=k, r_comm=r_comm, alias=alias, fr=fr,
|
||||
table_expr=table_expr, condition=condition
|
||||
))
|
||||
for i in range(tdSql.queryRows):
|
||||
print(f"case in {line}: ", end='')
|
||||
tdSql.checkData(i, 0, pre_mavg[i])
|
||||
|
||||
pass
|
||||
|
||||
|
|
|
@ -101,3 +101,4 @@ python3 ./test.py -f 7-tmq/subscribeStb1.py
|
|||
python3 ./test.py -f 7-tmq/subscribeStb2.py
|
||||
python3 ./test.py -f 7-tmq/subscribeStb3.py
|
||||
python3 ./test.py -f 7-tmq/subscribeStb4.py
|
||||
python3 ./test.py -f 7-tmq/db.py
|
||||
|
|
|
@ -86,6 +86,7 @@ void dumpDb(SSdb *pSdb, SJson *json) {
|
|||
tjsonAddIntegerToObject(item, "cacheLastRow", pObj->cfg.cacheLastRow);
|
||||
tjsonAddIntegerToObject(item, "hashMethod", pObj->cfg.hashMethod);
|
||||
tjsonAddIntegerToObject(item, "numOfRetensions", pObj->cfg.numOfRetensions);
|
||||
tjsonAddIntegerToObject(item, "schemaless", pObj->cfg.schemaless);
|
||||
|
||||
sdbRelease(pSdb, pObj);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define MAX_SQL_STR_LEN (1024 * 1024)
|
||||
#define MAX_ROW_STR_LEN (16 * 1024)
|
||||
#define MAX_CONSUMER_THREAD_CNT (16)
|
||||
#define MAX_VGROUP_CNT (32)
|
||||
|
||||
typedef struct {
|
||||
TdThread thread;
|
||||
|
@ -61,6 +62,10 @@ typedef struct {
|
|||
|
||||
tmq_t* tmq;
|
||||
tmq_list_t* topicList;
|
||||
|
||||
int32_t numOfVgroups;
|
||||
int32_t rowsOfPerVgroups[MAX_VGROUP_CNT][2]; // [i][0]: vgroup id, [i][1]: rows of consume
|
||||
int64_t ts;
|
||||
|
||||
} SThreadInfo;
|
||||
|
||||
|
@ -69,7 +74,8 @@ typedef struct {
|
|||
char cdbName[32];
|
||||
char dbName[32];
|
||||
int32_t showMsgFlag;
|
||||
int32_t showRowFlag;
|
||||
int32_t showRowFlag;
|
||||
int32_t saveRowFlag;
|
||||
int32_t consumeDelay; // unit s
|
||||
int32_t numOfThread;
|
||||
SThreadInfo stThreads[MAX_CONSUMER_THREAD_CNT];
|
||||
|
@ -77,6 +83,7 @@ typedef struct {
|
|||
|
||||
static SConfInfo g_stConfInfo;
|
||||
TdFilePtr g_fp = NULL;
|
||||
static int running = 1;
|
||||
|
||||
// char* g_pRowValue = NULL;
|
||||
// TdFilePtr g_fp = NULL;
|
||||
|
@ -93,6 +100,8 @@ static void printHelp() {
|
|||
printf("%s%s%s%d\n", indent, indent, "showMsgFlag, default is ", g_stConfInfo.showMsgFlag);
|
||||
printf("%s%s\n", indent, "-r");
|
||||
printf("%s%s%s%d\n", indent, indent, "showRowFlag, default is ", g_stConfInfo.showRowFlag);
|
||||
printf("%s%s\n", indent, "-s");
|
||||
printf("%s%s%s%d\n", indent, indent, "saveRowFlag, default is ", g_stConfInfo.saveRowFlag);
|
||||
printf("%s%s\n", indent, "-y");
|
||||
printf("%s%s%s%d\n", indent, indent, "consume delay, default is s", g_stConfInfo.consumeDelay);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
@ -135,6 +144,7 @@ void saveConfigToLogFile() {
|
|||
taosFprintfFile(g_fp, "# cdbName: %s\n", g_stConfInfo.cdbName);
|
||||
taosFprintfFile(g_fp, "# showMsgFlag: %d\n", g_stConfInfo.showMsgFlag);
|
||||
taosFprintfFile(g_fp, "# showRowFlag: %d\n", g_stConfInfo.showRowFlag);
|
||||
taosFprintfFile(g_fp, "# saveRowFlag: %d\n", g_stConfInfo.saveRowFlag);
|
||||
taosFprintfFile(g_fp, "# consumeDelay: %d\n", g_stConfInfo.consumeDelay);
|
||||
taosFprintfFile(g_fp, "# numOfThread: %d\n", g_stConfInfo.numOfThread);
|
||||
|
||||
|
@ -165,6 +175,7 @@ void parseArgument(int32_t argc, char* argv[]) {
|
|||
memset(&g_stConfInfo, 0, sizeof(SConfInfo));
|
||||
g_stConfInfo.showMsgFlag = 0;
|
||||
g_stConfInfo.showRowFlag = 0;
|
||||
g_stConfInfo.saveRowFlag = 0;
|
||||
g_stConfInfo.consumeDelay = 5;
|
||||
|
||||
for (int32_t i = 1; i < argc; i++) {
|
||||
|
@ -181,6 +192,8 @@ void parseArgument(int32_t argc, char* argv[]) {
|
|||
g_stConfInfo.showMsgFlag = atol(argv[++i]);
|
||||
} else if (strcmp(argv[i], "-r") == 0) {
|
||||
g_stConfInfo.showRowFlag = atol(argv[++i]);
|
||||
} else if (strcmp(argv[i], "-s") == 0) {
|
||||
g_stConfInfo.saveRowFlag = atol(argv[++i]);
|
||||
} else if (strcmp(argv[i], "-y") == 0) {
|
||||
g_stConfInfo.consumeDelay = atol(argv[++i]);
|
||||
} else {
|
||||
|
@ -200,6 +213,7 @@ void parseArgument(int32_t argc, char* argv[]) {
|
|||
pPrint("%s consumeDelay:%d %s", GREEN, g_stConfInfo.consumeDelay, NC);
|
||||
pPrint("%s showMsgFlag:%d %s", GREEN, g_stConfInfo.showMsgFlag, NC);
|
||||
pPrint("%s showRowFlag:%d %s", GREEN, g_stConfInfo.showRowFlag, NC);
|
||||
pPrint("%s saveRowFlag:%d %s", GREEN, g_stConfInfo.saveRowFlag, NC);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -225,15 +239,64 @@ void ltrim(char* str) {
|
|||
// return str;
|
||||
}
|
||||
|
||||
static int running = 1;
|
||||
static int32_t msg_process(TAOS_RES* msg, int64_t msgIndex, int32_t threadLable) {
|
||||
void addRowsToVgroupId(SThreadInfo* pInfo, int32_t vgroupId, int32_t rows) {
|
||||
int32_t i;
|
||||
for (i = 0; i < pInfo->numOfVgroups; i++) {
|
||||
if (vgroupId == pInfo->rowsOfPerVgroups[i][0]) {
|
||||
pInfo->rowsOfPerVgroups[i][1] += rows;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pInfo->rowsOfPerVgroups[pInfo->numOfVgroups][0] = vgroupId;
|
||||
pInfo->rowsOfPerVgroups[pInfo->numOfVgroups][1] += rows;
|
||||
pInfo->numOfVgroups++;
|
||||
|
||||
taosFprintfFile(g_fp, "consume id %d, add one new vogroup id: %d\n", pInfo->consumerId, vgroupId);
|
||||
if (pInfo->numOfVgroups > MAX_VGROUP_CNT) {
|
||||
taosFprintfFile(g_fp, "====consume id %d, vgroup num %d over than 32. new vgroupId: %d\n", pInfo->consumerId, pInfo->numOfVgroups, vgroupId);
|
||||
taosCloseFile(&g_fp);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t saveConsumeContentToTbl(SThreadInfo* pInfo, char* buf) {
|
||||
char sqlStr[1100] = {0};
|
||||
|
||||
if (strlen(buf) > 1024) {
|
||||
taosFprintfFile(g_fp, "The length of one row[%d] is overflow 1024\n", strlen(buf));
|
||||
taosCloseFile(&g_fp);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
TAOS* pConn = taos_connect(NULL, "root", "taosdata", NULL, 0);
|
||||
assert(pConn != NULL);
|
||||
|
||||
sprintf(sqlStr, "insert into %s.content_%d values (%"PRId64", \'%s\')", g_stConfInfo.cdbName, pInfo->consumerId, pInfo->ts++, buf);
|
||||
TAOS_RES* pRes = taos_query(pConn, sqlStr);
|
||||
if (taos_errno(pRes) != 0) {
|
||||
pError("error in insert consume result, reason:%s\n", taos_errstr(pRes));
|
||||
taosFprintfFile(g_fp, "error in insert consume result, reason:%s\n", taos_errstr(pRes));
|
||||
taosCloseFile(&g_fp);
|
||||
taos_free_result(pRes);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
taos_free_result(pRes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t msg_process(TAOS_RES* msg, SThreadInfo* pInfo, int32_t msgIndex) {
|
||||
char buf[1024];
|
||||
int32_t totalRows = 0;
|
||||
|
||||
|
||||
// printf("topic: %s\n", tmq_get_topic_name(msg));
|
||||
// printf("vg:%d\n", tmq_get_vgroup_id(msg));
|
||||
taosFprintfFile(g_fp, "msg index:%" PRId64 ", threadLable: %d\n", msgIndex, threadLable);
|
||||
taosFprintfFile(g_fp, "topic: %s, vgroupId: %d\n", tmq_get_topic_name(msg), tmq_get_vgroup_id(msg));
|
||||
int32_t vgroupId = tmq_get_vgroup_id(msg);
|
||||
|
||||
taosFprintfFile(g_fp, "msg index:%" PRId64 ", consumerId: %d\n", msgIndex, pInfo->consumerId);
|
||||
//taosFprintfFile(g_fp, "topic: %s, vgroupId: %d, tableName: %s\n", tmq_get_topic_name(msg), vgroupId, tmq_get_table_name(msg));
|
||||
taosFprintfFile(g_fp, "topic: %s, vgroupId: %d\n", tmq_get_topic_name(msg), vgroupId);
|
||||
|
||||
while (1) {
|
||||
TAOS_ROW row = taos_fetch_row(msg);
|
||||
|
@ -247,11 +310,16 @@ static int32_t msg_process(TAOS_RES* msg, int64_t msgIndex, int32_t threadLable)
|
|||
|
||||
if (0 != g_stConfInfo.showRowFlag) {
|
||||
taosFprintfFile(g_fp, "rows[%d]: %s\n", totalRows, buf);
|
||||
if (0 != g_stConfInfo.saveRowFlag) {
|
||||
saveConsumeContentToTbl(pInfo, buf);
|
||||
}
|
||||
}
|
||||
|
||||
totalRows++;
|
||||
}
|
||||
|
||||
addRowsToVgroupId(pInfo, vgroupId, totalRows);
|
||||
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
|
@ -344,6 +412,32 @@ int32_t saveConsumeResult(SThreadInfo* pInfo) {
|
|||
|
||||
taos_free_result(pRes);
|
||||
|
||||
#if 0
|
||||
// vgroups
|
||||
for (i = 0; i < pInfo->numOfVgroups; i++) {
|
||||
// schema: ts timestamp, consumerid int, consummsgcnt bigint, checkresult int
|
||||
sprintf(sqlStr, "insert into %s.vgroup_%d values (%"PRId64", %d, %" PRId64 ", %" PRId64 ", %d)",
|
||||
g_stConfInfo.cdbName,
|
||||
now,
|
||||
pInfo->consumerId,
|
||||
pInfo->consumeMsgCnt,
|
||||
pInfo->consumeRowCnt,
|
||||
pInfo->checkresult);
|
||||
|
||||
char tmpString[128];
|
||||
taosFprintfFile(g_fp, "%s, consume id %d result: %s\n", getCurrentTimeString(tmpString), pInfo->consumerId ,sqlStr);
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, sqlStr);
|
||||
if (taos_errno(pRes) != 0) {
|
||||
pError("error in save consumeinfo, reason:%s\n", taos_errstr(pRes));
|
||||
taos_free_result(pRes);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -356,11 +450,13 @@ void loop_consume(SThreadInfo* pInfo) {
|
|||
char tmpString[128];
|
||||
taosFprintfFile(g_fp, "%s consumer id %d start to loop pull msg\n", getCurrentTimeString(tmpString), pInfo->consumerId);
|
||||
|
||||
pInfo->ts = taosGetTimestampMs();
|
||||
|
||||
while (running) {
|
||||
TAOS_RES* tmqMsg = tmq_consumer_poll(pInfo->tmq, g_stConfInfo.consumeDelay * 1000);
|
||||
if (tmqMsg) {
|
||||
if (0 != g_stConfInfo.showMsgFlag) {
|
||||
totalRows += msg_process(tmqMsg, totalMsgs, pInfo->consumerId);
|
||||
totalRows += msg_process(tmqMsg, pInfo, totalMsgs);
|
||||
}
|
||||
|
||||
taos_free_result(tmqMsg);
|
||||
|
|
Loading…
Reference in New Issue