Merge branch 'develop' into feature/TD-4399
This commit is contained in:
commit
45b861317c
|
@ -26,7 +26,7 @@
|
|||
| TSDB_CODE_COM_OUT_OF_MEMORY | 0 | 0x0102 | "Out of memory" | -2147483390 |
|
||||
| TSDB_CODE_COM_INVALID_CFG_MSG | 0 | 0x0103 | "Invalid config message" | -2147483389 |
|
||||
| TSDB_CODE_COM_FILE_CORRUPTED | 0 | 0x0104 | "Data file corrupted" | -2147483388 |
|
||||
| TSDB_CODE_TSC_INVALID_SQL | 0 | 0x0200 | "Invalid SQL statement" | -2147483136 |
|
||||
| TSDB_CODE_TSC_INVALID_OPERATION | 0 | 0x0200 | "Invalid SQL statement" | -2147483136 |
|
||||
| TSDB_CODE_TSC_INVALID_QHANDLE | 0 | 0x0201 | "Invalid qhandle" | -2147483135 |
|
||||
| TSDB_CODE_TSC_INVALID_TIME_STAMP | 0 | 0x0202 | "Invalid combination of client/service time" | -2147483134 |
|
||||
| TSDB_CODE_TSC_INVALID_VALUE | 0 | 0x0203 | "Invalid value in client" | -2147483133 |
|
||||
|
|
|
@ -44,34 +44,24 @@ typedef struct SLocalMerger {
|
|||
int32_t numOfCompleted;
|
||||
int32_t numOfVnode;
|
||||
SLoserTreeInfo *pLoserTree;
|
||||
tFilePage * pResultBuf;
|
||||
int32_t nResultBufSize;
|
||||
tFilePage * pTempBuffer;
|
||||
struct SQLFunctionCtx *pCtx;
|
||||
int32_t rowSize; // size of each intermediate result.
|
||||
tOrderDescriptor *pDesc;
|
||||
SColumnModel * resColModel;
|
||||
SColumnModel* finalModel;
|
||||
tExtMemBuffer **pExtMemBuffer; // disk-based buffer
|
||||
bool orderPrjOnSTable; // projection query on stable
|
||||
char *buf; // temp buffer
|
||||
} SLocalMerger;
|
||||
|
||||
typedef struct SRetrieveSupport {
|
||||
tExtMemBuffer ** pExtMemBuffer; // for build loser tree
|
||||
tOrderDescriptor *pOrderDescriptor;
|
||||
SColumnModel* pFinalColModel; // colModel for final result
|
||||
SColumnModel* pFFColModel;
|
||||
int32_t subqueryIndex; // index of current vnode in vnode list
|
||||
SSqlObj * pParentSql;
|
||||
tFilePage * localBuffer; // temp buffer, there is a buffer for each vnode to
|
||||
uint32_t numOfRetry; // record the number of retry times
|
||||
} SRetrieveSupport;
|
||||
|
||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pDesc,
|
||||
SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSize);
|
||||
int32_t tscLocalReducerEnvCreate(SQueryInfo* pQueryInfo, tExtMemBuffer ***pMemBuffer, int32_t numOfSub, tOrderDescriptor **pDesc, uint32_t nBufferSize, int64_t id);
|
||||
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel* pFFModel,
|
||||
int32_t numOfVnodes);
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes);
|
||||
|
||||
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
||||
int32_t numOfRows, int32_t orderType);
|
||||
|
@ -81,12 +71,10 @@ int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tF
|
|||
/*
|
||||
* create local reducer to launch the second-stage reduce process at client site
|
||||
*/
|
||||
void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||
SColumnModel *finalModel, SColumnModel *pFFModel, SSqlObj* pSql);
|
||||
int32_t tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||
SQueryInfo *pQueryInfo, SLocalMerger **pMerger, int64_t id);
|
||||
|
||||
void tscDestroyLocalMerger(SSqlObj *pSql);
|
||||
|
||||
//int32_t tscDoLocalMerge(SSqlObj *pSql);
|
||||
void tscDestroyLocalMerger(SLocalMerger* pLocalMerger);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tsched.h"
|
||||
#include "exception.h"
|
||||
#include "os.h"
|
||||
#include "qExtbuffer.h"
|
||||
|
@ -36,6 +37,9 @@ extern "C" {
|
|||
#define UTIL_TABLE_IS_NORMAL_TABLE(metaInfo)\
|
||||
(!(UTIL_TABLE_IS_SUPER_TABLE(metaInfo) || UTIL_TABLE_IS_CHILD_TABLE(metaInfo)))
|
||||
|
||||
#define UTIL_TABLE_IS_TMP_TABLE(metaInfo) \
|
||||
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE))
|
||||
|
||||
#pragma pack(push,1)
|
||||
// this struct is transfered as binary, padding two bytes to avoid
|
||||
// an 'uid' whose low bytes is 0xff being recoginized as NULL,
|
||||
|
@ -59,7 +63,7 @@ typedef struct SJoinSupporter {
|
|||
SArray* exprList;
|
||||
SFieldInfo fieldsInfo;
|
||||
STagCond tagCond;
|
||||
SSqlGroupbyExpr groupInfo; // group by info
|
||||
SGroupbyExpr groupInfo; // group by info
|
||||
struct STSBuf* pTSBuf; // the TSBuf struct that holds the compressed timestamp array
|
||||
FILE* f; // temporary file in order to create TSBuf
|
||||
char path[PATH_MAX]; // temporary file path, todo dynamic allocate memory
|
||||
|
@ -90,22 +94,14 @@ typedef struct SVgroupTableInfo {
|
|||
SArray *itemList; // SArray<STableIdInfo>
|
||||
} SVgroupTableInfo;
|
||||
|
||||
static FORCE_INLINE SQueryInfo* tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex) {
|
||||
assert(pCmd != NULL && subClauseIndex >= 0);
|
||||
if (pCmd->pQueryInfo == NULL || subClauseIndex >= pCmd->numOfClause) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pCmd->pQueryInfo[subClauseIndex];
|
||||
}
|
||||
|
||||
SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd);
|
||||
int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len);
|
||||
|
||||
int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks);
|
||||
void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta);
|
||||
void tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf);
|
||||
|
||||
void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo);
|
||||
void doRetrieveSubqueryData(SSchedMsg *pMsg);
|
||||
|
||||
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, int16_t bytes,
|
||||
uint32_t offset);
|
||||
|
@ -127,7 +123,7 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
|
|||
*/
|
||||
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
|
||||
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
|
||||
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
|
||||
bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo);
|
||||
bool tscGroupbyColumn(SQueryInfo* pQueryInfo);
|
||||
bool tscIsTopBotQuery(SQueryInfo* pQueryInfo);
|
||||
bool hasTagValOutput(SQueryInfo* pQueryInfo);
|
||||
|
@ -136,13 +132,14 @@ bool isStabledev(SQueryInfo* pQueryInfo);
|
|||
bool isTsCompQuery(SQueryInfo* pQueryInfo);
|
||||
bool isSimpleAggregate(SQueryInfo* pQueryInfo);
|
||||
bool isBlockDistQuery(SQueryInfo* pQueryInfo);
|
||||
int32_t tscGetTopbotQueryParam(SQueryInfo* pQueryInfo);
|
||||
bool isSimpleAggregateRv(SQueryInfo* pQueryInfo);
|
||||
|
||||
bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||
bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||
|
||||
bool tscIsProjectionQuery(SQueryInfo* pQueryInfo);
|
||||
bool tscHasColumnFilter(SQueryInfo* pQueryInfo);
|
||||
|
||||
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||
bool tscQueryTags(SQueryInfo* pQueryInfo);
|
||||
|
@ -150,9 +147,9 @@ bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
|||
bool tscQueryBlockInfo(SQueryInfo* pQueryInfo);
|
||||
|
||||
SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
|
||||
SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType);
|
||||
SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType, int16_t colId);
|
||||
|
||||
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql);
|
||||
int32_t tscSetTableFullName(SName* pName, SStrToken* pzTableName, SSqlObj* pSql);
|
||||
void tscClearInterpInfo(SQueryInfo* pQueryInfo);
|
||||
|
||||
bool tscIsInsertData(char* sqlstr);
|
||||
|
@ -171,36 +168,49 @@ void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
|
|||
|
||||
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
|
||||
void tscFieldInfoClear(SFieldInfo* pFieldInfo);
|
||||
void tscFieldInfoCopy(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArray* pExprList);
|
||||
|
||||
static FORCE_INLINE int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutput; }
|
||||
|
||||
int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize);
|
||||
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
||||
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid);
|
||||
|
||||
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
||||
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||
|
||||
int32_t tscGetResRowLength(SArray* pExprList);
|
||||
|
||||
SExprInfo* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol);
|
||||
|
||||
SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
SExprInfo* tscExprCreate(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
int16_t size, int16_t resColId, int16_t interSize, int32_t colType);
|
||||
|
||||
void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||
|
||||
SExprInfo* tscExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol);
|
||||
|
||||
SExprInfo* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
|
||||
SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
|
||||
int16_t size);
|
||||
size_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo);
|
||||
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid);
|
||||
|
||||
SExprInfo* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index);
|
||||
int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
||||
void tscSqlExprAssign(SExprInfo* dst, const SExprInfo* src);
|
||||
void tscSqlExprInfoDestroy(SArray* pExprInfo);
|
||||
size_t tscNumOfExprs(SQueryInfo* pQueryInfo);
|
||||
SExprInfo *tscExprGet(SQueryInfo* pQueryInfo, int32_t index);
|
||||
int32_t tscExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
||||
int32_t tscExprCopyAll(SArray* dst, const SArray* src, bool deepcopy);
|
||||
void tscExprAssign(SExprInfo* dst, const SExprInfo* src);
|
||||
void tscExprDestroy(SArray* pExprInfo);
|
||||
|
||||
int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num);
|
||||
|
||||
void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta);
|
||||
|
||||
SColumn* tscColumnClone(const SColumn* src);
|
||||
bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid);
|
||||
SColumn* tscColumnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
|
||||
void tscColumnListDestroy(SArray* pColList);
|
||||
void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid);
|
||||
void tscColumnListCopyAll(SArray* dst, const SArray* src);
|
||||
|
||||
void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||
|
||||
|
@ -222,14 +232,14 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo);
|
|||
|
||||
bool tscShouldBeFreed(SSqlObj* pSql);
|
||||
|
||||
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex);
|
||||
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t tableIndex);
|
||||
STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||
|
||||
void tscInitQueryInfo(SQueryInfo* pQueryInfo);
|
||||
void tscClearSubqueryInfo(SSqlCmd* pCmd);
|
||||
int32_t tscAddQueryInfo(SSqlCmd *pCmd);
|
||||
SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex);
|
||||
SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd, int32_t subClauseIndex);
|
||||
SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd);
|
||||
SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd);
|
||||
|
||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo);
|
||||
|
||||
|
@ -243,12 +253,11 @@ SArray* tscVgroupTableInfoDup(SArray* pVgroupTables);
|
|||
void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index);
|
||||
void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo);
|
||||
|
||||
int tscGetSTableVgroupInfo(SSqlObj* pSql, int32_t clauseIndex);
|
||||
int tscGetSTableVgroupInfo(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||
int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo);
|
||||
int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool createIfNotExists);
|
||||
|
||||
void tscResetForNextRetrieve(SSqlRes* pRes);
|
||||
void tscDoQuery(SSqlObj* pSql);
|
||||
void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||
void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||
|
||||
|
@ -279,7 +288,7 @@ void registerSqlObj(SSqlObj* pSql);
|
|||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t fp, void* param, int32_t cmd, SSqlObj* pPrevSql);
|
||||
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex);
|
||||
|
||||
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex);
|
||||
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex, SSqlCmd* pCmd);
|
||||
|
||||
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid);
|
||||
int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId);
|
||||
|
@ -295,6 +304,11 @@ void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
|||
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
||||
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
|
||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corEpSet);
|
||||
int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, __async_cb_func_t fp);
|
||||
|
||||
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray);
|
||||
|
||||
bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx);
|
||||
|
||||
bool tscSetSqlOwner(SSqlObj* pSql);
|
||||
void tscClearSqlOwner(SSqlObj* pSql);
|
||||
|
@ -309,10 +323,12 @@ CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta);
|
|||
uint32_t tscGetTableMetaMaxSize();
|
||||
int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, void* buf);
|
||||
STableMeta* tscTableMetaDup(STableMeta* pTableMeta);
|
||||
SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo);
|
||||
|
||||
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr);
|
||||
|
||||
void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema);
|
||||
void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage);
|
||||
void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage);
|
||||
|
||||
void* malloc_throw(size_t size);
|
||||
void* calloc_throw(size_t nmemb, size_t size);
|
||||
|
|
|
@ -42,12 +42,6 @@ extern "C" {
|
|||
struct SSqlInfo;
|
||||
struct SLocalMerger;
|
||||
|
||||
// data source from sql string or from file
|
||||
enum {
|
||||
DATA_FROM_SQL_STRING = 1,
|
||||
DATA_FROM_DATA_FILE = 2,
|
||||
};
|
||||
|
||||
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows);
|
||||
|
||||
typedef struct STableComInfo {
|
||||
|
@ -205,10 +199,11 @@ typedef struct SQueryInfo {
|
|||
SInterval interval; // tumble time window
|
||||
SSessionWindow sessionWindow; // session time window
|
||||
|
||||
SSqlGroupbyExpr groupbyExpr; // groupby tags info
|
||||
SGroupbyExpr groupbyExpr; // groupby tags info
|
||||
SArray * colList; // SArray<SColumn*>
|
||||
SFieldInfo fieldsInfo;
|
||||
SArray * exprList; // SArray<SExprInfo*>
|
||||
SArray * exprList1; // final exprlist in case of arithmetic expression exists
|
||||
SLimitVal limit;
|
||||
SLimitVal slimit;
|
||||
STagCond tagCond;
|
||||
|
@ -232,30 +227,50 @@ typedef struct SQueryInfo {
|
|||
int32_t bufLen;
|
||||
char* buf;
|
||||
SQInfo* pQInfo; // global merge operator
|
||||
SArray* pDSOperator; // data source operator
|
||||
SArray* pPhyOperator; // physical query execution plan
|
||||
SQueryAttr* pQueryAttr; // query object
|
||||
|
||||
struct SQueryInfo *sibling; // sibling
|
||||
SArray *pUpstream; // SArray<struct SQueryInfo>
|
||||
struct SQueryInfo *pDownstream;
|
||||
int32_t havingFieldNum;
|
||||
bool stableQuery;
|
||||
bool groupbyColumn;
|
||||
bool simpleAgg;
|
||||
bool arithmeticOnAgg;
|
||||
bool projectionQuery;
|
||||
bool hasFilter;
|
||||
bool onlyTagQuery;
|
||||
} SQueryInfo;
|
||||
|
||||
typedef struct {
|
||||
STableMeta *pTableMeta;
|
||||
SVgroupsInfo *pVgroupInfo;
|
||||
} STableMetaVgroupInfo;
|
||||
|
||||
typedef struct SInsertStatementParam {
|
||||
SName **pTableNameList; // all involved tableMeta list of current insert sql statement.
|
||||
int32_t numOfTables; // number of tables in table name list
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
SArray *pDataBlocks; // SArray<STableDataBlocks*>. Merged submit block for each vgroup
|
||||
int8_t schemaAttached; // denote if submit block is built with table schema or not
|
||||
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
||||
|
||||
char msg[512]; // error message
|
||||
char *sql; // current sql statement position
|
||||
uint32_t insertType; // insert data from [file|sql statement| bound statement]
|
||||
} SInsertStatementParam;
|
||||
|
||||
// TODO extract sql parser supporter
|
||||
typedef struct {
|
||||
int command;
|
||||
uint8_t msgType;
|
||||
SInsertStatementParam insertParam;
|
||||
char reserve1[3]; // fix bus error on arm32
|
||||
bool autoCreated; // create table if it is not existed during retrieve table meta in mnode
|
||||
|
||||
union {
|
||||
int32_t count;
|
||||
int32_t numOfTablesInSubmit;
|
||||
};
|
||||
|
||||
uint32_t insertType; // TODO remove it
|
||||
char * curSql; // current sql, resume position of sql after parsing paused
|
||||
int8_t parseFinished;
|
||||
char reserve2[3]; // fix bus error on arm32
|
||||
|
||||
int16_t numOfCols;
|
||||
|
@ -264,25 +279,13 @@ typedef struct {
|
|||
char * payload;
|
||||
int32_t payloadLen;
|
||||
|
||||
SQueryInfo **pQueryInfo;
|
||||
int32_t numOfClause;
|
||||
int32_t clauseIndex; // index of multiple subclause query
|
||||
SHashObj *pTableMetaMap; // local buffer to keep the queried table meta, before validating the AST
|
||||
SQueryInfo *pQueryInfo;
|
||||
SQueryInfo *active; // current active query info
|
||||
|
||||
int32_t batchSize; // for parameter ('?') binding and batch processing
|
||||
int32_t numOfParams;
|
||||
|
||||
int8_t dataSourceType; // load data from file or not
|
||||
char reserve4[3]; // fix bus error on arm32
|
||||
int8_t submitSchema; // submit block is built with table schema
|
||||
char reserve5[3]; // fix bus error on arm32
|
||||
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
||||
|
||||
SName **pTableNameList; // all involved tableMeta list of current insert sql statement.
|
||||
int32_t numOfTables;
|
||||
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
SArray *pDataBlocks; // SArray<STableDataBlocks*>. Merged submit block for each vgroup
|
||||
int32_t resColumnId;
|
||||
} SSqlCmd;
|
||||
|
||||
typedef struct SResRec {
|
||||
|
@ -443,7 +446,7 @@ int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
|||
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||
void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock);
|
||||
|
||||
void handleDownstreamOperator(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||
void handleDownstreamOperator(SSqlObj** pSqlList, int32_t numOfUpstream, SQueryInfo* px, SSqlRes* pOutput);
|
||||
void destroyTableNameList(SSqlCmd* pCmd);
|
||||
|
||||
void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta);
|
||||
|
@ -489,7 +492,7 @@ char *tscGetErrorMsgPayload(SSqlCmd *pCmd);
|
|||
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql);
|
||||
int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* sql);
|
||||
|
||||
int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||
int32_t tscValidateSqlInfo(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||
|
||||
extern int32_t sentinel;
|
||||
extern SHashObj *tscVgroupMap;
|
||||
|
@ -505,7 +508,7 @@ extern int tscNumOfObj; // number of existed sqlObj in current process.
|
|||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||
|
||||
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
||||
int16_t getNewResColId(SQueryInfo* pQueryInfo);
|
||||
int16_t getNewResColId(SSqlCmd* pCmd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -218,11 +218,19 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(J
|
|||
|
||||
/*
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method: executeBatchImp
|
||||
* Method: closeStmt
|
||||
* Signature: (JJ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
|
||||
|
||||
/**
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method: setTableNameTagsImp
|
||||
* Signature: (JLjava/lang/String;I[B[B[B[BJ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp
|
||||
(JNIEnv *, jobject, jlong, jstring, jint, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jlong);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -749,7 +749,6 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
|
|||
}
|
||||
|
||||
jniDebug("jobj:%p, conn:%p, set stmt bind table name:%s", jobj, tsconn, name);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jname, name);
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
@ -799,23 +798,11 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
|
|||
b->length = (int32_t*)lengthArray;
|
||||
|
||||
// set the length and is_null array
|
||||
switch(dataType) {
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
if (!IS_VAR_DATA_TYPE(dataType)) {
|
||||
int32_t bytes = tDataTypes[dataType].bytes;
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
b->length[i] = bytes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
int32_t code = taos_stmt_bind_single_param_batch(pStmt, b, colIndex);
|
||||
|
@ -878,3 +865,74 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv
|
|||
jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon);
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp(JNIEnv *env, jobject jobj,
|
||||
jlong stmt, jstring tableName, jint numOfTags, jbyteArray tags, jbyteArray typeList, jbyteArray lengthList, jbyteArray nullList, jlong conn) {
|
||||
TAOS *tsconn = (TAOS *)conn;
|
||||
if (tsconn == NULL) {
|
||||
jniError("jobj:%p, connection already closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
TAOS_STMT* pStmt = (TAOS_STMT*) stmt;
|
||||
if (pStmt == NULL) {
|
||||
jniError("jobj:%p, conn:%p, invalid stmt handle", jobj, tsconn);
|
||||
return JNI_SQL_NULL;
|
||||
}
|
||||
|
||||
jsize len = (*env)->GetArrayLength(env, tags);
|
||||
char *tagsData = (char *)calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, tags, 0, len, (jbyte *)tagsData);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// todo handle error
|
||||
}
|
||||
|
||||
len = (*env)->GetArrayLength(env, lengthList);
|
||||
int64_t *lengthArray = (int64_t*) calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
}
|
||||
|
||||
len = (*env)->GetArrayLength(env, typeList);
|
||||
char *typeArray = (char*) calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, typeList, 0, len, (jbyte*) typeArray);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
}
|
||||
|
||||
len = (*env)->GetArrayLength(env, nullList);
|
||||
int32_t *nullArray = (int32_t*) calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte*) nullArray);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
}
|
||||
|
||||
const char *name = (*env)->GetStringUTFChars(env, tableName, NULL);
|
||||
char* curTags = tagsData;
|
||||
|
||||
TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND));
|
||||
for(int32_t i = 0; i < numOfTags; ++i) {
|
||||
tagsBind[i].buffer_type = typeArray[i];
|
||||
tagsBind[i].buffer = curTags;
|
||||
tagsBind[i].is_null = &nullArray[i];
|
||||
tagsBind[i].length = (uintptr_t*) &lengthArray[i];
|
||||
|
||||
curTags += lengthArray[i];
|
||||
}
|
||||
|
||||
int32_t code = taos_stmt_set_tbname_tags((void*)stmt, name, tagsBind);
|
||||
|
||||
int32_t nTags = (int32_t) numOfTags;
|
||||
jniDebug("jobj:%p, conn:%p, set table name:%s, numOfTags:%d", jobj, tsconn, name, nTags);
|
||||
|
||||
tfree(tagsData);
|
||||
tfree(lengthArray);
|
||||
tfree(typeArray);
|
||||
tfree(nullArray);
|
||||
(*env)->ReleaseStringUTFChars(env, tableName, name);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code));
|
||||
return JNI_TDENGINE_ERROR;
|
||||
}
|
||||
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
|||
|
||||
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||
pCmd->curSql = pSql->sqlstr;
|
||||
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||
|
||||
int32_t code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) return;
|
||||
|
@ -69,7 +70,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
|||
return;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
executeQuery(pSql, pQueryInfo);
|
||||
}
|
||||
|
||||
|
@ -127,7 +128,8 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
* all available virtual node has been checked already, now we need to check
|
||||
* for the next subclause queries
|
||||
*/
|
||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
if (pCmd->active->sibling != NULL) {
|
||||
pCmd->active = pCmd->active->sibling;
|
||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
}
|
||||
|
@ -220,6 +222,17 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
|||
tscResetForNextRetrieve(pRes);
|
||||
|
||||
// handle the sub queries of join query
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) {
|
||||
SSchedMsg schedMsg = {0};
|
||||
schedMsg.fp = doRetrieveSubqueryData;
|
||||
schedMsg.ahandle = (void *)pSql;
|
||||
schedMsg.thandle = (void *)1;
|
||||
schedMsg.msg = 0;
|
||||
taosScheduleTask(tscQhandle, &schedMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
|
||||
tscFetchDatablockForSubquery(pSql);
|
||||
} else if (pRes->completed) {
|
||||
|
@ -231,7 +244,8 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
|||
* all available virtual nodes in current clause has been checked already, now try the
|
||||
* next one in the following union subclause
|
||||
*/
|
||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
if (pCmd->active->sibling != NULL) {
|
||||
pCmd->active = pCmd->active->sibling; // todo refactor
|
||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
}
|
||||
|
@ -255,7 +269,7 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
|||
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo1 = tscGetActiveQueryInfo(&pSql->cmd);
|
||||
SQueryInfo* pQueryInfo1 = tscGetQueryInfo(&pSql->cmd);
|
||||
tscBuildAndSendRequest(pSql, pQueryInfo1);
|
||||
}
|
||||
}
|
||||
|
@ -317,27 +331,39 @@ static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableM
|
|||
// update the pExpr info, colList info, number of table columns
|
||||
// TODO Re-parse this sql and issue the corresponding subquery as an alternative for this case.
|
||||
if (pSql->retryReason == TSDB_CODE_TDB_INVALID_TABLE_ID) {
|
||||
int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||
int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
||||
int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
|
||||
|
||||
SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||
SSchema *pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||
|
||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||
SSqlExpr *pExpr = &(tscSqlExprGet(pQueryInfo, i)->base);
|
||||
SSqlExpr *pExpr = &(tscExprGet(pQueryInfo, i)->base);
|
||||
|
||||
// update the table uid
|
||||
pExpr->uid = pTableMetaInfo->pTableMeta->id.uid;
|
||||
|
||||
if (pExpr->colInfo.colIndex >= 0) {
|
||||
int32_t index = pExpr->colInfo.colIndex;
|
||||
|
||||
if ((TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && index >= numOfCols) ||
|
||||
(TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < numOfCols || index >= (numOfCols + numOfTags)))) {
|
||||
(TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < 0 || index >= numOfTags))) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
|
||||
if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
||||
if ((pTagSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||
strcasecmp(pExpr->colInfo.name, pTagSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
} else if (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag)) {
|
||||
if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||
strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
} else { // do nothing for udc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,12 +400,12 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
|
||||
tscDebug("0x%"PRIx64" get %s successfully", pSql->self, msg);
|
||||
if (pSql->pStream == NULL) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
// check if it is a sub-query of super table query first, if true, enter another routine
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||
tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send the corresponding query", pSql->self);
|
||||
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY | TSDB_QUERY_TYPE_SUBQUERY |
|
||||
TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||
tscDebug("0x%" PRIx64 " update cached table-meta, continue to process sql and send the corresponding query", pSql->self);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
|
@ -401,42 +427,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else { // continue to process normal async query
|
||||
if (pCmd->parseFinished) {
|
||||
tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send corresponding query", pSql->self);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
|
||||
assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pCmd->command != TSDB_SQL_INSERT);
|
||||
|
||||
if (pCmd->command == TSDB_SQL_SELECT) {
|
||||
tscDebug("0x%"PRIx64" redo parse sql string and proceed", pSql->self);
|
||||
pCmd->parseFinished = false;
|
||||
tscResetSqlCmd(pCmd, true);
|
||||
|
||||
code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
tscBuildAndSendRequest(pSql, NULL);
|
||||
} else { // in all other cases, simple retry
|
||||
tscBuildAndSendRequest(pSql, NULL);
|
||||
}
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else {
|
||||
tscDebug("0x%"PRIx64" continue parse sql after get table meta", pSql->self);
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) {
|
||||
tscDebug("0x%" PRIx64 " continue parse sql after get table-meta", pSql->self);
|
||||
|
||||
code = tsParseSql(pSql, false);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
|
@ -446,8 +438,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
goto _error;
|
||||
}
|
||||
|
||||
if (pCmd->insertType == TSDB_QUERY_TYPE_STMT_INSERT) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT)) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
@ -457,59 +449,52 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
}
|
||||
|
||||
(*pSql->fp)(pSql->param, pSql, code);
|
||||
} else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) {
|
||||
if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) {
|
||||
} else {
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
|
||||
tscImportDataFromFile(pSql);
|
||||
} else {
|
||||
tscHandleMultivnodeInsert(pSql);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
if (pSql->retryReason != TSDB_CODE_SUCCESS) {
|
||||
tscDebug("0x%" PRIx64 " update cached table-meta, re-validate sql statement and send query again",
|
||||
pSql->self);
|
||||
tscResetSqlCmd(pCmd, false);
|
||||
pSql->retryReason = TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
tscDebug("0x%" PRIx64 " cached table-meta, continue validate sql statement and send query", pSql->self);
|
||||
}
|
||||
|
||||
code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pCmd);
|
||||
executeQuery(pSql, pQueryInfo1);
|
||||
}
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} else { // stream computing
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pCmd->command);
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
code = tscGetSTableVgroupInfo(pSql, pCmd->clauseIndex);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
}
|
||||
|
||||
tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pSql->cmd.command);
|
||||
if (!pSql->cmd.parseFinished) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
if (tscNumOfExprs(pQueryInfo) == 0) {
|
||||
tsParseSql(pSql, false);
|
||||
}
|
||||
|
||||
(*pSql->fp)(pSql->param, pSql, code);
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// tscDoQuery(pSql);
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
||||
return;
|
||||
|
||||
_error:
|
||||
|
|
|
@ -53,7 +53,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
|||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
// one column for each row
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||
|
@ -154,14 +154,14 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
|
||||
pSql->cmd.numOfCols = numOfCols;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
|
||||
TAOS_FIELD f = {.type = TSDB_DATA_TYPE_BINARY, .bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE};
|
||||
tstrncpy(f.name, "Field", sizeof(f.name));
|
||||
|
||||
SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||
(TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false);
|
||||
|
||||
rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE);
|
||||
|
@ -171,7 +171,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
tstrncpy(f.name, "Type", sizeof(f.name));
|
||||
|
||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE),
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE),
|
||||
-1000, typeColLength, false);
|
||||
|
||||
rowLen += typeColLength + VARSTR_HEADER_SIZE;
|
||||
|
@ -181,7 +181,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
tstrncpy(f.name, "Length", sizeof(f.name));
|
||||
|
||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t),
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t),
|
||||
-1000, sizeof(int32_t), false);
|
||||
|
||||
rowLen += sizeof(int32_t);
|
||||
|
@ -191,7 +191,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
tstrncpy(f.name, "Note", sizeof(f.name));
|
||||
|
||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE),
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE),
|
||||
-1000, noteColLength, false);
|
||||
|
||||
rowLen += noteColLength + VARSTR_HEADER_SIZE;
|
||||
|
@ -199,7 +199,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
}
|
||||
|
||||
static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL);
|
||||
|
||||
|
@ -390,7 +390,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
|||
SColumnIndex index = {0};
|
||||
pSql->cmd.numOfCols = 2;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
|
||||
TAOS_FIELD f;
|
||||
|
@ -405,7 +405,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
|||
}
|
||||
|
||||
SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false);
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false);
|
||||
|
||||
rowLen += f.bytes;
|
||||
|
||||
|
@ -418,7 +418,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
|||
}
|
||||
|
||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||
(int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false);
|
||||
|
||||
rowLen += ddlLen + VARSTR_HEADER_SIZE;
|
||||
|
@ -428,7 +428,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
|||
static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
int32_t numOfRows = 1;
|
||||
if (strlen(ddl) == 0) {
|
||||
|
||||
|
@ -445,7 +445,7 @@ static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const c
|
|||
return 0;
|
||||
}
|
||||
static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result);
|
||||
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
|
@ -532,7 +532,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) {
|
|||
}
|
||||
buf[0] = 0;
|
||||
|
||||
STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->pTableMeta;
|
||||
STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0)->pTableMeta;
|
||||
if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
|
||||
pMeta->tableType == TSDB_STREAM_TABLE) {
|
||||
free(buf);
|
||||
|
@ -553,7 +553,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||
|
@ -607,7 +607,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch
|
|||
}
|
||||
|
||||
static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||
|
||||
|
@ -634,7 +634,7 @@ static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName,
|
|||
}
|
||||
static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||
char *result = ddl;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||
|
||||
|
@ -675,7 +675,7 @@ static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName,
|
|||
}
|
||||
|
||||
static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
assert(pTableMetaInfo->pTableMeta != NULL);
|
||||
|
||||
|
@ -704,7 +704,7 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
|
@ -730,7 +730,7 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
|||
return TSDB_CODE_TSC_ACTION_IN_PROGRESS;
|
||||
}
|
||||
static int32_t tscProcessCurrentUser(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -757,7 +757,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
|
|||
extractDBName(pSql->pTscObj->db, db);
|
||||
pthread_mutex_unlock(&pSql->pTscObj->mutex);
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -784,7 +784,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
|
|||
|
||||
static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
||||
const char* v = pSql->pTscObj->sversion;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -807,7 +807,7 @@ static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -859,7 +859,7 @@ static int32_t tscProcessServStatus(SSqlObj *pSql) {
|
|||
return pSql->res.code;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
|
||||
int32_t val = 1;
|
||||
|
@ -873,7 +873,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa
|
|||
|
||||
pCmd->numOfCols = 1;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
|
||||
tscFieldInfoClear(&pQueryInfo->fieldsInfo);
|
||||
|
@ -928,7 +928,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|||
} else if (pCmd->command == TSDB_SQL_SERV_STATUS) {
|
||||
pRes->code = tscProcessServStatus(pSql);
|
||||
} else {
|
||||
pRes->code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
pRes->code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
tscError("0x%"PRIx64" not support command:%d", pSql->self, pCmd->command);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
#include "texpr.h"
|
||||
#include "tlosertree.h"
|
||||
#include "tscLog.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tschemautil.h"
|
||||
#include "tsclient.h"
|
||||
#include "qUtil.h"
|
||||
|
||||
|
@ -59,77 +57,25 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
|
|||
}
|
||||
}
|
||||
|
||||
// todo merge with vnode side function
|
||||
void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema) {
|
||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
pCtx[i].order = pQueryInfo->order.order;
|
||||
pCtx[i].functionId = pExpr->base.functionId;
|
||||
|
||||
pCtx[i].order = pQueryInfo->order.order;
|
||||
pCtx[i].functionId = pExpr->base.functionId;
|
||||
|
||||
// input data format comes from pModel
|
||||
pCtx[i].inputType = pSchema[i].type;
|
||||
pCtx[i].inputBytes = pSchema[i].bytes;
|
||||
|
||||
pCtx[i].outputBytes = pExpr->base.resBytes;
|
||||
pCtx[i].outputType = pExpr->base.resType;
|
||||
|
||||
// input buffer hold only one point data
|
||||
pCtx[i].size = 1;
|
||||
pCtx[i].hasNull = true;
|
||||
pCtx[i].currentStage = MERGE_STAGE;
|
||||
|
||||
// for top/bottom function, the output of timestamp is the first column
|
||||
int32_t functionId = pExpr->base.functionId;
|
||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
|
||||
pCtx[i].ptsOutputBuf = pCtx[0].pOutput;
|
||||
pCtx[i].param[2].i64 = pQueryInfo->order.order;
|
||||
pCtx[i].param[2].nType = TSDB_DATA_TYPE_BIGINT;
|
||||
pCtx[i].param[1].i64 = pQueryInfo->order.orderColId;
|
||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64; // top/bot parameter
|
||||
} else if (functionId == TSDB_FUNC_APERCT) {
|
||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64;
|
||||
pCtx[i].param[0].nType = pExpr->base.param[0].nType;
|
||||
} else if (functionId == TSDB_FUNC_BLKINFO) {
|
||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64;
|
||||
pCtx[i].param[0].nType = pExpr->base.param[0].nType;
|
||||
pCtx[i].numOfParams = 1;
|
||||
}
|
||||
|
||||
pCtx[i].interBufBytes = pExpr->base.interBytes;
|
||||
pCtx[i].stableQuery = true;
|
||||
}
|
||||
}
|
||||
|
||||
void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||
SColumnModel *finalmodel, SColumnModel *pFFModel, SSqlObj *pSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
int32_t tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||
SQueryInfo* pQueryInfo, SLocalMerger **pMerger, int64_t id) {
|
||||
if (pMemBuffer == NULL) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
tscError("pMemBuffer:%p is NULL", pMemBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
tscError("0x%"PRIx64" %p pMemBuffer is NULL", id, pMemBuffer);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
if (pDesc->pColumnModel == NULL) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
tscError("0x%"PRIx64" no local buffer or intermediate result format model", pSql->self);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
tscError("0x%"PRIx64" no local buffer or intermediate result format model", id);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
int32_t numOfFlush = 0;
|
||||
for (int32_t i = 0; i < numOfBuffer; ++i) {
|
||||
int32_t len = pMemBuffer[i]->fileMeta.flushoutData.nLength;
|
||||
if (len == 0) {
|
||||
tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", pSql->self, i + 1);
|
||||
tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", id, i + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -137,41 +83,36 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
}
|
||||
|
||||
if (numOfFlush == 0 || numOfBuffer == 0) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty
|
||||
tscDebug("0x%"PRIx64" retrieved no data", pSql->self);
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
tscDebug("0x%"PRIx64" no data to retrieve", id);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (pDesc->pColumnModel->capacity >= pMemBuffer[0]->pageSize) {
|
||||
tscError("0x%"PRIx64" Invalid value of buffer capacity %d and page size %d ", pSql->self, pDesc->pColumnModel->capacity,
|
||||
tscError("0x%"PRIx64" Invalid value of buffer capacity %d and page size %d ", id, pDesc->pColumnModel->capacity,
|
||||
pMemBuffer[0]->pageSize);
|
||||
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
size_t size = sizeof(SLocalMerger) + POINTER_BYTES * numOfFlush;
|
||||
*pMerger = (SLocalMerger *) calloc(1, sizeof(SLocalMerger));
|
||||
if ((*pMerger) == NULL) {
|
||||
tscError("0x%"PRIx64" failed to create local merge structure, out of memory", id);
|
||||
|
||||
SLocalMerger *pMerger = (SLocalMerger *) calloc(1, size);
|
||||
if (pMerger == NULL) {
|
||||
tscError("0x%"PRIx64" failed to create local merge structure, out of memory", pSql->self);
|
||||
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMerger->pExtMemBuffer = pMemBuffer;
|
||||
pMerger->pLocalDataSrc = (SLocalDataSource **)&pMerger[1];
|
||||
assert(pMerger->pLocalDataSrc != NULL);
|
||||
(*pMerger)->pExtMemBuffer = pMemBuffer;
|
||||
(*pMerger)->pLocalDataSrc = calloc(numOfFlush, POINTER_BYTES);
|
||||
assert((*pMerger)->pLocalDataSrc != NULL);
|
||||
|
||||
pMerger->numOfBuffer = numOfFlush;
|
||||
pMerger->numOfVnode = numOfBuffer;
|
||||
(*pMerger)->numOfBuffer = numOfFlush;
|
||||
(*pMerger)->numOfVnode = numOfBuffer;
|
||||
|
||||
pMerger->pDesc = pDesc;
|
||||
tscDebug("0x%"PRIx64" the number of merged leaves is: %d", pSql->self, pMerger->numOfBuffer);
|
||||
(*pMerger)->pDesc = pDesc;
|
||||
tscDebug("0x%"PRIx64" the number of merged leaves is: %d", id, (*pMerger)->numOfBuffer);
|
||||
|
||||
int32_t idx = 0;
|
||||
for (int32_t i = 0; i < numOfBuffer; ++i) {
|
||||
|
@ -180,13 +121,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
for (int32_t j = 0; j < numOfFlushoutInFile; ++j) {
|
||||
SLocalDataSource *ds = (SLocalDataSource *)malloc(sizeof(SLocalDataSource) + pMemBuffer[0]->pageSize);
|
||||
if (ds == NULL) {
|
||||
tscError("0x%"PRIx64" failed to create merge structure", pSql->self);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscError("0x%"PRIx64" failed to create merge structure", id);
|
||||
tfree(pMerger);
|
||||
return;
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMerger->pLocalDataSrc[idx] = ds;
|
||||
(*pMerger)->pLocalDataSrc[idx] = ds;
|
||||
|
||||
ds->pMemBuffer = pMemBuffer[i];
|
||||
ds->flushoutIdx = j;
|
||||
|
@ -194,12 +134,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
ds->pageId = 0;
|
||||
ds->rowIdx = 0;
|
||||
|
||||
tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", pSql->self, i + 1, idx + 1);
|
||||
tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", id, i + 1, idx + 1);
|
||||
tExtMemBufferLoadData(pMemBuffer[i], &(ds->filePage), j, 0);
|
||||
#ifdef _DEBUG_VIEW
|
||||
printf("load data page into mem for build loser tree: %" PRIu64 " rows\n", ds->filePage.num);
|
||||
SSrcColumnInfo colInfo[256] = {0};
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
||||
|
||||
|
@ -208,7 +148,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
#endif
|
||||
|
||||
if (ds->filePage.num == 0) { // no data in this flush, the index does not increase
|
||||
tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", pSql->self, idx);
|
||||
tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", id, idx);
|
||||
tfree(ds);
|
||||
continue;
|
||||
}
|
||||
|
@ -219,115 +159,54 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
|
||||
// no data actually, no need to merge result.
|
||||
if (idx == 0) {
|
||||
tfree(pMerger);
|
||||
return;
|
||||
tscDebug("0x%"PRIx64" retrieved no data", id);
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pMerger->numOfBuffer = idx;
|
||||
(*pMerger)->numOfBuffer = idx;
|
||||
|
||||
SCompareParam *param = malloc(sizeof(SCompareParam));
|
||||
if (param == NULL) {
|
||||
tfree(pMerger);
|
||||
return;
|
||||
tfree((*pMerger));
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
param->pLocalData = pMerger->pLocalDataSrc;
|
||||
param->pDesc = pMerger->pDesc;
|
||||
param->num = pMerger->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
param->pLocalData = (*pMerger)->pLocalDataSrc;
|
||||
param->pDesc = (*pMerger)->pDesc;
|
||||
param->num = (*pMerger)->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage;
|
||||
|
||||
param->groupOrderType = pQueryInfo->groupbyExpr.orderType;
|
||||
pMerger->orderPrjOnSTable = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0);
|
||||
|
||||
pRes->code = tLoserTreeCreate(&pMerger->pLoserTree, pMerger->numOfBuffer, param, treeComparator);
|
||||
if (pMerger->pLoserTree == NULL || pRes->code != 0) {
|
||||
int32_t code = tLoserTreeCreate(&(*pMerger)->pLoserTree, (*pMerger)->numOfBuffer, param, treeComparator);
|
||||
if ((*pMerger)->pLoserTree == NULL || code != TSDB_CODE_SUCCESS) {
|
||||
tfree(param);
|
||||
tfree(pMerger);
|
||||
return;
|
||||
tfree((*pMerger));
|
||||
return code;
|
||||
}
|
||||
|
||||
// the input data format follows the old format, but output in a new format.
|
||||
// so, all the input must be parsed as old format
|
||||
pMerger->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx));
|
||||
pMerger->rowSize = pMemBuffer[0]->nElemSize;
|
||||
(*pMerger)->rowSize = pMemBuffer[0]->nElemSize;
|
||||
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
// todo fixed row size is larger than the minimum page size;
|
||||
assert((*pMerger)->rowSize <= pMemBuffer[0]->pageSize);
|
||||
|
||||
if (pMerger->rowSize > pMemBuffer[0]->pageSize) {
|
||||
assert(false); // todo fixed row size is larger than the minimum page size;
|
||||
}
|
||||
|
||||
// used to keep the latest input row
|
||||
pMerger->pTempBuffer = (tFilePage *)calloc(1, pMerger->rowSize + sizeof(tFilePage));
|
||||
|
||||
pMerger->nResultBufSize = pMemBuffer[0]->pageSize * 16;
|
||||
pMerger->pResultBuf = (tFilePage *)calloc(1, pMerger->nResultBufSize + sizeof(tFilePage));
|
||||
|
||||
pMerger->resColModel = finalmodel;
|
||||
pMerger->resColModel->capacity = pMerger->nResultBufSize;
|
||||
pMerger->finalModel = pFFModel;
|
||||
|
||||
if (finalmodel->rowSize > 0) {
|
||||
pMerger->resColModel->capacity /= finalmodel->rowSize;
|
||||
}
|
||||
|
||||
assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pMerger->rowSize);
|
||||
|
||||
if (pMerger->pTempBuffer == NULL || pMerger->pLoserTree == NULL) {
|
||||
tfree(pMerger->pTempBuffer);
|
||||
tfree(pMerger->pLoserTree);
|
||||
if ((*pMerger)->pLoserTree == NULL) {
|
||||
tfree((*pMerger)->pLoserTree);
|
||||
tfree(param);
|
||||
tfree(pMerger);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return;
|
||||
tfree((*pMerger));
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMerger->pTempBuffer->num = 0;
|
||||
tscCreateResPointerInfo(pRes, pQueryInfo);
|
||||
|
||||
SSchema* pschema = calloc(pDesc->pColumnModel->numOfCols, sizeof(SSchema));
|
||||
for(int32_t i = 0; i < pDesc->pColumnModel->numOfCols; ++i) {
|
||||
pschema[i] = pDesc->pColumnModel->pFields[i].field;
|
||||
}
|
||||
|
||||
tsCreateSQLFunctionCtx(pQueryInfo, pMerger->pCtx, pschema);
|
||||
// setCtxInputOutputBuffer(pQueryInfo, pMerger->pCtx, pMerger, pDesc);
|
||||
|
||||
tfree(pschema);
|
||||
|
||||
int32_t maxBufSize = 0;
|
||||
for (int32_t k = 0; k < tscSqlExprNumOfExprs(pQueryInfo); ++k) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
if (maxBufSize < pExpr->base.resBytes && pExpr->base.functionId == TSDB_FUNC_TAG) {
|
||||
maxBufSize = pExpr->base.resBytes;
|
||||
}
|
||||
}
|
||||
|
||||
// we change the capacity of schema to denote that there is only one row in temp buffer
|
||||
pMerger->pDesc->pColumnModel->capacity = 1;
|
||||
|
||||
// restore the limitation value at the last stage
|
||||
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
pQueryInfo->limit.limit = pQueryInfo->clauseLimit;
|
||||
pQueryInfo->limit.offset = pQueryInfo->prjOffset;
|
||||
}
|
||||
|
||||
pRes->pLocalMerger = pMerger;
|
||||
pRes->numOfGroups = 0;
|
||||
// we change the capacity of schema to denote that there is only one row in temp buffer
|
||||
(*pMerger)->pDesc->pColumnModel->capacity = 1;
|
||||
|
||||
// STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
// STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
|
||||
// TSKEY stime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.skey : pQueryInfo->window.ekey;
|
||||
// int64_t revisedSTime = taosTimeTruncate(stime, &pQueryInfo->interval, tinfo.precision);
|
||||
|
||||
// if (pQueryInfo->fillType != TSDB_FILL_NONE) {
|
||||
// SFillColInfo* pFillCol = createFillColInfo(pQueryInfo);
|
||||
// pMerger->pFillInfo =
|
||||
// taosCreateFillInfo(pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols, 4096,
|
||||
// (int32_t)pQueryInfo->fieldsInfo.numOfOutput, pQueryInfo->interval.sliding,
|
||||
// pQueryInfo->interval.slidingUnit, tinfo.precision, pQueryInfo->fillType, pFillCol, pSql);
|
||||
// }
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage,
|
||||
|
@ -418,44 +297,32 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tscDestroyLocalMerger(SSqlObj *pSql) {
|
||||
if (pSql == NULL) {
|
||||
void tscDestroyLocalMerger(SLocalMerger* pLocalMerger) {
|
||||
if (pLocalMerger == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSqlRes *pRes = &(pSql->res);
|
||||
if (pRes->pLocalMerger == NULL) {
|
||||
return;
|
||||
for (int32_t i = 0; i < pLocalMerger->numOfBuffer; ++i) {
|
||||
tfree(pLocalMerger->pLocalDataSrc[i]);
|
||||
}
|
||||
|
||||
// there is no more result, so we release all allocated resource
|
||||
SLocalMerger *pLocalMerge = (SLocalMerger *)atomic_exchange_ptr(&pRes->pLocalMerger, NULL);
|
||||
tfree(pLocalMerge->pResultBuf);
|
||||
tfree(pLocalMerge->pCtx);
|
||||
pLocalMerger->numOfBuffer = 0;
|
||||
tscLocalReducerEnvDestroy(pLocalMerger->pExtMemBuffer, pLocalMerger->pDesc, pLocalMerger->numOfVnode);
|
||||
|
||||
if (pLocalMerge->pLoserTree) {
|
||||
tfree(pLocalMerge->pLoserTree->param);
|
||||
tfree(pLocalMerge->pLoserTree);
|
||||
pLocalMerger->numOfCompleted = 0;
|
||||
|
||||
if (pLocalMerger->pLoserTree) {
|
||||
tfree(pLocalMerger->pLoserTree->param);
|
||||
tfree(pLocalMerger->pLoserTree);
|
||||
}
|
||||
|
||||
tscLocalReducerEnvDestroy(pLocalMerge->pExtMemBuffer, pLocalMerge->pDesc, pLocalMerge->resColModel,
|
||||
pLocalMerge->finalModel, pLocalMerge->numOfVnode);
|
||||
for (int32_t i = 0; i < pLocalMerge->numOfBuffer; ++i) {
|
||||
tfree(pLocalMerge->pLocalDataSrc[i]);
|
||||
tfree(pLocalMerger->buf);
|
||||
tfree(pLocalMerger->pLocalDataSrc);
|
||||
free(pLocalMerger);
|
||||
}
|
||||
|
||||
pLocalMerge->numOfBuffer = 0;
|
||||
pLocalMerge->numOfCompleted = 0;
|
||||
tfree(pLocalMerge->pTempBuffer);
|
||||
|
||||
free(pLocalMerge);
|
||||
|
||||
tscDebug("0x%"PRIx64" free local reducer finished", pSql->self);
|
||||
}
|
||||
|
||||
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) {
|
||||
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SQueryInfo* pQueryInfo, SColumnModel *pModel) {
|
||||
int32_t numOfGroupByCols = 0;
|
||||
SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd);
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||
numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||
|
@ -474,13 +341,13 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
|||
if (numOfGroupByCols > 0) {
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||
int32_t numOfInternalOutput = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
int32_t numOfInternalOutput = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||
|
||||
// the last "pQueryInfo->groupbyExpr.numOfGroupCols" columns are order-by columns
|
||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
|
||||
for(int32_t j = 0; j < numOfInternalOutput; ++j) {
|
||||
SExprInfo* pExprInfo = tscSqlExprGet(pQueryInfo, j);
|
||||
SExprInfo* pExprInfo = tscExprGet(pQueryInfo, j);
|
||||
|
||||
int32_t functionId = pExprInfo->base.functionId;
|
||||
if (pColIndex->colId == pExprInfo->base.colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG)) {
|
||||
|
@ -502,9 +369,9 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
|||
if (pQueryInfo->interval.interval != 0) {
|
||||
orderColIndexList[0] = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||
} else {
|
||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
size_t size = tscNumOfExprs(pQueryInfo);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||
if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
orderColIndexList[0] = i;
|
||||
}
|
||||
|
@ -525,37 +392,30 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
|||
}
|
||||
}
|
||||
|
||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc,
|
||||
SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSizes) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
int32_t tscLocalReducerEnvCreate(SQueryInfo *pQueryInfo, tExtMemBuffer ***pMemBuffer, int32_t numOfSub,
|
||||
tOrderDescriptor **pOrderDesc, uint32_t nBufferSizes, int64_t id) {
|
||||
SSchema *pSchema = NULL;
|
||||
SColumnModel *pModel = NULL;
|
||||
*pFinalModel = NULL;
|
||||
|
||||
SQueryInfo * pQueryInfo = tscGetActiveQueryInfo(pCmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pSql->subState.numOfSub);
|
||||
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * numOfSub);
|
||||
if (*pMemBuffer == NULL) {
|
||||
tscError("0x%"PRIx64" failed to allocate memory", pSql->self);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pRes->code;
|
||||
tscError("0x%"PRIx64" failed to allocate memory", id);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
size_t size = tscNumOfExprs(pQueryInfo);
|
||||
|
||||
pSchema = (SSchema *)calloc(1, sizeof(SSchema) * size);
|
||||
if (pSchema == NULL) {
|
||||
tscError("0x%"PRIx64" failed to allocate memory", pSql->self);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pRes->code;
|
||||
tscError("0x%"PRIx64" failed to allocate memory", id);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t rlen = 0;
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||
|
||||
pSchema[i].bytes = pExpr->base.resBytes;
|
||||
pSchema[i].type = (int8_t)pExpr->base.resType;
|
||||
|
@ -570,6 +430,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
}
|
||||
|
||||
pModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
||||
tfree(pSchema);
|
||||
|
||||
int32_t pg = DEFAULT_PAGE_SIZE;
|
||||
int32_t overhead = sizeof(tFilePage);
|
||||
|
@ -577,95 +438,26 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
pg *= 2;
|
||||
}
|
||||
|
||||
size_t numOfSubs = pSql->subState.numOfSub;
|
||||
assert(numOfSubs <= pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
for (int32_t i = 0; i < numOfSubs; ++i) {
|
||||
assert(numOfSub <= pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
for (int32_t i = 0; i < numOfSub; ++i) {
|
||||
(*pMemBuffer)[i] = createExtMemBuffer(nBufferSizes, rlen, pg, pModel);
|
||||
(*pMemBuffer)[i]->flushModel = MULTIPLE_APPEND_MODEL;
|
||||
}
|
||||
|
||||
if (createOrderDescriptor(pOrderDesc, pCmd, pModel) != TSDB_CODE_SUCCESS) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tfree(pSchema);
|
||||
return pRes->code;
|
||||
if (createOrderDescriptor(pOrderDesc, pQueryInfo, pModel) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// final result depends on the fields number
|
||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
SSchema p1 = {0};
|
||||
if (pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
p1 = *tGetTbnameColumnSchema();
|
||||
} else if (TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag)) {
|
||||
p1.bytes = pExpr->base.resBytes;
|
||||
p1.type = (uint8_t) pExpr->base.resType;
|
||||
tstrncpy(p1.name, pExpr->base.aliasName, tListLen(p1.name));
|
||||
} else {
|
||||
p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex);
|
||||
}
|
||||
|
||||
int32_t inter = 0;
|
||||
int16_t type = -1;
|
||||
int16_t bytes = 0;
|
||||
|
||||
// the final result size and type in the same as query on single table.
|
||||
// so here, set the flag to be false;
|
||||
int32_t functionId = pExpr->base.functionId;
|
||||
if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) {
|
||||
type = pModel->pFields[i].field.type;
|
||||
bytes = pModel->pFields[i].field.bytes;
|
||||
} else {
|
||||
if (functionId == TSDB_FUNC_FIRST_DST) {
|
||||
functionId = TSDB_FUNC_FIRST;
|
||||
} else if (functionId == TSDB_FUNC_LAST_DST) {
|
||||
functionId = TSDB_FUNC_LAST;
|
||||
} else if (functionId == TSDB_FUNC_STDDEV_DST) {
|
||||
functionId = TSDB_FUNC_STDDEV;
|
||||
}
|
||||
|
||||
int32_t ret = getResultDataInfo(p1.type, p1.bytes, functionId, 0, &type, &bytes, &inter, 0, false);
|
||||
assert(ret == TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
pSchema[i].type = (uint8_t)type;
|
||||
pSchema[i].bytes = bytes;
|
||||
strcpy(pSchema[i].name, pModel->pFields[i].field.name);
|
||||
}
|
||||
|
||||
*pFinalModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
||||
|
||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
||||
size = tscNumOfFields(pQueryInfo);
|
||||
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i);
|
||||
pSchema[i].bytes = pField->field.bytes;
|
||||
pSchema[i].type = pField->field.type;
|
||||
tstrncpy(pSchema[i].name, pField->field.name, tListLen(pSchema[i].name));
|
||||
}
|
||||
|
||||
*pFFModel = createColumnModel(pSchema, (int32_t) size, capacity);
|
||||
|
||||
tfree(pSchema);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pMemBuffer
|
||||
* @param pDesc
|
||||
* @param pFinalModel
|
||||
* @param numOfVnodes
|
||||
*/
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel *pFFModel,
|
||||
int32_t numOfVnodes) {
|
||||
destroyColumnModel(pFinalModel);
|
||||
destroyColumnModel(pFFModel);
|
||||
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes) {
|
||||
tOrderDescDestroy(pDesc);
|
||||
|
||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||
pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]);
|
||||
}
|
||||
|
@ -877,10 +669,12 @@ static bool isAllSourcesCompleted(SLocalMerger *pLocalMerge) {
|
|||
return (pLocalMerge->numOfBuffer == pLocalMerge->numOfCompleted);
|
||||
}
|
||||
|
||||
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) {
|
||||
SSqlRes *pRes = &pObj->res;
|
||||
void tscInitResObjForLocalQuery(SSqlObj *pSql, int32_t numOfRes, int32_t rowLen) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
if (pRes->pLocalMerger != NULL) {
|
||||
tscDestroyLocalMerger(pObj);
|
||||
tscDestroyLocalMerger(pRes->pLocalMerger);
|
||||
pRes->pLocalMerger = NULL;
|
||||
tscDebug("0x%"PRIx64" free local reducer finished", pSql->self);
|
||||
}
|
||||
|
||||
pRes->qId = 1; // hack to pass the safety check in fetch_row function
|
||||
|
@ -891,14 +685,12 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
|
|||
pRes->pLocalMerger = (SLocalMerger *)calloc(1, sizeof(SLocalMerger));
|
||||
|
||||
/*
|
||||
* we need one additional byte space
|
||||
* the sprintf function needs one additional space to put '\0' at the end of string
|
||||
* One more byte space is required, since the sprintf function needs one additional space to put '\0' at
|
||||
* the end of string
|
||||
*/
|
||||
size_t allocSize = numOfRes * rowLen + sizeof(tFilePage) + 1;
|
||||
pRes->pLocalMerger->pResultBuf = (tFilePage *)calloc(1, allocSize);
|
||||
|
||||
pRes->pLocalMerger->pResultBuf->num = numOfRes;
|
||||
pRes->data = pRes->pLocalMerger->pResultBuf->data;
|
||||
size_t size = numOfRes * rowLen + 1;
|
||||
pRes->pLocalMerger->buf = calloc(1, size);
|
||||
pRes->data = pRes->pLocalMerger->buf;
|
||||
}
|
||||
|
||||
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
|
||||
|
@ -910,12 +702,12 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
|||
|
||||
// todo refactor
|
||||
arithSup.offset = 0;
|
||||
arithSup.numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
arithSup.numOfCols = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||
arithSup.exprList = pQueryInfo->exprList;
|
||||
arithSup.data = calloc(arithSup.numOfCols, POINTER_BYTES);
|
||||
|
||||
for(int32_t k = 0; k < arithSup.numOfCols; ++k) {
|
||||
SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
SExprInfo* pExpr = tscExprGet(pQueryInfo, k);
|
||||
arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->base.offset);
|
||||
}
|
||||
|
||||
|
@ -944,8 +736,8 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
|||
return offset;
|
||||
}
|
||||
|
||||
#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \
|
||||
(data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes)
|
||||
#define COLMODEL_GET_VAL(data, schema, rowId, colId) \
|
||||
(data + (schema)->pFields[colId].offset * ((schema)->capacity) + (rowId) * (schema)->pFields[colId].field.bytes)
|
||||
|
||||
static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel *pModel, int32_t rowIndex,
|
||||
int32_t maxRows) {
|
||||
|
@ -953,7 +745,7 @@ static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel
|
|||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
|
||||
char* p = pColInfo->pData + pBlock->info.rows * pColInfo->info.bytes;
|
||||
|
||||
char *src = COLMODEL_GET_VAL(buf, pModel, maxRows, rowIndex, i);
|
||||
char *src = COLMODEL_GET_VAL(buf, pModel, rowIndex, i);
|
||||
memmove(p, src, pColInfo->info.bytes);
|
||||
}
|
||||
|
||||
|
@ -970,8 +762,6 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
|
||||
SLocalMerger *pMerger = pInfo->pMerge;
|
||||
SLoserTreeInfo *pTree = pMerger->pLoserTree;
|
||||
SColumnModel *pModel = pMerger->pDesc->pColumnModel;
|
||||
tFilePage *tmpBuffer = pMerger->pTempBuffer;
|
||||
|
||||
pInfo->binfo.pRes->info.rows = 0;
|
||||
|
||||
|
@ -984,7 +774,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
printf("chosen data in pTree[0] = %d\n", pTree->pNode[0].index);
|
||||
#endif
|
||||
|
||||
assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0) && tmpBuffer->num == 0);
|
||||
assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0));
|
||||
|
||||
// chosen from loser tree
|
||||
SLocalDataSource *pOneDataSrc = pMerger->pLocalDataSrc[pTree->pNode[0].index];
|
||||
|
@ -997,8 +787,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i);
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex);
|
||||
|
||||
char *newRow =
|
||||
COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity,
|
||||
char *newRow = COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||
pOneDataSrc->rowIdx, pIndex->colIndex);
|
||||
|
||||
char *data = pInfo->prevRow[i];
|
||||
|
@ -1020,8 +809,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i);
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex);
|
||||
|
||||
char *curCol =
|
||||
COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity,
|
||||
char *curCol = COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||
pOneDataSrc->rowIdx, pIndex->colIndex);
|
||||
memcpy(pInfo->prevRow[i], curCol, pColInfo->info.bytes);
|
||||
}
|
||||
|
@ -1033,7 +821,8 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
return pInfo->binfo.pRes;
|
||||
}
|
||||
|
||||
appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pModel, pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity);
|
||||
appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||
pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity);
|
||||
|
||||
#if defined(_DEBUG_VIEW)
|
||||
printf("chosen row:\t");
|
||||
|
@ -1082,7 +871,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
|||
}
|
||||
|
||||
SMultiwayMergeInfo *pAggInfo = pOperator->info;
|
||||
SOperatorInfo *upstream = pOperator->upstream;
|
||||
SOperatorInfo *upstream = pOperator->upstream[0];
|
||||
|
||||
*newgroup = false;
|
||||
bool handleData = false;
|
||||
|
@ -1166,7 +955,6 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
|||
if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && pRes->info.rows > 0) {
|
||||
STimeWindow* w = &pRes->info.window;
|
||||
|
||||
// TODO in case of desc order, swap it
|
||||
w->skey = *(int64_t*)pInfoData->pData;
|
||||
w->ekey = *(int64_t*)(((char*)pInfoData->pData) + TSDB_KEYSIZE * (pRes->info.rows - 1));
|
||||
|
||||
|
@ -1186,7 +974,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
|
||||
SSDataBlock* pBlock = NULL;
|
||||
if (pInfo->currentGroupOffset == 0) {
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
@ -1194,7 +982,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
|
||||
if (*newgroup == false && pInfo->limit.limit > 0 && pInfo->rowsTotal >= pInfo->limit.limit) {
|
||||
while ((*newgroup) == false) { // ignore the remain blocks
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
@ -1206,7 +994,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
return pBlock;
|
||||
}
|
||||
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
@ -1220,7 +1008,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
}
|
||||
|
||||
while ((*newgroup) == false) {
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
|
|
@ -107,7 +107,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1
|
|||
}
|
||||
|
||||
if (parseAbsoluteDuration(valueToken.z, valueToken.n, &interval) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (timePrec == TSDB_TIME_PRECISION_MILLI) {
|
||||
|
@ -441,7 +441,7 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1
|
|||
*str += index;
|
||||
|
||||
if (sToken.type == TK_QUESTION) {
|
||||
if (pCmd->insertType != TSDB_QUERY_TYPE_STMT_INSERT) {
|
||||
if (pCmd->insertParam.insertType != TSDB_QUERY_TYPE_STMT_INSERT) {
|
||||
return tscSQLSyntaxErrMsg(pCmd->payload, "? only allowed in binding insertion", *str);
|
||||
}
|
||||
|
||||
|
@ -647,7 +647,7 @@ static int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta,
|
|||
pBlocks->sversion = pTableMeta->sversion;
|
||||
|
||||
if (pBlocks->numOfRows + numOfRows >= INT16_MAX) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
} else {
|
||||
pBlocks->numOfRows += numOfRows;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -708,7 +708,7 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlock
|
|||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
char tmpTokenBuf[16*1024] = {0}; // used for deleting Escape character: \\, \', \"
|
||||
|
||||
int32_t numOfRows = 0;
|
||||
|
@ -747,12 +747,10 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
const int32_t STABLE_INDEX = 1;
|
||||
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
char *sql = *sqlstr;
|
||||
|
||||
pSql->cmd.autoCreated = false;
|
||||
|
||||
// get the token of specified table
|
||||
index = 0;
|
||||
tableToken = tStrGetToken(sql, &index, false);
|
||||
|
@ -786,7 +784,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
}
|
||||
|
||||
if (numOfColList == 0 && (*boundColumn) != NULL) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
|
||||
|
@ -802,7 +800,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
}
|
||||
|
||||
STableMetaInfo *pSTableMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
|
||||
code = tscSetTableFullName(pSTableMetaInfo, &sToken, pSql);
|
||||
code = tscSetTableFullName(&pSTableMetaInfo->name, &sToken, pSql);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -879,7 +877,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
if (TK_ILLEGAL == sToken.type) {
|
||||
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||
tscDestroyBoundColumnInfo(&spd);
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (sToken.n == 0 || sToken.type == TK_RP) {
|
||||
|
@ -961,7 +959,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
}
|
||||
|
||||
if (numOfColsAfterTags == 0 && (*boundColumn) != NULL) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sToken = tStrGetToken(sql, &index, false);
|
||||
|
@ -973,13 +971,13 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
return tscInvalidSQLErrMsg(pCmd->payload, "invalid table name", *sqlstr);
|
||||
}
|
||||
|
||||
int32_t ret = tscSetTableFullName(pTableMetaInfo, &tableToken, pSql);
|
||||
int32_t ret = tscSetTableFullName(&pTableMetaInfo->name, &tableToken, pSql);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (sql == NULL) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, true);
|
||||
|
@ -991,7 +989,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
sql = sToken.z;
|
||||
|
||||
if (sql == NULL) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, false);
|
||||
|
@ -1015,12 +1013,17 @@ int validateTableName(char *tblName, int len, SStrToken* psTblToken) {
|
|||
return tscValidateName(psTblToken);
|
||||
}
|
||||
|
||||
static int32_t validateDataSource(SSqlCmd *pCmd, int8_t type, const char *sql) {
|
||||
if (pCmd->dataSourceType != 0 && pCmd->dataSourceType != type) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up", sql);
|
||||
static int32_t validateDataSource(SSqlCmd *pCmd, int32_t type, const char *sql) {
|
||||
uint32_t *insertType = &pCmd->insertParam.insertType;
|
||||
if (*insertType == TSDB_QUERY_TYPE_STMT_INSERT && type == TSDB_QUERY_TYPE_INSERT) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pCmd->dataSourceType = type;
|
||||
if ((*insertType) != 0 && (*insertType) != type) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mixed up", sql);
|
||||
}
|
||||
|
||||
*insertType = type;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1090,7 +1093,6 @@ static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SS
|
|||
|
||||
_clean:
|
||||
pCmd->curSql = NULL;
|
||||
pCmd->parseFinished = 1;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1106,7 +1108,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
int32_t totalNum = 0;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
assert(pQueryInfo != NULL);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = (pQueryInfo->numOfTables == 0)? tscAddEmptyMetaInfo(pQueryInfo):tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
@ -1120,9 +1122,9 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
return code;
|
||||
}
|
||||
|
||||
if (NULL == pCmd->pTableBlockHashList) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (NULL == pCmd->pTableBlockHashList) {
|
||||
if (NULL == pCmd->insertParam.pTableBlockHashList) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (NULL == pCmd->insertParam.pTableBlockHashList) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _clean;
|
||||
}
|
||||
|
@ -1130,7 +1132,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
str = pCmd->curSql;
|
||||
}
|
||||
|
||||
tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pCmd->pTableBlockHashList);
|
||||
tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pCmd->insertParam.pTableBlockHashList);
|
||||
|
||||
while (1) {
|
||||
int32_t index = 0;
|
||||
|
@ -1142,7 +1144,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
* if the data is from the data file, no data has been generated yet. So, there no data to
|
||||
* merge or submit, save the file path and parse the file in other routines.
|
||||
*/
|
||||
if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) {
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
|
@ -1151,7 +1153,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
* Otherwise, create the first submit block and submit to virtual node.
|
||||
*/
|
||||
if (totalNum == 0) {
|
||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
goto _clean;
|
||||
} else {
|
||||
break;
|
||||
|
@ -1168,7 +1170,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
goto _clean;
|
||||
}
|
||||
|
||||
if ((code = tscSetTableFullName(pTableMetaInfo, &sTblToken, pSql)) != TSDB_CODE_SUCCESS) {
|
||||
if ((code = tscSetTableFullName(&pTableMetaInfo->name, &sTblToken, pSql)) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
|
@ -1203,7 +1205,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
if (sToken.type == TK_FILE) {
|
||||
if (validateDataSource(pCmd, DATA_FROM_DATA_FILE, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
if (validateDataSource(pCmd, TSDB_QUERY_TYPE_FILE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
|
@ -1236,12 +1238,12 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
if (bindedColumns == NULL) {
|
||||
STableMeta *pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
|
||||
if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
if (validateDataSource(pCmd, TSDB_QUERY_TYPE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
STableDataBlocks *dataBuf = NULL;
|
||||
int32_t ret = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
int32_t ret = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta,
|
||||
&dataBuf, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1254,14 +1256,14 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
}
|
||||
} else { // bindedColumns != NULL
|
||||
// insert into tablename(col1, col2,..., coln) values(v1, v2,... vn);
|
||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta;
|
||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, 0)->pTableMeta;
|
||||
|
||||
if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
if (validateDataSource(pCmd, TSDB_QUERY_TYPE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
STableDataBlocks *dataBuf = NULL;
|
||||
int32_t ret = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
int32_t ret = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta,
|
||||
&dataBuf, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1297,7 +1299,8 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
goto _clean;
|
||||
}
|
||||
|
||||
if ((pCmd->insertType != TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pCmd->pTableBlockHashList) > 0) { // merge according to vgId
|
||||
// merge according to vgId
|
||||
if (!TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pCmd->insertParam.pTableBlockHashList) > 0) {
|
||||
if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
@ -1308,7 +1311,6 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
|
||||
_clean:
|
||||
pCmd->curSql = NULL;
|
||||
pCmd->parseFinished = 1;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1326,9 +1328,8 @@ int tsInsertInitialCheck(SSqlObj *pSql) {
|
|||
pCmd->count = 0;
|
||||
pCmd->command = TSDB_SQL_INSERT;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex);
|
||||
|
||||
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT | pCmd->insertType);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd);
|
||||
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT);
|
||||
|
||||
sToken = tStrGetToken(pSql->sqlstr, &index, false);
|
||||
if (sToken.type != TK_INTO) {
|
||||
|
@ -1343,11 +1344,11 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
|
|||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
if ((!pCmd->parseFinished) && (!initial)) {
|
||||
if (!initial) {
|
||||
tscDebug("0x%"PRIx64" resume to parse sql: %s", pSql->self, pCmd->curSql);
|
||||
}
|
||||
|
||||
ret = tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
ret = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
if (TSDB_CODE_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1357,31 +1358,32 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
// make a backup as tsParseInsertSql may modify the string
|
||||
char* sqlstr = strdup(pSql->sqlstr);
|
||||
ret = tsParseInsertSql(pSql);
|
||||
if ((sqlstr == NULL) || (pSql->parseRetry >= 1) ||
|
||||
(ret != TSDB_CODE_TSC_SQL_SYNTAX_ERROR && ret != TSDB_CODE_TSC_INVALID_SQL)) {
|
||||
free(sqlstr);
|
||||
} else {
|
||||
assert(ret == TSDB_CODE_SUCCESS || ret == TSDB_CODE_TSC_ACTION_IN_PROGRESS || ret == TSDB_CODE_TSC_SQL_SYNTAX_ERROR || ret == TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
if (pSql->parseRetry < 1 && (ret == TSDB_CODE_TSC_SQL_SYNTAX_ERROR || ret == TSDB_CODE_TSC_INVALID_OPERATION)) {
|
||||
tscDebug("0x%"PRIx64 " parse insert sql statement failed, code:%s, clear meta cache and retry ", pSql->self, tstrerror(ret));
|
||||
|
||||
tscResetSqlCmd(pCmd, true);
|
||||
free(pSql->sqlstr);
|
||||
pSql->sqlstr = sqlstr;
|
||||
pSql->parseRetry++;
|
||||
|
||||
if ((ret = tsInsertInitialCheck(pSql)) == TSDB_CODE_SUCCESS) {
|
||||
ret = tsParseInsertSql(pSql);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SSqlInfo SQLInfo = qSqlParse(pSql->sqlstr);
|
||||
ret = tscToSQLCmd(pSql, &SQLInfo);
|
||||
if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) {
|
||||
SSqlInfo sqlInfo = qSqlParse(pSql->sqlstr);
|
||||
ret = tscValidateSqlInfo(pSql, &sqlInfo);
|
||||
if (ret == TSDB_CODE_TSC_INVALID_OPERATION && pSql->parseRetry < 1 && sqlInfo.type == TSDB_SQL_SELECT) {
|
||||
tscDebug("0x%"PRIx64 " parse query sql statement failed, code:%s, clear meta cache and retry ", pSql->self, tstrerror(ret));
|
||||
|
||||
tscResetSqlCmd(pCmd, true);
|
||||
pSql->parseRetry++;
|
||||
ret = tscToSQLCmd(pSql, &SQLInfo);
|
||||
|
||||
ret = tscValidateSqlInfo(pSql, &sqlInfo);
|
||||
}
|
||||
|
||||
SqlInfoDestroy(&SQLInfo);
|
||||
SqlInfoDestroy(&sqlInfo);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1398,8 +1400,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
|
|||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
pSql->res.numOfRows = 0;
|
||||
|
||||
assert(pCmd->numOfClause == 1);
|
||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta;
|
||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, 0)->pTableMeta;
|
||||
|
||||
SSubmitBlk *pBlocks = (SSubmitBlk *)(pTableDataBlocks->pData);
|
||||
code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
|
@ -1411,7 +1412,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
|
|||
return code;
|
||||
}
|
||||
|
||||
STableDataBlocks *pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0);
|
||||
STableDataBlocks *pDataBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, 0);
|
||||
if ((code = tscCopyDataBlockToPayload(pSql, pDataBlock)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -1461,17 +1462,17 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow
|
|||
// accumulate the total submit records
|
||||
pParentSql->res.numOfRows += pSql->res.numOfRows;
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
||||
|
||||
destroyTableNameList(pCmd);
|
||||
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks);
|
||||
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
@ -1479,7 +1480,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow
|
|||
|
||||
STableDataBlocks *pTableDataBlock = NULL;
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tinfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pTableDataBlock, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
pParentSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -1561,8 +1562,8 @@ void tscImportDataFromFile(SSqlObj *pSql) {
|
|||
return;
|
||||
}
|
||||
|
||||
assert(pCmd->dataSourceType == DATA_FROM_DATA_FILE && strlen(pCmd->payload) != 0);
|
||||
pCmd->active = pCmd->pQueryInfo[0];
|
||||
assert(TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT) && strlen(pCmd->payload) != 0);
|
||||
pCmd->active = pCmd->pQueryInfo;
|
||||
|
||||
SImportFileSupport *pSupporter = calloc(1, sizeof(SImportFileSupport));
|
||||
SSqlObj *pNew = createSubqueryObj(pSql, 0, parseFileSendDataBlock, pSupporter, TSDB_SQL_INSERT, NULL);
|
||||
|
|
|
@ -46,9 +46,13 @@ typedef struct SNormalStmt {
|
|||
|
||||
typedef struct SMultiTbStmt {
|
||||
bool nameSet;
|
||||
bool tagSet;
|
||||
uint64_t currentUid;
|
||||
uint32_t tbNum;
|
||||
SStrToken tbname;
|
||||
SStrToken stbname;
|
||||
SStrToken values;
|
||||
SArray *tags;
|
||||
SHashObj *pTableHash;
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
} SMultiTbStmt;
|
||||
|
@ -308,7 +312,7 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
|||
int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
||||
STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL);
|
||||
|
||||
STableDataBlocks* pOneTableBlock = *p;
|
||||
while(pOneTableBlock) {
|
||||
|
@ -317,7 +321,7 @@ int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
|||
fillColumnsNull(pOneTableBlock, pBlocks->numOfRows);
|
||||
}
|
||||
|
||||
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
||||
p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p);
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -840,12 +844,12 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
|||
STableDataBlocks* pBlock = NULL;
|
||||
|
||||
if (pStmt->multiTbInsert) {
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||
if (t1 == NULL) {
|
||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
|
@ -853,15 +857,15 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
|||
|
||||
pBlock = *t1;
|
||||
} else {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
|
@ -904,12 +908,12 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
|
|||
STableDataBlocks* pBlock = NULL;
|
||||
|
||||
if (pStmt->multiTbInsert) {
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||
if (t1 == NULL) {
|
||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
|
@ -917,15 +921,15 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
|
|||
|
||||
pBlock = *t1;
|
||||
} else {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
|
@ -991,12 +995,11 @@ static int insertStmtUpdateBatch(STscStmt* stmt) {
|
|||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
assert(pCmd->numOfClause == 1);
|
||||
if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) {
|
||||
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid));
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid));
|
||||
if (t1 == NULL) {
|
||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, stmt->mtb.currentUid);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
|
@ -1032,9 +1035,9 @@ static int insertStmtReset(STscStmt* pStmt) {
|
|||
if (pCmd->batchSize > 2) {
|
||||
int32_t alloced = (pCmd->batchSize + 1) / 2;
|
||||
|
||||
size_t size = taosArrayGetSize(pCmd->pDataBlocks);
|
||||
size_t size = taosArrayGetSize(pCmd->insertParam.pDataBlocks);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, i);
|
||||
STableDataBlocks* pBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, i);
|
||||
|
||||
uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk);
|
||||
pBlock->size = sizeof(SSubmitBlk) + totalDataSize / alloced;
|
||||
|
@ -1045,7 +1048,7 @@ static int insertStmtReset(STscStmt* pStmt) {
|
|||
}
|
||||
pCmd->batchSize = 0;
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
pTableMetaInfo->vgroupIndex = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1056,22 +1059,21 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
assert(pCmd->numOfClause == 1);
|
||||
if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) {
|
||||
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
STableDataBlocks* pBlock = NULL;
|
||||
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
assert(ret == 0);
|
||||
pBlock->size = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize;
|
||||
|
@ -1088,7 +1090,7 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
return code;
|
||||
}
|
||||
|
||||
STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0);
|
||||
STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, 0);
|
||||
code = tscCopyDataBlockToPayload(stmt->pSql, pDataBlock);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -1106,15 +1108,15 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
|
||||
// data block reset
|
||||
pCmd->batchSize = 0;
|
||||
for(int32_t i = 0; i < pCmd->numOfTables; ++i) {
|
||||
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
||||
tfree(pCmd->pTableNameList[i]);
|
||||
for(int32_t i = 0; i < pCmd->insertParam.numOfTables; ++i) {
|
||||
if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) {
|
||||
tfree(pCmd->insertParam.pTableNameList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pCmd->numOfTables = 0;
|
||||
tfree(pCmd->pTableNameList);
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
pCmd->insertParam.numOfTables = 0;
|
||||
tfree(pCmd->insertParam.pTableNameList);
|
||||
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks);
|
||||
|
||||
return pSql->res.code;
|
||||
}
|
||||
|
@ -1122,21 +1124,21 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
static void insertBatchClean(STscStmt* pStmt) {
|
||||
SSqlCmd *pCmd = &pStmt->pSql->cmd;
|
||||
SSqlObj *pSql = pStmt->pSql;
|
||||
int32_t size = taosHashGetSize(pCmd->pTableBlockHashList);
|
||||
int32_t size = taosHashGetSize(pCmd->insertParam.pTableBlockHashList);
|
||||
|
||||
// data block reset
|
||||
pCmd->batchSize = 0;
|
||||
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
||||
tfree(pCmd->pTableNameList[i]);
|
||||
if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) {
|
||||
tfree(pCmd->insertParam.pTableNameList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(pCmd->pTableNameList);
|
||||
tfree(pCmd->insertParam.pTableNameList);
|
||||
|
||||
/*
|
||||
STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
||||
STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL);
|
||||
|
||||
STableDataBlocks* pOneTableBlock = *p;
|
||||
|
||||
|
@ -1147,7 +1149,7 @@ static void insertBatchClean(STscStmt* pStmt) {
|
|||
|
||||
pBlocks->numOfRows = 0;
|
||||
|
||||
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
||||
p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p);
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -1156,10 +1158,10 @@ static void insertBatchClean(STscStmt* pStmt) {
|
|||
}
|
||||
*/
|
||||
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
pCmd->numOfTables = 0;
|
||||
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks);
|
||||
pCmd->insertParam.numOfTables = 0;
|
||||
|
||||
taosHashEmpty(pCmd->pTableBlockHashList);
|
||||
taosHashEmpty(pCmd->insertParam.pTableBlockHashList);
|
||||
tscFreeSqlResult(pSql);
|
||||
tscFreeSubobj(pSql);
|
||||
tfree(pSql->pSubs);
|
||||
|
@ -1176,7 +1178,7 @@ static int insertBatchStmtExecute(STscStmt* pStmt) {
|
|||
|
||||
pStmt->pSql->retry = pStmt->pSql->maxRetry + 1; //no retry
|
||||
|
||||
if (taosHashGetSize(pStmt->pSql->cmd.pTableBlockHashList) <= 0) { // merge according to vgId
|
||||
if (taosHashGetSize(pStmt->pSql->cmd.insertParam.pTableBlockHashList) <= 0) { // merge according to vgId
|
||||
tscError("0x%"PRIx64" no data block to insert", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
@ -1201,6 +1203,184 @@ static int insertBatchStmtExecute(STscStmt* pStmt) {
|
|||
return pStmt->pSql->res.code;
|
||||
}
|
||||
|
||||
|
||||
int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
|
||||
if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t index = 0;
|
||||
SStrToken sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n == 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (sToken.n == 1 && sToken.type == TK_QUESTION) {
|
||||
pStmt->multiTbInsert = true;
|
||||
pStmt->mtb.tbname = sToken;
|
||||
pStmt->mtb.nameSet = false;
|
||||
if (pStmt->mtb.pTableHash == NULL) {
|
||||
pStmt->mtb.pTableHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false);
|
||||
}
|
||||
|
||||
if (pStmt->mtb.pTableBlockHashList == NULL) {
|
||||
pStmt->mtb.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
pStmt->mtb.tagSet = true;
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n > 0 && sToken.type == TK_VALUES) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (sToken.n <= 0 || sToken.type != TK_USING) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
pStmt->mtb.stbname = sToken;
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0 || sToken.type != TK_TAGS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0 || sToken.type != TK_LP) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken));
|
||||
|
||||
int32_t loopCont = 1;
|
||||
|
||||
while (loopCont) {
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
switch (sToken.type) {
|
||||
case TK_RP:
|
||||
loopCont = 0;
|
||||
break;
|
||||
case TK_VALUES:
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
case TK_QUESTION:
|
||||
pStmt->mtb.tagSet = false; //continue
|
||||
default:
|
||||
taosArrayPush(pStmt->mtb.tags, &sToken);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pStmt->mtb.tags) <= 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0 || sToken.type != TK_VALUES) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
pStmt->mtb.values = sToken;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAOS_BIND* tags) {
|
||||
size_t tagNum = taosArrayGetSize(pStmt->mtb.tags);
|
||||
size_t size = 1048576;
|
||||
char *str = calloc(1, size);
|
||||
size_t len = 0;
|
||||
int32_t ret = 0;
|
||||
int32_t j = 0;
|
||||
|
||||
while (1) {
|
||||
len = (size_t)snprintf(str, size - 1, "insert into %s using %.*s tags(", name, pStmt->mtb.stbname.n, pStmt->mtb.stbname.z);
|
||||
if (len >= (size -1)) {
|
||||
size *= 2;
|
||||
free(str);
|
||||
str = calloc(1, size);
|
||||
continue;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
|
||||
for (size_t i = 0; i < tagNum && len < (size - 1); ++i) {
|
||||
SStrToken *t = taosArrayGet(pStmt->mtb.tags, i);
|
||||
if (t->type == TK_QUESTION) {
|
||||
int32_t l = 0;
|
||||
if (i > 0) {
|
||||
str[len++] = ',';
|
||||
}
|
||||
|
||||
if (tags[j].is_null && (*tags[j].is_null)) {
|
||||
ret = converToStr(str + len, TSDB_DATA_TYPE_NULL, NULL, -1, &l);
|
||||
} else {
|
||||
if (tags[j].buffer == NULL) {
|
||||
free(str);
|
||||
tscError("empty");
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
ret = converToStr(str + len, tags[j].buffer_type, tags[j].buffer, tags[j].length ? (int32_t)*tags[j].length : -1, &l);
|
||||
}
|
||||
|
||||
++j;
|
||||
|
||||
if (ret) {
|
||||
free(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
len += l;
|
||||
} else {
|
||||
len += (size_t)snprintf(str + len, size - len - 1, i > 0 ? ",%.*s" : "%.*s", t->n, t->z);
|
||||
}
|
||||
}
|
||||
|
||||
if (len >= (size - 1)) {
|
||||
size *= 2;
|
||||
free(str);
|
||||
str = calloc(1, size);
|
||||
continue;
|
||||
}
|
||||
|
||||
strcat(str, ") ");
|
||||
len += 2;
|
||||
|
||||
if ((len + strlen(pStmt->mtb.values.z)) >= (size - 1)) {
|
||||
size *= 2;
|
||||
free(str);
|
||||
str = calloc(1, size);
|
||||
continue;
|
||||
}
|
||||
|
||||
strcat(str, pStmt->mtb.values.z);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
free(pSql->sqlstr);
|
||||
pSql->sqlstr = str;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// interface functions
|
||||
|
||||
|
@ -1221,6 +1401,7 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) {
|
|||
pStmt->taos = pObj;
|
||||
|
||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||
|
||||
if (pSql == NULL) {
|
||||
free(pStmt);
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -1263,7 +1444,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
|||
pSql->fp = waitForQueryRsp;
|
||||
pSql->fetchFp = waitForQueryRsp;
|
||||
|
||||
pCmd->insertType = TSDB_QUERY_TYPE_STMT_INSERT;
|
||||
pCmd->insertParam.insertType = TSDB_QUERY_TYPE_STMT_INSERT;
|
||||
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||
tscError("%p failed to malloc payload buffer", pSql);
|
||||
|
@ -1292,34 +1473,15 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
|||
|
||||
registerSqlObj(pSql);
|
||||
|
||||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
|
||||
if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) {
|
||||
int32_t ret = stmtParseInsertTbTags(pSql, pStmt);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t index = 0;
|
||||
SStrToken sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
|
||||
if (sToken.n == 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
if (sToken.n == 1 && sToken.type == TK_QUESTION) {
|
||||
pStmt->multiTbInsert = true;
|
||||
pStmt->mtb.tbname = sToken;
|
||||
pStmt->mtb.nameSet = false;
|
||||
if (pStmt->mtb.pTableHash == NULL) {
|
||||
pStmt->mtb.pTableHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false);
|
||||
}
|
||||
if (pStmt->mtb.pTableBlockHashList == NULL) {
|
||||
pStmt->mtb.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
if (pStmt->multiTbInsert) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pStmt->multiTbInsert = false;
|
||||
memset(&pStmt->mtb, 0, sizeof(pStmt->mtb));
|
||||
|
||||
int32_t code = tsParseSql(pSql, true);
|
||||
|
@ -1336,8 +1498,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
|||
return normalStmtPrepare(pStmt);
|
||||
}
|
||||
|
||||
|
||||
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||
int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
SSqlObj* pSql = pStmt->pSql;
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
@ -1379,26 +1540,39 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
|||
SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData;
|
||||
pCmd->batchSize = pBlk->numOfRows;
|
||||
|
||||
taosHashPut(pCmd->pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
|
||||
taosHashPut(pCmd->insertParam.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
|
||||
|
||||
tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (pStmt->mtb.tagSet) {
|
||||
pStmt->mtb.tbname = tscReplaceStrToken(&pSql->sqlstr, &pStmt->mtb.tbname, name);
|
||||
} else {
|
||||
if (tags == NULL) {
|
||||
tscError("No tags set");
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
int32_t ret = stmtGenInsertStatement(pSql, pStmt, name, tags);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
pStmt->mtb.nameSet = true;
|
||||
pStmt->mtb.tagSet = true;
|
||||
|
||||
tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||
|
||||
pSql->cmd.parseFinished = 0;
|
||||
pSql->cmd.numOfParams = 0;
|
||||
pSql->cmd.batchSize = 0;
|
||||
|
||||
if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) {
|
||||
SHashObj* hashList = pCmd->pTableBlockHashList;
|
||||
pCmd->pTableBlockHashList = NULL;
|
||||
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) > 0) {
|
||||
SHashObj* hashList = pCmd->insertParam.pTableBlockHashList;
|
||||
pCmd->insertParam.pTableBlockHashList = NULL;
|
||||
tscResetSqlCmd(pCmd, true);
|
||||
pCmd->pTableBlockHashList = hashList;
|
||||
pCmd->insertParam.pTableBlockHashList = hashList;
|
||||
}
|
||||
|
||||
int32_t code = tsParseSql(pStmt->pSql, true);
|
||||
|
@ -1410,10 +1584,11 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
|||
}
|
||||
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
STableDataBlocks* pBlock = NULL;
|
||||
code = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
code = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -1426,7 +1601,6 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
|||
pStmt->mtb.tbNum++;
|
||||
|
||||
taosHashPut(pStmt->mtb.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)&pBlock, POINTER_BYTES);
|
||||
|
||||
taosHashPut(pStmt->mtb.pTableHash, name, strlen(name), (char*) &pTableMeta->id.uid, sizeof(pTableMeta->id.uid));
|
||||
|
||||
tscDebug("0x%"PRIx64" table:%s is prepared, uid:%" PRIx64, pSql->self, name, pStmt->mtb.currentUid);
|
||||
|
@ -1435,6 +1609,12 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
|||
return code;
|
||||
}
|
||||
|
||||
|
||||
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||
return taos_stmt_set_tbname_tags(stmt, name, NULL);
|
||||
}
|
||||
|
||||
|
||||
int taos_stmt_close(TAOS_STMT* stmt) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
if (!pStmt->isInsert) {
|
||||
|
@ -1451,8 +1631,9 @@ int taos_stmt_close(TAOS_STMT* stmt) {
|
|||
if (pStmt->multiTbInsert) {
|
||||
taosHashCleanup(pStmt->mtb.pTableHash);
|
||||
pStmt->mtb.pTableBlockHashList = tscDestroyBlockHashTable(pStmt->mtb.pTableBlockHashList, true);
|
||||
taosHashCleanup(pStmt->pSql->cmd.pTableBlockHashList);
|
||||
pStmt->pSql->cmd.pTableBlockHashList = NULL;
|
||||
taosHashCleanup(pStmt->pSql->cmd.insertParam.pTableBlockHashList);
|
||||
pStmt->pSql->cmd.insertParam.pTableBlockHashList = NULL;
|
||||
taosArrayDestroy(pStmt->mtb.tags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1617,9 +1798,10 @@ int taos_stmt_execute(TAOS_STMT* stmt) {
|
|||
ret = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
} else {
|
||||
if (pStmt->pSql != NULL) {
|
||||
taos_free_result(pStmt->pSql);
|
||||
tscFreeSqlObj(pStmt->pSql);
|
||||
pStmt->pSql = NULL;
|
||||
}
|
||||
|
||||
pStmt->pSql = taos_query((TAOS*)pStmt->taos, sql);
|
||||
ret = taos_errno(pStmt->pSql);
|
||||
free(sql);
|
||||
|
@ -1689,16 +1871,16 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
|
|||
|
||||
if (pStmt->isInsert) {
|
||||
SSqlCmd* pCmd = &pStmt->pSql->cmd;
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
STableDataBlocks* pBlock = NULL;
|
||||
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
if (ret != 0) {
|
||||
// todo handle error
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -373,11 +373,15 @@ int taos_num_fields(TAOS_RES *res) {
|
|||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||
|
||||
int32_t num = 0;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
if (pQueryInfo == NULL) {
|
||||
return num;
|
||||
}
|
||||
|
||||
while(pQueryInfo->pDownstream != NULL) {
|
||||
pQueryInfo = pQueryInfo->pDownstream;
|
||||
}
|
||||
|
||||
size_t numOfCols = tscNumOfFields(pQueryInfo);
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
SInternalField* pInfo = taosArrayGet(pQueryInfo->fieldsInfo.internalField, i);
|
||||
|
@ -408,7 +412,7 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
|
|||
SSqlRes *pRes = &pSql->res;
|
||||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
if (pQueryInfo == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -560,7 +564,7 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) {
|
|||
return true;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
if ((pQueryInfo == NULL) || tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
||||
return true;
|
||||
|
@ -614,7 +618,7 @@ int taos_errno(TAOS_RES *tres) {
|
|||
* why the sql is invalid
|
||||
*/
|
||||
static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) {
|
||||
if (code != TSDB_CODE_TSC_INVALID_SQL
|
||||
if (code != TSDB_CODE_TSC_INVALID_OPERATION
|
||||
&& code != TSDB_CODE_TSC_SQL_SYNTAX_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
@ -673,7 +677,7 @@ char *taos_get_client_info() { return version; }
|
|||
static void tscKillSTableQuery(SSqlObj *pSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
if (!tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
||||
return;
|
||||
|
@ -724,7 +728,7 @@ void taos_stop_query(TAOS_RES *res) {
|
|||
// set the error code for master pSqlObj firstly
|
||||
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
||||
assert(pSql->rpcRid <= 0);
|
||||
|
@ -754,7 +758,7 @@ bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
|
|||
return true;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
if (pQueryInfo == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
@ -829,9 +833,9 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
int32_t charLen = varDataLen((char*)row[i] - VARSTR_HEADER_SIZE);
|
||||
if (fields[i].type == TSDB_DATA_TYPE_BINARY) {
|
||||
assert(charLen <= fields[i].bytes);
|
||||
assert(charLen <= fields[i].bytes && charLen >= 0);
|
||||
} else {
|
||||
assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE);
|
||||
assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE && charLen >= 0);
|
||||
}
|
||||
|
||||
memcpy(str + len, row[i], charLen);
|
||||
|
@ -870,13 +874,9 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
|
||||
pSql->pTscObj = taos;
|
||||
pSql->signature = pSql;
|
||||
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
pRes->numOfTotal = 0;
|
||||
pRes->numOfClauseTotal = 0;
|
||||
|
||||
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||
|
||||
tscDebug("0x%"PRIx64" Valid SQL: %s pObj:%p", pSql->self, sql, pObj);
|
||||
|
||||
|
@ -896,10 +896,10 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
|
||||
strtolower(pSql->sqlstr, sql);
|
||||
|
||||
pCmd->curSql = NULL;
|
||||
if (NULL != pCmd->pTableBlockHashList) {
|
||||
taosHashCleanup(pCmd->pTableBlockHashList);
|
||||
pCmd->pTableBlockHashList = NULL;
|
||||
// pCmd->curSql = NULL;
|
||||
if (NULL != pCmd->insertParam.pTableBlockHashList) {
|
||||
taosHashCleanup(pCmd->insertParam.pTableBlockHashList);
|
||||
pCmd->insertParam.pTableBlockHashList = NULL;
|
||||
}
|
||||
|
||||
pSql->fp = asyncCallback;
|
||||
|
@ -921,90 +921,19 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t tblListLen) {
|
||||
// must before clean the sqlcmd object
|
||||
tscResetSqlCmd(&pSql->cmd, false);
|
||||
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
pCmd->command = TSDB_SQL_MULTI_META;
|
||||
pCmd->count = 0;
|
||||
|
||||
int code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||
char *str = (char *)tblNameList;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex);
|
||||
if (pQueryInfo == NULL) {
|
||||
pSql->res.code = terrno;
|
||||
return terrno;
|
||||
void loadMultiTableMetaCallback(void *param, TAOS_RES *res, int code) {
|
||||
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param);
|
||||
if (pSql == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
|
||||
|
||||
if ((code = tscAllocPayload(pCmd, tblListLen + 16)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
pSql->res.code = code;
|
||||
tsem_post(&pSql->rspSem);
|
||||
}
|
||||
|
||||
char *nextStr;
|
||||
char tblName[TSDB_TABLE_FNAME_LEN];
|
||||
int payloadLen = 0;
|
||||
char *pMsg = pCmd->payload;
|
||||
while (1) {
|
||||
nextStr = strchr(str, ',');
|
||||
if (nextStr == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(tblName, str, nextStr - str);
|
||||
int32_t len = (int32_t)(nextStr - str);
|
||||
tblName[len] = '\0';
|
||||
|
||||
str = nextStr + 1;
|
||||
len = (int32_t)strtrim(tblName);
|
||||
|
||||
SStrToken sToken = {.n = len, .type = TK_ID, .z = tblName};
|
||||
tGetToken(tblName, &sToken.type);
|
||||
|
||||
// Check if the table name available or not
|
||||
if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) {
|
||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||
sprintf(pCmd->payload, "table name is invalid");
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((code = tscSetTableFullName(pTableMetaInfo, &sToken, pSql)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if (++pCmd->count > TSDB_MULTI_TABLEMETA_MAX_NUM) {
|
||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||
sprintf(pCmd->payload, "tables over the max number");
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t xlen = tNameLen(&pTableMetaInfo->name);
|
||||
if (payloadLen + xlen + 128 >= pCmd->allocSize) {
|
||||
char *pNewMem = realloc(pCmd->payload, pCmd->allocSize + tblListLen);
|
||||
if (pNewMem == NULL) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
sprintf(pCmd->payload, "failed to allocate memory");
|
||||
return code;
|
||||
}
|
||||
|
||||
pCmd->payload = pNewMem;
|
||||
pCmd->allocSize = pCmd->allocSize + tblListLen;
|
||||
pMsg = pCmd->payload;
|
||||
}
|
||||
|
||||
char n[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, n);
|
||||
payloadLen += sprintf(pMsg + payloadLen, "%s,", n);
|
||||
}
|
||||
|
||||
*(pMsg + payloadLen) = '\0';
|
||||
pCmd->payloadLen = payloadLen + 1;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
static void freeElem(void* p) {
|
||||
tfree(*(char**)p);
|
||||
}
|
||||
|
||||
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||
|
@ -1020,38 +949,28 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
|||
pSql->pTscObj = taos;
|
||||
pSql->signature = pSql;
|
||||
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
pSql->fp = NULL; // todo set the correct callback function pointer
|
||||
pSql->cmd.pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||
|
||||
pRes->code = 0;
|
||||
pRes->numOfTotal = 0; // the number of getting table meta from server
|
||||
pRes->numOfClauseTotal = 0;
|
||||
|
||||
assert(pSql->fp == NULL);
|
||||
tscDebug("0x%"PRIx64" tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj);
|
||||
|
||||
int32_t tblListLen = (int32_t)strlen(tableNameList);
|
||||
if (tblListLen > MAX_TABLE_NAME_LENGTH) {
|
||||
tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, tblListLen, MAX_TABLE_NAME_LENGTH);
|
||||
int32_t length = (int32_t)strlen(tableNameList);
|
||||
if (length > MAX_TABLE_NAME_LENGTH) {
|
||||
tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, length, MAX_TABLE_NAME_LENGTH);
|
||||
tscFreeSqlObj(pSql);
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
char *str = calloc(1, tblListLen + 1);
|
||||
char *str = calloc(1, length + 1);
|
||||
if (str == NULL) {
|
||||
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
||||
tscError("0x%"PRIx64" failed to allocate sql string buffer", pSql->self);
|
||||
tscFreeSqlObj(pSql);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
strtolower(str, tableNameList);
|
||||
int32_t code = (uint8_t) tscParseTblNameList(pSql, str, tblListLen);
|
||||
SArray* plist = taosArrayInit(4, POINTER_BYTES);
|
||||
SArray* vgroupList = taosArrayInit(4, POINTER_BYTES);
|
||||
|
||||
/*
|
||||
* set the qhandle to 0 before return in order to erase the qhandle value assigned in the previous successful query.
|
||||
* If qhandle is NOT set 0, the function of taos_free_result() will send message to server by calling tscBuildAndSendRequest()
|
||||
* to free connection, which may cause segment fault, when the parse phrase is not even successfully executed.
|
||||
*/
|
||||
pRes->qId = 0;
|
||||
int32_t code = (uint8_t) tscTransferTableNameList(pSql, str, length, plist);
|
||||
free(str);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1059,12 +978,23 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
|||
return code;
|
||||
}
|
||||
|
||||
tscDoQuery(pSql);
|
||||
registerSqlObj(pSql);
|
||||
tscDebug("0x%"PRIx64" load multiple table meta, tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj);
|
||||
|
||||
tscDebug("0x%"PRIx64" load multi-table meta result:%d %s pObj:%p", pSql->self, pRes->code, taos_errstr(pSql), pObj);
|
||||
if ((code = pRes->code) != TSDB_CODE_SUCCESS) {
|
||||
tscFreeSqlObj(pSql);
|
||||
code = getMultiTableMetaFromMnode(pSql, plist, vgroupList, loadMultiTableMetaCallback);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
taosArrayDestroyEx(plist, freeElem);
|
||||
taosArrayDestroyEx(vgroupList, freeElem);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscFreeRegisteredSqlObj(pSql);
|
||||
return code;
|
||||
}
|
||||
|
||||
tsem_wait(&pSql->rspSem);
|
||||
tscFreeRegisteredSqlObj(pSql);
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ static int64_t getDelayValueAfterTimewindowClosed(SSqlStream* pStream, int64_t l
|
|||
|
||||
static bool isProjectStream(SQueryInfo* pQueryInfo) {
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||
if (pExpr->base.functionId != TSDB_FUNC_PRJ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -89,12 +89,12 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) {
|
|||
return;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
code = tscGetSTableVgroupInfo(pSql, 0);
|
||||
code = tscGetSTableVgroupInfo(pSql, pQueryInfo);
|
||||
}
|
||||
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
|
@ -138,7 +138,7 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
|||
|
||||
pStream->numOfRes = 0; // reset the numOfRes.
|
||||
SSqlObj *pSql = pStream->pSql;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
tscDebug("0x%"PRIx64" timer launch query", pSql->self);
|
||||
|
||||
if (pStream->isProject) {
|
||||
|
@ -197,7 +197,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
|||
tscError("0x%"PRIx64" stream:%p, query data failed, code:0x%08x, retry in %" PRId64 "ms", pStream->pSql->self,
|
||||
pStream, numOfRows, retryDelay);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0);
|
||||
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
|
@ -224,7 +224,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
|||
static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) {
|
||||
#if 0
|
||||
SSqlObj * pSql = pStream->pSql;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
if (pQueryInfo->fillType != TSDB_FILL_SET_VALUE && pQueryInfo->fillType != TSDB_FILL_NULL) {
|
||||
return;
|
||||
|
@ -273,7 +273,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
|||
return;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||
|
||||
if (numOfRows > 0) { // when reaching here the first execution of stream computing is successful.
|
||||
|
@ -444,7 +444,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
|||
int64_t minIntervalTime =
|
||||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
if (!pStream->isProject && pQueryInfo->interval.interval == 0) {
|
||||
sprintf(pSql->cmd.payload, "the interval value is 0");
|
||||
|
@ -494,7 +494,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
|||
}
|
||||
|
||||
static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
if (pStream->isProject) {
|
||||
// no data in table, flush all data till now to destination meter, 10sec delay
|
||||
|
@ -556,7 +556,7 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
|||
return;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
|
||||
|
@ -619,10 +619,10 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
|||
pStream->callback = callback;
|
||||
pStream->param = param;
|
||||
pStream->pSql = pSql;
|
||||
|
||||
pSql->pStream = pStream;
|
||||
pSql->param = pStream;
|
||||
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||
|
||||
pSql->sqlstr = calloc(1, strlen(sqlstr) + 1);
|
||||
if (pSql->sqlstr == NULL) {
|
||||
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
||||
|
@ -632,14 +632,14 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
|||
}
|
||||
|
||||
strtolower(pSql->sqlstr, sqlstr);
|
||||
pSql->fp = tscCreateStream;
|
||||
pSql->fetchFp = tscCreateStream;
|
||||
pSql->cmd.resColumnId = TSDB_RES_COL_ID;
|
||||
|
||||
tsem_init(&pSql->rspSem, 0, 0);
|
||||
registerSqlObj(pSql);
|
||||
|
||||
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||
tsem_init(&pSql->rspSem, 0, 0);
|
||||
|
||||
pSql->fp = tscCreateStream;
|
||||
pSql->fetchFp = tscCreateStream;
|
||||
|
||||
int32_t code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
|
|
|
@ -151,6 +151,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
strtolower(pSql->sqlstr, pSql->sqlstr);
|
||||
pRes->qId = 0;
|
||||
pRes->numOfRows = 1;
|
||||
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||
|
||||
code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -173,7 +174,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
|
||||
if (pSql->cmd.command != TSDB_SQL_SELECT && pSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||
line = __LINE__;
|
||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -266,7 +267,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
|||
|
||||
pSub->lastSyncTime = taosGetTimestampMs();
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
|
||||
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
SSubscriptionProgress target = {.uid = pTableMeta->id.uid, .key = 0};
|
||||
|
@ -284,7 +285,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
|||
}
|
||||
size_t numOfTables = taosArrayGetSize(tables);
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
SArray* progress = taosArrayInit(numOfTables, sizeof(SSubscriptionProgress));
|
||||
for( size_t i = 0; i < numOfTables; i++ ) {
|
||||
STidTags* tt = taosArrayGet( tables, i );
|
||||
|
@ -304,7 +305,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
|||
}
|
||||
taosArrayDestroy(tables);
|
||||
|
||||
TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd, 0)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
|
||||
TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -503,8 +504,8 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
|||
SSqlObj *pSql = pSub->pSql;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single table subscription
|
||||
|
||||
size_t size = taosArrayGetSize(pSub->progress);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -44,8 +44,8 @@ typedef struct SResPair {
|
|||
// the structure for sql function in select clause
|
||||
typedef struct SSqlExpr {
|
||||
char aliasName[TSDB_COL_NAME_LEN]; // as aliasName
|
||||
char token[TSDB_COL_NAME_LEN]; // original token
|
||||
SColIndex colInfo;
|
||||
|
||||
uint64_t uid; // refactor use the pointer
|
||||
|
||||
int16_t functionId; // function id in aAgg array
|
||||
|
@ -92,8 +92,6 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len);
|
|||
|
||||
void extractTableNameFromToken(SStrToken *pToken, SStrToken* pTable);
|
||||
|
||||
//SSchema tGetTbnameColumnSchema();
|
||||
|
||||
SSchema tGetBlockDistColumnSchema();
|
||||
|
||||
SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name);
|
||||
|
|
|
@ -2569,6 +2569,7 @@ _arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) {
|
|||
case TSDB_BINARY_OP_REMAINDER:
|
||||
return vectorRemainder;
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <texpr.h>
|
||||
#include "os.h"
|
||||
|
||||
#include "texpr.h"
|
||||
|
@ -465,27 +466,29 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
|||
return expr;
|
||||
}
|
||||
|
||||
tExprNode* exprdup(tExprNode* pTree) {
|
||||
if (pTree == NULL) {
|
||||
tExprNode* exprdup(tExprNode* pNode) {
|
||||
if (pNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tExprNode* pNode = calloc(1, sizeof(tExprNode));
|
||||
if (pTree->nodeType == TSQL_NODE_EXPR) {
|
||||
tExprNode* pLeft = exprdup(pTree->_node.pLeft);
|
||||
tExprNode* pRight = exprdup(pTree->_node.pRight);
|
||||
tExprNode* pCloned = calloc(1, sizeof(tExprNode));
|
||||
if (pNode->nodeType == TSQL_NODE_EXPR) {
|
||||
tExprNode* pLeft = exprdup(pNode->_node.pLeft);
|
||||
tExprNode* pRight = exprdup(pNode->_node.pRight);
|
||||
|
||||
pNode->nodeType = TSQL_NODE_EXPR;
|
||||
pNode->_node.pLeft = pLeft;
|
||||
pNode->_node.pRight = pRight;
|
||||
} else if (pTree->nodeType == TSQL_NODE_VALUE) {
|
||||
pNode->pVal = calloc(1, sizeof(tVariant));
|
||||
tVariantAssign(pNode->pVal, pTree->pVal);
|
||||
} else if (pTree->nodeType == TSQL_NODE_COL) {
|
||||
pNode->pSchema = calloc(1, sizeof(SSchema));
|
||||
*pNode->pSchema = *pTree->pSchema;
|
||||
pCloned->_node.pLeft = pLeft;
|
||||
pCloned->_node.pRight = pRight;
|
||||
pCloned->_node.optr = pNode->_node.optr;
|
||||
pCloned->_node.hasPK = pNode->_node.hasPK;
|
||||
} else if (pNode->nodeType == TSQL_NODE_VALUE) {
|
||||
pCloned->pVal = calloc(1, sizeof(tVariant));
|
||||
tVariantAssign(pCloned->pVal, pNode->pVal);
|
||||
} else if (pNode->nodeType == TSQL_NODE_COL) {
|
||||
pCloned->pSchema = calloc(1, sizeof(SSchema));
|
||||
*pCloned->pSchema = *pNode->pSchema;
|
||||
}
|
||||
|
||||
return pNode;
|
||||
pCloned->nodeType = pNode->nodeType;
|
||||
return pCloned;
|
||||
}
|
||||
|
||||
|
|
|
@ -310,6 +310,16 @@ public class TSDBJNIConnector {
|
|||
|
||||
private native int setBindTableNameImp(long stmt, String name, long conn);
|
||||
|
||||
public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException {
|
||||
int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(),
|
||||
nullList.array(), this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags");
|
||||
}
|
||||
}
|
||||
|
||||
private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn);
|
||||
|
||||
public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException {
|
||||
int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
|
|
|
@ -41,6 +41,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
private boolean isPrepared;
|
||||
|
||||
private ArrayList<ColumnInfo> colData;
|
||||
private ArrayList<TableTagInfo> tableTags;
|
||||
private int tagValueLength;
|
||||
|
||||
private String tableName;
|
||||
private long nativeStmtHandle = 0;
|
||||
|
||||
|
@ -63,8 +66,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
|
||||
if (parameterCnt > 1) {
|
||||
// the table name is also a parameter, so ignore it.
|
||||
this.colData = new ArrayList<ColumnInfo>(parameterCnt - 1);
|
||||
this.colData.addAll(Collections.nCopies(parameterCnt - 1, null));
|
||||
this.colData = new ArrayList<ColumnInfo>();
|
||||
this.tableTags = new ArrayList<TableTagInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,11 +565,109 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
}
|
||||
};
|
||||
|
||||
private static class TableTagInfo {
|
||||
private boolean isNull;
|
||||
private Object value;
|
||||
private int type;
|
||||
public TableTagInfo(Object value, int type) {
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static TableTagInfo createNullTag(int type) {
|
||||
TableTagInfo info = new TableTagInfo(null, type);
|
||||
info.isNull = true;
|
||||
return info;
|
||||
}
|
||||
};
|
||||
|
||||
public void setTableName(String name) {
|
||||
this.tableName = name;
|
||||
}
|
||||
|
||||
private void ensureTagCapacity(int index) {
|
||||
if (this.tableTags.size() < index + 1) {
|
||||
int delta = index + 1 - this.tableTags.size();
|
||||
this.tableTags.addAll(Collections.nCopies(delta, null));
|
||||
}
|
||||
}
|
||||
|
||||
public void setTagNull(int index, int type) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, TableTagInfo.createNullTag(type));
|
||||
}
|
||||
|
||||
public void setTagBoolean(int index, boolean value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL));
|
||||
this.tagValueLength += Byte.BYTES;
|
||||
}
|
||||
|
||||
public void setTagInt(int index, int value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT));
|
||||
this.tagValueLength += Integer.BYTES;
|
||||
}
|
||||
|
||||
public void setTagByte(int index, byte value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT));
|
||||
this.tagValueLength += Byte.BYTES;
|
||||
}
|
||||
|
||||
public void setTagShort(int index, short value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT));
|
||||
this.tagValueLength += Short.BYTES;
|
||||
}
|
||||
|
||||
public void setTagLong(int index, long value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT));
|
||||
this.tagValueLength += Long.BYTES;
|
||||
}
|
||||
|
||||
public void setTagTimestamp(int index, long value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP));
|
||||
this.tagValueLength += Long.BYTES;
|
||||
}
|
||||
|
||||
public void setTagFloat(int index, float value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT));
|
||||
this.tagValueLength += Float.BYTES;
|
||||
}
|
||||
|
||||
public void setTagDouble(int index, double value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE));
|
||||
this.tagValueLength += Double.BYTES;
|
||||
}
|
||||
|
||||
public void setTagString(int index, String value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY));
|
||||
this.tagValueLength += value.getBytes().length;
|
||||
}
|
||||
|
||||
public void setTagNString(int index, String value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR));
|
||||
|
||||
String charset = TaosGlobalConfig.getCharset();
|
||||
try {
|
||||
this.tagValueLength += value.getBytes(charset).length;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
|
||||
if (this.colData.size() == 0) {
|
||||
this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null));
|
||||
|
||||
}
|
||||
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
|
||||
if (col == null) {
|
||||
ColumnInfo p = new ColumnInfo();
|
||||
|
@ -641,7 +742,122 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
|
||||
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||
this.nativeStmtHandle = connector.prepareStmt(rawSql);
|
||||
|
||||
if (this.tableTags == null) {
|
||||
connector.setBindTableName(this.nativeStmtHandle, this.tableName);
|
||||
} else {
|
||||
int num = this.tableTags.size();
|
||||
ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength);
|
||||
tagDataList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer typeList = ByteBuffer.allocate(num);
|
||||
typeList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES);
|
||||
lengthList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES);
|
||||
isNullList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
for (int i = 0; i < num; ++i) {
|
||||
TableTagInfo tag = this.tableTags.get(i);
|
||||
if (tag.isNull) {
|
||||
typeList.put((byte) tag.type);
|
||||
isNullList.putInt(1);
|
||||
lengthList.putLong(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (tag.type) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
Integer val = (Integer) tag.value;
|
||||
tagDataList.putInt(val);
|
||||
lengthList.putLong(Integer.BYTES);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
|
||||
Byte val = (Byte) tag.value;
|
||||
tagDataList.put(val);
|
||||
lengthList.putLong(Byte.BYTES);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
|
||||
Boolean val = (Boolean) tag.value;
|
||||
tagDataList.put((byte) (val ? 1 : 0));
|
||||
lengthList.putLong(Byte.BYTES);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
|
||||
Short val = (Short) tag.value;
|
||||
tagDataList.putShort(val);
|
||||
lengthList.putLong(Short.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
|
||||
Long val = (Long) tag.value;
|
||||
tagDataList.putLong(val == null ? 0 : val);
|
||||
lengthList.putLong(Long.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
|
||||
Float val = (Float) tag.value;
|
||||
tagDataList.putFloat(val == null ? 0 : val);
|
||||
lengthList.putLong(Float.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
Double val = (Double) tag.value;
|
||||
tagDataList.putDouble(val == null ? 0 : val);
|
||||
lengthList.putLong(Double.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
String charset = TaosGlobalConfig.getCharset();
|
||||
String val = (String) tag.value;
|
||||
|
||||
byte[] b = null;
|
||||
try {
|
||||
if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
|
||||
b = val.getBytes();
|
||||
} else {
|
||||
b = val.getBytes(charset);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
tagDataList.put(b);
|
||||
lengthList.putLong(b.length);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
|
||||
}
|
||||
}
|
||||
|
||||
typeList.put((byte) tag.type);
|
||||
isNullList.putInt(tag.isNull? 1 : 0);
|
||||
}
|
||||
|
||||
connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList,
|
||||
typeList, lengthList, isNullList);
|
||||
}
|
||||
|
||||
ColumnInfo colInfo = (ColumnInfo) this.colData.get(0);
|
||||
if (colInfo == null) {
|
||||
|
|
|
@ -86,6 +86,17 @@ static SStep tsDnodeSteps[] = {
|
|||
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
||||
};
|
||||
|
||||
static SStep tsDnodeCompactSteps[] = {
|
||||
{"dnode-tfile", tfInit, tfCleanup},
|
||||
{"dnode-storage", dnodeInitStorage, dnodeCleanupStorage},
|
||||
{"dnode-eps", dnodeInitEps, dnodeCleanupEps},
|
||||
{"dnode-wal", walInit, walCleanUp},
|
||||
{"dnode-mread", dnodeInitMRead, NULL},
|
||||
{"dnode-mwrite", dnodeInitMWrite, NULL},
|
||||
{"dnode-mpeer", dnodeInitMPeer, NULL},
|
||||
{"dnode-modules", dnodeInitModules, dnodeCleanupModules},
|
||||
};
|
||||
|
||||
static int dnodeCreateDir(const char *dir) {
|
||||
if (mkdir(dir, 0755) != 0 && errno != EEXIST) {
|
||||
return -1;
|
||||
|
@ -95,13 +106,23 @@ static int dnodeCreateDir(const char *dir) {
|
|||
}
|
||||
|
||||
static void dnodeCleanupComponents() {
|
||||
if (!tsCompactMnodeWal) {
|
||||
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
||||
dnodeStepCleanup(tsDnodeSteps, stepSize);
|
||||
} else {
|
||||
int32_t stepSize = sizeof(tsDnodeCompactSteps) / sizeof(SStep);
|
||||
dnodeStepCleanup(tsDnodeCompactSteps, stepSize);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t dnodeInitComponents() {
|
||||
if (!tsCompactMnodeWal) {
|
||||
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
||||
return dnodeStepInit(tsDnodeSteps, stepSize);
|
||||
} else {
|
||||
int32_t stepSize = sizeof(tsDnodeCompactSteps) / sizeof(SStep);
|
||||
return dnodeStepInit(tsDnodeCompactSteps, stepSize);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t dnodeInitTmr() {
|
||||
|
|
|
@ -112,6 +112,7 @@ typedef struct TAOS_MULTI_BIND {
|
|||
|
||||
TAOS_STMT *taos_stmt_init(TAOS *taos);
|
||||
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
|
||||
int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags);
|
||||
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name);
|
||||
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
|
||||
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
|
||||
|
|
|
@ -347,6 +347,7 @@ do { \
|
|||
#define TSDB_QUERY_TYPE_TAG_FILTER_QUERY 0x400u
|
||||
#define TSDB_QUERY_TYPE_INSERT 0x100u // insert type
|
||||
#define TSDB_QUERY_TYPE_MULTITABLE_QUERY 0x200u
|
||||
#define TSDB_QUERY_TYPE_FILE_INSERT 0x400u // insert data from file
|
||||
#define TSDB_QUERY_TYPE_STMT_INSERT 0x800u // stmt insert type
|
||||
|
||||
#define TSDB_QUERY_HAS_TYPE(x, _type) (((x) & (_type)) != 0)
|
||||
|
|
|
@ -74,7 +74,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_REF_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x010A) //"Ref is not there")
|
||||
|
||||
//client
|
||||
#define TSDB_CODE_TSC_INVALID_SQL TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid SQL statement")
|
||||
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid Operation")
|
||||
#define TSDB_CODE_TSC_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0201) //"Invalid qhandle")
|
||||
#define TSDB_CODE_TSC_INVALID_TIME_STAMP TAOS_DEF_ERROR_CODE(0, 0x0202) //"Invalid combination of client/service time")
|
||||
#define TSDB_CODE_TSC_INVALID_VALUE TAOS_DEF_ERROR_CODE(0, 0x0203) //"Invalid value in client")
|
||||
|
|
|
@ -84,7 +84,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_TABLE, "drop-table" )
|
|||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_TABLE, "alter-table" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLE_META, "table-meta" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_STABLE_VGROUP, "stable-vgroup" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLES_META, "tables-meta" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLES_META, "multiTable-meta" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_STREAM, "alter-stream" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_SHOW, "show" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_RETRIEVE, "retrieve" )
|
||||
|
@ -294,6 +294,8 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
// if user specify DROP STABLE, this flag will be set. And an error will be returned if it is not a super table
|
||||
int8_t supertable;
|
||||
int8_t igNotExists;
|
||||
} SCMDropTableMsg;
|
||||
|
||||
|
@ -703,8 +705,9 @@ typedef struct {
|
|||
} STableInfoMsg;
|
||||
|
||||
typedef struct {
|
||||
int32_t numOfVgroups;
|
||||
int32_t numOfTables;
|
||||
char tableIds[];
|
||||
char tableNames[];
|
||||
} SMultiTableInfoMsg;
|
||||
|
||||
typedef struct SSTableVgroupMsg {
|
||||
|
@ -753,8 +756,9 @@ typedef struct STableMetaMsg {
|
|||
|
||||
typedef struct SMultiTableMeta {
|
||||
int32_t numOfTables;
|
||||
int32_t numOfVgroup;
|
||||
int32_t contLen;
|
||||
char metas[];
|
||||
char meta[];
|
||||
} SMultiTableMeta;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -209,6 +209,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
#define TK_SPACE 300
|
||||
#define TK_COMMENT 301
|
||||
#define TK_ILLEGAL 302
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#include "taoserror.h"
|
||||
#include "tutil.h"
|
||||
|
||||
#define STMT_IFACE_ENABLED 1
|
||||
|
||||
#define REQ_EXTRA_BUF_LEN 1024
|
||||
#define RESP_BUF_LEN 4096
|
||||
|
||||
|
@ -253,12 +255,13 @@ typedef struct SColumn_S {
|
|||
|
||||
typedef struct SSuperTable_S {
|
||||
char sTblName[MAX_TB_NAME_SIZE+1];
|
||||
char dataSource[MAX_TB_NAME_SIZE+1]; // rand_gen or sample
|
||||
char childTblPrefix[MAX_TB_NAME_SIZE];
|
||||
char insertMode[MAX_TB_NAME_SIZE]; // taosc, rest
|
||||
uint16_t childTblExists;
|
||||
int64_t childTblCount;
|
||||
bool childTblExists; // 0: no, 1: yes
|
||||
uint64_t batchCreateTableNum; // 0: no batch, > 0: batch table number in one sql
|
||||
uint8_t autoCreateTable; // 0: create sub table, 1: auto create sub table
|
||||
char childTblPrefix[MAX_TB_NAME_SIZE];
|
||||
char dataSource[MAX_TB_NAME_SIZE+1]; // rand_gen or sample
|
||||
uint16_t iface; // 0: taosc, 1: rest, 2: stmt
|
||||
int64_t childTblLimit;
|
||||
uint64_t childTblOffset;
|
||||
|
@ -377,7 +380,7 @@ typedef struct SDbs_S {
|
|||
typedef struct SpecifiedQueryInfo_S {
|
||||
uint64_t queryInterval; // 0: unlimit > 0 loop/s
|
||||
uint32_t concurrent;
|
||||
uint64_t sqlCount;
|
||||
int sqlCount;
|
||||
uint32_t asyncMode; // 0: sync, 1: async
|
||||
uint64_t subscribeInterval; // ms
|
||||
uint64_t queryTimes;
|
||||
|
@ -386,6 +389,7 @@ typedef struct SpecifiedQueryInfo_S {
|
|||
char sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1];
|
||||
char result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1];
|
||||
int resubAfterConsume[MAX_QUERY_SQL_COUNT];
|
||||
int endAfterConsume[MAX_QUERY_SQL_COUNT];
|
||||
TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT];
|
||||
char topic[MAX_QUERY_SQL_COUNT][32];
|
||||
int consumed[MAX_QUERY_SQL_COUNT];
|
||||
|
@ -404,10 +408,11 @@ typedef struct SuperQueryInfo_S {
|
|||
uint64_t queryTimes;
|
||||
int64_t childTblCount;
|
||||
char childTblPrefix[MAX_TB_NAME_SIZE];
|
||||
uint64_t sqlCount;
|
||||
int sqlCount;
|
||||
char sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1];
|
||||
char result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1];
|
||||
int resubAfterConsume;
|
||||
int endAfterConsume;
|
||||
TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT];
|
||||
|
||||
char* childTblName;
|
||||
|
@ -688,7 +693,11 @@ static void printHelp() {
|
|||
printf("%s%s%s%s\n", indent, "-p", indent,
|
||||
"The TCP/IP port number to use for the connection. Default is 0.");
|
||||
printf("%s%s%s%s\n", indent, "-I", indent,
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
"The interface (taosc, rest, and stmt) taosdemo uses. Default is 'taosc'.");
|
||||
#else
|
||||
"The interface (taosc, rest) taosdemo uses. Default is 'taosc'.");
|
||||
#endif
|
||||
printf("%s%s%s%s\n", indent, "-d", indent,
|
||||
"Destination database. Default is 'test'.");
|
||||
printf("%s%s%s%s\n", indent, "-a", indent,
|
||||
|
@ -788,8 +797,10 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) {
|
|||
arguments->iface = TAOSC_IFACE;
|
||||
} else if (0 == strcasecmp(argv[i], "rest")) {
|
||||
arguments->iface = REST_IFACE;
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
} else if (0 == strcasecmp(argv[i], "stmt")) {
|
||||
arguments->iface = STMT_IFACE;
|
||||
#endif
|
||||
} else {
|
||||
errorPrint("%s", "\n\t-I need a valid string following!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -826,7 +837,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) {
|
|||
if ((argc == i+1)
|
||||
|| (!isStringNumber(argv[i+1]))) {
|
||||
printHelp();
|
||||
errorPrint("%s", "\n\t-q need a number following!\nQuery mode -- 0: SYNC, 1: ASYNC. Default is SYNC.\n");
|
||||
errorPrint("%s", "\n\t-q need a number following!\nQuery mode -- 0: SYNC, not-0: ASYNC. Default is SYNC.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
arguments->async_mode = atoi(argv[++i]);
|
||||
|
@ -1467,7 +1478,8 @@ static int printfInsertMeta() {
|
|||
|
||||
if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) {
|
||||
printf(" autoCreateTable: \033[33m%s\033[0m\n", "no");
|
||||
} else if (AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) {
|
||||
} else if (AUTO_CREATE_SUBTBL ==
|
||||
g_Dbs.db[i].superTbls[j].autoCreateTable) {
|
||||
printf(" autoCreateTable: \033[33m%s\033[0m\n", "yes");
|
||||
} else {
|
||||
printf(" autoCreateTable: \033[33m%s\033[0m\n", "error");
|
||||
|
@ -1771,7 +1783,7 @@ static void printfQueryMeta() {
|
|||
|
||||
if ((SUBSCRIBE_TEST == g_args.test_mode) || (QUERY_TEST == g_args.test_mode)) {
|
||||
printf("specified table query info: \n");
|
||||
printf("sqlCount: \033[33m%"PRIu64"\033[0m\n",
|
||||
printf("sqlCount: \033[33m%d\033[0m\n",
|
||||
g_queryInfo.specifiedQueryInfo.sqlCount);
|
||||
if (g_queryInfo.specifiedQueryInfo.sqlCount > 0) {
|
||||
printf("specified tbl query times:\n");
|
||||
|
@ -1791,15 +1803,15 @@ static void printfQueryMeta() {
|
|||
printf("keepProgress: \033[33m%d\033[0m\n",
|
||||
g_queryInfo.specifiedQueryInfo.subscribeKeepProgress);
|
||||
|
||||
for (uint64_t i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) {
|
||||
printf(" sql[%"PRIu64"]: \033[33m%s\033[0m\n",
|
||||
for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) {
|
||||
printf(" sql[%d]: \033[33m%s\033[0m\n",
|
||||
i, g_queryInfo.specifiedQueryInfo.sql[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("super table query info:\n");
|
||||
printf("sqlCount: \033[33m%"PRIu64"\033[0m\n",
|
||||
printf("sqlCount: \033[33m%d\033[0m\n",
|
||||
g_queryInfo.superQueryInfo.sqlCount);
|
||||
|
||||
if (g_queryInfo.superQueryInfo.sqlCount > 0) {
|
||||
|
@ -3063,23 +3075,23 @@ static void createChildTables() {
|
|||
if (g_Dbs.use_metric) {
|
||||
if (g_Dbs.db[i].superTblCount > 0) {
|
||||
// with super table
|
||||
for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) {
|
||||
for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
|
||||
if ((AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable)
|
||||
|| (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
verbosePrint("%s() LN%d: %s\n", __func__, __LINE__,
|
||||
g_Dbs.db[i].superTbls[j].colsOfCreateChildTable);
|
||||
uint64_t tableFrom = 0;
|
||||
uint64_t startFrom = 0;
|
||||
g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount;
|
||||
|
||||
verbosePrint("%s() LN%d: create %"PRId64" child tables from %"PRIu64"\n",
|
||||
__func__, __LINE__, g_totalChildTables, tableFrom);
|
||||
__func__, __LINE__, g_totalChildTables, startFrom);
|
||||
|
||||
startMultiThreadCreateChildTable(
|
||||
g_Dbs.db[i].superTbls[j].colsOfCreateChildTable,
|
||||
g_Dbs.threadCountByCreateTbl,
|
||||
tableFrom,
|
||||
startFrom,
|
||||
g_Dbs.db[i].superTbls[j].childTblCount,
|
||||
g_Dbs.db[i].dbName, &(g_Dbs.db[i].superTbls[j]));
|
||||
}
|
||||
|
@ -3088,14 +3100,11 @@ static void createChildTables() {
|
|||
// normal table
|
||||
len = snprintf(tblColsBuf, MAX_SQL_SIZE, "(TS TIMESTAMP");
|
||||
for (int j = 0; j < g_args.num_of_CPR; j++) {
|
||||
if (g_args.datatype[j]
|
||||
&& ((strncasecmp(g_args.datatype[j],
|
||||
"BINARY", strlen("BINARY")) == 0)
|
||||
if ((strncasecmp(g_args.datatype[j], "BINARY", strlen("BINARY")) == 0)
|
||||
|| (strncasecmp(g_args.datatype[j],
|
||||
"NCHAR", strlen("NCHAR")) == 0))) {
|
||||
"NCHAR", strlen("NCHAR")) == 0)) {
|
||||
snprintf(tblColsBuf + len, MAX_SQL_SIZE - len,
|
||||
", COL%d %s(%d)", j, g_args.datatype[j],
|
||||
g_args.len_of_binary);
|
||||
", COL%d %s(%d)", j, g_args.datatype[j], g_args.len_of_binary);
|
||||
} else {
|
||||
snprintf(tblColsBuf + len, MAX_SQL_SIZE - len,
|
||||
", COL%d %s", j, g_args.datatype[j]);
|
||||
|
@ -3810,25 +3819,29 @@ static bool getMetaFromInsertJsonFile(cJSON* root) {
|
|||
|
||||
// dbinfo
|
||||
cJSON *stbName = cJSON_GetObjectItem(stbInfo, "name");
|
||||
if (!stbName || stbName->type != cJSON_String || stbName->valuestring == NULL) {
|
||||
if (!stbName || stbName->type != cJSON_String
|
||||
|| stbName->valuestring == NULL) {
|
||||
errorPrint("%s() LN%d, failed to read json, stb name not found\n",
|
||||
__func__, __LINE__);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tstrncpy(g_Dbs.db[i].superTbls[j].sTblName, stbName->valuestring, MAX_TB_NAME_SIZE);
|
||||
tstrncpy(g_Dbs.db[i].superTbls[j].sTblName, stbName->valuestring,
|
||||
MAX_TB_NAME_SIZE);
|
||||
|
||||
cJSON *prefix = cJSON_GetObjectItem(stbInfo, "childtable_prefix");
|
||||
if (!prefix || prefix->type != cJSON_String || prefix->valuestring == NULL) {
|
||||
printf("ERROR: failed to read json, childtable_prefix not found\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tstrncpy(g_Dbs.db[i].superTbls[j].childTblPrefix, prefix->valuestring, MAX_DB_NAME_SIZE);
|
||||
tstrncpy(g_Dbs.db[i].superTbls[j].childTblPrefix, prefix->valuestring,
|
||||
MAX_DB_NAME_SIZE);
|
||||
|
||||
cJSON *autoCreateTbl = cJSON_GetObjectItem(stbInfo, "auto_create_table"); // yes, no, null
|
||||
cJSON *autoCreateTbl = cJSON_GetObjectItem(stbInfo, "auto_create_table");
|
||||
if (autoCreateTbl
|
||||
&& autoCreateTbl->type == cJSON_String
|
||||
&& autoCreateTbl->valuestring != NULL) {
|
||||
if (0 == strncasecmp(autoCreateTbl->valuestring, "yes", 3)) {
|
||||
if ((0 == strncasecmp(autoCreateTbl->valuestring, "yes", 3))
|
||||
&& (TBL_ALREADY_EXISTS != g_Dbs.db[i].superTbls[j].childTblExists)) {
|
||||
g_Dbs.db[i].superTbls[j].autoCreateTable = AUTO_CREATE_SUBTBL;
|
||||
} else if (0 == strncasecmp(autoCreateTbl->valuestring, "no", 2)) {
|
||||
g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL;
|
||||
|
@ -3873,6 +3886,10 @@ static bool getMetaFromInsertJsonFile(cJSON* root) {
|
|||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
if (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists) {
|
||||
g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL;
|
||||
}
|
||||
|
||||
cJSON* count = cJSON_GetObjectItem(stbInfo, "childtable_count");
|
||||
if (!count || count->type != cJSON_Number || 0 >= count->valueint) {
|
||||
errorPrint("%s() LN%d, failed to read json, childtable_count input mistake\n",
|
||||
|
@ -3901,8 +3918,10 @@ static bool getMetaFromInsertJsonFile(cJSON* root) {
|
|||
g_Dbs.db[i].superTbls[j].iface= TAOSC_IFACE;
|
||||
} else if (0 == strcasecmp(stbIface->valuestring, "rest")) {
|
||||
g_Dbs.db[i].superTbls[j].iface= REST_IFACE;
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
} else if (0 == strcasecmp(stbIface->valuestring, "stmt")) {
|
||||
g_Dbs.db[i].superTbls[j].iface= STMT_IFACE;
|
||||
#endif
|
||||
} else {
|
||||
errorPrint("%s() LN%d, failed to read json, insert_mode %s not recognized\n",
|
||||
__func__, __LINE__, stbIface->valuestring);
|
||||
|
@ -3930,7 +3949,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) {
|
|||
cJSON* childTbl_offset = cJSON_GetObjectItem(stbInfo, "childtable_offset");
|
||||
if ((childTbl_offset) && (g_Dbs.db[i].drop != true)
|
||||
&& (g_Dbs.db[i].superTbls[j].childTblExists == TBL_ALREADY_EXISTS)) {
|
||||
if (childTbl_offset->type != cJSON_Number || 0 > childTbl_offset->valueint) {
|
||||
if ((childTbl_offset->type != cJSON_Number)
|
||||
|| (0 > childTbl_offset->valueint)) {
|
||||
printf("ERROR: failed to read json, childtable_offset\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
@ -3986,7 +4006,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) {
|
|||
}
|
||||
|
||||
cJSON *tagsFile = cJSON_GetObjectItem(stbInfo, "tags_file");
|
||||
if (tagsFile && tagsFile->type == cJSON_String && tagsFile->valuestring != NULL) {
|
||||
if ((tagsFile && tagsFile->type == cJSON_String)
|
||||
&& (tagsFile->valuestring != NULL)) {
|
||||
tstrncpy(g_Dbs.db[i].superTbls[j].tagsFile,
|
||||
tagsFile->valuestring, MAX_FILE_NAME_LEN);
|
||||
if (0 == g_Dbs.db[i].superTbls[j].tagsFile[0]) {
|
||||
|
@ -4266,7 +4287,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) {
|
|||
if (concurrent && concurrent->type == cJSON_Number) {
|
||||
if (concurrent->valueint <= 0) {
|
||||
errorPrint(
|
||||
"%s() LN%d, query sqlCount %"PRIu64" or concurrent %d is not correct.\n",
|
||||
"%s() LN%d, query sqlCount %d or concurrent %d is not correct.\n",
|
||||
__func__, __LINE__,
|
||||
g_queryInfo.specifiedQueryInfo.sqlCount,
|
||||
g_queryInfo.specifiedQueryInfo.concurrent);
|
||||
|
@ -4365,6 +4386,17 @@ static bool getMetaFromQueryJsonFile(cJSON* root) {
|
|||
tstrncpy(g_queryInfo.specifiedQueryInfo.sql[j],
|
||||
sqlStr->valuestring, MAX_QUERY_SQL_LENGTH);
|
||||
|
||||
cJSON* endAfterConsume =
|
||||
cJSON_GetObjectItem(specifiedQuery, "endAfterConsume");
|
||||
if (endAfterConsume
|
||||
&& endAfterConsume->type == cJSON_Number) {
|
||||
g_queryInfo.specifiedQueryInfo.endAfterConsume[j]
|
||||
= endAfterConsume->valueint;
|
||||
} else if (!endAfterConsume) {
|
||||
// default value is -1, which mean infinite loop
|
||||
g_queryInfo.specifiedQueryInfo.endAfterConsume[j] = -1;
|
||||
}
|
||||
|
||||
cJSON* resubAfterConsume =
|
||||
cJSON_GetObjectItem(specifiedQuery, "resubAfterConsume");
|
||||
if (resubAfterConsume
|
||||
|
@ -4372,9 +4404,8 @@ static bool getMetaFromQueryJsonFile(cJSON* root) {
|
|||
g_queryInfo.specifiedQueryInfo.resubAfterConsume[j]
|
||||
= resubAfterConsume->valueint;
|
||||
} else if (!resubAfterConsume) {
|
||||
//printf("failed to read json, subscribe interval no found\n");
|
||||
//goto PARSE_OVER;
|
||||
g_queryInfo.specifiedQueryInfo.resubAfterConsume[j] = 1;
|
||||
// default value is -1, which mean do not resub
|
||||
g_queryInfo.specifiedQueryInfo.resubAfterConsume[j] = -1;
|
||||
}
|
||||
|
||||
cJSON *result = cJSON_GetObjectItem(sql, "result");
|
||||
|
@ -4518,16 +4549,26 @@ static bool getMetaFromQueryJsonFile(cJSON* root) {
|
|||
g_queryInfo.superQueryInfo.subscribeKeepProgress = 0;
|
||||
}
|
||||
|
||||
cJSON* superEndAfterConsume =
|
||||
cJSON_GetObjectItem(superQuery, "endAfterConsume");
|
||||
if (superEndAfterConsume
|
||||
&& superEndAfterConsume->type == cJSON_Number) {
|
||||
g_queryInfo.superQueryInfo.endAfterConsume =
|
||||
superEndAfterConsume->valueint;
|
||||
} else if (!superEndAfterConsume) {
|
||||
// default value is -1, which mean do not resub
|
||||
g_queryInfo.superQueryInfo.endAfterConsume = -1;
|
||||
}
|
||||
|
||||
cJSON* superResubAfterConsume =
|
||||
cJSON_GetObjectItem(superQuery, "resubAfterConsume");
|
||||
cJSON_GetObjectItem(superQuery, "endAfterConsume");
|
||||
if (superResubAfterConsume
|
||||
&& superResubAfterConsume->type == cJSON_Number) {
|
||||
g_queryInfo.superQueryInfo.resubAfterConsume =
|
||||
g_queryInfo.superQueryInfo.endAfterConsume =
|
||||
superResubAfterConsume->valueint;
|
||||
} else if (!superResubAfterConsume) {
|
||||
//printf("failed to read json, subscribe interval no found\n");
|
||||
////goto PARSE_OVER;
|
||||
g_queryInfo.superQueryInfo.resubAfterConsume = 1;
|
||||
// default value is -1, which mean do not resub
|
||||
g_queryInfo.superQueryInfo.endAfterConsume = -1;
|
||||
}
|
||||
|
||||
// supert table sqls
|
||||
|
@ -4900,6 +4941,7 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k)
|
|||
}
|
||||
break;
|
||||
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
case STMT_IFACE:
|
||||
debugPrint("%s() LN%d, stmt=%p", __func__, __LINE__, pThreadInfo->stmt);
|
||||
if (0 != taos_stmt_execute(pThreadInfo->stmt)) {
|
||||
|
@ -4909,6 +4951,7 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k)
|
|||
}
|
||||
affectedRows = k;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
errorPrint("%s() LN%d: unknown insert mode: %d\n",
|
||||
|
@ -4923,14 +4966,13 @@ static void getTableName(char *pTblName,
|
|||
threadInfo* pThreadInfo, uint64_t tableSeq)
|
||||
{
|
||||
SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
|
||||
if ((superTblInfo)
|
||||
&& (AUTO_CREATE_SUBTBL != superTblInfo->autoCreateTable)) {
|
||||
if (superTblInfo) {
|
||||
if (AUTO_CREATE_SUBTBL != superTblInfo->autoCreateTable) {
|
||||
if (superTblInfo->childTblLimit > 0) {
|
||||
snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s",
|
||||
superTblInfo->childTblName +
|
||||
(tableSeq - superTblInfo->childTblOffset) * TSDB_TABLE_NAME_LEN);
|
||||
} else {
|
||||
|
||||
verbosePrint("[%d] %s() LN%d: from=%"PRIu64" count=%"PRId64" seq=%"PRIu64"\n",
|
||||
pThreadInfo->threadID, __func__, __LINE__,
|
||||
pThreadInfo->start_table_from,
|
||||
|
@ -4938,6 +4980,10 @@ static void getTableName(char *pTblName,
|
|||
snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s",
|
||||
superTblInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN);
|
||||
}
|
||||
} else {
|
||||
snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s%"PRIu64"",
|
||||
superTblInfo->childTblPrefix, tableSeq);
|
||||
}
|
||||
} else {
|
||||
snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s%"PRIu64"",
|
||||
g_args.tb_prefix, tableSeq);
|
||||
|
@ -5259,6 +5305,7 @@ static int64_t generateInterlaceDataWithoutStb(
|
|||
return k;
|
||||
}
|
||||
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
static int32_t prepareStmtBindArrayByType(TAOS_BIND *bind,
|
||||
char *dataType, int32_t dataLen, char **ptr)
|
||||
{
|
||||
|
@ -5469,6 +5516,7 @@ static int32_t prepareStmtWithoutStb(
|
|||
}
|
||||
}
|
||||
|
||||
free(bindArray);
|
||||
return k;
|
||||
}
|
||||
|
||||
|
@ -5549,8 +5597,10 @@ static int32_t prepareStbStmt(SSuperTable *stbInfo,
|
|||
}
|
||||
}
|
||||
|
||||
free(bindArray);
|
||||
return k;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int32_t generateStbProgressiveData(
|
||||
SSuperTable *superTblInfo,
|
||||
|
@ -5738,6 +5788,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) {
|
|||
int32_t generated;
|
||||
if (superTblInfo) {
|
||||
if (superTblInfo->iface == STMT_IFACE) {
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
generated = prepareStbStmt(superTblInfo,
|
||||
pThreadInfo->stmt,
|
||||
tableName,
|
||||
|
@ -5745,6 +5796,9 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) {
|
|||
insertRows, i,
|
||||
startTime,
|
||||
pThreadInfo->buffer);
|
||||
#else
|
||||
generated = -1;
|
||||
#endif
|
||||
} else {
|
||||
generated = generateStbInterlaceData(
|
||||
superTblInfo,
|
||||
|
@ -5762,11 +5816,15 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) {
|
|||
pThreadInfo->threadID,
|
||||
__func__, __LINE__,
|
||||
tableName, batchPerTbl, startTime);
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
generated = prepareStmtWithoutStb(
|
||||
pThreadInfo->stmt, tableName,
|
||||
batchPerTbl,
|
||||
insertRows, i,
|
||||
startTime);
|
||||
#else
|
||||
generated = -1;
|
||||
#endif
|
||||
} else {
|
||||
generated = generateInterlaceDataWithoutStb(
|
||||
tableName, batchPerTbl,
|
||||
|
@ -5947,12 +6005,16 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) {
|
|||
int32_t generated;
|
||||
if (superTblInfo) {
|
||||
if (superTblInfo->iface == STMT_IFACE) {
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
generated = prepareStbStmt(
|
||||
superTblInfo,
|
||||
pThreadInfo->stmt,
|
||||
tableName,
|
||||
g_args.num_of_RPR,
|
||||
insertRows, i, start_time, pstr);
|
||||
#else
|
||||
generated = -1;
|
||||
#endif
|
||||
} else {
|
||||
generated = generateStbProgressiveData(
|
||||
superTblInfo,
|
||||
|
@ -5963,12 +6025,16 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) {
|
|||
}
|
||||
} else {
|
||||
if (g_args.iface == STMT_IFACE) {
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
generated = prepareStmtWithoutStb(
|
||||
pThreadInfo->stmt,
|
||||
tableName,
|
||||
g_args.num_of_RPR,
|
||||
insertRows, i,
|
||||
start_time);
|
||||
#else
|
||||
generated = -1;
|
||||
#endif
|
||||
} else {
|
||||
generated = generateProgressiveDataWithoutStb(
|
||||
tableName,
|
||||
|
@ -6353,6 +6419,7 @@ static void startMultiThreadInsertData(int threads, char* db_name,
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
if ((g_args.iface == STMT_IFACE)
|
||||
|| ((superTblInfo) && (superTblInfo->iface == STMT_IFACE))) {
|
||||
|
||||
|
@ -6392,6 +6459,7 @@ static void startMultiThreadInsertData(int threads, char* db_name,
|
|||
exit(-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
pThreadInfo->taos = NULL;
|
||||
}
|
||||
|
@ -6432,9 +6500,11 @@ static void startMultiThreadInsertData(int threads, char* db_name,
|
|||
|
||||
tsem_destroy(&(pThreadInfo->lock_sem));
|
||||
|
||||
#if STMT_IFACE_ENABLED == 1
|
||||
if (pThreadInfo->stmt) {
|
||||
taos_stmt_close(pThreadInfo->stmt);
|
||||
}
|
||||
#endif
|
||||
tsem_destroy(&(pThreadInfo->lock_sem));
|
||||
taos_close(pThreadInfo->taos);
|
||||
|
||||
|
@ -6711,7 +6781,6 @@ static int insertTestProcess() {
|
|||
}
|
||||
}
|
||||
|
||||
// taosMsleep(1000);
|
||||
// create sub threads for inserting data
|
||||
//start = taosGetTimestampMs();
|
||||
for (int i = 0; i < g_Dbs.dbCount; i++) {
|
||||
|
@ -7230,7 +7299,10 @@ static void *superSubscribe(void *sarg) {
|
|||
|
||||
uint64_t st = 0, et = 0;
|
||||
|
||||
while(1) {
|
||||
while ((g_queryInfo.superQueryInfo.endAfterConsume == -1)
|
||||
|| (g_queryInfo.superQueryInfo.endAfterConsume <
|
||||
consumed[pThreadInfo->end_table_to - pThreadInfo->start_table_from])) {
|
||||
|
||||
for (uint64_t i = pThreadInfo->start_table_from;
|
||||
i <= pThreadInfo->end_table_to; i++) {
|
||||
tsubSeq = i - pThreadInfo->start_table_from;
|
||||
|
@ -7259,7 +7331,7 @@ static void *superSubscribe(void *sarg) {
|
|||
}
|
||||
consumed[tsubSeq] ++;
|
||||
|
||||
if ((g_queryInfo.superQueryInfo.subscribeKeepProgress)
|
||||
if ((g_queryInfo.superQueryInfo.resubAfterConsume != -1)
|
||||
&& (consumed[tsubSeq] >=
|
||||
g_queryInfo.superQueryInfo.resubAfterConsume)) {
|
||||
printf("keepProgress:%d, resub super table query: %"PRIu64"\n",
|
||||
|
@ -7341,7 +7413,10 @@ static void *specifiedSubscribe(void *sarg) {
|
|||
// start loop to consume result
|
||||
|
||||
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0;
|
||||
while(1) {
|
||||
while((g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq] == -1)
|
||||
|| (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] <
|
||||
g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq])) {
|
||||
|
||||
if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) {
|
||||
continue;
|
||||
}
|
||||
|
@ -7349,15 +7424,18 @@ static void *specifiedSubscribe(void *sarg) {
|
|||
g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID] = taos_consume(
|
||||
g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]);
|
||||
if (g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]) {
|
||||
if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
|
||||
if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0]
|
||||
!= 0) {
|
||||
sprintf(pThreadInfo->filePath, "%s-%d",
|
||||
g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
|
||||
pThreadInfo->threadID);
|
||||
fetchResult(g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID], pThreadInfo);
|
||||
fetchResult(
|
||||
g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID],
|
||||
pThreadInfo);
|
||||
}
|
||||
|
||||
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] ++;
|
||||
if ((g_queryInfo.specifiedQueryInfo.subscribeKeepProgress)
|
||||
if ((g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq] != -1)
|
||||
&& (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] >=
|
||||
g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq])) {
|
||||
printf("keepProgress:%d, resub specified query: %"PRIu64"\n",
|
||||
|
@ -7366,7 +7444,8 @@ static void *specifiedSubscribe(void *sarg) {
|
|||
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0;
|
||||
taos_unsubscribe(g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID],
|
||||
g_queryInfo.specifiedQueryInfo.subscribeKeepProgress);
|
||||
g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] = subscribeImpl(
|
||||
g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] =
|
||||
subscribeImpl(
|
||||
SPECIFIED_CLASS,
|
||||
pThreadInfo,
|
||||
g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq],
|
||||
|
@ -7424,12 +7503,12 @@ static int subscribeTestProcess() {
|
|||
|
||||
//==== create threads for query for specified table
|
||||
if (g_queryInfo.specifiedQueryInfo.sqlCount <= 0) {
|
||||
debugPrint("%s() LN%d, sepcified query sqlCount %"PRIu64".\n",
|
||||
debugPrint("%s() LN%d, sepcified query sqlCount %d.\n",
|
||||
__func__, __LINE__,
|
||||
g_queryInfo.specifiedQueryInfo.sqlCount);
|
||||
} else {
|
||||
if (g_queryInfo.specifiedQueryInfo.concurrent <= 0) {
|
||||
errorPrint("%s() LN%d, sepcified query sqlCount %"PRIu64".\n",
|
||||
errorPrint("%s() LN%d, sepcified query sqlCount %d.\n",
|
||||
__func__, __LINE__,
|
||||
g_queryInfo.specifiedQueryInfo.sqlCount);
|
||||
exit(-1);
|
||||
|
@ -7462,7 +7541,7 @@ static int subscribeTestProcess() {
|
|||
|
||||
//==== create threads for super table query
|
||||
if (g_queryInfo.superQueryInfo.sqlCount <= 0) {
|
||||
debugPrint("%s() LN%d, super table query sqlCount %"PRIu64".\n",
|
||||
debugPrint("%s() LN%d, super table query sqlCount %d.\n",
|
||||
__func__, __LINE__,
|
||||
g_queryInfo.superQueryInfo.sqlCount);
|
||||
} else {
|
||||
|
@ -7588,7 +7667,7 @@ static void setParaFromArg(){
|
|||
g_Dbs.threadCountByCreateTbl = g_args.num_of_threads;
|
||||
|
||||
g_Dbs.dbCount = 1;
|
||||
g_Dbs.db[0].drop = 1;
|
||||
g_Dbs.db[0].drop = true;
|
||||
|
||||
tstrncpy(g_Dbs.db[0].dbName, g_args.database, MAX_DB_NAME_SIZE);
|
||||
g_Dbs.db[0].dbCfg.replica = g_args.replica;
|
||||
|
|
|
@ -121,7 +121,7 @@ int32_t mnodeStartSystem() {
|
|||
|
||||
int32_t mnodeInitSystem() {
|
||||
mnodeInitTimer();
|
||||
if (mnodeNeedStart()) {
|
||||
if (mnodeNeedStart() || tsCompactMnodeWal) {
|
||||
return mnodeStartSystem();
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -690,7 +690,7 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
|||
pthread_mutex_unlock(&tsSdbMgmt.mutex);
|
||||
|
||||
// from app, row is created
|
||||
if (pRow != NULL) {
|
||||
if (pRow != NULL && tsCompactMnodeWal != 1) {
|
||||
// forward to peers
|
||||
pRow->processedCount = 0;
|
||||
int32_t syncCode = syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
||||
|
@ -713,7 +713,9 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
|||
actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version);
|
||||
|
||||
// even it is WAL/FWD, it shall be called to update version in sync
|
||||
if (tsCompactMnodeWal != 1) {
|
||||
syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
||||
}
|
||||
|
||||
// from wal or forward msg, row not created, should add into hash
|
||||
if (action == SDB_ACTION_INSERT) {
|
||||
|
|
|
@ -966,6 +966,11 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) {
|
|||
pMsg->rpcMsg.ahandle, pDrop->name, pSTable->uid, pSTable->numOfTables, taosHashGetSize(pSTable->vgHash));
|
||||
return mnodeProcessDropSuperTableMsg(pMsg);
|
||||
} else {
|
||||
// user specify the "DROP STABLE" sql statement, but it is actually a normal table, return error msg.
|
||||
if (pDrop->supertable) {
|
||||
return TSDB_CODE_MND_INVALID_TABLE_TYPE;
|
||||
}
|
||||
|
||||
SCTableObj *pCTable = (SCTableObj *)pMsg->pTable;
|
||||
mInfo("msg:%p, app:%p table:%s, start to drop ctable, vgId:%d tid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle,
|
||||
pDrop->name, pCTable->vgId, pCTable->tid, pCTable->uid);
|
||||
|
@ -1674,12 +1679,9 @@ static int32_t mnodeSetSchemaFromSuperTable(SSchema *pSchema, SSTableObj *pTable
|
|||
return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema);
|
||||
}
|
||||
|
||||
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
||||
static int32_t mnodeDoGetSuperTableMeta(SMnodeMsg *pMsg, STableMetaMsg* pMeta) {
|
||||
SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
|
||||
STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16));
|
||||
if (pMeta == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMeta->uid = htobe64(pTable->uid);
|
||||
pMeta->sversion = htons(pTable->sversion);
|
||||
pMeta->tversion = htons(pTable->tversion);
|
||||
|
@ -1690,6 +1692,18 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
|||
pMeta->contLen = sizeof(STableMetaMsg) + mnodeSetSchemaFromSuperTable(pMeta->schema, pTable);
|
||||
tstrncpy(pMeta->tableFname, pTable->info.tableId, sizeof(pMeta->tableFname));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
||||
SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
|
||||
STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16));
|
||||
if (pMeta == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mnodeDoGetSuperTableMeta(pMsg, pMeta);
|
||||
|
||||
pMsg->rpcRsp.len = pMeta->contLen;
|
||||
pMeta->contLen = htons(pMeta->contLen);
|
||||
|
||||
|
@ -1700,11 +1714,7 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||
SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||
int32_t numOfTable = htonl(pInfo->numOfTables);
|
||||
|
||||
// reserve space
|
||||
static int32_t calculateVgroupMsgLength(SSTableVgroupMsg* pInfo, int32_t numOfTable) {
|
||||
int32_t contLen = sizeof(SSTableVgroupRspMsg) + 32 * sizeof(SVgroupMsg) + sizeof(SVgroupsMsg);
|
||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
||||
|
@ -1716,37 +1726,29 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
|||
mnodeDecTableRef(pTable);
|
||||
}
|
||||
|
||||
SSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen);
|
||||
if (pRsp == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
return contLen;
|
||||
}
|
||||
|
||||
pRsp->numOfTables = 0;
|
||||
char *msg = (char *)pRsp + sizeof(SSTableVgroupRspMsg);
|
||||
static char* serializeVgroupInfo(SSTableObj *pTable, char* name, char* msg, SMnodeMsg* pMsgBody, void* handle) {
|
||||
SName sn = {0};
|
||||
tNameFromString(&sn, name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
const char* tableName = tNameGetTableName(&sn);
|
||||
|
||||
strncpy(msg, tableName, TSDB_TABLE_NAME_LEN);
|
||||
msg += TSDB_TABLE_NAME_LEN;
|
||||
|
||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
||||
SSTableObj *pTable = mnodeGetSuperTable(stableName);
|
||||
if (pTable == NULL) {
|
||||
mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, stableName);
|
||||
mnodeDecTableRef(pTable);
|
||||
continue;
|
||||
}
|
||||
if (pTable->vgHash == NULL) {
|
||||
mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle,
|
||||
stableName);
|
||||
mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsgBody, handle, name);
|
||||
mnodeDecTableRef(pTable);
|
||||
|
||||
// even this super table has no corresponding table, still return
|
||||
pRsp->numOfTables++;
|
||||
|
||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
||||
pVgroupMsg->numOfVgroups = 0;
|
||||
|
||||
msg += sizeof(SVgroupsMsg);
|
||||
} else {
|
||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
||||
mDebug("msg:%p, app:%p stable:%s, hash:%p sizeOfVgList:%d will be returned", pMsg, pMsg->rpcMsg.ahandle,
|
||||
mDebug("msg:%p, app:%p stable:%s, hash:%p sizeOfVgList:%d will be returned", pMsgBody, handle,
|
||||
pTable->info.tableId, pTable->vgHash, taosHashGetSize(pTable->vgHash));
|
||||
|
||||
int32_t *pVgId = taosHashIterate(pTable->vgHash, NULL);
|
||||
|
@ -1754,7 +1756,9 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
|||
while (pVgId) {
|
||||
SVgObj *pVgroup = mnodeGetVgroup(*pVgId);
|
||||
pVgId = taosHashIterate(pTable->vgHash, pVgId);
|
||||
if (pVgroup == NULL) continue;
|
||||
if (pVgroup == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pVgroupMsg->vgroups[vgSize].vgId = htonl(pVgroup->vgId);
|
||||
pVgroupMsg->vgroups[vgSize].numOfEps = 0;
|
||||
|
@ -1780,8 +1784,37 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
// one table is done, try the next table
|
||||
msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SVgroupMsg);
|
||||
pRsp->numOfTables++;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||
SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||
int32_t numOfTable = htonl(pInfo->numOfTables);
|
||||
|
||||
// calculate the required space.
|
||||
int32_t contLen = calculateVgroupMsgLength(pInfo, numOfTable);
|
||||
SSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen);
|
||||
if (pRsp == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pRsp->numOfTables = 0;
|
||||
char *msg = (char *)pRsp + sizeof(SSTableVgroupRspMsg);
|
||||
|
||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
||||
|
||||
SSTableObj *pTable = mnodeGetSuperTable(stableName);
|
||||
if (pTable == NULL) {
|
||||
mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, stableName);
|
||||
mnodeDecTableRef(pTable);
|
||||
continue;
|
||||
}
|
||||
|
||||
msg = serializeVgroupInfo(pTable, stableName, msg, pMsg, pMsg->rpcMsg.ahandle);
|
||||
pRsp->numOfTables++;
|
||||
}
|
||||
|
||||
if (pRsp->numOfTables != numOfTable) {
|
||||
|
@ -2415,9 +2448,9 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) {
|
|||
pMeta->vgroup.numOfEps++;
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId);
|
||||
|
||||
mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d sid:%d", pMsg, pMsg->rpcMsg.ahandle,
|
||||
pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId);
|
||||
mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d tid:%d", pMsg, pMsg->rpcMsg.ahandle,
|
||||
pTable->info.tableId, pTable->uid, pTable->vgId, pTable->tid);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -2811,56 +2844,137 @@ static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg) {
|
|||
|
||||
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
||||
SMultiTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||
pInfo->numOfTables = htonl(pInfo->numOfTables);
|
||||
|
||||
int32_t totalMallocLen = 4 * 1024 * 1024; // first malloc 4 MB, subsequent reallocation as twice
|
||||
SMultiTableMeta *pMultiMeta = rpcMallocCont(totalMallocLen);
|
||||
pInfo->numOfTables = htonl(pInfo->numOfTables);
|
||||
pInfo->numOfVgroups = htonl(pInfo->numOfVgroups);
|
||||
|
||||
int32_t contLen = pMsg->rpcMsg.contLen - sizeof(SMultiTableInfoMsg);
|
||||
|
||||
int32_t num = 0;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
char* str = strndup(pInfo->tableNames, contLen);
|
||||
char** nameList = strsplit(str, ",", &num);
|
||||
SArray* pList = taosArrayInit(4, POINTER_BYTES);
|
||||
SMultiTableMeta *pMultiMeta = NULL;
|
||||
|
||||
if (num != pInfo->numOfTables + pInfo->numOfVgroups) {
|
||||
mError("msg:%p, app:%p, failed to get multi-tableMeta, msg inconsistent", pMsg, pMsg->rpcMsg.ahandle);
|
||||
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
// first malloc 80KB, subsequent reallocation will expand the size as twice of the original size
|
||||
int32_t totalMallocLen = sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16);
|
||||
pMultiMeta = rpcMallocCont(totalMallocLen);
|
||||
if (pMultiMeta == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
code = TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
pMultiMeta->contLen = sizeof(SMultiTableMeta);
|
||||
pMultiMeta->numOfTables = 0;
|
||||
|
||||
for (int32_t t = 0; t < pInfo->numOfTables; ++t) {
|
||||
char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_FNAME_LEN);
|
||||
SCTableObj *pTable = mnodeGetChildTable(tableId);
|
||||
if (pTable == NULL) continue;
|
||||
int32_t t = 0;
|
||||
for (; t < pInfo->numOfTables; ++t) {
|
||||
char *fullName = nameList[t];
|
||||
|
||||
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableName(tableId);
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||
mnodeDecTableRef(pTable);
|
||||
continue;
|
||||
pMsg->pTable = mnodeGetTable(fullName);
|
||||
if (pMsg->pTable == NULL) {
|
||||
mError("msg:%p, app:%p table:%s, failed to get table meta, table not exist", pMsg, pMsg->rpcMsg.ahandle, fullName);
|
||||
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
int availLen = totalMallocLen - pMultiMeta->contLen;
|
||||
if (availLen <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) {
|
||||
if (pMsg->pDb == NULL) {
|
||||
pMsg->pDb = mnodeGetDbByTableName(fullName);
|
||||
}
|
||||
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||
mnodeDecTableRef(pMsg->pTable);
|
||||
code = TSDB_CODE_APP_NOT_READY;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
int remain = totalMallocLen - pMultiMeta->contLen;
|
||||
if (remain <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) {
|
||||
totalMallocLen *= 2;
|
||||
pMultiMeta = rpcReallocCont(pMultiMeta, totalMallocLen);
|
||||
if (pMultiMeta == NULL) {
|
||||
mnodeDecTableRef(pTable);
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
} else {
|
||||
t--;
|
||||
mnodeDecTableRef(pTable);
|
||||
continue;
|
||||
mnodeDecTableRef(pMsg->pTable);
|
||||
code = TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
|
||||
STableMetaMsg *pMeta = (STableMetaMsg *)(pMultiMeta->metas + pMultiMeta->contLen);
|
||||
int32_t code = mnodeDoGetChildTableMeta(pMsg, pMeta);
|
||||
STableMetaMsg *pMeta = (STableMetaMsg *)((char*) pMultiMeta + pMultiMeta->contLen);
|
||||
|
||||
if (pMsg->pTable->type == TSDB_SUPER_TABLE) {
|
||||
code = mnodeDoGetSuperTableMeta(pMsg, pMeta);
|
||||
taosArrayPush(pList, &fullName); // keep the full name for each super table for retrieve vgroup list
|
||||
} else {
|
||||
code = mnodeDoGetChildTableMeta(pMsg, pMeta);
|
||||
if (pMsg->pVgroup != NULL) {
|
||||
mnodeDecVgroupRef(pMsg->pVgroup);
|
||||
pMsg->pVgroup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mnodeDecTableRef(pMsg->pTable);
|
||||
pMsg->pTable = NULL;
|
||||
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
pMultiMeta->numOfTables++;
|
||||
pMultiMeta->contLen += pMeta->contLen;
|
||||
} else {
|
||||
// ignore error and continue.
|
||||
// Otherwise the client may found that the responding message is inconsistent.
|
||||
// goto _end;
|
||||
}
|
||||
}
|
||||
|
||||
mnodeDecTableRef(pTable);
|
||||
char* msg = (char*) pMultiMeta + pMultiMeta->contLen;
|
||||
|
||||
// add the additional super table names that needs the vgroup info
|
||||
for(;t < num; ++t) {
|
||||
taosArrayPush(pList, &nameList[t]);
|
||||
}
|
||||
|
||||
// add the pVgroupList into the pList
|
||||
int32_t numOfVgroupList = (int32_t) taosArrayGetSize(pList);
|
||||
pMultiMeta->numOfVgroup = htonl(numOfVgroupList);
|
||||
|
||||
for(int32_t i = 0; i < numOfVgroupList; ++i) {
|
||||
char* name = taosArrayGetP(pList, i);
|
||||
|
||||
SSTableObj *pTable = mnodeGetSuperTable(name);
|
||||
if (pTable == NULL) {
|
||||
mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, name);
|
||||
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
msg = serializeVgroupInfo(pTable, name, msg, pMsg, pMsg->rpcMsg.ahandle);
|
||||
}
|
||||
|
||||
pMultiMeta->contLen = (int32_t) (msg - (char*) pMultiMeta);
|
||||
|
||||
pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables);
|
||||
pMsg->rpcRsp.rsp = pMultiMeta;
|
||||
pMsg->rpcRsp.len = pMultiMeta->contLen;
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_end:
|
||||
tfree(str);
|
||||
tfree(nameList);
|
||||
taosArrayDestroy(pList);
|
||||
pMsg->pTable = NULL;
|
||||
pMsg->pVgroup = NULL;
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
rpcFreeCont(pMultiMeta);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
|
@ -3267,7 +3381,7 @@ static int32_t mnodeCompactSuperTables() {
|
|||
.rowSize = sizeof(SSTableObj) + schemaSize,
|
||||
};
|
||||
|
||||
mInfo("compact super %" PRIu64, pTable->uid);
|
||||
//mInfo("compact super %" PRIu64, pTable->uid);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
@ -3293,7 +3407,7 @@ static int32_t mnodeCompactChildTables() {
|
|||
.pTable = tsChildTableSdb,
|
||||
};
|
||||
|
||||
mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid);
|
||||
//mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
|
|
@ -87,12 +87,12 @@ static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t time
|
|||
|
||||
int32_t taosGetTimestampSec() { return (int32_t)time(NULL); }
|
||||
|
||||
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t daylight) {
|
||||
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
|
||||
/* parse datatime string in with tz */
|
||||
if (strnchr(timestr, 'T', len, false) != NULL) {
|
||||
return parseTimeWithTz(timestr, time, timePrec);
|
||||
} else {
|
||||
return (*parseLocaltimeFp[daylight])(timestr, time, timePrec);
|
||||
return (*parseLocaltimeFp[day_light])(timestr, time, timePrec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char *errMsg) {
|
|||
}
|
||||
}
|
||||
|
||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_SQL & 0XFFFF, temp);
|
||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_OPERATION & 0XFFFF, temp);
|
||||
}
|
||||
|
||||
void httpSendSuccResp(HttpContext *pContext, char *desc) {
|
||||
|
|
|
@ -263,7 +263,7 @@ void httpProcessSingleSqlCallBackImp(void *param, TAOS_RES *result, int32_t code
|
|||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
SSqlObj *pObj = (SSqlObj *)result;
|
||||
if (code == TSDB_CODE_TSC_INVALID_SQL) {
|
||||
if (code == TSDB_CODE_TSC_INVALID_OPERATION) {
|
||||
terrno = code;
|
||||
httpError("context:%p, fd:%d, user:%s, query error, code:%s, sqlObj:%p, error:%s", pContext, pContext->fd,
|
||||
pContext->user, tstrerror(code), pObj, taos_errstr(pObj));
|
||||
|
|
|
@ -237,6 +237,11 @@ void httpFreeMultiCmds(HttpContext *pContext) {
|
|||
JsonBuf *httpMallocJsonBuf(HttpContext *pContext) {
|
||||
if (pContext->jsonBuf == NULL) {
|
||||
pContext->jsonBuf = (JsonBuf *)malloc(sizeof(JsonBuf));
|
||||
if (pContext->jsonBuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(pContext->jsonBuf, 0, sizeof(JsonBuf));
|
||||
}
|
||||
|
||||
if (!pContext->jsonBuf->pContext) {
|
||||
|
|
|
@ -70,13 +70,13 @@ typedef struct SResultRowPool {
|
|||
SArray* pData; // SArray<void*>
|
||||
} SResultRowPool;
|
||||
|
||||
typedef struct SSqlGroupbyExpr {
|
||||
typedef struct SGroupbyExpr {
|
||||
int16_t tableIndex;
|
||||
SArray* columnInfo; // SArray<SColIndex>, group by columns information
|
||||
int16_t numOfGroupCols;
|
||||
int16_t numOfGroupCols; // todo remove it
|
||||
int16_t orderIndex; // order by column index
|
||||
int16_t orderType; // order by type: asc/desc
|
||||
} SSqlGroupbyExpr;
|
||||
} SGroupbyExpr;
|
||||
|
||||
typedef struct SResultRow {
|
||||
int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer
|
||||
|
@ -216,7 +216,7 @@ typedef struct SQueryAttr {
|
|||
int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query.
|
||||
int32_t maxTableColumnWidth;
|
||||
int32_t tagLen; // tag value length of current query
|
||||
SSqlGroupbyExpr* pGroupbyExpr;
|
||||
SGroupbyExpr* pGroupbyExpr;
|
||||
|
||||
SExprInfo* pExpr1;
|
||||
SExprInfo* pExpr2;
|
||||
|
@ -302,6 +302,7 @@ enum OPERATOR_TYPE_E {
|
|||
OP_GlobalAggregate = 18, // global merge for the multi-way data sources.
|
||||
OP_Filter = 19,
|
||||
OP_Distinct = 20,
|
||||
OP_Join = 21,
|
||||
};
|
||||
|
||||
typedef struct SOperatorInfo {
|
||||
|
@ -314,7 +315,8 @@ typedef struct SOperatorInfo {
|
|||
SExprInfo *pExpr;
|
||||
SQueryRuntimeEnv *pRuntimeEnv;
|
||||
|
||||
struct SOperatorInfo *upstream;
|
||||
struct SOperatorInfo **upstream; // upstream pointer list
|
||||
int32_t numOfUpstream; // number of upstream. The value is always ONE expect for join operator
|
||||
__operator_fn_t exec;
|
||||
__optr_cleanup_fn_t cleanup;
|
||||
} SOperatorInfo;
|
||||
|
@ -362,7 +364,7 @@ typedef struct SQueryParam {
|
|||
|
||||
SColIndex *pGroupColIndex;
|
||||
SColumnInfo *pTagColumnInfo;
|
||||
SSqlGroupbyExpr *pGroupbyExpr;
|
||||
SGroupbyExpr *pGroupbyExpr;
|
||||
int32_t tableScanOperator;
|
||||
SArray *pOperator;
|
||||
} SQueryParam;
|
||||
|
@ -494,6 +496,8 @@ typedef struct SMultiwayMergeInfo {
|
|||
bool groupMix;
|
||||
} SMultiwayMergeInfo;
|
||||
|
||||
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream);
|
||||
|
||||
SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime);
|
||||
SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime);
|
||||
SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||
|
@ -514,12 +518,20 @@ SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SEx
|
|||
int32_t numOfRows, void* merger, bool groupMix);
|
||||
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param);
|
||||
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||
int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter);
|
||||
|
||||
SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput);
|
||||
|
||||
SSDataBlock* doGlobalAggregate(void* param, bool* newgroup);
|
||||
SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup);
|
||||
SSDataBlock* doSLimit(void* param, bool* newgroup);
|
||||
|
||||
int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId);
|
||||
void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock);
|
||||
bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p);
|
||||
void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p);
|
||||
|
||||
SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows);
|
||||
void* destroyOutputBuf(SSDataBlock* pBlock);
|
||||
|
||||
|
@ -536,13 +548,14 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
|
|||
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
|
||||
SSqlExpr **pExpr, SExprInfo *prevExpr);
|
||||
|
||||
SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
||||
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
||||
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t *qId);
|
||||
|
||||
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
|
||||
int32_t prevResultLen, void* merger);
|
||||
|
||||
int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId);
|
||||
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters);
|
||||
|
||||
STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf);
|
||||
|
|
|
@ -62,7 +62,7 @@ typedef struct SFillInfo {
|
|||
|
||||
SFillColInfo* pFillCol; // column info for fill operations
|
||||
SFillTagColInfo* pTags; // tags value for filling gap
|
||||
void* handle; // for dubug purpose
|
||||
void* handle; // for debug purpose
|
||||
} SFillInfo;
|
||||
|
||||
typedef struct SPoint {
|
||||
|
@ -82,8 +82,6 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
|
|||
|
||||
void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
||||
|
||||
void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* pInput);
|
||||
|
||||
bool taosFillHasMoreResults(SFillInfo* pFillInfo);
|
||||
|
||||
int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows);
|
||||
|
|
|
@ -16,7 +16,38 @@
|
|||
#ifndef TDENGINE_QPLAN_H
|
||||
#define TDENGINE_QPLAN_H
|
||||
|
||||
//TODO refactor
|
||||
struct SQueryInfo;
|
||||
|
||||
typedef struct SQueryNodeBasicInfo {
|
||||
int32_t type;
|
||||
char *name;
|
||||
} SQueryNodeBasicInfo;
|
||||
|
||||
typedef struct SQueryTableInfo {
|
||||
char *tableName;
|
||||
STableId id;
|
||||
} SQueryTableInfo;
|
||||
|
||||
typedef struct SQueryNode {
|
||||
SQueryNodeBasicInfo info;
|
||||
SQueryTableInfo tableInfo;
|
||||
SSchema *pSchema; // the schema of the input SSDatablock
|
||||
int32_t numOfCols; // number of input columns
|
||||
SExprInfo *pExpr; // the query functions or sql aggregations
|
||||
int32_t numOfOutput; // number of result columns, which is also the number of pExprs
|
||||
|
||||
void *pExtInfo; // additional information
|
||||
// previous operator to generated result for current node to process
|
||||
// in case of join, multiple prev nodes exist.
|
||||
SArray *pPrevNodes;// upstream nodes
|
||||
struct SQueryNode *nextNode;
|
||||
} SQueryNode;
|
||||
|
||||
SQueryNode* qCreateQueryPlan(struct SQueryInfo* pQueryInfo);
|
||||
void* qDestroyQueryPlan(SQueryNode* pQueryNode);
|
||||
|
||||
char* queryPlanToString(SQueryNode* pQueryNode);
|
||||
|
||||
SArray* createTableScanPlan(SQueryAttr* pQueryAttr);
|
||||
SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr);
|
||||
SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr);
|
||||
|
|
|
@ -107,14 +107,18 @@ typedef struct SSqlNode {
|
|||
struct tSqlExpr *pHaving; // having clause [optional]
|
||||
} SSqlNode;
|
||||
|
||||
typedef struct STableNamePair {
|
||||
SStrToken name;
|
||||
typedef struct SRelElementPair {
|
||||
union {
|
||||
SStrToken tableName;
|
||||
SArray *pSubquery;
|
||||
};
|
||||
|
||||
SStrToken aliasName;
|
||||
} STableNamePair;
|
||||
} SRelElementPair;
|
||||
|
||||
typedef struct SRelationInfo {
|
||||
int32_t type; // nested query|table name list
|
||||
SArray *list; // SArray<STableNamePair>|SArray<SSqlNode*>
|
||||
SArray *list; // SArray<SRelElementPair>
|
||||
} SRelationInfo;
|
||||
|
||||
typedef struct SCreatedTableInfo {
|
||||
|
@ -254,8 +258,9 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int
|
|||
SArray *tVariantListAppendToken(SArray *pList, SStrToken *pAliasToken, uint8_t sortOrder);
|
||||
|
||||
SRelationInfo *setTableNameList(SRelationInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias);
|
||||
SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SArray* pSqlNode);
|
||||
//SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SRelElementPair* p);
|
||||
void *destroyRelationInfo(SRelationInfo* pFromInfo);
|
||||
SRelationInfo *addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias);
|
||||
|
||||
// sql expr leaf node
|
||||
tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType);
|
||||
|
|
|
@ -47,6 +47,9 @@ void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, in
|
|||
|
||||
SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset);
|
||||
|
||||
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
|
||||
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols);
|
||||
|
||||
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
||||
return pResultRowInfo->pResult[slot];
|
||||
|
|
|
@ -512,7 +512,13 @@ distinct(X) ::= . { X.n = 0;}
|
|||
%type from {SRelationInfo*}
|
||||
%destructor from {destroyRelationInfo($$);}
|
||||
from(A) ::= FROM tablelist(X). {A = X;}
|
||||
from(A) ::= FROM LP union(Y) RP. {A = setSubquery(NULL, Y);}
|
||||
from(A) ::= FROM sub(X). {A = X;}
|
||||
|
||||
%type sub {SRelationInfo*}
|
||||
%destructor sub {destroyRelationInfo($$);}
|
||||
sub(A) ::= LP union(Y) RP. {A = addSubqueryElem(NULL, Y, NULL);}
|
||||
sub(A) ::= LP union(Y) RP ids(Z). {A = addSubqueryElem(NULL, Y, &Z);}
|
||||
sub(A) ::= sub(X) COMMA LP union(Y) RP ids(Z).{A = addSubqueryElem(X, Y, &Z);}
|
||||
|
||||
%type tablelist {SRelationInfo*}
|
||||
%destructor tablelist {destroyRelationInfo($$);}
|
||||
|
|
|
@ -166,7 +166,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
|||
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) {
|
||||
if (!isValidDataType(dataType)) {
|
||||
qError("Illegal data type %d or data type length %d", dataType, dataBytes);
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY ||
|
||||
|
@ -353,7 +353,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
|||
*interBytes = (*bytes);
|
||||
|
||||
} else {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -3700,7 +3700,7 @@ char *getArithColumnData(void *param, const char* name, int32_t colId) {
|
|||
}
|
||||
}
|
||||
|
||||
assert(index >= 0 /*&& colId >= 0*/);
|
||||
assert(index >= 0);
|
||||
return pSupport->data[index] + pSupport->offset * pSupport->colList[index].bytes;
|
||||
}
|
||||
|
||||
|
@ -4839,7 +4839,7 @@ static void mergeTableBlockDist(STableBlockDist* pDist, const STableBlockDist* p
|
|||
pDist->dataBlockInfos = taosArrayInit(4, sizeof(SFileBlockInfo));
|
||||
}
|
||||
|
||||
taosArrayPushBatch(pDist->dataBlockInfos, pSrc->dataBlockInfos->pData, (int32_t) taosArrayGetSize(pSrc->dataBlockInfos));
|
||||
taosArrayAddBatch(pDist->dataBlockInfos, pSrc->dataBlockInfos->pData, (int32_t) taosArrayGetSize(pSrc->dataBlockInfos));
|
||||
}
|
||||
|
||||
void block_func_merge(SQLFunctionCtx* pCtx) {
|
||||
|
|
|
@ -171,6 +171,8 @@ static void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, S
|
|||
static void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo);
|
||||
static bool hasMainOutput(SQueryAttr *pQueryAttr);
|
||||
|
||||
static SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int32_t* numOfFilterCols);
|
||||
|
||||
static int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, STableQueryInfo *pTableQueryInfo);
|
||||
static void releaseQueryBuf(size_t numOfTables);
|
||||
static int32_t binarySearchForKey(char *pValue, int num, TSKEY key, int order);
|
||||
|
@ -178,8 +180,6 @@ static STsdbQueryCond createTsdbQueryCond(SQueryAttr* pQueryAttr, STimeWindow* w
|
|||
static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo);
|
||||
|
||||
static void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInfo* pDownstream);
|
||||
static int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols,
|
||||
SSingleColumnFilterInfo** pFilterInfo, uint64_t qId);
|
||||
static void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols);
|
||||
|
||||
static int32_t getNumOfScanTimes(SQueryAttr* pQueryAttr);
|
||||
|
@ -193,7 +193,7 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator);
|
|||
|
||||
static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock);
|
||||
|
||||
static int32_t getGroupbyColumnIndex(SSqlGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock);
|
||||
static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock);
|
||||
static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOperatorInfo *pInfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex);
|
||||
|
||||
static void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size);
|
||||
|
@ -1422,7 +1422,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOp
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t getGroupbyColumnIndex(SSqlGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock) {
|
||||
static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock) {
|
||||
for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) {
|
||||
SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, k);
|
||||
if (TSDB_COL_IS_TAG(pColIndex->flag)) {
|
||||
|
@ -1712,38 +1712,40 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
|||
case OP_MultiTableTimeInterval: {
|
||||
pRuntimeEnv->proot =
|
||||
createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot);
|
||||
break;
|
||||
}
|
||||
case OP_TimeWindow: {
|
||||
pRuntimeEnv->proot =
|
||||
createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot);
|
||||
break;
|
||||
}
|
||||
case OP_Groupby: {
|
||||
pRuntimeEnv->proot =
|
||||
createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot);
|
||||
break;
|
||||
}
|
||||
case OP_SessionWindow: {
|
||||
pRuntimeEnv->proot =
|
||||
createSWindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot);
|
||||
break;
|
||||
}
|
||||
case OP_MultiTableAggregate: {
|
||||
pRuntimeEnv->proot =
|
||||
createMultiTableAggOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot);
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot);
|
||||
break;
|
||||
}
|
||||
case OP_Aggregate: {
|
||||
pRuntimeEnv->proot =
|
||||
createAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||
if (pRuntimeEnv->proot->upstream->operatorType != OP_DummyInput) {
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot);
|
||||
|
||||
int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType;
|
||||
if (opType != OP_DummyInput && opType != OP_Join) {
|
||||
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1752,7 +1754,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
|||
SOperatorInfo* prev = pRuntimeEnv->proot;
|
||||
if (i == 0) {
|
||||
pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, prev, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||
if (pRuntimeEnv->proot != NULL && pRuntimeEnv->proot->operatorType != OP_DummyInput) { // TODO refactor
|
||||
if (pRuntimeEnv->proot != NULL && prev->operatorType != OP_DummyInput && prev->operatorType != OP_Join) { // TODO refactor
|
||||
setTableScanFilterOperatorInfo(prev->info, pRuntimeEnv->proot);
|
||||
}
|
||||
} else {
|
||||
|
@ -1769,12 +1771,25 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
|||
}
|
||||
|
||||
case OP_Filter: { // todo refactor
|
||||
assert(pQueryAttr->havingNum > 0);
|
||||
int32_t numOfFilterCols = 0;
|
||||
// if (pQueryAttr->numOfFilterCols > 0) {
|
||||
// pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1,
|
||||
// pQueryAttr->numOfOutput, pQueryAttr->tableCols, pQueryAttr->numOfFilterCols);
|
||||
// } else {
|
||||
if (pQueryAttr->stableQuery) {
|
||||
pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3, pQueryAttr->numOfExpr3);
|
||||
SColumnInfo* pColInfo =
|
||||
extractColumnFilterInfo(pQueryAttr->pExpr3, pQueryAttr->numOfExpr3, &numOfFilterCols);
|
||||
pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3,
|
||||
pQueryAttr->numOfExpr3, pColInfo, numOfFilterCols);
|
||||
freeColumnInfo(pColInfo, pQueryAttr->numOfExpr3);
|
||||
} else {
|
||||
pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||
SColumnInfo* pColInfo =
|
||||
extractColumnFilterInfo(pQueryAttr->pExpr1, pQueryAttr->numOfOutput, &numOfFilterCols);
|
||||
pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1,
|
||||
pQueryAttr->numOfOutput, pColInfo, numOfFilterCols);
|
||||
freeColumnInfo(pColInfo, pQueryAttr->numOfOutput);
|
||||
}
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2392,38 +2407,9 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key, bool asc
|
|||
return TS_JOIN_TS_EQUAL;
|
||||
}
|
||||
|
||||
void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols,
|
||||
SSDataBlock* pBlock, bool ascQuery) {
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
|
||||
int8_t *p = calloc(numOfRows, sizeof(int8_t));
|
||||
bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p) {
|
||||
bool all = true;
|
||||
|
||||
if (pRuntimeEnv->pTsBuf != NULL) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
|
||||
TSKEY* k = (TSKEY*) pColInfoData->pData;
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
int32_t offset = ascQuery? i:(numOfRows - i - 1);
|
||||
int32_t ret = doTSJoinFilter(pRuntimeEnv, k[offset], ascQuery);
|
||||
if (ret == TS_JOIN_TAG_NOT_EQUALS) {
|
||||
break;
|
||||
} else if (ret == TS_JOIN_TS_NOT_EQUALS) {
|
||||
all = false;
|
||||
continue;
|
||||
} else {
|
||||
assert(ret == TS_JOIN_TS_EQUAL);
|
||||
p[offset] = true;
|
||||
}
|
||||
|
||||
if (!tsBufNextPos(pRuntimeEnv->pTsBuf)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// save the cursor status
|
||||
pRuntimeEnv->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf);
|
||||
} else {
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
bool qualified = false;
|
||||
|
||||
|
@ -2467,11 +2453,13 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf
|
|||
all = false;
|
||||
}
|
||||
}
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
if (!all) {
|
||||
int32_t start = 0;
|
||||
void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p) {
|
||||
int32_t len = 0;
|
||||
int32_t start = 0;
|
||||
for (int32_t j = 0; j < numOfRows; ++j) {
|
||||
if (p[j] == 1) {
|
||||
len++;
|
||||
|
@ -2482,7 +2470,8 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf
|
|||
SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
|
||||
int16_t bytes = pColumnInfoData->info.bytes;
|
||||
memmove(((char*)pColumnInfoData->pData) + start * bytes, pColumnInfoData->pData + cstart * bytes, len * bytes);
|
||||
memmove(((char*)pColumnInfoData->pData) + start * bytes, pColumnInfoData->pData + cstart * bytes,
|
||||
len * bytes);
|
||||
}
|
||||
|
||||
start += len;
|
||||
|
@ -2517,6 +2506,45 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf
|
|||
}
|
||||
}
|
||||
|
||||
void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols,
|
||||
SSDataBlock* pBlock, bool ascQuery) {
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
|
||||
int8_t *p = calloc(numOfRows, sizeof(int8_t));
|
||||
bool all = true;
|
||||
|
||||
if (pRuntimeEnv->pTsBuf != NULL) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
|
||||
TSKEY* k = (TSKEY*) pColInfoData->pData;
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
int32_t offset = ascQuery? i:(numOfRows - i - 1);
|
||||
int32_t ret = doTSJoinFilter(pRuntimeEnv, k[offset], ascQuery);
|
||||
if (ret == TS_JOIN_TAG_NOT_EQUALS) {
|
||||
break;
|
||||
} else if (ret == TS_JOIN_TS_NOT_EQUALS) {
|
||||
all = false;
|
||||
continue;
|
||||
} else {
|
||||
assert(ret == TS_JOIN_TS_EQUAL);
|
||||
p[offset] = true;
|
||||
}
|
||||
|
||||
if (!tsBufNextPos(pRuntimeEnv->pTsBuf)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// save the cursor status
|
||||
pRuntimeEnv->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf);
|
||||
} else {
|
||||
all = doFilterDataBlock(pFilterInfo, numOfFilterCols, numOfRows, p);
|
||||
}
|
||||
|
||||
if (!all) {
|
||||
doCompactSDataBlock(pBlock, numOfRows, p);
|
||||
}
|
||||
|
||||
tfree(p);
|
||||
}
|
||||
|
||||
|
@ -2542,7 +2570,7 @@ static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSData
|
|||
return status;
|
||||
}
|
||||
|
||||
static void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock) {
|
||||
void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock) {
|
||||
if (numOfFilterCols > 0 && pFilterInfo[0].pData != NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -3947,6 +3975,15 @@ void queryCostStatis(SQInfo *pQInfo) {
|
|||
// return true;
|
||||
//}
|
||||
|
||||
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream) {
|
||||
if (p->upstream == NULL) {
|
||||
assert(p->numOfUpstream == 0);
|
||||
}
|
||||
|
||||
p->upstream = realloc(p->upstream, POINTER_BYTES * (p->numOfUpstream + 1));
|
||||
p->upstream[p->numOfUpstream++] = pUpstream;
|
||||
}
|
||||
|
||||
static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo);
|
||||
|
||||
static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64_t qId, bool isSTableQuery) {
|
||||
|
@ -4626,13 +4663,14 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv,
|
|||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
|
||||
pOperator->exec = doGlobalAggregate;
|
||||
pOperator->cleanup = destroyGlobalAggOperatorInfo;
|
||||
appendUpstream(pOperator, upstream);
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -4697,7 +4735,7 @@ static SSDataBlock* doAggregate(void* param, bool* newgroup) {
|
|||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||
int32_t order = pQueryAttr->order.order;
|
||||
|
||||
SOperatorInfo* upstream = pOperator->upstream;
|
||||
SOperatorInfo* upstream = pOperator->upstream[0];
|
||||
|
||||
while(1) {
|
||||
SSDataBlock* pBlock = upstream->exec(upstream, newgroup);
|
||||
|
@ -4752,7 +4790,7 @@ static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) {
|
|||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||
int32_t order = pQueryAttr->order.order;
|
||||
|
||||
SOperatorInfo* upstream = pOperator->upstream;
|
||||
SOperatorInfo* upstream = pOperator->upstream[0];
|
||||
|
||||
while(1) {
|
||||
SSDataBlock* pBlock = upstream->exec(upstream, newgroup);
|
||||
|
@ -4836,7 +4874,7 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) {
|
|||
bool prevVal = *newgroup;
|
||||
|
||||
// The upstream exec may change the value of the newgroup, so use a local variable instead.
|
||||
SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
SSDataBlock* pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
assert(*newgroup == false);
|
||||
|
||||
|
@ -4870,7 +4908,7 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) {
|
|||
}
|
||||
|
||||
pRes->info.rows = getNumOfResult(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput);
|
||||
if (pRes->info.rows >= pRuntimeEnv->resultInfo.threshold) {
|
||||
if (pRes->info.rows >= 1000/*pRuntimeEnv->resultInfo.threshold*/) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4890,7 +4928,7 @@ static SSDataBlock* doLimit(void* param, bool* newgroup) {
|
|||
|
||||
SSDataBlock* pBlock = NULL;
|
||||
while (1) {
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
@ -4930,27 +4968,6 @@ static SSDataBlock* doLimit(void* param, bool* newgroup) {
|
|||
return pBlock;
|
||||
}
|
||||
|
||||
|
||||
bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem, __filter_func_t fp) {
|
||||
char* input = p->pData + p->info.bytes * rid;
|
||||
bool isnull = isNull(input, p->info.type);
|
||||
if (isnull) {
|
||||
return (fp == isNullOperator) ? true : false;
|
||||
} else {
|
||||
if (fp == notNullOperator) {
|
||||
return true;
|
||||
} else if (fp == isNullOperator) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fp(filterElem, input, input, p->info.type)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static SSDataBlock* doFilter(void* param, bool* newgroup) {
|
||||
SOperatorInfo *pOperator = (SOperatorInfo *)param;
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
|
@ -4961,7 +4978,7 @@ static SSDataBlock* doFilter(void* param, bool* newgroup) {
|
|||
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||
|
||||
while (1) {
|
||||
SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
SSDataBlock *pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -5003,7 +5020,7 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) {
|
|||
int32_t order = pQueryAttr->order.order;
|
||||
STimeWindow win = pQueryAttr->window;
|
||||
|
||||
SOperatorInfo* upstream = pOperator->upstream;
|
||||
SOperatorInfo* upstream = pOperator->upstream[0];
|
||||
|
||||
while(1) {
|
||||
SSDataBlock* pBlock = upstream->exec(upstream, newgroup);
|
||||
|
@ -5056,7 +5073,7 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) {
|
|||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||
int32_t order = pQueryAttr->order.order;
|
||||
|
||||
SOperatorInfo* upstream = pOperator->upstream;
|
||||
SOperatorInfo* upstream = pOperator->upstream[0];
|
||||
|
||||
while(1) {
|
||||
SSDataBlock* pBlock = upstream->exec(upstream, newgroup);
|
||||
|
@ -5111,7 +5128,7 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) {
|
|||
int32_t order = pQueryAttr->order.order;
|
||||
STimeWindow win = pQueryAttr->window;
|
||||
|
||||
SOperatorInfo* upstream = pOperator->upstream;
|
||||
SOperatorInfo* upstream = pOperator->upstream[0];
|
||||
|
||||
while(1) {
|
||||
SSDataBlock* pBlock = upstream->exec(upstream, newgroup);
|
||||
|
@ -5162,7 +5179,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) {
|
|||
return pInfo->binfo.pRes;
|
||||
}
|
||||
|
||||
SOperatorInfo* upstream = pOperator->upstream;
|
||||
SOperatorInfo* upstream = pOperator->upstream[0];
|
||||
|
||||
while(1) {
|
||||
SSDataBlock* pBlock = upstream->exec(upstream, newgroup);
|
||||
|
@ -5231,7 +5248,7 @@ static SSDataBlock* doFill(void* param, bool* newgroup) {
|
|||
}
|
||||
|
||||
while(1) {
|
||||
SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
SSDataBlock* pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (*newgroup) {
|
||||
assert(pBlock != NULL);
|
||||
}
|
||||
|
@ -5307,7 +5324,15 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) {
|
|||
pOperator->cleanup(pOperator->info, pOperator->numOfOutput);
|
||||
}
|
||||
|
||||
destroyOperatorInfo(pOperator->upstream);
|
||||
if (pOperator->upstream != NULL) {
|
||||
for(int32_t i = 0; i < pOperator->numOfUpstream; ++i) {
|
||||
destroyOperatorInfo(pOperator->upstream[i]);
|
||||
}
|
||||
|
||||
tfree(pOperator->upstream);
|
||||
pOperator->numOfUpstream = 0;
|
||||
}
|
||||
|
||||
tfree(pOperator->info);
|
||||
tfree(pOperator);
|
||||
}
|
||||
|
@ -5332,13 +5357,14 @@ SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera
|
|||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
|
||||
pOperator->exec = doAggregate;
|
||||
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||
appendUpstream(pOperator, upstream);
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -5405,13 +5431,13 @@ SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SO
|
|||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
|
||||
pOperator->exec = doSTableAggregate;
|
||||
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||
appendUpstream(pOperator, upstream);
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
@ -5435,22 +5461,18 @@ SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI
|
|||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
|
||||
pOperator->exec = doArithmeticOperation;
|
||||
pOperator->cleanup = destroyArithOperatorInfo;
|
||||
appendUpstream(pOperator, upstream);
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||
int32_t numOfOutput) {
|
||||
SFilterOperatorInfo* pInfo = calloc(1, sizeof(SFilterOperatorInfo));
|
||||
|
||||
{
|
||||
SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int32_t* numOfFilterCols) {
|
||||
SColumnInfo* pCols = calloc(numOfOutput, sizeof(SColumnInfo));
|
||||
|
||||
int32_t numOfFilter = 0;
|
||||
|
@ -5469,29 +5491,32 @@ SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator
|
|||
}
|
||||
|
||||
assert(numOfFilter > 0);
|
||||
|
||||
*numOfFilterCols = numOfFilter;
|
||||
return pCols;
|
||||
}
|
||||
|
||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||
int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter) {
|
||||
SFilterOperatorInfo* pInfo = calloc(1, sizeof(SFilterOperatorInfo));
|
||||
|
||||
assert(numOfFilter > 0 && pCols != NULL);
|
||||
doCreateFilterInfo(pCols, numOfOutput, numOfFilter, &pInfo->pFilterInfo, 0);
|
||||
pInfo->numOfFilterCols = numOfFilter;
|
||||
|
||||
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||
tfree(pCols[i].flist.filterInfo);
|
||||
}
|
||||
|
||||
tfree(pCols);
|
||||
}
|
||||
|
||||
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||
|
||||
pOperator->name = "ConditionOperator";
|
||||
pOperator->name = "FilterOperator";
|
||||
pOperator->operatorType = OP_Filter;
|
||||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->exec = doFilter;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
pOperator->cleanup = destroyConditionOperatorInfo;
|
||||
appendUpstream(pOperator, upstream);
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
@ -5506,10 +5531,10 @@ SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI
|
|||
pOperator->operatorType = OP_Limit;
|
||||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->exec = doLimit;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
appendUpstream(pOperator, upstream);
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
@ -5527,7 +5552,6 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
|||
pOperator->operatorType = OP_TimeWindow;
|
||||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->info = pInfo;
|
||||
|
@ -5535,6 +5559,7 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
|||
pOperator->exec = doIntervalAgg;
|
||||
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||
|
||||
appendUpstream(pOperator, upstream);
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -5552,7 +5577,6 @@ SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato
|
|||
pOperator->operatorType = OP_SessionWindow;
|
||||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->info = pInfo;
|
||||
|
@ -5560,6 +5584,7 @@ SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato
|
|||
pOperator->exec = doSessionWindowAgg;
|
||||
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||
|
||||
appendUpstream(pOperator, upstream);
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -5575,7 +5600,6 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRunti
|
|||
pOperator->operatorType = OP_MultiTableTimeInterval;
|
||||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->info = pInfo;
|
||||
|
@ -5584,6 +5608,7 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRunti
|
|||
pOperator->exec = doSTableIntervalAgg;
|
||||
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||
|
||||
appendUpstream(pOperator, upstream);
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -5600,7 +5625,6 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato
|
|||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->operatorType = OP_Groupby;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->info = pInfo;
|
||||
|
@ -5608,6 +5632,7 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato
|
|||
pOperator->exec = hashGroupbyAggregate;
|
||||
pOperator->cleanup = destroyGroupbyOperatorInfo;
|
||||
|
||||
appendUpstream(pOperator, upstream);
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -5637,8 +5662,6 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn
|
|||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->operatorType = OP_Fill;
|
||||
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->info = pInfo;
|
||||
|
@ -5647,6 +5670,7 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn
|
|||
pOperator->exec = doFill;
|
||||
pOperator->cleanup = destroySFillOperatorInfo;
|
||||
|
||||
appendUpstream(pOperator, upstream);
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -5685,11 +5709,12 @@ SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator
|
|||
pOperator->operatorType = OP_SLimit;
|
||||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->exec = doSLimit;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
pOperator->cleanup = destroySlimitOperatorInfo;
|
||||
|
||||
appendUpstream(pOperator, upstream);
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -5856,7 +5881,7 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
|
|||
pRes->info.rows = 0;
|
||||
SSDataBlock* pBlock = NULL;
|
||||
while(1) {
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
@ -5917,12 +5942,13 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
|
|||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->operatorType = OP_Distinct;
|
||||
pOperator->upstream = upstream;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
pOperator->exec = hashDistinct;
|
||||
pOperator->cleanup = destroyDistinctOperatorInfo;
|
||||
|
||||
appendUpstream(pOperator, upstream);
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -6469,7 +6495,7 @@ static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SCol
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// TODO tag length should be passed from client
|
||||
// TODO tag length should be passed from client, refactor
|
||||
int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo,
|
||||
SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg) {
|
||||
*pExprInfo = NULL;
|
||||
|
@ -6640,13 +6666,13 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t nu
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code) {
|
||||
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code) {
|
||||
if (pQueryMsg->numOfGroupCols == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// using group by tag columns
|
||||
SSqlGroupbyExpr *pGroupbyExpr = (SSqlGroupbyExpr *)calloc(1, sizeof(SSqlGroupbyExpr));
|
||||
SGroupbyExpr *pGroupbyExpr = (SGroupbyExpr *)calloc(1, sizeof(SGroupbyExpr));
|
||||
if (pGroupbyExpr == NULL) {
|
||||
*code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
|
@ -6664,8 +6690,7 @@ SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *
|
|||
return pGroupbyExpr;
|
||||
}
|
||||
|
||||
static int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols,
|
||||
SSingleColumnFilterInfo** pFilterInfo, uint64_t qId) {
|
||||
int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId) {
|
||||
*pFilterInfo = calloc(1, sizeof(SSingleColumnFilterInfo) * numOfFilterCols);
|
||||
if (pFilterInfo == NULL) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
|
@ -6722,7 +6747,7 @@ void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFil
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId) {
|
||||
int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId) {
|
||||
for (int32_t i = 0; i < pQueryAttr->numOfCols; ++i) {
|
||||
if (pQueryAttr->tableCols[i].flist.numOfFilters > 0) {
|
||||
pQueryAttr->numOfFilterCols++;
|
||||
|
@ -6807,7 +6832,7 @@ FORCE_INLINE bool checkQIdEqual(void *qHandle, uint64_t qId) {
|
|||
return ((SQInfo *)qHandle)->qId == qId;
|
||||
}
|
||||
|
||||
SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs,
|
||||
SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs,
|
||||
SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId,
|
||||
char* sql, uint64_t *qId) {
|
||||
int16_t numOfCols = pQueryMsg->numOfCols;
|
||||
|
@ -7110,7 +7135,7 @@ static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) {
|
|||
pTableqinfoGroupInfo->numOfTables = 0;
|
||||
}
|
||||
|
||||
static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) {
|
||||
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) {
|
||||
if (pExprInfo == NULL) {
|
||||
assert(numOfExpr == 0);
|
||||
return NULL;
|
||||
|
@ -7134,6 +7159,20 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols) {
|
||||
if (pColumnInfo != NULL) {
|
||||
assert(numOfCols >= 0);
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; i++) {
|
||||
freeColumnFilterInfo(pColumnInfo[i].flist.filterInfo, pColumnInfo[i].flist.numOfFilters);
|
||||
}
|
||||
|
||||
tfree(pColumnInfo);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void freeQInfo(SQInfo *pQInfo) {
|
||||
if (!isValidQInfo(pQInfo)) {
|
||||
return;
|
||||
|
@ -7318,13 +7357,7 @@ void freeQueryAttr(SQueryAttr* pQueryAttr) {
|
|||
tfree(pQueryAttr->tagColList);
|
||||
tfree(pQueryAttr->pFilterInfo);
|
||||
|
||||
if (pQueryAttr->tableCols != NULL) {
|
||||
for (int32_t i = 0; i < pQueryAttr->numOfCols; i++) {
|
||||
SColumnInfo* column = pQueryAttr->tableCols + i;
|
||||
freeColumnFilterInfo(column->flist.filterInfo, column->flist.numOfFilters);
|
||||
}
|
||||
tfree(pQueryAttr->tableCols);
|
||||
}
|
||||
pQueryAttr->tableCols = freeColumnInfo(pQueryAttr->tableCols, pQueryAttr->numOfCols);
|
||||
|
||||
if (pQueryAttr->pGroupbyExpr != NULL) {
|
||||
taosArrayDestroy(pQueryAttr->pGroupbyExpr->columnInfo);
|
||||
|
|
|
@ -363,10 +363,6 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3
|
|||
pFillInfo->rowSize = setTagColumnInfo(pFillInfo, pFillInfo->numOfCols, pFillInfo->alloc);
|
||||
assert(pFillInfo->rowSize > 0);
|
||||
|
||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
||||
pFillInfo->pData[i] = malloc(pFillInfo->pFillCol[i].col.bytes * pFillInfo->alloc);
|
||||
}
|
||||
|
||||
return pFillInfo;
|
||||
}
|
||||
|
||||
|
@ -392,10 +388,6 @@ void* taosDestroyFillInfo(SFillInfo* pFillInfo) {
|
|||
tfree(pFillInfo->pTags[i].tagVal);
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
||||
tfree(pFillInfo->pData[i]);
|
||||
}
|
||||
|
||||
tfree(pFillInfo->pTags);
|
||||
|
||||
tfree(pFillInfo->pData);
|
||||
|
@ -417,17 +409,6 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
|
|||
|
||||
pFillInfo->index = 0;
|
||||
pFillInfo->numOfRows = numOfRows;
|
||||
|
||||
// ensure the space
|
||||
if (pFillInfo->alloc < numOfRows) {
|
||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
||||
char* tmp = realloc(pFillInfo->pData[i], numOfRows*pFillInfo->pFillCol[i].col.bytes);
|
||||
assert(tmp != NULL); // todo handle error
|
||||
|
||||
memset(tmp, 0, numOfRows*pFillInfo->pFillCol[i].col.bytes);
|
||||
pFillInfo->pData[i] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) {
|
||||
|
@ -435,16 +416,7 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput)
|
|||
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
||||
|
||||
SColumnInfoData* pColData = taosArrayGet(pInput->pDataBlock, i);
|
||||
// pFillInfo->pData[i] = pColData->pData;
|
||||
if (pInput->info.rows > pFillInfo->alloc) {
|
||||
char* t = realloc(pFillInfo->pData[i], pColData->info.bytes * pInput->info.rows);
|
||||
assert(t != NULL);
|
||||
|
||||
pFillInfo->pData[i] = t;
|
||||
pFillInfo->alloc = pInput->info.rows;
|
||||
}
|
||||
|
||||
memcpy(pFillInfo->pData[i], pColData->pData, pColData->info.bytes * pInput->info.rows);
|
||||
pFillInfo->pData[i] = pColData->pData;
|
||||
|
||||
if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer
|
||||
SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex];
|
||||
|
@ -454,31 +426,6 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput)
|
|||
}
|
||||
}
|
||||
|
||||
void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* pInput) {
|
||||
assert(pFillInfo->numOfRows == pInput->num);
|
||||
|
||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
||||
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
||||
|
||||
const char* data = pInput->data + pCol->col.offset * pInput->num;
|
||||
if (pInput->num > pFillInfo->alloc) {
|
||||
char* t = realloc(pFillInfo->pData[i], (size_t)(pCol->col.bytes * pInput->num));
|
||||
assert(t != NULL);
|
||||
|
||||
pFillInfo->pData[i] = t;
|
||||
pFillInfo->alloc = (int32_t)pInput->num;
|
||||
}
|
||||
|
||||
memcpy(pFillInfo->pData[i], data, (size_t)(pCol->col.bytes * pInput->num));
|
||||
|
||||
if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer
|
||||
SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex];
|
||||
assert (pTag->col.colId == pCol->col.colId);
|
||||
memcpy(pTag->tagVal, data, pCol->col.bytes); // TODO not memcpy??
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool taosFillHasMoreResults(SFillInfo* pFillInfo) {
|
||||
int32_t remain = taosNumOfRemainRows(pFillInfo);
|
||||
if (remain > 0) {
|
||||
|
|
|
@ -1,44 +1,523 @@
|
|||
#include "os.h"
|
||||
#include "tsclient.h"
|
||||
#include "tschemautil.h"
|
||||
#include "qPlan.h"
|
||||
#include "qExecutor.h"
|
||||
#include "qUtil.h"
|
||||
#include "texpr.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
|
||||
#define QNODE_PROJECT 1
|
||||
#define QNODE_FILTER 2
|
||||
#define QNODE_RELATION 3
|
||||
#define QNODE_TAGSCAN 1
|
||||
#define QNODE_TABLESCAN 2
|
||||
#define QNODE_PROJECT 3
|
||||
#define QNODE_AGGREGATE 4
|
||||
#define QNODE_GROUPBY 5
|
||||
#define QNODE_LIMIT 6
|
||||
#define QNODE_JOIN 7
|
||||
#define QNODE_DIST 8
|
||||
#define QNODE_DISTINCT 8
|
||||
#define QNODE_SORT 9
|
||||
#define QNODE_UNIONALL 10
|
||||
#define QNODE_TIMEWINDOW 11
|
||||
#define QNODE_SESSIONWINDOW 12
|
||||
#define QNODE_FILL 13
|
||||
|
||||
typedef struct SQueryNode {
|
||||
int32_t type; // the type of logic node
|
||||
char *name; // the name of logic node
|
||||
typedef struct SFillEssInfo {
|
||||
int32_t fillType; // fill type
|
||||
int64_t *val; // fill value
|
||||
} SFillEssInfo;
|
||||
|
||||
SSchema *pSchema; // the schema of the input SSDatablock
|
||||
int32_t numOfCols; // number of input columns
|
||||
SExprInfo *pExpr; // the query functions or sql aggregations
|
||||
int32_t numOfOutput; // number of result columns, which is also the number of pExprs
|
||||
typedef struct SJoinCond {
|
||||
bool tagExists; // denote if tag condition exists or not
|
||||
SColumn *tagCond[2];
|
||||
SColumn *colCond[2];
|
||||
} SJoinCond;
|
||||
|
||||
// previous operator to generated result for current node to process
|
||||
// in case of join, multiple prev nodes exist.
|
||||
struct SQueryNode* prevNode;
|
||||
struct SQueryNode* nextNode;
|
||||
} SQueryNode;
|
||||
static SQueryNode* createQueryNode(int32_t type, const char* name, SQueryNode** prev,
|
||||
int32_t numOfPrev, SExprInfo** pExpr, int32_t numOfOutput, SQueryTableInfo* pTableInfo,
|
||||
void* pExtInfo) {
|
||||
SQueryNode* pNode = calloc(1, sizeof(SQueryNode));
|
||||
|
||||
pNode->info.type = type;
|
||||
pNode->info.name = strdup(name);
|
||||
|
||||
if (pTableInfo->id.uid != 0) { // it is a true table
|
||||
pNode->tableInfo.id = pTableInfo->id;
|
||||
pNode->tableInfo.tableName = strdup(pTableInfo->tableName);
|
||||
}
|
||||
|
||||
pNode->numOfOutput = numOfOutput;
|
||||
pNode->pExpr = calloc(numOfOutput, sizeof(SExprInfo));
|
||||
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||
tscExprAssign(&pNode->pExpr[i], pExpr[i]);
|
||||
}
|
||||
|
||||
pNode->pPrevNodes = taosArrayInit(4, POINTER_BYTES);
|
||||
for(int32_t i = 0; i < numOfPrev; ++i) {
|
||||
taosArrayPush(pNode->pPrevNodes, &prev[i]);
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case QNODE_TABLESCAN: {
|
||||
STimeWindow* window = calloc(1, sizeof(STimeWindow));
|
||||
memcpy(window, pExtInfo, sizeof(STimeWindow));
|
||||
pNode->pExtInfo = window;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_TIMEWINDOW: {
|
||||
SInterval* pInterval = calloc(1, sizeof(SInterval));
|
||||
pNode->pExtInfo = pInterval;
|
||||
memcpy(pInterval, pExtInfo, sizeof(SInterval));
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_GROUPBY: {
|
||||
SGroupbyExpr* p = (SGroupbyExpr*) pExtInfo;
|
||||
SGroupbyExpr* pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr));
|
||||
|
||||
pGroupbyExpr->tableIndex = p->tableIndex;
|
||||
pGroupbyExpr->orderType = p->orderType;
|
||||
pGroupbyExpr->orderIndex = p->orderIndex;
|
||||
pGroupbyExpr->numOfGroupCols = p->numOfGroupCols;
|
||||
pGroupbyExpr->columnInfo = taosArrayDup(p->columnInfo);
|
||||
pNode->pExtInfo = pGroupbyExpr;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_FILL: { // todo !!
|
||||
pNode->pExtInfo = pExtInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_LIMIT: {
|
||||
pNode->pExtInfo = calloc(1, sizeof(SLimitVal));
|
||||
memcpy(pNode->pExtInfo, pExtInfo, sizeof(SLimitVal));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryNode* doAddTableColumnNode(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SQueryTableInfo* info,
|
||||
SArray* pExprs, SArray* tableCols) {
|
||||
if (pQueryInfo->onlyTagQuery) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pExprs);
|
||||
SQueryNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info, NULL);
|
||||
|
||||
if (pQueryInfo->distinctTag) {
|
||||
pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, info, NULL);
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
STimeWindow* window = &pQueryInfo->window;
|
||||
SQueryNode* pNode = createQueryNode(QNODE_TABLESCAN, "TableScan", NULL, 0, NULL, 0,
|
||||
info, window);
|
||||
if (pQueryInfo->projectionQuery) {
|
||||
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExprs->pData, numOfOutput, info, NULL);
|
||||
} else {
|
||||
// table source column projection, generate the projection expr
|
||||
int32_t numOfCols = (int32_t) taosArrayGetSize(tableCols);
|
||||
SExprInfo** pExpr = calloc(numOfCols, POINTER_BYTES);
|
||||
SSchema* pSchema = pTableMetaInfo->pTableMeta->schema;
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(tableCols, i);
|
||||
|
||||
SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex};
|
||||
SExprInfo* p = tscExprCreate(pQueryInfo, TSDB_FUNC_PRJ, &index, pCol->info.type, pCol->info.bytes,
|
||||
pCol->info.colId, 0, TSDB_COL_NORMAL);
|
||||
strncpy(p->base.aliasName, pSchema[pCol->columnIndex].name, tListLen(p->base.aliasName));
|
||||
|
||||
pExpr[i] = p;
|
||||
}
|
||||
|
||||
pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExpr, numOfCols, info, NULL);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
destroyQueryFuncExpr(pExpr[i], 1);
|
||||
}
|
||||
tfree(pExpr);
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryNode* doCreateQueryPlanForOneTableImpl(SQueryInfo* pQueryInfo, SQueryNode* pNode, SQueryTableInfo* info,
|
||||
SArray* pExprs) {
|
||||
// check for aggregation
|
||||
if (pQueryInfo->interval.interval > 0) {
|
||||
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||
|
||||
pNode = createQueryNode(QNODE_TIMEWINDOW, "TimeWindowAgg", &pNode, 1, pExprs->pData, numOfOutput, info,
|
||||
&pQueryInfo->interval);
|
||||
} else if (pQueryInfo->groupbyColumn) {
|
||||
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, pExprs->pData, numOfOutput, info,
|
||||
&pQueryInfo->groupbyExpr);
|
||||
} else if (pQueryInfo->sessionWindow.gap > 0) {
|
||||
pNode = createQueryNode(QNODE_SESSIONWINDOW, "SessionWindowAgg", &pNode, 1, NULL, 0, info, NULL);
|
||||
} else if (pQueryInfo->simpleAgg) {
|
||||
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, pExprs->pData, numOfOutput, info, NULL);
|
||||
}
|
||||
|
||||
if (pQueryInfo->havingFieldNum > 0 || pQueryInfo->arithmeticOnAgg) {
|
||||
int32_t numOfExpr = (int32_t) taosArrayGetSize(pQueryInfo->exprList1);
|
||||
pNode =
|
||||
createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pQueryInfo->exprList1->pData, numOfExpr, info, NULL);
|
||||
}
|
||||
|
||||
if (pQueryInfo->fillType != TSDB_FILL_NONE) {
|
||||
SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo));
|
||||
pInfo->fillType = pQueryInfo->fillType;
|
||||
pInfo->val = calloc(pNode->numOfOutput, sizeof(int64_t));
|
||||
memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfOutput);
|
||||
|
||||
pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, NULL, 0, info, pInfo);
|
||||
}
|
||||
|
||||
|
||||
if (pQueryInfo->limit.limit != -1 || pQueryInfo->limit.offset != 0) {
|
||||
pNode = createQueryNode(QNODE_LIMIT, "Limit", &pNode, 1, NULL, 0, info, &pQueryInfo->limit);
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryNode* doCreateQueryPlanForOneTable(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs,
|
||||
SArray* tableCols) {
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
|
||||
SQueryTableInfo info = {.tableName = strdup(name), .id = pTableMetaInfo->pTableMeta->id,};
|
||||
|
||||
// handle the only tag query
|
||||
SQueryNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, pExprs, tableCols);
|
||||
if (pQueryInfo->onlyTagQuery) {
|
||||
tfree(info.tableName);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
SQueryNode* pNode1 = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pExprs);
|
||||
tfree(info.tableName);
|
||||
return pNode1;
|
||||
}
|
||||
|
||||
SArray* createQueryPlanImpl(SQueryInfo* pQueryInfo) {
|
||||
SArray* upstream = NULL;
|
||||
|
||||
if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // subquery in the from clause
|
||||
upstream = taosArrayInit(4, POINTER_BYTES);
|
||||
|
||||
size_t size = taosArrayGetSize(pQueryInfo->pUpstream);
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SQueryInfo* pq = taosArrayGet(pQueryInfo->pUpstream, i);
|
||||
SArray* p = createQueryPlanImpl(pq);
|
||||
taosArrayAddBatch(upstream, p->pData, (int32_t) taosArrayGetSize(p));
|
||||
}
|
||||
}
|
||||
|
||||
if (pQueryInfo->numOfTables > 1) { // it is a join query
|
||||
// 1. separate the select clause according to table
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
|
||||
for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[i];
|
||||
uint64_t uid = pTableMetaInfo->pTableMeta->id.uid;
|
||||
|
||||
SArray* exprList = taosArrayInit(4, POINTER_BYTES);
|
||||
if (tscExprCopy(exprList, pQueryInfo->exprList, uid, true) != 0) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// 2. create the query execution node
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
SQueryTableInfo info = {.tableName = strdup(name), .id = pTableMetaInfo->pTableMeta->id,};
|
||||
|
||||
// 3. get the required table column list
|
||||
SArray* tableColumnList = taosArrayInit(4, sizeof(SColumn));
|
||||
tscColumnListCopy(tableColumnList, pQueryInfo->colList, uid);
|
||||
|
||||
// 4. add the projection query node
|
||||
SQueryNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
}
|
||||
|
||||
// 3. add the join node here
|
||||
SQueryTableInfo info = {0};
|
||||
int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList);
|
||||
SQueryNode* pNode = createQueryNode(QNODE_JOIN, "Join", upstream->pData, pQueryInfo->numOfTables,
|
||||
pQueryInfo->exprList->pData, num, &info, NULL);
|
||||
|
||||
// 4. add the aggregation or projection execution node
|
||||
pNode = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pQueryInfo->exprList);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
} else { // only one table, normal query process
|
||||
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||
SQueryNode* pNode = doCreateQueryPlanForOneTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList, pQueryInfo->colList);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
}
|
||||
|
||||
return upstream;
|
||||
}
|
||||
|
||||
// TODO create the query plan
|
||||
SQueryNode* qCreateQueryPlan(SQueryInfo* pQueryInfo) {
|
||||
SArray* upstream = createQueryPlanImpl(pQueryInfo);
|
||||
assert(taosArrayGetSize(upstream) == 1);
|
||||
|
||||
SQueryNode* p = taosArrayGetP(upstream, 0);
|
||||
taosArrayDestroy(upstream);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static void doDestroyQueryNode(SQueryNode* pQueryNode) {
|
||||
tfree(pQueryNode->pExtInfo);
|
||||
tfree(pQueryNode->pSchema);
|
||||
tfree(pQueryNode->info.name);
|
||||
|
||||
tfree(pQueryNode->tableInfo.tableName);
|
||||
|
||||
pQueryNode->pExpr = destroyQueryFuncExpr(pQueryNode->pExpr, pQueryNode->numOfOutput);
|
||||
|
||||
if (pQueryNode->pPrevNodes != NULL) {
|
||||
int32_t size = (int32_t) taosArrayGetSize(pQueryNode->pPrevNodes);
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SQueryNode* p = taosArrayGetP(pQueryNode->pPrevNodes, i);
|
||||
doDestroyQueryNode(p);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pQueryNode->pPrevNodes);
|
||||
}
|
||||
|
||||
tfree(pQueryNode);
|
||||
}
|
||||
|
||||
void* qDestroyQueryPlan(SQueryNode* pQueryNode) {
|
||||
if (pQueryNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* queryPlanToString() {
|
||||
doDestroyQueryNode(pQueryNode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool hasAliasName(SExprInfo* pExpr) {
|
||||
assert(pExpr != NULL);
|
||||
return strncmp(pExpr->base.token, pExpr->base.aliasName, tListLen(pExpr->base.aliasName)) != 0;
|
||||
}
|
||||
|
||||
static int32_t doPrintPlan(char* buf, SQueryNode* pQueryNode, int32_t level, int32_t totalLen) {
|
||||
if (level > 0) {
|
||||
sprintf(buf + totalLen, "%*c", level, ' ');
|
||||
totalLen += level;
|
||||
}
|
||||
|
||||
int32_t len1 = sprintf(buf + totalLen, "%s(", pQueryNode->info.name);
|
||||
int32_t len = len1 + totalLen;
|
||||
|
||||
switch(pQueryNode->info.type) {
|
||||
case QNODE_TABLESCAN: {
|
||||
STimeWindow* win = (STimeWindow*)pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len, "%s #0x%" PRIx64 ") time_range: %" PRId64 " - %" PRId64 "\n",
|
||||
pQueryNode->tableInfo.tableName, pQueryNode->tableInfo.id.uid, win->skey, win->ekey);
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_PROJECT: {
|
||||
len1 = sprintf(buf + len, "cols: ");
|
||||
len += len1;
|
||||
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SSqlExpr* p = &pQueryNode->pExpr[i].base;
|
||||
len1 = sprintf(buf + len, "[%s #%d]", p->aliasName, p->resColId);
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len, ", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len, ")");
|
||||
len += len1;
|
||||
|
||||
//todo print filter info
|
||||
len1 = sprintf(buf + len, " filters:(nil)\n");
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_AGGREGATE: {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SSqlExpr* pExpr = &pQueryNode->pExpr[i].base;
|
||||
if (hasAliasName(&pQueryNode->pExpr[i])) {
|
||||
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName);
|
||||
} else {
|
||||
len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||
}
|
||||
|
||||
len += len1;
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len, ", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len, ")\n");
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_TIMEWINDOW: {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SSqlExpr* pExpr = &pQueryNode->pExpr[i].base;
|
||||
if (hasAliasName(&pQueryNode->pExpr[i])) {
|
||||
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName);
|
||||
} else {
|
||||
len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||
}
|
||||
|
||||
len += len1;
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len,") ");
|
||||
len += len1;
|
||||
|
||||
SInterval* pInterval = pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len, "interval:%" PRId64 "(%c), sliding:%" PRId64 "(%c), offset:%" PRId64 "\n",
|
||||
pInterval->interval, pInterval->intervalUnit, pInterval->sliding, pInterval->slidingUnit,
|
||||
pInterval->offset);
|
||||
len += len1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_GROUPBY: { // todo hide the invisible column
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SSqlExpr* pExpr = &pQueryNode->pExpr[i].base;
|
||||
|
||||
if (hasAliasName(&pQueryNode->pExpr[i])) {
|
||||
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName);
|
||||
} else {
|
||||
len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||
}
|
||||
|
||||
len += len1;
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
SGroupbyExpr* pGroupbyExpr = pQueryNode->pExtInfo;
|
||||
SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, 0);
|
||||
|
||||
len1 = sprintf(buf + len,") groupby_col: [%s #%d]\n", pIndex->name, pIndex->colId);
|
||||
len += len1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_FILL: {
|
||||
SFillEssInfo* pEssInfo = pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len,"%d", pEssInfo->fillType);
|
||||
len += len1;
|
||||
|
||||
if (pEssInfo->fillType == TSDB_FILL_SET_VALUE) {
|
||||
len1 = sprintf(buf + len,", val:");
|
||||
len += len1;
|
||||
|
||||
// todo get the correct fill data type
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
len1 = sprintf(buf + len,"%"PRId64, pEssInfo->val[i]);
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len,")\n");
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_LIMIT: {
|
||||
SLimitVal* pVal = pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len,"limit: %"PRId64", offset: %"PRId64")\n", pVal->limit, pVal->offset);
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_DISTINCT:
|
||||
case QNODE_TAGSCAN: {
|
||||
len1 = sprintf(buf + len,"cols: ");
|
||||
len += len1;
|
||||
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SSqlExpr* p = &pQueryNode->pExpr[i].base;
|
||||
len1 = sprintf(buf + len,"[%s #%d]", p->aliasName, p->resColId);
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len,")\n");
|
||||
len += len1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_JOIN: {
|
||||
// print join condition
|
||||
len1 = sprintf(buf + len, ")\n");
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int32_t queryPlanToStringImpl(char* buf, SQueryNode* pQueryNode, int32_t level, int32_t totalLen) {
|
||||
int32_t len = doPrintPlan(buf, pQueryNode, level, totalLen);
|
||||
|
||||
for(int32_t i = 0; i < taosArrayGetSize(pQueryNode->pPrevNodes); ++i) {
|
||||
SQueryNode* p1 = taosArrayGetP(pQueryNode->pPrevNodes, i);
|
||||
int32_t len1 = queryPlanToStringImpl(buf, p1, level + 1, len);
|
||||
len = len1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
char* queryPlanToString(SQueryNode* pQueryNode) {
|
||||
assert(pQueryNode);
|
||||
|
||||
char* buf = calloc(1, 4096);
|
||||
|
||||
int32_t len = sprintf(buf, "===== logic plan =====\n");
|
||||
queryPlanToStringImpl(buf, pQueryNode, 0, len);
|
||||
return buf;
|
||||
}
|
||||
|
||||
SQueryNode* queryPlanFromString() {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -136,9 +615,14 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
|
|||
taosArrayPush(plan, &op);
|
||||
}
|
||||
} else { // diff/add/multiply/subtract/division
|
||||
if (pQueryAttr->numOfFilterCols > 0 && pQueryAttr->vgId == 0) { // todo refactor
|
||||
op = OP_Filter;
|
||||
taosArrayPush(plan, &op);
|
||||
} else {
|
||||
op = OP_Arithmetic;
|
||||
taosArrayPush(plan, &op);
|
||||
}
|
||||
}
|
||||
|
||||
if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0) {
|
||||
op = OP_Limit;
|
||||
|
|
|
@ -229,7 +229,6 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) {
|
|||
pExpr->flags &= ~(1 << EXPR_FLAG_TS_ERROR);
|
||||
}
|
||||
|
||||
|
||||
switch (optrType) {
|
||||
case TK_PLUS: {
|
||||
pExpr->value.i64 = pLeft->value.i64 + pRight->value.i64;
|
||||
|
@ -325,7 +324,6 @@ static FORCE_INLINE int32_t tStrTokenCompare(SStrToken* left, SStrToken* right)
|
|||
return (left->type == right->type && left->n == right->n && strncasecmp(left->z, right->z, left->n) == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) {
|
||||
if ((left == NULL && right) || (left && right == NULL)) {
|
||||
return 1;
|
||||
|
@ -389,8 +387,6 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
tSqlExpr *tSqlExprClone(tSqlExpr *pSrc) {
|
||||
tSqlExpr *pExpr = calloc(1, sizeof(tSqlExpr));
|
||||
|
||||
|
@ -536,11 +532,11 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int
|
|||
SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, SStrToken* pAlias) {
|
||||
if (pRelationInfo == NULL) {
|
||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(STableNamePair));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair));
|
||||
}
|
||||
|
||||
pRelationInfo->type = SQL_NODE_FROM_TABLELIST;
|
||||
STableNamePair p = {.name = *pName};
|
||||
SRelElementPair p = {.tableName = *pName};
|
||||
if (pAlias != NULL) {
|
||||
p.aliasName = *pAlias;
|
||||
} else {
|
||||
|
@ -551,18 +547,6 @@ SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName,
|
|||
return pRelationInfo;
|
||||
}
|
||||
|
||||
SRelationInfo* setSubquery(SRelationInfo* pRelationInfo, SArray* pList) {
|
||||
if (pRelationInfo == NULL) {
|
||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||
pRelationInfo->list = taosArrayInit(4, POINTER_BYTES);
|
||||
}
|
||||
|
||||
pRelationInfo->type = SQL_NODE_FROM_SUBQUERY;
|
||||
taosArrayPush(pRelationInfo->list, &pList);
|
||||
|
||||
return pRelationInfo;
|
||||
}
|
||||
|
||||
void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
||||
if (pRelationInfo == NULL) {
|
||||
return NULL;
|
||||
|
@ -573,7 +557,7 @@ void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
|||
} else {
|
||||
size_t size = taosArrayGetSize(pRelationInfo->list);
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SArray* pa = taosArrayGetP(pRelationInfo->list, 0);
|
||||
SArray* pa = taosArrayGetP(pRelationInfo->list, i);
|
||||
destroyAllSqlNode(pa);
|
||||
}
|
||||
taosArrayDestroy(pRelationInfo->list);
|
||||
|
@ -583,6 +567,24 @@ void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SRelationInfo* addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias) {
|
||||
if (pRelationInfo == NULL) {
|
||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair));
|
||||
}
|
||||
|
||||
pRelationInfo->type = SQL_NODE_FROM_SUBQUERY;
|
||||
|
||||
SRelElementPair p = {.pSubquery = pSub};
|
||||
if (pAlias != NULL) {
|
||||
p.aliasName = *pAlias;
|
||||
} else {
|
||||
TPARSER_SET_NONE_TOKEN(p.aliasName);
|
||||
}
|
||||
|
||||
taosArrayPush(pRelationInfo->list, &p);
|
||||
return pRelationInfo;
|
||||
}
|
||||
|
||||
void tSetDbName(SStrToken *pCpxName, SStrToken *pDb) {
|
||||
pCpxName->type = pDb->type;
|
||||
|
@ -724,9 +726,9 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
|||
* extract the select info out of sql string
|
||||
*/
|
||||
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
||||
SSessionWindowVal *pSession, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit,
|
||||
SLimitVal *psLimit, tSqlExpr *pHaving) {
|
||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *pSession,
|
||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *psLimit,
|
||||
tSqlExpr *pHaving) {
|
||||
assert(pSelNodeList != NULL);
|
||||
|
||||
SSqlNode *pSqlNode = calloc(1, sizeof(SSqlNode));
|
||||
|
|
1873
src/query/src/sql.c
1873
src/query/src/sql.c
File diff suppressed because it is too large
Load Diff
|
@ -99,47 +99,47 @@ TEST(testCase, db_table_name) {
|
|||
EXPECT_EQ(testValidateName(t4), TSDB_CODE_SUCCESS);
|
||||
|
||||
char t5[] = "table.'def'";
|
||||
EXPECT_EQ(testValidateName(t5), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t5), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t6[] = "'table'.'def'";
|
||||
EXPECT_EQ(testValidateName(t6), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t6), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t7[] = "'_ab1234'.'def'";
|
||||
EXPECT_EQ(testValidateName(t7), TSDB_CODE_SUCCESS);
|
||||
printf("%s\n", t7);
|
||||
|
||||
char t8[] = "'_ab&^%1234'.'def'";
|
||||
EXPECT_EQ(testValidateName(t8), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t8), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t9[] = "'_123'.'gtest中文'";
|
||||
EXPECT_EQ(testValidateName(t9), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t9), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t10[] = "abc.'gtest中文'";
|
||||
EXPECT_EQ(testValidateName(t10), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t10), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t10_1[] = "abc.'中文gtest'";
|
||||
EXPECT_EQ(testValidateName(t10_1), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t10_1), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t11[] = "'192.168.0.1'.abc";
|
||||
EXPECT_EQ(testValidateName(t11), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t11), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t12[] = "192.168.0.1.abc";
|
||||
EXPECT_EQ(testValidateName(t12), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t12), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t13[] = "abc.";
|
||||
EXPECT_EQ(testValidateName(t13), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t13), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t14[] = ".abc";
|
||||
EXPECT_EQ(testValidateName(t14), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t14), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t15[] = ".'abc'";
|
||||
EXPECT_EQ(testValidateName(t15), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t15), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t16[] = ".abc'";
|
||||
EXPECT_EQ(testValidateName(t16), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t16), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t17[] = "123a.\"abc\"";
|
||||
EXPECT_EQ(testValidateName(t17), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t17), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
printf("%s\n", t17);
|
||||
|
||||
char t18[] = "a.\"abc\"";
|
||||
|
@ -147,13 +147,13 @@ TEST(testCase, db_table_name) {
|
|||
printf("%s\n", t18);
|
||||
|
||||
char t19[] = "'_ab1234'.'def'.'ab123'";
|
||||
EXPECT_EQ(testValidateName(t19), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t19), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t20[] = "'_ab1234*&^'";
|
||||
EXPECT_EQ(testValidateName(t20), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t20), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t21[] = "'1234_abc'";
|
||||
EXPECT_EQ(testValidateName(t21), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t21), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
|
||||
// =======Containing capital letters=================
|
||||
|
@ -167,10 +167,10 @@ TEST(testCase, db_table_name) {
|
|||
EXPECT_EQ(testValidateName(t32), TSDB_CODE_SUCCESS);
|
||||
|
||||
char t33[] = "'ABC.def";
|
||||
EXPECT_EQ(testValidateName(t33), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t33), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t33_0[] = "abc.DEF'";
|
||||
EXPECT_EQ(testValidateName(t33_0), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t33_0), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t34[] = "'ABC.def'";
|
||||
//int32_t tmp0 = testValidateName(t34);
|
||||
|
@ -193,136 +193,136 @@ TEST(testCase, db_table_name) {
|
|||
|
||||
// do not use key words
|
||||
char t39[] = "table.'DEF'";
|
||||
EXPECT_EQ(testValidateName(t39), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t39), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t40[] = "'table'.'DEF'";
|
||||
EXPECT_EQ(testValidateName(t40), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t40), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t41[] = "'_abXYZ1234'.'deFF'";
|
||||
EXPECT_EQ(testValidateName(t41), TSDB_CODE_SUCCESS);
|
||||
|
||||
char t42[] = "'_abDEF&^%1234'.'DIef'";
|
||||
EXPECT_EQ(testValidateName(t42), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t42), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t43[] = "'_123'.'Gtest中文'";
|
||||
EXPECT_EQ(testValidateName(t43), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t43), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t44[] = "'aABC'.'Gtest中文'";
|
||||
EXPECT_EQ(testValidateName(t44), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t44), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t45[] = "'ABC'.";
|
||||
EXPECT_EQ(testValidateName(t45), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t45), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t46[] = ".'ABC'";
|
||||
EXPECT_EQ(testValidateName(t46), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t46), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t47[] = "a.\"aTWc\"";
|
||||
EXPECT_EQ(testValidateName(t47), TSDB_CODE_SUCCESS);
|
||||
|
||||
// ================has space =================
|
||||
char t60[] = " ABC ";
|
||||
EXPECT_EQ(testValidateName(t60), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t60), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t60_1[] = " ABC ";
|
||||
EXPECT_EQ(testValidateName(t60_1), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t60_1), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t61[] = "' ABC '";
|
||||
EXPECT_EQ(testValidateName(t61), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t61), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t61_1[] = "' ABC '";
|
||||
EXPECT_EQ(testValidateName(t61_1), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t61_1), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t62[] = " ABC . def ";
|
||||
EXPECT_EQ(testValidateName(t62), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t62), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t63[] = "' ABC . def ";
|
||||
EXPECT_EQ(testValidateName(t63), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t63), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t63_0[] = " abc . DEF ' ";
|
||||
EXPECT_EQ(testValidateName(t63_0), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t63_0), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t64[] = " ' ABC . def ' ";
|
||||
//int32_t tmp1 = testValidateName(t64);
|
||||
EXPECT_EQ(testValidateName(t64), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t64), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t65[] = " ' ABC '. def ";
|
||||
EXPECT_EQ(testValidateName(t65), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t65), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t66[] = "' ABC '.' DEF '";
|
||||
EXPECT_EQ(testValidateName(t66), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t66), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t67[] = "abc . ' DEF '";
|
||||
EXPECT_EQ(testValidateName(t67), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t67), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t68[] = "' abc '.' DEF '";
|
||||
EXPECT_EQ(testValidateName(t68), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t68), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
// do not use key words
|
||||
char t69[] = "table.'DEF'";
|
||||
EXPECT_EQ(testValidateName(t69), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t69), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t70[] = "'table'.'DEF'";
|
||||
EXPECT_EQ(testValidateName(t70), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t70), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t71[] = "'_abXYZ1234 '.' deFF '";
|
||||
EXPECT_EQ(testValidateName(t71), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t71), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t72[] = "'_abDEF&^%1234'.' DIef'";
|
||||
EXPECT_EQ(testValidateName(t72), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t72), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t73[] = "'_123'.' Gtest中文'";
|
||||
EXPECT_EQ(testValidateName(t73), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t73), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t74[] = "' aABC'.'Gtest中文'";
|
||||
EXPECT_EQ(testValidateName(t74), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t74), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t75[] = "' ABC '.";
|
||||
EXPECT_EQ(testValidateName(t75), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t75), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t76[] = ".' ABC'";
|
||||
EXPECT_EQ(testValidateName(t76), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t76), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t77[] = " a . \"aTWc\" ";
|
||||
EXPECT_EQ(testValidateName(t77), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t77), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t78[] = " a.\"aTWc \"";
|
||||
EXPECT_EQ(testValidateName(t78), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t78), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
|
||||
// ===============muti string by space ===================
|
||||
// There's no such case.
|
||||
//char t160[] = "A BC";
|
||||
//EXPECT_EQ(testValidateName(t160), TSDB_CODE_TSC_INVALID_SQL);
|
||||
//EXPECT_EQ(testValidateName(t160), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
//printf("end:%s\n", t160);
|
||||
|
||||
// There's no such case.
|
||||
//char t161[] = "' A BC '";
|
||||
//EXPECT_EQ(testValidateName(t161), TSDB_CODE_TSC_INVALID_SQL);
|
||||
//EXPECT_EQ(testValidateName(t161), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t162[] = " AB C . de f ";
|
||||
EXPECT_EQ(testValidateName(t162), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t162), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t163[] = "' AB C . de f ";
|
||||
EXPECT_EQ(testValidateName(t163), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t163), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t163_0[] = " ab c . DE F ' ";
|
||||
EXPECT_EQ(testValidateName(t163_0), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t163_0), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t164[] = " ' AB C . de f ' ";
|
||||
//int32_t tmp2 = testValidateName(t164);
|
||||
EXPECT_EQ(testValidateName(t164), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t164), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t165[] = " ' A BC '. de f ";
|
||||
EXPECT_EQ(testValidateName(t165), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t165), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t166[] = "' AB C '.' DE F '";
|
||||
EXPECT_EQ(testValidateName(t166), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t166), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t167[] = "ab c . ' D EF '";
|
||||
EXPECT_EQ(testValidateName(t167), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t167), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
char t168[] = "' a bc '.' DE F '";
|
||||
EXPECT_EQ(testValidateName(t168), TSDB_CODE_TSC_INVALID_SQL);
|
||||
EXPECT_EQ(testValidateName(t168), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1152,7 +1152,7 @@ static int tsdbCommitAddBlock(SCommitH *pCommith, const SBlock *pSupBlock, const
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (pSubBlocks && taosArrayPushBatch(pCommith->aSubBlk, pSubBlocks, nSubBlocks) == NULL) {
|
||||
if (pSubBlocks && taosArrayAddBatch(pCommith->aSubBlk, pSubBlocks, nSubBlocks) == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -148,6 +148,7 @@ int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj);
|
|||
size_t taosHashGetMemSize(const SHashObj *pHashObj);
|
||||
|
||||
void *taosHashIterate(SHashObj *pHashObj, void *p);
|
||||
|
||||
void taosHashCancelIterate(SHashObj *pHashObj, void *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -50,7 +50,15 @@ void* taosArrayInit(size_t size, size_t elemSize);
|
|||
* @param nEles
|
||||
* @return
|
||||
*/
|
||||
void *taosArrayPushBatch(SArray *pArray, const void *pData, int nEles);
|
||||
void *taosArrayAddBatch(SArray *pArray, const void *pData, int nEles);
|
||||
|
||||
/**
|
||||
* add all element from the source array list into the destination
|
||||
* @param pArray
|
||||
* @param pInput
|
||||
* @return
|
||||
*/
|
||||
void* taosArrayAddAll(SArray* pArray, const SArray* pInput);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -59,7 +67,7 @@ void *taosArrayPushBatch(SArray *pArray, const void *pData, int nEles);
|
|||
* @return
|
||||
*/
|
||||
static FORCE_INLINE void* taosArrayPush(SArray* pArray, const void* pData) {
|
||||
return taosArrayPushBatch(pArray, pData, 1);
|
||||
return taosArrayAddBatch(pArray, pData, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,8 +37,6 @@ typedef struct SStrToken {
|
|||
char *z;
|
||||
} SStrToken;
|
||||
|
||||
extern const char escapeChar[];
|
||||
|
||||
/**
|
||||
* check if it is a number or not
|
||||
* @param pToken
|
||||
|
@ -47,8 +45,6 @@ extern const char escapeChar[];
|
|||
#define isNumber(tk) \
|
||||
((tk)->type == TK_INTEGER || (tk)->type == TK_FLOAT || (tk)->type == TK_HEX || (tk)->type == TK_BIN)
|
||||
|
||||
#define GET_ESCAPE_CHAR(c) (escapeChar[(uint8_t)(c)])
|
||||
|
||||
/**
|
||||
* tokenizer for sql string
|
||||
* @param z
|
||||
|
|
|
@ -56,7 +56,7 @@ static int32_t taosArrayResize(SArray* pArray) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void* taosArrayPushBatch(SArray* pArray, const void* pData, int nEles) {
|
||||
void* taosArrayAddBatch(SArray* pArray, const void* pData, int nEles) {
|
||||
if (pArray == NULL || pData == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -82,6 +82,10 @@ void* taosArrayPushBatch(SArray* pArray, const void* pData, int nEles) {
|
|||
return dst;
|
||||
}
|
||||
|
||||
void* taosArrayAddAll(SArray* pArray, const SArray* pInput) {
|
||||
return taosArrayAddBatch(pArray, pInput->pData, (int32_t) taosArrayGetSize(pInput));
|
||||
}
|
||||
|
||||
void* taosArrayPop(SArray* pArray) {
|
||||
assert( pArray != NULL );
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_REF_ALREADY_EXIST, "Ref is already there"
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_REF_NOT_EXIST, "Ref is not there")
|
||||
|
||||
//client
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_SQL, "Invalid SQL statement")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_OPERATION, "Invalid operation")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_QHANDLE, "Invalid qhandle")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TIME_STAMP, "Invalid combination of client/service time")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_VALUE, "Invalid value in client")
|
||||
|
|
|
@ -233,18 +233,6 @@ static const char isIdChar[] = {
|
|||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
|
||||
};
|
||||
|
||||
const char escapeChar[] = {
|
||||
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 0x */
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* 1x */
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, /* 2x */
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, /* 3x */
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,/* 4x */
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,/* 5x */
|
||||
0x60, 0x07, 0x08, 0x63, 0x64, 0x65, 0x0C, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x0A, 0x6F,/* 6x */
|
||||
0x70, 0x71, 0x0D, 0x73, 0x09, 0x75, 0x0B, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,/* 7x */
|
||||
};
|
||||
|
||||
static void* keywordHashTable = NULL;
|
||||
|
||||
static void doInitKeywordsTable(void) {
|
||||
|
@ -594,7 +582,6 @@ SStrToken tscReplaceStrToken(char **str, SStrToken *token, const char* newToken)
|
|||
return ntoken;
|
||||
}
|
||||
|
||||
|
||||
SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) {
|
||||
SStrToken t0 = {0};
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) {
|
|||
|
||||
// kill current query and free corresponding resources.
|
||||
if (pRetrieve->free == 1) {
|
||||
vWarn("vgId:%d, QInfo:%"PRIu64 "-%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, pRetrieve->qId, *handle);
|
||||
vWarn("vgId:%d, QInfo:%"PRIx64 "-%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, pRetrieve->qId, *handle);
|
||||
qKillQuery(*handle);
|
||||
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true);
|
||||
|
||||
|
|
|
@ -430,6 +430,8 @@ static int32_t walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp, ch
|
|||
pWal->vgId, fileId, pHead->version, pWal->version, pHead->len, offset);
|
||||
|
||||
pWal->version = pHead->version;
|
||||
|
||||
//wInfo("writeFp: %ld", offset);
|
||||
(*writeFp)(pVnode, pHead, TAOS_QTYPE_WAL, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ IF (TD_LINUX)
|
|||
AUX_SOURCE_DIRECTORY(. SRC)
|
||||
ADD_EXECUTABLE(demo apitest.c)
|
||||
TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread )
|
||||
ADD_EXECUTABLE(subscribe subscribe.c)
|
||||
TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread )
|
||||
ADD_EXECUTABLE(epoll epoll.c)
|
||||
TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread )
|
||||
ENDIF ()
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <taos.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static void prepare_data(TAOS* taos) {
|
||||
TAOS_RES *result;
|
||||
result = taos_query(taos, "drop database if exists test;");
|
||||
|
@ -69,7 +68,6 @@ static void prepare_data(TAOS* taos) {
|
|||
usleep(1000000);
|
||||
}
|
||||
|
||||
|
||||
static int print_result(TAOS_RES* res, int blockFetch) {
|
||||
TAOS_ROW row = NULL;
|
||||
int num_fields = taos_num_fields(res);
|
||||
|
@ -99,7 +97,6 @@ static int print_result(TAOS_RES* res, int blockFetch) {
|
|||
return nRows;
|
||||
}
|
||||
|
||||
|
||||
static void check_row_count(int line, TAOS_RES* res, int expected) {
|
||||
int actual = print_result(res, expected % 2);
|
||||
if (actual != expected) {
|
||||
|
@ -109,7 +106,6 @@ static void check_row_count(int line, TAOS_RES* res, int expected) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void verify_query(TAOS* taos) {
|
||||
prepare_data(taos);
|
||||
|
||||
|
@ -153,7 +149,6 @@ static void verify_query(TAOS* taos) {
|
|||
taos_free_result(res);
|
||||
}
|
||||
|
||||
|
||||
void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
|
||||
int rows = print_result(res, *(int*)param);
|
||||
printf("%d rows consumed in subscribe_callback\n", rows);
|
||||
|
@ -235,10 +230,10 @@ static void verify_subscribe(TAOS* taos) {
|
|||
taos_unsubscribe(tsub, 0);
|
||||
}
|
||||
|
||||
|
||||
void verify_prepare(TAOS* taos) {
|
||||
TAOS_RES* result = taos_query(taos, "drop database if exists test;");
|
||||
taos_free_result(result);
|
||||
|
||||
usleep(100000);
|
||||
result = taos_query(taos, "create database test;");
|
||||
|
||||
|
@ -248,6 +243,7 @@ void verify_prepare(TAOS* taos) {
|
|||
taos_free_result(result);
|
||||
return;
|
||||
}
|
||||
|
||||
taos_free_result(result);
|
||||
|
||||
usleep(100000);
|
||||
|
@ -369,6 +365,7 @@ void verify_prepare(TAOS* taos) {
|
|||
taos_stmt_add_batch(stmt);
|
||||
}
|
||||
if (taos_stmt_execute(stmt) != 0) {
|
||||
taos_stmt_close(stmt);
|
||||
printf("\033[31mfailed to execute insert statement.\033[0m\n");
|
||||
return;
|
||||
}
|
||||
|
@ -381,6 +378,7 @@ void verify_prepare(TAOS* taos) {
|
|||
v.v2 = 15;
|
||||
taos_stmt_bind_param(stmt, params + 2);
|
||||
if (taos_stmt_execute(stmt) != 0) {
|
||||
taos_stmt_close(stmt);
|
||||
printf("\033[31mfailed to execute select statement.\033[0m\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -17497,3 +17497,24 @@
|
|||
obj:/usr/bin/python3.8
|
||||
fun:PyVectorcall_Call
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:__libc_alloc_buffer_allocate
|
||||
fun:alloc_buffer_allocate
|
||||
fun:__resolv_conf_allocate
|
||||
fun:__resolv_conf_load
|
||||
fun:__resolv_conf_get_current
|
||||
fun:__res_vinit
|
||||
fun:maybe_init
|
||||
fun:context_get
|
||||
fun:context_get
|
||||
fun:__resolv_context_get
|
||||
fun:gaih_inet.constprop.0
|
||||
fun:getaddrinfo
|
||||
fun:taosGetFqdn
|
||||
fun:taosCheckGlobalCfg
|
||||
fun:taos_init_imp
|
||||
}
|
|
@ -38,6 +38,8 @@ python3 ./test.py -f table/boundary.py
|
|||
python3 ./test.py -f table/create.py
|
||||
python3 ./test.py -f table/del_stable.py
|
||||
|
||||
#stable
|
||||
python3 ./test.py -f stable/insert.py
|
||||
|
||||
# tag
|
||||
python3 ./test.py -f tag_lite/filter.py
|
||||
|
|
|
@ -72,6 +72,9 @@ class TDTestCase:
|
|||
tdSql.query("describe db.stb")
|
||||
tdSql.checkRows(3)
|
||||
|
||||
tdSql.error("drop stable if exists db.dev_01")
|
||||
tdSql.error("drop stable if exists db.dev_02")
|
||||
|
||||
tdSql.execute("alter stable db.stb add tag t1 int")
|
||||
tdSql.query("describe db.stb")
|
||||
tdSql.checkRows(4)
|
||||
|
@ -80,6 +83,13 @@ class TDTestCase:
|
|||
tdSql.query("show stables")
|
||||
tdSql.checkRows(1)
|
||||
|
||||
tdSql.error("drop stable if exists db.dev_001")
|
||||
tdSql.error("drop stable if exists db.dev_002")
|
||||
|
||||
for i in range(10):
|
||||
tdSql.execute("drop stable if exists db.stb")
|
||||
tdSql.query("show stables")
|
||||
tdSql.checkRows(1)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,10 +34,20 @@ if $rows != 0 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
|
||||
sql create stable stb (ts timestamp, c1 int, c2 binary(10), c3 nchar(10)) tags(id int)
|
||||
sql create table tb1 using stb tags(1)
|
||||
sql insert into tb1 values (now, 1, "1", "1")
|
||||
sql alter table stb alter column length c2 20;
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
##### ILLEGAL OPERATIONS
|
||||
|
||||
# try dropping columns that are defined in metric
|
||||
sql_error alter table tb alter column length c1 10;
|
||||
sql_error alter table tb1 alter column length c2 10;
|
||||
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
system sh/stop_dnodes.sh
|
||||
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
|
|
|
@ -809,3 +809,5 @@ endi
|
|||
if $data00 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
print ====================> TODO stddev + normal column filter
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
system sh/stop_dnodes.sh
|
||||
|
||||
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/cfg.sh -n dnode1 -c walLevel -v 1
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
system sh/stop_dnodes.sh
|
||||
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/cfg.sh -n dnode1 -c walLevel -v 1
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
|
||||
sleep 100
|
||||
sql connect
|
||||
|
||||
print ======================== dnode1 start
|
||||
|
||||
$dbPrefix = nest_query
|
||||
$tbPrefix = nest_tb
|
||||
$mtPrefix = nest_mt
|
||||
$tbNum = 10
|
||||
$rowNum = 10000
|
||||
$totalNum = $tbNum * $rowNum
|
||||
|
||||
print =============== nestquery.sim
|
||||
|
||||
$i = 0
|
||||
$db = $dbPrefix . $i
|
||||
$mt = $mtPrefix . $i
|
||||
|
||||
sql drop database if exists $db
|
||||
sql create database if not exists $db
|
||||
|
||||
sql use $db
|
||||
sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int)
|
||||
|
||||
$half = $tbNum / 2
|
||||
|
||||
$i = 0
|
||||
while $i < $half
|
||||
$tb = $tbPrefix . $i
|
||||
|
||||
$nextSuffix = $i + $half
|
||||
$tb1 = $tbPrefix . $nextSuffix
|
||||
|
||||
sql create table $tb using $mt tags( $i )
|
||||
sql create table $tb1 using $mt tags( $nextSuffix )
|
||||
|
||||
$x = 0
|
||||
while $x < $rowNum
|
||||
$y = $x * 60000
|
||||
$ms = 1600099200000 + $y
|
||||
$c = $x / 100
|
||||
$c = $c * 100
|
||||
$c = $x - $c
|
||||
$binary = 'binary . $c
|
||||
$binary = $binary . '
|
||||
$nchar = 'nchar . $c
|
||||
$nchar = $nchar . '
|
||||
sql insert into $tb values ($ms , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $tb1 values ($ms , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar )
|
||||
$x = $x + 1
|
||||
endw
|
||||
|
||||
$i = $i + 1
|
||||
endw
|
||||
|
||||
sleep 100
|
||||
|
||||
$i = 1
|
||||
$tb = $tbPrefix . $i
|
||||
|
||||
print ==============> simple nest query test
|
||||
sql select count(*) from (select count(*) from nest_mt0)
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select count(*) from (select count(*) from nest_mt0 group by tbname)
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select count(*) from (select count(*) from nest_mt0 interval(10h) group by tbname)
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 170 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select sum(a) from (select count(*) a from nest_mt0 interval(10h) group by tbname)
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 100000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
print =================> alias name test
|
||||
sql select ts from (select count(*) a from nest_tb0 interval(1h))
|
||||
if $rows != 167 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != @20-09-15 00:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select count(a) from (select count(*) a from nest_tb0 interval(1h))
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 167 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
print ================>master query + filter
|
||||
sql select t.* from (select count(*) a from nest_tb0 interval(10h)) t where t.a <= 520;
|
||||
if $rows != 2 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
print ===================> nest query interval
|
||||
|
||||
|
||||
|
||||
print ===================> complex query
|
||||
|
||||
|
||||
|
||||
print ===================> group by + having
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print =========================> nest query join
|
||||
sql select a.ts,a.k,b.ts from (select count(*) k from nest_tb0 interval(30a)) a, (select count(*) f from nest_tb1 interval(30a)) b where a.ts = b.ts ;
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != @20-09-15 00:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != @20-09-15 00:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != @20-09-15 00:01:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data11 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data12 != @20-09-15 00:01:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select sum(a.k), sum(b.f) from (select count(*) k from nest_tb0 interval(30a)) a, (select count(*) f from nest_tb1 interval(30a)) b where a.ts = b.ts ;
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select a.ts,a.k,b.ts,c.ts,c.ts,c.x from (select count(*) k from nest_tb0 interval(30a)) a, (select count(*) f from nest_tb1 interval(30a)) b, (select count(*) x from nest_tb2 interval(30a)) c where a.ts = b.ts and a.ts = c.ts
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != @20-09-15 00:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != @20-09-15 00:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != @20-09-15 00:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|
@ -54,7 +54,6 @@ run general/parser/timestamp.sim
|
|||
run general/parser/sliding.sim
|
||||
run general/parser/function.sim
|
||||
run general/parser/stableOp.sim
|
||||
|
||||
run general/parser/having.sim
|
||||
run general/parser/having_child.sim
|
||||
run general/parser/slimit_alter_tags.sim
|
||||
|
|
Loading…
Reference in New Issue