diff --git a/documentation/webdocs/markdowndocs/TAOS SQL-ch.md b/documentation/webdocs/markdowndocs/TAOS SQL-ch.md index 1e9383c40c22bf645413405b88b72bf78f9e4d4b..cd184cbc71b36ee8cac3738c4f28772547c9d8c0 100644 --- a/documentation/webdocs/markdowndocs/TAOS SQL-ch.md +++ b/documentation/webdocs/markdowndocs/TAOS SQL-ch.md @@ -191,9 +191,10 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic ``` 同时向表tb1_name和tb2_name中按列分别插入多条记录 -注意:对同一张表,插入的新记录的时间戳必须递增,否则会跳过插入该条记录。如果时间戳为0,系统将自动使用服务器当前时间作为该记录的时间戳。 +注意:1、对同一张表,插入的新记录的时间戳必须递增,否则会跳过插入该条记录。如果时间戳为0,系统将自动使用服务器当前时间作为该记录的时间戳。 + 2、允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的keep值(数据保留的天数),允许插入的最新记录的时间戳,是相对于当前服务器时间,加上配置的days值(数据文件存储数据的时间跨度,单位为天)。keep和days都是可以在创建数据库时指定的,缺省值分别是3650天和10天。 -**IMPORT**:如果需要将时间戳小于最后一条记录时间的记录写入到数据库中,可使用IMPORT替代INSERT命令,IMPORT的语法与INSERT完全一样。如果同时IMPORT多条记录,需要保证一批记录是按时间戳排序好的。 +**IMPORT**:如果需要将时间戳小于最后一条记录时间的记录写入到数据库中,可使用IMPORT替代INSERT命令,IMPORT的语法与INSERT完全一样。 ## 数据查询 diff --git a/documentation/webdocs/markdowndocs/TAOS SQL.md b/documentation/webdocs/markdowndocs/TAOS SQL.md index 870529417fbb4dd9dd1e73bb253962e9293e94f4..99aa73b4354c60fb3c50ff8b3d2454eb6691c340 100644 --- a/documentation/webdocs/markdowndocs/TAOS SQL.md +++ b/documentation/webdocs/markdowndocs/TAOS SQL.md @@ -181,9 +181,10 @@ All the keywords in a SQL statement are case-insensitive, but strings values are tb2_name (tb2_field1_name, ...) VALUES(field1_value1, ...) (field1_value2, ...) ``` -Note: For a table, the new record must have a timestamp bigger than the last data record, otherwise, it will be discarded and not inserted. If the timestamp is 0, the time stamp will be set to the system time on the server. - -**IMPORT**: If you do want to insert a historical data record into a table, use IMPORT command instead of INSERT. IMPORT has the same syntax as INSERT. If you want to import a batch of historical records, the records must be ordered by the timestamp, otherwise, TDengine won't handle it in the right way. +Note: 1. For a table, the new record must have a timestamp bigger than the last data record, otherwise, it will be discarded and not inserted. If the timestamp is 0, the time stamp will be set to the system time on the server. + 2.The timestamp of the oldest record allowed to be inserted is relative to the current server time, minus the configured keep value (the number of days the data is retained), and the timestamp of the latest record allowed to be inserted is relative to the current server time, plus the configured days value (the time span in which the data file stores data, in days). Both keep and days can be specified when creating the database. The default values are 3650 days and 10 days, respectively. + +**IMPORT**: If you do want to insert a historical data record into a table, use IMPORT command instead of INSERT. IMPORT has the same syntax as INSERT. ## Data Query diff --git a/src/client/inc/tscSQLParser.h b/src/client/inc/tscSQLParser.h index dd579d08c3c6b1465ce6b34e29f453c7b00827ec..0e4ad279dc0beaf0c56109583d3d02f5ae60b4f3 100644 --- a/src/client/inc/tscSQLParser.h +++ b/src/client/inc/tscSQLParser.h @@ -86,15 +86,16 @@ enum _sql_cmd { TSDB_SQL_MAX //48 }; -#define MAX_TOKEN_LEN 30 - -// token type enum { TSQL_NODE_TYPE_EXPR = 0x1, TSQL_NODE_TYPE_ID = 0x2, TSQL_NODE_TYPE_VALUE = 0x4, }; +#define NON_ARITHMEIC_EXPR 0 +#define NORMAL_ARITHMETIC 1 +#define AGG_ARIGHTMEIC 2 + extern char tTokenTypeSwitcher[13]; #define toTSDBType(x) \ @@ -112,7 +113,7 @@ typedef struct SLimitVal { } SLimitVal; typedef struct SOrderVal { - int32_t order; + uint32_t order; int32_t orderColId; } SOrderVal; diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index f60861a349d70312a7b26bcc1922319b0ad4953f..a869e45198fe2da615b2178c55a32bcd64a9285a 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -67,7 +67,7 @@ typedef struct SJoinSubquerySupporter { } SJoinSubquerySupporter; int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, const char* name, - SMeterMeta* pMeterMeta, STableDataBlocks** dataBlocks); + STableMeta* pMeterMeta, STableDataBlocks** dataBlocks); void tscAppendDataBlock(SDataBlockList* pList, STableDataBlocks* pBlocks); void tscDestroyDataBlock(STableDataBlocks* pDataBlock); @@ -81,11 +81,11 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock); void tscFreeUnusedDataBlocks(SDataBlockList* pList); int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pDataList); int32_t tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList, int64_t id, int32_t size, - int32_t startOffset, int32_t rowSize, const char* tableId, SMeterMeta* pMeterMeta, + int32_t startOffset, int32_t rowSize, const char* tableId, STableMeta* pMeterMeta, STableDataBlocks** dataBlocks); -SVnodeSidList* tscGetVnodeSidList(SMetricMeta* pMetricmeta, int32_t vnodeIdx); -SMeterSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx); +SVnodeSidList* tscGetVnodeSidList(SSuperTableMeta* pMetricmeta, int32_t vnodeIdx); +STableSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx); /** * @@ -120,7 +120,7 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo); bool tscIsInsertOrImportData(char* sqlstr); /* use for keep current db info temporarily, for handle table with db prefix */ -void tscGetDBInfoFromMeterId(char* meterId, char* db); +void tscGetDBInfoFromMeterId(char* tableId, char* db); int tscAllocPayload(SSqlCmd* pCmd, int size); @@ -128,6 +128,8 @@ void tscFieldInfoSetValFromSchema(SFieldInfo* pFieldInfo, int32_t index, SSchema void tscFieldInfoSetValFromField(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* pField); void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, const char* name, int16_t bytes); void tscFieldInfoUpdateVisible(SFieldInfo* pFieldInfo, int32_t index, bool visible); +void tscFieldInfoSetExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlExpr* pExpr); +void tscFieldInfoSetBinExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlFunctionExpr* pExpr); void tscFieldInfoCalOffset(SQueryInfo* pQueryInfo); void tscFieldInfoUpdateOffsetForInterResult(SQueryInfo* pQueryInfo); @@ -149,9 +151,10 @@ SSqlExpr* tscSqlExprInsertEmpty(SQueryInfo* pQueryInfo, int32_t index, int16_t f SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, int16_t size); +int32_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo); SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index); -void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t uid); +void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t uid, bool deepcopy); void* tscSqlExprDestroy(SSqlExpr* pExpr); void tscSqlExprInfoDestroy(SSqlExprInfo* pExprInfo); @@ -196,7 +199,7 @@ int32_t tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex, SQuer SMeterMetaInfo* tscGetMeterMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, int32_t* index); void tscClearMeterMetaInfo(SMeterMetaInfo* pMeterMetaInfo, bool removeFromCache); -SMeterMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, SMeterMeta* pMeterMeta, SMetricMeta* pMetricMeta, +SMeterMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pMeterMeta, SSuperTableMeta* pMetricMeta, int16_t numOfTags, int16_t* tags); SMeterMetaInfo* tscAddEmptyMeterMetaInfo(SQueryInfo *pQueryInfo); int32_t tscAddSubqueryInfo(SSqlCmd *pCmd); diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index ec839e25758793f7ada6a12684274903f6bfdfa0..7e3b54545a5c6fb942d2a70da6c09b5f47123727 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -32,9 +32,8 @@ extern "C" { #include "tutil.h" #include "trpc.h" -#define TSC_GET_RESPTR_BASE(res, _queryinfo, col, ord) \ - (res->data + tscFieldInfoGetOffset(_queryinfo, col) * res->numOfRows) - +#define TSC_GET_RESPTR_BASE(res, _queryinfo, col) (res->data + ((_queryinfo)->fieldsInfo.pSqlExpr[col]->offset) * res->numOfRows) + // forward declaration struct SSqlInfo; @@ -47,8 +46,8 @@ typedef struct SSqlGroupbyExpr { } SSqlGroupbyExpr; typedef struct SMeterMetaInfo { - SMeterMeta * pMeterMeta; // metermeta - SMetricMeta *pMetricMeta; // metricmeta + STableMeta * pMeterMeta; // metermeta + SSuperTableMeta *pMetricMeta; // metricmeta /* * 1. keep the vnode index during the multi-vnode super table projection query @@ -71,13 +70,19 @@ typedef struct SSqlExpr { int16_t interResBytes; // inter result buffer size int16_t numOfParams; // argument value of each function tVariant param[3]; // parameters are not more than 3 + int32_t offset; // sub result column value of arithmetic expression. } SSqlExpr; +typedef struct SColumnIndex { + int16_t tableIndex; + int16_t columnIndex; +} SColumnIndex; + typedef struct SFieldInfo { int16_t numOfOutputCols; // number of column in result int16_t numOfAlloc; // allocated size TAOS_FIELD *pFields; - short * pOffset; +// short * pOffset; /* * define if this column is belong to the queried result, it may be add by parser to faciliate @@ -86,20 +91,17 @@ typedef struct SFieldInfo { * NOTE: these hidden columns always locate at the end of the output columns */ bool * pVisibleCols; - int32_t numOfHiddenCols; // the number of column not belongs to the queried result columns + int32_t numOfHiddenCols; // the number of column not belongs to the queried result columns + SSqlFunctionExpr** pExpr; // used for aggregation arithmetic express,such as count(*)+count(*) + SSqlExpr** pSqlExpr; } SFieldInfo; typedef struct SSqlExprInfo { - int16_t numOfAlloc; - int16_t numOfExprs; - SSqlExpr *pExprs; + int16_t numOfAlloc; + int16_t numOfExprs; + SSqlExpr** pExprs; } SSqlExprInfo; -typedef struct SColumnIndex { - int16_t tableIndex; - int16_t columnIndex; -} SColumnIndex; - typedef struct SColumnBase { SColumnIndex colIndex; int32_t numOfFilters; @@ -120,7 +122,7 @@ typedef struct SCond { } SCond; typedef struct SJoinNode { - char meterId[TSDB_TABLE_ID_LEN]; + char tableId[TSDB_TABLE_ID_LEN]; uint64_t uid; int16_t tagCol; } SJoinNode; @@ -155,23 +157,23 @@ typedef struct SParamInfo { } SParamInfo; typedef struct STableDataBlocks { - char meterId[TSDB_TABLE_ID_LEN]; + char tableId[TSDB_TABLE_ID_LEN]; int8_t tsSource; // where does the UNIX timestamp come from, server or client bool ordered; // if current rows are ordered or not int64_t vgid; // virtual group id int64_t prevTS; // previous timestamp, recorded to decide if the records array is ts ascending - int32_t numOfMeters; // number of tables in current submit block + int32_t numOfTables; // number of tables in current submit block int32_t rowSize; // row size for current table uint32_t nAllocSize; - uint32_t headerSize; // header for metadata (submit metadata) + uint32_t headerSize; // header for metadata (submit metadata) uint32_t size; /* * the metermeta for current table, the metermeta will be used during submit stage, keep a ref * to avoid it to be removed from cache */ - SMeterMeta *pMeterMeta; + STableMeta *pMeterMeta; union { char *filename; @@ -199,9 +201,9 @@ typedef struct SQueryInfo { char intervalTimeUnit; int64_t etime, stime; - int64_t nAggTimeInterval; // aggregation time interval - int64_t nSlidingTime; // sliding window in mseconds - SSqlGroupbyExpr groupbyExpr; // group by tags info + int64_t intervalTime; // aggregation time interval + int64_t slidingTime; // sliding window in mseconds + SSqlGroupbyExpr groupbyExpr; // group by tags info SColumnBaseInfo colList; SFieldInfo fieldsInfo; @@ -217,9 +219,9 @@ typedef struct SQueryInfo { int64_t * defaultVal; // default value for interpolation char * msg; // pointer to the pCmd->payload to keep error message temporarily int64_t clauseLimit; // limit for current sub clause - + // offset value in the original sql expression, NOT sent to virtual node, only applied at client side - int64_t prjOffset; + int64_t prjOffset; } SQueryInfo; // data source from sql string or from file @@ -270,29 +272,27 @@ typedef struct SResRec { struct STSBuf; typedef struct { - uint8_t code; - int64_t numOfRows; // num of results in current retrieved - int64_t numOfTotal; // num of total results - int64_t numOfTotalInCurrentClause; // num of total result in current subclause - - char * pRsp; - int rspType; - int rspLen; - uint64_t qhandle; - int64_t uid; - int64_t useconds; - int64_t offset; // offset value from vnode during projection query of stable - int row; - int16_t numOfnchar; - int16_t precision; - int32_t numOfGroups; - SResRec * pGroupRec; - char * data; - short * bytes; - void ** tsrow; - char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t) + int32_t code; + int64_t numOfRows; // num of results in current retrieved + int64_t numOfTotal; // num of total results + int64_t numOfTotalInCurrentClause; // num of total result in current subclause + char * pRsp; + int rspType; + int rspLen; + uint64_t qhandle; + int64_t uid; + int64_t useconds; + int64_t offset; // offset value from vnode during projection query of stable + int row; + int16_t numOfCols; + int16_t precision; + int32_t numOfGroups; + SResRec * pGroupRec; + char * data; + void ** tsrow; + char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t) + SColumnIndex *pColumnIndex; struct SLocalReducer *pLocalReducer; - SColumnIndex * pColumnIndex; } SSqlRes; typedef struct _tsc_obj { @@ -324,14 +324,12 @@ typedef struct _sql_obj { short vnode; int64_t stime; uint32_t queryId; - void * thandle; - SRpcIpSet ipSet; void * pStream; void * pSubscription; char * sqlstr; char retry; char maxRetry; - uint8_t index; + SRpcIpSet *ipList; char freed : 4; char listed : 4; tsem_t rspSem; @@ -373,18 +371,20 @@ typedef struct _sstream { struct _sstream *prev, *next; } SSqlStream; +int32_t tscInitRpc(const char *user, const char *secret); + // tscSql API int tsParseSql(SSqlObj *pSql, bool multiVnodeInsertion); void tscInitMsgs(); extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo); -void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle); -int tscProcessSql(SSqlObj *pSql); +void tscProcessMsgFromServer(char type, void *pCont, int contLen, void *ahandle, int32_t code); +int tscProcessSql(SSqlObj *pSql); void tscAsyncInsertMultiVnodesProxy(void *param, TAOS_RES *tres, int numOfRows); -int tscRenewMeterMeta(SSqlObj *pSql, char *meterId); +int tscRenewMeterMeta(SSqlObj *pSql, char *tableId); void tscQueueAsyncRes(SSqlObj *pSql); void tscQueueAsyncError(void(*fp), void *param); @@ -400,19 +400,17 @@ int taos_retrieve(TAOS_RES *res); int32_t tscTansformSQLFunctionForSTableQuery(SQueryInfo *pQueryInfo); void tscRestoreSQLFunctionForMetricQuery(SQueryInfo *pQueryInfo); -void tscClearSqlMetaInfoForce(SSqlCmd *pCmd); - int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo); void tscDestroyResPointerInfo(SSqlRes *pRes); void tscFreeSqlCmdData(SSqlCmd *pCmd); -void tscFreeResData(SSqlObj* pSql); +void tscFreeResData(SSqlObj *pSql); /** * free query result of the sql object * @param pObj */ -void tscFreeSqlResult(SSqlObj* pSql); +void tscFreeSqlResult(SSqlObj *pSql); /** * only free part of resources allocated during query. diff --git a/src/client/src/tscAst.c b/src/client/src/tscAst.c index c740f65dcf40173385de3286db5b47e515d5d531..22100bc1d17c71af57b1230e2421e135b0c9eec6 100644 --- a/src/client/src/tscAst.c +++ b/src/client/src/tscAst.c @@ -139,7 +139,7 @@ static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols, } else { pNode->colId = -1; pNode->pSchema->type = TSDB_DATA_TYPE_BINARY; - pNode->pSchema->bytes = TSDB_METER_NAME_LEN; + pNode->pSchema->bytes = TSDB_TABLE_NAME_LEN; strcpy(pNode->pSchema->name, TSQL_TBNAME_L); pNode->pSchema->colId = -1; } @@ -158,7 +158,7 @@ static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols, return pNode; } -static uint8_t getBinaryExprOptr(SSQLToken *pToken) { +uint8_t getBinaryExprOptr(SSQLToken *pToken) { switch (pToken->type) { case TK_LT: return TSDB_RELATION_LESS; @@ -183,6 +183,7 @@ static uint8_t getBinaryExprOptr(SSQLToken *pToken) { case TK_STAR: return TSDB_BINARY_OP_MULTIPLY; case TK_SLASH: + case TK_DIVIDE: return TSDB_BINARY_OP_DIVIDE; case TK_REM: return TSDB_BINARY_OP_REMAINDER; diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index a70a314298ca870e927ae1f7ff3629d0b925747d..9528097d207f7d2546c3702f2c2712591fb81cc6 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -284,8 +284,15 @@ void tscAsyncFetchSingleRowProxy(void *param, TAOS_RES *tres, int numOfRows) { return; } - for (int i = 0; i < pCmd->numOfCols; ++i) - pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order) + pRes->bytes[i] * pRes->row; + for (int i = 0; i < pCmd->numOfCols; ++i){ + SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[i]; + if (pExpr != NULL) { + pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i) + pExpr->resBytes * pRes->row; + } else { + //todo add + } + } + pRes->row++; (*pSql->fetchFp)(pSql->param, pSql, pSql->res.tsrow); @@ -299,7 +306,12 @@ void tscProcessFetchRow(SSchedMsg *pMsg) { SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); for (int i = 0; i < pCmd->numOfCols; ++i) { - pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order) + pRes->bytes[i] * pRes->row; + SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[i]; + if (pExpr != NULL) { + pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i) + pExpr->resBytes * pRes->row; + } else { + //todo add + } } pRes->row++; @@ -318,13 +330,6 @@ void tscProcessAsyncRes(SSchedMsg *pMsg) { int cmd = pCmd->command; int code = pRes->code ? -pRes->code : pRes->numOfRows; - if ((tscKeepConn[cmd] == 0 || (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS)) && - pSql->pStream == NULL) { - if (pSql->thandle) taosAddConnIntoCache(tscConnCache, pSql->thandle, pSql->ip, pSql->vnode, pTscObj->user); - - pSql->thandle = NULL; - } - // in case of async insert, restore the user specified callback function bool shouldFree = tscShouldFreeAsyncSqlObj(pSql); @@ -451,11 +456,11 @@ void tscMeterMetaCallBack(void *param, TAOS_RES *res, int code) { if (code != 0) { code = abs(code); pRes->code = code; - tscTrace("%p failed to renew meterMeta", pSql); + tscTrace("%p failed to renew tableMeta", pSql); tsem_post(&pSql->rspSem); } else { - tscTrace("%p renew meterMeta successfully, command:%d, code:%d, thandle:%p, retry:%d", - pSql, pSql->cmd.command, pSql->res.code, pSql->thandle, pSql->retry); + tscTrace("%p renew tableMeta successfully, command:%d, code:%d, retry:%d", + pSql, pSql->cmd.command, pSql->res.code, pSql->retry); SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0, 0); assert(pMeterMetaInfo->pMeterMeta == NULL); @@ -553,7 +558,7 @@ void tscMeterMetaCallBack(void *param, TAOS_RES *res, int code) { tscTansformSQLFunctionForSTableQuery(pQueryInfo); tscIncStreamExecutionCount(pSql->pStream); } else { - tscTrace("%p get meterMeta/metricMeta successfully", pSql); + tscTrace("%p get tableMeta/metricMeta successfully", pSql); } tscDoQuery(pSql); diff --git a/src/client/src/tscFunctionImpl.c b/src/client/src/tscFunctionImpl.c index 837a0ce0054b8fd7cc92a7b164f667cb6841a276..88b1fc0c28157f9023a3fbef62dabc05802cf05c 100644 --- a/src/client/src/tscFunctionImpl.c +++ b/src/client/src/tscFunctionImpl.c @@ -322,6 +322,10 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI return TSDB_CODE_SUCCESS; } +bool stableQueryFunctChanged(int32_t funcId) { + return (aAggs[funcId].stableFuncId != funcId); +} + /** * the numOfRes should be kept, since it may be used later * and allow the ResultInfo to be re initialized @@ -719,12 +723,15 @@ static int32_t first_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY return BLK_DATA_NO_NEEDED; } - SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes); - if (pInfo->hasResult != DATA_SET_FLAG) { - return BLK_DATA_ALL_NEEDED; - } else { // data in current block is not earlier than current result - return (pInfo->ts <= start) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED; - } + // result buffer has not been set yet. + return BLK_DATA_ALL_NEEDED; + //todo optimize the filter info +// SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes); +// if (pInfo->hasResult != DATA_SET_FLAG) { +// return BLK_DATA_ALL_NEEDED; +// } else { // data in current block is not earlier than current result +// return (pInfo->ts <= start) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED; +// } } static int32_t last_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId, @@ -733,12 +740,13 @@ static int32_t last_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY return BLK_DATA_NO_NEEDED; } - SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes); - if (pInfo->hasResult != DATA_SET_FLAG) { - return BLK_DATA_ALL_NEEDED; - } else { - return (pInfo->ts > end) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED; - } + return BLK_DATA_ALL_NEEDED; +// SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes); +// if (pInfo->hasResult != DATA_SET_FLAG) { +// return BLK_DATA_ALL_NEEDED; +// } else { +// return (pInfo->ts > end) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED; +// } } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -1437,7 +1445,9 @@ static void stddev_next_step(SQLFunctionCtx *pCtx) { */ pStd->stage++; avg_finalizer(pCtx); - + + pResInfo->initialized = true; // set it initialized to avoid re-initialization + // save average value into tmpBuf, for second stage scan SAvgInfo *pAvg = pResInfo->interResultBuf; @@ -2184,7 +2194,7 @@ static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) { // only the first_stage_merge is directly written data into final output buffer if (pResInfo->superTableQ && pCtx->currentStage != SECONDARY_STAGE_MERGE) { return (STopBotInfo*) pCtx->aOutputBuf; - } else { // for normal table query and super table at the secondary_stage, result is written to intermediate buffer + } else { // during normal table query and super table at the secondary_stage, result is written to intermediate buffer return pResInfo->interResultBuf; } } @@ -3312,7 +3322,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) { tSQLBinaryExprCalcTraverse(sas->pExpr->pBinExprInfo.pBinExpr, pCtx->size, pCtx->aOutputBuf, sas, pCtx->order, arithmetic_callback_function); - pCtx->aOutputBuf += pCtx->outputBytes * pCtx->size/* * GET_FORWARD_DIRECTION_FACTOR(pCtx->order)*/; + pCtx->aOutputBuf += pCtx->outputBytes * pCtx->size; pCtx->param[1].pz = NULL; } @@ -3573,6 +3583,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) { } GET_RES_INFO(pCtx)->numOfRes = 1; // todo add test case + doFinalizer(pCtx); } /* diff --git a/src/client/src/tscJoinProcess.c b/src/client/src/tscJoinProcess.c index 1bafb60f1a0e487aeaa7b70e1c1817111f8a631d..afd8e98edac4522089e0aaafa02237da67bdd1cc 100644 --- a/src/client/src/tscJoinProcess.c +++ b/src/client/src/tscJoinProcess.c @@ -100,7 +100,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSuppor * in case of stable query, limit/offset is not applied here. the limit/offset is applied to the * final results which is acquired after the secondry merge of in the client. */ - if (pLimit->offset == 0 || pQueryInfo->nAggTimeInterval > 0 || QUERY_IS_STABLE_QUERY(pQueryInfo->type)) { + if (pLimit->offset == 0 || pQueryInfo->intervalTime > 0 || QUERY_IS_STABLE_QUERY(pQueryInfo->type)) { if (*st > elem1.ts) { *st = elem1.ts; } @@ -165,7 +165,7 @@ SJoinSubquerySupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pS pSupporter->subqueryIndex = index; SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); - pSupporter->interval = pQueryInfo->nAggTimeInterval; + pSupporter->interval = pQueryInfo->intervalTime; pSupporter->limit = pQueryInfo->limit; SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, pSql->cmd.clauseIndex, index); @@ -275,6 +275,7 @@ int32_t tscLaunchSecondPhaseSubqueries(SSqlObj* pSql) { pSubQueryInfo->tsBuf = NULL; // free result for async object will also free sqlObj + assert(pSubQueryInfo->exprsInfo.numOfExprs == 1); // ts_comp query only requires one resutl columns taos_free_result(pPrevSub); SSqlObj *pNew = createSubqueryObj(pSql, (int16_t) i, tscJoinQueryCallback, pSupporter, NULL); @@ -293,24 +294,26 @@ int32_t tscLaunchSecondPhaseSubqueries(SSqlObj* pSql) { // set the second stage sub query for join process pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_SEC_STAGE; - pQueryInfo->nAggTimeInterval = pSupporter->interval; + pQueryInfo->intervalTime = pSupporter->interval; pQueryInfo->groupbyExpr = pSupporter->groupbyExpr; tscColumnBaseInfoCopy(&pQueryInfo->colList, &pSupporter->colList, 0); tscTagCondCopy(&pQueryInfo->tagCond, &pSupporter->tagCond); - tscSqlExprCopy(&pQueryInfo->exprsInfo, &pSupporter->exprsInfo, pSupporter->uid); + tscSqlExprCopy(&pQueryInfo->exprsInfo, &pSupporter->exprsInfo, pSupporter->uid, false); tscFieldInfoCopyAll(&pQueryInfo->fieldsInfo, &pSupporter->fieldsInfo); - + + pSupporter->exprsInfo.numOfExprs = 0; + pSupporter->fieldsInfo.numOfOutputCols = 0; + /* * if the first column of the secondary query is not ts function, add this function. * Because this column is required to filter with timestamp after intersecting. */ - if (pSupporter->exprsInfo.pExprs[0].functionId != TSDB_FUNC_TS) { + if (pSupporter->exprsInfo.pExprs[0]->functionId != TSDB_FUNC_TS) { tscAddTimestampColumn(pQueryInfo, TSDB_FUNC_TS, 0); } - // todo refactor function name SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); assert(pNew->numOfSubs == 0 && pNew->cmd.numOfClause == 1 && pNewQueryInfo->numOfTables == 1); diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index f5e34e5132d8b3f4b57598178f7c80e8e9d7f801..ab57719d0979d4994e2c5ee913f21d320ca21561 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -77,7 +77,7 @@ static int32_t getToStringLength(const char *pData, int32_t length, int32_t type * length((uint64_t) 123456789011) > 12, greater than sizsof(uint64_t) */ static int32_t tscMaxLengthOfTagsFields(SSqlObj *pSql) { - SMeterMeta *pMeta = tscGetMeterMetaInfo(&pSql->cmd, 0, 0)->pMeterMeta; + STableMeta *pMeta = tscGetMeterMetaInfo(&pSql->cmd, 0, 0)->pMeterMeta; if (pMeta->tableType == TSDB_TABLE_TYPE_SUPER_TABLE || pMeta->tableType == TSDB_TABLE_TYPE_NORMAL_TABLE || pMeta->tableType == TSDB_TABLE_TYPE_STREAM_TABLE) { @@ -109,7 +109,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - SMeterMeta * pMeta = pMeterMetaInfo->pMeterMeta; + STableMeta * pMeta = pMeterMetaInfo->pMeterMeta; /* * tagValueCnt is to denote the number of tags columns for meter, not metric. and is to show the column data. @@ -251,6 +251,13 @@ static int32_t tscBuildMeterSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 3, TSDB_DATA_TYPE_BINARY, "Note", noteColLength); rowLen += noteColLength; + + //set the sqlexpr part + SColumnIndex index = {0}; + pQueryInfo->fieldsInfo.pSqlExpr[0] = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, TSDB_COL_NAME_LEN, TSDB_COL_NAME_LEN); + pQueryInfo->fieldsInfo.pSqlExpr[1] = tscSqlExprInsert(pQueryInfo, 1, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, typeColLength, typeColLength); + pQueryInfo->fieldsInfo.pSqlExpr[2] = tscSqlExprInsert(pQueryInfo, 2, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), sizeof(int32_t)); + pQueryInfo->fieldsInfo.pSqlExpr[3] = tscSqlExprInsert(pQueryInfo, 3, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, noteColLength, noteColLength); return rowLen; } @@ -285,7 +292,7 @@ static int tscBuildMetricTagProjectionResult(SSqlObj *pSql) { SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta; + SSuperTableMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta; SSchema * pSchema = tsGetTagSchema(pMeterMetaInfo->pMeterMeta); int32_t vOffset[TSDB_MAX_COLUMNS] = {0}; @@ -293,13 +300,13 @@ static int tscBuildMetricTagProjectionResult(SSqlObj *pSql) { for (int32_t f = 1; f < pMeterMetaInfo->numOfTags; ++f) { int16_t tagColumnIndex = pMeterMetaInfo->tagColumnIndex[f - 1]; if (tagColumnIndex == -1) { - vOffset[f] = vOffset[f - 1] + TSDB_METER_NAME_LEN; + vOffset[f] = vOffset[f - 1] + TSDB_TABLE_NAME_LEN; } else { vOffset[f] = vOffset[f - 1] + pSchema[tagColumnIndex].bytes; } } - int32_t totalNumOfResults = pMetricMeta->numOfMeters; + int32_t totalNumOfResults = pMetricMeta->numOfTables; int32_t rowLen = tscGetResRowLength(pQueryInfo); tscInitResObjForLocalQuery(pSql, totalNumOfResults, rowLen); @@ -309,7 +316,7 @@ static int tscBuildMetricTagProjectionResult(SSqlObj *pSql) { SVnodeSidList *pSidList = (SVnodeSidList *)((char *)pMetricMeta + pMetricMeta->list[i]); for (int32_t j = 0; j < pSidList->numOfSids; ++j) { - SMeterSidExtInfo *pSidExt = tscGetMeterSidInfo(pSidList, j); + STableSidExtInfo *pSidExt = tscGetMeterSidInfo(pSidList, j); for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) { SColIndexEx *pColIndex = &tscSqlExprGet(pQueryInfo, k)->colInfo; @@ -336,7 +343,7 @@ static int tscBuildMetricTagSqlFunctionResult(SSqlObj *pSql) { SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); - SMetricMeta *pMetricMeta = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0)->pMetricMeta; + SSuperTableMeta *pMetricMeta = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0)->pMetricMeta; int32_t totalNumOfResults = 1; // count function only produce one result int32_t rowLen = tscGetResRowLength(pQueryInfo); @@ -351,7 +358,7 @@ static int tscBuildMetricTagSqlFunctionResult(SSqlObj *pSql) { TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, k); memcpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, i) * totalNumOfResults + pField->bytes * rowIdx, - &pMetricMeta->numOfMeters, sizeof(pMetricMeta->numOfMeters)); + &pMetricMeta->numOfTables, sizeof(pMetricMeta->numOfTables)); } else { tscError("not support operations"); continue; @@ -368,7 +375,7 @@ static int tscProcessQueryTags(SSqlObj *pSql) { SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); - SMeterMeta *pMeterMeta = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0)->pMeterMeta; + STableMeta *pMeterMeta = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0)->pMeterMeta; if (pMeterMeta == NULL || pMeterMeta->numOfTags == 0 || pMeterMeta->numOfColumns == 0) { strcpy(pCmd->payload, "invalid table"); pSql->res.code = TSDB_CODE_INVALID_TABLE; @@ -455,6 +462,8 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa tscInitResObjForLocalQuery(pSql, 1, valueLength); TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, 0); + pQueryInfo->fieldsInfo.pSqlExpr[0] = pQueryInfo->exprsInfo.pExprs[0]; + strncpy(pRes->data, val, pField->bytes); } diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 8039fbe405feada1552993cc2c1d78364ec2b2ab..59dc708e99fe930f887b20fe784c984fa1954a90 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -496,7 +496,7 @@ static int32_t rowDataCompar(const void *lhs, const void *rhs) { } } -int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMeta, int maxRows, +int tsParseValues(char **str, STableDataBlocks *pDataBlock, STableMeta *pMeterMeta, int maxRows, SParsedDataColInfo *spd, char *error, int32_t *code, char *tmpTokenBuf) { int32_t index = 0; SSQLToken sToken; @@ -601,7 +601,7 @@ int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int3 return TSDB_CODE_SUCCESS; } -static void tsSetBlockInfo(SShellSubmitBlock *pBlocks, const SMeterMeta *pMeterMeta, int32_t numOfRows) { +static void tsSetBlockInfo(SShellSubmitBlock *pBlocks, const STableMeta *pMeterMeta, int32_t numOfRows) { pBlocks->sid = pMeterMeta->sid; pBlocks->uid = pMeterMeta->uid; pBlocks->sversion = pMeterMeta->sversion; @@ -655,7 +655,7 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableHashList, char int32_t *totalNum) { SSqlCmd * pCmd = &pSql->cmd; SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - SMeterMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta; STableDataBlocks *dataBuf = NULL; int32_t ret = tscGetDataBlockFromList(pTableHashList, pCmd->pDataBlocks, pMeterMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE, @@ -695,7 +695,7 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableHashList, char tsSetBlockInfo(pBlocks, pMeterMeta, numOfRows); dataBuf->vgid = pMeterMeta->vgid; - dataBuf->numOfMeters = 1; + dataBuf->numOfTables = 1; /* * the value of pRes->numOfRows does not affect the true result of AFFECTED ROWS, @@ -1136,7 +1136,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { wordfree(&full_path); STableDataBlocks *pDataBlock = NULL; - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; int32_t ret = tscCreateDataBlock(PATH_MAX, pMeterMeta->rowSize, sizeof(SShellSubmitBlock), pMeterMetaInfo->name, pMeterMeta, &pDataBlock); @@ -1148,7 +1148,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { strcpy(pDataBlock->filename, fname); } else if (sToken.type == TK_LP) { /* insert into tablename(col1, col2,..., coln) values(v1, v2,... vn); */ - SMeterMeta *pMeterMeta = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0)->pMeterMeta; + STableMeta *pMeterMeta = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0)->pMeterMeta; SSchema * pSchema = tsGetSchema(pMeterMeta); if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) { @@ -1349,7 +1349,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock SSqlCmd *pCmd = &pSql->cmd; assert(pCmd->numOfClause == 1); - SMeterMeta *pMeterMeta = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0)->pMeterMeta; + STableMeta *pMeterMeta = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0)->pMeterMeta; SShellSubmitBlock *pBlocks = (SShellSubmitBlock *)(pTableDataBlocks->pData); tsSetBlockInfo(pBlocks, pMeterMeta, numOfRows); @@ -1383,7 +1383,7 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp, char *tmpTokenBuf) { int nrows = 0; SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - SMeterMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta; assert(pCmd->numOfClause == 1); int32_t rowSize = pMeterMeta->rowSize; @@ -1544,7 +1544,7 @@ void tscProcessMultiVnodesInsertFromFile(SSqlObj *pSql) { continue; } - strncpy(pMeterMetaInfo->name, pDataBlock->meterId, TSDB_TABLE_ID_LEN); + strncpy(pMeterMetaInfo->name, pDataBlock->tableId, TSDB_TABLE_ID_LEN); memset(pDataBlock->pData, 0, pDataBlock->nAllocSize); int32_t ret = tscGetMeterMeta(pSql, pMeterMetaInfo); diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index 4ab63c18e9ad339664b1771bead46aedcb0c9d48..cb991691f5473cb7b8c528f017508d53df7b45b2 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -451,7 +451,6 @@ static int insertStmtExecute(STscStmt* stmt) { pRes->numOfTotalInCurrentClause = 0; pRes->qhandle = 0; - pSql->thandle = NULL; tscDoQuery(pSql); diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index c6abfabf93370bac4995b6d8f6384b4fc98a6273..00c8d776190fc2cff077fd9be87e8ac966f4d5cd 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -145,7 +145,7 @@ void tscKillQuery(STscObj *pObj, uint32_t killId) { if (pSql == NULL) return; - tscTrace("%p query is killed, queryId:%d thandle:%p", pSql, killId, pSql->thandle); + tscTrace("%p query is killed, queryId:%d", pSql, killId); taos_stop_query(pSql); } @@ -209,16 +209,16 @@ void tscKillStream(STscObj *pObj, uint32_t killId) { } char *tscBuildQueryStreamDesc(char *pMsg, STscObj *pObj) { - SQList *pQList = (SQList *)pMsg; + SQqueryList *pQList = (SQqueryList *)pMsg; char * pMax = pMsg + TSDB_PAYLOAD_SIZE - 256; - SQDesc *pQdesc = pQList->qdesc; + SQueryDesc *pQdesc = pQList->qdesc; pQList->numOfQueries = 0; // We extract the lock to tscBuildHeartBeatMsg function. /* pthread_mutex_lock (&pObj->mutex); */ - pMsg += sizeof(SQList); + pMsg += sizeof(SQqueryList); SSqlObj *pSql = pObj->sqlList; while (pSql) { /* @@ -239,15 +239,15 @@ char *tscBuildQueryStreamDesc(char *pMsg, STscObj *pObj) { pQList->numOfQueries++; pQdesc++; pSql = pSql->next; - pMsg += sizeof(SQDesc); + pMsg += sizeof(SQueryDesc); if (pMsg > pMax) break; } - SSList *pSList = (SSList *)pMsg; - SSDesc *pSdesc = pSList->sdesc; + SStreamList *pSList = (SStreamList *)pMsg; + SStreamDesc *pSdesc = pSList->sdesc; pSList->numOfStreams = 0; - pMsg += sizeof(SSList); + pMsg += sizeof(SStreamList); SSqlStream *pStream = pObj->streamList; while (pStream) { strncpy(pSdesc->sql, pStream->pSql->sqlstr, TSDB_SHOW_SQL_LEN - 1); @@ -265,7 +265,7 @@ char *tscBuildQueryStreamDesc(char *pMsg, STscObj *pObj) { pSList->numOfStreams++; pSdesc++; pStream = pStream->next; - pMsg += sizeof(SSDesc); + pMsg += sizeof(SStreamDesc); if (pMsg > pMax) break; } diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index e5499fd04f68cec22cc548db27cdb27c4da61717..92323dcdfe05e40fd0281ca9dd0495f0230fd1e9 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -22,6 +22,7 @@ #include "tstoken.h" #include "tstrbuild.h" #include "ttime.h" +#include "tast.h" #include "tscSQLParser.h" #include "tscUtil.h" @@ -58,9 +59,9 @@ static int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pD static void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength); static void getRevisedName(char* resultFieldName, int32_t functionId, int32_t maxLen, char* columnName); -static int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem); +static int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem, bool isResultColumn); static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes, - int8_t type, char* fieldName); + int8_t type, char* fieldName, SSqlExpr* pSqlExpr); static int32_t changeFunctionID(int32_t optr, int16_t* functionId); static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable); @@ -85,7 +86,7 @@ static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo); static int32_t validateSqlFunctionInStreamSql(SQueryInfo* pQueryInfo); static int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString); static int32_t validateFunctionsInIntervalOrGroupbyQuery(SQueryInfo* pQueryInfo); -static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList); +static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type); static int32_t validateDNodeConfig(tDCLSQL* pOptions); static int32_t validateLocalConfig(tDCLSQL* pOptions); static int32_t validateColumnName(char* name); @@ -93,7 +94,6 @@ static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo); static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField); static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo); -static bool hasDefaultQueryTimeRange(SQueryInfo *pQueryInfo); static void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex); @@ -115,6 +115,9 @@ static int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo); static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo); static int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index); +static int32_t tSQLBinaryExprCreateFromSqlExpr(tSQLSyntaxNode **pExpr, tSQLExpr* pAst, int32_t* num, + SColIndexEx** pColIndex, SSqlExprInfo* pExprInfo); + /* * Used during parsing query sql. Since the query sql usually small in length, error position * is not needed in the final error message. @@ -127,7 +130,7 @@ static int32_t tscQueryOnlyMetricTags(SQueryInfo* pQueryInfo, bool* queryOnMetri assert(QUERY_IS_STABLE_QUERY(pQueryInfo->type)); *queryOnMetricTags = true; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId != TSDB_FUNC_TAGPRJ && @@ -203,7 +206,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { int32_t code = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex, &pQueryInfo); assert(pQueryInfo->numOfTables == 0); - + SMeterMetaInfo* pMeterMetaInfo = tscAddEmptyMeterMetaInfo(pQueryInfo); pCmd->command = pInfo->type; @@ -363,7 +366,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (pToken->n > TSDB_METER_NAME_LEN) { + if (pToken->n > TSDB_TABLE_NAME_LEN) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } @@ -392,7 +395,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { char* pMsg = pCmd->payload + tsRpcHeadSize; pMsg += sizeof(SMgmtHead); - SCfgMsg* pCfg = (SCfgMsg*)pMsg; + SCfgDnodeMsg* pCfg = (SCfgDnodeMsg*)pMsg; strncpy(pCfg->ip, pDCL->a[0].z, pDCL->a[0].n); strncpy(pCfg->config, pDCL->a[1].z, pDCL->a[1].n); @@ -413,7 +416,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { const char* msg3 = "name too long"; pCmd->command = pInfo->type; - //tDCLSQL* pDCL = pInfo->pDCLInfo; + // tDCLSQL* pDCL = pInfo->pDCLInfo; SUserInfo* pUser = &pInfo->pDCLInfo->user; SSQLToken* pName = &pUser->user; @@ -501,7 +504,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { case TSDB_SQL_SELECT: { assert(pCmd->numOfClause == 1); const char* msg1 = "columns in select clause not identical"; - + for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) { SQueryInfo* pqi = NULL; if ((code = tscGetQueryInfoDetailSafely(pCmd, i, &pqi)) != TSDB_CODE_SUCCESS) { @@ -516,18 +519,18 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { if ((code = doCheckForQuery(pSql, pQuerySql, i)) != TSDB_CODE_SUCCESS) { return code; } - + tscPrintSelectClause(pSql, i); } - + // set the command/global limit parameters from the first subclause to the sqlcmd object SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0); pCmd->command = pQueryInfo1->command; - + // if there is only one element, the limit of clause is the limit of global result. - for(int32_t i = 1; i < pCmd->numOfClause; ++i) { + for (int32_t i = 1; i < pCmd->numOfClause; ++i) { SQueryInfo* pQueryInfo2 = tscGetQueryInfoDetail(pCmd, i); - + int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo); if (ret != 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -567,7 +570,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { * are available. */ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) { - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { @@ -590,25 +593,29 @@ int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) { // interval is not null SSQLToken* t = &pQuerySql->interval; - if (getTimestampInUsFromStr(t->z, t->n, &pQueryInfo->nAggTimeInterval) != TSDB_CODE_SUCCESS) { + if (getTimestampInUsFromStr(t->z, t->n, &pQueryInfo->intervalTime) != TSDB_CODE_SUCCESS) { return TSDB_CODE_INVALID_SQL; } // if the unit of time window value is millisecond, change the value from microsecond if (pMeterMetaInfo->pMeterMeta->precision == TSDB_TIME_PRECISION_MILLI) { - pQueryInfo->nAggTimeInterval = pQueryInfo->nAggTimeInterval / 1000; + pQueryInfo->intervalTime = pQueryInfo->intervalTime / 1000; } /* parser has filter the illegal type, no need to check here */ pQueryInfo->intervalTimeUnit = pQuerySql->interval.z[pQuerySql->interval.n - 1]; // interval cannot be less than 10 milliseconds - if (pQueryInfo->nAggTimeInterval < tsMinIntervalTime) { + if (pQueryInfo->intervalTime < tsMinIntervalTime) { return invalidSqlErrMsg(pQueryInfo->msg, msg2); } // for top/bottom + interval query, we do not add additional timestamp column in the front if (isTopBottomQuery(pQueryInfo)) { + if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_INVALID_SQL; + } + return TSDB_CODE_SUCCESS; } @@ -616,18 +623,18 @@ int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) { * check invalid SQL: * select count(tbname)/count(tag1)/count(tag2) from super_table_name interval(1d); */ - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { return invalidSqlErrMsg(pQueryInfo->msg, msg1); } } - + /* * check invalid SQL: * select tbname, tags_fields from super_table_name interval(1s) */ - if (tscQueryMetricTags(pQueryInfo) && pQueryInfo->nAggTimeInterval > 0) { + if (tscQueryMetricTags(pQueryInfo) && pQueryInfo->intervalTime > 0) { return invalidSqlErrMsg(pQueryInfo->msg, msg1); } @@ -648,19 +655,20 @@ int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) { } SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE); + SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE); SColumnList ids = getColumnList(1, 0, PRIMARYKEY_TIMESTAMP_COL_INDEX); - int32_t ret = insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].aName); + int32_t ret = + insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].aName, pExpr); if (ret != TSDB_CODE_SUCCESS) { return ret; } - + if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) { return TSDB_CODE_INVALID_SQL; } - + return TSDB_CODE_SUCCESS; } @@ -672,20 +680,20 @@ int32_t parseSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) { SSQLToken* pSliding = &pQuerySql->sliding; if (pSliding->n != 0) { - getTimestampInUsFromStr(pSliding->z, pSliding->n, &pQueryInfo->nSlidingTime); + getTimestampInUsFromStr(pSliding->z, pSliding->n, &pQueryInfo->slidingTime); if (pMeterMetaInfo->pMeterMeta->precision == TSDB_TIME_PRECISION_MILLI) { - pQueryInfo->nSlidingTime /= 1000; + pQueryInfo->slidingTime /= 1000; } - if (pQueryInfo->nSlidingTime < tsMinSlidingTime) { + if (pQueryInfo->slidingTime < tsMinSlidingTime) { return invalidSqlErrMsg(pQueryInfo->msg, msg0); } - if (pQueryInfo->nSlidingTime > pQueryInfo->nAggTimeInterval) { + if (pQueryInfo->slidingTime > pQueryInfo->intervalTime) { return invalidSqlErrMsg(pQueryInfo->msg, msg1); } } else { - pQueryInfo->nSlidingTime = -1; + pQueryInfo->slidingTime = pQueryInfo->intervalTime; } return TSDB_CODE_SUCCESS; @@ -699,11 +707,11 @@ int32_t setMeterID(SMeterMetaInfo* pMeterMetaInfo, SSQLToken* pzTableName, SSqlO // backup the old name in pMeterMetaInfo size_t size = strlen(pMeterMetaInfo->name); - char* oldName = NULL; + char* oldName = NULL; if (size > 0) { oldName = strdup(pMeterMetaInfo->name); } - + if (hasSpecifyDB(pzTableName)) { // db has been specified in sql string so we ignore current db path code = setObjFullName(pMeterMetaInfo->name, getAccountId(pSql), NULL, pzTableName, NULL); @@ -722,7 +730,7 @@ int32_t setMeterID(SMeterMetaInfo* pMeterMetaInfo, SSQLToken* pzTableName, SSqlO free(oldName); return code; } - + /* * the old name exists and is not equalled to the new name. Release the metermeta/metricmeta * that are corresponding to the old name for the new table name. @@ -734,7 +742,7 @@ int32_t setMeterID(SMeterMetaInfo* pMeterMetaInfo, SSQLToken* pzTableName, SSqlO } else { assert(pMeterMetaInfo->pMeterMeta == NULL && pMeterMetaInfo->pMetricMeta == NULL); } - + tfree(oldName); return TSDB_CODE_SUCCESS; } @@ -881,9 +889,9 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { const char* msg6 = "invalid data type in tags"; assert(pCmd->numOfClause == 1); - + SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; // no more than 6 tags if (pMeterMeta->numOfTags == TSDB_MAX_TAGS) { @@ -953,7 +961,7 @@ bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { assert(pCmd->numOfClause == 1); SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; // no more max columns if (pMeterMeta->numOfColumns >= TSDB_MAX_COLUMNS || @@ -1054,12 +1062,12 @@ int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQL totalLen += 1; /* here we only check the table name length limitation */ - if (tableName->n > TSDB_METER_NAME_LEN) { + if (tableName->n > TSDB_TABLE_NAME_LEN) { return TSDB_CODE_INVALID_SQL; } } else { // pDB == NULL, the db prefix name is specified in tableName /* the length limitation includes tablename + dbname + sep */ - if (tableName->n > TSDB_METER_NAME_LEN + TSDB_DB_NAME_LEN + tListLen(TS_PATH_DELIMITER)) { + if (tableName->n > TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN + tListLen(TS_PATH_DELIMITER)) { return TSDB_CODE_INVALID_SQL; } } @@ -1099,11 +1107,11 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel const char* msg3 = "not support query expression"; const char* msg4 = "columns from different table mixed up in arithmetic expression"; const char* msg5 = "invalid function name"; - + SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); for (int32_t i = 0; i < pSelection->nExpr; ++i) { - int32_t outputIndex = pQueryInfo->fieldsInfo.numOfOutputCols; + int32_t outputIndex = pQueryInfo->exprsInfo.numOfExprs; tSQLExprItem* pItem = &pSelection->a[i]; // project on all fields @@ -1115,7 +1123,6 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel // if the name of column is quoted, remove it and set the right information for later process extractColumnNameFromString(pItem); - pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; // select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2 @@ -1124,45 +1131,94 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel } } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_AVG_IRATE) { // sql function in selection clause, append sql function info in pSqlCmd structure sequentially - if (addExprAndResultField(pQueryInfo, outputIndex, pItem) != TSDB_CODE_SUCCESS) { + if (addExprAndResultField(pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) { return TSDB_CODE_INVALID_SQL; } } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) { - // arithmetic function in select + // arithmetic function in select clause SColumnList columnList = {0}; - if (validateArithmeticSQLExpr(pItem->pNode, pQueryInfo, &columnList) != TSDB_CODE_SUCCESS) { + int32_t arithmeticType = NON_ARITHMEIC_EXPR; + + if (validateArithmeticSQLExpr(pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(pQueryInfo->msg, msg1); } int32_t tableIndex = columnList.ids[0].tableIndex; - for(int32_t f = 1; f < columnList.num; ++f) { - if (columnList.ids[f].tableIndex != tableIndex) { - return invalidSqlErrMsg(pQueryInfo->msg, msg4); - } - } - char arithmeticExprStr[1024] = {0}; char* p = arithmeticExprStr; - - if (buildArithmeticExprString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_INVALID_SQL; - } - - // expr string is set as the parameter of function - SColumnIndex index = {.tableIndex = tableIndex}; - SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputIndex, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, - sizeof(double), sizeof(double)); - addExprParams(pExpr, arithmeticExprStr, TSDB_DATA_TYPE_BINARY, strlen(arithmeticExprStr), index.tableIndex); - - /* todo alias name should use the original sql string */ - if (pItem->aliasName != NULL) { - strncpy(pExpr->aliasName, pItem->aliasName, TSDB_COL_NAME_LEN); + + if (arithmeticType == NORMAL_ARITHMETIC) { + pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; + + // all columns in arithmetic expression must belong to the same table + for (int32_t f = 1; f < columnList.num; ++f) { + if (columnList.ids[f].tableIndex != tableIndex) { + return invalidSqlErrMsg(pQueryInfo->msg, msg4); + } + } + + if (buildArithmeticExprString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_INVALID_SQL; + } + + // expr string is set as the parameter of function + SColumnIndex index = {.tableIndex = tableIndex}; + SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputIndex, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, + sizeof(double), sizeof(double)); + addExprParams(pExpr, arithmeticExprStr, TSDB_DATA_TYPE_BINARY, strlen(arithmeticExprStr), index.tableIndex); + + /* todo alias name should use the original sql string */ + char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr; + strncpy(pExpr->aliasName, name, TSDB_COL_NAME_LEN); + + insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr); } else { - strncpy(pExpr->aliasName, arithmeticExprStr, TSDB_COL_NAME_LEN); + columnList.num = 0; + columnList.ids[0] = (SColumnIndex) {0, 0}; + + insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, "abc", NULL); + + int32_t slot = tscNumOfFields(pQueryInfo) - 1; + + if (pQueryInfo->fieldsInfo.pExpr[slot] == NULL) { + SSqlFunctionExpr* pFuncExpr = calloc(1, sizeof(SSqlFunctionExpr)); + tscFieldInfoSetBinExpr(&pQueryInfo->fieldsInfo, slot, pFuncExpr); + + // arithmetic expression always return result in the format of double float + pFuncExpr->resBytes = sizeof(double); + pFuncExpr->interResBytes = sizeof(double); + pFuncExpr->resType = TSDB_DATA_TYPE_DOUBLE; + + SSqlBinaryExprInfo* pBinExprInfo = &pFuncExpr->pBinExprInfo; + + tSQLSyntaxNode* pNode = NULL; + SColIndexEx* pColIndex = NULL; + + int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pNode, pItem->pNode, &pBinExprInfo->numOfCols, &pColIndex, &pQueryInfo->exprsInfo); + if (ret != TSDB_CODE_SUCCESS) { + tSQLBinaryExprDestroy(&pNode->pExpr, NULL); + return invalidSqlErrMsg(pQueryInfo->msg, "invalid expression in select clause"); + } + + pBinExprInfo->pBinExpr = pNode->pExpr; + pBinExprInfo->pReqColumns = pColIndex; + + for(int32_t k = 0; k < pBinExprInfo->numOfCols; ++k) { + SColIndexEx* pCol = &pBinExprInfo->pReqColumns[k]; + for(int32_t f = 0; f < pQueryInfo->exprsInfo.numOfExprs; ++f) { + SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, f); + if (strcmp(pExpr->aliasName, pCol->name) == 0) { + pCol->colIdxInBuf = f; + break; + } + } + + assert(pCol->colIdxInBuf >= 0 && pCol->colIdxInBuf < pQueryInfo->exprsInfo.numOfExprs); + tfree(pNode); + } + } } - - insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName); } else { /* * not support such expression @@ -1184,7 +1240,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel pQueryInfo->type |= TSDB_QUERY_TYPE_STABLE_QUERY; SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - if (tscQueryMetricTags(pQueryInfo)) { // local handle the metric tag query + if (tscQueryMetricTags(pQueryInfo)) { // local handle the metric tag query pCmd->count = pMeterMetaInfo->pMeterMeta->numOfColumns; // the number of meter schema, tricky. pQueryInfo->command = TSDB_SQL_RETRIEVE_TAGS; } @@ -1203,19 +1259,21 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel return TSDB_CODE_SUCCESS; } -int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes, int8_t type, - char* fieldName) { +int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes, + int8_t type, char* fieldName, SSqlExpr* pSqlExpr) { for (int32_t i = 0; i < pIdList->num; ++i) { tscColumnBaseInfoInsert(pQueryInfo, &(pIdList->ids[i])); } tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, outputIndex, type, fieldName, bytes); + tscFieldInfoSetExpr(&pQueryInfo->fieldsInfo, outputIndex, pSqlExpr); + return TSDB_CODE_SUCCESS; } SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIdx, int32_t tableIndex) { SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, tableIndex); - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; SSchema* pSchema = tsGetColumnSchema(pMeterMeta, colIdx); int32_t numOfCols = pMeterMeta->numOfColumns; @@ -1267,12 +1325,13 @@ static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumn SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos, pIndex->columnIndex, pIndex->tableIndex); SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, pIndex->tableIndex); - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; SSchema* pSchema = tsGetColumnSchema(pMeterMeta, pIndex->columnIndex); char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName; - + strncpy(pExpr->aliasName, colName, tListLen(pExpr->aliasName)); + SColumnList ids = {0}; ids.num = 1; ids.ids[0] = *pIndex; @@ -1281,7 +1340,7 @@ static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumn ids.num = 0; } - insertResultField(pQueryInfo, startPos, &ids, pExpr->resBytes, pExpr->resType, colName); + insertResultField(pQueryInfo, startPos, &ids, pExpr->resBytes, pExpr->resType, pExpr->aliasName, pExpr); } void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, @@ -1294,7 +1353,7 @@ void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex ids.num = 0; } - insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name); + insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr); pExpr->colInfo.flag = flag; if (TSDB_COL_IS_TAG(flag)) { @@ -1306,7 +1365,7 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, pIndex->tableIndex); int32_t numOfTotalColumns = 0; - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; SSchema* pSchema = tsGetSchema(pMeterMeta); if (UTIL_METER_IS_SUPERTABLE(pMeterMetaInfo)) { @@ -1316,7 +1375,8 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum } for (int32_t j = 0; j < numOfTotalColumns; ++j) { - doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex); + SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex); + strncpy(pExpr->aliasName, pSchema[j].name, tListLen(pExpr->aliasName)); pIndex->columnIndex = j; SColumnList ids = {0}; @@ -1325,7 +1385,7 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum // tag columns do not add to source list ids.num = (j >= pMeterMeta->numOfColumns) ? 0 : 1; - insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name); + insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr); } return numOfTotalColumns; @@ -1335,7 +1395,7 @@ int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pI const char* msg0 = "invalid column name"; const char* msg1 = "tag for table query is not allowed"; - int32_t startPos = pQueryInfo->fieldsInfo.numOfOutputCols; + int32_t startPos = pQueryInfo->exprsInfo.numOfExprs; if (pItem->pNode->nSQLOptr == TK_ALL) { // project on all fields SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -1361,14 +1421,14 @@ int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pI } if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { - SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = TSDB_METER_NAME_LEN}; + SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = TSDB_TABLE_NAME_LEN}; strcpy(colSchema.name, TSQL_TBNAME_L); pQueryInfo->type = TSDB_QUERY_TYPE_STABLE_QUERY; tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, true); } else { SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, index.tableIndex); - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; if (index.columnIndex >= pMeterMeta->numOfColumns && UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { return invalidSqlErrMsg(pQueryInfo->msg, msg1); @@ -1411,9 +1471,10 @@ static int32_t setExprInfoForFunctions(SQueryInfo* pQueryInfo, SSchema* pSchema, } else { getRevisedName(columnName, functionID, TSDB_COL_NAME_LEN, pSchema[pColIndex->columnIndex].name); } - - tscSqlExprInsert(pQueryInfo, resColIdx, functionID, pColIndex, type, bytes, bytes); - + + SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, resColIdx, functionID, pColIndex, type, bytes, bytes); + strncpy(pExpr->aliasName, columnName, tListLen(pExpr->aliasName)); + // for point interpolation/last_row query, we need the timestamp column to be loaded SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; if (functionID == TSDB_FUNC_INTERP || functionID == TSDB_FUNC_LAST_ROW) { @@ -1421,12 +1482,12 @@ static int32_t setExprInfoForFunctions(SQueryInfo* pQueryInfo, SSchema* pSchema, } SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex); - insertResultField(pQueryInfo, resColIdx, &ids, bytes, type, columnName); + insertResultField(pQueryInfo, resColIdx, &ids, bytes, type, columnName, pExpr); return TSDB_CODE_SUCCESS; } -int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem) { +int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem, bool finalResult) { SMeterMetaInfo* pMeterMetaInfo = NULL; int32_t optr = pItem->pNode->nSQLOptr; @@ -1449,6 +1510,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt return TSDB_CODE_INVALID_SQL; } + SSqlExpr* pExpr = NULL; SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (pItem->pNode->pParam != NULL) { @@ -1469,7 +1531,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize; - tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size); + pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size); } else { // count the number of meters created according to the metric if (getColumnIndexByName(pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { @@ -1484,22 +1546,28 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt } int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize; - tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size); + pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size); } } else { // count(*) is equalled to count(primary_timestamp_key) index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize; - tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size); + pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size); } - - char columnName[TSDB_COL_NAME_LEN] = {0}; - getColumnName(pItem, columnName, TSDB_COL_NAME_LEN); - - // count always use the primary timestamp key column, which is 0. + + memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); + getColumnName(pItem, pExpr->aliasName, TSDB_COL_NAME_LEN); + SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex); - - insertResultField(pQueryInfo, colIdx, &ids, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, columnName); + if (finalResult) { + int32_t numOfOutput = tscNumOfFields(pQueryInfo); + insertResultField(pQueryInfo, numOfOutput, &ids, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->aliasName, pExpr); + } else { + for (int32_t i = 0; i < ids.num; ++i) { + tscColumnBaseInfoInsert(pQueryInfo, &(ids.ids[i])); + } + } + return TSDB_CODE_SUCCESS; } case TK_SUM: @@ -1543,9 +1611,6 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt return invalidSqlErrMsg(pQueryInfo->msg, msg1); } - char columnName[TSDB_COL_NAME_LEN] = {0}; - getColumnName(pItem, columnName, TSDB_COL_NAME_LEN); - int16_t resultType = 0; int16_t resultSize = 0; int16_t intermediateResSize = 0; @@ -1564,11 +1629,11 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt if (optr == TK_DIFF) { colIdx += 1; SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; - tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, + SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE); SColumnList ids = getColumnList(1, 0, 0); - insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName); + insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr); } // functions can not be applied to tags @@ -1598,8 +1663,18 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt SColumnList ids = {0}; ids.num = 1; ids.ids[0] = index; - - insertResultField(pQueryInfo, colIdx, &ids, pExpr->resBytes, pExpr->resType, columnName); + + memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); + getColumnName(pItem, pExpr->aliasName, TSDB_COL_NAME_LEN); + + if (finalResult) { + int32_t numOfOutput = tscNumOfFields(pQueryInfo); + insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, pExpr->resType, pExpr->aliasName, pExpr); + } else { + for (int32_t i = 0; i < ids.num; ++i) { + tscColumnBaseInfoInsert(pQueryInfo, &(ids.ids[i])); + } + } return TSDB_CODE_SUCCESS; } @@ -1701,10 +1776,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt if (pParamElem->pNode->nSQLOptr != TK_ID) { return invalidSqlErrMsg(pQueryInfo->msg, msg2); } - - char columnName[TSDB_COL_NAME_LEN] = {0}; - getColumnName(pItem, columnName, TSDB_COL_NAME_LEN); - + SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(&pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(pQueryInfo->msg, msg3); @@ -1735,7 +1807,8 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt int16_t resultSize = pSchema[index.columnIndex].bytes; char val[8] = {0}; - int32_t numOfAddedColumn = 1; + SSqlExpr* pExpr = NULL; + if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) { tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE); @@ -1757,7 +1830,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt return TSDB_CODE_INVALID_SQL; } - SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize); + pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize); addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0); } else { tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT); @@ -1774,22 +1847,30 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt // set the first column ts for top/bottom query SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE); + pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE); const int32_t TS_COLUMN_INDEX = 0; SColumnList ids = getColumnList(1, 0, TS_COLUMN_INDEX); insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, - aAggs[TSDB_FUNC_TS].aName); + aAggs[TSDB_FUNC_TS].aName, pExpr); colIdx += 1; // the first column is ts - numOfAddedColumn += 1; - SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize); + pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize); addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0); } - + + memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); + getColumnName(pItem, pExpr->aliasName, TSDB_COL_NAME_LEN); + SColumnList ids = getColumnList(1, 0, index.columnIndex); - insertResultField(pQueryInfo, colIdx, &ids, resultSize, resultType, columnName); + if (finalResult) { + insertResultField(pQueryInfo, colIdx, &ids, resultSize, resultType, pExpr->aliasName, pExpr); + } else { + for (int32_t i = 0; i < ids.num; ++i) { + tscColumnBaseInfoInsert(pQueryInfo, &(ids.ids[i])); + } + } return TSDB_CODE_SUCCESS; } @@ -1835,7 +1916,7 @@ static bool isTablenameToken(SSQLToken* token) { } static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SSQLToken* pToken) { - SMeterMeta* pMeterMeta = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, index)->pMeterMeta; + STableMeta* pMeterMeta = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, index)->pMeterMeta; int32_t numOfCols = pMeterMeta->numOfColumns + pMeterMeta->numOfTags; SSchema* pSchema = tsGetSchema(pMeterMeta); @@ -2036,7 +2117,7 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SSqlCmd* pCmd = &pSql->cmd; SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); assert(pCmd->numOfClause == 1); - + pCmd->command = TSDB_SQL_SHOW; const char* msg1 = "invalid name"; @@ -2085,7 +2166,7 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); } - if (pCmd->payloadLen > TSDB_METER_NAME_LEN) { + if (pCmd->payloadLen > TSDB_TABLE_NAME_LEN) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } } @@ -2166,16 +2247,17 @@ int32_t tscTansformSQLFunctionForSTableQuery(SQueryInfo* pQueryInfo) { int16_t type = 0; int16_t intermediateBytes = 0; - for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) { + for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); - TAOS_FIELD* pField = tscFieldInfoGetField(pQueryInfo, k); - int16_t functionId = aAggs[pExpr->functionId].stableFuncId; + int32_t colIndex = pExpr->colInfo.colIdx; + SSchema* pSrcSchema = tsGetColumnSchema(pMeterMetaInfo->pMeterMeta, colIndex); + if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) || (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) || (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) { - if (getResultDataInfo(pField->type, pField->bytes, functionId, pExpr->param[0].i64Key, &type, &bytes, + if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, pExpr->param[0].i64Key, &type, &bytes, &intermediateBytes, 0, true) != TSDB_CODE_SUCCESS) { return TSDB_CODE_INVALID_SQL; } @@ -2197,15 +2279,31 @@ void tscRestoreSQLFunctionForMetricQuery(SQueryInfo* pQueryInfo) { return; } - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - TAOS_FIELD* pField = tscFieldInfoGetField(pQueryInfo, i); - - if ((pExpr->functionId >= TSDB_FUNC_FIRST_DST && pExpr->functionId <= TSDB_FUNC_LAST_DST) || - (pExpr->functionId >= TSDB_FUNC_SUM && pExpr->functionId <= TSDB_FUNC_MAX)) { - pExpr->resBytes = pField->bytes; - pExpr->resType = pField->type; - } + SSchema* pSchema = tsGetColumnSchema(pMeterMetaInfo->pMeterMeta, pExpr->colInfo.colIdx); + +// if (/*(pExpr->functionId >= TSDB_FUNC_FIRST_DST && pExpr->functionId <= TSDB_FUNC_LAST_DST) || +// (pExpr->functionId >= TSDB_FUNC_SUM && pExpr->functionId <= TSDB_FUNC_MAX) || +// pExpr->functionId == TSDB_FUNC_LAST_ROW*/) { + // the final result size and type in the same as query on single table. + // so here, set the flag to be false; + int16_t inter = 0; + + int32_t functionId = pExpr->functionId; + if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { + continue; + } + + if (functionId == TSDB_FUNC_FIRST_DST) { + functionId = TSDB_FUNC_FIRST; + } else if (functionId == TSDB_FUNC_LAST_DST) { + functionId = TSDB_FUNC_LAST; + } + + getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->resType, &pExpr->resBytes, + &inter, 0, false); +// } } } @@ -2213,9 +2311,9 @@ bool hasUnsupportFunctionsForSTableQuery(SQueryInfo* pQueryInfo) { const char* msg1 = "TWA not allowed to apply to super table directly"; const char* msg2 = "TWA only support group by tbname for super table query"; const char* msg3 = "function not support for super table query"; - + // filter sql function not supported by metric query yet. - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_METRIC) == 0) { invalidSqlErrMsg(pQueryInfo->msg, msg3); @@ -2252,7 +2350,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo) { // diff function cannot be executed with other function // arithmetic function can be executed with other arithmetic functions - for (int32_t i = startIdx + 1; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = startIdx + 1; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); int16_t functionId = pExpr->functionId; @@ -2360,7 +2458,7 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* return invalidSqlErrMsg(pQueryInfo->msg, msg1); } - SMeterMeta* pMeterMeta = NULL; + STableMeta* pMeterMeta = NULL; SSchema* pSchema = NULL; SSchema s = tsGetTbnameColumnSchema(); @@ -2554,7 +2652,13 @@ static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) { } else if (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_STRING) { // value *str += tVariantToString(&pExpr->val, *str); - } else { + } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) { + /* + * arithmetic expression of aggregation, such as count(ts) + count(ts) *2 + */ + strncpy(*str, pExpr->operand.z, pExpr->operand.n); + *str += pExpr->operand.n; + } else { // not supported operation assert(false); } @@ -2679,7 +2783,7 @@ static int32_t tablenameListToString(tSQLExpr* pExpr, /*char* str*/ SStringBuild taosStringBuilderAppendString(sb, TBNAME_LIST_SEP); } - if (pSub->val.nLen <= 0 || pSub->val.nLen > TSDB_METER_NAME_LEN) { + if (pSub->val.nLen <= 0 || pSub->val.nLen > TSDB_TABLE_NAME_LEN) { return TSDB_CODE_INVALID_SQL; } } @@ -2704,7 +2808,7 @@ enum { static int32_t extractColumnFilterInfo(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, tSQLExpr* pExpr, int32_t sqlOptr) { SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, pIndex->tableIndex); - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; SSchema* pSchema = tsGetColumnSchema(pMeterMeta, pIndex->columnIndex); const char* msg1 = "non binary column not support like operator"; @@ -2867,7 +2971,7 @@ static int32_t getJoinCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) { pLeft->uid = pMeterMetaInfo->pMeterMeta->uid; pLeft->tagCol = tagColIndex; - strcpy(pLeft->meterId, pMeterMetaInfo->name); + strcpy(pLeft->tableId, pMeterMetaInfo->name); index = (SColumnIndex)COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(&pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { @@ -2879,7 +2983,7 @@ static int32_t getJoinCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) { pRight->uid = pMeterMetaInfo->pMeterMeta->uid; pRight->tagCol = tagColIndex; - strcpy(pRight->meterId, pMeterMetaInfo->name); + strcpy(pRight->tableId, pMeterMetaInfo->name); pTagCond->joinInfo.hasJoin = true; return TSDB_CODE_SUCCESS; @@ -2890,8 +2994,7 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) { tSQLExpr* pLeft = pExpr->pLeft; tSQLExpr* pRight = pExpr->pRight; - *(*exprString) = '('; - *exprString += 1; + *(*exprString)++ = '('; if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) { buildArithmeticExprString(pLeft, exprString); @@ -2913,50 +3016,67 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) { } } - *(*exprString) = ')'; - *exprString += 1; + *(*exprString)++ = ')'; return TSDB_CODE_SUCCESS; } -static int32_t validateSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList) { +static int32_t validateSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) { if (pExpr->nSQLOptr == TK_ID) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_INVALID_SQL; - } + if (*type == NON_ARITHMEIC_EXPR) { + *type = NORMAL_ARITHMETIC; + } else if (*type == AGG_ARIGHTMEIC) { + return TSDB_CODE_INVALID_SQL; + } - // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql - SMeterMeta* pMeterMeta = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, index.tableIndex)->pMeterMeta; - SSchema* pSchema = tsGetSchema(pMeterMeta) + index.columnIndex; - if ((pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || (pSchema->type == TSDB_DATA_TYPE_BOOL) - || (pSchema->type == TSDB_DATA_TYPE_BINARY) || (pSchema->type == TSDB_DATA_TYPE_NCHAR)){ - return TSDB_CODE_INVALID_SQL; - } - - pList->ids[pList->num++] = index; + SColumnIndex index = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_INVALID_SQL; + } + + // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql + STableMeta* pMeterMeta = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, index.tableIndex)->pMeterMeta; + SSchema* pSchema = tsGetSchema(pMeterMeta) + index.columnIndex; + if ((pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || (pSchema->type == TSDB_DATA_TYPE_BOOL) || + (pSchema->type == TSDB_DATA_TYPE_BINARY) || (pSchema->type == TSDB_DATA_TYPE_NCHAR)) { + return TSDB_CODE_INVALID_SQL; + } + + pList->ids[pList->num++] = index; } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) { return TSDB_CODE_INVALID_SQL; - } else if (pExpr->nSQLOptr >= TK_MIN && pExpr->nSQLOptr <= TK_AVG_IRATE) { - return TSDB_CODE_INVALID_SQL; + } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) { + if (*type == NON_ARITHMEIC_EXPR) { + *type = AGG_ARIGHTMEIC; + } else if (*type == NORMAL_ARITHMETIC) { + return TSDB_CODE_INVALID_SQL; + } + + int32_t outputIndex = pQueryInfo->exprsInfo.numOfExprs; + tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL}; + + // sql function in selection clause, append sql function info in pSqlCmd structure sequentially + if (addExprAndResultField(pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_INVALID_SQL; + } } return TSDB_CODE_SUCCESS; } -static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList) { +static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } tSQLExpr* pLeft = pExpr->pLeft; if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) { - int32_t ret = validateArithmeticSQLExpr(pLeft, pQueryInfo, pList); + int32_t ret = validateArithmeticSQLExpr(pLeft, pQueryInfo, pList, type); if (ret != TSDB_CODE_SUCCESS) { return ret; } } else { - int32_t ret = validateSQLExpr(pLeft, pQueryInfo, pList); + int32_t ret = validateSQLExpr(pLeft, pQueryInfo, pList, type); if (ret != TSDB_CODE_SUCCESS) { return ret; } @@ -2964,12 +3084,12 @@ static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo tSQLExpr* pRight = pExpr->pRight; if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) { - int32_t ret = validateArithmeticSQLExpr(pRight, pQueryInfo, pList); + int32_t ret = validateArithmeticSQLExpr(pRight, pQueryInfo, pList, type); if (ret != TSDB_CODE_SUCCESS) { return ret; } } else { - int32_t ret = validateSQLExpr(pRight, pQueryInfo, pList); + int32_t ret = validateSQLExpr(pRight, pQueryInfo, pList, type); if (ret != TSDB_CODE_SUCCESS) { return ret; } @@ -3140,7 +3260,7 @@ static int32_t handleExprInQueryCond(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, S assert(isExprDirectParentOfLeaftNode(*pExpr)); SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, index.tableIndex); - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range if (!validateJoinExprNode(pQueryInfo, *pExpr, &index)) { @@ -3485,7 +3605,7 @@ static int32_t getTimeRangeFromExpr(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) { } SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, index.tableIndex); - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; tSQLExpr* pRight = pExpr->pRight; @@ -3771,6 +3891,7 @@ int32_t getTimeRange(int64_t* stime, int64_t* etime, tSQLExpr* pRight, int32_t o return TSDB_CODE_SUCCESS; } +// todo error !!!! int32_t tsRewriteFieldNameIfNecessary(SQueryInfo* pQueryInfo) { const char rep[] = {'(', ')', '*', ',', '.', '/', '\\', '+', '-', '%', ' '}; @@ -3817,7 +3938,7 @@ int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) { } if (pQueryInfo->defaultVal == NULL) { - pQueryInfo->defaultVal = calloc(pQueryInfo->fieldsInfo.numOfOutputCols, sizeof(int64_t)); + pQueryInfo->defaultVal = calloc(pQueryInfo->exprsInfo.numOfExprs, sizeof(int64_t)); if (pQueryInfo->defaultVal == NULL) { return TSDB_CODE_CLI_OUT_OF_MEMORY; } @@ -3827,7 +3948,7 @@ int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) { pQueryInfo->interpoType = TSDB_INTERPO_NONE; } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) { pQueryInfo->interpoType = TSDB_INTERPO_NULL; - for (int32_t i = START_INTERPO_COL_IDX; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = START_INTERPO_COL_IDX; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { TAOS_FIELD* pFields = tscFieldInfoGetField(pQueryInfo, i); setNull((char*)&pQueryInfo->defaultVal[i], pFields->type, pFields->bytes); } @@ -3849,12 +3970,12 @@ int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) { if (tscIsPointInterpQuery(pQueryInfo)) { startPos = 0; - if (numOfFillVal > pQueryInfo->fieldsInfo.numOfOutputCols) { - numOfFillVal = pQueryInfo->fieldsInfo.numOfOutputCols; + if (numOfFillVal > pQueryInfo->exprsInfo.numOfExprs) { + numOfFillVal = pQueryInfo->exprsInfo.numOfExprs; } } else { - numOfFillVal = (pFillToken->nExpr > pQueryInfo->fieldsInfo.numOfOutputCols) - ? pQueryInfo->fieldsInfo.numOfOutputCols + numOfFillVal = (pFillToken->nExpr > pQueryInfo->exprsInfo.numOfExprs) + ? pQueryInfo->exprsInfo.numOfExprs : pFillToken->nExpr; } @@ -3862,28 +3983,29 @@ int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) { for (int32_t i = startPos; i < numOfFillVal; ++i, ++j) { TAOS_FIELD* pFields = tscFieldInfoGetField(pQueryInfo, i); - + if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) { setNull((char*)(&pQueryInfo->defaultVal[i]), pFields->type, pFields->bytes); continue; } - + int32_t ret = tVariantDump(&pFillToken->a[j].pVar, (char*)&pQueryInfo->defaultVal[i], pFields->type); if (ret != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(pQueryInfo->msg, msg); } } - if ((pFillToken->nExpr < pQueryInfo->fieldsInfo.numOfOutputCols) || - ((pFillToken->nExpr - 1 < pQueryInfo->fieldsInfo.numOfOutputCols) && (tscIsPointInterpQuery(pQueryInfo)))) { + if ((pFillToken->nExpr < pQueryInfo->exprsInfo.numOfExprs) || + ((pFillToken->nExpr - 1 < pQueryInfo->exprsInfo.numOfExprs) && (tscIsPointInterpQuery(pQueryInfo)))) { tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1]; - for (int32_t i = numOfFillVal; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = numOfFillVal; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { TAOS_FIELD* pFields = tscFieldInfoGetField(pQueryInfo, i); - tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->defaultVal[i], pFields->type); if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) { setNull((char*)(&pQueryInfo->defaultVal[i]), pFields->type, pFields->bytes); + } else { + tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->defaultVal[i], pFields->type); } } } @@ -4086,7 +4208,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { return ret; } - SMeterMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta* pMeterMeta = pMeterMetaInfo->pMeterMeta; if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) { @@ -4277,11 +4399,11 @@ int32_t validateSqlFunctionInStreamSql(SQueryInfo* pQueryInfo) { const char* msg0 = "sample interval can not be less than 10ms."; const char* msg1 = "functions not allowed in select clause"; - if (pQueryInfo->nAggTimeInterval != 0 && pQueryInfo->nAggTimeInterval < 10) { + if (pQueryInfo->intervalTime != 0 && pQueryInfo->intervalTime < 10) { return invalidSqlErrMsg(pQueryInfo->msg, msg0); } - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId; if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) { return invalidSqlErrMsg(pQueryInfo->msg, msg1); @@ -4296,13 +4418,13 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SQueryInfo* pQueryInfo) { const char* msg1 = "column projection is not compatible with interval"; // multi-output set/ todo refactor - for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) { + for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); // projection query on primary timestamp, the selectivity function needs to be present. if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { bool hasSelectivity = false; - for (int32_t j = 0; j < pQueryInfo->fieldsInfo.numOfOutputCols; ++j) { + for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) { SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j); if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) { hasSelectivity = true; @@ -4470,13 +4592,15 @@ int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* const char* msg1 = "slimit/soffset only available for STable query"; const char* msg2 = "function not supported on table"; const char* msg3 = "slimit/soffset can not apply to projection query"; - + // handle the limit offset value, validate the limit pQueryInfo->limit = pQuerySql->limit; pQueryInfo->clauseLimit = pQueryInfo->limit.limit; - pQueryInfo->slimit = pQuerySql->slimit; - + + tscTrace("%p limit:%d, offset:%" PRId64 " slimit:%d, soffset:%" PRId64, pSql, pQueryInfo->limit.limit, + pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset); + if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) { return invalidSqlErrMsg(pQueryInfo->msg, msg0); } @@ -4500,24 +4624,16 @@ int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) { return invalidSqlErrMsg(pQueryInfo->msg, msg3); } - + + // for projection query on super table, all queries are subqueries if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { -// if (pQueryInfo->order.orderColId >= 0) { -// if (pQueryInfo->limit.limit == -1) { -// return invalidSqlErrMsg(pQueryInfo->msg, msg4); -// } else if (pQueryInfo->limit.limit > 10000) { // the result set can not be larger than 10000 -// //todo use global config parameter -// return invalidSqlErrMsg(pQueryInfo->msg, msg5); -// } -// } - - pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY; // for projection query on super table, all queries are subqueries + pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY; } } } if (pQueryInfo->slimit.limit == 0) { - tscTrace("%p limit 0, no output result", pSql); + tscTrace("%p slimit 0, no output result", pSql); pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; return TSDB_CODE_SUCCESS; } @@ -4534,8 +4650,8 @@ int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* } // No tables included. No results generated. Query results are empty. - SMetricMeta* pMetricMeta = pMeterMetaInfo->pMetricMeta; - if (pMeterMetaInfo->pMeterMeta == NULL || pMetricMeta == NULL || pMetricMeta->numOfMeters == 0) { + SSuperTableMeta* pMetricMeta = pMeterMetaInfo->pMetricMeta; + if (pMeterMetaInfo->pMeterMeta == NULL || pMetricMeta == NULL || pMetricMeta->numOfTables == 0) { tscTrace("%p no table in metricmeta, no output result", pSql); pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; } @@ -4543,7 +4659,7 @@ int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* // keep original limitation value in globalLimit pQueryInfo->clauseLimit = pQueryInfo->limit.limit; pQueryInfo->prjOffset = pQueryInfo->limit.offset; - + if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { /* * the limitation/offset value should be removed during retrieve data from virtual node, @@ -4553,7 +4669,7 @@ int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* if (pQueryInfo->limit.limit > 0) { pQueryInfo->limit.limit = -1; } - + pQueryInfo->limit.offset = 0; } } else { @@ -4562,7 +4678,7 @@ int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* } // filter the query functions operating on "tbname" column that are not supported by normal columns. - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX) { return invalidSqlErrMsg(pQueryInfo->msg, msg2); @@ -4629,7 +4745,7 @@ static int32_t setTimePrecisionOption(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreate } static void setCreateDBOption(SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) { - pMsg->blocksPerMeter = htons(pCreateDb->numOfBlocksPerTable); + pMsg->blocksPerTable = htons(pCreateDb->numOfBlocksPerTable); pMsg->compression = pCreateDb->compressionLevel; pMsg->commitLog = (char)pCreateDb->commitLog; @@ -4643,7 +4759,7 @@ static void setCreateDBOption(SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) { } int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) { - SCreateDbMsg* pMsg = (SCreateDbMsg*)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead)); + SCreateDbMsg* pMsg = (SCreateDbMsg*)(pCmd->payload); setCreateDBOption(pMsg, pCreateDbSql); if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) { @@ -4677,7 +4793,7 @@ void tscAddTimestampColumn(SQueryInfo* pQueryInfo, int16_t functionId, int16_t t // NOTE: tag column does not add to source column list SColumnList ids = getColumnList(1, tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX); - insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, "ts"); + insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, "ts", pExpr); } } @@ -4700,13 +4816,13 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau int16_t bytes = pSchema[index.columnIndex].bytes; char* name = pSchema[index.columnIndex].name; - pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->fieldsInfo.numOfOutputCols, TSDB_FUNC_TAG, &index, type, bytes, + pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_TAG, &index, type, bytes, bytes); pExpr->colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list SColumnList ids = {0}; - insertResultField(pQueryInfo, pQueryInfo->fieldsInfo.numOfOutputCols, &ids, bytes, type, name); + insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, &ids, bytes, type, name, pExpr); int32_t relIndex = index.columnIndex; @@ -4721,7 +4837,7 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau // limit the output to be 1 for each state value static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) { int32_t outputRow = 1; - tVariantCreateFromBinary(&pExpr->param[0], (char*) &outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT); + tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT); pExpr->numOfParams = 1; } @@ -4733,25 +4849,25 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) { SSchema* pSchema = tsGetColumnSchema(pMeterMetaInfo->pMeterMeta, index); SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = index}; - SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->fieldsInfo.numOfOutputCols, TSDB_FUNC_PRJ, &colIndex, + SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_PRJ, &colIndex, pSchema->type, pSchema->bytes, pSchema->bytes); pExpr->colInfo.flag = TSDB_COL_NORMAL; doLimitOutputNormalColOfGroupby(pExpr); - + // NOTE: tag column does not add to source column list SColumnList list = {0}; list.num = 1; list.ids[0] = colIndex; - insertResultField(pQueryInfo, pQueryInfo->fieldsInfo.numOfOutputCols, &list, pSchema->bytes, pSchema->type, - pSchema->name); - tscFieldInfoUpdateVisible(&pQueryInfo->fieldsInfo, pQueryInfo->fieldsInfo.numOfOutputCols - 1, false); + insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs - 1, &list, pSchema->bytes, pSchema->type, + pSchema->name, pExpr); + tscFieldInfoUpdateVisible(&pQueryInfo->fieldsInfo, pQueryInfo->exprsInfo.numOfExprs - 1, false); } static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { int32_t tagLength = 0; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId == TSDB_FUNC_TAGPRJ || pExpr->functionId == TSDB_FUNC_TAG) { pExpr->functionId = TSDB_FUNC_TAG_DUMMY; @@ -4765,7 +4881,7 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); SSchema* pSchema = tsGetSchema(pMeterMetaInfo->pMeterMeta); - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) { SSchema* pColSchema = &pSchema[pExpr->colInfo.colIdx]; @@ -4776,7 +4892,7 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { } static void doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId == TSDB_FUNC_PRJ) { bool qualifiedCol = false; @@ -4808,7 +4924,7 @@ static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) { bool hasTagPrj = false; bool hasColumnPrj = false; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId == TSDB_FUNC_PRJ) { hasColumnPrj = true; @@ -4824,7 +4940,7 @@ static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) { static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) { bool allInGroupby = true; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId != TSDB_FUNC_TAGPRJ) { continue; @@ -4841,7 +4957,7 @@ static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) { } static void updateTagPrjFunction(SQueryInfo* pQueryInfo) { - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId == TSDB_FUNC_TAGPRJ) { pExpr->functionId = TSDB_FUNC_TAG; @@ -4863,7 +4979,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo) { int16_t numOfSelectivity = 0; int16_t numOfAggregation = 0; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId == TSDB_FUNC_TAGPRJ || (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { @@ -4872,7 +4988,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo) { } } - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_ARITHM) { @@ -4904,7 +5020,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo) { * If more than one selectivity functions exist, all the selectivity functions must be last_row. * Otherwise, return with error code. */ - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; if (functionId == TSDB_FUNC_TAGPRJ) { continue; @@ -4951,7 +5067,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SQueryInfo* pQueryInfo) { int16_t colIndex = pColIndex->colIdx; if (pColIndex->colIdx == TSDB_TBNAME_COLUMN_INDEX) { type = TSDB_DATA_TYPE_BINARY; - bytes = TSDB_METER_NAME_LEN; + bytes = TSDB_TABLE_NAME_LEN; name = TSQL_TBNAME_L; } else { colIndex = (TSDB_COL_IS_TAG(pColIndex->flag)) ? pMeterMetaInfo->pMeterMeta->numOfColumns + pColIndex->colIdx @@ -4965,22 +5081,22 @@ static int32_t doAddGroupbyColumnsOnDemand(SQueryInfo* pQueryInfo) { if (TSDB_COL_IS_TAG(pColIndex->flag)) { SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; - SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->fieldsInfo.numOfOutputCols, TSDB_FUNC_TAG, &index, + SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_TAG, &index, type, bytes, bytes); pExpr->colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list SColumnList ids = {0}; - insertResultField(pQueryInfo, pQueryInfo->fieldsInfo.numOfOutputCols, &ids, bytes, type, name); + insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs-1, &ids, bytes, type, name, pExpr); } else { // if this query is "group by" normal column, interval is not allowed - if (pQueryInfo->nAggTimeInterval > 0) { + if (pQueryInfo->intervalTime > 0) { return invalidSqlErrMsg(pQueryInfo->msg, msg2); } bool hasGroupColumn = false; - for (int32_t j = 0; j < pQueryInfo->fieldsInfo.numOfOutputCols; ++j) { + for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j); if (pExpr->colInfo.colId == pColIndex->colId) { break; @@ -5008,7 +5124,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { // only retrieve tags, group by is not supportted if (pCmd->command == TSDB_SQL_RETRIEVE_TAGS) { - if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->nAggTimeInterval > 0) { + if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); } else { return TSDB_CODE_SUCCESS; @@ -5023,7 +5139,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { } // check all query functions in selection clause, multi-output functions are not allowed - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); int32_t functId = pExpr->functionId; @@ -5111,11 +5227,8 @@ int32_t doLocalQueryProcess(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) { } SSqlExpr* pExpr1 = tscSqlExprInsertEmpty(pQueryInfo, 0, TSDB_FUNC_TAG_DUMMY); - if (pExprList->a[0].aliasName != NULL) { - strncpy(pExpr1->aliasName, pExprList->a[0].aliasName, tListLen(pExpr1->aliasName)); - } else { - strncpy(pExpr1->aliasName, functionsInfo[index].name, tListLen(pExpr1->aliasName)); - } + const char* name = (pExprList->a[0].aliasName != NULL)? pExprList->a[0].aliasName:functionsInfo[index].name; + strncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName)); switch (index) { case 0: @@ -5220,8 +5333,8 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { } int32_t totalBufSize = 1024; - - char str[1024] = {0}; + + char str[1024] = {0}; int32_t offset = 0; offset += sprintf(str, "num:%d [", pQueryInfo->exprsInfo.numOfExprs); @@ -5229,12 +5342,13 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); char tmpBuf[1024] = {0}; - int32_t tmpLen = 0; - tmpLen = sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId); + int32_t tmpLen = 0; + tmpLen = + sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId); if (tmpLen + offset > totalBufSize) break; offset += sprintf(str + offset, "%s", tmpBuf); - + if (i < pQueryInfo->exprsInfo.numOfExprs - 1) { str[offset++] = ','; } @@ -5424,7 +5538,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { if (parseIntervalClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) { return TSDB_CODE_INVALID_SQL; } else { - if ((pQueryInfo->nAggTimeInterval > 0) && + if ((pQueryInfo->intervalTime > 0) && (validateFunctionsInIntervalOrGroupbyQuery(pQueryInfo) != TSDB_CODE_SUCCESS)) { return TSDB_CODE_INVALID_SQL; } @@ -5454,7 +5568,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { * not here. */ if (pQuerySql->fillType != NULL) { - if (pQueryInfo->nAggTimeInterval == 0) { + if (pQueryInfo->intervalTime == 0) { return invalidSqlErrMsg(pQueryInfo->msg, msg3); } @@ -5493,7 +5607,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { if (pMeterMetaInfo == NULL) { pMeterMetaInfo = tscAddEmptyMeterMetaInfo(pQueryInfo); } - + // too many result columns not support order by in query if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); @@ -5517,7 +5631,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { } pQueryInfo->command = TSDB_SQL_SELECT; - + // set all query tables, which are maybe more than one. for (int32_t i = 0; i < pQuerySql->from->nExpr; ++i) { tVariant* pTableItem = &pQuerySql->from->a[i].pVar; @@ -5566,7 +5680,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { if (parseIntervalClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) { return TSDB_CODE_INVALID_SQL; } else { - if ((pQueryInfo->nAggTimeInterval > 0) && + if ((pQueryInfo->intervalTime > 0) && (validateFunctionsInIntervalOrGroupbyQuery(pQueryInfo) != TSDB_CODE_SUCCESS)) { return TSDB_CODE_INVALID_SQL; } @@ -5603,7 +5717,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { // no result due to invalid query time range if (pQueryInfo->stime > pQueryInfo->etime) { - pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; + pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; return TSDB_CODE_SUCCESS; } @@ -5633,24 +5747,24 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { updateTagColumnIndex(pQueryInfo, i); } - + /* * fill options are set at the end position, when all columns are set properly * the columns may be increased due to group by operation */ if (pQuerySql->fillType != NULL) { - if (pQueryInfo->nAggTimeInterval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) { + if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); } - - if (pQueryInfo->nAggTimeInterval > 0) { + + if (pQueryInfo->intervalTime > 0) { int64_t timeRange = labs(pQueryInfo->stime - pQueryInfo->etime); // number of result is not greater than 10,000,000 - if ((timeRange == 0) || (timeRange / pQueryInfo->nAggTimeInterval) > MAX_RETRIEVE_ROWS_IN_INTERVAL_QUERY) { + if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_RETRIEVE_ROWS_IN_INTERVAL_QUERY) { return invalidSqlErrMsg(pQueryInfo->msg, msg6); } } - + int32_t ret = parseFillClause(pQueryInfo, pQuerySql); if (ret != TSDB_CODE_SUCCESS) { return ret; @@ -5660,7 +5774,80 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { return TSDB_CODE_SUCCESS; // Does not build query message here } -bool hasDefaultQueryTimeRange(SQueryInfo *pQueryInfo) { - return (pQueryInfo->stime == 0 && pQueryInfo->etime == INT64_MAX) || - (pQueryInfo->stime == INT64_MAX && pQueryInfo->etime == 0); +static int32_t tSQLBinaryExprCreateFromSqlExpr(tSQLSyntaxNode **pExpr, tSQLExpr* pAst, int32_t* num, + SColIndexEx** pColIndex, SSqlExprInfo* pExprInfo) { + tSQLSyntaxNode* pLeft = NULL; + tSQLSyntaxNode* pRight= NULL; + + if (pAst->pLeft != NULL) { + int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pLeft, pAst->pLeft, num, pColIndex, pExprInfo); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + } + + if (pAst->pRight != NULL) { + int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pRight, pAst->pRight, num, pColIndex, pExprInfo); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + } + + if (pAst->pLeft == NULL) { + if (pAst->nSQLOptr >= TK_TINYINT && pAst->nSQLOptr <= TK_DOUBLE) { + *pExpr = calloc(1, sizeof(tSQLSyntaxNode) + sizeof(tVariant)); + (*pExpr)->nodeType = TSQL_NODE_VALUE; + (*pExpr)->pVal = (tVariant*) ((char*)(*pExpr) + sizeof(tSQLSyntaxNode)); + tVariantAssign((*pExpr)->pVal, &pAst->val); + } else if (pAst->nSQLOptr >= TK_COUNT && pAst->nSQLOptr <= TK_AVG_IRATE) { + *pExpr = calloc(1, sizeof(tSQLSyntaxNode) + sizeof(SSchemaEx)); + (*pExpr)->nodeType = TSQL_NODE_COL; + (*pExpr)->pSchema = (SSchema*)((char*)(*pExpr) + sizeof(tSQLSyntaxNode)); + strncpy((*pExpr)->pSchema->name, pAst->operand.z, pAst->operand.n); + + // set the input column data byte and type. + for (int32_t i = 0; i < pExprInfo->numOfExprs; ++i) { + if (strcmp((*pExpr)->pSchema->name, pExprInfo->pExprs[i]->aliasName) == 0) { + (*pExpr)->pSchema->type = pExprInfo->pExprs[i]->resType; + (*pExpr)->pSchema->bytes = pExprInfo->pExprs[i]->resBytes; + break; + } + } + } else { //todo return error + return TSDB_CODE_SUCCESS; + } + + (*pExpr)->colId = -1; + + *pColIndex = realloc(*pColIndex, (++(*num)) * sizeof(SColIndexEx)); + memset(&(*pColIndex)[(*num) - 1], 0, sizeof(SColIndexEx)); + + strncpy((*pColIndex)[(*num) - 1].name, pAst->operand.z, pAst->operand.n); + } else { + tSQLBinaryExpr *pBinExpr = (tSQLBinaryExpr *)calloc(1, sizeof(tSQLBinaryExpr)); + pBinExpr->filterOnPrimaryKey = false; + pBinExpr->pLeft = pLeft; + pBinExpr->pRight = pRight; + SSQLToken t = {.type = pAst->nSQLOptr}; + pBinExpr->nSQLBinaryOptr = getBinaryExprOptr(&t); + + assert(pBinExpr->nSQLBinaryOptr != 0); + + (*pExpr) = malloc(sizeof(tSQLSyntaxNode)); + (*pExpr)->nodeType = TSQL_NODE_EXPR; + (*pExpr)->pExpr = pBinExpr; + (*pExpr)->colId = -1; + + if (pBinExpr->nSQLBinaryOptr == TSDB_BINARY_OP_DIVIDE) { + if (pRight->nodeType == TSQL_NODE_VALUE) { + if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) { + return TSDB_CODE_INVALID_SQL; + } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) { + return TSDB_CODE_INVALID_SQL; + } + } + } + } + + return TSDB_CODE_SUCCESS; } diff --git a/src/client/src/tscSchemaUtil.c b/src/client/src/tscSchemaUtil.c index 648c25657cf4e60549ed9a60b702aea9d8f1445a..605b77a796421cba4902232b8fa584909ac8ff76 100644 --- a/src/client/src/tscSchemaUtil.c +++ b/src/client/src/tscSchemaUtil.c @@ -64,14 +64,14 @@ bool isValidSchema(struct SSchema* pSchema, int32_t numOfCols) { return (rowLen <= TSDB_MAX_BYTES_PER_ROW); } -struct SSchema* tsGetSchema(SMeterMeta* pMeta) { +struct SSchema* tsGetSchema(STableMeta* pMeta) { if (pMeta == NULL) { return NULL; } return tsGetColumnSchema(pMeta, 0); } -struct SSchema* tsGetTagSchema(SMeterMeta* pMeta) { +struct SSchema* tsGetTagSchema(STableMeta* pMeta) { if (pMeta == NULL || pMeta->numOfTags == 0) { return NULL; } @@ -79,12 +79,12 @@ struct SSchema* tsGetTagSchema(SMeterMeta* pMeta) { return tsGetColumnSchema(pMeta, pMeta->numOfColumns); } -struct SSchema* tsGetColumnSchema(SMeterMeta* pMeta, int32_t startCol) { - return (SSchema*)(((char*)pMeta + sizeof(SMeterMeta)) + startCol * sizeof(SSchema)); +struct SSchema* tsGetColumnSchema(STableMeta* pMeta, int32_t startCol) { + return (SSchema*)(((char*)pMeta + sizeof(STableMeta)) + startCol * sizeof(SSchema)); } struct SSchema tsGetTbnameColumnSchema() { - struct SSchema s = {.colId = TSDB_TBNAME_COLUMN_INDEX, .type = TSDB_DATA_TYPE_BINARY, .bytes = TSDB_METER_NAME_LEN}; + struct SSchema s = {.colId = TSDB_TBNAME_COLUMN_INDEX, .type = TSDB_DATA_TYPE_BINARY, .bytes = TSDB_TABLE_NAME_LEN}; strcpy(s.name, TSQL_TBNAME_L); return s; @@ -94,7 +94,7 @@ struct SSchema tsGetTbnameColumnSchema() { * the MeterMeta data format in memory is as follows: * * +--------------------+ - * |SMeterMeta Body data| sizeof(SMeterMeta) + * |STableMeta Body data| sizeof(STableMeta) * +--------------------+ * |Schema data | numOfTotalColumns * sizeof(SSchema) * +--------------------+ @@ -104,14 +104,14 @@ struct SSchema tsGetTbnameColumnSchema() { * @param pMeta * @return */ -char* tsGetTagsValue(SMeterMeta* pMeta) { +char* tsGetTagsValue(STableMeta* pMeta) { int32_t numOfTotalCols = pMeta->numOfColumns + pMeta->numOfTags; - uint32_t offset = sizeof(SMeterMeta) + numOfTotalCols * sizeof(SSchema); + uint32_t offset = sizeof(STableMeta) + numOfTotalCols * sizeof(SSchema); return ((char*)pMeta + offset); } -bool tsMeterMetaIdentical(SMeterMeta* p1, SMeterMeta* p2) { +bool tsMeterMetaIdentical(STableMeta* p1, STableMeta* p2) { if (p1 == NULL || p2 == NULL || p1->uid != p2->uid || p1->sversion != p2->sversion) { return false; } @@ -120,7 +120,7 @@ bool tsMeterMetaIdentical(SMeterMeta* p1, SMeterMeta* p2) { return true; } - size_t size = sizeof(SMeterMeta) + p1->numOfColumns * sizeof(SSchema); + size_t size = sizeof(STableMeta) + p1->numOfColumns * sizeof(SSchema); for (int32_t i = 0; i < p1->numOfTags; ++i) { SSchema* pColSchema = tsGetColumnSchema(p1, i + p1->numOfColumns); @@ -151,16 +151,16 @@ static FORCE_INLINE size_t copy(char* dst, const char* src, char delimiter) { /** * extract table name from meterid, which the format of userid.dbname.metername - * @param meterId + * @param tableId * @return */ -void extractTableName(char* meterId, char* name) { - char* r = skipSegments(meterId, TS_PATH_DELIMITER[0], 2); +void extractTableName(char* tableId, char* name) { + char* r = skipSegments(tableId, TS_PATH_DELIMITER[0], 2); copy(name, r, TS_PATH_DELIMITER[0]); } -SSQLToken extractDBName(char* meterId, char* name) { - char* r = skipSegments(meterId, TS_PATH_DELIMITER[0], 1); +SSQLToken extractDBName(char* tableId, char* name) { + char* r = skipSegments(tableId, TS_PATH_DELIMITER[0], 1); size_t len = copy(name, r, TS_PATH_DELIMITER[0]); SSQLToken token = {.z = name, .n = len, .type = TK_STRING}; diff --git a/src/client/src/tscSecondaryMerge.c b/src/client/src/tscSecondaryMerge.c index ca57030539a451d4967ace21fc688a1e44ffea76..51a59005f001f7555a3ffc2e5c7e15ed111af988 100644 --- a/src/client/src/tscSecondaryMerge.c +++ b/src/client/src/tscSecondaryMerge.c @@ -13,10 +13,11 @@ * along with this program. If not, see . */ +#include "tscSecondaryMerge.h" #include "os.h" #include "tlosertree.h" -#include "tscSecondaryMerge.h" #include "tscUtil.h" +#include "tschemautil.h" #include "tsclient.h" #include "tutil.h" @@ -58,40 +59,37 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SSqlRes *pRes, SLocalReducer *pRedu * the fields and offset attributes in pCmd and pModel may be different due to * merge requirement. So, the final result in pRes structure is formatted in accordance with the pCmd object. */ - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SQLFunctionCtx *pCtx = &pReducer->pCtx[i]; + SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i); - pCtx->aOutputBuf = pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->capacity; + pCtx->aOutputBuf = + pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->capacity; pCtx->order = pQueryInfo->order.order; - pCtx->functionId = pQueryInfo->exprsInfo.pExprs[i].functionId; + pCtx->functionId = pExpr->functionId; // input buffer hold only one point data - int16_t offset = getColumnModelOffset(pDesc->pColumnModel, i); - SSchema* pSchema = getColumnModelSchema(pDesc->pColumnModel, i); - + int16_t offset = getColumnModelOffset(pDesc->pColumnModel, i); + SSchema *pSchema = getColumnModelSchema(pDesc->pColumnModel, i); + pCtx->aInputElemBuf = pReducer->pTempBuffer->data + offset; // input data format comes from pModel pCtx->inputType = pSchema->type; pCtx->inputBytes = pSchema->bytes; - TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); // output data format yet comes from pCmd. - pCtx->outputBytes = pField->bytes; - pCtx->outputType = pField->type; + pCtx->outputBytes = pExpr->resBytes; + pCtx->outputType = pExpr->resType; pCtx->startOffset = 0; pCtx->size = 1; pCtx->hasNull = true; pCtx->currentStage = SECONDARY_STAGE_MERGE; - pRes->bytes[i] = pField->bytes; - - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - // for top/bottom function, the output of timestamp is the first column - int32_t functionId = pExpr->functionId; + int32_t functionId = pExpr->functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { pCtx->ptsOutputBuf = pReducer->pCtx[0].aOutputBuf; pCtx->param[2].i64Key = pQueryInfo->order.order; @@ -107,12 +105,12 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SSqlRes *pRes, SLocalReducer *pRedu pCtx->resultInfo->superTableQ = true; } - int16_t n = 0; - int16_t tagLen = 0; - SQLFunctionCtx** pTagCtx = calloc(pQueryInfo->fieldsInfo.numOfOutputCols, POINTER_BYTES); + int16_t n = 0; + int16_t tagLen = 0; + SQLFunctionCtx **pTagCtx = calloc(pQueryInfo->fieldsInfo.numOfOutputCols, POINTER_BYTES); - SQLFunctionCtx* pCtx = NULL; - for(int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + SQLFunctionCtx *pCtx = NULL; + for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId == TSDB_FUNC_TAG_DUMMY || pExpr->functionId == TSDB_FUNC_TS_DUMMY) { tagLen += pExpr->resBytes; @@ -218,12 +216,12 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd #ifdef _DEBUG_VIEW printf("load data page into mem for build loser tree: %" PRIu64 " rows\n", pDS->filePage.numOfElems); SSrcColumnInfo colInfo[256] = {0}; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); tscGetSrcColumnInfo(colInfo, pQueryInfo); - tColModelDisplayEx(pDesc->pColumnModel, pDS->filePage.data, pDS->filePage.numOfElems, pMemBuffer[0]->numOfElemsPerPage, - colInfo); + tColModelDisplayEx(pDesc->pColumnModel, pDS->filePage.data, pDS->filePage.numOfElems, + pMemBuffer[0]->numOfElemsPerPage, colInfo); #endif if (pDS->filePage.numOfElems == 0) { // no data in this flush tscTrace("%p flush data is empty, ignore %d flush record", pSqlObjAddr, idx); @@ -244,8 +242,8 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd param->pLocalData = pReducer->pLocalDataSrc; param->pDesc = pReducer->pDesc; param->numOfElems = pReducer->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + param->groupOrderType = pQueryInfo->groupbyExpr.orderType; pRes->code = tLoserTreeCreate(&pReducer->pLoserTree, pReducer->numOfBuffer, param, treeComparator); @@ -255,7 +253,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd // the input data format follows the old format, but output in a new format. // so, all the input must be parsed as old format - pReducer->pCtx = (SQLFunctionCtx *)calloc(pQueryInfo->fieldsInfo.numOfOutputCols, sizeof(SQLFunctionCtx)); + pReducer->pCtx = (SQLFunctionCtx *)calloc(pQueryInfo->exprsInfo.numOfExprs, sizeof(SQLFunctionCtx)); pReducer->rowSize = pMemBuffer[0]->nElemSize; @@ -279,7 +277,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd pReducer->nResultBufSize = pMemBuffer[0]->pageSize * 16; pReducer->pResultBuf = (tFilePage *)calloc(1, pReducer->nResultBufSize + sizeof(tFilePage)); - + int32_t finalRowLength = tscGetResRowLength(pQueryInfo); pReducer->resColModel = finalmodel; pReducer->resColModel->capacity = pReducer->nResultBufSize / finalRowLength; @@ -288,12 +286,12 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity); pReducer->pBufForInterpo = calloc(1, pReducer->nResultBufSize); - if (pReducer->pTempBuffer == NULL|| pReducer->discardData == NULL || pReducer->pResultBuf == NULL || + if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL || pReducer->pBufForInterpo == NULL || pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) { tfree(pReducer->pTempBuffer); tfree(pReducer->discardData); tfree(pReducer->pResultBuf); - tfree(pReducer->pFinalRes); + tfree(pReducer->pFinalRes); tfree(pReducer->pBufForInterpo); tfree(pReducer->prevRowOfInput); @@ -302,30 +300,31 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd } pReducer->pTempBuffer->numOfElems = 0; - pReducer->pResInfo = calloc((size_t)pQueryInfo->fieldsInfo.numOfOutputCols, sizeof(SResultInfo)); + pReducer->pResInfo = calloc((size_t)pQueryInfo->exprsInfo.numOfExprs, sizeof(SResultInfo)); tscCreateResPointerInfo(pRes, pQueryInfo); tscInitSqlContext(pCmd, pRes, pReducer, pDesc); // we change the capacity of schema to denote that there is only one row in temp buffer pReducer->pDesc->pColumnModel->capacity = 1; - - //restore the limitation value at the last stage + + // restore the limitation value at the last stage if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { pQueryInfo->limit.limit = pQueryInfo->clauseLimit; pQueryInfo->limit.offset = pQueryInfo->prjOffset; } - + pReducer->offset = pQueryInfo->limit.offset; - + pRes->pLocalReducer = pReducer; pRes->numOfGroups = 0; - SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - int16_t prec = pMeterMetaInfo->pMeterMeta->precision; + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); + int16_t prec = pMeterMetaInfo->pMeterMeta->precision; int64_t stime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->stime : pQueryInfo->etime; - int64_t revisedSTime = taosGetIntervalStartTimestamp(stime, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, prec); + int64_t revisedSTime = + taosGetIntervalStartTimestamp(stime, pQueryInfo->intervalTime, pQueryInfo->intervalTimeUnit, prec); SInterpolationInfo *pInterpoInfo = &pReducer->interpolationInfo; taosInitInterpoInfo(pInterpoInfo, pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols, @@ -336,7 +335,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { pInterpoInfo->pTags[0] = (char *)pInterpoInfo->pTags + POINTER_BYTES * pQueryInfo->groupbyExpr.numOfGroupCols; for (int32_t i = 1; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) { - SSchema* pSchema = getColumnModelSchema(pReducer->resColModel, startIndex + i - 1); + SSchema *pSchema = getColumnModelSchema(pReducer->resColModel, startIndex + i - 1); pInterpoInfo->pTags[i] = pSchema->bytes + pInterpoInfo->pTags[i - 1]; } } else { @@ -388,7 +387,7 @@ int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tF int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data, int32_t numOfRows, int32_t orderType) { SColumnModel *pModel = pDesc->pColumnModel; - + if (pPage->numOfElems + numOfRows <= pModel->capacity) { tColModelAppend(pModel, pPage, data, 0, numOfRows, numOfRows); return 0; @@ -445,11 +444,11 @@ void tscDestroyLocalReducer(SSqlObj *pSql) { return; } - SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - + SSqlCmd * pCmd = &pSql->cmd; + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + // there is no more result, so we release all allocated resource - SLocalReducer *pLocalReducer = (SLocalReducer*)atomic_exchange_ptr(&pRes->pLocalReducer, NULL); + SLocalReducer *pLocalReducer = (SLocalReducer *)atomic_exchange_ptr(&pRes->pLocalReducer, NULL); if (pLocalReducer != NULL) { int32_t status = 0; while ((status = atomic_val_compare_exchange_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY, @@ -461,19 +460,18 @@ void tscDestroyLocalReducer(SSqlObj *pSql) { taosDestoryInterpoInfo(&pLocalReducer->interpolationInfo); if (pLocalReducer->pCtx != NULL) { - for(int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { SQLFunctionCtx *pCtx = &pLocalReducer->pCtx[i]; - + tVariantDestroy(&pCtx->tag); if (pCtx->tagInfo.pTagCtxList != NULL) { tfree(pCtx->tagInfo.pTagCtxList); } } - + tfree(pLocalReducer->pCtx); } - tfree(pLocalReducer->prevRowOfInput); tfree(pLocalReducer->pTempBuffer); @@ -514,15 +512,15 @@ void tscDestroyLocalReducer(SSqlObj *pSql) { } static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) { - int32_t numOfGroupByCols = 0; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - + int32_t numOfGroupByCols = 0; + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols; } // primary timestamp column is involved in final result - if (pQueryInfo->nAggTimeInterval != 0 || tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { + if (pQueryInfo->intervalTime != 0 || tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { numOfGroupByCols++; } @@ -539,7 +537,7 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm orderIdx[i] = startCols++; } - if (pQueryInfo->nAggTimeInterval != 0) { + if (pQueryInfo->intervalTime != 0) { // the first column is the timestamp, handles queries like "interval(10m) group by tags" orderIdx[numOfGroupByCols - 1] = PRIMARYKEY_TIMESTAMP_COL_INDEX; } @@ -556,17 +554,17 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm } bool isSameGroup(SSqlCmd *pCmd, SLocalReducer *pReducer, char *pPrev, tFilePage *tmpBuffer) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + int16_t functionId = tscSqlExprGet(pQueryInfo, 0)->functionId; // disable merge procedure for column projection query assert(functionId != TSDB_FUNC_ARITHM); - + if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { return true; } - + if (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_ARITHM) { return false; } @@ -581,10 +579,10 @@ bool isSameGroup(SSqlCmd *pCmd, SLocalReducer *pReducer, char *pPrev, tFilePage if (pOrderDesc->orderIdx.pData[numOfCols - 1] == PRIMARYKEY_TIMESTAMP_COL_INDEX) { //<= 0 // super table interval query - assert(pQueryInfo->nAggTimeInterval > 0); + assert(pQueryInfo->intervalTime > 0); pOrderDesc->orderIdx.numOfCols -= 1; } else { // simple group by query - assert(pQueryInfo->nAggTimeInterval == 0); + assert(pQueryInfo->intervalTime == 0); } // only one row exists @@ -599,11 +597,11 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; - SSchema * pSchema = NULL; + SSchema * pSchema = NULL; SColumnModel *pModel = NULL; *pFinalModel = NULL; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); (*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pMeterMetaInfo->pMetricMeta->numOfVnodes); @@ -613,7 +611,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr return pRes->code; } - pSchema = (SSchema *)calloc(1, sizeof(SSchema) * pQueryInfo->fieldsInfo.numOfOutputCols); + pSchema = (SSchema *)calloc(1, sizeof(SSchema) * pQueryInfo->exprsInfo.numOfExprs); if (pSchema == NULL) { tscError("%p failed to allocate memory", pSql); pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY; @@ -621,7 +619,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr } int32_t rlen = 0; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); pSchema[i].bytes = pExpr->resBytes; @@ -634,8 +632,8 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr if (rlen != 0) { capacity = nBufferSizes / rlen; } - - pModel = createColumnModel(pSchema, pQueryInfo->fieldsInfo.numOfOutputCols, capacity); + + pModel = createColumnModel(pSchema, pQueryInfo->exprsInfo.numOfExprs, capacity); for (int32_t i = 0; i < pMeterMetaInfo->pMetricMeta->numOfVnodes; ++i) { (*pMemBuffer)[i] = createExtMemBuffer(nBufferSizes, rlen, pModel); @@ -647,16 +645,43 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr return pRes->code; } - memset(pSchema, 0, sizeof(SSchema) * pQueryInfo->fieldsInfo.numOfOutputCols); - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); + // final result depends on the fields number + memset(pSchema, 0, sizeof(SSchema) * pQueryInfo->exprsInfo.numOfExprs); + for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { + SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); + + SSchema *p1 = tsGetColumnSchema(pMeterMetaInfo->pMeterMeta, pExpr->colInfo.colIdx); + + int16_t inter = 0; + int16_t type = -1; + int16_t bytes = 0; + + // if ((pExpr->functionId >= TSDB_FUNC_FIRST_DST && pExpr->functionId <= TSDB_FUNC_LAST_DST) || + // (pExpr->functionId >= TSDB_FUNC_SUM && pExpr->functionId <= TSDB_FUNC_MAX) || + // pExpr->functionId == TSDB_FUNC_LAST_ROW) { + // 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->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; + } - pSchema[i].type = pField->type; - pSchema[i].bytes = pField->bytes; - strcpy(pSchema[i].name, pField->name); + getResultDataInfo(p1->type, p1->bytes, functionId, 0, &type, &bytes, &inter, 0, false); + } + + pSchema[i].type = type; + pSchema[i].bytes = bytes; + strcpy(pSchema[i].name, pModel->pFields[i].field.name); } - *pFinalModel = createColumnModel(pSchema, pQueryInfo->fieldsInfo.numOfOutputCols, capacity); + *pFinalModel = createColumnModel(pSchema, pQueryInfo->exprsInfo.numOfExprs, capacity); tfree(pSchema); return TSDB_CODE_SUCCESS; @@ -746,13 +771,15 @@ void adjustLoserTreeFromNewData(SLocalReducer *pLocalReducer, SLocalDataSource * } } -void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo* pQueryInfo, SInterpolationInfo *pInterpoInfo) { +void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo *pQueryInfo, + SInterpolationInfo *pInterpoInfo) { // discard following dataset in the same group and reset the interpolation information - SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - int16_t prec = pMeterMetaInfo->pMeterMeta->precision; + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); + int16_t prec = pMeterMetaInfo->pMeterMeta->precision; int64_t stime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->stime : pQueryInfo->etime; - int64_t revisedSTime = taosGetIntervalStartTimestamp(stime, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, prec); + int64_t revisedSTime = + taosGetIntervalStartTimestamp(stime, pQueryInfo->intervalTime, pQueryInfo->intervalTimeUnit, prec); taosInitInterpoInfo(pInterpoInfo, pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols, pLocalReducer->rowSize); @@ -765,24 +792,25 @@ void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo* } // todo merge with following function -static void reversedCopyResultToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage *pFinalDataPage) { - - for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); - - int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i); - char * src = pFinalDataPage->data + (pRes->numOfRows - 1) * pField->bytes + pRes->numOfRows * offset; - char * dst = pRes->data + pRes->numOfRows * offset; - - for (int32_t j = 0; j < pRes->numOfRows; ++j) { - memcpy(dst, src, (size_t)pField->bytes); - dst += pField->bytes; - src -= pField->bytes; - } - } -} +// static void reversedCopyResultToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage *pFinalDataPage) { +// +// for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { +// TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); +// +// int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i); +// char * src = pFinalDataPage->data + (pRes->numOfRows - 1) * pField->bytes + pRes->numOfRows * offset; +// char * dst = pRes->data + pRes->numOfRows * offset; +// +// for (int32_t j = 0; j < pRes->numOfRows; ++j) { +// memcpy(dst, src, (size_t)pField->bytes); +// dst += pField->bytes; +// src -= pField->bytes; +// } +// } +//} -static void reversedCopyFromInterpolationToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage **pResPages, SLocalReducer *pLocalReducer) { +static void reversedCopyFromInterpolationToDstBuf(SQueryInfo *pQueryInfo, SSqlRes *pRes, tFilePage **pResPages, + SLocalReducer *pLocalReducer) { assert(0); for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); @@ -806,11 +834,11 @@ static void reversedCopyFromInterpolationToDstBuf(SQueryInfo* pQueryInfo, SSqlRe * by "interuptHandler" function in shell */ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneOutput) { - SSqlCmd * pCmd = &pSql->cmd; - SSqlRes * pRes = &pSql->res; - tFilePage *pFinalDataPage = pLocalReducer->pResultBuf; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - + SSqlCmd * pCmd = &pSql->cmd; + SSqlRes * pRes = &pSql->res; + tFilePage * pFinalDataPage = pLocalReducer->pResultBuf; + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + if (pRes->pLocalReducer != pLocalReducer) { /* * Release the SSqlObj is called, and it is int destroying function invoked by other thread. @@ -820,7 +848,7 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo assert(pRes->pLocalReducer == NULL); } - if (pQueryInfo->nAggTimeInterval == 0 || pQueryInfo->interpoType == TSDB_INTERPO_NONE) { + if (pQueryInfo->intervalTime == 0 || pQueryInfo->interpoType == TSDB_INTERPO_NONE) { // no interval query, no interpolation pRes->data = pLocalReducer->pFinalRes; pRes->numOfRows = pFinalDataPage->numOfElems; @@ -862,19 +890,14 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo } int32_t rowSize = tscGetResRowLength(pQueryInfo); - // handle the descend order output -// if (pQueryInfo->order.order == TSQL_SO_ASC) { - memcpy(pRes->data, pFinalDataPage->data, pRes->numOfRows * rowSize); -// } else { -// reversedCopyResultToDstBuf(pQueryInfo, pRes, pFinalDataPage); -// } + memcpy(pRes->data, pFinalDataPage->data, pRes->numOfRows * rowSize); pFinalDataPage->numOfElems = 0; return; } int64_t *pPrimaryKeys = (int64_t *)pLocalReducer->pBufForInterpo; - + SInterpolationInfo *pInterpoInfo = &pLocalReducer->interpolationInfo; int64_t actualETime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->etime : pQueryInfo->stime; @@ -889,22 +912,23 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo int32_t *functions = (int32_t *)((char *)srcData + pQueryInfo->fieldsInfo.numOfOutputCols * sizeof(void *)); for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { - srcData[i] = pLocalReducer->pBufForInterpo + tscFieldInfoGetOffset(pQueryInfo, i) * pInterpoInfo->numOfRawDataInRows; + srcData[i] = + pLocalReducer->pBufForInterpo + tscFieldInfoGetOffset(pQueryInfo, i) * pInterpoInfo->numOfRawDataInRows; functions[i] = tscSqlExprGet(pQueryInfo, i)->functionId; } - SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - int8_t precision = pMeterMetaInfo->pMeterMeta->precision; + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); + int8_t precision = pMeterMetaInfo->pMeterMeta->precision; while (1) { int32_t remains = taosNumOfRemainPoints(pInterpoInfo); - TSKEY etime = taosGetRevisedEndKey(actualETime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, - precision); - int32_t nrows = taosGetNumOfResultWithInterpo(pInterpoInfo, pPrimaryKeys, remains, pQueryInfo->nAggTimeInterval, etime, + TSKEY etime = taosGetRevisedEndKey(actualETime, pQueryInfo->order.order, pQueryInfo->intervalTime, + pQueryInfo->intervalTimeUnit, precision); + int32_t nrows = taosGetNumOfResultWithInterpo(pInterpoInfo, pPrimaryKeys, remains, pQueryInfo->intervalTime, etime, pLocalReducer->resColModel->capacity); int32_t newRows = taosDoInterpoResult(pInterpoInfo, pQueryInfo->interpoType, pResPages, remains, nrows, - pQueryInfo->nAggTimeInterval, pPrimaryKeys, pLocalReducer->resColModel, srcData, + pQueryInfo->intervalTime, pPrimaryKeys, pLocalReducer->resColModel, srcData, pQueryInfo->defaultVal, functions, pLocalReducer->resColModel->capacity); assert(newRows <= nrows); @@ -914,7 +938,8 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo if (pQueryInfo->limit.offset > 0) { for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); - memmove(pResPages[i]->data, pResPages[i]->data + pField->bytes * pQueryInfo->limit.offset, newRows * pField->bytes); + memmove(pResPages[i]->data, pResPages[i]->data + pField->bytes * pQueryInfo->limit.offset, + newRows * pField->bytes); } } @@ -937,7 +962,7 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo /* all output for current group are completed */ int32_t totalRemainRows = - taosGetNumOfResWithoutLimit(pInterpoInfo, pPrimaryKeys, rpoints, pQueryInfo->nAggTimeInterval, actualETime); + taosGetNumOfResWithoutLimit(pInterpoInfo, pPrimaryKeys, rpoints, pQueryInfo->intervalTime, actualETime); if (totalRemainRows <= 0) { break; } @@ -962,10 +987,10 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo if (pQueryInfo->order.order == TSQL_SO_ASC) { for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); - int16_t offset = getColumnModelOffset(pLocalReducer->resColModel, i); + int16_t offset = getColumnModelOffset(pLocalReducer->resColModel, i); memcpy(pRes->data + offset * pRes->numOfRows, pResPages[i]->data, pField->bytes * pRes->numOfRows); } - } else {//todo bug?? + } else { // todo bug?? reversedCopyFromInterpolationToDstBuf(pQueryInfo, pRes, pResPages, pLocalReducer); } } @@ -985,9 +1010,9 @@ static void savePreviousRow(SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) // copy to previous temp buffer for (int32_t i = 0; i < pColumnModel->numOfCols; ++i) { - SSchema* pSchema = getColumnModelSchema(pColumnModel, i); - int16_t offset = getColumnModelOffset(pColumnModel, i); - + SSchema *pSchema = getColumnModelSchema(pColumnModel, i); + int16_t offset = getColumnModelOffset(pColumnModel, i); + memcpy(pLocalReducer->prevRowOfInput + offset, tmpBuffer->data + offset, pSchema->bytes); } @@ -995,19 +1020,19 @@ static void savePreviousRow(SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) pLocalReducer->hasPrevRow = true; } -static void doExecuteSecondaryMerge(SSqlCmd* pCmd, SLocalReducer *pLocalReducer, bool needInit) { +static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalReducer *pLocalReducer, bool needInit) { // the tag columns need to be set before all functions execution - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - for(int32_t j = 0; j < pQueryInfo->fieldsInfo.numOfOutputCols; ++j) { + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + + for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) { SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, j); SQLFunctionCtx *pCtx = &pLocalReducer->pCtx[j]; tVariantAssign(&pCtx->param[0], &pExpr->param[0]); // tags/tags_dummy function, the tag field of SQLFunctionCtx is from the input buffer - if (pExpr->functionId == TSDB_FUNC_TAG_DUMMY || pExpr->functionId == TSDB_FUNC_TAG || - pExpr->functionId == TSDB_FUNC_TS_DUMMY) { + int32_t functionId = pExpr->functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS_DUMMY) { tVariantDestroy(&pCtx->tag); tVariantCreateFromBinary(&pCtx->tag, pCtx->aInputElemBuf, pCtx->inputBytes, pCtx->inputType); } @@ -1019,7 +1044,7 @@ static void doExecuteSecondaryMerge(SSqlCmd* pCmd, SLocalReducer *pLocalReducer, } } - for (int32_t j = 0; j < pQueryInfo->fieldsInfo.numOfOutputCols; ++j) { + for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) { int32_t functionId = tscSqlExprGet(pQueryInfo, j)->functionId; if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { continue; @@ -1029,7 +1054,7 @@ static void doExecuteSecondaryMerge(SSqlCmd* pCmd, SLocalReducer *pLocalReducer, } } -static void handleUnprocessedRow(SSqlCmd* pCmd, SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) { +static void handleUnprocessedRow(SSqlCmd *pCmd, SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) { if (pLocalReducer->hasUnprocessedRow) { pLocalReducer->hasUnprocessedRow = false; doExecuteSecondaryMerge(pCmd, pLocalReducer, true); @@ -1039,14 +1064,22 @@ static void handleUnprocessedRow(SSqlCmd* pCmd, SLocalReducer *pLocalReducer, tF static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx) { int64_t maxOutput = 0; - + for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) { - int32_t functionId = tscSqlExprGet(pQueryInfo, j)->functionId; + // SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[j]; + // if (pExpr == NULL) { + // assert(pQueryInfo->fieldsInfo.pExpr[j] != NULL); + // + // maxOutput = 1; + // continue; + // } /* * ts, tag, tagprj function can not decide the output number of current query * the number of output result is decided by main output */ + SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, j); + int32_t functionId = pExpr->functionId; if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ) { continue; } @@ -1055,6 +1088,7 @@ static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx) maxOutput = GET_RES_INFO(&pCtx[j])->numOfRes; } } + return maxOutput; } @@ -1064,9 +1098,9 @@ static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx) * filled with the same result, which is the tags, specified in group by clause * */ -static void fillMultiRowsOfTagsVal(SQueryInfo* pQueryInfo, int32_t numOfRes, SLocalReducer *pLocalReducer) { +static void fillMultiRowsOfTagsVal(SQueryInfo *pQueryInfo, int32_t numOfRes, SLocalReducer *pLocalReducer) { int32_t maxBufSize = 0; // find the max tags column length to prepare the buffer - for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) { + for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) { SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k); if (maxBufSize < pExpr->resBytes && pExpr->functionId == TSDB_FUNC_TAG) { maxBufSize = pExpr->resBytes; @@ -1075,8 +1109,8 @@ static void fillMultiRowsOfTagsVal(SQueryInfo* pQueryInfo, int32_t numOfRes, SLo assert(maxBufSize >= 0); - char *buf = malloc((size_t) maxBufSize); - for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) { + char *buf = malloc((size_t)maxBufSize); + for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) { SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k); if (pExpr->functionId != TSDB_FUNC_TAG) { continue; @@ -1097,13 +1131,10 @@ static void fillMultiRowsOfTagsVal(SQueryInfo* pQueryInfo, int32_t numOfRes, SLo free(buf); } -int32_t finalizeRes(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer) { - for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) { +int32_t finalizeRes(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { + for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) { SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k); aAggs[pExpr->functionId].xFinalize(&pLocalReducer->pCtx[k]); - - // allow to re-initialize for the next round - pLocalReducer->pCtx[k].resultInfo->initialized = false; } pLocalReducer->hasPrevRow = false; @@ -1122,7 +1153,7 @@ int32_t finalizeRes(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer) { * results generated by simple aggregation function, we merge them all into one points * *Exception*: column projection query, required no merge procedure */ -bool needToMerge(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) { +bool needToMerge(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) { int32_t ret = 0; // merge all result by default int16_t functionId = tscSqlExprGet(pQueryInfo, 0)->functionId; @@ -1144,7 +1175,7 @@ bool needToMerge(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer, tFilePage return (ret == 0); } -static bool reachGroupResultLimit(SQueryInfo* pQueryInfo, SSqlRes *pRes) { +static bool reachGroupResultLimit(SQueryInfo *pQueryInfo, SSqlRes *pRes) { return (pRes->numOfGroups >= pQueryInfo->slimit.limit && pQueryInfo->slimit.limit >= 0); } @@ -1152,7 +1183,7 @@ static bool saveGroupResultInfo(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); pRes->numOfGroups += 1; // the output group is limited by the slimit clause @@ -1175,11 +1206,11 @@ static bool saveGroupResultInfo(SSqlObj *pSql) { * @return if current group is skipped, return false, and do NOT record it into pRes->numOfGroups */ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCurrentGroupRes) { - SSqlCmd * pCmd = &pSql->cmd; - SSqlRes * pRes = &pSql->res; - - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - tFilePage *pResBuf = pLocalReducer->pResultBuf; + SSqlCmd *pCmd = &pSql->cmd; + SSqlRes *pRes = &pSql->res; + + SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + tFilePage * pResBuf = pLocalReducer->pResultBuf; SColumnModel *pModel = pLocalReducer->resColModel; pRes->code = TSDB_CODE_SUCCESS; @@ -1207,11 +1238,10 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no int32_t startIndex = pQueryInfo->fieldsInfo.numOfOutputCols - pQueryInfo->groupbyExpr.numOfGroupCols; for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) { - int16_t offset = getColumnModelOffset(pModel, startIndex + i); - SSchema* pSchema = getColumnModelSchema(pModel, startIndex + i); - - memcpy(pInterpoInfo->pTags[i], - pLocalReducer->pBufForInterpo + offset * pResBuf->numOfElems, pSchema->bytes); + int16_t offset = getColumnModelOffset(pModel, startIndex + i); + SSchema *pSchema = getColumnModelSchema(pModel, startIndex + i); + + memcpy(pInterpoInfo->pTags[i], pLocalReducer->pBufForInterpo + offset * pResBuf->numOfElems, pSchema->bytes); } taosInterpoSetStartInfo(&pLocalReducer->interpolationInfo, pResBuf->numOfElems, pQueryInfo->interpoType); @@ -1220,7 +1250,7 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no return true; } -void resetOutputBuf(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer) { // reset output buffer to the beginning +void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { // reset output buffer to the beginning for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { pLocalReducer->pCtx[i].aOutputBuf = pLocalReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pLocalReducer->resColModel->capacity; @@ -1233,21 +1263,22 @@ static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalReducer // In handling data in other groups, we need to reset the interpolation information for a new group data pRes->numOfRows = 0; pRes->numOfTotalInCurrentClause = 0; - - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - + + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + pQueryInfo->limit.offset = pLocalReducer->offset; - SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - int16_t precision = pMeterMetaInfo->pMeterMeta->precision; + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); + int16_t precision = pMeterMetaInfo->pMeterMeta->precision; // for group result interpolation, do not return if not data is generated if (pQueryInfo->interpoType != TSDB_INTERPO_NONE) { int64_t stime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->stime : pQueryInfo->etime; - int64_t newTime = taosGetIntervalStartTimestamp(stime, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, precision); + int64_t newTime = + taosGetIntervalStartTimestamp(stime, pQueryInfo->intervalTime, pQueryInfo->intervalTimeUnit, precision); - taosInitInterpoInfo(&pLocalReducer->interpolationInfo, pQueryInfo->order.order, newTime, pQueryInfo->groupbyExpr.numOfGroupCols, - pLocalReducer->rowSize); + taosInitInterpoInfo(&pLocalReducer->interpolationInfo, pQueryInfo->order.order, newTime, + pQueryInfo->groupbyExpr.numOfGroupCols, pLocalReducer->rowSize); } } @@ -1259,12 +1290,12 @@ static bool doInterpolationForCurrentGroup(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SLocalReducer * pLocalReducer = pRes->pLocalReducer; SInterpolationInfo *pInterpoInfo = &pLocalReducer->interpolationInfo; - SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - int8_t p = pMeterMetaInfo->pMeterMeta->precision; + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); + int8_t p = pMeterMetaInfo->pMeterMeta->precision; if (taosHasRemainsDataForInterpolation(pInterpoInfo)) { assert(pQueryInfo->interpoType != TSDB_INTERPO_NONE); @@ -1273,9 +1304,10 @@ static bool doInterpolationForCurrentGroup(SSqlObj *pSql) { int64_t etime = *(int64_t *)(pFinalDataBuf->data + TSDB_KEYSIZE * (pInterpoInfo->numOfRawDataInRows - 1)); int32_t remain = taosNumOfRemainPoints(pInterpoInfo); - TSKEY ekey = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, p); + TSKEY ekey = + taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->intervalTime, pQueryInfo->intervalTimeUnit, p); int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, (TSKEY *)pLocalReducer->pBufForInterpo, remain, - pQueryInfo->nAggTimeInterval, ekey, pLocalReducer->resColModel->capacity); + pQueryInfo->intervalTime, ekey, pLocalReducer->resColModel->capacity); if (rows > 0) { // do interpo doInterpolateResult(pSql, pLocalReducer, false); } @@ -1295,9 +1327,9 @@ static bool doHandleLastRemainData(SSqlObj *pSql) { bool prevGroupCompleted = (!pLocalReducer->discard) && pLocalReducer->hasUnprocessedRow; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - int8_t precision = pMeterMetaInfo->pMeterMeta->precision; + SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); + int8_t precision = pMeterMetaInfo->pMeterMeta->precision; if ((isAllSourcesCompleted(pLocalReducer) && !pLocalReducer->hasPrevRow) || pLocalReducer->pLocalDataSrc[0] == NULL || prevGroupCompleted) { @@ -1305,8 +1337,9 @@ static bool doHandleLastRemainData(SSqlObj *pSql) { if (pQueryInfo->interpoType != TSDB_INTERPO_NONE) { int64_t etime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->etime : pQueryInfo->stime; - etime = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, precision); - int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, NULL, 0, pQueryInfo->nAggTimeInterval, etime, + etime = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->intervalTime, + pQueryInfo->intervalTimeUnit, precision); + int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, NULL, 0, pQueryInfo->intervalTime, etime, pLocalReducer->resColModel->capacity); if (rows > 0) { // do interpo doInterpolateResult(pSql, pLocalReducer, true); @@ -1334,15 +1367,15 @@ static bool doHandleLastRemainData(SSqlObj *pSql) { return false; } -static void doMergeWithPrevRows(SSqlObj *pSql, int32_t numOfRes) { - SSqlCmd * pCmd = &pSql->cmd; - SSqlRes * pRes = &pSql->res; - +static void doProcessResultInNextWindow(SSqlObj *pSql, int32_t numOfRes) { + SSqlCmd *pCmd = &pSql->cmd; + SSqlRes *pRes = &pSql->res; + SLocalReducer *pLocalReducer = pRes->pLocalReducer; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k); + SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + + for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) { + SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, k); SQLFunctionCtx *pCtx = &pLocalReducer->pCtx[k]; pCtx->aOutputBuf += pCtx->outputBytes * numOfRes; @@ -1359,24 +1392,24 @@ static void doMergeWithPrevRows(SSqlObj *pSql, int32_t numOfRes) { int32_t tscDoLocalreduce(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; - + tscResetForNextRetrieve(pRes); - + if (pSql->signature != pSql || pRes == NULL || pRes->pLocalReducer == NULL) { // all data has been processed tscTrace("%s call the drop local reducer", __FUNCTION__); tscDestroyLocalReducer(pSql); return 0; } - + SLocalReducer *pLocalReducer = pRes->pLocalReducer; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - + SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + // set the data merge in progress int32_t prevStatus = atomic_val_compare_exchange_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY, TSC_LOCALREDUCE_IN_PROGRESS); if (prevStatus != TSC_LOCALREDUCE_READY || pLocalReducer == NULL) { - assert(prevStatus == TSC_LOCALREDUCE_TOBE_FREED); // it is in tscDestroyLocalReducer function already + assert(prevStatus == TSC_LOCALREDUCE_TOBE_FREED); // it is in tscDestroyLocalReducer function already return TSDB_CODE_SUCCESS; } @@ -1474,8 +1507,7 @@ int32_t tscDoLocalreduce(SSqlObj *pSql) { * if the previous group does NOT generate any result (pResBuf->numOfElems == 0), * continue to process results instead of return results. */ - if ((!sameGroup && pResBuf->numOfElems > 0) || - (pResBuf->numOfElems == pLocalReducer->resColModel->capacity)) { + if ((!sameGroup && pResBuf->numOfElems > 0) || (pResBuf->numOfElems == pLocalReducer->resColModel->capacity)) { // does not belong to the same group bool notSkipped = doGenerateFinalResults(pSql, pLocalReducer, !sameGroup); @@ -1528,7 +1560,7 @@ int32_t tscDoLocalreduce(SSqlObj *pSql) { return TSDB_CODE_SUCCESS; } } else { // result buffer is not full - doMergeWithPrevRows(pSql, numOfRes); + doProcessResultInNextWindow(pSql, numOfRes); savePreviousRow(pLocalReducer, tmpBuffer); } } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 7f3f0273dbc2672bd8e720e507e8e3a224eb21ed..c6efafe3329ff57e6d5c3f1dfadd1b49952c4beb 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -31,18 +31,15 @@ #define TSC_MGMT_VNODE 999 -SRpcIpSet tscMgmtIpList; int tsMasterIndex = 0; int tsSlaveIndex = 1; -//temp -SRpcIpSet tscMgmtIpSet; +SRpcIpSet tscMgmtIpList; SRpcIpSet tscDnodeIpSet; int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo) = {0}; int (*tscProcessMsgRsp[TSDB_SQL_MAX])(SSqlObj *pSql); -char *doBuildMsgHeader(SSqlObj *pSql, char **pStart); void (*tscUpdateVnodeMsg[TSDB_SQL_MAX])(SSqlObj *pSql, char *buf); void tscProcessActivityTimer(void *handle, void *tmrId); int tscKeepConn[TSDB_SQL_MAX] = {0}; @@ -62,29 +59,27 @@ void tscPrintMgmtIp() { } } -void tscSetMgmtIpListFromCluster(SIpList *pIpList) { - tscMgmtIpList.numOfIps = pIpList->numOfIps; - if (memcmp(tscMgmtIpList.ip, pIpList->ip, pIpList->numOfIps * 4) != 0) { - for (int i = 0; i < pIpList->numOfIps; ++i) { - //tinet_ntoa(tscMgmtIpList.ipStr[i], pIpList->ip[i]); - tscMgmtIpList.ip[i] = pIpList->ip[i]; - } - tscTrace("cluster mgmt IP list:"); - tscPrintMgmtIp(); +void tscSetMgmtIpListFromCluster(SRpcIpSet *pIpList) { + tscMgmtIpList.numOfIps = htons(pIpList->numOfIps); + tscMgmtIpList.inUse = htons(pIpList->inUse); + tscMgmtIpList.port = htons(pIpList->port); + for (int32_t i = 0; i ip[i]; } } void tscSetMgmtIpListFromEdge() { - if (tscMgmtIpList.numOfIps != 2) { - tscMgmtIpList.numOfIps = 2; + if (tscMgmtIpList.numOfIps != 1) { + tscMgmtIpList.numOfIps = 1; + tscMgmtIpList.inUse = 0; + tscMgmtIpList.port = tsMgmtShellPort; tscMgmtIpList.ip[0] = inet_addr(tsMasterIp); - tscMgmtIpList.ip[1] = inet_addr(tsMasterIp); tscTrace("edge mgmt IP list:"); tscPrintMgmtIp(); } } -void tscSetMgmtIpList(SIpList *pIpList) { +void tscSetMgmtIpList(SRpcIpSet *pIpList) { /* * The iplist returned by the cluster edition is the current management nodes * and the iplist returned by the edge edition is empty @@ -121,14 +116,14 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { if (code == 0) { SHeartBeatRsp *pRsp = (SHeartBeatRsp *)pRes->pRsp; - SIpList * pIpList = &pRsp->ipList; + SRpcIpSet * pIpList = &pRsp->ipList; tscSetMgmtIpList(pIpList); if (pRsp->killConnection) { tscKillConnection(pObj); } else { - if (pRsp->queryId) tscKillQuery(pObj, pRsp->queryId); - if (pRsp->streamId) tscKillStream(pObj, pRsp->streamId); + if (pRsp->queryId) tscKillQuery(pObj, htonl(pRsp->queryId)); + if (pRsp->streamId) tscKillStream(pObj, htonl(pRsp->streamId)); } } else { tscTrace("heart beat failed, code:%d", code); @@ -169,9 +164,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { } if (tscShouldFreeHeatBeat(pObj->pHb)) { - tscTrace("%p free HB object and release connection, pConn:%p", pObj, pObj->pHb->thandle); - //taosCloseRpcConn(pObj->pHb->thandle); - + tscTrace("%p free HB object and release connection", pObj); tscFreeSqlObj(pObj->pHb); tscCloseTscObj(pObj); return; @@ -180,287 +173,58 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { tscProcessSql(pObj->pHb); } - -void tscGetConnToMgmt(SSqlObj *pSql, uint8_t *pCode) { - STscObj *pTscObj = pSql->pTscObj; - if (pSql->retry < tscGetMgmtConnMaxRetryTimes()) { - *pCode = 0; - pSql->retry++; - pSql->index = pSql->index % tscMgmtIpList.numOfIps; - if (pSql->cmd.command > TSDB_SQL_READ && pSql->index == 0) pSql->index = 1; - void *thandle = taosGetConnFromCache(tscConnCache, tscMgmtIpList.ip[pSql->index], TSC_MGMT_VNODE, pTscObj->user); - - -// if (thandle == NULL) { -// SRpcConnInit connInit; -// memset(&connInit, 0, sizeof(connInit)); -// connInit.cid = 0; -// connInit.sid = 0; -// connInit.meterId = pSql->pTscObj->user; -// connInit.peerId = 0; -// connInit.shandle = pTscMgmtConn; -// connInit.ahandle = pSql; -// connInit.peerPort = tsMgmtShellPort; -// connInit.spi = 1; -// connInit.encrypt = 0; -// connInit.secret = pSql->pTscObj->pass; -// -// connInit.peerIp = tscMgmtIpList.ipstr[pSql->index]; -// thandle = taosOpenRpcConn(&connInit, pCode); -// } - - pSql->thandle = thandle; - pSql->ip = tscMgmtIpList.ip[pSql->index]; - pSql->vnode = TSC_MGMT_VNODE; - tscTrace("%p mgmt index:%d ip:0x%x is picked up, pConn:%p", pSql, pSql->index, tscMgmtIpList.ip[pSql->index], - pSql->thandle); - } - - // the pSql->res.code is the previous error(status) code. - if (pSql->thandle == NULL && pSql->retry >= pSql->maxRetry) { - if (pSql->res.code != TSDB_CODE_SUCCESS && pSql->res.code != TSDB_CODE_ACTION_IN_PROGRESS) { - *pCode = pSql->res.code; - } - - tscError("%p reach the max retry:%d, code:%d", pSql, pSql->retry, *pCode); - } -} - -void tscGetConnToVnode(SSqlObj *pSql, uint8_t *pCode) { - SVPeerDesc *pVPeersDesc = NULL; - static int vidIndex = 0; - STscObj * pTscObj = pSql->pTscObj; - - pSql->thandle = NULL; - - SSqlCmd * pCmd = &pSql->cmd; - SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - - if (UTIL_METER_IS_SUPERTABLE(pMeterMetaInfo)) { // multiple vnode query - SVnodeSidList *vnodeList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, pMeterMetaInfo->vnodeIndex); - if (vnodeList != NULL) { - pVPeersDesc = vnodeList->vpeerDesc; - } - } else { - SMeterMeta *pMeta = pMeterMetaInfo->pMeterMeta; - if (pMeta == NULL) { - tscError("%p pMeterMeta is NULL", pSql); - pSql->retry = pSql->maxRetry; - return; - } - pVPeersDesc = pMeta->vpeerDesc; - } - - if (pVPeersDesc == NULL) { - pSql->retry = pSql->maxRetry; - tscError("%p pVPeerDesc is NULL", pSql); - } - - while (pSql->retry < pSql->maxRetry) { - (pSql->retry)++; - char ipstr[40] = {0}; - if (pVPeersDesc[pSql->index].ip == 0) { - /* - * in the edge edition, ip is 0, and at this time we use masterIp instead - * in the cluster edition, ip is vnode ip - */ - pVPeersDesc[pSql->index].ip = tscMgmtIpList.ip[0]; - } - *pCode = TSDB_CODE_SUCCESS; - - void *thandle = - taosGetConnFromCache(tscConnCache, pVPeersDesc[pSql->index].ip, pVPeersDesc[pSql->index].vnode, pTscObj->user); - -// if (thandle == NULL) { -// SRpcConnInit connInit; -// tinet_ntoa(ipstr, pVPeersDesc[pSql->index].ip); -// memset(&connInit, 0, sizeof(connInit)); -// connInit.cid = vidIndex; -// connInit.sid = 0; -// connInit.spi = 0; -// connInit.encrypt = 0; -// connInit.meterId = pSql->pTscObj->user; -// connInit.peerId = htonl((pVPeersDesc[pSql->index].vnode << TSDB_SHELL_VNODE_BITS)); -// connInit.shandle = pVnodeConn; -// connInit.ahandle = pSql; -// connInit.peerIp = ipstr; -// connInit.peerPort = tsVnodeShellPort; -// thandle = taosOpenRpcConn(&connInit, pCode); -// vidIndex = (vidIndex + 1) % tscNumOfThreads; -// } - - pSql->thandle = thandle; - pSql->ip = pVPeersDesc[pSql->index].ip; - pSql->vnode = pVPeersDesc[pSql->index].vnode; - tscTrace("%p vnode:%d ip:%p index:%d is picked up, pConn:%p", pSql, pVPeersDesc[pSql->index].vnode, - pVPeersDesc[pSql->index].ip, pSql->index, pSql->thandle); - - //TODO fetch from vpeerdesc - pSql->ipSet = tscMgmtIpSet; - break; - } - - // the pSql->res.code is the previous error(status) code. - if (pSql->thandle == NULL && pSql->retry >= pSql->maxRetry) { - if (pSql->res.code != TSDB_CODE_SUCCESS && pSql->res.code != TSDB_CODE_ACTION_IN_PROGRESS) { - *pCode = pSql->res.code; - } - - tscError("%p reach the max retry:%d, code:%d", pSql, pSql->retry, *pCode); - } -} - int tscSendMsgToServer(SSqlObj *pSql) { - uint8_t code = TSDB_CODE_NETWORK_UNAVAIL; - - if (pSql->thandle == NULL) { - if (pSql->cmd.command < TSDB_SQL_MGMT) - tscGetConnToVnode(pSql, &code); - else - tscGetConnToMgmt(pSql, &code); - } - - if (pSql->thandle) { - /* - * the total length of message - * rpc header + actual message body + digest - * - * the pSql object may be released automatically during insert procedure, in which the access of - * message body by using "if (pHeader->msgType & 1)" may cause the segment fault. - * - */ - size_t totalLen = pSql->cmd.payloadLen + tsRpcHeadSize + 100; - - // the memory will be released by taosProcessResponse, so no memory leak here - char *pStart = rpcMallocCont(pSql->cmd.payloadLen); - if (NULL == pStart) { - tscError("%p msg:%s malloc fail", pSql, taosMsg[pSql->cmd.msgType]); - return TSDB_CODE_CLI_OUT_OF_MEMORY; - } - memcpy(pStart, pSql->cmd.payload + tsRpcHeadSize, pSql->cmd.payloadLen); - - tscTrace("%p msg:%s is sent to server", pSql, taosMsg[pSql->cmd.msgType]); - - if (pStart) { - /* - * this SQL object may be released by other thread due to the completion of this query even before the log - * is dumped to log file. So the signature needs to be kept in a local variable. - */ - uint64_t signature = (uint64_t)pSql->signature; - //if (tscUpdateVnodeMsg[pSql->cmd.command]) (*tscUpdateVnodeMsg[pSql->cmd.command])(pSql, pStart); - - if (pSql->cmd.command < TSDB_SQL_MGMT) { - rpcSendRequest(pTscMgmtConn, &tscMgmtIpList, pSql->cmd.msgType, pStart, pSql->cmd.payloadLen, pSql); - } else { - SRpcIpSet rpcSet = tscMgmtIpList; - rpcSendRequest(pVnodeConn, &rpcSet, pSql->cmd.msgType, pStart, pSql->cmd.payloadLen, pSql); - } - - tscTrace("%p send msg code:%d sig:%p", pSql, code, signature); - } + char *pMsg = rpcMallocCont(pSql->cmd.payloadLen); + if (NULL == pMsg) { + tscError("%p msg:%s malloc fail", pSql, taosMsg[pSql->cmd.msgType]); + return TSDB_CODE_CLI_OUT_OF_MEMORY; } - return code; -} - -void tscProcessMgmtRedirect(SSqlObj *pSql, uint8_t *cont) { - SIpList *pIpList = (SIpList *)(cont); - tscSetMgmtIpList(pIpList); - - if (pSql->cmd.command < TSDB_SQL_READ) { - tsMasterIndex = 0; - pSql->index = 0; + pSql->ipList->ip[0] = inet_addr("192.168.0.1"); + if (pSql->cmd.command < TSDB_SQL_MGMT) { + pSql->ipList->port = tsVnodeShellPort; + tscPrint("%p msg:%s is sent to server %d", pSql, taosMsg[pSql->cmd.msgType], pSql->ipList->port); + memcpy(pMsg, pSql->cmd.payload + tsRpcHeadSize, pSql->cmd.payloadLen); + rpcSendRequest(pVnodeConn, pSql->ipList, pSql->cmd.msgType, pMsg, pSql->cmd.payloadLen, pSql); } else { - pSql->index++; + pSql->ipList->port = tsMgmtShellPort; + tscPrint("%p msg:%s is sent to server %d", pSql, taosMsg[pSql->cmd.msgType], pSql->ipList->port); + memcpy(pMsg, pSql->cmd.payload, pSql->cmd.payloadLen); + rpcSendRequest(pTscMgmtConn, pSql->ipList, pSql->cmd.msgType, pMsg, pSql->cmd.payloadLen, pSql); } - tscPrintMgmtIp(); + return TSDB_CODE_SUCCESS; } -void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { - if (ahandle == NULL) return NULL; - - SIntMsg *pMsg = (SIntMsg *)msg; +void tscProcessMsgFromServer(char type, void *pCont, int contLen, void *ahandle, int32_t code) { + tscPrint("response:%s is received, len:%d error:%s", taosMsg[(uint8_t)type], contLen, tstrerror(code)); SSqlObj *pSql = (SSqlObj *)ahandle; - SSqlRes *pRes = &pSql->res; - SSqlCmd *pCmd = &pSql->cmd; - STscObj *pObj = pSql->pTscObj; - int code = TSDB_CODE_NETWORK_UNAVAIL; - - if (pSql->signature != pSql) { + if (pSql == NULL || pSql->signature != pSql) { tscError("%p sql is already released, signature:%p", pSql, pSql->signature); - return NULL; - } - - if (pSql->thandle != thandle) { - tscError("%p thandle:%p is different from received:%p", pSql, pSql->thandle, thandle); - return NULL; + return; } - tscTrace("%p msg:%p is received from server, pConn:%p", pSql, msg, thandle); + SSqlRes *pRes = &pSql->res; + SSqlCmd *pCmd = &pSql->cmd; + STscObj *pObj = pSql->pTscObj; + tscTrace("%p msg:%p is received from server", pSql, pCont); if (pSql->freed || pObj->signature != pObj) { tscTrace("%p sql is already released or DB connection is closed, freed:%d pObj:%p signature:%p", pSql, pSql->freed, pObj, pObj->signature); - taosAddConnIntoCache(tscConnCache, pSql->thandle, pSql->ip, pSql->vnode, pObj->user); tscFreeSqlObj(pSql); - return ahandle; + rpcFreeCont(pCont); + return; } - SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - if (msg == NULL) { - tscTrace("%p no response from ip:%s", pSql, taosIpStr(pSql->ip)); - - pSql->index++; - pSql->thandle = NULL; - // todo taos_stop_query() in async model - /* - * in case of - * 1. query cancelled(pRes->code != TSDB_CODE_QUERY_CANCELLED), do NOT re-issue the request to server. - * 2. retrieve, do NOT re-issue the retrieve request since the qhandle may have been released by server - */ - if (pCmd->command != TSDB_SQL_FETCH && pCmd->command != TSDB_SQL_RETRIEVE && pCmd->command != TSDB_SQL_KILL_QUERY && - pRes->code != TSDB_CODE_QUERY_CANCELLED) { - code = tscSendMsgToServer(pSql); - if (code == 0) return NULL; - } - - // renew meter meta in case it is changed - if (pCmd->command < TSDB_SQL_FETCH && pRes->code != TSDB_CODE_QUERY_CANCELLED) { - pSql->maxRetry = TSDB_VNODES_SUPPORT * 2; - code = tscRenewMeterMeta(pSql, pMeterMetaInfo->name); - pRes->code = code; - if (code == TSDB_CODE_ACTION_IN_PROGRESS) return pSql; - - if (pMeterMetaInfo->pMeterMeta) { - code = tscSendMsgToServer(pSql); - if (code == 0) return pSql; - } - } + if (pCont == NULL) { + code = TSDB_CODE_NETWORK_UNAVAIL; } else { - uint16_t rspCode = pMsg->content[0]; - - if (rspCode == TSDB_CODE_REDIRECT) { - tscTrace("%p it shall be redirected!", pSql); - taosAddConnIntoCache(tscConnCache, thandle, pSql->ip, pSql->vnode, pObj->user); - pSql->thandle = NULL; - - if (pCmd->command > TSDB_SQL_MGMT) { - tscProcessMgmtRedirect(pSql, pMsg->content + 1); - } else if (pCmd->command == TSDB_SQL_INSERT) { - pSql->index++; - pSql->maxRetry = TSDB_VNODES_SUPPORT * 2; - } else { - pSql->index++; - } - - code = tscSendMsgToServer(pSql); - if (code == 0) return pSql; - msg = NULL; - } else if (rspCode == TSDB_CODE_NOT_ACTIVE_TABLE || rspCode == TSDB_CODE_INVALID_TABLE_ID || - rspCode == TSDB_CODE_INVALID_VNODE_ID || rspCode == TSDB_CODE_NOT_ACTIVE_VNODE || - rspCode == TSDB_CODE_NETWORK_UNAVAIL || rspCode == TSDB_CODE_NOT_ACTIVE_SESSION || - rspCode == TSDB_CODE_TABLE_ID_MISMATCH) { + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); + if (code == TSDB_CODE_NOT_ACTIVE_TABLE || code == TSDB_CODE_INVALID_TABLE_ID || + code == TSDB_CODE_INVALID_VNODE_ID || code == TSDB_CODE_NOT_ACTIVE_VNODE || + code == TSDB_CODE_NETWORK_UNAVAIL || code == TSDB_CODE_NOT_ACTIVE_SESSION || + code == TSDB_CODE_TABLE_ID_MISMATCH) { /* * not_active_table: 1. the virtual node may fail to create table, since the procedure of create table is asynchronized, * the virtual node may have not create table till now, so try again by using the new metermeta. @@ -471,53 +235,33 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { * removed. So, renew metermeta and try again. * not_active_session: db has been move to other node, the vnode does not exist on this dnode anymore. */ - pSql->thandle = NULL; - taosAddConnIntoCache(tscConnCache, thandle, pSql->ip, pSql->vnode, pObj->user); - if (pCmd->command == TSDB_SQL_CONNECT) { code = TSDB_CODE_NETWORK_UNAVAIL; + rpcFreeCont(pCont); + return; } else if (pCmd->command == TSDB_SQL_HB) { code = TSDB_CODE_NOT_READY; + rpcFreeCont(pCont); + return; } else { - tscTrace("%p it shall renew meter meta, code:%d", pSql, rspCode); + tscTrace("%p it shall renew meter meta, code:%d", pSql, code); pSql->maxRetry = TSDB_VNODES_SUPPORT * 2; - pSql->res.code = (uint8_t)rspCode; // keep the previous error code + pSql->res.code = (uint8_t) code; // keep the previous error code code = tscRenewMeterMeta(pSql, pMeterMetaInfo->name); - if (code == TSDB_CODE_ACTION_IN_PROGRESS) return pSql; if (pMeterMetaInfo->pMeterMeta) { - code = tscSendMsgToServer(pSql); - if (code == 0) return pSql; + tscSendMsgToServer(pSql); + rpcFreeCont(pCont); + return; } } - - msg = NULL; - } else { // for other error set and return to invoker - code = rspCode; } } pSql->retry = 0; - if (msg) { - if (pCmd->command < TSDB_SQL_MGMT) { - if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { - if (pMeterMetaInfo->pMeterMeta) // it may be deleted - pMeterMetaInfo->pMeterMeta->index = pSql->index; - } else { - SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, pMeterMetaInfo->vnodeIndex); - pVnodeSidList->index = pSql->index; - } - } else { - if (pCmd->command > TSDB_SQL_READ) - tsSlaveIndex = pSql->index; - else - tsMasterIndex = pSql->index; - } - } - if (pSql->fp == NULL) tsem_wait(&pSql->emptyRspSem); pRes->rspLen = 0; @@ -527,11 +271,11 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { tscTrace("%p query is cancelled, code:%d", pSql, pRes->code); } - if (msg && pRes->code != TSDB_CODE_QUERY_CANCELLED) { - assert(pMsg->msgType == pCmd->msgType + 1); - pRes->code = pMsg->content[0]; - pRes->rspType = pMsg->msgType; - pRes->rspLen = pMsg->msgLen - sizeof(SIntMsg); + if (pRes->code != TSDB_CODE_QUERY_CANCELLED) { + assert(type == pCmd->msgType + 1); + pRes->code = (int32_t)code; + pRes->rspType = type; + pRes->rspLen = contLen; char *tmp = (char *)realloc(pRes->pRsp, pRes->rspLen); if (tmp == NULL) { @@ -539,7 +283,7 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { } else { pRes->pRsp = tmp; if (pRes->rspLen) { - memcpy(pRes->pRsp, pMsg->content + 1, pRes->rspLen - 1); + memcpy(pRes->pRsp, pCont, pRes->rspLen); } } @@ -552,9 +296,15 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { * There is not response callback function for submit response. * The actual inserted number of points is the first number. */ - if (pMsg->msgType == TSDB_MSG_TYPE_DNODE_SUBMIT_RSP) { - pRes->numOfRows += *(int32_t *)pRes->pRsp; - + if (type == TSDB_MSG_TYPE_SUBMIT_RSP) { + SShellSubmitRspMsg *pMsg = pRes->pRsp; + pMsg->code = htonl(pMsg->code); + pMsg->numOfRows = htonl(pMsg->numOfRows); + pMsg->affectedRows = htonl(pMsg->affectedRows); + pMsg->failedRows = htonl(pMsg->failedRows); + pMsg->numOfFailedBlocks = htonl(pMsg->numOfFailedBlocks); + + pRes->numOfRows += pMsg->affectedRows; tscTrace("%p cmd:%d code:%d, inserted rows:%d, rsp len:%d", pSql, pCmd->command, pRes->code, *(int32_t *)pRes->pRsp, pRes->rspLen); } else { @@ -562,14 +312,6 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { } } - if (tscKeepConn[pCmd->command] == 0 || - (pRes->code != TSDB_CODE_SUCCESS && pRes->code != TSDB_CODE_ACTION_IN_PROGRESS)) { - if (pSql->thandle != NULL) { - taosAddConnIntoCache(tscConnCache, pSql->thandle, pSql->ip, pSql->vnode, pObj->user); - pSql->thandle = NULL; - } - } - if (pSql->fp == NULL) { tsem_post(&pSql->rspSem); } else { @@ -611,7 +353,7 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { } } - return ahandle; + rpcFreeCont(pCont); } static SSqlObj *tscCreateSqlObjForSubquery(SSqlObj *pSql, SRetrieveSupport *trsupport, SSqlObj *prevSqlObj); @@ -650,19 +392,23 @@ int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSubquerySu tscColumnBaseInfoUpdateTableIndex(&pNewQueryInfo->colList, 0); tscColumnBaseInfoCopy(&pSupporter->colList, &pNewQueryInfo->colList, 0); - tscSqlExprCopy(&pSupporter->exprsInfo, &pNewQueryInfo->exprsInfo, pSupporter->uid); - + tscSqlExprCopy(&pSupporter->exprsInfo, &pNewQueryInfo->exprsInfo, pSupporter->uid, false); tscFieldInfoCopyAll(&pSupporter->fieldsInfo, &pNewQueryInfo->fieldsInfo); + tscTagCondCopy(&pSupporter->tagCond, &pNewQueryInfo->tagCond); pNew->cmd.numOfCols = 0; - pNewQueryInfo->nAggTimeInterval = 0; + pNewQueryInfo->intervalTime = 0; memset(&pNewQueryInfo->limit, 0, sizeof(SLimitVal)); // backup the data and clear it in the sqlcmd object pSupporter->groupbyExpr = pNewQueryInfo->groupbyExpr; memset(&pNewQueryInfo->groupbyExpr, 0, sizeof(SSqlGroupbyExpr)); + // this data needs to be transfer to support struct + pNewQueryInfo->fieldsInfo.numOfOutputCols = 0; + pNewQueryInfo->exprsInfo.numOfExprs = 0; + // set the ts,tags that involved in join, as the output column of intermediate result tscClearSubqueryInfo(&pNew->cmd); @@ -771,28 +517,27 @@ int tscProcessSql(SSqlObj *pSql) { } tscTrace("%p SQL cmd:%d will be processed, name:%s, type:%d", pSql, pCmd->command, name, type); - pSql->retry = 0; if (pSql->cmd.command < TSDB_SQL_MGMT) { - pSql->maxRetry = TSDB_VNODES_SUPPORT; - // the pMeterMetaInfo cannot be NULL if (pMeterMetaInfo == NULL) { pSql->res.code = TSDB_CODE_OTHERS; return pSql->res.code; } - if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { - pSql->index = pMeterMetaInfo->pMeterMeta->index; - } else { // it must be the parent SSqlObj for super table query - if ((pQueryInfo->type & TSDB_QUERY_TYPE_SUBQUERY) != 0) { - int32_t idx = pMeterMetaInfo->vnodeIndex; - - SVnodeSidList *pSidList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, idx); - pSql->index = pSidList->index; - } - } + // temp + pSql->ipList = &tscMgmtIpList; +// if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { +// pSql->index = pMeterMetaInfo->pMeterMeta->index; +// } else { // it must be the parent SSqlObj for super table query +// if ((pQueryInfo->type & TSDB_QUERY_TYPE_SUBQUERY) != 0) { +// int32_t idx = pMeterMetaInfo->vnodeIndex; +// +// SVnodeSidList *pSidList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, idx); +// pSql->index = pSidList->index; +// } +// } } else if (pSql->cmd.command < TSDB_SQL_LOCAL) { - pSql->index = pSql->cmd.command < TSDB_SQL_READ ? tsMasterIndex : tsSlaveIndex; + pSql->ipList = &tscMgmtIpList; } else { // local handler return (*tscProcessMsgRsp[pCmd->command])(pSql); } @@ -908,7 +653,7 @@ int tscLaunchSTableSubqueries(SSqlObj *pSql) { tExtMemBuffer ** pMemoryBuf = NULL; tOrderDescriptor *pDesc = NULL; - SColumnModel * pModel = NULL; + SColumnModel * pModel = NULL; pRes->qhandle = 1; // hack the qhandle check @@ -1313,7 +1058,7 @@ void tscKillMetricQuery(SSqlObj *pSql) { for (int i = 0; i < pSql->numOfSubs; ++i) { SSqlObj *pSub = pSql->pSubs[i]; - if (pSub == NULL || pSub->thandle == NULL) { + if (pSub == NULL) { continue; } @@ -1325,8 +1070,6 @@ void tscKillMetricQuery(SSqlObj *pSql) { //taosStopRpcConn(pSql->pSubs[i]->thandle); } - pSql->numOfSubs = 0; - /* * 1. if the subqueries are not launched or partially launched, we need to waiting the launched * query return to successfully free allocated resources. @@ -1463,15 +1206,16 @@ int tscBuildRetrieveMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pStart = pSql->cmd.payload + tsRpcHeadSize; pMsg = pStart; - *((uint64_t *)pMsg) = pSql->res.qhandle; + SRetrieveTableMsg *pRetrieveMsg = (SShellSubmitMsg *)pMsg; + pRetrieveMsg->qhandle = htobe64(pSql->res.qhandle); pMsg += sizeof(pSql->res.qhandle); SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); - *((uint16_t *)pMsg) = htons(pQueryInfo->type); + pRetrieveMsg->free = htons(pQueryInfo->type); pMsg += sizeof(pQueryInfo->type); pSql->cmd.payloadLen = pMsg - pStart; - pSql->cmd.msgType = TSDB_MSG_TYPE_DNODE_RETRIEVE; + pSql->cmd.msgType = TSDB_MSG_TYPE_RETRIEVE; return TSDB_CODE_SUCCESS; } @@ -1481,11 +1225,12 @@ void tscUpdateVnodeInSubmitMsg(SSqlObj *pSql, char *buf) { char * pMsg; SMeterMetaInfo * pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, pSql->cmd.clauseIndex, 0); - SMeterMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta; pMsg = buf + tsRpcHeadSize; - pShellMsg = (SShellSubmitMsg *)pMsg; + //TODO set iplist + //pShellMsg = (SShellSubmitMsg *)pMsg; //pShellMsg->vnode = htons(pMeterMeta->vpeerDesc[pSql->index].vnode); //tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pMeterMeta->vpeerDesc[pSql->index].ip), // htons(pShellMsg->vnode)); @@ -1498,7 +1243,7 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - SMeterMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta; pStart = pSql->cmd.payload + tsRpcHeadSize; pMsg = pStart; @@ -1506,32 +1251,35 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pShellMsg = (SShellSubmitMsg *)pMsg; pShellMsg->import = htons(TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT) ? 0 : 1); - //pShellMsg->vnode = htons(pMeterMeta->vpeerDesc[pMeterMeta->index].vnode); + pShellMsg->vnode = 0; //htons(pMeterMeta->vpeerDesc[pMeterMeta->index].vnode); pShellMsg->numOfSid = htonl(pSql->cmd.numOfTablesInSubmit); // number of meters to be inserted // pSql->cmd.payloadLen is set during parse sql routine, so we do not use it here - pSql->cmd.msgType = TSDB_MSG_TYPE_DNODE_SUBMIT; - //tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pMeterMeta->vpeerDesc[pMeterMeta->index].ip), - // htons(pShellMsg->vnode)); - + pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT; + tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pMeterMeta->vpeerDesc[pMeterMeta->index].ip), + htons(pShellMsg->vnode)); + + pSql->cmd.payloadLen = sizeof(SShellSubmitMsg); + return TSDB_CODE_SUCCESS; } void tscUpdateVnodeInQueryMsg(SSqlObj *pSql, char *buf) { - SSqlCmd * pCmd = &pSql->cmd; - SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - - char * pStart = buf + tsRpcHeadSize; - SQueryMeterMsg *pQueryMsg = (SQueryMeterMsg *)pStart; - - if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { // pColumnModel == NULL, query on meter - SMeterMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta; - pQueryMsg->vnode = htons(pMeterMeta->vpeerDesc[pSql->index].vnode); - } else { // query on metric - SMetricMeta * pMetricMeta = pMeterMetaInfo->pMetricMeta; - SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex); - pQueryMsg->vnode = htons(pVnodeSidList->vpeerDesc[pSql->index].vnode); - } + //TODO +// SSqlCmd * pCmd = &pSql->cmd; +// SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); +// +// char * pStart = buf + tsRpcHeadSize; +// SQueryTableMsg *pQueryMsg = (SQueryTableMsg *)pStart; +// +// if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { // pColumnModel == NULL, query on meter +// STableMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta; +// pQueryMsg->vnode = htons(pMeterMeta->vpeerDesc[pSql->index].vnode); +// } else { // query on metric +// SSuperTableMeta * pMetricMeta = pMeterMetaInfo->pMetricMeta; +// SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex); +// pQueryMsg->vnode = htons(pVnodeSidList->vpeerDesc[pSql->index].vnode); +// } } /* @@ -1544,20 +1292,19 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) { int32_t srcColListSize = pQueryInfo->colList.numOfCols * sizeof(SColumnInfo); - int32_t exprSize = sizeof(SSqlFuncExprMsg) * pQueryInfo->fieldsInfo.numOfOutputCols; + int32_t exprSize = sizeof(SSqlFuncExprMsg) * pQueryInfo->exprsInfo.numOfExprs; SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); // meter query without tags values if (!UTIL_METER_IS_SUPERTABLE(pMeterMetaInfo)) { - return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryMeterMsg) + srcColListSize + exprSize; + return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + exprSize; } - SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta; - + SSuperTableMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta; SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex); - int32_t meterInfoSize = (pMetricMeta->tagLen + sizeof(SMeterSidExtInfo)) * pVnodeSidList->numOfSids; - int32_t outputColumnSize = pQueryInfo->fieldsInfo.numOfOutputCols * sizeof(SSqlFuncExprMsg); + int32_t meterInfoSize = (pMetricMeta->tagLen + sizeof(STableSidExtInfo)) * pVnodeSidList->numOfSids; + int32_t outputColumnSize = pQueryInfo->exprsInfo.numOfExprs * sizeof(SSqlFuncExprMsg); int32_t size = meterInfoSize + outputColumnSize + srcColListSize + exprSize + MIN_QUERY_MSG_PKT_SIZE; if (pQueryInfo->tsBuf != NULL) { @@ -1567,34 +1314,34 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) { return size; } -static char *doSerializeTableInfo(SSqlObj *pSql, int32_t numOfMeters, int32_t vnodeId, char *pMsg) { +static char *doSerializeTableInfo(SSqlObj *pSql, int32_t numOfTables, int32_t vnodeId, char *pMsg) { SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, pSql->cmd.clauseIndex, 0); - SMeterMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta; - SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta; + STableMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta; + SSuperTableMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta; - tscTrace("%p vid:%d, query on %d meters", pSql, htons(vnodeId), numOfMeters); + tscTrace("%p vid:%d, query on %d meters", pSql, vnodeId, numOfTables); if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { #ifdef _DEBUG_VIEW tscTrace("%p sid:%d, uid:%" PRIu64, pSql, pMeterMetaInfo->pMeterMeta->sid, pMeterMetaInfo->pMeterMeta->uid); #endif - SMeterSidExtInfo *pMeterInfo = (SMeterSidExtInfo *)pMsg; + STableSidExtInfo *pMeterInfo = (STableSidExtInfo *)pMsg; pMeterInfo->sid = htonl(pMeterMeta->sid); pMeterInfo->uid = htobe64(pMeterMeta->uid); pMeterInfo->key = htobe64(tscGetSubscriptionProgress(pSql->pSubscription, pMeterMeta->uid)); - pMsg += sizeof(SMeterSidExtInfo); + pMsg += sizeof(STableSidExtInfo); } else { SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex); - for (int32_t i = 0; i < numOfMeters; ++i) { - SMeterSidExtInfo *pMeterInfo = (SMeterSidExtInfo *)pMsg; - SMeterSidExtInfo *pQueryMeterInfo = tscGetMeterSidInfo(pVnodeSidList, i); + for (int32_t i = 0; i < numOfTables; ++i) { + STableSidExtInfo *pMeterInfo = (STableSidExtInfo *)pMsg; + STableSidExtInfo *pQueryMeterInfo = tscGetMeterSidInfo(pVnodeSidList, i); pMeterInfo->sid = htonl(pQueryMeterInfo->sid); pMeterInfo->uid = htobe64(pQueryMeterInfo->uid); pMeterInfo->key = htobe64(tscGetSubscriptionProgress(pSql->pSubscription, pQueryMeterInfo->uid)); - pMsg += sizeof(SMeterSidExtInfo); + pMsg += sizeof(STableSidExtInfo); memcpy(pMsg, pQueryMeterInfo->tags, pMetricMeta->tagLen); pMsg += pMetricMeta->tagLen; @@ -1623,16 +1370,16 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { char * pStart = pCmd->payload + tsRpcHeadSize; - SMeterMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta; - SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta; + STableMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta; + SSuperTableMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta; - SQueryMeterMsg *pQueryMsg = (SQueryMeterMsg *)pStart; + SQueryTableMsg *pQueryMsg = (SQueryTableMsg *)pStart; int32_t msgLen = 0; - int32_t numOfMeters = 0; + int32_t numOfTables = 0; if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { - numOfMeters = 1; + numOfTables = 1; tscTrace("%p query on vnode: %d, number of sid:%d, meter id: %s", pSql, pMeterMeta->vpeerDesc[pMeterMeta->index].vnode, 1, pMeterMetaInfo->name); @@ -1649,17 +1396,17 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex); uint32_t vnodeId = pVnodeSidList->vpeerDesc[pVnodeSidList->index].vnode; - numOfMeters = pVnodeSidList->numOfSids; - if (numOfMeters <= 0) { - tscError("%p vid:%d,error numOfMeters in query message:%d", pSql, vnodeId, numOfMeters); + numOfTables = pVnodeSidList->numOfSids; + if (numOfTables <= 0) { + tscError("%p vid:%d,error numOfTables in query message:%d", pSql, vnodeId, numOfTables); return -1; // error } - tscTrace("%p query on vid:%d, number of sid:%d", pSql, vnodeId, numOfMeters); + tscTrace("%p query on vid:%d, number of sid:%d", pSql, vnodeId, numOfTables); pQueryMsg->vnode = htons(vnodeId); } - pQueryMsg->numOfSids = htonl(numOfMeters); + pQueryMsg->numOfSids = htonl(numOfTables); pQueryMsg->numOfTagsCols = htons(pMeterMetaInfo->numOfTags); if (pQueryInfo->order.order == TSQL_SO_ASC) { @@ -1690,12 +1437,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return -1; } - pQueryMsg->nAggTimeInterval = htobe64(pQueryInfo->nAggTimeInterval); + pQueryMsg->intervalTime = htobe64(pQueryInfo->intervalTime); pQueryMsg->intervalTimeUnit = pQueryInfo->intervalTimeUnit; - pQueryMsg->slidingTime = htobe64(pQueryInfo->nSlidingTime); + pQueryMsg->slidingTime = htobe64(pQueryInfo->slidingTime); - if (pQueryInfo->nAggTimeInterval < 0) { - tscError("%p illegal value of aggregation time interval in query msg: %ld", pSql, pQueryInfo->nAggTimeInterval); + if (pQueryInfo->intervalTime < 0) { + tscError("%p illegal value of aggregation time interval in query msg: %ld", pSql, pQueryInfo->intervalTime); return -1; } @@ -1775,7 +1522,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlFuncExprMsg *pSqlFuncExpr = (SSqlFuncExprMsg *)pMsg; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { + for (int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) { SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr->functionId == TSDB_FUNC_ARITHM) { @@ -1830,7 +1577,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pQueryMsg->colNameLen = htonl(len); // serialize the table info (sid, uid, tags) - pMsg = doSerializeTableInfo(pSql, numOfMeters, htons(pQueryMsg->vnode), pMsg); + pMsg = doSerializeTableInfo(pSql, numOfTables, htons(pQueryMsg->vnode), pMsg); // only include the required tag column schema. If a tag is not required, it won't be sent to vnode if (pMeterMetaInfo->numOfTags > 0) { @@ -1840,7 +1587,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { for (int32_t j = 0; j < pMeterMetaInfo->numOfTags; ++j) { if (pMeterMetaInfo->tagColumnIndex[j] == TSDB_TBNAME_COLUMN_INDEX) { SSchema tbSchema = { - .bytes = TSDB_METER_NAME_LEN, .colId = TSDB_TBNAME_COLUMN_INDEX, .type = TSDB_DATA_TYPE_BINARY}; + .bytes = TSDB_TABLE_NAME_LEN, .colId = TSDB_TBNAME_COLUMN_INDEX, .type = TSDB_DATA_TYPE_BINARY}; memcpy(pMsg, &tbSchema, sizeof(SSchema)); } else { memcpy(pMsg, &pTagSchema[pMeterMetaInfo->tagColumnIndex[j]], sizeof(SSchema)); @@ -1869,6 +1616,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { *((int16_t *)pMsg) += pCol->flag; pMsg += sizeof(pCol->flag); + + memcpy(pMsg, pCol->name, tListLen(pCol->name)); + pMsg += tListLen(pCol->name); } } @@ -1907,7 +1657,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { tscTrace("%p msg built success,len:%d bytes", pSql, msgLen); pCmd->payloadLen = msgLen; - pSql->cmd.msgType = TSDB_MSG_TYPE_DNODE_QUERY; + pSql->cmd.msgType = TSDB_MSG_TYPE_QUERY; assert(msgLen + minMsgSize() <= size); @@ -1915,56 +1665,48 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SCreateDbMsg *pCreateDbMsg; - char * pMsg, *pStart; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SCreateDbMsg); + pCmd->msgType = TSDB_MSG_TYPE_CREATE_DB; + + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - pMsg = doBuildMsgHeader(pSql, &pStart); - pCreateDbMsg = (SCreateDbMsg *)pMsg; + SCreateDbMsg *pCreateDbMsg = (SCreateDbMsg*)pCmd->payload; assert(pCmd->numOfClause == 1); SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - strncpy(pCreateDbMsg->db, pMeterMetaInfo->name, tListLen(pCreateDbMsg->db)); - pMsg += sizeof(SCreateDbMsg); - - pCmd->payloadLen = pMsg - pStart; - pCmd->msgType = TSDB_MSG_TYPE_CREATE_DB; return TSDB_CODE_SUCCESS; } int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SCreateDnodeMsg *pCreate; - - char *pMsg, *pStart; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SCreateDnodeMsg); + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - pMsg = doBuildMsgHeader(pSql, &pStart); - - pCreate = (SCreateDnodeMsg *)pMsg; + SCreateDnodeMsg *pCreate = (SCreateDnodeMsg *)pCmd->payload; strncpy(pCreate->ip, pInfo->pDCLInfo->a[0].z, pInfo->pDCLInfo->a[0].n); - - pMsg += sizeof(SCreateDnodeMsg); - - pCmd->payloadLen = pMsg - pStart; pCmd->msgType = TSDB_MSG_TYPE_CREATE_DNODE; return TSDB_CODE_SUCCESS; } int32_t tscBuildAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SCreateAcctMsg *pAlterMsg; - char * pMsg, *pStart; - int msgLen = 0; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SCreateAcctMsg); + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - pMsg = doBuildMsgHeader(pSql, &pStart); - - pAlterMsg = (SCreateAcctMsg *)pMsg; + SCreateAcctMsg *pAlterMsg = (SCreateAcctMsg *)pCmd->payload; SSQLToken *pName = &pInfo->pDCLInfo->user.user; SSQLToken *pPwd = &pInfo->pDCLInfo->user.passwd; @@ -1972,8 +1714,6 @@ int32_t tscBuildAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) { strncpy(pAlterMsg->user, pName->z, pName->n); strncpy(pAlterMsg->pass, pPwd->z, pPwd->n); - pMsg += sizeof(SCreateAcctMsg); - SCreateAcctSQL *pAcctOpt = &pInfo->pDCLInfo->acctOpt; pAlterMsg->cfg.maxUsers = htonl(pAcctOpt->maxUsers); @@ -1999,25 +1739,23 @@ int32_t tscBuildAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } } - msgLen = pMsg - pStart; - pCmd->payloadLen = msgLen; - pCmd->msgType = TSDB_MSG_TYPE_CREATE_ACCT; return TSDB_CODE_SUCCESS; } int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SCreateUserMsg *pAlterMsg; - char * pMsg, *pStart; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SCreateUserMsg); - pMsg = doBuildMsgHeader(pSql, &pStart); - pAlterMsg = (SCreateUserMsg *)pMsg; + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } + + SCreateUserMsg *pAlterMsg = (SCreateUserMsg*)pCmd->payload; SUserInfo *pUser = &pInfo->pDCLInfo->user; strncpy(pAlterMsg->user, pUser->user.z, pUser->user.n); - pAlterMsg->flag = pUser->type; if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) { @@ -2028,9 +1766,6 @@ int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) { strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n); } - pMsg += sizeof(SCreateUserMsg); - pCmd->payloadLen = pMsg - pStart; - if (pUser->type == TSDB_ALTER_USER_PASSWD || pUser->type == TSDB_ALTER_USER_PRIVILEGES) { pCmd->msgType = TSDB_MSG_TYPE_ALTER_USER; } else { @@ -2041,178 +1776,127 @@ int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int32_t tscBuildCfgDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - char * pStart = NULL; SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SCfgDnodeMsg); - char *pMsg = doBuildMsgHeader(pSql, &pStart); - pMsg += sizeof(SCfgMsg); + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - pCmd->payloadLen = pMsg - pStart; pCmd->msgType = TSDB_MSG_TYPE_DNODE_CFG; - return TSDB_CODE_SUCCESS; } -char *doBuildMsgHeader(SSqlObj *pSql, char **pStart) { - SSqlCmd *pCmd = &pSql->cmd; - STscObj *pObj = pSql->pTscObj; - - char *pMsg = pCmd->payload + tsRpcHeadSize; - *pStart = pMsg; - - SMgmtHead *pMgmt = (SMgmtHead *)pMsg; - strcpy(pMgmt->db, pObj->db); - - pMsg += sizeof(SMgmtHead); - - return pMsg; -} - int32_t tscBuildDropDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SDropDbMsg *pDropDbMsg; - char * pMsg, *pStart; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SDropDbMsg); + + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - pMsg = doBuildMsgHeader(pSql, &pStart); - pDropDbMsg = (SDropDbMsg *)pMsg; + SDropDbMsg *pDropDbMsg = (SDropDbMsg*)pCmd->payload; SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); strncpy(pDropDbMsg->db, pMeterMetaInfo->name, tListLen(pDropDbMsg->db)); pDropDbMsg->ignoreNotExists = pInfo->pDCLInfo->existsCheck ? 1 : 0; - pMsg += sizeof(SDropDbMsg); - - pCmd->payloadLen = pMsg - pStart; pCmd->msgType = TSDB_MSG_TYPE_DROP_DB; - return TSDB_CODE_SUCCESS; } int32_t tscBuildDropTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SDropTableMsg *pDropTableMsg; - char * pMsg, *pStart; - int msgLen = 0; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SDropTableMsg); - //pMsg = doBuildMsgHeader(pSql, &pStart); - SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - - pMsg = pCmd->payload + tsRpcHeadSize; - pStart = pMsg; - - SMgmtHead *pMgmt = (SMgmtHead *)pMsg; - tscGetDBInfoFromMeterId(pMeterMetaInfo->name, pMgmt->db); - pMsg += sizeof(SMgmtHead); - - pDropTableMsg = (SDropTableMsg *)pMsg; - - strcpy(pDropTableMsg->meterId, pMeterMetaInfo->name); + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } + SDropTableMsg *pDropTableMsg = (SDropTableMsg*)pCmd->payload; + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); + strcpy(pDropTableMsg->tableId, pMeterMetaInfo->name); pDropTableMsg->igNotExists = pInfo->pDCLInfo->existsCheck ? 1 : 0; - pMsg += sizeof(SDropTableMsg); - msgLen = pMsg - pStart; - pCmd->payloadLen = msgLen; pCmd->msgType = TSDB_MSG_TYPE_DROP_TABLE; - return TSDB_CODE_SUCCESS; } int32_t tscBuildDropDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SDropDnodeMsg *pDrop; - char * pMsg, *pStart; + SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SDropDnodeMsg); + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - SSqlCmd * pCmd = &pSql->cmd; + SDropDnodeMsg *pDrop = (SDropDnodeMsg *)pCmd->payload; SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - - pMsg = doBuildMsgHeader(pSql, &pStart); - pDrop = (SDropDnodeMsg *)pMsg; - strcpy(pDrop->ip, pMeterMetaInfo->name); - - pMsg += sizeof(SDropDnodeMsg); - - pCmd->payloadLen = pMsg - pStart; pCmd->msgType = TSDB_MSG_TYPE_DROP_DNODE; return TSDB_CODE_SUCCESS; } int32_t tscBuildDropAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SDropUserMsg *pDropMsg; - char * pMsg, *pStart; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SDropUserMsg); + pCmd->msgType = TSDB_MSG_TYPE_DROP_USER; - pMsg = doBuildMsgHeader(pSql, &pStart); - pDropMsg = (SDropUserMsg *)pMsg; + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } + SDropUserMsg *pDropMsg = (SDropUserMsg*)pCmd->payload; SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); strcpy(pDropMsg->user, pMeterMetaInfo->name); - pMsg += sizeof(SDropUserMsg); - - pCmd->payloadLen = pMsg - pStart; - pCmd->msgType = TSDB_MSG_TYPE_DROP_USER; - return TSDB_CODE_SUCCESS; } int32_t tscBuildUseDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SUseDbMsg *pUseDbMsg; - char * pMsg, *pStart; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SUseDbMsg); - pMsg = doBuildMsgHeader(pSql, &pStart); - pUseDbMsg = (SUseDbMsg *)pMsg; + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } + SUseDbMsg *pUseDbMsg = (SUseDbMsg*)pCmd->payload; SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); strcpy(pUseDbMsg->db, pMeterMetaInfo->name); - - pMsg += sizeof(SUseDbMsg); - - pCmd->payloadLen = pMsg - pStart; pCmd->msgType = TSDB_MSG_TYPE_USE_DB; return TSDB_CODE_SUCCESS; } int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SShowMsg *pShowMsg; - char * pMsg, *pStart; - int msgLen = 0; - - SSqlCmd *pCmd = &pSql->cmd; STscObj *pObj = pSql->pTscObj; + SSqlCmd *pCmd = &pSql->cmd; + pCmd->msgType = TSDB_MSG_TYPE_SHOW; + pCmd->payloadLen = sizeof(SShowMsg) + 100; - int32_t size = minMsgSize() + sizeof(SMgmtHead) + sizeof(SShowTableMsg) + pCmd->payloadLen + TSDB_EXTRA_PAYLOAD_SIZE; - if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) { - tscError("%p failed to malloc for show msg", pSql); - return -1; + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; } - pMsg = pCmd->payload + tsRpcHeadSize; - pStart = pMsg; - - SMgmtHead *pMgmt = (SMgmtHead *)pMsg; + SShowMsg *pShowMsg = (SShowMsg*)pCmd->payload; SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - size_t nameLen = strlen(pMeterMetaInfo->name); - + size_t nameLen = strlen(pMeterMetaInfo->name); if (nameLen > 0) { - strcpy(pMgmt->db, pMeterMetaInfo->name); // prefix is set here + strcpy(pShowMsg->db, pMeterMetaInfo->name); // prefix is set here } else { - strcpy(pMgmt->db, pObj->db); + strcpy(pShowMsg->db, pObj->db); } - pMsg += sizeof(SMgmtHead); - - pShowMsg = (SShowMsg *)pMsg; SShowInfo *pShowInfo = &pInfo->pDCLInfo->showOpt; - pShowMsg->type = pShowInfo->showType; if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) { @@ -2221,41 +1905,29 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) { strncpy(pShowMsg->payload, pPattern->z, pPattern->n); pShowMsg->payloadLen = htons(pPattern->n); } - pMsg += (sizeof(SShowTableMsg) + pPattern->n); } else { SSQLToken *pIpAddr = &pShowInfo->prefix; assert(pIpAddr->n > 0 && pIpAddr->type > 0); strncpy(pShowMsg->payload, pIpAddr->z, pIpAddr->n); pShowMsg->payloadLen = htons(pIpAddr->n); - - pMsg += (sizeof(SShowTableMsg) + pIpAddr->n); } - pCmd->payloadLen = pMsg - pStart; - pCmd->msgType = TSDB_MSG_TYPE_SHOW; - - assert(msgLen + minMsgSize() <= size); - + pCmd->payloadLen = sizeof(SShowMsg) + pShowMsg->payloadLen; return TSDB_CODE_SUCCESS; } int32_t tscBuildKillMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SKillQuery *pKill; - char * pMsg, *pStart; - SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SKillQueryMsg); - pMsg = doBuildMsgHeader(pSql, &pStart); - pKill = (SKillQuery *)pMsg; + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - pKill->handle = 0; + SKillQueryMsg *pKill = (SKillQueryMsg*)pCmd->payload; strncpy(pKill->queryId, pInfo->pDCLInfo->ip.z, pInfo->pDCLInfo->ip.n); - - pMsg += sizeof(SKillQuery); - - pCmd->payloadLen = pMsg - pStart; - switch (pCmd->command) { case TSDB_SQL_KILL_QUERY: pCmd->msgType = TSDB_MSG_TYPE_KILL_QUERY; @@ -2290,12 +1962,9 @@ int tscEstimateCreateTableMsgLength(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SCreateTableMsg *pCreateTableMsg; - char * pMsg, *pStart; int msgLen = 0; SSchema * pSchema; int size = 0; - SSqlCmd *pCmd = &pSql->cmd; SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); @@ -2308,18 +1977,12 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return TSDB_CODE_CLI_OUT_OF_MEMORY; } - pMsg = pCmd->payload + tsRpcHeadSize; - pStart = pMsg; - SMgmtHead *pMgmt = (SMgmtHead *)pMsg; + SCreateTableMsg *pCreateTableMsg = (SCreateTableMsg *)pCmd->payload; + strcpy(pCreateTableMsg->tableId, pMeterMetaInfo->name); // use dbinfo from table id without modifying current db info - tscGetDBInfoFromMeterId(pMeterMetaInfo->name, pMgmt->db); - - pMsg += sizeof(SMgmtHead); - - pCreateTableMsg = (SCreateTableMsg *)pMsg; - strcpy(pCreateTableMsg->meterId, pMeterMetaInfo->name); + tscGetDBInfoFromMeterId(pMeterMetaInfo->name, pCreateTableMsg->db); SCreateTableSQL *pCreateTable = pInfo->pCreateTableInfo; @@ -2329,7 +1992,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pCreateTableMsg->numOfTags = htons(pCmd->count); pCreateTableMsg->sqlLen = 0; - pMsg = (char *)pCreateTableMsg->schema; + char *pMsg = (char *)pCreateTableMsg->schema; int8_t type = pInfo->pCreateTableInfo->type; if (type == TSQL_CREATE_TABLE_FROM_STABLE) { // create by using super table, tags value @@ -2360,7 +2023,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { tscClearFieldInfo(&pQueryInfo->fieldsInfo); - msgLen = pMsg - pStart; + msgLen = pMsg - (char*)pCreateTableMsg; pCmd->payloadLen = msgLen; pCmd->msgType = TSDB_MSG_TYPE_CREATE_TABLE; @@ -2391,17 +2054,13 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return -1; } - pMsg = pCmd->payload + tsRpcHeadSize; - pStart = pMsg; + pAlterTableMsg = (SAlterTableMsg *)pCmd->payload; - SMgmtHead *pMgmt = (SMgmtHead *)pMsg; - tscGetDBInfoFromMeterId(pMeterMetaInfo->name, pMgmt->db); - pMsg += sizeof(SMgmtHead); + tscGetDBInfoFromMeterId(pMeterMetaInfo->name, pAlterTableMsg->db); SAlterTableSQL *pAlterInfo = pInfo->pAlterInfo; - pAlterTableMsg = (SAlterTableMsg *)pMsg; - strcpy(pAlterTableMsg->meterId, pMeterMetaInfo->name); + strcpy(pAlterTableMsg->tableId, pMeterMetaInfo->name); pAlterTableMsg->type = htons(pAlterInfo->type); pAlterTableMsg->numOfCols = htons(tscNumOfFields(pQueryInfo)); @@ -2419,7 +2078,7 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pMsg = (char *)pSchema; - msgLen = pMsg - pStart; + msgLen = pMsg - (char*)pAlterTableMsg; pCmd->payloadLen = msgLen; pCmd->msgType = TSDB_MSG_TYPE_ALTER_TABLE; @@ -2429,65 +2088,36 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscAlterDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SAlterDbMsg *pAlterDbMsg; - char * pMsg, *pStart; - int msgLen = 0; - - SSqlCmd * pCmd = &pSql->cmd; - STscObj * pObj = pSql->pTscObj; - SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); - - pStart = pCmd->payload + tsRpcHeadSize; - pMsg = pStart; + SSqlCmd *pCmd = &pSql->cmd; + pCmd->payloadLen = sizeof(SAlterDbMsg); + pCmd->msgType = TSDB_MSG_TYPE_ALTER_DB; - SMgmtHead *pMgmt = (SMgmtHead *)pMsg; - strcpy(pMgmt->db, pObj->db); - pMsg += sizeof(SMgmtHead); + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - pAlterDbMsg = (SAlterDbMsg *)pMsg; + SAlterDbMsg *pAlterDbMsg = (SAlterDbMsg*)pCmd->payload; + SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); strcpy(pAlterDbMsg->db, pMeterMetaInfo->name); - pMsg += sizeof(SAlterDbMsg); - - msgLen = pMsg - pStart; - pCmd->payloadLen = msgLen; - pCmd->msgType = TSDB_MSG_TYPE_ALTER_DB; - return TSDB_CODE_SUCCESS; } int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - char *pMsg, *pStart; - int msgLen = 0; - SSqlCmd *pCmd = &pSql->cmd; - STscObj *pObj = pSql->pTscObj; - pMsg = pCmd->payload + tsRpcHeadSize; - pStart = pMsg; - - SMgmtHead *pMgmt = (SMgmtHead *)pMsg; - - SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); - SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - size_t nameLen = strlen(pMeterMetaInfo->name); + pCmd->msgType = TSDB_MSG_TYPE_RETRIEVE; + pCmd->payloadLen = sizeof(SRetrieveTableMsg); - if (nameLen > 0) { - strcpy(pMgmt->db, pMeterMetaInfo->name); - } else { - strcpy(pMgmt->db, pObj->db); + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; } - pMsg += sizeof(SMgmtHead); - - *((uint64_t *)pMsg) = pSql->res.qhandle; - pMsg += sizeof(pSql->res.qhandle); - - *((uint16_t *)pMsg) = htons(pQueryInfo->type); - pMsg += sizeof(pQueryInfo->type); - - msgLen = pMsg - pStart; - pCmd->payloadLen = msgLen; - pCmd->msgType = TSDB_MSG_TYPE_DNODE_RETRIEVE; + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg*)pCmd->payload; + pRetrieveMsg->qhandle = htobe64(pSql->res.qhandle); + pRetrieveMsg->free = htons(pQueryInfo->type); return TSDB_CODE_SUCCESS; } @@ -2498,16 +2128,8 @@ static int tscSetResultPointer(SQueryInfo *pQueryInfo, SSqlRes *pRes) { } for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); - int16_t offset = tscFieldInfoGetOffset(pQueryInfo, i); - - pRes->bytes[i] = pField->bytes; -// if (pQueryInfo->order.order == TSQL_SO_DESC) { -// pRes->bytes[i] = -pRes->bytes[i]; -// pRes->tsrow[i] = ((pRes->data + offset * pRes->numOfRows) + (pRes->numOfRows - 1) * pField->bytes); -// } else { - pRes->tsrow[i] = (pRes->data + offset * pRes->numOfRows); -// } + int16_t offset = tscFieldInfoGetOffset(pQueryInfo, i); + pRes->tsrow[i] = (pRes->data + offset * pRes->numOfRows); } return 0; @@ -2566,7 +2188,7 @@ int tscProcessTagRetrieveRsp(SSqlObj *pSql) { int32_t numOfRes = 0; if (tscSqlExprGet(pQueryInfo, 0)->functionId == TSDB_FUNC_TAGPRJ) { - numOfRes = pMeterMetaInfo->pMetricMeta->numOfMeters; + numOfRes = pMeterMetaInfo->pMetricMeta->numOfTables; } else { numOfRes = 1; // for count function, there is only one output. } @@ -2601,34 +2223,31 @@ int tscProcessRetrieveMetricRsp(SSqlObj *pSql) { int tscProcessEmptyResultRsp(SSqlObj *pSql) { return tscLocalResultCommonBuilder(pSql, 0); } int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SConnectMsg *pConnect; - char * pMsg, *pStart; - - SSqlCmd *pCmd = &pSql->cmd; STscObj *pObj = pSql->pTscObj; - pMsg = pCmd->payload + tsRpcHeadSize; - pStart = pMsg; + SSqlCmd *pCmd = &pSql->cmd; + pCmd->msgType = TSDB_MSG_TYPE_CONNECT; + pCmd->payloadLen = sizeof(SConnectMsg); + + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { + tscError("%p failed to malloc for query msg", pSql); + return TSDB_CODE_CLI_OUT_OF_MEMORY; + } - pConnect = (SConnectMsg *)pMsg; + SConnectMsg *pConnect = (SConnectMsg*)pCmd->payload; char *db; // ugly code to move the space db = strstr(pObj->db, TS_PATH_DELIMITER); db = (db == NULL) ? pObj->db : db + 1; strcpy(pConnect->db, db); - strcpy(pConnect->clientVersion, version); - - pMsg += sizeof(SConnectMsg); - - pCmd->payloadLen = pMsg - pStart; - pCmd->msgType = TSDB_MSG_TYPE_CONNECT; + strcpy(pConnect->msgVersion, ""); return TSDB_CODE_SUCCESS; } int tscBuildMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SMeterInfoMsg *pInfoMsg; - char * pMsg, *pStart; + STableInfoMsg *pInfoMsg; + char * pMsg; int msgLen = 0; char *tmpData = 0; @@ -2647,25 +2266,18 @@ int tscBuildMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - pMsg = pCmd->payload + tsRpcHeadSize; - pStart = pMsg; - - SMgmtHead *pMgmt = (SMgmtHead *)pMsg; - tscGetDBInfoFromMeterId(pMeterMetaInfo->name, pMgmt->db); - - pMsg += sizeof(SMgmtHead); - - pInfoMsg = (SMeterInfoMsg *)pMsg; - strcpy(pInfoMsg->meterId, pMeterMetaInfo->name); + pInfoMsg = (STableInfoMsg *)pCmd->payload; + strcpy(pInfoMsg->tableId, pMeterMetaInfo->name); pInfoMsg->createFlag = htons(pSql->cmd.createOnDemand ? 1 : 0); - pMsg += sizeof(SMeterInfoMsg); + + pMsg = (char*)pInfoMsg + sizeof(STableInfoMsg); if (pSql->cmd.createOnDemand) { memcpy(pInfoMsg->tags, tmpData, sizeof(STagData)); pMsg += sizeof(STagData); } - msgLen = pMsg - pStart; + msgLen = pMsg - (char*)pInfoMsg; pCmd->payloadLen = msgLen; pCmd->msgType = TSDB_MSG_TYPE_TABLE_META; @@ -2677,7 +2289,7 @@ int tscBuildMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { /** * multi meter meta req pkg format: - * | SMgmtHead | SMultiMeterInfoMsg | meterId0 | meterId1 | meterId2 | ...... + * | SMgmtHead | SMultiTableInfoMsg | tableId0 | tableId1 | tableId2 | ...... * no used 4B **/ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { @@ -2695,21 +2307,21 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SMgmtHead *pMgmt = (SMgmtHead *)(pCmd->payload + tsRpcHeadSize); memset(pMgmt->db, 0, TSDB_TABLE_ID_LEN); // server don't need the db - SMultiMeterInfoMsg *pInfoMsg = (SMultiMeterInfoMsg *)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead)); - pInfoMsg->numOfMeters = htonl((int32_t)pCmd->count); + SMultiTableInfoMsg *pInfoMsg = (SMultiTableInfoMsg *)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead)); + pInfoMsg->numOfTables = htonl((int32_t)pCmd->count); if (pCmd->payloadLen > 0) { - memcpy(pInfoMsg->meterId, tmpData, pCmd->payloadLen); + memcpy(pInfoMsg->tableIds, tmpData, pCmd->payloadLen); } tfree(tmpData); - pCmd->payloadLen += sizeof(SMgmtHead) + sizeof(SMultiMeterInfoMsg); + pCmd->payloadLen += sizeof(SMgmtHead) + sizeof(SMultiTableInfoMsg); pCmd->msgType = TSDB_MSG_TYPE_MULTI_TABLE_META; assert(pCmd->payloadLen + minMsgSize() <= pCmd->allocSize); - tscTrace("%p build load multi-metermeta msg completed, numOfMeters:%d, msg size:%d", pSql, pCmd->count, + tscTrace("%p build load multi-metermeta msg completed, numOfTables:%d, msg size:%d", pSql, pCmd->count, pCmd->payloadLen); return pCmd->payloadLen; @@ -2731,9 +2343,11 @@ static int32_t tscEstimateMetricMetaMsgSize(SSqlCmd *pCmd) { } int32_t joinCondLen = (TSDB_TABLE_ID_LEN + sizeof(int16_t)) * 2; - int32_t elemSize = sizeof(SMetricMetaElemMsg) * pQueryInfo->numOfTables; + int32_t elemSize = sizeof(SSuperTableMetaElemMsg) * pQueryInfo->numOfTables; + + int32_t colSize = pQueryInfo->groupbyExpr.numOfGroupCols*sizeof(SColIndexEx); - int32_t len = tagLen + joinCondLen + elemSize + defaultSize; + int32_t len = tagLen + joinCondLen + elemSize + colSize + defaultSize; return MAX(len, TSDB_DEFAULT_PAYLOAD_SIZE); } @@ -2766,7 +2380,7 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pMsg += sizeof(SMgmtHead); pMetaMsg = (SSuperTableMetaMsg *)pMsg; - pMetaMsg->numOfMeters = htonl(pQueryInfo->numOfTables); + pMetaMsg->numOfTables = htonl(pQueryInfo->numOfTables); pMsg += sizeof(SSuperTableMetaMsg); @@ -2776,13 +2390,13 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { // todo refactor pMetaMsg->joinCondLen = htonl((TSDB_TABLE_ID_LEN + sizeof(int16_t)) * 2); - memcpy(pMsg, pTagCond->joinInfo.left.meterId, TSDB_TABLE_ID_LEN); + memcpy(pMsg, pTagCond->joinInfo.left.tableId, TSDB_TABLE_ID_LEN); pMsg += TSDB_TABLE_ID_LEN; *(int16_t *)pMsg = pTagCond->joinInfo.left.tagCol; pMsg += sizeof(int16_t); - memcpy(pMsg, pTagCond->joinInfo.right.meterId, TSDB_TABLE_ID_LEN); + memcpy(pMsg, pTagCond->joinInfo.right.tableId, TSDB_TABLE_ID_LEN); pMsg += TSDB_TABLE_ID_LEN; *(int16_t *)pMsg = pTagCond->joinInfo.right.tagCol; @@ -2795,14 +2409,14 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { offset = pMsg - (char *)pMetaMsg; pMetaMsg->metaElem[i] = htonl(offset); - SMetricMetaElemMsg *pElem = (SMetricMetaElemMsg *)pMsg; - pMsg += sizeof(SMetricMetaElemMsg); + SSuperTableMetaElemMsg *pElem = (SSuperTableMetaElemMsg *)pMsg; + pMsg += sizeof(SSuperTableMetaElemMsg); // convert to unicode before sending to mnode for metric query int32_t condLen = 0; if (pTagCond->numOfTagCond > 0) { SCond *pCond = tsGetMetricQueryCondPos(pTagCond, uid); - if (pCond != NULL) { + if (pCond != NULL && pCond->cond != NULL) { condLen = strlen(pCond->cond) + 1; bool ret = taosMbsToUcs4(pCond->cond, condLen, pMsg, condLen * TSDB_NCHAR_SIZE); @@ -2824,11 +2438,14 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { offset = pMsg - (char *)pMetaMsg; pElem->tableCond = htonl(offset); - - uint32_t len = strlen(pTagCond->tbnameCond.cond); + + uint32_t len = 0; + if (pTagCond->tbnameCond.cond != NULL) { + len = strlen(pTagCond->tbnameCond.cond); + memcpy(pMsg, pTagCond->tbnameCond.cond, len); + } + pElem->tableCondLen = htonl(len); - - memcpy(pMsg, pTagCond->tbnameCond.cond, len); pMsg += len; } @@ -2858,13 +2475,14 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pDestCol->colIdx = htons(pCol->colIdx); pDestCol->colId = htons(pDestCol->colId); pDestCol->flag = htons(pDestCol->flag); + strncpy(pDestCol->name, pCol->name, tListLen(pCol->name)); pMsg += sizeof(SColIndexEx); } } } - strcpy(pElem->meterId, pMeterMetaInfo->name); + strcpy(pElem->tableId, pMeterMetaInfo->name); pElem->numOfTags = htons(pMeterMetaInfo->numOfTags); int16_t len = pMsg - (char *)pElem; @@ -2884,18 +2502,18 @@ int tscEstimateHeartBeatMsgLength(SSqlObj *pSql) { STscObj *pObj = pSql->pTscObj; size += tsRpcHeadSize + sizeof(SMgmtHead); - size += sizeof(SQList); + size += sizeof(SQqueryList); SSqlObj *tpSql = pObj->sqlList; while (tpSql) { - size += sizeof(SQDesc); + size += sizeof(SQueryDesc); tpSql = tpSql->next; } - size += sizeof(SSList); + size += sizeof(SStreamList); SSqlStream *pStream = pObj->streamList; while (pStream) { - size += sizeof(SSDesc); + size += sizeof(SStreamDesc); pStream = pStream->next; } @@ -2937,25 +2555,17 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscProcessMeterMetaRsp(SSqlObj *pSql) { - SMeterMeta *pMeta; + STableMeta *pMeta; SSchema * pSchema; uint8_t ieType; - char *rsp = pSql->res.pRsp; - - ieType = *rsp; - if (ieType != TSDB_IE_TYPE_META) { - tscError("invalid ie type:%d", ieType); - return TSDB_CODE_INVALID_IE; - } - - rsp++; - pMeta = (SMeterMeta *)rsp; + pMeta = (STableMeta *)pSql->res.pRsp; pMeta->sid = htonl(pMeta->sid); pMeta->sversion = htons(pMeta->sversion); pMeta->vgid = htonl(pMeta->vgid); pMeta->uid = htobe64(pMeta->uid); + pMeta->contLen = htons(pMeta->contLen); if (pMeta->sid < 0 || pMeta->vgid < 0) { tscError("invalid meter vgid:%d, sid%d", pMeta->vgid, pMeta->sid); @@ -2979,8 +2589,7 @@ int tscProcessMeterMetaRsp(SSqlObj *pSql) { } pMeta->rowSize = 0; - rsp += sizeof(SMeterMeta); - pSchema = (SSchema *)rsp; + pSchema = (SSchema *)(pSql->res.pRsp + sizeof(STableMeta)); int32_t numOfTotalCols = pMeta->numOfColumns + pMeta->numOfTags; for (int i = 0; i < numOfTotalCols; ++i) { @@ -2994,29 +2603,29 @@ int tscProcessMeterMetaRsp(SSqlObj *pSql) { pSchema++; } - rsp += numOfTotalCols * sizeof(SSchema); - - int32_t tagLen = 0; - SSchema *pTagsSchema = tsGetTagSchema(pMeta); - - if (pMeta->tableType == TSDB_TABLE_TYPE_CHILD_TABLE) { - for (int32_t i = 0; i < pMeta->numOfTags; ++i) { - tagLen += pTagsSchema[i].bytes; - } - } - - rsp += tagLen; - int32_t size = (int32_t)(rsp - (char *)pMeta); +// rsp += numOfTotalCols * sizeof(SSchema); +// +// int32_t tagLen = 0; +// SSchema *pTagsSchema = tsGetTagSchema(pMeta); +// +// if (pMeta->tableType == TSDB_TABLE_TYPE_CHILD_TABLE) { +// for (int32_t i = 0; i < pMeta->numOfTags; ++i) { +// tagLen += pTagsSchema[i].bytes; +// } +// } +// +// rsp += tagLen; +// int32_t size = (int32_t)(rsp - (char *)pMeta); // pMeta->index = rand() % TSDB_VNODES_SUPPORT; - pMeta->index = 0; +// pMeta->index = 0; // todo add one more function: taosAddDataIfNotExists(); SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0, 0); assert(pMeterMetaInfo->pMeterMeta == NULL); - pMeterMetaInfo->pMeterMeta = (SMeterMeta *)taosAddDataIntoCache(tscCacheHandle, pMeterMetaInfo->name, (char *)pMeta, - size, tsMeterMetaKeepTimer); + pMeterMetaInfo->pMeterMeta = (STableMeta *)taosAddDataIntoCache(tscCacheHandle, pMeterMetaInfo->name, (char *)pMeta, + pMeta->contLen, tsMeterMetaKeepTimer); // todo handle out of memory case if (pMeterMetaInfo->pMeterMeta == NULL) return 0; @@ -3025,7 +2634,7 @@ int tscProcessMeterMetaRsp(SSqlObj *pSql) { /** * multi meter meta rsp pkg format: - * | STaosRsp | ieType | SMultiMeterInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2 + * | STaosRsp | ieType | SMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2 * |...... 1B 1B 4B **/ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { @@ -3046,13 +2655,13 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { rsp++; - SMultiMeterInfoMsg *pInfo = (SMultiMeterInfoMsg *)rsp; - totalNum = htonl(pInfo->numOfMeters); - rsp += sizeof(SMultiMeterInfoMsg); + SMultiTableInfoMsg *pInfo = (SMultiTableInfoMsg *)rsp; + totalNum = htonl(pInfo->numOfTables); + rsp += sizeof(SMultiTableInfoMsg); for (i = 0; i < totalNum; i++) { - SMultiMeterMeta *pMultiMeta = (SMultiMeterMeta *)rsp; - SMeterMeta * pMeta = &pMultiMeta->meta; + SMultiTableMeta *pMultiMeta = (SMultiTableMeta *)rsp; + STableMeta * pMeta = &pMultiMeta->metas; pMeta->sid = htonl(pMeta->sid); pMeta->sversion = htons(pMeta->sversion); @@ -3094,7 +2703,7 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { } pMeta->rowSize = 0; - rsp += sizeof(SMultiMeterMeta); + rsp += sizeof(SMultiTableMeta); pSchema = (SSchema *)rsp; int32_t numOfTotalCols = pMeta->numOfColumns + pMeta->numOfTags; @@ -3121,10 +2730,10 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { } rsp += tagLen; - int32_t size = (int32_t)(rsp - ((char *)pMeta)); // Consistent with SMeterMeta in cache + int32_t size = (int32_t)(rsp - ((char *)pMeta)); // Consistent with STableMeta in cache pMeta->index = 0; - (void)taosAddDataIntoCache(tscCacheHandle, pMultiMeta->meterId, (char *)pMeta, size, tsMeterMetaKeepTimer); + (void)taosAddDataIntoCache(tscCacheHandle, pMeta->tableId, (char *)pMeta, size, tsMeterMetaKeepTimer); } pSql->res.code = TSDB_CODE_SUCCESS; @@ -3134,7 +2743,7 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { } int tscProcessMetricMetaRsp(SSqlObj *pSql) { - SMetricMeta *pMeta; + SSuperTableMeta *pMeta; uint8_t ieType; void ** metricMetaList = NULL; int32_t * sizes = NULL; @@ -3165,16 +2774,16 @@ int tscProcessMetricMetaRsp(SSqlObj *pSql) { } for (int32_t k = 0; k < num; ++k) { - pMeta = (SMetricMeta *)rsp; + pMeta = (SSuperTableMeta *)rsp; size_t size = (size_t)pSql->res.rspLen - 1; - rsp = rsp + sizeof(SMetricMeta); + rsp = rsp + sizeof(SSuperTableMeta); - pMeta->numOfMeters = htonl(pMeta->numOfMeters); + pMeta->numOfTables = htonl(pMeta->numOfTables); pMeta->numOfVnodes = htonl(pMeta->numOfVnodes); pMeta->tagLen = htons(pMeta->tagLen); - size += pMeta->numOfVnodes * sizeof(SVnodeSidList *) + pMeta->numOfMeters * sizeof(SMeterSidExtInfo *); + size += pMeta->numOfVnodes * sizeof(SVnodeSidList *) + pMeta->numOfTables * sizeof(STableSidExtInfo *); char *pBuf = calloc(1, size); if (pBuf == NULL) { @@ -3182,14 +2791,14 @@ int tscProcessMetricMetaRsp(SSqlObj *pSql) { goto _error_clean; } - SMetricMeta *pNewMetricMeta = (SMetricMeta *)pBuf; + SSuperTableMeta *pNewMetricMeta = (SSuperTableMeta *)pBuf; metricMetaList[k] = pNewMetricMeta; - pNewMetricMeta->numOfMeters = pMeta->numOfMeters; + pNewMetricMeta->numOfTables = pMeta->numOfTables; pNewMetricMeta->numOfVnodes = pMeta->numOfVnodes; pNewMetricMeta->tagLen = pMeta->tagLen; - pBuf = pBuf + sizeof(SMetricMeta) + pNewMetricMeta->numOfVnodes * sizeof(SVnodeSidList *); + pBuf = pBuf + sizeof(SSuperTableMeta) + pNewMetricMeta->numOfVnodes * sizeof(SVnodeSidList *); for (int32_t i = 0; i < pMeta->numOfVnodes; ++i) { SVnodeSidList *pSidLists = (SVnodeSidList *)rsp; @@ -3198,18 +2807,18 @@ int tscProcessMetricMetaRsp(SSqlObj *pSql) { pNewMetricMeta->list[i] = pBuf - (char *)pNewMetricMeta; // offset value SVnodeSidList *pLists = (SVnodeSidList *)pBuf; - tscTrace("%p metricmeta:vid:%d,numOfMeters:%d", pSql, i, pLists->numOfSids); + tscTrace("%p metricmeta:vid:%d,numOfTables:%d", pSql, i, pLists->numOfSids); - pBuf += sizeof(SVnodeSidList) + sizeof(SMeterSidExtInfo *) * pSidLists->numOfSids; + pBuf += sizeof(SVnodeSidList) + sizeof(STableSidExtInfo *) * pSidLists->numOfSids; rsp += sizeof(SVnodeSidList); - size_t elemSize = sizeof(SMeterSidExtInfo) + pNewMetricMeta->tagLen; + size_t elemSize = sizeof(STableSidExtInfo) + pNewMetricMeta->tagLen; for (int32_t j = 0; j < pSidLists->numOfSids; ++j) { pLists->pSidExtInfoList[j] = pBuf - (char *)pLists; memcpy(pBuf, rsp, elemSize); - ((SMeterSidExtInfo *)pBuf)->uid = htobe64(((SMeterSidExtInfo *)pBuf)->uid); - ((SMeterSidExtInfo *)pBuf)->sid = htonl(((SMeterSidExtInfo *)pBuf)->sid); + ((STableSidExtInfo *)pBuf)->uid = htobe64(((STableSidExtInfo *)pBuf)->uid); + ((STableSidExtInfo *)pBuf)->sid = htonl(((STableSidExtInfo *)pBuf)->sid); rsp += elemSize; pBuf += elemSize; @@ -3233,7 +2842,7 @@ int tscProcessMetricMetaRsp(SSqlObj *pSql) { // release the used metricmeta taosRemoveDataFromCache(tscCacheHandle, (void **)&(pMeterMetaInfo->pMetricMeta), false); - pMeterMetaInfo->pMetricMeta = (SMetricMeta *)taosAddDataIntoCache(tscCacheHandle, name, (char *)metricMetaList[i], + pMeterMetaInfo->pMetricMeta = (SSuperTableMeta *)taosAddDataIntoCache(tscCacheHandle, name, (char *)metricMetaList[i], sizes[i], tsMetricMetaKeepTimer); tfree(metricMetaList[i]); @@ -3260,8 +2869,8 @@ _error_clean: * current process do not use the cache at all */ int tscProcessShowRsp(SSqlObj *pSql) { - SMeterMeta * pMeta; - SShowRspMsg *pShow; + STableMeta * pMeta; + SShowRsp *pShow; SSchema * pSchema; char key[20]; @@ -3272,15 +2881,16 @@ int tscProcessShowRsp(SSqlObj *pSql) { SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0); - pShow = (SShowRspMsg *)pRes->pRsp; + pShow = (SShowRsp *)pRes->pRsp; + pShow->qhandle = htobe64(pShow->qhandle); pRes->qhandle = pShow->qhandle; tscResetForNextRetrieve(pRes); - pMeta = &(pShow->meterMeta); + pMeta = &(pShow->tableMeta); pMeta->numOfColumns = ntohs(pMeta->numOfColumns); - pSchema = (SSchema *)((char *)pMeta + sizeof(SMeterMeta)); + pSchema = (SSchema *)((char *)pMeta + sizeof(STableMeta)); pMeta->sid = ntohs(pMeta->sid); for (int i = 0; i < pMeta->numOfColumns; ++i) { pSchema->bytes = htons(pSchema->bytes); @@ -3292,9 +2902,9 @@ int tscProcessShowRsp(SSqlObj *pSql) { taosRemoveDataFromCache(tscCacheHandle, (void *)&(pMeterMetaInfo->pMeterMeta), false); - int32_t size = pMeta->numOfColumns * sizeof(SSchema) + sizeof(SMeterMeta); + int32_t size = pMeta->numOfColumns * sizeof(SSchema) + sizeof(STableMeta); pMeterMetaInfo->pMeterMeta = - (SMeterMeta *)taosAddDataIntoCache(tscCacheHandle, key, (char *)pMeta, size, tsMeterMetaKeepTimer); + (STableMeta *)taosAddDataIntoCache(tscCacheHandle, key, (char *)pMeta, size, tsMeterMetaKeepTimer); pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutputCols; SSchema *pMeterSchema = tsGetSchema(pMeterMetaInfo->pMeterMeta); @@ -3305,6 +2915,9 @@ int tscProcessShowRsp(SSqlObj *pSql) { index.columnIndex = i; tscColumnBaseInfoInsert(pQueryInfo, &index); tscFieldInfoSetValFromSchema(&pQueryInfo->fieldsInfo, i, &pMeterSchema[i]); + + pQueryInfo->fieldsInfo.pSqlExpr[i] = tscSqlExprInsert(pQueryInfo, i, TSDB_FUNC_TS_DUMMY, &index, + pMeterSchema[i].type, pMeterSchema[i].bytes, pMeterSchema[i].bytes); } tscFieldInfoCalOffset(pQueryInfo); @@ -3312,25 +2925,23 @@ int tscProcessShowRsp(SSqlObj *pSql) { } int tscProcessConnectRsp(SSqlObj *pSql) { - char temp[TSDB_TABLE_ID_LEN * 2]; - SConnectRsp *pConnect; - + char temp[TSDB_TABLE_ID_LEN * 2]; STscObj *pObj = pSql->pTscObj; SSqlRes *pRes = &pSql->res; - pConnect = (SConnectRsp *)pRes->pRsp; + SConnectRsp *pConnect = (SConnectRsp *)pRes->pRsp; strcpy(pObj->acctId, pConnect->acctId); // copy acctId from response int32_t len = sprintf(temp, "%s%s%s", pObj->acctId, TS_PATH_DELIMITER, pObj->db); assert(len <= tListLen(pObj->db)); strncpy(pObj->db, temp, tListLen(pObj->db)); - SIpList * pIpList; - char *rsp = pRes->pRsp + sizeof(SConnectRsp); - pIpList = (SIpList *)rsp; - tscSetMgmtIpList(pIpList); +// SIpList * pIpList; +// char *rsp = pRes->pRsp + sizeof(SConnectRsp); +// pIpList = (SIpList *)rsp; +// tscSetMgmtIpList(pIpList); - strcpy(pObj->sversion, pConnect->version); + strcpy(pObj->sversion, pConnect->serverVersion); pObj->writeAuth = pConnect->writeAuth; pObj->superAuth = pConnect->superAuth; taosTmrReset(tscProcessActivityTimer, tsShellActivityTimer * 500, pObj, tscTmr, &pObj->pTimer); @@ -3354,7 +2965,7 @@ int tscProcessDropDbRsp(SSqlObj *UNUSED_PARAM(pSql)) { int tscProcessDropTableRsp(SSqlObj *pSql) { SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0, 0); - SMeterMeta *pMeterMeta = taosGetDataFromCache(tscCacheHandle, pMeterMetaInfo->name); + STableMeta *pMeterMeta = taosGetDataFromCache(tscCacheHandle, pMeterMetaInfo->name); if (pMeterMeta == NULL) { /* not in cache, abort */ return 0; @@ -3381,7 +2992,7 @@ int tscProcessDropTableRsp(SSqlObj *pSql) { int tscProcessAlterTableMsgRsp(SSqlObj *pSql) { SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0, 0); - SMeterMeta *pMeterMeta = taosGetDataFromCache(tscCacheHandle, pMeterMetaInfo->name); + STableMeta *pMeterMeta = taosGetDataFromCache(tscCacheHandle, pMeterMetaInfo->name); if (pMeterMeta == NULL) { /* not in cache, abort */ return 0; } @@ -3412,7 +3023,10 @@ int tscProcessAlterDbMsgRsp(SSqlObj *pSql) { int tscProcessQueryRsp(SSqlObj *pSql) { SSqlRes *pRes = &pSql->res; - pRes->qhandle = *((uint64_t *)pRes->pRsp); + SQueryTableRsp *pQuery = (SRetrieveTableRsp *)pRes->pRsp; + pQuery->qhandle = htobe64(pQuery->qhandle); + pRes->qhandle = pQuery->qhandle; + pRes->data = NULL; tscResetForNextRetrieve(pRes); return 0; @@ -3423,7 +3037,7 @@ int tscProcessRetrieveRspFromVnode(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; STscObj *pObj = pSql->pTscObj; - SRetrieveMeterRsp *pRetrieve = (SRetrieveMeterRsp *)pRes->pRsp; + SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp; pRes->numOfRows = htonl(pRetrieve->numOfRows); pRes->precision = htons(pRetrieve->precision); @@ -3442,9 +3056,9 @@ int tscProcessRetrieveRspFromVnode(SSqlObj *pSql) { char* p = pRes->data + (pField->bytes + offset) * pRes->numOfRows; - int32_t numOfMeters = htonl(*(int32_t*)p); + int32_t numOfTables = htonl(*(int32_t*)p); p += sizeof(int32_t); - for (int i = 0; i < numOfMeters; i++) { + for (int i = 0; i < numOfTables; i++) { int64_t uid = htobe64(*(int64_t*)p); p += sizeof(int64_t); TSKEY key = htobe64(*(TSKEY*)p); @@ -3455,18 +3069,7 @@ int tscProcessRetrieveRspFromVnode(SSqlObj *pSql) { pRes->row = 0; - /** - * If the query result is exhausted, or current query is to free resource at server side, - * the connection will be recycled. - */ - if ((pRes->numOfRows == 0 && !(tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && pRes->offset > 0)) || - ((pQueryInfo->type & TSDB_QUERY_TYPE_FREE_RESOURCE) == TSDB_QUERY_TYPE_FREE_RESOURCE)) { - tscTrace("%p no result or free resource, recycle connection", pSql); - taosAddConnIntoCache(tscConnCache, pSql->thandle, pSql->ip, pSql->vnode, pObj->user); - pSql->thandle = NULL; - } else { - tscTrace("%p numOfRows:%d, offset:%d, not recycle connection", pSql, pRes->numOfRows, pRes->offset); - } + tscTrace("%p numOfRows:%d, offset:%d", pSql, pRes->numOfRows, pRes->offset); return 0; } @@ -3476,7 +3079,7 @@ int tscProcessRetrieveRspFromLocal(SSqlObj *pSql) { SSqlCmd * pCmd = &pSql->cmd; SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); - SRetrieveMeterRsp *pRetrieve = (SRetrieveMeterRsp *)pRes->pRsp; + SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp; pRes->numOfRows = htonl(pRetrieve->numOfRows); pRes->data = pRetrieve->data; @@ -3519,7 +3122,7 @@ static int32_t doGetMeterMetaFromServer(SSqlObj *pSql, SMeterMetaInfo *pMeterMet strcpy(pNewMeterMetaInfo->name, pMeterMetaInfo->name); memcpy(pNew->cmd.payload, pSql->cmd.payload, TSDB_DEFAULT_PAYLOAD_SIZE); // tag information if table does not exists. - tscTrace("%p new pSqlObj:%p to get meterMeta", pSql, pNew); + tscTrace("%p new pSqlObj:%p to get tableMeta", pSql, pNew); if (pSql->fp == NULL) { tsem_init(&pNew->rspSem, 0, 0); @@ -3561,11 +3164,11 @@ int tscGetMeterMeta(SSqlObj *pSql, SMeterMetaInfo *pMeterMetaInfo) { taosRemoveDataFromCache(tscCacheHandle, (void **)&(pMeterMetaInfo->pMeterMeta), false); } - pMeterMetaInfo->pMeterMeta = (SMeterMeta *)taosGetDataFromCache(tscCacheHandle, pMeterMetaInfo->name); + pMeterMetaInfo->pMeterMeta = (STableMeta *)taosGetDataFromCache(tscCacheHandle, pMeterMetaInfo->name); if (pMeterMetaInfo->pMeterMeta != NULL) { - SMeterMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta; + STableMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta; - tscTrace("%p retrieve meterMeta from cache, the number of columns:%d, numOfTags:%d", pSql, pMeterMeta->numOfColumns, + tscTrace("%p retrieve tableMeta from cache, the number of columns:%d, numOfTags:%d", pSql, pMeterMeta->numOfColumns, pMeterMeta->numOfTags); return TSDB_CODE_SUCCESS; @@ -3599,10 +3202,10 @@ static void tscWaitingForCreateTable(SSqlCmd *pCmd) { /** * in renew metermeta, do not retrieve metadata in cache. * @param pSql sql object - * @param meterId meter id + * @param tableId meter id * @return status code */ -int tscRenewMeterMeta(SSqlObj *pSql, char *meterId) { +int tscRenewMeterMeta(SSqlObj *pSql, char *tableId) { int code = 0; // handle metric meta renew process @@ -3661,7 +3264,7 @@ int tscGetMetricMeta(SSqlObj *pSql, int32_t clauseIndex) { taosRemoveDataFromCache(tscCacheHandle, (void **)&(pMeterMetaInfo->pMetricMeta), false); - SMetricMeta *ppMeta = (SMetricMeta *)taosGetDataFromCache(tscCacheHandle, tagstr); + SSuperTableMeta *ppMeta = (SSuperTableMeta *)taosGetDataFromCache(tscCacheHandle, tagstr); if (ppMeta == NULL) { required = true; break; @@ -3689,7 +3292,7 @@ int tscGetMetricMeta(SSqlObj *pSql, int32_t clauseIndex) { for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { SMeterMetaInfo *pMMInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, i); - SMeterMeta *pMeterMeta = taosGetDataFromCache(tscCacheHandle, pMMInfo->name); + STableMeta *pMeterMeta = taosGetDataFromCache(tscCacheHandle, pMMInfo->name); tscAddMeterMetaInfo(pNewQueryInfo, pMMInfo->name, pMeterMeta, NULL, pMMInfo->numOfTags, pMMInfo->tagColumnIndex); } @@ -3735,7 +3338,7 @@ int tscGetMetricMeta(SSqlObj *pSql, int32_t clauseIndex) { #endif taosRemoveDataFromCache(tscCacheHandle, (void **)&(pMeterMetaInfo->pMetricMeta), false); - pMeterMetaInfo->pMetricMeta = (SMetricMeta *)taosGetDataFromCache(tscCacheHandle, tagstr); + pMeterMetaInfo->pMetricMeta = (SSuperTableMeta *)taosGetDataFromCache(tscCacheHandle, tagstr); } } diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 0ea4c64204cd56278234cec1448d75b72adb3840..2f3312b0b6dca5d8ec5db584b4ca732b91fcdcdf 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -13,8 +13,9 @@ * along with this program. If not, see . */ -#include "os.h" +#include #include "hash.h" +#include "os.h" #include "tcache.h" #include "tlog.h" #include "tnote.h" @@ -34,12 +35,8 @@ TAOS *taos_connect_imp(const char *ip, const char *user, const char *pass, const void (*fp)(void *, TAOS_RES *, int), void *param, void **taos) { STscObj *pObj; - taos_init(); - if (pTscMgmtConn == NULL || pVnodeConn == NULL) { - globalCode = TSDB_CODE_APP_ERROR; - return NULL; - } + taos_init(); if (user == NULL) { globalCode = TSDB_CODE_INVALID_ACCT; @@ -63,15 +60,30 @@ TAOS *taos_connect_imp(const char *ip, const char *user, const char *pass, const } } + if (tscInitRpc(user, pass) != 0) { + globalCode = TSDB_CODE_NETWORK_UNAVAIL; + return NULL; + } + if (ip && ip[0]) { - tscMgmtIpList.numOfIps = 3; - tscMgmtIpList.ip[0] = inet_addr(ip); - tscMgmtIpList.ip[1] = inet_addr(tsMasterIp); - tscMgmtIpList.ip[2] = inet_addr(tsSecondIp); - tscMgmtIpList.index = 0; + tscMgmtIpList.inUse = 0; tscMgmtIpList.port = tsMgmtShellPort; + tscMgmtIpList.numOfIps = 1; + tscMgmtIpList.ip[0] = inet_addr(ip); + + if (tsMasterIp[0] && strcmp(ip, tsMasterIp) != 0) { + tscMgmtIpList.numOfIps = 2; + tscMgmtIpList.ip[1] = inet_addr(tsMasterIp); + } + + if (tsSecondIp[0] && strcmp(tsSecondIp, tsMasterIp) != 0) { + tscMgmtIpList.numOfIps = 3; + tscMgmtIpList.ip[2] = inet_addr(tsSecondIp); + } } + tscMgmtIpList.port = port ? port : tsMgmtShellPort; + pObj = (STscObj *)malloc(sizeof(STscObj)); if (NULL == pObj) { globalCode = TSDB_CODE_CLI_OUT_OF_MEMORY; @@ -197,7 +209,7 @@ int taos_query_imp(STscObj *pObj, SSqlObj *pSql) { taosCleanUpHashTable(pSql->pTableHashList); pSql->pTableHashList = NULL; } - + tscDump("%p pObj:%p, SQL: %s", pSql, pObj, pSql->sqlstr); pRes->code = (uint8_t)tsParseSql(pSql, false); @@ -208,7 +220,6 @@ int taos_query_imp(STscObj *pObj, SSqlObj *pSql) { * to free connection, which may cause segment fault, when the parse phrase is not even successfully executed. */ pRes->qhandle = 0; - pSql->thandle = NULL; if (pRes->code == TSDB_CODE_SUCCESS) { tscDoQuery(pSql); @@ -364,9 +375,7 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) { SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { -// pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order) + -// pRes->bytes[i] * (1 - pQueryInfo->order.order) * (pRes->numOfRows - 1); - pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order); + pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i); } *rows = pRes->tsrow; @@ -374,54 +383,115 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) { return (pQueryInfo->order.order == TSQL_SO_DESC) ? pRes->numOfRows : -pRes->numOfRows; } +static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) { + SSqlRes *pRes = &pSql->res; + + if (isNull(pRes->tsrow[columnIndex], pField->type)) { + pRes->tsrow[columnIndex] = NULL; + } else if (pField->type == TSDB_DATA_TYPE_NCHAR) { + // convert unicode to native code in a temporary buffer extra one byte for terminated symbol + if (pRes->buffer[columnIndex] == NULL) { + pRes->buffer[columnIndex] = malloc(pField->bytes + TSDB_NCHAR_SIZE); + } + + /* string terminated char for binary data*/ + memset(pRes->buffer[columnIndex], 0, pField->bytes + TSDB_NCHAR_SIZE); + + if (taosUcs4ToMbs(pRes->tsrow[columnIndex], pField->bytes, pRes->buffer[columnIndex])) { + pRes->tsrow[columnIndex] = pRes->buffer[columnIndex]; + } else { + tscError("%p charset:%s to %s. val:%ls convert failed.", pSql, DEFAULT_UNICODE_ENCODEC, tsCharset, pRes->tsrow); + pRes->tsrow[columnIndex] = NULL; + } + } +} + +static char *getArithemicInputSrc(void *param, char *name, int32_t colId) { + SArithmeticSupport *pSupport = (SArithmeticSupport *)param; + SSqlFunctionExpr * pExpr = pSupport->pExpr; + + int32_t index = -1; + for (int32_t i = 0; i < pExpr->pBinExprInfo.numOfCols; ++i) { + if (strcmp(name, pExpr->pBinExprInfo.pReqColumns[i].name) == 0) { + index = i; + break; + } + } + + assert(index >= 0 && index < pExpr->pBinExprInfo.numOfCols); + return pSupport->data[index] + pSupport->offset * pSupport->elemSize[index]; +} + static void **doSetResultRowData(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; - + assert(pRes->row >= 0 && pRes->row <= pRes->numOfRows); - + if (pRes->row >= pRes->numOfRows) { // all the results has returned to invoker tfree(pRes->tsrow); return pRes->tsrow; } - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + + //todo refactor move away + for(int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) { + SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); + + if (k > 0) { + SSqlExpr* pPrev = tscSqlExprGet(pQueryInfo, k - 1); + pExpr->offset = pPrev->offset + pPrev->resBytes; + } + } + int32_t num = 0; - for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) { - pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order) + pRes->bytes[i] * pRes->row; + for (int i = 0; i < tscNumOfFields(pQueryInfo); ++i) { + if (pQueryInfo->fieldsInfo.pSqlExpr[i] != NULL) { + SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[i]; + pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i) + pExpr->resBytes * pRes->row; + } else { + assert(0); + } // primary key column cannot be null in interval query, no need to check - if (i == 0 && pQueryInfo->nAggTimeInterval > 0) { + if (i == 0 && pQueryInfo->intervalTime > 0) { continue; } TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i); - if (isNull(pRes->tsrow[i], pField->type)) { - pRes->tsrow[i] = NULL; - } else if (pField->type == TSDB_DATA_TYPE_NCHAR) { - // convert unicode to native code in a temporary buffer extra one byte for terminated symbol - if (pRes->buffer[num] == NULL) { - pRes->buffer[num] = malloc(pField->bytes + TSDB_NCHAR_SIZE); - } + transferNcharData(pSql, i, pField); - /* string terminated char for binary data*/ - memset(pRes->buffer[num], 0, pField->bytes + TSDB_NCHAR_SIZE); - - if (taosUcs4ToMbs(pRes->tsrow[i], pField->bytes, pRes->buffer[num])) { - pRes->tsrow[i] = pRes->buffer[num]; - } else { - tscError("%p charset:%s to %s. val:%ls convert failed.", pSql, DEFAULT_UNICODE_ENCODEC, tsCharset, pRes->tsrow); - pRes->tsrow[i] = NULL; + // calculate the result from serveral other columns + if (pQueryInfo->fieldsInfo.pExpr != NULL && pQueryInfo->fieldsInfo.pExpr[i] != NULL) { + SArithmeticSupport *sas = (SArithmeticSupport *)calloc(1, sizeof(SArithmeticSupport)); + sas->offset = 0; + sas->pExpr = pQueryInfo->fieldsInfo.pExpr[i]; + + sas->numOfCols = sas->pExpr->pBinExprInfo.numOfCols; + + if (pRes->buffer[i] == NULL) { + pRes->buffer[i] = malloc(tscFieldInfoGetField(pQueryInfo, i)->bytes); + } + + for(int32_t k = 0; k < sas->numOfCols; ++k) { + int32_t columnIndex = sas->pExpr->pBinExprInfo.pReqColumns[k].colIdxInBuf; + SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, columnIndex); + + sas->elemSize[k] = pExpr->resBytes; + sas->data[k] = (pRes->data + pRes->numOfRows* pExpr->offset) + pRes->row*pExpr->resBytes; } + + tSQLBinaryExprCalcTraverse(sas->pExpr->pBinExprInfo.pBinExpr, 1, pRes->buffer[i], sas, TSQL_SO_ASC, getArithemicInputSrc); + pRes->tsrow[i] = pRes->buffer[i]; - num++; + free(sas); //todo optimization } } assert(num <= pQueryInfo->fieldsInfo.numOfOutputCols); - - pRes->row++; // index increase one-step + + pRes->row++; // index increase one-step return pRes->tsrow; } @@ -463,7 +533,7 @@ static bool tscHashRemainDataInSubqueryResultSet(SSqlObj *pSql) { if (pSql->pSubs[i] == 0) { continue; } - + SSqlRes * pRes1 = &pSql->pSubs[i]->res; SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(&pSql->pSubs[i]->cmd, 0); @@ -499,11 +569,10 @@ static void **tscBuildResFromSubqueries(SSqlObj *pSql) { if (numOfTableHasRes >= 2) { // do merge result - success = (doSetResultRowData(pSql->pSubs[0]) != NULL) && - (doSetResultRowData(pSql->pSubs[1]) != NULL); - // TSKEY key1 = *(TSKEY *)pRes1->tsrow[0]; - // TSKEY key2 = *(TSKEY *)pRes2->tsrow[0]; - // printf("first:%" PRId64 ", second:%" PRId64 "\n", key1, key2); + success = (doSetResultRowData(pSql->pSubs[0]) != NULL) && (doSetResultRowData(pSql->pSubs[1]) != NULL); + // TSKEY key1 = *(TSKEY *)pRes1->tsrow[0]; + // TSKEY key2 = *(TSKEY *)pRes2->tsrow[0]; + // printf("first:%" PRId64 ", second:%" PRId64 "\n", key1, key2); } else { // only one subquery SSqlObj *pSub = pSql->pSubs[0]; if (pSub == NULL) { @@ -593,7 +662,7 @@ TAOS_ROW taos_fetch_row_impl(TAOS_RES *res) { tscProcessSql(pSql); // retrieve data from virtual node - //if failed to retrieve data from current virtual node, try next one if exists + // if failed to retrieve data from current virtual node, try next one if exists if (hasMoreVnodesToTry(pSql)) { tscTryQueryNextVnode(pSql, NULL); } @@ -635,7 +704,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) { // current subclause is completed, try the next subclause while (rows == NULL && pCmd->clauseIndex < pCmd->numOfClause - 1) { tscTryQueryNextClause(pSql, NULL); - + // if the rows is not NULL, return immediately rows = taos_fetch_row_impl(res); } @@ -698,7 +767,7 @@ int taos_select_db(TAOS *taos, const char *db) { return taos_query(taos, sql); } -void taos_free_result_imp(TAOS_RES* res, int keepCmd) { +void taos_free_result_imp(TAOS_RES *res, int keepCmd) { if (res == NULL) return; SSqlObj *pSql = (SSqlObj *)res; @@ -713,7 +782,6 @@ void taos_free_result_imp(TAOS_RES* res, int keepCmd) { /* Query rsp is not received from vnode, so the qhandle is NULL */ tscTrace("%p qhandle is null, abort free, fp:%p", pSql, pSql->fp); if (pSql->fp != NULL) { - pSql->thandle = NULL; tscFreeSqlObj(pSql); tscTrace("%p Async SqlObj is freed by app", pSql); } else if (keepCmd) { @@ -752,7 +820,7 @@ void taos_free_result_imp(TAOS_RES* res, int keepCmd) { pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; tscTrace("%p code:%d, numOfRows:%d, command:%d", pSql, pRes->code, pRes->numOfRows, pCmd->command); - + void *fp = pSql->fp; if (fp != NULL) { pSql->freed = 1; @@ -774,7 +842,6 @@ void taos_free_result_imp(TAOS_RES* res, int keepCmd) { * * Then this object will be reused and no free operation is required. */ - pSql->thandle = NULL; if (keepCmd) { tscFreeSqlResult(pSql); tscTrace("%p sql result is freed by app while sql command is kept", pSql); @@ -785,7 +852,6 @@ void taos_free_result_imp(TAOS_RES* res, int keepCmd) { } } else { // if no free resource msg is sent to vnode, we free this object immediately. - pSql->thandle = NULL; if (pSql->fp) { assert(pRes->numOfRows == 0 || (pCmd->command > TSDB_SQL_LOCAL)); @@ -801,9 +867,7 @@ void taos_free_result_imp(TAOS_RES* res, int keepCmd) { } } -void taos_free_result(TAOS_RES *res) { - taos_free_result_imp(res, 0); -} +void taos_free_result(TAOS_RES *res) { taos_free_result_imp(res, 0); } int taos_errno(TAOS *taos) { STscObj *pObj = (STscObj *)taos; @@ -819,26 +883,24 @@ int taos_errno(TAOS *taos) { return code; } -static bool validErrorCode(int32_t code) { - return code >= TSDB_CODE_SUCCESS && code < TSDB_CODE_MAX_ERROR_CODE; -} +static bool validErrorCode(int32_t code) { return code >= TSDB_CODE_SUCCESS && code < TSDB_CODE_MAX_ERROR_CODE; } /* * In case of invalid sql error, additional information is attached to explain * why the sql is invalid */ -static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd* pCmd) { +static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) { if (code != TSDB_CODE_INVALID_SQL) { return false; } size_t len = strlen(pCmd->payload); - - char* z = NULL; + + char *z = NULL; if (len > 0) { - z = strstr (pCmd->payload, "invalid SQL"); + z = strstr(pCmd->payload, "invalid SQL"); } - + return z != NULL; } @@ -846,20 +908,21 @@ char *taos_errstr(TAOS *taos) { STscObj *pObj = (STscObj *)taos; uint8_t code; - if (pObj == NULL || pObj->signature != pObj) return tstrerror(globalCode); + if (pObj == NULL || pObj->signature != pObj) + return (char*)tstrerror(globalCode); + + SSqlObj *pSql = pObj->pSql; - SSqlObj* pSql = pObj->pSql; - if (validErrorCode(pSql->res.code)) { code = pSql->res.code; } else { - code = TSDB_CODE_OTHERS; //unknown error + code = TSDB_CODE_OTHERS; // unknown error } if (hasAdditionalErrorInfo(code, &pSql->cmd)) { return pSql->cmd.payload; } else { - return tstrerror(code); + return (char*)tstrerror(code); } } @@ -899,11 +962,6 @@ void taos_stop_query(TAOS_RES *res) { return; } - if (pSql->thandle == NULL) { - tscTrace("%p no connection, abort cancel", res); - return; - } - //taosStopRpcConn(pSql->thandle); tscTrace("%p query is cancelled", res); } @@ -951,14 +1009,14 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: { - size_t xlen = 0; - for (xlen = 0; xlen <= fields[i].bytes; xlen++) { - char c = ((char*)row[i])[xlen]; - if (c == 0) break; - str[len++] = c; - } - str[len] = 0; - } break; + size_t xlen = 0; + for (xlen = 0; xlen <= fields[i].bytes; xlen++) { + char c = ((char *)row[i])[xlen]; + if (c == 0) break; + str[len++] = c; + } + str[len] = 0; + } break; case TSDB_DATA_TYPE_TIMESTAMP: len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i])); @@ -1147,7 +1205,6 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { * to free connection, which may cause segment fault, when the parse phrase is not even successfully executed. */ pRes->qhandle = 0; - pSql->thandle = NULL; free(str); if (pRes->code != TSDB_CODE_SUCCESS) { diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index 79b524be0f8fd9b18847e03e9420941c6ec0c05c..5fd0adf5b15b31abe741dd51025e8e0a5a211230 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -246,8 +246,6 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf int32_t retry = tsProjectExecInterval; tscError("%p stream:%p, retrieve no data, code:%d, retry in %" PRId64 "ms", pSql, pStream, numOfRows, retry); - tscClearSqlMetaInfoForce(&(pStream->pSql->cmd)); - tscSetRetryTimer(pStream, pStream->pSql, retry); return; } @@ -381,41 +379,41 @@ static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) { SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); - if (pQueryInfo->nAggTimeInterval < minIntervalTime) { + if (pQueryInfo->intervalTime < minIntervalTime) { tscWarn("%p stream:%p, original sample interval:%ld too small, reset to:%" PRId64 "", pSql, pStream, - pQueryInfo->nAggTimeInterval, minIntervalTime); - pQueryInfo->nAggTimeInterval = minIntervalTime; + pQueryInfo->intervalTime, minIntervalTime); + pQueryInfo->intervalTime = minIntervalTime; } - pStream->interval = pQueryInfo->nAggTimeInterval; // it shall be derived from sql string + pStream->interval = pQueryInfo->intervalTime; // it shall be derived from sql string - if (pQueryInfo->nSlidingTime == 0) { - pQueryInfo->nSlidingTime = pQueryInfo->nAggTimeInterval; + if (pQueryInfo->slidingTime == 0) { + pQueryInfo->slidingTime = pQueryInfo->intervalTime; } int64_t minSlidingTime = (pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinSlidingTime * 1000L : tsMinSlidingTime; - if (pQueryInfo->nSlidingTime == -1) { - pQueryInfo->nSlidingTime = pQueryInfo->nAggTimeInterval; - } else if (pQueryInfo->nSlidingTime < minSlidingTime) { + if (pQueryInfo->slidingTime == -1) { + pQueryInfo->slidingTime = pQueryInfo->intervalTime; + } else if (pQueryInfo->slidingTime < minSlidingTime) { tscWarn("%p stream:%p, original sliding value:%" PRId64 " too small, reset to:%" PRId64 "", pSql, pStream, - pQueryInfo->nSlidingTime, minSlidingTime); + pQueryInfo->slidingTime, minSlidingTime); - pQueryInfo->nSlidingTime = minSlidingTime; + pQueryInfo->slidingTime = minSlidingTime; } - if (pQueryInfo->nSlidingTime > pQueryInfo->nAggTimeInterval) { + if (pQueryInfo->slidingTime > pQueryInfo->intervalTime) { tscWarn("%p stream:%p, sliding value:%" PRId64 " can not be larger than interval range, reset to:%" PRId64 "", pSql, pStream, - pQueryInfo->nSlidingTime, pQueryInfo->nAggTimeInterval); + pQueryInfo->slidingTime, pQueryInfo->intervalTime); - pQueryInfo->nSlidingTime = pQueryInfo->nAggTimeInterval; + pQueryInfo->slidingTime = pQueryInfo->intervalTime; } - pStream->slidingTime = pQueryInfo->nSlidingTime; + pStream->slidingTime = pQueryInfo->slidingTime; - pQueryInfo->nAggTimeInterval = 0; // clear the interval value to avoid the force time window split by query processor - pQueryInfo->nSlidingTime = 0; + pQueryInfo->intervalTime = 0; // clear the interval value to avoid the force time window split by query processor + pQueryInfo->slidingTime = 0; } static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) { diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c index 610c119e6d327c9b8b372136959b07098ffaef2e..3d55ff1c7267adc242ff037e2df8faa423076319 100644 --- a/src/client/src/tscSub.c +++ b/src/client/src/tscSub.c @@ -44,7 +44,7 @@ typedef struct SSub { int interval; TAOS_SUBSCRIBE_CALLBACK fp; void * param; - int numOfMeters; + int numOfTables; SSubscriptionProgress * progress; } SSub; @@ -62,7 +62,7 @@ TSKEY tscGetSubscriptionProgress(void* sub, int64_t uid) { return 0; SSub* pSub = (SSub*)sub; - for (int s = 0, e = pSub->numOfMeters; s < e;) { + for (int s = 0, e = pSub->numOfTables; s < e;) { int m = (s + e) / 2; SSubscriptionProgress* p = pSub->progress + m; if (p->uid > uid) @@ -81,7 +81,7 @@ void tscUpdateSubscriptionProgress(void* sub, int64_t uid, TSKEY ts) { return; SSub* pSub = (SSub*)sub; - for (int s = 0, e = pSub->numOfMeters; s < e;) { + for (int s = 0, e = pSub->numOfTables; s < e;) { int m = (s + e) / 2; SSubscriptionProgress* p = pSub->progress + m; if (p->uid > uid) @@ -176,43 +176,43 @@ int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { } SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0, 0); - int numOfMeters = 0; + int numOfTables = 0; if (!UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { - SMetricMeta* pMetricMeta = pMeterMetaInfo->pMetricMeta; + SSuperTableMeta* pMetricMeta = pMeterMetaInfo->pMetricMeta; for (int32_t i = 0; i < pMetricMeta->numOfVnodes; i++) { SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, i); - numOfMeters += pVnodeSidList->numOfSids; + numOfTables += pVnodeSidList->numOfSids; } } - SSubscriptionProgress* progress = (SSubscriptionProgress*)calloc(numOfMeters, sizeof(SSubscriptionProgress)); + SSubscriptionProgress* progress = (SSubscriptionProgress*)calloc(numOfTables, sizeof(SSubscriptionProgress)); if (progress == NULL) { tscError("failed to allocate memory for progress: %s", pSub->topic); return 0; } if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { - numOfMeters = 1; + numOfTables = 1; int64_t uid = pMeterMetaInfo->pMeterMeta->uid; progress[0].uid = uid; progress[0].key = tscGetSubscriptionProgress(pSub, uid); } else { - SMetricMeta* pMetricMeta = pMeterMetaInfo->pMetricMeta; - numOfMeters = 0; + SSuperTableMeta* pMetricMeta = pMeterMetaInfo->pMetricMeta; + numOfTables = 0; for (int32_t i = 0; i < pMetricMeta->numOfVnodes; i++) { SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, i); for (int32_t j = 0; j < pVnodeSidList->numOfSids; j++) { - SMeterSidExtInfo *pMeterInfo = tscGetMeterSidInfo(pVnodeSidList, j); + STableSidExtInfo *pMeterInfo = tscGetMeterSidInfo(pVnodeSidList, j); int64_t uid = pMeterInfo->uid; - progress[numOfMeters].uid = uid; - progress[numOfMeters++].key = tscGetSubscriptionProgress(pSub, uid); + progress[numOfTables].uid = uid; + progress[numOfTables++].key = tscGetSubscriptionProgress(pSub, uid); } } - qsort(progress, numOfMeters, sizeof(SSubscriptionProgress), tscCompareSubscriptionProgress); + qsort(progress, numOfTables, sizeof(SSubscriptionProgress), tscCompareSubscriptionProgress); } free(pSub->progress); - pSub->numOfMeters = numOfMeters; + pSub->numOfTables = numOfTables; pSub->progress = progress; pSub->lastSyncTime = taosGetTimestampMs(); @@ -257,9 +257,9 @@ static int tscLoadSubscriptionProgress(SSub* pSub) { return 0; } - int numOfMeters = atoi(buf); - SSubscriptionProgress* progress = calloc(numOfMeters, sizeof(SSubscriptionProgress)); - for (int i = 0; i < numOfMeters; i++) { + int numOfTables = atoi(buf); + SSubscriptionProgress* progress = calloc(numOfTables, sizeof(SSubscriptionProgress)); + for (int i = 0; i < numOfTables; i++) { if (fgets(buf, sizeof(buf), fp) == NULL) { fclose(fp); free(progress); @@ -273,10 +273,10 @@ static int tscLoadSubscriptionProgress(SSub* pSub) { fclose(fp); - qsort(progress, numOfMeters, sizeof(SSubscriptionProgress), tscCompareSubscriptionProgress); - pSub->numOfMeters = numOfMeters; + qsort(progress, numOfTables, sizeof(SSubscriptionProgress), tscCompareSubscriptionProgress); + pSub->numOfTables = numOfTables; pSub->progress = progress; - tscTrace("subscription progress loaded, %d tables: %s", numOfMeters, pSub->topic); + tscTrace("subscription progress loaded, %d tables: %s", numOfTables, pSub->topic); return 1; } @@ -297,8 +297,8 @@ void tscSaveSubscriptionProgress(void* sub) { } fputs(pSub->pSql->sqlstr, fp); - fprintf(fp, "\n%d\n", pSub->numOfMeters); - for (int i = 0; i < pSub->numOfMeters; i++) { + fprintf(fp, "\n%d\n", pSub->numOfTables); + for (int i = 0; i < pSub->numOfTables; i++) { int64_t uid = pSub->progress[i].uid; TSKEY key = pSub->progress[i].key; fprintf(fp, "%" PRId64 ":%" PRId64 "\n", uid, key); @@ -382,7 +382,6 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) { pRes->numOfRows = 1; pRes->numOfTotal = 0; pRes->qhandle = 0; - pSql->thandle = NULL; pSql->cmd.command = TSDB_SQL_SELECT; pQueryInfo->type = type; diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c index f411698bb7e6182c644aa28dbea93d8b9b844f54..6e4653c2d442e58e6d8cfa58a4ed402dc44b725a 100644 --- a/src/client/src/tscSystem.c +++ b/src/client/src/tscSystem.c @@ -45,6 +45,7 @@ int tsInsertHeadSize; extern int tscEmbedded; int tscNumOfThreads; static pthread_once_t tscinit = PTHREAD_ONCE_INIT; +static pthread_mutex_t tscMutex; extern int tsTscEnableRecordSql; extern int tsNumOfLogLines; @@ -56,11 +57,64 @@ void tscCheckDiskUsage(void *para, void *unused) { taosTmrReset(tscCheckDiskUsage, 1000, NULL, tscTmr, &tscCheckDiskUsageTmr); } +int32_t tscInitRpc(const char *user, const char *secret) { + SRpcInit rpcInit; + char secretEncrypt[32] = {0}; + taosEncryptPass((uint8_t *)secret, strlen(secret), secretEncrypt); + + pthread_mutex_lock(&tscMutex); + if (pVnodeConn == NULL) { + memset(&rpcInit, 0, sizeof(rpcInit)); + rpcInit.localIp = tsLocalIp; + rpcInit.localPort = 0; + rpcInit.label = "TSC-vnode"; + rpcInit.numOfThreads = tscNumOfThreads; + rpcInit.cfp = tscProcessMsgFromServer; + rpcInit.sessions = tsMaxVnodeConnections; + rpcInit.connType = TAOS_CONN_CLIENT; + rpcInit.user = user; + rpcInit.ckey = "key"; + rpcInit.secret = secretEncrypt; + + pVnodeConn = rpcOpen(&rpcInit); + if (pVnodeConn == NULL) { + tscError("failed to init connection to vnode"); + pthread_mutex_unlock(&tscMutex); + return -1; + } + } + + if (pTscMgmtConn == NULL) { + memset(&rpcInit, 0, sizeof(rpcInit)); + rpcInit.localIp = tsLocalIp; + rpcInit.localPort = 0; + rpcInit.label = "TSC-mgmt"; + rpcInit.numOfThreads = 1; + rpcInit.cfp = tscProcessMsgFromServer; + rpcInit.sessions = tsMaxMgmtConnections; + rpcInit.connType = TAOS_CONN_CLIENT; + rpcInit.idleTime = 2000; + rpcInit.user = "root"; + rpcInit.ckey = "key"; + rpcInit.secret = secretEncrypt; + + pTscMgmtConn = rpcOpen(&rpcInit); + if (pTscMgmtConn == NULL) { + tscError("failed to init connection to mgmt"); + pthread_mutex_unlock(&tscMutex); + return -1; + } + } + + pthread_mutex_unlock(&tscMutex); + return 0; +} + void taos_init_imp() { char temp[128]; struct stat dirstat; - SRpcInit rpcInit; + pthread_mutex_init(&tscMutex, NULL); srand(taosGetTimestampSec()); deltaToUtcInitOnce(); @@ -96,12 +150,12 @@ void taos_init_imp() { taosInitNote(tsNumOfLogLines / 10, 1, (char*)"tsc_note"); } - tscMgmtIpList.index = 0; + tscMgmtIpList.inUse = 0; tscMgmtIpList.port = tsMgmtShellPort; tscMgmtIpList.numOfIps = 1; tscMgmtIpList.ip[0] = inet_addr(tsMasterIp); - if (tsSecondIp[0]) { + if (tsSecondIp[0] && strcmp(tsSecondIp, tsMasterIp) != 0) { tscMgmtIpList.numOfIps = 2; tscMgmtIpList.ip[1] = inet_addr(tsSecondIp); } @@ -124,34 +178,6 @@ void taos_init_imp() { return; } - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localIp = tsLocalIp; - rpcInit.localPort = 0; - rpcInit.label = "TSC-vnode"; - rpcInit.numOfThreads = tscNumOfThreads; - rpcInit.afp = tscProcessMsgFromServer; - rpcInit.sessions = tsMaxVnodeConnections; - rpcInit.connType = TAOS_CONN_SOCKET_TYPE_C(); - pVnodeConn = rpcOpen(&rpcInit); - if (pVnodeConn == NULL) { - tscError("failed to init connection to vnode"); - return; - } - - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localIp = tsLocalIp; - rpcInit.localPort = 0; - rpcInit.label = "TSC-mgmt"; - rpcInit.numOfThreads = 1; - rpcInit.afp = tscProcessMsgFromServer; - rpcInit.sessions = tsMaxMgmtConnections; - rpcInit.connType = TAOS_CONN_SOCKET_TYPE_C(); - pTscMgmtConn = rpcOpen(&rpcInit); - if (pTscMgmtConn == NULL) { - tscError("failed to init connection to mgmt"); - return; - } - tscTmr = taosTmrInit(tsMaxMgmtConnections * 2, 200, 60000, "TSC"); if(0 == tscEmbedded){ taosTmrReset(tscCheckDiskUsage, 10, NULL, tscTmr, &tscCheckDiskUsageTmr); @@ -319,10 +345,10 @@ static int taos_options_imp(TSDB_OPTION option, const char *pStr) { assert(cfg != NULL); if (cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) { - if (strcasecmp(pStr, TAOS_SOCKET_TYPE_NAME_UDP) != 0 && strcasecmp(pStr, TAOS_SOCKET_TYPE_NAME_TCP) != 0) { - tscError("only 'tcp' or 'udp' allowed for configuring the socket type"); - return -1; - } +// if (strcasecmp(pStr, TAOS_SOCKET_TYPE_NAME_UDP) != 0 && strcasecmp(pStr, TAOS_SOCKET_TYPE_NAME_TCP) != 0) { +// tscError("only 'tcp' or 'udp' allowed for configuring the socket type"); +// return -1; +// } strncpy(tsSocketType, pStr, tListLen(tsSocketType)); cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION; diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 59e3283b1490f07307a6ef9a649cae7a568be2ef..2a5af0473c8bc5c8e40807c43ee1968a9ead24f0 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -27,6 +27,7 @@ #include "tsclient.h" #include "tsqldef.h" #include "ttimer.h" +#include "tast.h" /* * the detailed information regarding metric meta key is: @@ -56,7 +57,7 @@ void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) { char join[512] = {0}; if (pTagCond->joinInfo.hasJoin) { - sprintf(join, "%s,%s", pTagCond->joinInfo.left.meterId, pTagCond->joinInfo.right.meterId); + sprintf(join, "%s,%s", pTagCond->joinInfo.left.tableId, pTagCond->joinInfo.right.tableId); } // estimate the buffer size @@ -64,7 +65,7 @@ void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) { size_t redundantLen = 20; size_t bufSize = strlen(pMeterMetaInfo->name) + tbnameCondLen + strlen(join) + strlen(tagIdBuf); - if (cond != NULL) { + if (cond != NULL && cond->cond != NULL) { bufSize += strlen(cond->cond); } @@ -72,7 +73,7 @@ void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) { char* tmp = calloc(1, bufSize); int32_t keyLen = snprintf(tmp, bufSize, "%s,%s,%s,%d,%s,[%s],%d", pMeterMetaInfo->name, - (cond != NULL ? cond->cond : NULL), (tbnameCondLen > 0 ? pTagCond->tbnameCond.cond : NULL), + ((cond != NULL && cond->cond != NULL) ? cond->cond : NULL), (tbnameCondLen > 0 ? pTagCond->tbnameCond.cond : NULL), pTagCond->relType, join, tagIdBuf, pQueryInfo->groupbyExpr.orderType); assert(keyLen <= bufSize); @@ -118,7 +119,7 @@ bool tscQueryOnMetric(SSqlCmd* pCmd) { SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); return ((pQueryInfo->type & TSDB_QUERY_TYPE_STABLE_QUERY) == TSDB_QUERY_TYPE_STABLE_QUERY) && - (pCmd->msgType == TSDB_MSG_TYPE_DNODE_QUERY); + (pCmd->msgType == TSDB_MSG_TYPE_QUERY); } bool tscQueryMetricTags(SQueryInfo* pQueryInfo) { @@ -156,13 +157,13 @@ bool tscIsSelectivityWithTagQuery(SSqlCmd* pCmd) { return false; } -void tscGetDBInfoFromMeterId(char* meterId, char* db) { - char* st = strstr(meterId, TS_PATH_DELIMITER); +void tscGetDBInfoFromMeterId(char* tableId, char* db) { + char* st = strstr(tableId, TS_PATH_DELIMITER); if (st != NULL) { char* end = strstr(st + 1, TS_PATH_DELIMITER); if (end != NULL) { - memcpy(db, meterId, (end - meterId)); - db[end - meterId] = 0; + memcpy(db, tableId, (end - tableId)); + db[end - tableId] = 0; return; } } @@ -170,13 +171,13 @@ void tscGetDBInfoFromMeterId(char* meterId, char* db) { db[0] = 0; } -SVnodeSidList* tscGetVnodeSidList(SMetricMeta* pMetricmeta, int32_t vnodeIdx) { +SVnodeSidList* tscGetVnodeSidList(SSuperTableMeta* pMetricmeta, int32_t vnodeIdx) { if (pMetricmeta == NULL) { tscError("illegal metricmeta"); return 0; } - if (pMetricmeta->numOfVnodes == 0 || pMetricmeta->numOfMeters == 0) { + if (pMetricmeta->numOfVnodes == 0 || pMetricmeta->numOfTables == 0) { return 0; } @@ -190,7 +191,7 @@ SVnodeSidList* tscGetVnodeSidList(SMetricMeta* pMetricmeta, int32_t vnodeIdx) { return (SVnodeSidList*)(pMetricmeta->list[vnodeIdx] + (char*)pMetricmeta); } -SMeterSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx) { +STableSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx) { if (pSidList == NULL) { tscError("illegal sidlist"); return 0; @@ -202,7 +203,10 @@ SMeterSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx) { tscError("illegal sidIdx:%d, reset to 0, sidIdx range:%d-%d", idx, 0, sidRange); idx = 0; } - return (SMeterSidExtInfo*)(pSidList->pSidExtInfoList[idx] + (char*)pSidList); + + assert(pSidList->pSidExtInfoList[idx] >= 0); + + return (STableSidExtInfo*)(pSidList->pSidExtInfoList[idx] + (char*)pSidList); } bool tscIsTwoStageMergeMetricQuery(SQueryInfo* pQueryInfo, int32_t tableIndex) { @@ -211,7 +215,16 @@ bool tscIsTwoStageMergeMetricQuery(SQueryInfo* pQueryInfo, int32_t tableIndex) { } SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, tableIndex); - if (pMeterMetaInfo == NULL || pMeterMetaInfo->pMetricMeta == NULL) { + if (pMeterMetaInfo == NULL) { + return false; + } + + // for select query super table, the metricmeta can not be null in any cases. + if (pQueryInfo->command == TSDB_SQL_SELECT && UTIL_METER_IS_SUPERTABLE(pMeterMetaInfo)) { + assert(pMeterMetaInfo->pMetricMeta != NULL); + } + + if (pMeterMetaInfo->pMetricMeta == NULL) { return false; } @@ -335,35 +348,17 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) { tfree(pQueryInfo->defaultVal); } -void tscClearSqlMetaInfoForce(SSqlCmd* pCmd) { - /* remove the metermeta/metricmeta in cache */ - // taosRemoveDataFromCache(tscCacheHandle, (void**)&(pCmd->pMeterMeta), true); - // taosRemoveDataFromCache(tscCacheHandle, (void**)&(pCmd->pMetricMeta), true); -} - int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) { if (pRes->tsrow == NULL) { - pRes->numOfnchar = 0; - int32_t numOfOutputCols = pQueryInfo->fieldsInfo.numOfOutputCols; - for (int32_t i = 0; i < numOfOutputCols; ++i) { - TAOS_FIELD* pField = tscFieldInfoGetField(pQueryInfo, i); - if (pField->type == TSDB_DATA_TYPE_NCHAR) { - pRes->numOfnchar++; - } - } + pRes->numOfCols = numOfOutputCols; - pRes->tsrow = calloc(1, (POINTER_BYTES + sizeof(short)) * numOfOutputCols + POINTER_BYTES * pRes->numOfnchar); - pRes->bytes = calloc(numOfOutputCols, sizeof(short)); - - if (pRes->numOfnchar > 0) { - pRes->buffer = calloc(POINTER_BYTES, pRes->numOfnchar); - } + pRes->tsrow = calloc(POINTER_BYTES, numOfOutputCols); + pRes->buffer = calloc(POINTER_BYTES, numOfOutputCols); // not enough memory - if (pRes->tsrow == NULL || pRes->bytes == NULL || (pRes->buffer == NULL && pRes->numOfnchar > 0)) { + if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) { tfree(pRes->tsrow); - tfree(pRes->bytes); tfree(pRes->buffer); pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY; @@ -376,13 +371,12 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) { void tscDestroyResPointerInfo(SSqlRes* pRes) { if (pRes->buffer != NULL) { - assert(pRes->numOfnchar > 0); // free all buffers containing the multibyte string - for (int i = 0; i < pRes->numOfnchar; i++) { + for (int i = 0; i < pRes->numOfCols; i++) { tfree(pRes->buffer[i]); } - pRes->numOfnchar = 0; + pRes->numOfCols = 0; } tfree(pRes->pRsp); @@ -391,7 +385,6 @@ void tscDestroyResPointerInfo(SSqlRes* pRes) { tfree(pRes->pGroupRec); tfree(pRes->pColumnIndex); tfree(pRes->buffer); - tfree(pRes->bytes); pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free } @@ -430,6 +423,9 @@ void tscFreeResData(SSqlObj* pSql) { } void tscFreeSqlResult(SSqlObj* pSql) { + //TODO not free + return; + tfree(pSql->res.pRsp); pSql->res.row = 0; pSql->res.numOfRows = 0; @@ -580,19 +576,19 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) { SSqlCmd* pCmd = &pSql->cmd; assert(pDataBlock->pMeterMeta != NULL); - pCmd->numOfTablesInSubmit = pDataBlock->numOfMeters; + pCmd->numOfTablesInSubmit = pDataBlock->numOfTables; assert(pCmd->numOfClause == 1); SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); // set the correct metermeta object, the metermeta has been locked in pDataBlocks, so it must be in the cache if (pMeterMetaInfo->pMeterMeta != pDataBlock->pMeterMeta) { - strcpy(pMeterMetaInfo->name, pDataBlock->meterId); + strcpy(pMeterMetaInfo->name, pDataBlock->tableId); taosRemoveDataFromCache(tscCacheHandle, (void**)&(pMeterMetaInfo->pMeterMeta), false); pMeterMetaInfo->pMeterMeta = taosTransferDataInCache(tscCacheHandle, (void**)&pDataBlock->pMeterMeta); } else { - assert(strncmp(pMeterMetaInfo->name, pDataBlock->meterId, tListLen(pDataBlock->meterId)) == 0); + assert(strncmp(pMeterMetaInfo->name, pDataBlock->tableId, tListLen(pDataBlock->tableId)) == 0); } /* @@ -636,7 +632,7 @@ void tscFreeUnusedDataBlocks(SDataBlockList* pList) { * @return */ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, const char* name, - SMeterMeta* pMeterMeta, STableDataBlocks** dataBlocks) { + STableMeta* pMeterMeta, STableDataBlocks** dataBlocks) { STableDataBlocks* dataBuf = (STableDataBlocks*)calloc(1, sizeof(STableDataBlocks)); if (dataBuf == NULL) { tscError("failed to allocated memory, reason:%s", strerror(errno)); @@ -657,7 +653,7 @@ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOff dataBuf->size = startOffset; dataBuf->tsSource = -1; - strncpy(dataBuf->meterId, name, TSDB_TABLE_ID_LEN); + strncpy(dataBuf->tableId, name, TSDB_TABLE_ID_LEN); /* * The metermeta may be released since the metermeta cache are completed clean by other thread @@ -672,7 +668,7 @@ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOff } int32_t tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList, int64_t id, int32_t size, - int32_t startOffset, int32_t rowSize, const char* tableId, SMeterMeta* pMeterMeta, + int32_t startOffset, int32_t rowSize, const char* tableId, STableMeta* pMeterMeta, STableDataBlocks** dataBlocks) { *dataBlocks = NULL; @@ -706,7 +702,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockLi STableDataBlocks* dataBuf = NULL; int32_t ret = tscGetDataBlockFromList(pVnodeDataBlockHashList, pVnodeDataBlockList, pOneTableBlock->vgid, TSDB_PAYLOAD_SIZE, - tsInsertHeadSize, 0, pOneTableBlock->meterId, pOneTableBlock->pMeterMeta, &dataBuf); + tsInsertHeadSize, 0, pOneTableBlock->tableId, pOneTableBlock->pMeterMeta, &dataBuf); if (ret != TSDB_CODE_SUCCESS) { tscError("%p failed to prepare the data block buffer for merging table data, code:%d", pSql, ret); taosCleanUpHashTable(pVnodeDataBlockHashList); @@ -740,7 +736,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockLi char* e = (char*)pBlocks->payLoad + pOneTableBlock->rowSize*(pBlocks->numOfRows-1); - tscTrace("%p meterId:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->meterId, pBlocks->sid, + tscTrace("%p tableId:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->tableId, pBlocks->sid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->payLoad), GET_INT64_VAL(e)); pBlocks->sid = htonl(pBlocks->sid); @@ -751,7 +747,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockLi memcpy(dataBuf->pData + dataBuf->size, pOneTableBlock->pData, pOneTableBlock->size); dataBuf->size += pOneTableBlock->size; - dataBuf->numOfMeters += 1; + dataBuf->numOfTables += 1; } tscDestroyBlockArrayList(pTableDataBlockList); @@ -798,6 +794,7 @@ int tscAllocPayload(SSqlCmd* pCmd, int size) { pCmd->payload = (char*)malloc(size); if (pCmd->payload == NULL) return TSDB_CODE_CLI_OUT_OF_MEMORY; pCmd->allocSize = size; + memset(pCmd->payload, 0, pCmd->allocSize); } else { if (pCmd->allocSize < size) { char* b = realloc(pCmd->payload, size); @@ -807,7 +804,7 @@ int tscAllocPayload(SSqlCmd* pCmd, int size) { } } - memset(pCmd->payload, 0, pCmd->allocSize); + //memset(pCmd->payload, 0, pCmd->allocSize); assert(pCmd->allocSize >= size); return TSDB_CODE_SUCCESS; @@ -831,11 +828,18 @@ static void ensureSpace(SFieldInfo* pFieldInfo, int32_t size) { pFieldInfo->pFields = realloc(pFieldInfo->pFields, newSize * sizeof(TAOS_FIELD)); memset(&pFieldInfo->pFields[oldSize], 0, inc * sizeof(TAOS_FIELD)); - pFieldInfo->pOffset = realloc(pFieldInfo->pOffset, newSize * sizeof(int16_t)); - memset(&pFieldInfo->pOffset[oldSize], 0, inc * sizeof(int16_t)); +// pFieldInfo->pOffset = realloc(pFieldInfo->pOffset, newSize * sizeof(int16_t)); +// memset(&pFieldInfo->pOffset[oldSize], 0, inc * sizeof(int16_t)); pFieldInfo->pVisibleCols = realloc(pFieldInfo->pVisibleCols, newSize * sizeof(bool)); + memset(&pFieldInfo->pVisibleCols[oldSize], 0, inc * sizeof(bool)); + pFieldInfo->pSqlExpr = realloc(pFieldInfo->pSqlExpr, POINTER_BYTES*newSize); + pFieldInfo->pExpr = realloc(pFieldInfo->pExpr, POINTER_BYTES*newSize); + + memset(&pFieldInfo->pSqlExpr[oldSize], 0, inc * POINTER_BYTES); + memset(&pFieldInfo->pExpr[oldSize], 0, inc * POINTER_BYTES); + pFieldInfo->numOfAlloc = newSize; } } @@ -844,6 +848,15 @@ static void evic(SFieldInfo* pFieldInfo, int32_t index) { if (index < pFieldInfo->numOfOutputCols) { memmove(&pFieldInfo->pFields[index + 1], &pFieldInfo->pFields[index], sizeof(pFieldInfo->pFields[0]) * (pFieldInfo->numOfOutputCols - index)); + + memmove(&pFieldInfo->pVisibleCols[index + 1], &pFieldInfo->pVisibleCols[index], + sizeof(pFieldInfo->pVisibleCols[0]) * (pFieldInfo->numOfOutputCols - index)); + + memmove(&pFieldInfo->pSqlExpr[index + 1], &pFieldInfo->pSqlExpr[index], + sizeof(pFieldInfo->pSqlExpr[0]) * (pFieldInfo->numOfOutputCols - index)); + + memmove(&pFieldInfo->pExpr[index + 1], &pFieldInfo->pExpr[index], + sizeof(pFieldInfo->pExpr[0]) * (pFieldInfo->numOfOutputCols - index)); } } @@ -868,7 +881,6 @@ void tscFieldInfoSetValFromField(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIE memcpy(&pFieldInfo->pFields[index], pField, sizeof(TAOS_FIELD)); pFieldInfo->pVisibleCols[index] = true; - pFieldInfo->numOfOutputCols++; } @@ -902,29 +914,49 @@ void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, co pFieldInfo->numOfOutputCols++; } -void tscFieldInfoCalOffset(SQueryInfo* pQueryInfo) { - SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; - pFieldInfo->pOffset[0] = 0; +void tscFieldInfoSetExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlExpr* pExpr) { + assert(index >= 0 && index < pFieldInfo->numOfOutputCols); + pFieldInfo->pSqlExpr[index] = pExpr; +} + +void tscFieldInfoSetBinExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlFunctionExpr* pExpr) { + assert(index >= 0 && index < pFieldInfo->numOfOutputCols); + pFieldInfo->pExpr[index] = pExpr; +} - for (int32_t i = 1; i < pFieldInfo->numOfOutputCols; ++i) { - pFieldInfo->pOffset[i] = pFieldInfo->pOffset[i - 1] + pFieldInfo->pFields[i - 1].bytes; +void tscFieldInfoCalOffset(SQueryInfo* pQueryInfo) { + SSqlExprInfo* pExprInfo = &pQueryInfo->exprsInfo; + pExprInfo->pExprs[0]->offset = 0; + + for (int32_t i = 1; i < pExprInfo->numOfExprs; ++i) { + pExprInfo->pExprs[i]->offset = pExprInfo->pExprs[i - 1]->offset + pExprInfo->pExprs[i - 1]->resBytes; } } void tscFieldInfoUpdateOffsetForInterResult(SQueryInfo* pQueryInfo) { - SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; - if (pFieldInfo->numOfOutputCols == 0) { +// SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; +// if (pFieldInfo->numOfOutputCols == 0) { +// return; +// } +// +// pFieldInfo->pOffset[0] = 0; +// +// /* +// * the retTypeLen is used to store the intermediate result length +// * for potential secondary merge exists +// */ +// for (int32_t i = 1; i < pFieldInfo->numOfOutputCols; ++i) { +// pFieldInfo->pOffset[i] = pFieldInfo->pOffset[i - 1] + tscSqlExprGet(pQueryInfo, i - 1)->resBytes; +// } + SSqlExprInfo* pExprInfo = &pQueryInfo->exprsInfo; + if (pExprInfo->numOfExprs == 0) { return; } - - pFieldInfo->pOffset[0] = 0; - - /* - * the retTypeLen is used to store the intermediate result length - * for potential secondary merge exists - */ - for (int32_t i = 1; i < pFieldInfo->numOfOutputCols; ++i) { - pFieldInfo->pOffset[i] = pFieldInfo->pOffset[i - 1] + tscSqlExprGet(pQueryInfo, i - 1)->resBytes; + + pExprInfo->pExprs[0]->offset = 0; + + for (int32_t i = 1; i < pExprInfo->numOfExprs; ++i) { + pExprInfo->pExprs[i]->offset = pExprInfo->pExprs[i - 1]->offset + pExprInfo->pExprs[i - 1]->resBytes; } } @@ -940,6 +972,8 @@ void tscFieldInfoCopy(SFieldInfo* src, SFieldInfo* dst, const int32_t* indexList for (int32_t i = 0; i < size; ++i) { assert(indexList[i] >= 0 && indexList[i] <= src->numOfOutputCols); tscFieldInfoSetValFromField(dst, i, &src->pFields[indexList[i]]); + dst->pVisibleCols[i] = src->pVisibleCols[indexList[i]]; + dst->pSqlExpr[i] = src->pSqlExpr[indexList[i]]; } } } @@ -948,12 +982,14 @@ void tscFieldInfoCopyAll(SFieldInfo* dst, SFieldInfo* src) { *dst = *src; dst->pFields = malloc(sizeof(TAOS_FIELD) * dst->numOfAlloc); - dst->pOffset = malloc(sizeof(short) * dst->numOfAlloc); dst->pVisibleCols = malloc(sizeof(bool) * dst->numOfAlloc); + dst->pSqlExpr = malloc(POINTER_BYTES * dst->numOfAlloc); + dst->pExpr = malloc(POINTER_BYTES * dst->numOfAlloc); memcpy(dst->pFields, src->pFields, sizeof(TAOS_FIELD) * dst->numOfOutputCols); - memcpy(dst->pOffset, src->pOffset, sizeof(short) * dst->numOfOutputCols); memcpy(dst->pVisibleCols, src->pVisibleCols, sizeof(bool) * dst->numOfOutputCols); + memcpy(dst->pSqlExpr, src->pSqlExpr, POINTER_BYTES * dst->numOfOutputCols); + memcpy(dst->pExpr, src->pExpr, POINTER_BYTES * dst->numOfOutputCols); } TAOS_FIELD* tscFieldInfoGetField(SQueryInfo* pQueryInfo, int32_t index) { @@ -967,11 +1003,11 @@ TAOS_FIELD* tscFieldInfoGetField(SQueryInfo* pQueryInfo, int32_t index) { int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutputCols; } int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) { - if (index >= pQueryInfo->fieldsInfo.numOfOutputCols) { + if (index >= pQueryInfo->exprsInfo.numOfExprs) { return 0; } - return pQueryInfo->fieldsInfo.pOffset[index]; + return pQueryInfo->exprsInfo.pExprs[index]->offset; } int32_t tscFieldInfoCompare(SFieldInfo* pFieldInfo1, SFieldInfo* pFieldInfo2) { @@ -995,13 +1031,16 @@ int32_t tscFieldInfoCompare(SFieldInfo* pFieldInfo1, SFieldInfo* pFieldInfo2) { } int32_t tscGetResRowLength(SQueryInfo* pQueryInfo) { - SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; - if (pFieldInfo->numOfOutputCols <= 0) { + if (pQueryInfo->exprsInfo.numOfExprs <= 0) { return 0; } - - return pFieldInfo->pOffset[pFieldInfo->numOfOutputCols - 1] + - pFieldInfo->pFields[pFieldInfo->numOfOutputCols - 1].bytes; + + int32_t size = 0; + for(int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) { + size += pQueryInfo->exprsInfo.pExprs[i]->resBytes; + } + + return size; } void tscClearFieldInfo(SFieldInfo* pFieldInfo) { @@ -1009,10 +1048,19 @@ void tscClearFieldInfo(SFieldInfo* pFieldInfo) { return; } - tfree(pFieldInfo->pOffset); tfree(pFieldInfo->pFields); tfree(pFieldInfo->pVisibleCols); - + tfree(pFieldInfo->pSqlExpr); + + for(int32_t i = 0; i < pFieldInfo->numOfOutputCols; ++i) { + if (pFieldInfo->pExpr[i] != NULL) { + tSQLBinaryExprDestroy(&pFieldInfo->pExpr[i]->pBinExprInfo.pBinExpr, NULL); + tfree(pFieldInfo->pExpr[i]->pBinExprInfo.pReqColumns); + tfree(pFieldInfo->pExpr[i]); + } + } + + tfree(pFieldInfo->pExpr); memset(pFieldInfo, 0, sizeof(SFieldInfo)); } @@ -1050,11 +1098,12 @@ SSqlExpr* tscSqlExprInsertEmpty(SQueryInfo* pQueryInfo, int32_t index, int16_t f _exprCheckSpace(pExprInfo, pExprInfo->numOfExprs + 1); _exprEvic(pExprInfo, index); - - SSqlExpr* pExpr = &pExprInfo->pExprs[index]; + + SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr)); pExpr->functionId = functionId; - + pExprInfo->numOfExprs++; + pExprInfo->pExprs[index] = pExpr; return pExpr; } @@ -1067,8 +1116,9 @@ SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functi _exprCheckSpace(pExprInfo, pExprInfo->numOfExprs + 1); _exprEvic(pExprInfo, index); - SSqlExpr* pExpr = &pExprInfo->pExprs[index]; - + SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr)); + pExprInfo->pExprs[index] = pExpr; + pExpr->functionId = functionId; int16_t numOfCols = pMeterMetaInfo->pMeterMeta->numOfColumns; @@ -1110,7 +1160,7 @@ SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functi return NULL; } - SSqlExpr* pExpr = &pExprInfo->pExprs[index]; + SSqlExpr* pExpr = pExprInfo->pExprs[index]; pExpr->functionId = functionId; @@ -1123,6 +1173,10 @@ SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functi return pExpr; } +int32_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo) { + return pQueryInfo->exprsInfo.numOfExprs; +} + void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes, int16_t tableIndex) { if (pExpr == NULL || argument == NULL || bytes == 0) { return; @@ -1141,7 +1195,7 @@ SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index) { return NULL; } - return &pQueryInfo->exprsInfo.pExprs[index]; + return pQueryInfo->exprsInfo.pExprs[index]; } void* tscSqlExprDestroy(SSqlExpr* pExpr) { @@ -1153,6 +1207,8 @@ void* tscSqlExprDestroy(SSqlExpr* pExpr) { tVariantDestroy(&pExpr->param[i]); } + tfree(pExpr); + return NULL; } @@ -1164,8 +1220,8 @@ void tscSqlExprInfoDestroy(SSqlExprInfo* pExprInfo) { return; } - for(int32_t i = 0; i < pExprInfo->numOfAlloc; ++i) { - tscSqlExprDestroy(&pExprInfo->pExprs[i]); + for(int32_t i = 0; i < pExprInfo->numOfExprs; ++i) { + tscSqlExprDestroy(pExprInfo->pExprs[i]); } tfree(pExprInfo->pExprs); @@ -1175,27 +1231,40 @@ void tscSqlExprInfoDestroy(SSqlExprInfo* pExprInfo) { } -void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t tableuid) { +void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t tableuid, bool deepcopy) { if (src == NULL) { return; } *dst = *src; - dst->pExprs = calloc(dst->numOfAlloc, sizeof(SSqlExpr)); + dst->pExprs = calloc(dst->numOfAlloc, POINTER_BYTES); + int16_t num = 0; for (int32_t i = 0; i < src->numOfExprs; ++i) { - if (src->pExprs[i].uid == tableuid) { - dst->pExprs[num++] = src->pExprs[i]; + if (src->pExprs[i]->uid == tableuid) { + + if (deepcopy) { + dst->pExprs[num] = calloc(1, sizeof(SSqlExpr)); + *dst->pExprs[num] = *src->pExprs[i]; + } else { + dst->pExprs[num] = src->pExprs[i]; + } + + num++; } } dst->numOfExprs = num; - for (int32_t i = 0; i < dst->numOfExprs; ++i) { - for (int32_t j = 0; j < src->pExprs[i].numOfParams; ++j) { - tVariantAssign(&dst->pExprs[i].param[j], &src->pExprs[i].param[j]); + + if (deepcopy) { + for (int32_t i = 0; i < dst->numOfExprs; ++i) { + for (int32_t j = 0; j < src->pExprs[i]->numOfParams; ++j) { + tVariantAssign(&dst->pExprs[i]->param[j], &src->pExprs[i]->param[j]); + } } } + } static void clearVal(SColumnBase* pBase) { @@ -1796,8 +1865,8 @@ void tscFreeSubqueryInfo(SSqlCmd* pCmd) { tfree(pCmd->pQueryInfo); } -SMeterMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, SMeterMeta* pMeterMeta, - SMetricMeta* pMetricMeta, int16_t numOfTags, int16_t* tags) { +SMeterMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pMeterMeta, + SSuperTableMeta* pMetricMeta, int16_t numOfTags, int16_t* tags) { void* pAlloc = realloc(pQueryInfo->pMeterInfo, (pQueryInfo->numOfTables + 1) * POINTER_BYTES); if (pAlloc == NULL) { return NULL; @@ -1950,7 +2019,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void } uint64_t uid = pMeterMetaInfo->pMeterMeta->uid; - tscSqlExprCopy(&pNewQueryInfo->exprsInfo, &pQueryInfo->exprsInfo, uid); + tscSqlExprCopy(&pNewQueryInfo->exprsInfo, &pQueryInfo->exprsInfo, uid, true); int32_t numOfOutputCols = pNewQueryInfo->exprsInfo.numOfExprs; @@ -1965,7 +2034,19 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void tscFieldInfoCopy(&pQueryInfo->fieldsInfo, &pNewQueryInfo->fieldsInfo, indexList, numOfOutputCols); free(indexList); - + + // make sure the the sqlExpr for each fields is correct +// todo handle the agg arithmetic expression + for(int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutputCols; ++f) { + char* name = pNewQueryInfo->fieldsInfo.pFields[f].name; + for(int32_t k1 = 0; k1 < pNewQueryInfo->exprsInfo.numOfExprs; ++k1) { + SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1); + if (strcmp(name, pExpr1->aliasName) == 0) { + pNewQueryInfo->fieldsInfo.pSqlExpr[f] = pExpr1; + } + } + } + tscFieldInfoUpdateOffsetForInterResult(pNewQueryInfo); } @@ -1983,16 +2064,16 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void SMeterMetaInfo* pFinalInfo = NULL; if (pPrevSql == NULL) { - SMeterMeta* pMeterMeta = taosGetDataFromCache(tscCacheHandle, name); - SMetricMeta* pMetricMeta = taosGetDataFromCache(tscCacheHandle, key); + STableMeta* pMeterMeta = taosGetDataFromCache(tscCacheHandle, name); + SSuperTableMeta* pMetricMeta = taosGetDataFromCache(tscCacheHandle, key); pFinalInfo = tscAddMeterMetaInfo(pNewQueryInfo, name, pMeterMeta, pMetricMeta, pMeterMetaInfo->numOfTags, pMeterMetaInfo->tagColumnIndex); } else { // transfer the ownership of pMeterMeta/pMetricMeta to the newly create sql object. SMeterMetaInfo* pPrevInfo = tscGetMeterMetaInfo(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex, 0); - SMeterMeta* pPrevMeterMeta = taosTransferDataInCache(tscCacheHandle, (void**)&pPrevInfo->pMeterMeta); - SMetricMeta* pPrevMetricMeta = taosTransferDataInCache(tscCacheHandle, (void**)&pPrevInfo->pMetricMeta); + STableMeta* pPrevMeterMeta = taosTransferDataInCache(tscCacheHandle, (void**)&pPrevInfo->pMeterMeta); + SSuperTableMeta* pPrevMetricMeta = taosTransferDataInCache(tscCacheHandle, (void**)&pPrevInfo->pMetricMeta); pFinalInfo = tscAddMeterMetaInfo(pNewQueryInfo, name, pPrevMeterMeta, pPrevMetricMeta, pMeterMetaInfo->numOfTags, pMeterMetaInfo->tagColumnIndex); diff --git a/src/connector/jdbc/CMakeLists.txt b/src/connector/jdbc/CMakeLists.txt index 56a65a8ab526ad901941768938416f8bb10704c9..05c8bebafe79469466fa956c479aab80ccbc5943 100644 --- a/src/connector/jdbc/CMakeLists.txt +++ b/src/connector/jdbc/CMakeLists.txt @@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED) ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME} POST_BUILD COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-1.0.2-dist.jar ${LIBRARY_OUTPUT_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-1.0.3-dist.jar ${LIBRARY_OUTPUT_PATH} COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml COMMENT "build jdbc driver") ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME}) diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml index 75abea9edcd4b2f14d69feeb885669801b54700d..36f1a1010c372b319fab7fceaf13c9c44689dc6b 100755 --- a/src/connector/jdbc/pom.xml +++ b/src/connector/jdbc/pom.xml @@ -4,7 +4,7 @@ com.taosdata.jdbc taos-jdbcdriver - 1.0.2 + 1.0.3 jar JDBCDriver diff --git a/src/dnode/inc/dnodeMgmt.h b/src/dnode/inc/dnodeMgmt.h index 9530b6a4cba6fe1ad3eb7c271fa4957b5e1159d6..399b4b9920625a766f1bead360237673d539b6f0 100644 --- a/src/dnode/inc/dnodeMgmt.h +++ b/src/dnode/inc/dnodeMgmt.h @@ -23,12 +23,17 @@ extern "C" { #include #include -void dnodeProcessMsgFromMgmt(int8_t *pCont, int32_t contLen, int32_t msgType, void *pConn); -void dnodeSendVpeerCfgMsg(int32_t vnode); -void dnodeSendMeterCfgMsg(int32_t vnode, int32_t sid); +int32_t dnodeInitMgmt(); +void dnodeInitMgmtIp(); + +void dnodeProcessMsgFromMgmt(int8_t msgType, void *pCont, int32_t contLen, void *pConn, int32_t code); +void dnodeSendMsgToMnode(int8_t msgType, void *pCont, int32_t contLen); +void dnodeSendRspToMnode(void *pConn, int8_t msgType, int32_t code, void *pCont, int32_t contLen); + +void dnodeSendVnodeCfgMsg(int32_t vnode); +void dnodeSendTableCfgMsg(int32_t vnode, int32_t sid); + -extern int32_t (*dnodeSendMsgToMnode)(int8_t *pCont, int32_t contLen, int8_t msgType); -extern int32_t (*dnodeSendSimpleRspToMnode)(void *pConn, int32_t msgType, int32_t code); #ifdef __cplusplus } diff --git a/src/dnode/inc/dnodeRead.h b/src/dnode/inc/dnodeRead.h index ff7a8816e02cd6c706345c40a15ab057a3ff8ece..ce73ecac857361d0947bd84a15fdb5048bda0592 100644 --- a/src/dnode/inc/dnodeRead.h +++ b/src/dnode/inc/dnodeRead.h @@ -25,31 +25,21 @@ extern "C" { #include "taosdef.h" #include "taosmsg.h" -/* - * Clear query information associated with this connection - */ -void dnodeFreeQInfo(void *pConn); - -/* - * Clear all query informations - */ -void dnodeFreeQInfos(); - /* * handle query message, and the result is returned by callback function */ -void dnodeQueryData(SQueryMeterMsg *pQuery, void *pConn, void (*callback)(int32_t code, void *pQInfo, void *pConn)); +void dnodeQueryData(SQueryTableMsg *pQuery, void *pConn, void (*callback)(int32_t code, void *pQInfo, void *pConn)); /* * Dispose retrieve msg, and the result will passed through callback function */ typedef void (*SDnodeRetrieveCallbackFp)(int32_t code, void *pQInfo, void *pConn); -void dnodeRetrieveData(SRetrieveMeterMsg *pRetrieve, void *pConn, SDnodeRetrieveCallbackFp callbackFp); +void dnodeRetrieveData(SRetrieveTableMsg *pRetrieve, void *pConn, SDnodeRetrieveCallbackFp callbackFp); /* * Fill retrieve result according to query info */ -int32_t dnodeGetRetrieveData(void *pQInfo, SRetrieveMeterRsp *retrievalRsp); +int32_t dnodeGetRetrieveData(void *pQInfo, SRetrieveTableRsp *pRetrieve); /* * Get the size of retrieve result according to query info diff --git a/src/dnode/inc/dnodeVnodeMgmt.h b/src/dnode/inc/dnodeVnodeMgmt.h index 321ac3083bd429c549b5195077f7eeb0313f3502..504439fc7ea6da0957860c059bc33e90949cdee5 100644 --- a/src/dnode/inc/dnodeVnodeMgmt.h +++ b/src/dnode/inc/dnodeVnodeMgmt.h @@ -45,7 +45,7 @@ bool dnodeCheckVnodeExist(int32_t vid); * Create vnode with specified configuration and open it * if exist, config it */ -int32_t dnodeCreateVnode(int32_t vnode, SVPeersMsg *cfg); +int32_t dnodeCreateVnode(SCreateVnodeMsg *pVnode); /* * Remove vnode from local repository @@ -56,7 +56,7 @@ int32_t dnodeDropVnode(int32_t vnode); * Get the vnode object that has been opened */ //tsdb_repo_t* dnodeGetVnode(int vid); -void* dnodeGetVnode(int vid); +void* dnodeGetVnode(int32_t vnode); /* * get the status of vnode diff --git a/src/dnode/inc/dnodeWrite.h b/src/dnode/inc/dnodeWrite.h index 78af597132ba635af7f61898e9b8350b240107c8..42c94a440c4f370fe0b2b3c3b3d2698c7060b75f 100644 --- a/src/dnode/inc/dnodeWrite.h +++ b/src/dnode/inc/dnodeWrite.h @@ -38,23 +38,23 @@ void dnodeWriteData(SShellSubmitMsg *pSubmit, void *pConn, void (*callback)(SShe * Create table with specified configuration and open it * if table already exist, update its schema and tag */ -int32_t dnodeCreateTable(SDCreateTableMsg *table); +int32_t dnodeCreateTable(SDCreateTableMsg *pTable); /* * Remove table from local repository */ -int32_t dnodeDropTable(int32_t vnode, int32_t sid, uint64_t uid); +int32_t dnodeDropTable(SDRemoveTableMsg *pTable); /* * Create stream * if stream already exist, update it */ -int32_t dnodeCreateStream(SAlterStreamMsg *stream); +int32_t dnodeCreateStream(SDAlterStreamMsg *pStream); /* * Remove all child tables of supertable from local repository */ -int32_t dnodeDropSuperTable(uint64_t stableUid); +int32_t dnodeDropSuperTable(SDRemoveSuperTableMsg *pStable); #ifdef __cplusplus } diff --git a/src/dnode/src/dnodeMgmt.c b/src/dnode/src/dnodeMgmt.c index 60786b27f4120940ada62fef1e0f7e9f963616bf..e1e7df07af2cb15dcd37d12e1ab448c6cc9e6851 100644 --- a/src/dnode/src/dnodeMgmt.c +++ b/src/dnode/src/dnodeMgmt.c @@ -27,188 +27,245 @@ #include "dnodeWrite.h" #include "dnodeVnodeMgmt.h" -static int32_t (*dnodeProcessShellMsgFp[TSDB_MSG_TYPE_MAX])(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn); +void (*dnodeInitMgmtIpFp)() = NULL; +int32_t (*dnodeInitMgmtFp)() = NULL; +void (*dnodeProcessStatusRspFp)(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) = NULL; +void (*dnodeSendMsgToMnodeFp)(int8_t msgType, void *pCont, int32_t contLen) = NULL; +void (*dnodeSendRspToMnodeFp)(void *handle, int32_t code, void *pCont, int contLen) = NULL; + +static void (*dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MAX])(void *pCont, int32_t contLen, int8_t msgType, void *pConn); static void dnodeInitProcessShellMsg(); -void dnodeSendMsgToMnodeImpFp(SSchedMsg *sched) { - int8_t msgType = *(int8_t *) (sched->msg - sizeof(int32_t) - sizeof(int8_t)); - int32_t contLen = *(int32_t *) (sched->msg - sizeof(int8_t)); +static void dnodeSendMsgToMnodeQueueFp(SSchedMsg *sched) { + int32_t contLen = *(int32_t *) (sched->msg - 4); + int32_t code = *(int32_t *) (sched->msg - 8); + int8_t msgType = *(int8_t *) (sched->msg - 9); + void *handle = sched->ahandle; int8_t *pCont = sched->msg; - void *pConn = NULL; - mgmtProcessMsgFromDnode(pCont, contLen, msgType, pConn); - rpcFreeCont(sched->msg); + mgmtProcessMsgFromDnode(msgType, pCont, contLen, handle, code); } -int32_t dnodeSendMsgToMnodeImp(int8_t *pCont, int32_t contLen, int8_t msgType) { - dTrace("msg:%s is sent to mnode", taosMsg[msgType]); - *(int8_t *) (pCont - sizeof(int32_t) - sizeof(int8_t)) = msgType; - *(int32_t *) (pCont - sizeof(int8_t)) = contLen; - - SSchedMsg schedMsg = {0}; - schedMsg.fp = dnodeSendMsgToMnodeImpFp; - schedMsg.msg = pCont; - - taosScheduleTask(tsDnodeMgmtQhandle, &schedMsg); - - return TSDB_CODE_SUCCESS; +void dnodeSendMsgToMnode(int8_t msgType, void *pCont, int32_t contLen) { + dTrace("msg:%d:%s is sent to mnode", msgType, taosMsg[msgType]); + if (dnodeSendMsgToMnodeFp) { + dnodeSendMsgToMnodeFp(msgType, pCont, contLen); + } else { + if (pCont == NULL) { + pCont = rpcMallocCont(1); + contLen = 0; + } + SSchedMsg schedMsg = {0}; + schedMsg.fp = dnodeSendMsgToMnodeQueueFp; + schedMsg.msg = pCont; + *(int32_t *) (pCont - 4) = contLen; + *(int32_t *) (pCont - 8) = TSDB_CODE_SUCCESS; + *(int8_t *) (pCont - 9) = msgType; + taosScheduleTask(tsDnodeMgmtQhandle, &schedMsg); + } } -int32_t (*dnodeSendMsgToMnode)(int8_t *pCont, int32_t contLen, int8_t msgType) = dnodeSendMsgToMnodeImp; - -int32_t dnodeSendSimpleRspToMnodeImp(void *pConn, int32_t msgType, int32_t code) { - int8_t *pCont = rpcMallocCont(sizeof(int32_t)); - *(int32_t *) pCont = code; - - dnodeSendMsgToMnodeImp(pCont, sizeof(int32_t), msgType); - return TSDB_CODE_SUCCESS; +void dnodeSendRspToMnode(void *pConn, int8_t msgType, int32_t code, void *pCont, int32_t contLen) { + dTrace("rsp:%d:%s is sent to mnode, pConn:%p", msgType, taosMsg[msgType], pConn); + if (dnodeSendRspToMnodeFp) { + dnodeSendRspToMnodeFp(pConn, code, pCont, contLen); + } else { + //hack way + if (pCont == NULL) { + pCont = rpcMallocCont(1); + contLen = 0; + } + SSchedMsg schedMsg = {0}; + schedMsg.fp = dnodeSendMsgToMnodeQueueFp; + schedMsg.msg = pCont; + schedMsg.ahandle = pConn; + *(int32_t *) (pCont - 4) = contLen; + *(int32_t *) (pCont - 8) = code; + *(int8_t *) (pCont - 9) = msgType; + taosScheduleTask(tsDnodeMgmtQhandle, &schedMsg); + } } -int32_t (*dnodeSendSimpleRspToMnode)(void *pConn, int32_t msgType, int32_t code) = dnodeSendSimpleRspToMnodeImp; +int32_t dnodeInitMgmt() { + if (dnodeInitMgmtFp) { + dnodeInitMgmtFp(); + } -int32_t dnodeInitMgmtImp() { dnodeInitProcessShellMsg(); return 0; } -int32_t (*dnodeInitMgmt)() = dnodeInitMgmtImp; - -void dnodeInitMgmtIpImp() {} - -void (*dnodeInitMgmtIp)() = dnodeInitMgmtIpImp; +void dnodeInitMgmtIp() { + if (dnodeInitMgmtIpFp) { + dnodeInitMgmtIpFp(); + } +} -void dnodeProcessMsgFromMgmt(int8_t *pCont, int32_t contLen, int32_t msgType, void *pConn) { +void dnodeProcessMsgFromMgmt(int8_t msgType, void *pCont, int32_t contLen, void *pConn, int32_t code) { if (msgType < 0 || msgType >= TSDB_MSG_TYPE_MAX) { dError("invalid msg type:%d", msgType); - } else { - if (dnodeProcessShellMsgFp[msgType]) { - (*dnodeProcessShellMsgFp[msgType])(pCont, contLen, msgType, pConn); - } else { - dError("%s is not processed", taosMsg[msgType]); - } + return; } -} -int32_t dnodeProcessTableCfgRsp(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) { - int32_t code = htonl(*((int32_t *) pCont)); + dTrace("msg:%d:%s is received from mgmt, pConn:%p", msgType, taosMsg[msgType], pConn); - if (code == TSDB_CODE_SUCCESS) { - SDCreateTableMsg *table = (SDCreateTableMsg *) (pCont + sizeof(int32_t)); - return dnodeCreateTable(table); - } else if (code == TSDB_CODE_INVALID_TABLE_ID) { - SDRemoveTableMsg *table = (SDRemoveTableMsg *) (pCont + sizeof(int32_t)); - int32_t vnode = htonl(table->vnode); - int32_t sid = htonl(table->sid); - uint64_t uid = htobe64(table->uid); - dError("vnode:%d, sid:%d table is not configured, remove it", vnode, sid); - return dnodeDropTable(vnode, sid, uid); + if (msgType == TSDB_MSG_TYPE_STATUS_RSP && dnodeProcessStatusRspFp != NULL) { + dnodeProcessStatusRspFp(pCont, contLen, msgType, pConn); + } + if (dnodeProcessMgmtMsgFp[msgType]) { + (*dnodeProcessMgmtMsgFp[msgType])(pCont, contLen, msgType, pConn); } else { - dError("code:%d invalid message", code); - return TSDB_CODE_INVALID_MSG; + dError("%s is not processed", taosMsg[msgType]); } + + //rpcFreeCont(pCont); } -int32_t dnodeProcessCreateTableRequest(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) { - SDCreateTableMsg *table = (SDCreateTableMsg *) pCont; - int32_t code = dnodeCreateTable(table); - dnodeSendSimpleRspToMnode(pConn, msgType + 1, code); - return code; +static void dnodeProcessCreateTableRequest(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { + SDCreateTableMsg *pTable = pCont; + pTable->numOfColumns = htons(pTable->numOfColumns); + pTable->numOfTags = htons(pTable->numOfTags); + pTable->sid = htonl(pTable->sid); + pTable->sversion = htonl(pTable->sversion); + pTable->tagDataLen = htonl(pTable->tagDataLen); + pTable->sqlDataLen = htonl(pTable->sqlDataLen); + pTable->contLen = htonl(pTable->contLen); + pTable->numOfVPeers = htonl(pTable->numOfVPeers); + pTable->uid = htobe64(pTable->uid); + pTable->superTableUid = htobe64(pTable->superTableUid); + pTable->createdTime = htobe64(pTable->createdTime); + + for (int i = 0; i < pTable->numOfVPeers; ++i) { + pTable->vpeerDesc[i].ip = htonl(pTable->vpeerDesc[i].ip); + pTable->vpeerDesc[i].vnode = htonl(pTable->vpeerDesc[i].vnode); + } + + int32_t totalCols = pTable->numOfColumns + pTable->numOfTags; + SSchema *pSchema = (SSchema *) pTable->data; + for (int32_t col = 0; col < totalCols; ++col) { + pSchema->bytes = htons(pSchema->bytes); + pSchema->colId = htons(pSchema->colId); + pSchema++; + } + + int32_t code = dnodeCreateTable(pTable); + dnodeSendRspToMnode(pConn, msgType + 1, code, NULL, 0); } -int32_t dnodeProcessAlterStreamRequest(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) { - SAlterStreamMsg *stream = (SAlterStreamMsg *) pCont; - int32_t code = dnodeCreateStream(stream); - dnodeSendSimpleRspToMnode(pConn, msgType + 1, code); - return code; +static void dnodeProcessAlterStreamRequest(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { + SDAlterStreamMsg *pStream = pCont; + pStream->uid = htobe64(pStream->uid); + pStream->stime = htobe64(pStream->stime); + pStream->vnode = htonl(pStream->vnode); + pStream->sid = htonl(pStream->sid); + pStream->status = htonl(pStream->status); + + int32_t code = dnodeCreateStream(pStream); + dnodeSendRspToMnode(pConn, msgType + 1, code, NULL, 0); } -int32_t dnodeProcessRemoveTableRequest(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) { - SDRemoveTableMsg *table = (SDRemoveTableMsg *) pCont; - int32_t vnode = htonl(table->vnode); - int32_t sid = htonl(table->sid); - uint64_t uid = htobe64(table->uid); +static void dnodeProcessRemoveTableRequest(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { + SDRemoveTableMsg *pTable = pCont; + pTable->sid = htonl(pTable->sid); + pTable->numOfVPeers = htonl(pTable->numOfVPeers); + pTable->uid = htobe64(pTable->uid); - dPrint("vnode:%d, sid:%d table is not configured, remove it", vnode, sid); - int32_t code = dnodeDropTable(vnode, sid, uid); - dnodeSendSimpleRspToMnode(pConn, msgType + 1, code); - return code; + for (int i = 0; i < pTable->numOfVPeers; ++i) { + pTable->vpeerDesc[i].ip = htonl(pTable->vpeerDesc[i].ip); + pTable->vpeerDesc[i].vnode = htonl(pTable->vpeerDesc[i].vnode); + } + + int32_t code = dnodeDropTable(pTable); + dnodeSendRspToMnode(pConn, msgType + 1, code, NULL, 0); } -int32_t dnodeProcessVPeerCfgRsp(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) { +static void dnodeProcessVPeerCfgRsp(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { int32_t code = htonl(*((int32_t *) pCont)); if (code == TSDB_CODE_SUCCESS) { - SVPeersMsg *vpeer = (SVPeersMsg *) (pCont + sizeof(int32_t)); - int32_t vnode = htonl(vpeer->vnode); - return dnodeCreateVnode(vnode, vpeer); + SCreateVnodeMsg *pVnode = (SCreateVnodeMsg *) (pCont + sizeof(int32_t)); + dnodeCreateVnode(pVnode); } else if (code == TSDB_CODE_INVALID_VNODE_ID) { SFreeVnodeMsg *vpeer = (SFreeVnodeMsg *) (pCont + sizeof(int32_t)); int32_t vnode = htonl(vpeer->vnode); dError("vnode:%d, not exist, remove it", vnode); - return dnodeDropVnode(vnode); + dnodeDropVnode(vnode); } else { dError("code:%d invalid message", code); - return TSDB_CODE_INVALID_MSG; } } -int32_t dnodeProcessVPeersMsg(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) { - SVPeersMsg *vpeer = (SVPeersMsg *) pCont; - int32_t vnode = htonl(vpeer->vnode); - - dPrint("vnode:%d, start to config", vnode); +static void dnodeProcessTableCfgRsp(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { + int32_t code = htonl(*((int32_t *) pCont)); - int32_t code = dnodeCreateVnode(vnode, vpeer); - dnodeSendSimpleRspToMnode(pConn, msgType + 1, code); - return code; + if (code == TSDB_CODE_SUCCESS) { + SDCreateTableMsg *table = (SDCreateTableMsg *) (pCont + sizeof(int32_t)); + dnodeCreateTable(table); + } else if (code == TSDB_CODE_INVALID_TABLE_ID) { + SDRemoveTableMsg *pTable = (SDRemoveTableMsg *) (pCont + sizeof(int32_t)); + pTable->sid = htonl(pTable->sid); + pTable->uid = htobe64(pTable->uid); + dError("table:%s, sid:%d table is not configured, remove it", pTable->tableId, pTable->sid); + dnodeDropTable(pTable); + } else { + dError("code:%d invalid message", code); + } } -int32_t dnodeProcessFreeVnodeRequest(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) { - SFreeVnodeMsg *vpeer = (SFreeVnodeMsg *) pCont; - int32_t vnode = htonl(vpeer->vnode); +static void dnodeProcessCreateVnodeRequest(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { + SCreateVnodeMsg *pVnode = (SCreateVnodeMsg *) pCont; - dPrint("vnode:%d, remove it", vnode); + int32_t code = dnodeCreateVnode(pVnode); + dnodeSendRspToMnode(pConn, msgType + 1, code, NULL, 0); +} - int32_t code = dnodeDropVnode(vnode); - dnodeSendSimpleRspToMnode(pConn, msgType + 1, code); +static void dnodeProcessFreeVnodeRequest(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { + SFreeVnodeMsg *pVnode = (SFreeVnodeMsg *) pCont; + int32_t vnode = htonl(pVnode->vnode); - return code; + int32_t code = dnodeDropVnode(vnode); + dnodeSendRspToMnode(pConn, msgType + 1, code, NULL, 0); } -int32_t dnodeProcessDnodeCfgRequest(int8_t *pCont, int32_t contLen, int8_t msgType, void *pConn) { - SCfgMsg *pCfg = (SCfgMsg *)pCont; +static void dnodeProcessDnodeCfgRequest(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { + SCfgDnodeMsg *pCfg = (SCfgDnodeMsg *)pCont; + int32_t code = tsCfgDynamicOptions(pCfg->config); - dnodeSendSimpleRspToMnode(pConn, msgType + 1, code); - return code; + dnodeSendRspToMnode(pConn, msgType + 1, code, NULL, 0); +} + +static void dnodeProcessDropStableRequest(void *pCont, int32_t contLen, int8_t msgType, void *pConn) { + dnodeSendRspToMnode(pConn, msgType + 1, TSDB_CODE_SUCCESS, NULL, 0); } -void dnodeSendVpeerCfgMsg(int32_t vnode) { +void dnodeSendVnodeCfgMsg(int32_t vnode) { SVpeerCfgMsg *cfg = (SVpeerCfgMsg *) rpcMallocCont(sizeof(SVpeerCfgMsg)); if (cfg == NULL) { return; } cfg->vnode = htonl(vnode); - dnodeSendMsgToMnode((int8_t*)cfg, sizeof(SVpeerCfgMsg), TSDB_MSG_TYPE_VNODE_CFG); + dnodeSendMsgToMnode(TSDB_MSG_TYPE_VNODE_CFG, cfg, sizeof(SVpeerCfgMsg)); } -void dnodeSendMeterCfgMsg(int32_t vnode, int32_t sid) { - SMeterCfgMsg *cfg = (SMeterCfgMsg *) rpcMallocCont(sizeof(SMeterCfgMsg)); +void dnodeSendTableCfgMsg(int32_t vnode, int32_t sid) { + STableCfgMsg *cfg = (STableCfgMsg *) rpcMallocCont(sizeof(STableCfgMsg)); if (cfg == NULL) { return; } cfg->vnode = htonl(vnode); - dnodeSendMsgToMnode((int8_t*)cfg, sizeof(SMeterCfgMsg), TSDB_MSG_TYPE_TABLE_CFG); -} - -void dnodeInitProcessShellMsg() { - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_DNODE_CREATE_TABLE] = dnodeProcessCreateTableRequest; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_DNODE_REMOVE_TABLE] = dnodeProcessRemoveTableRequest; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_DNODE_VPEERS] = dnodeProcessVPeersMsg; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_DNODE_FREE_VNODE] = dnodeProcessFreeVnodeRequest; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_DNODE_CFG] = dnodeProcessDnodeCfgRequest; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_ALTER_STREAM] = dnodeProcessAlterStreamRequest; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_VNODE_CFG_RSP] = dnodeProcessVPeerCfgRsp; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_TABLE_CFG_RSP] = dnodeProcessTableCfgRsp; + dnodeSendMsgToMnode(TSDB_MSG_TYPE_TABLE_CFG, cfg, sizeof(STableCfgMsg)); +} + +static void dnodeInitProcessShellMsg() { + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_DNODE_CREATE_TABLE] = dnodeProcessCreateTableRequest; + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_DNODE_REMOVE_TABLE] = dnodeProcessRemoveTableRequest; + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_CREATE_VNODE] = dnodeProcessCreateVnodeRequest; + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_FREE_VNODE] = dnodeProcessFreeVnodeRequest; + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_DNODE_CFG] = dnodeProcessDnodeCfgRequest; + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_ALTER_STREAM] = dnodeProcessAlterStreamRequest; + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_DROP_STABLE] = dnodeProcessDropStableRequest; + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_VNODE_CFG_RSP] = dnodeProcessVPeerCfgRsp; + dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_TABLE_CFG_RSP] = dnodeProcessTableCfgRsp; } \ No newline at end of file diff --git a/src/dnode/src/dnodeModule.c b/src/dnode/src/dnodeModule.c index 70754cc6eb1ac16d463c7c0e2d84436d0c1357a5..96d0db5f6a0da50d0471d6c17e569c938e53d13d 100644 --- a/src/dnode/src/dnodeModule.c +++ b/src/dnode/src/dnodeModule.c @@ -121,10 +121,6 @@ void dnodeStartModulesImp() { } } } - - if (tsModule[TSDB_MOD_MGMT].num != 0 && tsModule[TSDB_MOD_MGMT].cleanUpFp) { - (*tsModule[TSDB_MOD_MGMT].cleanUpFp)(); - } } void (*dnodeStartModules)() = dnodeStartModulesImp; diff --git a/src/dnode/src/dnodeRead.c b/src/dnode/src/dnodeRead.c index b73d51780e83bb4bf4e90d6f2346d6a7e006b0ab..827e599806e1f591597750ae7172ee230f1ae069 100644 --- a/src/dnode/src/dnodeRead.c +++ b/src/dnode/src/dnodeRead.c @@ -22,34 +22,33 @@ #include "dnodeRead.h" #include "dnodeSystem.h" -void dnodeFreeQInfo(void *pConn) {} - -void dnodeFreeQInfos() {} - -void dnodeQueryData(SQueryMeterMsg *pQuery, void *pConn, void (*callback)(int32_t code, void *pQInfo, void *pConn)) { - void *pQInfo = NULL; - int code = TSDB_CODE_SUCCESS; - callback(code, pConn, pQInfo); +void dnodeQueryData(SQueryTableMsg *pQuery, void *pConn, void (*callback)(int32_t code, void *pQInfo, void *pConn)) { + dTrace("conn:%p, query msg is disposed", pConn); + void *pQInfo = 100; + callback(TSDB_CODE_SUCCESS, pQInfo, pConn); } static void dnodeExecuteRetrieveData(SSchedMsg *pSched) { - //SRetrieveMeterMsg *pRetrieve = (SRetrieveMeterMsg *)pSched->msg; SDnodeRetrieveCallbackFp callback = (SDnodeRetrieveCallbackFp)pSched->thandle; + SRetrieveTableMsg *pRetrieve = pSched->msg; void *pConn = pSched->ahandle; + dTrace("conn:%p, retrieve msg is disposed, qhandle:%" PRId64, pConn, pRetrieve->qhandle); + //examples - int32_t code = TSDB_CODE_INVALID_QHANDLE; - void *pQInfo = NULL; //get from pConn - (*callback)(code, pQInfo, pConn); + int32_t code = TSDB_CODE_SUCCESS; + void *pQInfo = (void*)pRetrieve->qhandle; - //TODO build response here + (*callback)(code, pQInfo, pConn); free(pSched->msg); } -void dnodeRetrieveData(SRetrieveMeterMsg *pRetrieve, void *pConn, SDnodeRetrieveCallbackFp callbackFp) { - int8_t *msg = malloc(sizeof(SRetrieveMeterMsg)); - memcpy(msg, pRetrieve, sizeof(SRetrieveMeterMsg)); +void dnodeRetrieveData(SRetrieveTableMsg *pRetrieve, void *pConn, SDnodeRetrieveCallbackFp callbackFp) { + dTrace("conn:%p, retrieve msg is received", pConn); + + void *msg = malloc(sizeof(SRetrieveTableMsg)); + memcpy(msg, pRetrieve, sizeof(SRetrieveTableMsg)); SSchedMsg schedMsg; schedMsg.msg = msg; @@ -59,12 +58,15 @@ void dnodeRetrieveData(SRetrieveMeterMsg *pRetrieve, void *pConn, SDnodeRetrieve taosScheduleTask(tsQueryQhandle, &schedMsg); } -int32_t dnodeGetRetrieveData(void *pQInfo, SRetrieveMeterRsp *retrievalRsp) { +int32_t dnodeGetRetrieveData(void *pQInfo, SRetrieveTableRsp *pRetrieve) { + dTrace("qInfo:%p, data is retrieved"); + pRetrieve->numOfRows = 0; return 0; } int32_t dnodeGetRetrieveDataSize(void *pQInfo) { - return 0; + dTrace("qInfo:%p, contLen is 100"); + return 100; } diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c index 164bc80a3576100993d95a193f949cedd4070e08..d1a58c65e953f0ec2b2f81789b0a91a69003318f 100644 --- a/src/dnode/src/dnodeShell.c +++ b/src/dnode/src/dnodeShell.c @@ -32,44 +32,16 @@ #include "dnodeVnodeMgmt.h" #include "dnodeWrite.h" -static void dnodeProcessRetrieveRequest(int8_t *pCont, int32_t contLen, void *pConn); -static void dnodeProcessQueryRequest(int8_t *pCont, int32_t contLen, void *pConn); -static void dnodeProcessShellSubmitRequest(int8_t *pCont, int32_t contLen, void *pConn); +static void dnodeProcessRetrieveMsg(void *pCont, int32_t contLen, void *pConn); +static void dnodeProcessQueryMsg(void *pCont, int32_t contLen, void *pConn); +static void dnodeProcessSubmitMsg(void *pCont, int32_t contLen, void *pConn); +static void dnodeProcessMsgFromShell(char msgType, void *pCont, int contLen, void *handle, int32_t code); +static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey); static void *tsDnodeShellServer = NULL; static int32_t tsDnodeQueryReqNum = 0; static int32_t tsDnodeSubmitReqNum = 0; -void* dnodeProcessMsgFromShell(int8_t msgType, void *pCont, int32_t contLen, void *handle, int32_t index) { - assert(handle != NULL); - - if (pCont == NULL || contLen == 0) { - dnodeFreeQInfo(handle); - dTrace("conn:%p, free query info", handle); - return NULL; - } - - if (dnodeGetRunStatus() != TSDB_DNODE_RUN_STATUS_RUNING) { - rpcSendResponse(handle, TSDB_CODE_NOT_READY, 0, 0); - dTrace("conn:%p, query msg is ignored since dnode not running", handle); - return NULL; - } - - dTrace("conn:%p, msg:%s is received", handle, taosMsg[msgType]); - - if (msgType == TSDB_MSG_TYPE_DNODE_QUERY) { - dnodeProcessQueryRequest(pCont, contLen, handle); - } else if (msgType == TSDB_MSG_TYPE_DNODE_RETRIEVE) { - dnodeProcessRetrieveRequest(pCont, contLen, handle); - } else if (msgType == TSDB_MSG_TYPE_DNODE_SUBMIT) { - dnodeProcessShellSubmitRequest(pCont, contLen, handle); - } else { - dError("conn:%p, msg:%s is not processed", handle, taosMsg[msgType]); - } - - return NULL; -} - int32_t dnodeInitShell() { int32_t numOfThreads = tsNumOfCores * tsNumOfThreadsPerCore; numOfThreads = (int32_t) ((1.0 - tsRatioOfQueryThreads) * numOfThreads / 2.0); @@ -83,10 +55,11 @@ int32_t dnodeInitShell() { rpcInit.localPort = tsVnodeShellPort; rpcInit.label = "DND-shell"; rpcInit.numOfThreads = numOfThreads; - rpcInit.cfp = dnodeProcessMsgFromShell; + rpcInit.cfp = dnodeProcessMsgFromShell; rpcInit.sessions = TSDB_SESSIONS_PER_DNODE; - rpcInit.connType = TAOS_CONN_SOCKET_TYPE_S(); + rpcInit.connType = TAOS_CONN_SERVER; rpcInit.idleTime = tsShellActivityTimer * 2000; + rpcInit.afp = dnodeRetrieveUserAuthInfo; tsDnodeShellServer = rpcOpen(&rpcInit); if (tsDnodeShellServer == NULL) { @@ -102,35 +75,69 @@ void dnodeCleanupShell() { if (tsDnodeShellServer) { rpcClose(tsDnodeShellServer); } +} - dnodeFreeQInfos(); +SDnodeStatisInfo dnodeGetStatisInfo() { + SDnodeStatisInfo info = {0}; + if (dnodeGetRunStatus() == TSDB_DNODE_RUN_STATUS_RUNING) { + info.httpReqNum = httpGetReqCount(); + info.queryReqNum = atomic_exchange_32(&tsDnodeQueryReqNum, 0); + info.submitReqNum = atomic_exchange_32(&tsDnodeSubmitReqNum, 0); + } + + return info; } -void dnodeProcessQueryRequestCb(int code, void *pQInfo, void *pConn) { - int32_t contLen = sizeof(SQueryMeterRsp); - SQueryMeterRsp *queryRsp = (SQueryMeterRsp *) rpcMallocCont(contLen); - if (queryRsp == NULL) { +static void dnodeProcessMsgFromShell(char msgType, void *pCont, int contLen, void *handle, int32_t code) { + if (dnodeGetRunStatus() != TSDB_DNODE_RUN_STATUS_RUNING) { + rpcSendResponse(handle, TSDB_CODE_NOT_READY, 0, 0); + dTrace("query msg is ignored since dnode not running"); return; } - dTrace("conn:%p, query data, code:%d pQInfo:%p", pConn, code, pQInfo); + dTrace("conn:%p, msg:%s is received", handle, taosMsg[(int8_t)msgType]); - queryRsp->code = htonl(code); - queryRsp->qhandle = (uint64_t) (pQInfo); + if (msgType == TSDB_MSG_TYPE_QUERY) { + dnodeProcessQueryMsg(pCont, contLen, handle); + } else if (msgType == TSDB_MSG_TYPE_RETRIEVE) { + dnodeProcessRetrieveMsg(pCont, contLen, handle); + } else if (msgType == TSDB_MSG_TYPE_SUBMIT) { + dnodeProcessSubmitMsg(pCont, contLen, handle); + } else { + dError("conn:%p, msg:%s is not processed", handle, taosMsg[(int8_t)msgType]); + } + + //TODO free may be cause segmentfault + // rpcFreeCont(pCont); +} + +static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey) { + return TSDB_CODE_SUCCESS; +} + +static void dnodeProcessQueryMsgCb(int32_t code, void *pQInfo, void *pConn) { + dTrace("conn:%p, query is returned, code:%d", pConn, code); + int32_t contLen = sizeof(SQueryTableRsp); + SQueryTableRsp *queryRsp = (SQueryTableRsp *) rpcMallocCont(contLen); + if (queryRsp == NULL) { + rpcSendResponse(pConn, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); + return; + } + + queryRsp->code = htonl(code); + queryRsp->qhandle = htobe64((uint64_t) (pQInfo)); rpcSendResponse(pConn, TSDB_CODE_SUCCESS, queryRsp, contLen); } -static void dnodeProcessQueryRequest(int8_t *pCont, int32_t contLen, void *pConn) { +static void dnodeProcessQueryMsg(void *pCont, int32_t contLen, void *pConn) { atomic_fetch_add_32(&tsDnodeQueryReqNum, 1); - dTrace("conn:%p, start to query data", pConn); - - SQueryMeterMsg *pQuery = (SQueryMeterMsg *) pCont; - dnodeQueryData(pQuery, pConn, dnodeProcessQueryRequestCb); + SQueryTableMsg *pQuery = (SQueryTableMsg *) pCont; + dnodeQueryData(pQuery, pConn, dnodeProcessQueryMsgCb); } -void dnodeProcessRetrieveRequestCb(int32_t code, void *pQInfo, void *pConn) { - dTrace("conn:%p, retrieve data, code:%d", pConn, code); +void dnodeProcessRetrieveMsgCb(int32_t code, void *pQInfo, void *pConn) { + dTrace("conn:%p, retrieve is returned, code:%d", pConn, code); assert(pConn != NULL); if (code != TSDB_CODE_SUCCESS) { @@ -140,56 +147,57 @@ void dnodeProcessRetrieveRequestCb(int32_t code, void *pQInfo, void *pConn) { assert(pQInfo != NULL); int32_t contLen = dnodeGetRetrieveDataSize(pQInfo); - SRetrieveMeterRsp *retrieveRsp = (SRetrieveMeterRsp *) rpcMallocCont(contLen); - if (retrieveRsp == NULL) { + SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *) rpcMallocCont(contLen); + if (pRetrieve == NULL) { rpcSendResponse(pConn, TSDB_CODE_SERV_OUT_OF_MEMORY, 0, 0); return; } - code = dnodeGetRetrieveData(pQInfo, retrieveRsp); + code = dnodeGetRetrieveData(pQInfo, pRetrieve); if (code != TSDB_CODE_SUCCESS) { rpcSendResponse(pConn, TSDB_CODE_INVALID_QHANDLE, 0, 0); } - retrieveRsp->numOfRows = htonl(retrieveRsp->numOfRows); - retrieveRsp->precision = htons(retrieveRsp->precision); - retrieveRsp->offset = htobe64(retrieveRsp->offset); - retrieveRsp->useconds = htobe64(retrieveRsp->useconds); + pRetrieve->numOfRows = htonl(pRetrieve->numOfRows); + pRetrieve->precision = htons(pRetrieve->precision); + pRetrieve->offset = htobe64(pRetrieve->offset); + pRetrieve->useconds = htobe64(pRetrieve->useconds); - rpcSendResponse(pConn, TSDB_CODE_SUCCESS, retrieveRsp, contLen); + rpcSendResponse(pConn, TSDB_CODE_SUCCESS, pRetrieve, contLen); } -static void dnodeProcessRetrieveRequest(int8_t *pCont, int32_t contLen, void *pConn) { - dTrace("conn:%p, start to retrieve data", pConn); +static void dnodeProcessRetrieveMsg(void *pCont, int32_t contLen, void *pConn) { + SRetrieveTableMsg *pRetrieve = (SRetrieveTableMsg *) pCont; + pRetrieve->qhandle = htobe64(pRetrieve->qhandle); + pRetrieve->free = htons(pRetrieve->free); - SRetrieveMeterMsg *pRetrieve = (SRetrieveMeterMsg *) pCont; - dnodeRetrieveData(pRetrieve, pConn, dnodeProcessRetrieveRequestCb); + dnodeRetrieveData(pRetrieve, pConn, dnodeProcessRetrieveMsgCb); } -void dnodeProcessShellSubmitRequestCb(SShellSubmitRspMsg *result, void *pConn) { +void dnodeProcessSubmitMsgCb(SShellSubmitRspMsg *result, void *pConn) { assert(result != NULL); + dTrace("conn:%p, submit is returned, code:%d", pConn, result->code); if (result->code != 0) { - rpcSendResponse(pConn, result->code, 0, 0); + rpcSendResponse(pConn, result->code, NULL, 0); return; } int32_t contLen = sizeof(SShellSubmitRspMsg) + result->numOfFailedBlocks * sizeof(SShellSubmitRspBlock); SShellSubmitRspMsg *submitRsp = (SShellSubmitRspMsg *) rpcMallocCont(contLen); if (submitRsp == NULL) { - rpcSendResponse(pConn, TSDB_CODE_SERV_OUT_OF_MEMORY, 0, 0); + rpcSendResponse(pConn, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); return; } - dTrace("code:%d, numOfRows:%d affectedRows:%d", result->code, result->numOfRows, result->affectedRows); memcpy(submitRsp, result, contLen); for (int i = 0; i < submitRsp->numOfFailedBlocks; ++i) { SShellSubmitRspBlock *block = &submitRsp->failedBlocks[i]; if (block->code == TSDB_CODE_NOT_ACTIVE_VNODE || block->code == TSDB_CODE_INVALID_VNODE_ID) { - dnodeSendVpeerCfgMsg(block->vnode); + dnodeSendVnodeCfgMsg(block->vnode); } else if (block->code == TSDB_CODE_INVALID_TABLE_ID || block->code == TSDB_CODE_NOT_ACTIVE_TABLE) { - dnodeSendMeterCfgMsg(block->vnode, block->sid); + dnodeSendTableCfgMsg(block->vnode, block->sid); } block->index = htonl(block->index); block->vnode = htonl(block->vnode); @@ -205,19 +213,9 @@ void dnodeProcessShellSubmitRequestCb(SShellSubmitRspMsg *result, void *pConn) { rpcSendResponse(pConn, TSDB_CODE_SUCCESS, submitRsp, contLen); } -static void dnodeProcessShellSubmitRequest(int8_t *pCont, int32_t contLen, void *pConn) { - SShellSubmitMsg *pSubmit = (SShellSubmitMsg *) pCont; - dnodeWriteData(pSubmit, pConn, dnodeProcessShellSubmitRequestCb); +static void dnodeProcessSubmitMsg(void *pCont, int32_t contLen, void *pConn) { atomic_fetch_add_32(&tsDnodeSubmitReqNum, 1); -} -SDnodeStatisInfo dnodeGetStatisInfo() { - SDnodeStatisInfo info = {0}; - if (dnodeGetRunStatus() == TSDB_DNODE_RUN_STATUS_RUNING) { - info.httpReqNum = httpGetReqCount(); - info.queryReqNum = atomic_exchange_32(&tsDnodeQueryReqNum, 0); - info.submitReqNum = atomic_exchange_32(&tsDnodeSubmitReqNum, 0); - } - - return info; -} \ No newline at end of file + SShellSubmitMsg *pSubmit = (SShellSubmitMsg *) pCont; + dnodeWriteData(pSubmit, pConn, dnodeProcessSubmitMsgCb); +} diff --git a/src/dnode/src/dnodeSystem.c b/src/dnode/src/dnodeSystem.c index 24eeddb1d1053a2f39b3b824822c4ccba6941125..71e8f47e1249ba71425765f9184e13514cba753b 100644 --- a/src/dnode/src/dnodeSystem.c +++ b/src/dnode/src/dnodeSystem.c @@ -33,16 +33,12 @@ #include "dnodeVnodeMgmt.h" #ifdef CLUSTER -#include "dnodeCluster.h" -#include "httpAdmin.h" -#include "mnodeAccount.h" -#include "mnodeBalance.h" -#include "mnodeCluster.h" -#include "sdbReplica.h" -#include "multilevelStorage.h" -#include "vnodeCluster.h" -#include "vnodeReplica.h" -#include "dnodeGrant.h" +#include "acct.h" +#include "admin.h" +#include "cluster.h" +#include "grant.h" +#include "replica.h" +#include "storage.h" #endif static pthread_mutex_t tsDnodeMutex; @@ -120,16 +116,7 @@ void dnodeCheckDataDirOpenned(const char *dir) { void dnodeInitPlugins() { #ifdef CLUSTER - dnodeClusterInit(); - httpAdminInit(); - mnodeAccountInit(); - mnodeBalanceInit(); - mnodeClusterInit(); - sdbReplicaInit(); - multilevelStorageInit(); - vnodeClusterInit(); - vnodeReplicaInit(); - dnodeGrantInit(); + acctInit(); #endif } diff --git a/src/dnode/src/dnodeVnodeMgmt.c b/src/dnode/src/dnodeVnodeMgmt.c index c39f7848e15103584e0f1b175a3cef4a665a726a..cf43f87aaae1882f52bac362bdad294d3d475f2e 100644 --- a/src/dnode/src/dnodeVnodeMgmt.c +++ b/src/dnode/src/dnodeVnodeMgmt.c @@ -20,34 +20,42 @@ #include "dnodeVnodeMgmt.h" int32_t dnodeOpenVnodes() { - return 0; + dPrint("open all vnodes"); + return TSDB_CODE_SUCCESS; } int32_t dnodeCleanupVnodes() { - return 0; + dPrint("clean all vnodes"); + return TSDB_CODE_SUCCESS; } bool dnodeCheckVnodeExist(int32_t vnode) { + dPrint("vnode:%d, check vnode exist", vnode); return true; } -int32_t dnodeCreateVnode(int32_t vnode, SVPeersMsg *cfg) { - return 0; +int32_t dnodeCreateVnode(SCreateVnodeMsg *pVnode) { + dPrint("vnode:%d, is created", htonl(pVnode->vnode)); + return TSDB_CODE_SUCCESS; } int32_t dnodeDropVnode(int32_t vnode) { - return 0; + dPrint("vnode:%d, is dropped", vnode); + return TSDB_CODE_SUCCESS; } -void* dnodeGetVnode(int vid) { +void* dnodeGetVnode(int32_t vnode) { + dPrint("vnode:%d, get vnode"); return NULL; } EVnodeStatus dnodeGetVnodeStatus(int32_t vnode) { + dPrint("vnode:%d, get vnode status"); return TSDB_VN_STATUS_MASTER; } bool dnodeCheckTableExist(int32_t vnode, int32_t sid, int64_t uid) { + dPrint("vnode:%d, sid:%d, check table exist"); return true; } diff --git a/src/dnode/src/dnodeWrite.c b/src/dnode/src/dnodeWrite.c index 59ede2711b15ff1c1384d05f408e4837d95d80e8..238fb58e7571fba44464f9182fb901cf5d865b49 100644 --- a/src/dnode/src/dnodeWrite.c +++ b/src/dnode/src/dnodeWrite.c @@ -17,10 +17,13 @@ #include "os.h" #include "taoserror.h" #include "tlog.h" +#include "tutil.h" #include "dnodeWrite.h" #include "dnodeVnodeMgmt.h" void dnodeWriteData(SShellSubmitMsg *pSubmit, void *pConn, void (*callback)(SShellSubmitRspMsg *rsp, void *pConn)) { + dTrace("submit msg is disposed, affectrows:1"); + SShellSubmitRspMsg result = {0}; int32_t numOfSid = htonl(pSubmit->numOfSid); @@ -30,18 +33,49 @@ void dnodeWriteData(SShellSubmitMsg *pSubmit, void *pConn, void (*callback)(SShe callback(&result, pConn); } - //TODO: submit implementation + result.code = 0; + result.numOfRows = 1; + result.affectedRows = 1; + result.numOfFailedBlocks = 0; + callback(&result, pConn); } -int32_t dnodeCreateTable(SDCreateTableMsg *table) { +int32_t dnodeCreateTable(SDCreateTableMsg *pTable) { + if (pTable->tableType == TSDB_TABLE_TYPE_CHILD_TABLE) { + dTrace("table:%s, start to create child table, stable:%s", pTable->tableId, pTable->superTableId); + } else if (pTable->tableType == TSDB_TABLE_TYPE_NORMAL_TABLE){ + dTrace("table:%s, start to create normal table", pTable->tableId); + } else if (pTable->tableType == TSDB_TABLE_TYPE_STREAM_TABLE){ + dTrace("table:%s, start to create stream table", pTable->tableId); + } else { + dError("table:%s, invalid table type:%d", pTable->tableType); + } + + for (int i = 0; i < pTable->numOfVPeers; ++i) { + dTrace("table:%s ip:%s vnode:%d sid:%d", pTable->tableId, taosIpStr(pTable->vpeerDesc[i].ip), + pTable->vpeerDesc[i].vnode, pTable->sid); + } + + SSchema *pSchema = (SSchema *) pTable->data; + for (int32_t col = 0; col < pTable->numOfColumns; ++col) { + dTrace("table:%s col index:%d colId:%d bytes:%d type:%d name:%s", + pTable->tableId, col, pSchema->colId, pSchema->bytes, pSchema->type, pSchema->name); + pSchema++; + } + for (int32_t col = 0; col < pTable->numOfTags; ++col) { + dTrace("table:%s tag index:%d colId:%d bytes:%d type:%d name:%s", + pTable->tableId, col, pSchema->colId, pSchema->bytes, pSchema->type, pSchema->name); + pSchema++; + } + return TSDB_CODE_SUCCESS; } - /* * Remove table from local repository */ -int32_t dnodeDropTable(int32_t vnode, int32_t sid, uint64_t uid) { +int32_t dnodeDropTable(SDRemoveTableMsg *pTable) { + dPrint("table:%s, sid:%d is removed", pTable->tableId, pTable->sid); return TSDB_CODE_SUCCESS; } @@ -49,24 +83,16 @@ int32_t dnodeDropTable(int32_t vnode, int32_t sid, uint64_t uid) { * Create stream * if stream already exist, update it */ -int32_t dnodeCreateStream(SAlterStreamMsg *stream) { - int32_t vnode = htonl(stream->vnode); - int32_t sid = htonl(stream->sid); - uint64_t uid = htobe64(stream->uid); - - if (!dnodeCheckTableExist(vnode, sid, uid)) { - return TSDB_CODE_INVALID_TABLE; - } - - //TODO create or remove stream - - return 0; +int32_t dnodeCreateStream(SDAlterStreamMsg *pStream) { + dPrint("stream:%s, is created, ", pStream->tableId); + return TSDB_CODE_SUCCESS; } /* * Remove all child tables of supertable from local repository */ -int32_t dnodeDropSuperTable(uint64_t stableUid) { +int32_t dnodeDropSuperTable(SDRemoveSuperTableMsg *pStable) { + dPrint("stable:%s, is removed", pStable->tableId); return TSDB_CODE_SUCCESS; } diff --git a/src/inc/.fuse_hidden0000e2ae00000244 b/src/inc/.fuse_hidden0000e2ae00000244 new file mode 100644 index 0000000000000000000000000000000000000000..6c704221906284c996e6a0fda354bd26c9d5655c --- /dev/null +++ b/src/inc/.fuse_hidden0000e2ae00000244 @@ -0,0 +1,816 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef TDENGINE_TAOSMSG_H +#define TDENGINE_TAOSMSG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "taosdef.h" +#include "taoserror.h" +#include "taosdef.h" +#include "trpc.h" + +// message type +#define TSDB_MSG_TYPE_REG 1 +#define TSDB_MSG_TYPE_REG_RSP 2 +#define TSDB_MSG_TYPE_DNODE_SUBMIT 3 +#define TSDB_MSG_TYPE_DNODE_SUBMIT_RSP 4 +#define TSDB_MSG_TYPE_DNODE_QUERY 5 +#define TSDB_MSG_TYPE_DNODE_QUERY_RSP 6 +#define TSDB_MSG_TYPE_RETRIEVE 7 +#define TSDB_MSG_TYPE_RETRIEVE_RSP 8 +#define TSDB_MSG_TYPE_DNODE_CREATE_TABLE 9 +#define TSDB_MSG_TYPE_DNODE_CREATE_TABLE_RSP 10 +#define TSDB_MSG_TYPE_DNODE_REMOVE_TABLE 11 +#define TSDB_MSG_TYPE_DNODE_REMOVE_TABLE_RSP 12 +#define TSDB_MSG_TYPE_DNODE_CREATE_VNODE 13 +#define TSDB_MSG_TYPE_DNODE_VPEERS_RSP 14 +#define TSDB_MSG_TYPE_DNODE_FREE_VNODE 15 +#define TSDB_MSG_TYPE_DNODE_FREE_VNODE_RSP 16 +#define TSDB_MSG_TYPE_DNODE_CFG 17 +#define TSDB_MSG_TYPE_DNODE_CFG_RSP 18 +#define TSDB_MSG_TYPE_DNODE_ALTER_STREAM 19 +#define TSDB_MSG_TYPE_DNODE_ALTER_STREAM_RSP 20 +#define TSDB_MSG_TYPE_SDB_SYNC 21 +#define TSDB_MSG_TYPE_SDB_SYNC_RSP 22 +#define TSDB_MSG_TYPE_SDB_FORWARD 23 +#define TSDB_MSG_TYPE_SDB_FORWARD_RSP 24 +#define TSDB_MSG_TYPE_CONNECT 31 +#define TSDB_MSG_TYPE_CONNECT_RSP 32 +#define TSDB_MSG_TYPE_CREATE_ACCT 33 +#define TSDB_MSG_TYPE_CREATE_ACCT_RSP 34 +#define TSDB_MSG_TYPE_ALTER_ACCT 35 +#define TSDB_MSG_TYPE_ALTER_ACCT_RSP 36 +#define TSDB_MSG_TYPE_DROP_ACCT 37 +#define TSDB_MSG_TYPE_DROP_ACCT_RSP 38 +#define TSDB_MSG_TYPE_CREATE_USER 39 +#define TSDB_MSG_TYPE_CREATE_USER_RSP 40 +#define TSDB_MSG_TYPE_ALTER_USER 41 +#define TSDB_MSG_TYPE_ALTER_USER_RSP 42 +#define TSDB_MSG_TYPE_DROP_USER 43 +#define TSDB_MSG_TYPE_DROP_USER_RSP 44 +#define TSDB_MSG_TYPE_CREATE_MNODE 45 +#define TSDB_MSG_TYPE_CREATE_MNODE_RSP 46 +#define TSDB_MSG_TYPE_DROP_MNODE 47 +#define TSDB_MSG_TYPE_DROP_MNODE_RSP 48 +#define TSDB_MSG_TYPE_CREATE_DNODE 49 +#define TSDB_MSG_TYPE_CREATE_DNODE_RSP 50 +#define TSDB_MSG_TYPE_DROP_DNODE 51 +#define TSDB_MSG_TYPE_DROP_DNODE_RSP 52 +#define TSDB_MSG_TYPE_ALTER_DNODE 53 +#define TSDB_MSG_TYPE_ALTER_DNODE_RSP 54 +#define TSDB_MSG_TYPE_CREATE_DB 55 +#define TSDB_MSG_TYPE_CREATE_DB_RSP 56 +#define TSDB_MSG_TYPE_DROP_DB 57 +#define TSDB_MSG_TYPE_DROP_DB_RSP 58 +#define TSDB_MSG_TYPE_USE_DB 59 +#define TSDB_MSG_TYPE_USE_DB_RSP 60 +#define TSDB_MSG_TYPE_ALTER_DB 61 +#define TSDB_MSG_TYPE_ALTER_DB_RSP 62 +#define TSDB_MSG_TYPE_CREATE_TABLE 63 +#define TSDB_MSG_TYPE_CREATE_TABLE_RSP 64 +#define TSDB_MSG_TYPE_DROP_TABLE 65 +#define TSDB_MSG_TYPE_DROP_TABLE_RSP 66 +#define TSDB_MSG_TYPE_ALTER_TABLE 67 +#define TSDB_MSG_TYPE_ALTER_TABLE_RSP 68 +#define TSDB_MSG_TYPE_VNODE_CFG 69 +#define TSDB_MSG_TYPE_VNODE_CFG_RSP 70 +#define TSDB_MSG_TYPE_TABLE_CFG 71 +#define TSDB_MSG_TYPE_TABLE_CFG_RSP 72 +#define TSDB_MSG_TYPE_TABLE_META 73 +#define TSDB_MSG_TYPE_TABLE_META_RSP 74 +#define TSDB_MSG_TYPE_STABLE_META 75 +#define TSDB_MSG_TYPE_STABLE_META_RSP 76 +#define TSDB_MSG_TYPE_MULTI_TABLE_META 77 +#define TSDB_MSG_TYPE_MULTI_TABLE_META_RSP 78 +#define TSDB_MSG_TYPE_ALTER_STREAM 79 +#define TSDB_MSG_TYPE_ALTER_STREAM_RSP 80 +#define TSDB_MSG_TYPE_SHOW 81 +#define TSDB_MSG_TYPE_SHOW_RSP 82 +#define TSDB_MSG_TYPE_CFG_MNODE 83 +#define TSDB_MSG_TYPE_CFG_MNODE_RSP 84 +#define TSDB_MSG_TYPE_KILL_QUERY 85 +#define TSDB_MSG_TYPE_KILL_QUERY_RSP 86 +#define TSDB_MSG_TYPE_KILL_STREAM 87 +#define TSDB_MSG_TYPE_KILL_STREAM_RSP 88 +#define TSDB_MSG_TYPE_KILL_CONNECTION 89 +#define TSDB_MSG_TYPE_KILL_CONNECTION_RSP 90 +#define TSDB_MSG_TYPE_HEARTBEAT 91 +#define TSDB_MSG_TYPE_HEARTBEAT_RSP 92 +#define TSDB_MSG_TYPE_STATUS 93 +#define TSDB_MSG_TYPE_STATUS_RSP 94 +#define TSDB_MSG_TYPE_GRANT 95 +#define TSDB_MSG_TYPE_GRANT_RSP 96 +#define TSDB_MSG_TYPE_MAX 97 + +// IE type +#define TSDB_IE_TYPE_SEC 1 +#define TSDB_IE_TYPE_META 2 +#define TSDB_IE_TYPE_MGMT_IP 3 +#define TSDB_IE_TYPE_DNODE_CFG 4 +#define TSDB_IE_TYPE_NEW_VERSION 5 +#define TSDB_IE_TYPE_DNODE_EXT 6 +#define TSDB_IE_TYPE_DNODE_STATE 7 + +enum _mgmt_table { + TSDB_MGMT_TABLE_ACCT, + TSDB_MGMT_TABLE_USER, + TSDB_MGMT_TABLE_DB, + TSDB_MGMT_TABLE_TABLE, + TSDB_MGMT_TABLE_DNODE, + TSDB_MGMT_TABLE_MNODE, + TSDB_MGMT_TABLE_VGROUP, + TSDB_MGMT_TABLE_METRIC, + TSDB_MGMT_TABLE_MODULE, + TSDB_MGMT_TABLE_QUERIES, + TSDB_MGMT_TABLE_STREAMS, + TSDB_MGMT_TABLE_CONFIGS, + TSDB_MGMT_TABLE_CONNS, + TSDB_MGMT_TABLE_SCORES, + TSDB_MGMT_TABLE_GRANTS, + TSDB_MGMT_TABLE_VNODES, + TSDB_MGMT_TABLE_MAX, +}; + +#define TSDB_ALTER_TABLE_ADD_TAG_COLUMN 1 +#define TSDB_ALTER_TABLE_DROP_TAG_COLUMN 2 +#define TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN 3 +#define TSDB_ALTER_TABLE_UPDATE_TAG_VAL 4 + +#define TSDB_ALTER_TABLE_ADD_COLUMN 5 +#define TSDB_ALTER_TABLE_DROP_COLUMN 6 + +#define TSDB_INTERPO_NONE 0 +#define TSDB_INTERPO_NULL 1 +#define TSDB_INTERPO_SET_VALUE 2 +#define TSDB_INTERPO_LINEAR 3 +#define TSDB_INTERPO_PREV 4 + +#define TSDB_ALTER_USER_PASSWD 0x1 +#define TSDB_ALTER_USER_PRIVILEGES 0x2 + +#define TSDB_KILL_MSG_LEN 30 + +typedef enum { + TSDB_TABLE_TYPE_SUPER_TABLE = 0, // super table + TSDB_TABLE_TYPE_CHILD_TABLE = 1, // table created from super table + TSDB_TABLE_TYPE_NORMAL_TABLE = 2, // ordinary table + TSDB_TABLE_TYPE_STREAM_TABLE = 3, // table created from stream computing + TSDB_TABLE_TYPE_MAX = 4 +} ETableType; + + +#define TSDB_VN_READ_ACCCESS ((char)0x1) +#define TSDB_VN_WRITE_ACCCESS ((char)0x2) +#define TSDB_VN_ALL_ACCCESS (TSDB_VN_READ_ACCCESS | TSDB_VN_WRITE_ACCCESS) + +#define TSDB_COL_NORMAL 0x0U +#define TSDB_COL_TAG 0x1U +#define TSDB_COL_JOIN 0x2U + +extern char *taosMsg[]; + +#pragma pack(push, 1) + +typedef struct { + int32_t vnode; + int32_t sid; + int32_t sversion; + uint64_t uid; + int16_t numOfRows; + char payLoad[]; +} SShellSubmitBlock; + +typedef struct { + int8_t import; + int8_t reserved[3]; + int32_t numOfSid; /* total number of sid */ + char blks[]; /* numOfSid blocks, each blocks for one table */ +} SShellSubmitMsg; + +typedef struct { + int32_t index; // index of failed block in submit blocks + int32_t vnode; // vnode index of failed block + int32_t sid; // table index of failed block + int32_t code; // errorcode while write data to vnode, such as not created, dropped, no space, invalid table +} SShellSubmitRspBlock; + +typedef struct { + int32_t code; // 0-success, > 0 error code + int32_t numOfRows; // number of records the client is trying to write + int32_t affectedRows; // number of records actually written + int32_t failedRows; // number of failed records (exclude duplicate records) + int32_t numOfFailedBlocks; + SShellSubmitRspBlock failedBlocks[]; +} SShellSubmitRspMsg; + +typedef struct SSchema { + uint8_t type; + char name[TSDB_COL_NAME_LEN + 1]; + int16_t colId; + int16_t bytes; +} SSchema; + +typedef struct { + int32_t vnode; //the index of vnode + uint32_t ip; +} SVPeerDesc; + +typedef struct { + int8_t tableType; + int16_t numOfColumns; + int16_t numOfTags; + int32_t sid; + int32_t sversion; + int32_t tagDataLen; + int32_t sqlDataLen; + int32_t contLen; + int32_t numOfVPeers; + uint64_t uid; + uint64_t superTableUid; + uint64_t createdTime; + SVPeerDesc vpeerDesc[TSDB_MAX_MPEERS]; + char tableId[TSDB_TABLE_ID_LEN + 1]; + char superTableId[TSDB_TABLE_ID_LEN + 1]; + char data[]; +} SDCreateTableMsg; + +typedef struct { + char tableId[TSDB_TABLE_ID_LEN + 1]; + char db[TSDB_DB_NAME_LEN + 1]; + int8_t igExists; + int16_t numOfTags; + int16_t numOfColumns; + int16_t sqlLen; // the length of SQL, it starts after schema , sql is a null-terminated string + int16_t reserved[16]; + SSchema schema[]; +} SCreateTableMsg; + +typedef struct { + char tableId[TSDB_TABLE_ID_LEN + 1]; + int8_t igNotExists; +} SDropTableMsg; + +typedef struct { + char tableId[TSDB_TABLE_ID_LEN + 1]; + char db[TSDB_DB_NAME_LEN + 1]; + int16_t type; /* operation type */ + char tagVal[TSDB_MAX_BYTES_PER_ROW]; + int8_t numOfCols; /* number of schema */ + SSchema schema[]; +} SAlterTableMsg; + +typedef struct { + char clientVersion[TSDB_VERSION_LEN]; + char msgVersion[TSDB_VERSION_LEN]; + char db[TSDB_TABLE_ID_LEN + 1]; +} SConnectMsg; + +typedef struct { + char acctId[TSDB_ACCT_LEN + 1]; + char serverVersion[TSDB_VERSION_LEN]; + int8_t writeAuth; + int8_t superAuth; + SRpcIpSet ipList; +} SConnectRsp; + +typedef struct { + int32_t maxUsers; + int32_t maxDbs; + int32_t maxTimeSeries; + int32_t maxConnections; + int32_t maxStreams; + int32_t maxPointsPerSecond; + int64_t maxStorage; // In unit of GB + int64_t maxQueryTime; // In unit of hour + int64_t maxInbound; + int64_t maxOutbound; + int8_t accessState; // Configured only by command +} SAcctCfg; + +typedef struct { + char user[TSDB_USER_LEN + 1]; + char pass[TSDB_KEY_LEN + 1]; + SAcctCfg cfg; +} SCreateAcctMsg, SAlterAcctMsg; + +typedef struct { + char user[TSDB_USER_LEN + 1]; +} SDropUserMsg, SDropAcctMsg; + +typedef struct { + char user[TSDB_USER_LEN + 1]; + char pass[TSDB_KEY_LEN + 1]; + int8_t privilege; + int8_t flag; +} SCreateUserMsg, SAlterUserMsg; + +typedef struct { + char db[TSDB_TABLE_ID_LEN + 1]; +} SMgmtHead; + +typedef struct { + int32_t sid; + int32_t numOfVPeers; + uint64_t uid; + SVPeerDesc vpeerDesc[TSDB_MAX_MPEERS]; + char tableId[TSDB_TABLE_ID_LEN + 1]; +} SDRemoveTableMsg; + +typedef struct { + char tableId[TSDB_TABLE_ID_LEN + 1]; + int64_t uid; +} SDRemoveSuperTableMsg; + +typedef struct { + int32_t vnode; +} SFreeVnodeMsg; + +typedef struct SColIndexEx { + int16_t colId; + /* + * colIdx is the index of column in latest schema of table + * it is available in the client side. Also used to determine + * whether current table schema is up-to-date. + * + * colIdxInBuf is used to denote the index of column in pQuery->colList, + * this value is invalid in client side, as well as in cache block of vnode either. + */ + int16_t colIdx; + int16_t colIdxInBuf; + uint16_t flag; // denote if it is a tag or not +} SColIndexEx; + +/* sql function msg, to describe the message to vnode about sql function + * operations in select clause */ +typedef struct SSqlFuncExprMsg { + int16_t functionId; + int16_t numOfParams; + + SColIndexEx colInfo; + struct ArgElem { + int16_t argType; + int16_t argBytes; + union { + double d; + int64_t i64; + char * pz; + } argValue; + } arg[3]; +} SSqlFuncExprMsg; + +typedef struct SSqlBinaryExprInfo { + struct tSQLBinaryExpr *pBinExpr; /* for binary expression */ + int32_t numOfCols; /* binary expression involves the readed number of columns*/ + SColIndexEx * pReqColumns; /* source column list */ +} SSqlBinaryExprInfo; + +typedef struct SSqlFunctionExpr { + SSqlFuncExprMsg pBase; + SSqlBinaryExprInfo pBinExprInfo; + int16_t resBytes; + int16_t resType; + int16_t interResBytes; +} SSqlFunctionExpr; + +typedef struct SColumnFilterInfo { + int16_t lowerRelOptr; + int16_t upperRelOptr; + int16_t filterOnBinary; /* denote if current column is binary */ + + union { + struct { + int64_t lowerBndi; + int64_t upperBndi; + }; + struct { + double lowerBndd; + double upperBndd; + }; + struct { + int64_t pz; + int64_t len; + }; + }; +} SColumnFilterInfo; + +/* + * for client side struct, we only need the column id, type, bytes are not necessary + * But for data in vnode side, we need all the following information. + */ +typedef struct SColumnInfo { + int16_t colId; + int16_t type; + int16_t bytes; + int16_t numOfFilters; + SColumnFilterInfo *filters; +} SColumnInfo; + +/* + * enable vnode to understand how to group several tables with different tag; + */ +typedef struct STableSidExtInfo { + int32_t sid; + int64_t uid; + TSKEY key; // key for subscription + char tags[]; +} STableSidExtInfo; + +/* + * the outputCols is equalled to or larger than numOfCols + * e.g., select min(colName), max(colName), avg(colName) from table + * the outputCols will be 3 while the numOfCols is 1. + */ +typedef struct { + int16_t vnode; + int32_t numOfSids; + uint64_t pSidExtInfo; // table id & tag info ptr, in windows pointer may + + uint64_t uid; + TSKEY skey; + TSKEY ekey; + + int16_t order; + int16_t orderColId; + + int16_t numOfCols; // the number of columns will be load from vnode + char intervalTimeUnit; // time interval type, for revisement of interval(1d) + + int64_t nAggTimeInterval; // time interval for aggregation, in million second + int64_t slidingTime; // value for sliding window + + // tag schema, used to parse tag information in pSidExtInfo + uint64_t pTagSchema; + + int16_t numOfTagsCols; // required number of tags + int16_t tagLength; // tag length in current query + + int16_t numOfGroupCols; // num of group by columns + int16_t orderByIdx; + int16_t orderType; // used in group by xx order by xxx + uint64_t groupbyTagIds; + + int64_t limit; + int64_t offset; + + int16_t queryType; // denote another query process + int16_t numOfOutputCols; // final output columns numbers + + int16_t interpoType; // interpolate type + uint64_t defaultVal; // default value array list + + int32_t colNameLen; + int64_t colNameList; + + int64_t pSqlFuncExprs; + + int32_t tsOffset; // offset value in current msg body, NOTE: ts list is compressed + int32_t tsLen; // total length of ts comp block + int32_t tsNumOfBlocks; // ts comp block numbers + int32_t tsOrder; // ts comp block order + SColumnInfo colList[]; +} SQueryTableMsg; + +typedef struct { + char code; + uint64_t qhandle; +} SQueryTableRsp; + +typedef struct { + uint64_t qhandle; + uint16_t free; +} SRetrieveTableMsg; + +typedef struct { + int32_t numOfRows; + int16_t precision; + int64_t offset; // updated offset value for multi-vnode projection query + int64_t useconds; + char data[]; +} SRetrieveTableRsp; + +typedef struct { + uint32_t vnode; + uint32_t vgId; + uint8_t status; + uint8_t dropStatus; + uint8_t accessState; + int64_t totalStorage; + int64_t compStorage; + int64_t pointsWritten; + uint8_t syncStatus; + uint8_t reserved[15]; +} SVnodeLoad; + +typedef struct { + uint32_t vnode; + char accessState; +} SVnodeAccess; + +/* + * NOTE: sizeof(SVnodeCfg) < TSDB_FILE_HEADER_LEN / 4 + */ +typedef struct { + char acct[TSDB_USER_LEN + 1]; + char db[TSDB_DB_NAME_LEN + 1]; + uint32_t vgId; + int32_t maxSessions; + int32_t cacheBlockSize; + union { + int32_t totalBlocks; + float fraction; + } cacheNumOfBlocks; + int32_t daysPerFile; + int32_t daysToKeep1; + int32_t daysToKeep2; + int32_t daysToKeep; + int32_t commitTime; + int32_t rowsInFileBlock; + int16_t blocksPerTable; + int8_t compression; + int8_t commitLog; + int8_t replications; + int8_t repStrategy; + int8_t loadLatest; // load into mem or not + uint8_t precision; // time resolution + int8_t reserved[16]; +} SVnodeCfg, SCreateDbMsg, SDbCfg, SAlterDbMsg; + +typedef struct { + char db[TSDB_TABLE_ID_LEN + 1]; + uint8_t ignoreNotExists; +} SDropDbMsg, SUseDbMsg; + +// IMPORTANT: sizeof(SVnodeStatisticInfo) should not exceed +// TSDB_FILE_HEADER_LEN/4 - TSDB_FILE_HEADER_VERSION_SIZE +typedef struct { + int64_t pointsWritten; // In unit of points + int64_t totalStorage; // In unit of bytes + int64_t compStorage; // In unit of bytes + int64_t queryTime; // In unit of second ?? + char reserved[64]; +} SVnodeStatisticInfo; + +typedef struct { + uint32_t version; + uint32_t publicIp; + uint32_t lastReboot; // time stamp for last reboot + uint16_t numOfCores; + uint8_t alternativeRole; + uint8_t reserve; + uint16_t numOfTotalVnodes; // from config file + uint16_t unused; + float diskAvailable; // GB + uint32_t openVnodes; + char reserved[16]; + SVnodeLoad load[]; +} SStatusMsg; + +typedef struct { + int32_t code; + SRpcIpSet ipList; +} SStatusRsp; + +typedef struct { + uint32_t moduleStatus; + uint32_t createdTime; + uint32_t numOfVnodes; + uint32_t reserved; +} SDnodeState; + +// internal message +typedef struct { + uint32_t destId; + uint32_t destIp; + char tableId[TSDB_UNI_LEN + 1]; + char empty[3]; + uint8_t msgType; + int32_t msgLen; + uint8_t content[0]; +} SIntMsg; + +typedef struct { + char spi; + char encrypt; + char secret[TSDB_KEY_LEN]; // key is changed if updated + char cipheringKey[TSDB_KEY_LEN]; +} SSecIe; + +typedef struct { + int32_t numOfVPeers; + SVPeerDesc vpeerDesc[]; +} SVpeerDescArray; + +typedef struct { + int32_t vnode; + SVnodeCfg cfg; + SVPeerDesc vpeerDesc[TSDB_MAX_MPEERS]; +} SCreateVnodeMsg; + +typedef struct { + char tableId[TSDB_TABLE_ID_LEN + 1]; + int16_t createFlag; + char tags[]; +} STableInfoMsg; + +typedef struct { + int32_t numOfTables; + char tableIds[]; +} SMultiTableInfoMsg; + +typedef struct { + char tableId[TSDB_TABLE_ID_LEN + 1]; +} SSuperTableInfoMsg; + +typedef struct { + int32_t numOfDnodes; + uint32_t dnodeIps[]; +} SSuperTableInfoRsp; + +typedef struct { + int16_t elemLen; + + char tableId[TSDB_TABLE_ID_LEN + 1]; + int16_t orderIndex; + int16_t orderType; // used in group by xx order by xxx + + int16_t rel; // denotes the relation between condition and table list + + int32_t tableCond; // offset value of table name condition + int32_t tableCondLen; + + int32_t cond; // offset of column query condition + int32_t condLen; + + int16_t tagCols[TSDB_MAX_TAGS + 1]; // required tag columns, plus one is for table name + int16_t numOfTags; // required number of tags + + int16_t numOfGroupCols; // num of group by columns + int32_t groupbyTagColumnList; +} SSuperTableMetaElemMsg; + +typedef struct { + int32_t numOfTables; + int32_t join; + int32_t joinCondLen; // for join condition + int32_t metaElem[TSDB_MAX_JOIN_TABLE_NUM]; +} SSuperTableMetaMsg; + +typedef struct { + SVPeerDesc vpeerDesc[TSDB_VNODES_SUPPORT]; + int16_t index; // used locally + int32_t numOfSids; + int32_t pSidExtInfoList[]; // offset value of STableSidExtInfo +} SVnodeSidList; + +typedef struct { + int32_t numOfTables; + int32_t numOfVnodes; + uint16_t tagLen; /* tag value length */ + int32_t list[]; /* offset of SVnodeSidList, compared to the SSuperTableMeta struct */ +} SSuperTableMeta; + +typedef struct STableMeta { + char tableId[TSDB_TABLE_ID_LEN + 1]; // note: This field must be at the front + int32_t contLen; + uint8_t numOfTags : 6; + uint8_t precision : 2; + uint8_t tableType : 4; + uint8_t index : 4; // used locally + int16_t numOfColumns; + int16_t rowSize; // used locally, calculated in client + int16_t sversion; + int8_t numOfVpeers; + SVPeerDesc vpeerDesc[TSDB_VNODES_SUPPORT]; + int32_t sid; + int32_t vgid; + uint64_t uid; + SSchema schema[]; +} STableMeta; + +typedef struct SMultiTableMeta { + int32_t numOfTables; + int32_t contLen; + STableMeta metas[]; +} SMultiTableMeta; + +typedef struct { + char name[TSDB_TABLE_ID_LEN + 1]; + char data[TSDB_MAX_TAGS_LEN]; +} STagData; + +/* + * sql: show tables like '%a_%' + * payload is the query condition, e.g., '%a_%' + * payloadLen is the length of payload + */ +typedef struct { + int8_t type; + char db[TSDB_DB_NAME_LEN + 1]; + uint16_t payloadLen; + char payload[]; +} SShowMsg; + +typedef struct { + uint64_t qhandle; + STableMeta tableMeta; +} SShowRsp; + +typedef struct { + char ip[32]; +} SCreateMnodeMsg, SDropMnodeMsg, SCreateDnodeMsg, SDropDnodeMsg; + +typedef struct { + uint32_t dnode; + int32_t vnode; + int32_t sid; +} STableCfgMsg; + +typedef struct { + uint32_t dnode; + int32_t vnode; +} SVpeerCfgMsg; + +typedef struct { + char ip[32]; + char config[64]; +} SCfgDnodeMsg; + +typedef struct { + char sql[TSDB_SHOW_SQL_LEN + 1]; + uint32_t queryId; + int64_t useconds; + int64_t stime; +} SQueryDesc; + +typedef struct { + char sql[TSDB_SHOW_SQL_LEN + 1]; + uint32_t streamId; + int64_t num; // number of computing/cycles + int64_t useconds; + int64_t ctime; + int64_t stime; + int64_t slidingTime; + int64_t interval; +} SStreamDesc; + +typedef struct { + int32_t numOfQueries; + SQueryDesc qdesc[]; +} SQqueryList; + +typedef struct { + int32_t numOfStreams; + SStreamDesc sdesc[]; +} SStreamList; + +typedef struct { + SQqueryList qlist; + SStreamList slist; +} SHeartBeatMsg; + +typedef struct { + uint32_t queryId; + uint32_t streamId; + int8_t killConnection; + SRpcIpSet ipList; +} SHeartBeatRsp; + +typedef struct { + char queryId[TSDB_KILL_MSG_LEN + 1]; +} SKillQueryMsg, SKillStreamMsg, SKillConnectionMsg; + +typedef struct { + int32_t vnode; + int32_t sid; + uint64_t uid; + uint64_t stime; // stream starting time + int32_t status; + char tableId[TSDB_TABLE_ID_LEN + 1]; +} SDAlterStreamMsg; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/inc/dnode.h b/src/inc/dnode.h index 4aaf0e866ee47273a57617079821bda0a0246b22..45ff014dc51fa92d1abfb335751d3c44f61246a0 100644 --- a/src/inc/dnode.h +++ b/src/inc/dnode.h @@ -44,13 +44,12 @@ extern uint32_t tsRebootTime; extern void (*dnodeStartModules)(); extern void (*dnodeParseParameterK)(); extern int32_t (*dnodeCheckSystem)(); -extern void (*dnodeInitMgmtIp)(); -extern int (*dnodeInitMgmt)(); -// dnodeMgmt -void dnodeProcessMsgFromMgmt(int8_t *pCont, int32_t contLen, int32_t msgType, void *pConn); -extern int32_t (*dnodeSendMsgToMnode)(int8_t *pCont, int32_t contLen, int8_t msgType); -extern int32_t (*dnodeSendSimpleRspToMnode)(void *pConn, int32_t msgType, int32_t code); + +// dnodeSystem +extern void *tsDnodeMgmtQhandle; + +void dnodeProcessMsgFromMgmt(int8_t msgType, void *pCont, int32_t contLen, void *pConn, int32_t code); // dnodeModule extern void (*dnodeStartModules)(); diff --git a/src/inc/mnode.h b/src/inc/mnode.h index 794e41cc6c741848e26af4f0ab88968fbfc26d6a..ca6294f623f6a6bdc5e6981068cd0690d0aef153 100644 --- a/src/inc/mnode.h +++ b/src/inc/mnode.h @@ -47,11 +47,7 @@ extern void *tsMgmtTmr; extern void *tsMgmtTranQhandle; extern char tsMgmtDirectory[]; -extern int tsAcctUpdateSize; extern int tsDbUpdateSize; -extern int tsDnodeUpdateSize; -extern int tsMnodeUpdateSize; -extern int tsVgUpdateSize; typedef struct { uint32_t privateIp; @@ -101,62 +97,34 @@ typedef struct { int32_t vgId; // vnode group ID } STableGid; -typedef struct _tab_obj { - char meterId[TSDB_TABLE_ID_LEN + 1]; - uint64_t uid; - STableGid gid; - - int32_t sversion; // schema version - int64_t createdTime; - int32_t numOfTags; // for metric - int32_t numOfMeters; // for metric - int32_t numOfColumns; - int32_t schemaSize; - short nextColId; - char tableType : 4; - char status : 3; - char isDirty : 1; // if the table change tag column 1 value - char reserved[15]; - char updateEnd[1]; - - pthread_rwlock_t rwLock; - tSkipList * pSkipList; - struct _tab_obj *pHead; // for metric, a link list for all meters created - // according to this metric - char *pTagData; // TSDB_TABLE_ID_LEN(metric_name)+ - // tags_value1/tags_value2/tags_value3 - struct _tab_obj *prev, *next; - char * pSql; // pointer to SQL, for SC, null-terminated string - char * pReserve1; - char * pReserve2; - char * schema; - // SSchema schema[]; -} STabObj; - typedef struct { char tableId[TSDB_TABLE_ID_LEN + 1]; int8_t type; + int8_t dirty; uint64_t uid; int32_t sid; int32_t vgId; int64_t createdTime; } STableInfo; +struct _vg_obj; + typedef struct SSuperTableObj { char tableId[TSDB_TABLE_ID_LEN + 1]; int8_t type; + int8_t dirty; uint64_t uid; int32_t sid; int32_t vgId; int64_t createdTime; int32_t sversion; - int32_t numOfTables; int32_t numOfColumns; int32_t numOfTags; int8_t reserved[7]; int8_t updateEnd[1]; + int32_t numOfTables; int16_t nextColId; - SSchema *schema; + SSchema *schema; } SSuperTableObj; typedef struct { @@ -172,21 +140,6 @@ typedef struct { SSuperTableObj *superTable; } SChildTableObj; -typedef struct { - char tableId[TSDB_TABLE_ID_LEN + 1]; - int8_t type; - uint64_t uid; - int32_t sid; - int32_t vgId; - int64_t createdTime; - int32_t sversion; - int32_t numOfColumns; - int8_t reserved[3]; - int8_t updateEnd[1]; - int16_t nextColId; - SSchema* schema; -} SNormalTableObj; - typedef struct { char tableId[TSDB_TABLE_ID_LEN + 1]; int8_t type; @@ -199,14 +152,14 @@ typedef struct { int16_t sqlLen; int8_t reserved[3]; int8_t updateEnd[1]; - int16_t nextColId; char* sql; //null-terminated string + int16_t nextColId; SSchema* schema; -} SStreamTableObj; +} SNormalTableObj; typedef struct _vg_obj { uint32_t vgId; - char dbName[TSDB_DB_NAME_LEN]; + char dbName[TSDB_DB_NAME_LEN + 1]; int64_t createdTime; uint64_t lastCreate; uint64_t lastRemove; @@ -224,36 +177,37 @@ typedef struct _vg_obj { } SVgObj; typedef struct _db_obj { - /* - * this length will cause the storage structure to change, rollback - */ char name[TSDB_DB_NAME_LEN + 1]; int64_t createdTime; SDbCfg cfg; - int32_t numOfVgroups; - int32_t numOfTables; - int32_t numOfMetrics; - uint8_t vgStatus; - uint8_t dropStatus; + int8_t dropStatus; char reserved[16]; char updateEnd[1]; - struct _db_obj *prev, *next; - SVgObj * pHead; // empty vgroup first - SVgObj * pTail; // empty vgroup end - void * vgTimer; + int32_t numOfVgroups; + int32_t numOfTables; + int32_t numOfSuperTables; + int32_t vgStatus; + SVgObj *pHead; // empty vgroup first + SVgObj *pTail; // empty vgroup end + void * vgTimer; } SDbObj; +struct _acctObj; + typedef struct _user_obj { char user[TSDB_USER_LEN + 1]; - char pass[TSDB_KEY_LEN]; - char acct[TSDB_USER_LEN]; + char pass[TSDB_KEY_LEN + 1]; + char acct[TSDB_USER_LEN + 1]; int64_t createdTime; - char superAuth : 1; - char writeAuth : 1; - char reserved[16]; - char updateEnd[1]; + int8_t superAuth; + int8_t writeAuth; + int8_t reserved[16]; + int8_t updateEnd[1]; struct _user_obj *prev, *next; + struct _acctObj * pAcct; + SQqueryList * pQList; // query list + SStreamList * pSList; // stream list } SUserObj; typedef struct { @@ -270,78 +224,49 @@ typedef struct { int64_t totalPoints; int64_t inblound; int64_t outbound; - TSKEY sKey; - char accessState; // Checked by mgmt heartbeat message + int64_t sKey; + int8_t accessState; // Checked by mgmt heartbeat message } SAcctInfo; -typedef struct { +typedef struct _acctObj { char user[TSDB_USER_LEN + 1]; - char pass[TSDB_KEY_LEN]; + char pass[TSDB_KEY_LEN + 1]; SAcctCfg cfg; int32_t acctId; int64_t createdTime; - char reserved[15]; - char updateEnd[1]; + int8_t reserved[15]; + int8_t updateEnd[1]; SAcctInfo acctInfo; - SDbObj * pHead; SUserObj * pUser; - struct _connObj *pConn; pthread_mutex_t mutex; } SAcctObj; -typedef struct _connObj { - SAcctObj * pAcct; - SDbObj * pDb; - SUserObj * pUser; - char user[TSDB_USER_LEN]; - uint64_t stime; // login time - char superAuth : 1; // super user flag - char writeAuth : 1; // write flag - char killConnection : 1; // kill the connection flag - uint8_t usePublicIp : 1; // if the connection request is publicIp - uint8_t reserved : 4; - uint32_t queryId; // query ID to be killed - uint32_t streamId; // stream ID to be killed - uint32_t ip; // shell IP - uint16_t port; // shell port - void * thandle; - SQList * pQList; // query list - SSList * pSList; // stream list - uint64_t qhandle; - struct _connObj *prev, *next; -} SConnObj; - -typedef struct { - char spi; - char encrypt; - char secret[TSDB_KEY_LEN]; - char cipheringKey[TSDB_KEY_LEN]; -} SSecInfo; - typedef struct { - char type; + int8_t type; + char db[TSDB_DB_NAME_LEN + 1]; void * pNode; - short numOfColumns; - int rowSize; - int numOfRows; - int numOfReads; - short offset[TSDB_MAX_COLUMNS]; - short bytes[TSDB_MAX_COLUMNS]; + int16_t numOfColumns; + int32_t rowSize; + int32_t numOfRows; + int32_t numOfReads; + int16_t offset[TSDB_MAX_COLUMNS]; + int16_t bytes[TSDB_MAX_COLUMNS]; void * signature; uint16_t payloadLen; /* length of payload*/ char payload[]; /* payload for wildcard match in show tables */ } SShowObj; - //mgmtSystem int32_t mgmtStartSystem(); void mgmtCleanUpSystem(); -void mgmtProcessMsgFromDnode(int8_t *pCont, int32_t contLen, int32_t msgType, void *pConn); +void mgmtProcessMsgFromDnode(char msgType, void *pCont, int contLen, void *pConn, int32_t code); extern int32_t (*mgmtInitSystem)(); extern void (*mgmtStopSystem)(); extern void (*mgmtCleanUpRedirect)(); + + #ifdef __cplusplus } #endif diff --git a/src/inc/sdb.h b/src/inc/sdb.h index 7316fd7ef5275b8edc4a2a32ae6aaa543e78a9bd..d0239522a9d2939cdd09374a5ad97937949d2400 100644 --- a/src/inc/sdb.h +++ b/src/inc/sdb.h @@ -37,8 +37,8 @@ extern int sdbExtConns; extern int sdbMaster; extern uint32_t sdbPublicIp; extern uint32_t sdbMasterStartTime; -extern SIpList *pSdbIpList; -extern SIpList *pSdbPublicIpList; +extern SRpcIpSet *pSdbIpList; +extern SRpcIpSet *pSdbPublicIpList; extern void (*sdbWorkAsMasterCallback)(); // this function pointer will be set by taosd @@ -71,8 +71,6 @@ enum _sdbaction { SDB_MAX_ACTION_TYPES }; -#ifdef CLUSTER - #define SDB_MAX_PEERS 4 typedef struct { uint32_t ip; @@ -103,8 +101,6 @@ extern SSdbPeer *sdbPeer[]; #define sdbInited (sdbPeer[0]) #define sdbStatus (sdbPeer[0]->status) -#endif - void *sdbOpenTable(int maxRows, int32_t maxRowSize, char *name, uint8_t keyType, char *directory, void *(*appTool)(char, void *, char *, int, int *)); @@ -138,12 +134,10 @@ int sdbCfgNode(char *cont); int64_t sdbGetVersion(); +int32_t sdbGetRunStatus(); -#define TSDB_MAX_TABLES 1000 -extern void* tsChildTableSdb; -extern void* tsNormalTableSdb; -extern void* tsStreamTableSdb; -extern void* tsSuperTableSdb; +#define TSDB_MAX_NORMAL_TABLES 10000 +#define TSDB_MAX_SUPER_TABLES 1000 #ifdef __cplusplus } diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index 288daa6ba7d68ac65a6e64f69ec242912fc55e1d..d3c8edee44458b203e83fb999f0838d58a0f2539 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -86,7 +86,7 @@ extern "C" { #define TS_PATH_DELIMITER_LEN 1 #define TSDB_METER_ID_LEN_MARGIN 10 -#define TSDB_TABLE_ID_LEN (TSDB_DB_NAME_LEN+TSDB_METER_NAME_LEN+2*TS_PATH_DELIMITER_LEN+TSDB_USERID_LEN+TSDB_METER_ID_LEN_MARGIN) //TSDB_DB_NAME_LEN+TSDB_METER_NAME_LEN+2*strlen(TS_PATH_DELIMITER)+strlen(USERID) +#define TSDB_TABLE_ID_LEN (TSDB_DB_NAME_LEN+TSDB_TABLE_NAME_LEN+2*TS_PATH_DELIMITER_LEN+TSDB_USERID_LEN+TSDB_METER_ID_LEN_MARGIN) //TSDB_DB_NAME_LEN+TSDB_TABLE_NAME_LEN+2*strlen(TS_PATH_DELIMITER)+strlen(USERID) #define TSDB_UNI_LEN 24 #define TSDB_USER_LEN TSDB_UNI_LEN #define TSDB_ACCT_LEN TSDB_UNI_LEN @@ -95,7 +95,7 @@ extern "C" { #define TSDB_MAX_COLUMNS 256 #define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns -#define TSDB_METER_NAME_LEN 64 +#define TSDB_TABLE_NAME_LEN 64 #define TSDB_DB_NAME_LEN 32 #define TSDB_COL_NAME_LEN 64 #define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 16 diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index f153a9a5739ebbae5c84b4a36065776472aa8083..6861d31b873a7898ae1e9812ade92cb25ff0c543 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -162,6 +162,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_FAILED_TO_LOCK_RESOURCES, 0, 117, "failed to lock TAOS_DEFINE_ERROR(TSDB_CODE_TABLE_ID_MISMATCH, 0, 118, "table id mismatch") TAOS_DEFINE_ERROR(TSDB_CODE_QUERY_CACHE_ERASED, 0, 119, "query cache erased") TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_MSG, 0, 120, "invalid message") +TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TABLE_TYPE, 0, 121, "invalid table typee") #ifdef TAOS_ERROR_C }; diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index ea8045c8515432aa0a9d6e56c259b6eada7757f3..f74bff7e57fa5a0e9773263d23ea536068ef866e 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -26,24 +26,25 @@ extern "C" { #include "taosdef.h" #include "taoserror.h" #include "taosdef.h" +#include "trpc.h" // message type #define TSDB_MSG_TYPE_REG 1 #define TSDB_MSG_TYPE_REG_RSP 2 -#define TSDB_MSG_TYPE_DNODE_SUBMIT 3 -#define TSDB_MSG_TYPE_DNODE_SUBMIT_RSP 4 -#define TSDB_MSG_TYPE_DNODE_QUERY 5 -#define TSDB_MSG_TYPE_DNODE_QUERY_RSP 6 -#define TSDB_MSG_TYPE_DNODE_RETRIEVE 7 -#define TSDB_MSG_TYPE_DNODE_RETRIEVE_RSP 8 +#define TSDB_MSG_TYPE_SUBMIT 3 +#define TSDB_MSG_TYPE_SUBMIT_RSP 4 +#define TSDB_MSG_TYPE_QUERY 5 +#define TSDB_MSG_TYPE_QUERY_RSP 6 +#define TSDB_MSG_TYPE_RETRIEVE 7 +#define TSDB_MSG_TYPE_RETRIEVE_RSP 8 #define TSDB_MSG_TYPE_DNODE_CREATE_TABLE 9 #define TSDB_MSG_TYPE_DNODE_CREATE_TABLE_RSP 10 #define TSDB_MSG_TYPE_DNODE_REMOVE_TABLE 11 #define TSDB_MSG_TYPE_DNODE_REMOVE_TABLE_RSP 12 -#define TSDB_MSG_TYPE_DNODE_VPEERS 13 -#define TSDB_MSG_TYPE_DNODE_VPEERS_RSP 14 -#define TSDB_MSG_TYPE_DNODE_FREE_VNODE 15 -#define TSDB_MSG_TYPE_DNODE_FREE_VNODE_RSP 16 +#define TSDB_MSG_TYPE_CREATE_VNODE 13 +#define TSDB_MSG_TYPE_CREATE_VNODE_RSP 14 +#define TSDB_MSG_TYPE_FREE_VNODE 15 +#define TSDB_MSG_TYPE_FREE_VNODE_RSP 16 #define TSDB_MSG_TYPE_DNODE_CFG 17 #define TSDB_MSG_TYPE_DNODE_CFG_RSP 18 #define TSDB_MSG_TYPE_DNODE_ALTER_STREAM 19 @@ -52,6 +53,8 @@ extern "C" { #define TSDB_MSG_TYPE_SDB_SYNC_RSP 22 #define TSDB_MSG_TYPE_SDB_FORWARD 23 #define TSDB_MSG_TYPE_SDB_FORWARD_RSP 24 +#define TSDB_MSG_TYPE_DROP_STABLE 25 +#define TSDB_MSG_TYPE_DROP_STABLE_RSP 26 #define TSDB_MSG_TYPE_CONNECT 31 #define TSDB_MSG_TYPE_CONNECT_RSP 32 #define TSDB_MSG_TYPE_CREATE_ACCT 33 @@ -189,53 +192,20 @@ extern char *taosMsg[]; #pragma pack(push, 1) -typedef struct { - char numOfIps; - uint32_t ip[]; -} SIpList; - -typedef struct { - char numOfIps; - uint32_t ip[TSDB_MAX_MGMT_IPS]; -} SMgmtIpList; - -typedef struct { - uint32_t customerId; - uint32_t osId; - uint32_t appId; - char hwId[TSDB_UNI_LEN]; - char hwVersion[TSDB_VERSION_LEN]; - char osVersion[TSDB_VERSION_LEN]; - char appVersion[TSDB_VERSION_LEN]; - char sdkVersion[TSDB_VERSION_LEN]; - char name[TSDB_UNI_LEN]; - char street[TSDB_STREET_LEN]; - char city[TSDB_CITY_LEN]; - char state[TSDB_STATE_LEN]; - char country[TSDB_COUNTRY_LEN]; - uint32_t longitude; - uint32_t latitude; -} SRegMsg; - -typedef struct { - short numOfRows; - char payLoad[]; -} SSubmitMsg; - typedef struct { int32_t vnode; int32_t sid; int32_t sversion; uint64_t uid; - short numOfRows; + int16_t numOfRows; char payLoad[]; } SShellSubmitBlock; typedef struct { - int8_t import; - int8_t reserved[3]; + int16_t import; + int16_t vnode; int32_t numOfSid; /* total number of sid */ - char blks[]; /* numOfSid blocks, each blocks for one meter */ + char blks[]; /* numOfSid blocks, each blocks for one table */ } SShellSubmitMsg; typedef struct { @@ -251,84 +221,79 @@ typedef struct { int32_t affectedRows; // number of records actually written int32_t failedRows; // number of failed records (exclude duplicate records) int32_t numOfFailedBlocks; - SShellSubmitRspBlock *failedBlocks; + SShellSubmitRspBlock failedBlocks[]; } SShellSubmitRspMsg; typedef struct SSchema { - uint8_t type; - char name[TSDB_COL_NAME_LEN]; - short colId; - short bytes; -} SSchema; - -typedef struct { - int8_t type; + uint8_t type; + char name[TSDB_COL_NAME_LEN + 1]; int16_t colId; int16_t bytes; -} SDTableColumn; - -typedef struct { - int32_t vnode; - int32_t sid; - uint64_t uid; - uint64_t superTableUid; - int32_t tableType; - int32_t sversion; - int16_t numOfColumns; - int16_t numOfTags; - int32_t tagDataLen; - int32_t sqlDataLen; - uint64_t createdTime; - char tableId[TSDB_TABLE_ID_LEN + 1]; - char superTableId[TSDB_TABLE_ID_LEN + 1]; - int8_t data[]; -} SDCreateTableMsg; - -typedef struct { - char db[TSDB_TABLE_ID_LEN]; - uint8_t ignoreNotExists; -} SDropDbMsg, SUseDbMsg; +} SSchema; typedef struct { - char user[TSDB_USER_LEN]; -} SDropUserMsg, SDropAcctMsg; + int32_t vnode; //the index of vnode + uint32_t ip; +} SVPeerDesc; typedef struct { - char db[TSDB_DB_NAME_LEN]; -} SShowTableMsg; + int8_t tableType; + int16_t numOfColumns; + int16_t numOfTags; + int32_t sid; + int32_t sversion; + int32_t tagDataLen; + int32_t sqlDataLen; + int32_t contLen; + int32_t numOfVPeers; + uint64_t uid; + uint64_t superTableUid; + uint64_t createdTime; + SVPeerDesc vpeerDesc[TSDB_MAX_MPEERS]; + char tableId[TSDB_TABLE_ID_LEN + 1]; + char superTableId[TSDB_TABLE_ID_LEN + 1]; + char data[]; +} SDCreateTableMsg; typedef struct { - char meterId[TSDB_TABLE_ID_LEN]; - char igExists; - - short numOfTags; - - short numOfColumns; - short sqlLen; // the length of SQL, it starts after schema , sql is a - // null-terminated string - char reserved[16]; - - SSchema schema[]; + char tableId[TSDB_TABLE_ID_LEN + 1]; + char db[TSDB_DB_NAME_LEN + 1]; + int8_t igExists; + int16_t numOfTags; + int16_t numOfColumns; + int16_t sqlLen; // the length of SQL, it starts after schema , sql is a null-terminated string + int16_t reserved[16]; + char schema[]; } SCreateTableMsg; typedef struct { - char meterId[TSDB_TABLE_ID_LEN]; - char igNotExists; + char tableId[TSDB_TABLE_ID_LEN + 1]; + int8_t igNotExists; } SDropTableMsg; typedef struct { - char meterId[TSDB_TABLE_ID_LEN]; - short type; /* operation type */ + char tableId[TSDB_TABLE_ID_LEN + 1]; + char db[TSDB_DB_NAME_LEN + 1]; + int16_t type; /* operation type */ char tagVal[TSDB_MAX_BYTES_PER_ROW]; - short numOfCols; /* number of schema */ + int8_t numOfCols; /* number of schema */ SSchema schema[]; } SAlterTableMsg; typedef struct { char clientVersion[TSDB_VERSION_LEN]; - char db[TSDB_TABLE_ID_LEN]; + char msgVersion[TSDB_VERSION_LEN]; + char db[TSDB_TABLE_ID_LEN + 1]; } SConnectMsg; +typedef struct { + char acctId[TSDB_ACCT_LEN + 1]; + char serverVersion[TSDB_VERSION_LEN]; + int8_t writeAuth; + int8_t superAuth; + SRpcIpSet ipList; +} SConnectRsp; + typedef struct { int32_t maxUsers; int32_t maxDbs; @@ -340,39 +305,42 @@ typedef struct { int64_t maxQueryTime; // In unit of hour int64_t maxInbound; int64_t maxOutbound; - char accessState; // Configured only by command + int8_t accessState; // Configured only by command } SAcctCfg; typedef struct { - char user[TSDB_USER_LEN]; - char pass[TSDB_KEY_LEN]; + char user[TSDB_USER_LEN + 1]; + char pass[TSDB_KEY_LEN + 1]; SAcctCfg cfg; } SCreateAcctMsg, SAlterAcctMsg; typedef struct { - char user[TSDB_USER_LEN]; - char pass[TSDB_KEY_LEN]; - char privilege; - char flag; + char user[TSDB_USER_LEN + 1]; +} SDropUserMsg, SDropAcctMsg; + +typedef struct { + char user[TSDB_USER_LEN + 1]; + char pass[TSDB_KEY_LEN + 1]; + int8_t privilege; + int8_t flag; } SCreateUserMsg, SAlterUserMsg; typedef struct { - char db[TSDB_TABLE_ID_LEN]; + char db[TSDB_TABLE_ID_LEN + 1]; } SMgmtHead; typedef struct { - char acctId[TSDB_ACCT_LEN]; - char version[TSDB_VERSION_LEN]; - char writeAuth; - char superAuth; -} SConnectRsp; + int32_t sid; + int32_t numOfVPeers; + uint64_t uid; + SVPeerDesc vpeerDesc[TSDB_MAX_MPEERS]; + char tableId[TSDB_TABLE_ID_LEN + 1]; +} SDRemoveTableMsg; typedef struct { - short vnode; - int32_t sid; - uint64_t uid; - char meterId[TSDB_TABLE_ID_LEN]; -} SDRemoveTableMsg; + char tableId[TSDB_TABLE_ID_LEN + 1]; + int64_t uid; +} SDRemoveSuperTableMsg; typedef struct { int32_t vnode; @@ -383,7 +351,7 @@ typedef struct SColIndexEx { /* * colIdx is the index of column in latest schema of table * it is available in the client side. Also used to determine - * whether current meter schema is up-to-date. + * whether current table schema is up-to-date. * * colIdxInBuf is used to denote the index of column in pQuery->colList, * this value is invalid in client side, as well as in cache block of vnode either. @@ -391,6 +359,7 @@ typedef struct SColIndexEx { int16_t colIdx; int16_t colIdxInBuf; uint16_t flag; // denote if it is a tag or not + char name[TSDB_COL_NAME_LEN]; } SColIndexEx; /* sql function msg, to describe the message to vnode about sql function @@ -461,22 +430,22 @@ typedef struct SColumnInfo { /* * enable vnode to understand how to group several tables with different tag; */ -typedef struct SMeterSidExtInfo { +typedef struct STableSidExtInfo { int32_t sid; int64_t uid; TSKEY key; // key for subscription char tags[]; -} SMeterSidExtInfo; +} STableSidExtInfo; /* * the outputCols is equalled to or larger than numOfCols - * e.g., select min(colName), max(colName), avg(colName) from meter_name + * e.g., select min(colName), max(colName), avg(colName) from table * the outputCols will be 3 while the numOfCols is 1. */ typedef struct { int16_t vnode; int32_t numOfSids; - uint64_t pSidExtInfo; // meter id & tag info ptr, in windows pointer may + uint64_t pSidExtInfo; // table id & tag info ptr, in windows pointer may uint64_t uid; TSKEY skey; @@ -488,9 +457,9 @@ typedef struct { int16_t numOfCols; // the number of columns will be load from vnode char intervalTimeUnit; // time interval type, for revisement of interval(1d) - int64_t nAggTimeInterval; // time interval for aggregation, in million second + int64_t intervalTime; // time interval for aggregation, in million second int64_t slidingTime; // value for sliding window - + // tag schema, used to parse tag information in pSidExtInfo uint64_t pTagSchema; @@ -521,26 +490,17 @@ typedef struct { int32_t tsNumOfBlocks; // ts comp block numbers int32_t tsOrder; // ts comp block order SColumnInfo colList[]; -} SQueryMeterMsg; +} SQueryTableMsg; typedef struct { char code; uint64_t qhandle; -} SQueryMeterRsp; - -typedef struct { - TSKEY skey; - TSKEY ekey; - int32_t num; - short order; - short numOfCols; - short colList[]; -} SQueryMsg; +} SQueryTableRsp; typedef struct { uint64_t qhandle; uint16_t free; -} SRetrieveMeterMsg; +} SRetrieveTableMsg; typedef struct { int32_t numOfRows; @@ -548,7 +508,7 @@ typedef struct { int64_t offset; // updated offset value for multi-vnode projection query int64_t useconds; char data[]; -} SRetrieveMeterRsp; +} SRetrieveTableRsp; typedef struct { uint32_t vnode; @@ -568,15 +528,12 @@ typedef struct { char accessState; } SVnodeAccess; -// NOTE: sizeof(SVnodeCfg) < TSDB_FILE_HEADER_LEN/4 +/* + * NOTE: sizeof(SVnodeCfg) < TSDB_FILE_HEADER_LEN / 4 + */ typedef struct { - char acct[TSDB_USER_LEN]; - /* - * the message is too large, so it may will overwrite the cfg information in meterobj.v* - * recover to origin codes - */ - //char db[TSDB_TABLE_ID_LEN+2]; // 8bytes align - char db[TSDB_DB_NAME_LEN]; + char acct[TSDB_USER_LEN + 1]; + char db[TSDB_DB_NAME_LEN + 1]; uint32_t vgId; int32_t maxSessions; int32_t cacheBlockSize; @@ -585,25 +542,26 @@ typedef struct { float fraction; } cacheNumOfBlocks; int32_t daysPerFile; - int32_t daysToKeep1; int32_t daysToKeep2; int32_t daysToKeep; - int32_t commitTime; int32_t rowsInFileBlock; - int16_t blocksPerMeter; - char compression; - char commitLog; - char replications; - - char repStrategy; - char loadLatest; // load into mem or not + int16_t blocksPerTable; + int8_t compression; + int8_t commitLog; + int8_t replications; + int8_t repStrategy; + int8_t loadLatest; // load into mem or not uint8_t precision; // time resolution - - char reserved[16]; + int8_t reserved[16]; } SVnodeCfg, SCreateDbMsg, SDbCfg, SAlterDbMsg; +typedef struct { + char db[TSDB_TABLE_ID_LEN + 1]; + uint8_t ignoreNotExists; +} SDropDbMsg, SUseDbMsg; + // IMPORTANT: sizeof(SVnodeStatisticInfo) should not exceed // TSDB_FILE_HEADER_LEN/4 - TSDB_FILE_HEADER_VERSION_SIZE typedef struct { @@ -629,6 +587,11 @@ typedef struct { SVnodeLoad load[]; } SStatusMsg; +typedef struct { + int32_t code; + SRpcIpSet ipList; +} SStatusRsp; + typedef struct { uint32_t moduleStatus; uint32_t createdTime; @@ -640,7 +603,7 @@ typedef struct { typedef struct { uint32_t destId; uint32_t destIp; - char meterId[TSDB_UNI_LEN]; + char tableId[TSDB_UNI_LEN + 1]; char empty[3]; uint8_t msgType; int32_t msgLen; @@ -654,12 +617,6 @@ typedef struct { char cipheringKey[TSDB_KEY_LEN]; } SSecIe; -typedef struct { - int32_t dnode; //the ID of dnode - int32_t vnode; //the index of vnode - uint32_t ip; -} SVPeerDesc; - typedef struct { int32_t numOfVPeers; SVPeerDesc vpeerDesc[]; @@ -668,24 +625,33 @@ typedef struct { typedef struct { int32_t vnode; SVnodeCfg cfg; - SVPeerDesc vpeerDesc[]; -} SVPeersMsg; + SVPeerDesc vpeerDesc[TSDB_MAX_MPEERS]; +} SCreateVnodeMsg; + +typedef struct { + char tableId[TSDB_TABLE_ID_LEN + 1]; + int16_t createFlag; + char tags[]; +} STableInfoMsg; + +typedef struct { + int32_t numOfTables; + char tableIds[]; +} SMultiTableInfoMsg; typedef struct { - char meterId[TSDB_TABLE_ID_LEN]; - short createFlag; - char tags[]; -} SMeterInfoMsg; + char tableId[TSDB_TABLE_ID_LEN + 1]; +} SSuperTableInfoMsg; typedef struct { - int32_t numOfMeters; - char meterId[]; -} SMultiMeterInfoMsg; + int32_t numOfDnodes; + uint32_t dnodeIps[]; +} SSuperTableInfoRsp; typedef struct { int16_t elemLen; - char meterId[TSDB_TABLE_ID_LEN]; + char tableId[TSDB_TABLE_ID_LEN + 1]; int16_t orderIndex; int16_t orderType; // used in group by xx order by xxx @@ -702,10 +668,10 @@ typedef struct { int16_t numOfGroupCols; // num of group by columns int32_t groupbyTagColumnList; -} SMetricMetaElemMsg; +} SSuperTableMetaElemMsg; typedef struct { - int32_t numOfMeters; + int32_t numOfTables; int32_t join; int32_t joinCondLen; // for join condition int32_t metaElem[TSDB_MAX_JOIN_TABLE_NUM]; @@ -715,41 +681,42 @@ typedef struct { SVPeerDesc vpeerDesc[TSDB_VNODES_SUPPORT]; int16_t index; // used locally int32_t numOfSids; - int32_t pSidExtInfoList[]; // offset value of SMeterSidExtInfo + int32_t pSidExtInfoList[]; // offset value of STableSidExtInfo } SVnodeSidList; typedef struct { - int32_t numOfMeters; + int32_t numOfTables; int32_t numOfVnodes; uint16_t tagLen; /* tag value length */ - int32_t list[]; /* offset of SVnodeSidList, compared to the SMetricMeta struct */ -} SMetricMeta; + int32_t list[]; /* offset of SVnodeSidList, compared to the SSuperTableMeta struct */ +} SSuperTableMeta; -typedef struct SMeterMeta { +typedef struct STableMeta { + char tableId[TSDB_TABLE_ID_LEN + 1]; // note: This field must be at the front + int32_t contLen; uint8_t numOfTags : 6; uint8_t precision : 2; uint8_t tableType : 4; uint8_t index : 4; // used locally - int16_t numOfColumns; - int16_t rowSize; // used locally, calculated in client int16_t sversion; - + int8_t numOfVpeers; SVPeerDesc vpeerDesc[TSDB_VNODES_SUPPORT]; - int32_t sid; int32_t vgid; uint64_t uid; -} SMeterMeta; + SSchema schema[]; +} STableMeta; -typedef struct SMultiMeterMeta { - char meterId[TSDB_TABLE_ID_LEN]; // note: This field must be at the front - SMeterMeta meta; -} SMultiMeterMeta; +typedef struct SMultiTableMeta { + int32_t numOfTables; + int32_t contLen; + STableMeta metas[]; +} SMultiTableMeta; typedef struct { - char name[TSDB_TABLE_ID_LEN]; + char name[TSDB_TABLE_ID_LEN + 1]; char data[TSDB_MAX_TAGS_LEN]; } STagData; @@ -759,50 +726,46 @@ typedef struct { * payloadLen is the length of payload */ typedef struct { - char type; + int8_t type; + char db[TSDB_DB_NAME_LEN + 1]; uint16_t payloadLen; char payload[]; } SShowMsg; typedef struct { - char ip[20]; -} SCreateMnodeMsg, SDropMnodeMsg, SCreateDnodeMsg, SDropDnodeMsg; + uint64_t qhandle; + STableMeta tableMeta; +} SShowRsp; typedef struct { - uint64_t qhandle; - SMeterMeta meterMeta; -} SShowRspMsg; + char ip[32]; +} SCreateMnodeMsg, SDropMnodeMsg, SCreateDnodeMsg, SDropDnodeMsg; typedef struct { - int32_t vnode; - int32_t sid; -} SMeterCfgMsg; + uint32_t dnode; + int32_t vnode; + int32_t sid; +} STableCfgMsg; typedef struct { + uint32_t dnode; int32_t vnode; } SVpeerCfgMsg; typedef struct { - char ip[20]; - char config[60]; -} SCfgMsg; + char ip[32]; + char config[64]; +} SCfgDnodeMsg; typedef struct { - uint32_t queryId; - uint32_t streamId; - char killConnection; - SIpList ipList; -} SHeartBeatRsp; - -typedef struct { - char sql[TSDB_SHOW_SQL_LEN]; + char sql[TSDB_SHOW_SQL_LEN + 1]; uint32_t queryId; int64_t useconds; int64_t stime; -} SQDesc; +} SQueryDesc; typedef struct { - char sql[TSDB_SHOW_SQL_LEN]; + char sql[TSDB_SHOW_SQL_LEN + 1]; uint32_t streamId; int64_t num; // number of computing/cycles int64_t useconds; @@ -810,22 +773,33 @@ typedef struct { int64_t stime; int64_t slidingTime; int64_t interval; -} SSDesc; +} SStreamDesc; typedef struct { int32_t numOfQueries; - SQDesc qdesc[]; -} SQList; + SQueryDesc qdesc[]; +} SQqueryList; typedef struct { int32_t numOfStreams; - SSDesc sdesc[]; -} SSList; + SStreamDesc sdesc[]; +} SStreamList; typedef struct { - uint64_t handle; - char queryId[TSDB_KILL_MSG_LEN]; -} SKillQuery, SKillStream, SKillConnection; + SQqueryList qlist; + SStreamList slist; +} SHeartBeatMsg; + +typedef struct { + uint32_t queryId; + uint32_t streamId; + int8_t killConnection; + SRpcIpSet ipList; +} SHeartBeatRsp; + +typedef struct { + char queryId[TSDB_KILL_MSG_LEN + 1]; +} SKillQueryMsg, SKillStreamMsg, SKillConnectionMsg; typedef struct { int32_t vnode; @@ -833,7 +807,8 @@ typedef struct { uint64_t uid; uint64_t stime; // stream starting time int32_t status; -} SAlterStreamMsg; + char tableId[TSDB_TABLE_ID_LEN + 1]; +} SDAlterStreamMsg; #pragma pack(pop) diff --git a/src/inc/tresultBuf.h b/src/inc/tresultBuf.h index a464479af27a7e8515f4260c0ea6a73aed780933..b99c44e73fcbd834152640b80f8a59728c7cfd8f 100644 --- a/src/inc/tresultBuf.h +++ b/src/inc/tresultBuf.h @@ -14,7 +14,7 @@ typedef struct SIDList { int32_t* pData; } SIDList; -typedef struct SQueryResultBuf { +typedef struct SQueryDiskbasedResultBuf { int32_t numOfRowsPerPage; int32_t numOfPages; int64_t totalBufSize; @@ -27,7 +27,7 @@ typedef struct SQueryResultBuf { uint32_t numOfAllocGroupIds; // number of allocated id list void* idsTable; // id hash table SIDList* list; // for each id, there is a page id list -} SQueryResultBuf; +} SQueryDiskbasedResultBuf; /** * create disk-based result buffer @@ -36,7 +36,7 @@ typedef struct SQueryResultBuf { * @param rowSize * @return */ -int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowSize); +int32_t createDiskbasedResultBuffer(SQueryDiskbasedResultBuf** pResultBuf, int32_t size, int32_t rowSize); /** * @@ -45,14 +45,14 @@ int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowS * @param pageId * @return */ -tFilePage* getNewDataBuf(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t* pageId); +tFilePage* getNewDataBuf(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t* pageId); /** * * @param pResultBuf * @return */ -int32_t getNumOfRowsPerPage(SQueryResultBuf* pResultBuf); +int32_t getNumOfRowsPerPage(SQueryDiskbasedResultBuf* pResultBuf); /** * @@ -60,7 +60,7 @@ int32_t getNumOfRowsPerPage(SQueryResultBuf* pResultBuf); * @param groupId * @return */ -SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId); +SIDList getDataBufPagesIdList(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId); /** * get the specified buffer page by id @@ -68,27 +68,27 @@ SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId); * @param id * @return */ -tFilePage* getResultBufferPageById(SQueryResultBuf* pResultBuf, int32_t id); +tFilePage* getResultBufferPageById(SQueryDiskbasedResultBuf* pResultBuf, int32_t id); /** * get the total buffer size in the format of disk file * @param pResultBuf * @return */ -int32_t getResBufSize(SQueryResultBuf* pResultBuf); +int32_t getResBufSize(SQueryDiskbasedResultBuf* pResultBuf); /** * get the number of groups in the result buffer * @param pResultBuf * @return */ -int32_t getNumOfResultBufGroupId(SQueryResultBuf* pResultBuf); +int32_t getNumOfResultBufGroupId(SQueryDiskbasedResultBuf* pResultBuf); /** * destroy result buffer * @param pResultBuf */ -void destroyResultBuf(SQueryResultBuf* pResultBuf); +void destroyResultBuf(SQueryDiskbasedResultBuf* pResultBuf); /** * diff --git a/src/inc/trpc.h b/src/inc/trpc.h index afd5d3e7ef21c25f3717f983d1f0ec5165fa310d..358feb444f16b6e709ef0082b8c7a13ead3a3590 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -23,62 +23,60 @@ extern "C" { #include #include "taosdef.h" -#define TAOS_CONN_UDPS 0 -#define TAOS_CONN_UDPC 1 -#define TAOS_CONN_TCPS 2 -#define TAOS_CONN_TCPC 3 -#define TAOS_CONN_HTTPS 4 -#define TAOS_CONN_HTTPC 5 - -#define TAOS_SOCKET_TYPE_NAME_TCP "tcp" -#define TAOS_SOCKET_TYPE_NAME_UDP "udp" - -#define TAOS_CONN_SOCKET_TYPE_S() ((strcasecmp(tsSocketType, TAOS_SOCKET_TYPE_NAME_UDP) == 0)? TAOS_CONN_UDPS:TAOS_CONN_TCPS) -#define TAOS_CONN_SOCKET_TYPE_C() ((strcasecmp(tsSocketType, TAOS_SOCKET_TYPE_NAME_UDP) == 0)? TAOS_CONN_UDPC:TAOS_CONN_TCPC) +#define TAOS_CONN_SERVER 0 +#define TAOS_CONN_CLIENT 1 extern int tsRpcHeadSize; typedef struct { - int16_t index; - int16_t numOfIps; + int8_t inUse; + int8_t numOfIps; uint16_t port; uint32_t ip[TSDB_MAX_MPEERS]; } SRpcIpSet; typedef struct { - char *localIp; // local IP used - uint16_t localPort; // local port - char *label; // for debug purpose - int numOfThreads; // number of threads to handle connections - int sessions; // number of sessions allowed - int connType; // TAOS_CONN_UDP, TAOS_CONN_TCPC, TAOS_CONN_TCPS - int idleTime; // milliseconds, 0 means idle timer is disabled + uint32_t clientIp; + uint16_t clientPort; + uint32_t serverIp; + char user[TSDB_USER_LEN]; +} SRpcConnInfo; - // the following is for client security only - char *meterId; // meter ID +typedef struct { + char *localIp; // local IP used + uint16_t localPort; // local port + char *label; // for debug purpose + int numOfThreads; // number of threads to handle connections + int sessions; // number of sessions allowed + int8_t connType; // TAOS_CONN_UDP, TAOS_CONN_TCPC, TAOS_CONN_TCPS + int idleTime; // milliseconds, 0 means idle timer is disabled + + // the following is for client app ecurity only + char *user; // user name char spi; // security parameter index char encrypt; // encrypt algorithm char *secret; // key for authentication char *ckey; // ciphering key - // call back to process incoming msg - void (*cfp)(char type, void *pCont, int contLen, void *ahandle, int32_t code); + // call back to process incoming msg, code shall be ignored by server app + void (*cfp)(char type, void *pCont, int contLen, void *handle, int32_t code); - // call back to process notify the ipSet changes + // call back to process notify the ipSet changes, for client app only void (*ufp)(void *ahandle, SRpcIpSet *pIpSet); - // call back to retrieve the client auth info - int (*afp)(char *meterId, char *spi, char *encrypt, char *secret, char *ckey); + // call back to retrieve the client auth info, for server app only + int (*afp)(char *tableId, char *spi, char *encrypt, char *secret, char *ckey); } SRpcInit; void *rpcOpen(SRpcInit *pRpc); void rpcClose(void *); void *rpcMallocCont(int contLen); void rpcFreeCont(void *pCont); +void *rpcReallocCont(void *ptr, int contLen); void rpcSendRequest(void *thandle, SRpcIpSet *pIpSet, char msgType, void *pCont, int contLen, void *ahandle); void rpcSendResponse(void *pConn, int32_t code, void *pCont, int contLen); void rpcSendRedirectRsp(void *pConn, SRpcIpSet *pIpSet); - +void rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo); #ifdef __cplusplus } diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index 27a4aaaa0cd24d84b46003ec3195f130d3ee8c85..22af4ca5c3d7a9514b0d604757b92e2b72cc952b 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -800,6 +800,8 @@ void source_file(TAOS *con, char *fptr) { } void shellGetGrantInfo(void *con) { + return; + char sql[] = "show grants"; int code = taos_query(con, sql); diff --git a/src/kit/shell/src/shellMain.c b/src/kit/shell/src/shellMain.c index a7b7e8383bafab2f76682488d131c0d2bfbe65d3..6b184b53b62b11e13dff737f50d2d2bd12aabce9 100644 --- a/src/kit/shell/src/shellMain.c +++ b/src/kit/shell/src/shellMain.c @@ -81,6 +81,17 @@ struct arguments args = { */ int main(int argc, char* argv[]) { /*setlocale(LC_ALL, "en_US.UTF-8"); */ + // + if (argc == 1) + { + printf("=== this a test for debug usage\n"); + void *taos = taos_connect(NULL, "root", "taosdata", NULL, 0); + taos_query(taos, "select * from d1.t6"); + while (1) { + sleep(1000); + } + } + // if (!checkVersion()) { exit(EXIT_FAILURE); diff --git a/src/kit/taosdump/taosdump.c b/src/kit/taosdump/taosdump.c index a7a8da24799b975fbd06e19dff7a49b236aa428a..0740045b4f084afef686d5c74dacd0aeb5fc95c7 100644 --- a/src/kit/taosdump/taosdump.c +++ b/src/kit/taosdump/taosdump.c @@ -116,8 +116,8 @@ typedef struct { } SDbInfo; typedef struct { - char name[TSDB_METER_NAME_LEN + 1]; - char metric[TSDB_METER_NAME_LEN + 1]; + char name[TSDB_TABLE_NAME_LEN + 1]; + char metric[TSDB_TABLE_NAME_LEN + 1]; } STableRecord; typedef struct { diff --git a/src/mnode/CMakeLists.txt b/src/mnode/CMakeLists.txt index a8abf54dfd7646fb08d9e0ea35b1497caf0e76a2..6bf4ef34e062b8559a48daf0383e2149a7064a92 100644 --- a/src/mnode/CMakeLists.txt +++ b/src/mnode/CMakeLists.txt @@ -13,9 +13,9 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) ADD_LIBRARY(mnode ${SRC}) TARGET_LINK_LIBRARIES(mnode trpc tutil sdb pthread) - #IF (TD_CLUSTER) - # TARGET_LINK_LIBRARIES(mnode mcluster) - #ENDIF () + IF (TD_CLUSTER) + TARGET_LINK_LIBRARIES(mnode acct) + ENDIF () ENDIF () diff --git a/src/mnode/inc/mgmtAcct.h b/src/mnode/inc/mgmtAcct.h index edffebaddc85df1345b7f5a9c41970330596512e..edc30409d6e4bf1f4b75fdeaa9f71ad935f8c617 100644 --- a/src/mnode/inc/mgmtAcct.h +++ b/src/mnode/inc/mgmtAcct.h @@ -28,14 +28,13 @@ int32_t mgmtAddUserIntoAcct(SAcctObj *pAcct, SUserObj *pUser); int32_t mgmtRemoveUserFromAcct(SAcctObj *pAcct, SUserObj *pUser); extern int32_t (*mgmtInitAccts)(); +extern void (*mgmtCleanUpAccts)(); extern SAcctObj* (*mgmtGetAcct)(char *acctName); extern int32_t (*mgmtCheckUserLimit)(SAcctObj *pAcct); extern int32_t (*mgmtCheckDbLimit)(SAcctObj *pAcct); extern int32_t (*mgmtCheckTableLimit)(SAcctObj *pAcct, SCreateTableMsg *pCreate); -extern void (*mgmtCheckAcct)(); -extern void (*mgmtCleanUpAccts)(); -extern int32_t (*mgmtGetAcctMeta)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -extern int32_t (*mgmtRetrieveAccts)(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +extern int32_t (*mgmtGetAcctMeta)(STableMeta *pMeta, SShowObj *pShow, void *pConn); +extern int32_t (*mgmtRetrieveAccts)(SShowObj *pShow, char *data, int32_t rows, void *pConn); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtChildTable.h b/src/mnode/inc/mgmtChildTable.h index 0fa6355898f4aa1c3bf8aa7ed37d81162e94001a..83c18ca46cb210c5c3c21b5eba9e7ae4a722c541 100644 --- a/src/mnode/inc/mgmtChildTable.h +++ b/src/mnode/inc/mgmtChildTable.h @@ -26,14 +26,16 @@ extern "C" { #include "mnode.h" -int32_t mgmtInitChildTables(); -void mgmtCleanUpChildTables(); -int32_t mgmtCreateChildTable(SDbObj *pDb, SCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t sid); -int32_t mgmtDropChildTable(SDbObj *pDb, SChildTableObj *pTable); -int32_t mgmtAlterChildTable(SDbObj *pDb, SAlterTableMsg *pAlter); -int32_t mgmtModifyChildTableTagValueByName(SChildTableObj *pTable, char *tagName, char *nContent); -SChildTableObj* mgmtGetChildTable(char *tableId); -int8_t * mgmtBuildCreateChildTableMsg(SChildTableObj *pTable, SVgObj *pVgroup); +int32_t mgmtInitChildTables(); +void mgmtCleanUpChildTables(); +void * mgmtGetChildTable(char *tableId); + +int32_t mgmtCreateChildTable(SCreateTableMsg *pCreate, int32_t contLen, SVgObj *pVgroup, int32_t sid, + SDCreateTableMsg **pDCreateOut, STableInfo **pTableOut); +int32_t mgmtDropChildTable(SDbObj *pDb, SChildTableObj *pTable); +int32_t mgmtModifyChildTableTagValueByName(SChildTableObj *pTable, char *tagName, char *nContent); + +int32_t mgmtGetChildTableMeta(SDbObj *pDb, SChildTableObj *pTable, STableMeta *pMeta, bool usePublicIp); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtConn.h b/src/mnode/inc/mgmtConn.h index 550cf6c20d2c10f20082281186c831cc642294f1..62dd5ebb42cf585f4aacc6902c9276b280ab932d 100644 --- a/src/mnode/inc/mgmtConn.h +++ b/src/mnode/inc/mgmtConn.h @@ -22,8 +22,12 @@ extern "C" { #include "mnode.h" -int mgmtGetConnsMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int mgmtRetrieveConns(SShowObj *pShow, char *data, int rows, SConnObj *pConn); +int mgmtGetConnsMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int mgmtRetrieveConns(SShowObj *pShow, char *data, int rows, void *pConn); + +bool mgmtCheckQhandle(uint64_t qhandle); +void mgmtSaveQhandle(void *qhandle); +void mgmtFreeQhandle(void *qhandle); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtDb.h b/src/mnode/inc/mgmtDb.h index 20575e21822de58c02938c720e1807401a66062b..b59cd6582a5a4e87f6780068af27540193db7e91 100644 --- a/src/mnode/inc/mgmtDb.h +++ b/src/mnode/inc/mgmtDb.h @@ -24,14 +24,13 @@ extern "C" { void mgmtMonitorDbDrop(void *unused, void *unusedt); int32_t mgmtAlterDb(SAcctObj *pAcct, SAlterDbMsg *pAlter); -int32_t mgmtUseDb(SConnObj *pConn, char *name); int32_t mgmtAddVgroupIntoDb(SDbObj *pDb, SVgObj *pVgroup); int32_t mgmtAddVgroupIntoDbTail(SDbObj *pDb, SVgObj *pVgroup); int32_t mgmtRemoveVgroupFromDb(SDbObj *pDb, SVgObj *pVgroup); int32_t mgmtMoveVgroupToTail(SDbObj *pDb, SVgObj *pVgroup); int32_t mgmtMoveVgroupToHead(SDbObj *pDb, SVgObj *pVgroup); -int32_t mgmtGetDbMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +int32_t mgmtGetDbMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void *pConn); void mgmtCleanUpDbs(); int32_t mgmtInitDbs(); @@ -43,6 +42,11 @@ int32_t mgmtDropDbByName(SAcctObj *pAcct, char *name, short ignoreNotExists); int32_t mgmtDropDb(SDbObj *pDb); bool mgmtCheckIsMonitorDB(char *db, char *monitordb); +void mgmtAddSuperTableIntoDb(SDbObj *pDb); +void mgmtRemoveSuperTableFromDb(SDbObj *pDb); +void mgmtAddTableIntoDb(SDbObj *pDb); +void mgmtRemoveTableFromDb(SDbObj *pDb); + #ifdef __cplusplus } #endif diff --git a/src/mnode/inc/mgmtDnode.h b/src/mnode/inc/mgmtDnode.h index 325ef5bb71fba64ba59755f4b1a65058e943165f..6159d5e5dca0336fa979295da79d04688600e553 100644 --- a/src/mnode/inc/mgmtDnode.h +++ b/src/mnode/inc/mgmtDnode.h @@ -30,19 +30,19 @@ int32_t mgmtDropDnodeByIp(uint32_t ip); int32_t mgmtGetNextVnode(SVnodeGid *pVnodeGid); void mgmtSetDnodeVgid(SVnodeGid vnodeGid[], int32_t numOfVnodes, int32_t vgId); void mgmtUnSetDnodeVgid(SVnodeGid vnodeGid[], int32_t numOfVnodes); -int32_t mgmtGetDnodeMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +int32_t mgmtGetDnodeMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn); int32_t mgmtSendCfgDnodeMsg(char *cont); void mgmtSetDnodeMaxVnodes(SDnodeObj *pDnode); -int32_t mgmtGetConfigMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +int32_t mgmtGetConfigMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, void *pConn); -int32_t mgmtGetModuleMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +int32_t mgmtGetModuleMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pConn); -int32_t mgmtGetVnodeMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +int32_t mgmtGetVnodeMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn); extern int32_t (*mgmtInitDnodes)(); extern void (*mgmtCleanUpDnodes)(); @@ -51,12 +51,13 @@ extern int32_t (*mgmtGetDnodesNum)(); extern void* (*mgmtGetNextDnode)(SShowObj *pShow, SDnodeObj **pDnode); extern int32_t (*mgmtUpdateDnode)(SDnodeObj *pDnode); extern void (*mgmtSetDnodeUnRemove)(SDnodeObj *pDnode); -extern int32_t (*mgmtGetScoresMeta)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -extern int32_t (*mgmtRetrieveScores)(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +extern int32_t (*mgmtGetScoresMeta)(STableMeta *pMeta, SShowObj *pShow, void *pConn); +extern int32_t (*mgmtRetrieveScores)(SShowObj *pShow, char *data, int32_t rows, void *pConn); extern bool (*mgmtCheckConfigShow)(SGlobalConfig *cfg); extern SDnodeObj tsDnodeObj; + #ifdef __cplusplus } #endif diff --git a/src/mnode/inc/mgmtDnodeInt.h b/src/mnode/inc/mgmtDnodeInt.h index 20cb7e5e81a80090073a2f418a582d148008bfb9..772c2ba3310366c0006e7d1ce76a2e35652c0cc0 100644 --- a/src/mnode/inc/mgmtDnodeInt.h +++ b/src/mnode/inc/mgmtDnodeInt.h @@ -26,24 +26,20 @@ extern "C" { extern void *mgmtStatusTimer; -int32_t mgmtSendCreateTableMsg(SChildTableObj *pTable, SVgObj *pVgroup); -int32_t mgmtSendCreateNormalTableMsg(SNormalTableObj *pTable, SVgObj *pVgroup); -int32_t mgmtSendCreateStreamTableMsg(SStreamTableObj *pTable, SVgObj *pVgroup); +void mgmtSendCreateTableMsg(SDCreateTableMsg *pCreate, SRpcIpSet *ipSet, void *ahandle); +void mgmtSendRemoveTableMsg(SDRemoveTableMsg *pRemove, SRpcIpSet *ipSet, void *ahandle); +void mgmtSendAlterStreamMsg(STableInfo *pTable, SRpcIpSet *ipSet, void *ahandle); +void mgmtSendCreateVnodeMsg(SVgObj *pVgroup, int32_t vnode, SRpcIpSet *ipSet, void *ahandle); +void mgmtSendCreateVgroupMsg(SVgObj *pVgroup, void *ahandle); +void mgmtSendOneFreeVnodeMsg(int32_t vnode, SRpcIpSet *ipSet, void *ahandle); +void mgmtSendRemoveVgroupMsg(SVgObj *pVgroup, void *ahandle); -int mgmtSendRemoveMeterMsgToDnode(STableInfo *pTable, SVgObj *pVgroup); -int mgmtSendVPeersMsg(SVgObj *pVgroup); -int mgmtSendFreeVnodeMsg(SVgObj *pVgroup); -int mgmtSendOneFreeVnodeMsg(SVnodeGid *pVnodeGid); - -char *taosBuildRspMsgToDnode(SDnodeObj *pObj, char type); -char *taosBuildReqMsgToDnode(SDnodeObj *pObj, char type); - -extern int32_t (*mgmtSendSimpleRspToDnode)(void *pConn, int32_t msgType, int32_t code); -extern int32_t (*mgmtSendMsgToDnode)(int8_t *pCont, int32_t contLen, int8_t msgType); extern int32_t (*mgmtInitDnodeInt)(); extern void (*mgmtCleanUpDnodeInt)(); extern void (*mgmtProcessDnodeStatus)(void *handle, void *tmrId); +void mgmtSendMsgToDnode(SRpcIpSet *ipSet, int8_t msgType, void *pCont, int32_t contLen, void *ahandle); +void mgmtSendRspToDnode(void *pConn, int8_t msgType, int32_t code, void *pCont, int32_t contLen); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtGrant.h b/src/mnode/inc/mgmtGrant.h index d8ae27430e630f765a559277b932c6ce6f277e00..e68e6ae71e31e6d961cf3f3a2ce352cb9a46d16f 100644 --- a/src/mnode/inc/mgmtGrant.h +++ b/src/mnode/inc/mgmtGrant.h @@ -25,13 +25,13 @@ extern "C" { #include "mnode.h" extern bool (*mgmtCheckExpired)(); -extern void (*mgmtAddTimeSeries)(uint32_t timeSeriesNum); -extern void (*mgmtRestoreTimeSeries)(uint32_t timeseries); +extern void (*mgmtAddTimeSeries)(SAcctObj *pAcct, uint32_t timeSeriesNum); +extern void (*mgmtRestoreTimeSeries)(SAcctObj *pAcct, uint32_t timeseries); extern int32_t (*mgmtCheckTimeSeries)(uint32_t timeseries); extern int32_t (*mgmtCheckUserGrant)(); extern int32_t (*mgmtCheckDbGrant)(); -extern int32_t (*mgmtGetGrantsMeta)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -extern int32_t (*mgmtRetrieveGrants)(SShowObj *pShow, char *data, int rows, SConnObj *pConn); +extern int32_t (*mgmtGetGrantsMeta)(STableMeta *pMeta, SShowObj *pShow, void *pConn); +extern int32_t (*mgmtRetrieveGrants)(SShowObj *pShow, char *data, int rows, void *pConn); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtMnode.h b/src/mnode/inc/mgmtMnode.h index 94ec307c43e23c70a00b7ab29adf5a1ed29acc51..e27296de7745abc83ef8adecbfca49744f661cbc 100644 --- a/src/mnode/inc/mgmtMnode.h +++ b/src/mnode/inc/mgmtMnode.h @@ -24,8 +24,8 @@ extern "C" { #include #include "mnode.h" -extern int32_t (*mgmtGetMnodeMeta)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -extern int32_t (*mgmtRetrieveMnodes)(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +extern int32_t (*mgmtGetMnodeMeta)(STableMeta *pMeta, SShowObj *pShow, void *pConn); +extern int32_t (*mgmtRetrieveMnodes)(SShowObj *pShow, char *data, int32_t rows, void *pConn); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtNormalTable.h b/src/mnode/inc/mgmtNormalTable.h index b45b6bbd4eb81fbe7313eeee2b527d3b0d42d050..e632b8b98759029d8f1217695ef5c61939379932 100644 --- a/src/mnode/inc/mgmtNormalTable.h +++ b/src/mnode/inc/mgmtNormalTable.h @@ -23,15 +23,18 @@ extern "C" { #include #include #include "mnode.h" - -int32_t mgmtInitNormalTables(); -void mgmtCleanUpNormalTables(); -int32_t mgmtCreateNormalTable(SDbObj *pDb, SCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t sid); -int32_t mgmtDropNormalTable(SDbObj *pDb, SNormalTableObj *pTable); -int32_t mgmtAddNormalTableColumn(SNormalTableObj *pTable, SSchema schema[], int32_t ncols); -int32_t mgmtDropNormalTableColumnByName(SNormalTableObj *pTable, char *colName); -SNormalTableObj* mgmtGetNormalTable(char *tableId); -int8_t * mgmtBuildCreateNormalTableMsg(SNormalTableObj *pTable); + +int32_t mgmtInitNormalTables(); +void mgmtCleanUpNormalTables(); +void * mgmtGetNormalTable(char *tableId); + +int32_t mgmtCreateNormalTable(SCreateTableMsg *pCreate, int32_t contLen, SVgObj *pVgroup, int32_t sid, + SDCreateTableMsg **pDCreateOut, STableInfo **pTableOut); +int32_t mgmtDropNormalTable(SDbObj *pDb, SNormalTableObj *pTable); +int32_t mgmtAddNormalTableColumn(SNormalTableObj *pTable, SSchema schema[], int32_t ncols); +int32_t mgmtDropNormalTableColumnByName(SNormalTableObj *pTable, char *colName); + +int32_t mgmtGetNormalTableMeta(SDbObj *pDb, SNormalTableObj *pTable, STableMeta *pMeta, bool usePublicIp); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtProfile.h b/src/mnode/inc/mgmtProfile.h index 6d5a08c4bb51d827f16b4b83f85f2bc1a23241a5..959f9e65ab93e220567384461de4bc93889be041 100644 --- a/src/mnode/inc/mgmtProfile.h +++ b/src/mnode/inc/mgmtProfile.h @@ -22,21 +22,37 @@ extern "C" { #include "mnode.h" -int mgmtGetQueryMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); +int32_t mgmtGetQueryMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); -int mgmtGetStreamMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); +int32_t mgmtGetStreamMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); -int mgmtRetrieveQueries(SShowObj *pShow, char *data, int rows, SConnObj *pConn); +int32_t mgmtRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, void *pConn); -int mgmtRetrieveStreams(SShowObj *pShow, char *data, int rows, SConnObj *pConn); +int32_t mgmtRetrieveStreams(SShowObj *pShow, char *data, int32_t rows, void *pConn); -int mgmtSaveQueryStreamList(char *cont, int contLen, SConnObj *pConn); +int32_t mgmtSaveQueryStreamList(SHeartBeatMsg *pHBMsg); -int mgmtKillQuery(char *qidstr, SConnObj *pConn); +int32_t mgmtKillQuery(char *qidstr, void *pConn); -int mgmtKillStream(char *qidstr, SConnObj *pConn); +int32_t mgmtKillStream(char *qidstr, void *pConn); -int mgmtKillConnection(char *qidstr, SConnObj *pConn); +int32_t mgmtKillConnection(char *qidstr, void *pConn); + +enum { + TSDB_PROCESS_CREATE_VGROUP, + TSDB_PROCESS_CREATE_VGROUP_GET_META, + TSDB_PROCESS_CREATE_TABLE, + TSDB_PROCESS_CREATE_TABLE_GET_META, +}; + +typedef struct { + void *thandle; // come from uplayer + void *ahandle; // object to process + void *cont; // additional information of object to process + int32_t type; // the type of sync process + int32_t received; // num of received, such as numOfVnodes + int32_t contLen; // the length of additional information +} SProcessInfo; #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtShell.h b/src/mnode/inc/mgmtShell.h index e1181ff0f347ab8234353ae3774f6eb3c4d72932..56668b512ffd6ee886d7e1bdef91007db07a8794 100644 --- a/src/mnode/inc/mgmtShell.h +++ b/src/mnode/inc/mgmtShell.h @@ -24,17 +24,32 @@ extern "C" { #include #include "mnode.h" -int mgmtInitShell(); +int32_t mgmtInitShell(); void mgmtCleanUpShell(); -extern int32_t (*mgmtCheckRedirectMsg)(SConnObj *pConn, int32_t msgType); -extern int32_t (*mgmtProcessAlterAcctMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn); -extern int32_t (*mgmtProcessCreateDnodeMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn); -extern int32_t (*mgmtProcessCfgMnodeMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn); -extern int32_t (*mgmtProcessDropMnodeMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn); -extern int32_t (*mgmtProcessDropDnodeMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn); -extern int32_t (*mgmtProcessDropAcctMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn); -extern int32_t (*mgmtProcessCreateAcctMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn); +extern int32_t (*mgmtCheckRedirectMsg)(void *pConn); +extern void (*mgmtProcessAlterAcctMsg)(void *pCont, int32_t contLen, void *ahandle); +extern void (*mgmtProcessCreateDnodeMsg)(void *pCont, int32_t contLen, void *ahandle); +extern void (*mgmtProcessCfgMnodeMsg)(void *pCont, int32_t contLen, void *ahandle); +extern void (*mgmtProcessDropMnodeMsg)(void *pCont, int32_t contLen, void *ahandle); +extern void (*mgmtProcessDropDnodeMsg)(void *pCont, int32_t contLen, void *ahandle); +extern void (*mgmtProcessDropAcctMsg)(void *pCont, int32_t contLen, void *ahandle); +extern void (*mgmtProcessCreateAcctMsg)(void *pCont, int32_t contLen, void *ahandle); + +/* + * If table not exist, will create it + */ +void mgmtProcessGetTableMeta(STableInfo *pTable, void *thandle); + +/* + * If vgroup not exist, will create vgroup + */ +void mgmtProcessCreateTable(SVgObj *pVgroup, SCreateTableMsg *pCreate, int32_t contLen, void *thandle, bool isGetMeta); + +/* + * If vgroup create returned, will then create table + */ +void mgmtProcessCreateVgroup(SCreateTableMsg *pCreate, int32_t contLen, void *thandle, bool isGetMeta); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtSuperTable.h b/src/mnode/inc/mgmtSuperTable.h index 6b87ee38ac63333d3914def7dbe3370454bfed49..4709772e84ab69575ea165e2c24d50437486f1f3 100644 --- a/src/mnode/inc/mgmtSuperTable.h +++ b/src/mnode/inc/mgmtSuperTable.h @@ -26,18 +26,26 @@ extern "C" { #include "taosdef.h" #include "mnode.h" -int32_t mgmtInitSuperTables(); -void mgmtCleanUpSuperTables(); -int32_t mgmtCreateSuperTable(SDbObj *pDb, SCreateTableMsg *pCreate); -int32_t mgmtDropSuperTable(SDbObj *pDb, SSuperTableObj *pTable); -SSuperTableObj* mgmtGetSuperTable(char *tableId); -int32_t mgmtFindSuperTableTagIndex(SSuperTableObj *pTable, const char *tagName); -int32_t mgmtAddSuperTableTag(SSuperTableObj *pTable, SSchema schema[], int32_t ntags); -int32_t mgmtDropSuperTableTag(SSuperTableObj *pTable, char *tagName); -int32_t mgmtModifySuperTableTagNameByName(SSuperTableObj *pTable, char *oldTagName, char *newTagName); -int32_t mgmtAddSuperTableColumn(SSuperTableObj *pTable, SSchema schema[], int32_t ncols); -int32_t mgmtDropSuperTableColumnByName(SSuperTableObj *pTable, char *colName); -int32_t mgmtGetTagsLength(SSuperTableObj* pSuperTable, int32_t col); +int32_t mgmtInitSuperTables(); +void mgmtCleanUpSuperTables(); + +void * mgmtGetSuperTable(char *tableId); +int32_t mgmtGetShowSuperTableMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, void *pConn); + +int32_t mgmtCreateSuperTable(SDbObj *pDb, SCreateTableMsg *pCreate); +int32_t mgmtDropSuperTable(SDbObj *pDb, SSuperTableObj *pTable); +int32_t mgmtAddSuperTableTag(SSuperTableObj *pTable, SSchema schema[], int32_t ntags); +int32_t mgmtDropSuperTableTag(SSuperTableObj *pTable, char *tagName); +int32_t mgmtModifySuperTableTagNameByName(SSuperTableObj *pTable, char *oldTagName, char *newTagName); +int32_t mgmtAddSuperTableColumn(SSuperTableObj *pTable, SSchema schema[], int32_t ncols); +int32_t mgmtDropSuperTableColumnByName(SSuperTableObj *pTable, char *colName); + +int32_t mgmtGetSuperTableMeta(SDbObj *pDb, SSuperTableObj *pTable, STableMeta *pMeta, bool usePublicIp); +void * mgmtGetSuperTableVgroup(SSuperTableObj *pStable); + +int32_t mgmtFindSuperTableTagIndex(SSuperTableObj *pTable, const char *tagName); +int32_t mgmtSetSchemaFromSuperTable(SSchema *pSchema, SSuperTableObj *pTable); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtTable.h b/src/mnode/inc/mgmtTable.h index 0b5b7636fda7e13ead5e095b174f5de48fcc93b3..a6cc811c35009a94e69bb20ac73a6255ac18be65 100644 --- a/src/mnode/inc/mgmtTable.h +++ b/src/mnode/inc/mgmtTable.h @@ -28,20 +28,22 @@ extern "C" { int32_t mgmtInitTables(); STableInfo* mgmtGetTable(char *tableId); STableInfo* mgmtGetTableByPos(uint32_t dnodeIp, int32_t vnode, int32_t sid); +int32_t mgmtGetTableMeta(SDbObj *pDb, STableInfo *pTable, STableMeta *pMeta, bool usePublicIp); -int32_t mgmtRetrieveMetricMeta(SConnObj *pConn, char **pStart, SSuperTableMetaMsg *pInfo); -int32_t mgmtCreateTable(SDbObj *pDb, SCreateTableMsg *pCreate); -int32_t mgmtDropTable(SDbObj *pDb, char *meterId, int32_t ignore); +int32_t mgmtRetrieveMetricMeta(void *pConn, char **pStart, SSuperTableMetaMsg *pInfo); +int32_t mgmtCreateTable(SCreateTableMsg *pCreate, int32_t contLen, void *thandle, bool isGetMeta); +int32_t mgmtDropTable(SDbObj *pDb, char *tableId, int32_t ignore); int32_t mgmtAlterTable(SDbObj *pDb, SAlterTableMsg *pAlter); -int32_t mgmtGetTableMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveTables(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +int32_t mgmtGetShowTableMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows, void *pConn); void mgmtCleanUpMeters(); void mgmtAddTableIntoSuperTable(SSuperTableObj *pStable); void mgmtRemoveTableFromSuperTable(SSuperTableObj *pStable); -int32_t mgmtGetSuperTableMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveSuperTables(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +void mgmtSetTableDirty(STableInfo *pTable, bool isDirty); +SDRemoveTableMsg *mgmtBuildRemoveTableMsg(STableInfo *pTable); +SDRemoveSuperTableMsg *mgmtBuildRemoveSuperTableMsg(STableInfo *pTable); #ifdef __cplusplus diff --git a/src/mnode/inc/mgmtUser.h b/src/mnode/inc/mgmtUser.h index 2977d688f7dadf5f05afeedc5df25a89abbc97d9..f6be37f452f9d961383bb2f77f94c6160f7ee951 100644 --- a/src/mnode/inc/mgmtUser.h +++ b/src/mnode/inc/mgmtUser.h @@ -29,9 +29,10 @@ SUserObj *mgmtGetUser(char *name); int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass); int32_t mgmtDropUser(SAcctObj *pAcct, char *name); int32_t mgmtUpdateUser(SUserObj *pUser); -int32_t mgmtGetUserMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); +int32_t mgmtGetUserMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, void *pConn); void mgmtCleanUpUsers(); +SUserObj *mgmtGetUserFromConn(void *pConn); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtVgroup.h b/src/mnode/inc/mgmtVgroup.h index 845da4e159c91a5dcfff8ec3622395ba1cf69b2e..8b3bcff73809aef890beb94d4c5ffe7b8373c1c5 100644 --- a/src/mnode/inc/mgmtVgroup.h +++ b/src/mnode/inc/mgmtVgroup.h @@ -25,16 +25,27 @@ extern "C" { #include "mnode.h" int32_t mgmtInitVgroups(); +void mgmtCleanUpVgroups(); SVgObj *mgmtGetVgroup(int32_t vgId); +SVgObj *mgmtGetVgroupByVnode(uint32_t dnode, int32_t vnode); + SVgObj *mgmtCreateVgroup(SDbObj *pDb); int32_t mgmtDropVgroup(SDbObj *pDb, SVgObj *pVgroup); +void mgmtUpdateVgroup(SVgObj *pVgroup); + +int32_t mgmtGetVgroupMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn); +int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, void *pConn); + void mgmtSetVgroupIdPool(); -int32_t mgmtGetVgroupMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); -void mgmtCleanUpVgroups(); +SVgObj *mgmtGetAvailableVgroup(SDbObj *pDb); + +void mgmtAddTableIntoVgroup(SVgObj *pVgroup, STableInfo *pTable); +void mgmtRemoveTableFromVgroup(SVgObj *pVgroup, STableInfo *pTable); + +SCreateVnodeMsg *mgmtBuildVpeersMsg(SVgObj *pVgroup, int32_t vnode); -SVgObj *mgmtGetAvailVgroup(SDbObj *pDb); -int32_t mgmtAllocateSid(SDbObj *pDb, SVgObj *pVgroup); +SRpcIpSet mgmtGetIpSetFromVgroup(SVgObj *pVgroup); +SRpcIpSet mgmtGetIpSetFromIp(uint32_t ip); #ifdef __cplusplus } diff --git a/src/mnode/src/mgmtAcct.c b/src/mnode/src/mgmtAcct.c index 17d20b67cce73aa6dc4d18979f7541381060075f..15db1680d47d803c0fa0c2eb52ede5580a245659 100644 --- a/src/mnode/src/mgmtAcct.c +++ b/src/mnode/src/mgmtAcct.c @@ -73,6 +73,7 @@ int32_t mgmtAddUserIntoAcct(SAcctObj *pAcct, SUserObj *pUser) { pAcct->pUser = pUser; pAcct->acctInfo.numOfUsers++; + pUser->pAcct = pAcct; pthread_mutex_unlock(&pAcct->mutex); return 0; @@ -97,18 +98,21 @@ int32_t mgmtRemoveUserFromAcct(SAcctObj *pAcct, SUserObj *pUser) { } int32_t mgmtInitAcctsImp() { + SAcctObj *pAcct = &tsAcctObj; + pAcct->acctId = 0; + strcpy(pAcct->user, "root"); return 0; } int32_t (*mgmtInitAccts)() = mgmtInitAcctsImp; -SAcctObj *mgmtGetAcctImp(char *acctName) { +static SAcctObj *mgmtGetAcctImp(char *acctName) { return &tsAcctObj; } SAcctObj *(*mgmtGetAcct)(char *acctName) = mgmtGetAcctImp; -int32_t mgmtCheckUserLimitImp(SAcctObj *pAcct) { +static int32_t mgmtCheckUserLimitImp(SAcctObj *pAcct) { int32_t numOfUsers = sdbGetNumOfRows(tsUserSdb); if (numOfUsers >= tsMaxUsers) { mWarn("numOfUsers:%d, exceed tsMaxUsers:%d", numOfUsers, tsMaxUsers); @@ -119,7 +123,7 @@ int32_t mgmtCheckUserLimitImp(SAcctObj *pAcct) { int32_t (*mgmtCheckUserLimit)(SAcctObj *pAcct) = mgmtCheckUserLimitImp; -int32_t mgmtCheckDbLimitImp(SAcctObj *pAcct) { +static int32_t mgmtCheckDbLimitImp(SAcctObj *pAcct) { int32_t numOfDbs = sdbGetNumOfRows(tsDbSdb); if (numOfDbs >= tsMaxDbs) { mWarn("numOfDbs:%d, exceed tsMaxDbs:%d", numOfDbs, tsMaxDbs); @@ -130,37 +134,36 @@ int32_t mgmtCheckDbLimitImp(SAcctObj *pAcct) { int32_t (*mgmtCheckDbLimit)(SAcctObj *pAcct) = mgmtCheckDbLimitImp; -int32_t mgmtCheckTableLimitImp(SAcctObj *pAcct, SCreateTableMsg *pCreate) { +static int32_t mgmtCheckTableLimitImp(SAcctObj *pAcct, SCreateTableMsg *pCreate) { return 0; } int32_t (*mgmtCheckTableLimit)(SAcctObj *pAcct, SCreateTableMsg *pCreate) = mgmtCheckTableLimitImp; -void mgmtCheckAcctImp() { - SAcctObj *pAcct = &tsAcctObj; - pAcct->acctId = 0; - strcpy(pAcct->user, "root"); - - mgmtCreateUser(pAcct, "root", "taosdata"); - mgmtCreateUser(pAcct, "monitor", tsInternalPass); - mgmtCreateUser(pAcct, "_root", tsInternalPass); -} - -void (*mgmtCheckAcct)() = mgmtCheckAcctImp; - -void mgmtCleanUpAcctsImp() { +static void mgmtCleanUpAcctsImp() { } void (*mgmtCleanUpAccts)() = mgmtCleanUpAcctsImp; -int32_t mgmtGetAcctMetaImp(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +static int32_t mgmtGetAcctMetaImp(STableMeta *pMeta, SShowObj *pShow, void *pConn) { return TSDB_CODE_OPS_NOT_SUPPORT; } -int32_t (*mgmtGetAcctMeta)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) = mgmtGetAcctMetaImp; +int32_t (*mgmtGetAcctMeta)(STableMeta *pMeta, SShowObj *pShow, void *pConn) = mgmtGetAcctMetaImp; -int32_t mgmtRetrieveAcctsImp(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +static int32_t mgmtRetrieveAcctsImp(SShowObj *pShow, char *data, int32_t rows, void *pConn) { return 0; } -int32_t (*mgmtRetrieveAccts)(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) = mgmtRetrieveAcctsImp; +int32_t (*mgmtRetrieveAccts)(SShowObj *pShow, char *data, int32_t rows, void *pConn) = mgmtRetrieveAcctsImp; + +SAcctObj *mgmtGetAcctFromConn(void *pConn) { + SRpcConnInfo connInfo; + rpcGetConnInfo(pConn, &connInfo); + SUserObj *pUser = mgmtGetUser(connInfo.user); + if(pUser != NULL) { + return pUser->pAcct; + } + + return NULL; +} diff --git a/src/mnode/src/mgmtChildTable.c b/src/mnode/src/mgmtChildTable.c index c99e4746ab2f37e2449807a61d9dbe64038137d6..e2b141fb64edb1507cf7758bc56f16b209614af4 100644 --- a/src/mnode/src/mgmtChildTable.c +++ b/src/mnode/src/mgmtChildTable.c @@ -31,11 +31,13 @@ #include "mgmtDb.h" #include "mgmtDnodeInt.h" #include "mgmtGrant.h" +#include "mgmtProfile.h" #include "mgmtSuperTable.h" #include "mgmtTable.h" #include "mgmtVgroup.h" void *tsChildTableSdb; +int32_t tsChildTableUpdateSize; void *(*mgmtChildTableActionFp[SDB_MAX_ACTION_TYPES])(void *row, char *str, int32_t size, int32_t *ssize); void *mgmtChildTableActionInsert(void *row, char *str, int32_t size, int32_t *ssize); @@ -61,6 +63,8 @@ static void mgmtChildTableActionInit() { } void *mgmtChildTableActionReset(void *row, char *str, int32_t size, int32_t *ssize) { + SChildTableObj *pTable = (SChildTableObj *) row; + memcpy(pTable, str, tsChildTableUpdateSize); return NULL; } @@ -102,10 +106,9 @@ void *mgmtChildTableActionInsert(void *row, char *str, int32_t size, int32_t *ss pTable->superTable = mgmtGetSuperTable(pTable->superTableId); mgmtAddTableIntoSuperTable(pTable->superTable); - pAcct->acctInfo.numOfTimeSeries += (pTable->superTable->numOfColumns - 1); - pVgroup->numOfTables++; - pDb->numOfTables++; - pVgroup->tableList[pTable->sid] = (STableInfo *) pTable; + mgmtAddTimeSeries(pAcct, pTable->superTable->numOfColumns - 1); + mgmtAddTableIntoDb(pDb); + mgmtAddTableIntoVgroup(pVgroup, (STableInfo *) pTable); if (pVgroup->numOfTables >= pDb->cfg.maxSessions - 1 && pDb->numOfVgroups > 1) { mgmtMoveVgroupToTail(pDb, pVgroup); @@ -138,11 +141,9 @@ void *mgmtChildTableActionDelete(void *row, char *str, int32_t size, int32_t *ss return NULL; } - pAcct->acctInfo.numOfTimeSeries -= (pTable->superTable->numOfColumns - 1); - pVgroup->tableList[pTable->sid] = NULL; - pVgroup->numOfTables--; - pDb->numOfTables--; - taosFreeId(pVgroup->idPool, pTable->sid); + mgmtRestoreTimeSeries(pAcct, pTable->superTable->numOfColumns - 1); + mgmtRemoveTableFromDb(pDb); + mgmtRemoveTableFromVgroup(pVgroup, (STableInfo *) pTable); mgmtRemoveTableFromSuperTable(pTable->superTable); @@ -161,8 +162,8 @@ void *mgmtChildTableActionEncode(void *row, char *str, int32_t size, int32_t *ss SChildTableObj *pTable = (SChildTableObj *) row; assert(row != NULL && str != NULL); - int32_t tsize = pTable->updateEnd - (int8_t *) pTable; - memcpy(str, pTable, tsize); + memcpy(str, pTable, tsChildTableUpdateSize); + *ssize = tsChildTableUpdateSize; return NULL; } @@ -170,18 +171,14 @@ void *mgmtChildTableActionEncode(void *row, char *str, int32_t size, int32_t *ss void *mgmtChildTableActionDecode(void *row, char *str, int32_t size, int32_t *ssize) { assert(str != NULL); - SChildTableObj *pTable = (SChildTableObj *)malloc(sizeof(SChildTableObj)); - if (pTable == NULL) { - return NULL; - } - memset(pTable, 0, sizeof(SChildTableObj)); + SChildTableObj *pTable = (SChildTableObj *)calloc(sizeof(SChildTableObj), 1); + if (pTable == NULL) return NULL; - int32_t tsize = pTable->updateEnd - (int8_t *)pTable; - if (size < tsize) { + if (size < tsChildTableUpdateSize) { mgmtDestroyChildTable(pTable); return NULL; } - memcpy(pTable, str, tsize); + memcpy(pTable, str, tsChildTableUpdateSize); return (void *)pTable; } @@ -199,8 +196,10 @@ int32_t mgmtInitChildTables() { SChildTableObj *pTable = NULL; mgmtChildTableActionInit(); + SChildTableObj tObj; + tsChildTableUpdateSize = tObj.updateEnd - (int8_t *)&tObj; - tsChildTableSdb = sdbOpenTable(tsMaxTables, sizeof(SChildTableObj), + tsChildTableSdb = sdbOpenTable(tsMaxTables, tsChildTableUpdateSize, "ctables", SDB_KEYTYPE_STRING, tsMgmtDirectory, mgmtChildTableAction); if (tsChildTableSdb == NULL) { mError("failed to init child table data"); @@ -216,73 +215,130 @@ int32_t mgmtInitChildTables() { SDbObj *pDb = mgmtGetDbByTableId(pTable->tableId); if (pDb == NULL) { - mError("super table:%s, failed to get db, discard it", pTable->tableId); + mError("ctable:%s, failed to get db, discard it", pTable->tableId); sdbDeleteRow(tsChildTableSdb, pTable); pNode = pLastNode; continue; } - } - mgmtSetVgroupIdPool(); + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + mError("ctable:%s, failed to get vgroup:%d sid:%d, discard it", pTable->tableId, pTable->vgId, pTable->sid); + pTable->vgId = 0; + sdbDeleteRow(tsChildTableSdb, pTable); + pNode = pLastNode; + continue; + } + + if (strcmp(pVgroup->dbName, pDb->name) != 0) { + mError("ctable:%s, db:%s not match with vgroup:%d db:%s sid:%d, discard it", + pTable->tableId, pDb->name, pTable->vgId, pVgroup->dbName, pTable->sid); + pTable->vgId = 0; + sdbDeleteRow(tsChildTableSdb, pTable); + pNode = pLastNode; + continue; + } + + if (pVgroup->tableList == NULL) { + mError("ctable:%s, vgroup:%d tableList is null", pTable->tableId, pTable->vgId); + pTable->vgId = 0; + sdbDeleteRow(tsChildTableSdb, pTable); + pNode = pLastNode; + continue; + } + + pVgroup->tableList[pTable->sid] = (STableInfo*)pTable; + taosIdPoolMarkStatus(pVgroup->idPool, pTable->sid, 1); + + SSuperTableObj *pSuperTable = mgmtGetSuperTable(pTable->superTableId); + if (pSuperTable == NULL) { + mError("ctable:%s, stable:%s not exist", pTable->tableId, pTable->superTableId); + pTable->vgId = 0; + sdbDeleteRow(tsChildTableSdb, pTable); + pNode = pLastNode; + continue; + } + + pTable->superTable = pSuperTable; + mgmtAddTableIntoSuperTable(pSuperTable); + + SAcctObj *pAcct = mgmtGetAcct(pDb->cfg.acct); + mgmtAddTimeSeries(pAcct, pTable->superTable->numOfColumns - 1); + } mTrace("child table is initialized"); return 0; } void mgmtCleanUpChildTables() { + sdbCloseTable(tsChildTableSdb); } -int8_t *mgmtBuildCreateChildTableMsg(SChildTableObj *pTable, SVgObj *pVgroup) { -// SCreateTableMsg *pCreateTable = (SCreateTableMsg *) pMsg; -// memcpy(pCreateTable->tableId, pTable->tableId, TSDB_TABLE_ID_LEN); -// memcpy(pCreateTable->superTableId, pTable->superTable->tableId, TSDB_TABLE_ID_LEN); -// pCreateTable->vnode = htonl(vnode); -// pCreateTable->sid = htonl(pTable->sid); -// pCreateTable->uid = pTable->uid; -// pCreateTable->createdTime = htobe64(pTable->createdTime); -// pCreateTable->sversion = htonl(pTable->superTable->sversion); -// pCreateTable->numOfColumns = htons(pTable->superTable->numOfColumns); -// pCreateTable->numOfTags = htons(pTable->superTable->numOfTags); -// -// SSchema *pSchema = pTable->superTable->schema; -// int32_t totalCols = pCreateTable->numOfColumns + pCreateTable->numOfTags; -// -// for (int32_t col = 0; col < totalCols; ++col) { -// SMColumn *colData = &((SMColumn *) (pCreateTable->data))[col]; -// colData->type = pSchema[col].type; -// colData->bytes = htons(pSchema[col].bytes); -// colData->colId = htons(pSchema[col].colId); -// } -// -// int32_t totalColsSize = sizeof(SMColumn *) * totalCols; -// pMsg = pCreateTable->data + totalColsSize + tagDataLen; -// -// memcpy(pCreateTable->data + totalColsSize, pTagData, tagDataLen); -// pCreateTable->tagDataLen = htonl(tagDataLen); +static void *mgmtBuildCreateChildTableMsg(SChildTableObj *pTable, SVgObj *pVgroup, void *pTagData, int32_t tagDataLen) { + int32_t totalCols = pTable->superTable->numOfColumns + pTable->superTable->numOfTags; + int32_t contLen = sizeof(SDCreateTableMsg) + totalCols * sizeof(SSchema) + tagDataLen; - return NULL; + SDCreateTableMsg *pCreateTable = rpcMallocCont(contLen); + if (pCreateTable == NULL) { + return NULL; + } + + memcpy(pCreateTable->tableId, pTable->tableId, TSDB_TABLE_ID_LEN); + memcpy(pCreateTable->superTableId, pTable->superTable->tableId, TSDB_TABLE_ID_LEN); + pCreateTable->tableType = pTable->type; + pCreateTable->numOfColumns = htons(pTable->superTable->numOfColumns); + pCreateTable->numOfTags = htons(pTable->superTable->numOfTags); + pCreateTable->sid = htonl(pTable->sid); + pCreateTable->sversion = htonl(pTable->superTable->sversion); + pCreateTable->tagDataLen = htonl(tagDataLen); + pCreateTable->sqlDataLen = 0; + pCreateTable->contLen = htonl(contLen); + pCreateTable->numOfVPeers = htonl(pVgroup->numOfVnodes); + pCreateTable->uid = htobe64(pTable->uid); + pCreateTable->superTableUid = htobe64(pTable->superTable->uid); + pCreateTable->createdTime = htobe64(pTable->createdTime); + + for (int i = 0; i < pVgroup->numOfVnodes; ++i) { + pCreateTable->vpeerDesc[i].ip = htonl(pVgroup->vnodeGid[i].ip); + pCreateTable->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); + } + + SSchema *pSchema = (SSchema *) pCreateTable->data; + memcpy(pSchema, pTable->superTable->schema, totalCols * sizeof(SSchema)); + for (int32_t col = 0; col < totalCols; ++col) { + pSchema->bytes = htons(pSchema->bytes); + pSchema->colId = htons(pSchema->colId); + pSchema++; + } + + memcpy(pCreateTable + sizeof(SDCreateTableMsg) + totalCols * sizeof(SSchema), pTagData, tagDataLen); + + return pCreateTable; } -int32_t mgmtCreateChildTable(SDbObj *pDb, SCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t sid) { +int32_t mgmtCreateChildTable(SCreateTableMsg *pCreate, int32_t contLen, SVgObj *pVgroup, int32_t sid, + SDCreateTableMsg **pDCreateOut, STableInfo **pTableOut) { int32_t numOfTables = sdbGetNumOfRows(tsChildTableSdb); if (numOfTables >= tsMaxTables) { - mError("table:%s, numOfTables:%d exceed maxTables:%d", pCreate->meterId, numOfTables, tsMaxTables); + mError("table:%s, numOfTables:%d exceed maxTables:%d", pCreate->tableId, numOfTables, tsMaxTables); return TSDB_CODE_TOO_MANY_TABLES; } char *pTagData = (char *) pCreate->schema; // it is a tag key SSuperTableObj *pSuperTable = mgmtGetSuperTable(pTagData); if (pSuperTable == NULL) { - mError("table:%s, corresponding super table does not exist", pCreate->meterId); + mError("table:%s, corresponding super table does not exist", pCreate->tableId); return TSDB_CODE_INVALID_TABLE; } SChildTableObj *pTable = (SChildTableObj *) calloc(sizeof(SChildTableObj), 1); if (pTable == NULL) { + mError("table:%s, failed to alloc memory", pCreate->tableId); return TSDB_CODE_SERV_OUT_OF_MEMORY; } - strcpy(pTable->tableId, pCreate->meterId); + strcpy(pTable->tableId, pCreate->tableId); strcpy(pTable->superTableId, pSuperTable->tableId); + pTable->type = TSDB_TABLE_TYPE_CHILD_TABLE; pTable->createdTime = taosGetTimestampMs(); pTable->superTable = pSuperTable; pTable->vgId = pVgroup->vgId; @@ -290,58 +346,67 @@ int32_t mgmtCreateChildTable(SDbObj *pDb, SCreateTableMsg *pCreate, SVgObj *pVgr pTable->uid = (((uint64_t) pTable->vgId) << 40) + ((((uint64_t) pTable->sid) & ((1ul << 24) - 1ul)) << 16) + ((uint64_t) sdbGetVersion() & ((1ul << 16) - 1ul)); - int32_t size = mgmtGetTagsLength(pSuperTable, INT_MAX) + (uint32_t) TSDB_TABLE_ID_LEN; - SSchema * schema = (SSchema *) calloc(1, size); - if (schema == NULL) { - free(pTable); - mError("table:%s, corresponding super table schema is null", pCreate->meterId); - return TSDB_CODE_INVALID_TABLE; - } - memcpy(schema, pTagData + TSDB_TABLE_ID_LEN + 1, size); - if (sdbInsertRow(tsChildTableSdb, pTable, 0) < 0) { - mError("table:%s, update sdb error", pCreate->meterId); + mError("table:%s, update sdb error", pCreate->tableId); return TSDB_CODE_SDB_ERROR; } - mgmtAddTimeSeries(pTable->superTable->numOfColumns - 1); + pTagData += (TSDB_TABLE_ID_LEN + 1); + int32_t tagDataLen = contLen - sizeof(SCreateTableMsg) - TSDB_TABLE_ID_LEN - 1; + *pDCreateOut = mgmtBuildCreateChildTableMsg(pTable, pVgroup, pTagData, tagDataLen); + if (*pDCreateOut == NULL) { + mError("table:%s, failed to build create table message", pCreate->tableId); + return TSDB_CODE_SERV_OUT_OF_MEMORY; + } - mgmtSendCreateTableMsg(pTable, pVgroup); + *pTableOut = (STableInfo *) pTable; - mTrace("table:%s, create table in vgroup, vgId:%d sid:%d vnode:%d uid:%" PRIu64 " db:%s", - pTable->tableId, pVgroup->vgId, sid, pVgroup->vnodeGid[0].vnode, pTable->uid, pDb->name); + mTrace("table:%s, create table in vgroup, vgroup:%d sid:%d vnode:%d uid:%" PRIu64 , + pTable->tableId, pVgroup->vgId, sid, pVgroup->vnodeGid[0].vnode, pTable->uid); - return 0; + return TSDB_CODE_SUCCESS; } int32_t mgmtDropChildTable(SDbObj *pDb, SChildTableObj *pTable) { - SVgObj *pVgroup; - SAcctObj *pAcct; - - pAcct = mgmtGetAcct(pDb->cfg.acct); + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + mError("table:%s, failed to drop child table, vgroup not exist", pTable->tableId); + return TSDB_CODE_OTHERS; + } - if (pAcct != NULL) { - pAcct->acctInfo.numOfTimeSeries -= (pTable->superTable->numOfColumns - 1); + SDRemoveTableMsg *pRemove = rpcMallocCont(sizeof(SDRemoveTableMsg)); + if (pRemove == NULL) { + mError("table:%s, failed to drop child table, no enough memory", pTable->tableId); + return TSDB_CODE_SERV_OUT_OF_MEMORY; } - pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - return TSDB_CODE_OTHERS; + strcpy(pRemove->tableId, pTable->tableId); + pRemove->sid = htonl(pTable->sid); + pRemove->uid = htobe64(pTable->uid); + + pRemove->numOfVPeers = htonl(pVgroup->numOfVnodes); + for (int i = 0; i < pVgroup->numOfVnodes; ++i) { + pRemove->vpeerDesc[i].ip = htonl(pVgroup->vnodeGid[i].ip); + pRemove->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); } - mgmtRestoreTimeSeries(pTable->superTable->numOfColumns - 1); - mgmtSendRemoveMeterMsgToDnode((STableInfo *) pTable, pVgroup); - sdbDeleteRow(tsChildTableSdb, pTable); + SRpcIpSet ipSet = mgmtGetIpSetFromVgroup(pVgroup); + mgmtSendRemoveTableMsg(pRemove, &ipSet, NULL); + + if (sdbDeleteRow(tsChildTableSdb, pTable) < 0) { + mError("table:%s, update ctables sdb error", pTable->tableId); + return TSDB_CODE_SDB_ERROR; + } if (pVgroup->numOfTables <= 0) { mgmtDropVgroup(pDb, pVgroup); } - return 0; + return TSDB_CODE_SUCCESS; } -SChildTableObj* mgmtGetChildTable(char *tableId) { - return (SChildTableObj *)sdbGetRow(tsChildTableSdb, tableId); +void* mgmtGetChildTable(char *tableId) { + return sdbGetRow(tsChildTableSdb, tableId); } int32_t mgmtModifyChildTableTagValueByName(SChildTableObj *pTable, char *tagName, char *nContent) { @@ -383,12 +448,41 @@ int32_t mgmtModifyChildTableTagValueByName(SChildTableObj *pTable, char *tagName // if (pTable->isDirty) pTable->isDirty = 0; // // if (ret < 0) { -// mError("Failed to modify tag column %d of table %s", col, pTable->meterId); +// mError("Failed to modify tag column %d of table %s", col, pTable->tableId); // return TSDB_CODE_APP_ERROR; // } // -// mTrace("Succeed to modify tag column %d of table %s", col, pTable->meterId); +// mTrace("Succeed to modify tag column %d of table %s", col, pTable->tableId); // return TSDB_CODE_SUCCESS; return 0; } +int32_t mgmtGetChildTableMeta(SDbObj *pDb, SChildTableObj *pTable, STableMeta *pMeta, bool usePublicIp) { + pMeta->uid = htobe64(pTable->uid); + pMeta->sid = htonl(pTable->sid); + pMeta->vgid = htonl(pTable->vgId); + pMeta->sversion = htons(pTable->superTable->sversion); + pMeta->precision = pDb->cfg.precision; + pMeta->numOfTags = pTable->superTable->numOfTags; + pMeta->numOfColumns = htons(pTable->superTable->numOfColumns); + pMeta->tableType = pTable->type; + pMeta->contLen = sizeof(STableMeta) + mgmtSetSchemaFromSuperTable(pMeta->schema, pTable->superTable); + strcpy(pMeta->tableId, pTable->tableId); + + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + return TSDB_CODE_INVALID_TABLE; + } + for (int32_t i = 0; i < TSDB_VNODES_SUPPORT; ++i) { + if (usePublicIp) { + pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].publicIp; + pMeta->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); + } else { + pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].ip; + pMeta->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); + } + } + pMeta->numOfVpeers = pVgroup->numOfVnodes; + + return TSDB_CODE_SUCCESS; +} diff --git a/src/mnode/src/mgmtConn.c b/src/mnode/src/mgmtConn.c index 9314d0b479af54d594c56a0193bc0840030a5411..5d7b8ab27f5da1a7c6af298301094d7812513391 100644 --- a/src/mnode/src/mgmtConn.c +++ b/src/mnode/src/mgmtConn.c @@ -32,45 +32,45 @@ typedef struct { SConnInfo connInfo[]; } SConnShow; -int mgmtGetConns(SShowObj *pShow, SConnObj *pConn) { - SAcctObj * pAcct = pConn->pAcct; - SConnShow *pConnShow; - - pthread_mutex_lock(&pAcct->mutex); - - pConnShow = malloc(sizeof(SConnInfo) * pAcct->acctInfo.numOfConns + sizeof(SConnShow)); - pConnShow->index = 0; - pConnShow->numOfConns = 0; - - if (pAcct->acctInfo.numOfConns > 0) { - pConn = pAcct->pConn; - SConnInfo *pConnInfo = pConnShow->connInfo; - - while (pConn && pConn->pUser) { - strcpy(pConnInfo->user, pConn->pUser->user); - pConnInfo->ip = pConn->ip; - pConnInfo->port = pConn->port; - pConnInfo->stime = pConn->stime; - - pConnShow->numOfConns++; - pConnInfo++; - pConn = pConn->next; - } - } - - pthread_mutex_unlock(&pAcct->mutex); - - // sorting based on useconds - - pShow->pNode = pConnShow; +int mgmtGetConns(SShowObj *pShow, void *pConn) { +// SAcctObj * pAcct = pConn->pAcct; +// SConnShow *pConnShow; +// +// pthread_mutex_lock(&pAcct->mutex); +// +// pConnShow = malloc(sizeof(SConnInfo) * pAcct->acctInfo.numOfConns + sizeof(SConnShow)); +// pConnShow->index = 0; +// pConnShow->numOfConns = 0; +// +// if (pAcct->acctInfo.numOfConns > 0) { +// pConn = pAcct->pConn; +// SConnInfo *pConnInfo = pConnShow->connInfo; +// +// while (pConn && pConn->pUser) { +// strcpy(pConnInfo->user, pConn->pUser->user); +// pConnInfo->ip = pConn->ip; +// pConnInfo->port = pConn->port; +// pConnInfo->stime = pConn->stime; +// +// pConnShow->numOfConns++; +// pConnInfo++; +// pConn = pConn->next; +// } +// } +// +// pthread_mutex_unlock(&pAcct->mutex); +// +// // sorting based on useconds +// +// pShow->pNode = pConnShow; return 0; } -int mgmtGetConnsMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +int mgmtGetConnsMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { int cols = 0; - pShow->bytes[cols] = TSDB_METER_NAME_LEN; + pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; SSchema *pSchema = tsGetSchema(pMeta); pSchema[cols].type = TSDB_DATA_TYPE_BINARY; @@ -104,7 +104,7 @@ int mgmtGetConnsMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return 0; } -int mgmtRetrieveConns(SShowObj *pShow, char *data, int rows, SConnObj *pConn) { +int mgmtRetrieveConns(SShowObj *pShow, char *data, int rows, void *pConn) { int numOfRows = 0; char *pWrite; int cols = 0; @@ -141,3 +141,13 @@ int mgmtRetrieveConns(SShowObj *pShow, char *data, int rows, SConnObj *pConn) { pShow->numOfReads += numOfRows; return numOfRows; } + +bool mgmtCheckQhandle(uint64_t qhandle) { + return true; +} + +void mgmtSaveQhandle(void *qhandle) { +} + +void mgmtFreeQhandle(void *qhandle) { +} \ No newline at end of file diff --git a/src/mnode/src/mgmtDb.c b/src/mnode/src/mgmtDb.c index 379f678ac1e0e7921b4c12988b420a362ac4cf3d..857e05fddc7297b4349b65b067ccb510fb02f28d 100644 --- a/src/mnode/src/mgmtDb.c +++ b/src/mnode/src/mgmtDb.c @@ -26,6 +26,7 @@ #include "mgmtDnodeInt.h" #include "mgmtGrant.h" #include "mgmtTable.h" +#include "mgmtUser.h" #include "mgmtVgroup.h" extern void *tsVgroupSdb; @@ -66,7 +67,10 @@ int32_t mgmtInitDbs() { mgmtDbActionInit(); - tsDbSdb = sdbOpenTable(tsMaxDbs, sizeof(SDbObj), "db", SDB_KEYTYPE_STRING, tsMgmtDirectory, mgmtDbAction); + SDbObj tObj; + tsDbUpdateSize = tObj.updateEnd - (char *)&tObj; + + tsDbSdb = sdbOpenTable(tsMaxDbs, tsDbUpdateSize, "db", SDB_KEYTYPE_STRING, tsMgmtDirectory, mgmtDbAction); if (tsDbSdb == NULL) { mError("failed to init db data"); return -1; @@ -82,7 +86,7 @@ int32_t mgmtInitDbs() { pDb->next = NULL; pDb->numOfTables = 0; pDb->numOfVgroups = 0; - pDb->numOfMetrics = 0; + pDb->numOfSuperTables = 0; pDb->vgStatus = TSDB_VG_STATUS_READY; pDb->vgTimer = NULL; pAcct = mgmtGetAcct(pDb->cfg.acct); @@ -93,9 +97,6 @@ int32_t mgmtInitDbs() { } } - SDbObj tObj; - tsDbUpdateSize = tObj.updateEnd - (char *)&tObj; - mTrace("db data is initialized"); return 0; } @@ -104,13 +105,13 @@ SDbObj *mgmtGetDb(char *db) { return (SDbObj *)sdbGetRow(tsDbSdb, db); } -SDbObj *mgmtGetDbByTableId(char *meterId) { +SDbObj *mgmtGetDbByTableId(char *tableId) { char db[TSDB_TABLE_ID_LEN], *pos; - pos = strstr(meterId, TS_PATH_DELIMITER); + pos = strstr(tableId, TS_PATH_DELIMITER); pos = strstr(pos + 1, TS_PATH_DELIMITER); memset(db, 0, sizeof(db)); - strncpy(db, meterId, pos - meterId); + strncpy(db, tableId, pos - tableId); return (SDbObj *)sdbGetRow(tsDbSdb, db); } @@ -216,16 +217,16 @@ int32_t mgmtCheckDbParams(SCreateDbMsg *pCreate) { } // calculate the blocks per table - if (pCreate->blocksPerMeter < 0) { - pCreate->blocksPerMeter = pCreate->cacheNumOfBlocks.totalBlocks / 4; + if (pCreate->blocksPerTable < 0) { + pCreate->blocksPerTable = pCreate->cacheNumOfBlocks.totalBlocks / 4; } - if (pCreate->blocksPerMeter > pCreate->cacheNumOfBlocks.totalBlocks * 3 / 4) { - pCreate->blocksPerMeter = pCreate->cacheNumOfBlocks.totalBlocks * 3 / 4; + if (pCreate->blocksPerTable > pCreate->cacheNumOfBlocks.totalBlocks * 3 / 4) { + pCreate->blocksPerTable = pCreate->cacheNumOfBlocks.totalBlocks * 3 / 4; } - if (pCreate->blocksPerMeter < TSDB_MIN_AVG_BLOCKS) { - pCreate->blocksPerMeter = TSDB_MIN_AVG_BLOCKS; + if (pCreate->blocksPerTable < TSDB_MIN_AVG_BLOCKS) { + pCreate->blocksPerTable = TSDB_MIN_AVG_BLOCKS; } pCreate->maxSessions++; @@ -294,7 +295,7 @@ int32_t mgmtSetDbDropping(SDbObj *pDb) { } } } - mgmtSendFreeVnodeMsg(pVgroup); +// mgmtSendRemoveVgroupMsg(pVgroup); pVgroup = pVgroup->next; } @@ -339,7 +340,7 @@ void mgmtDropDbFromSdb(SDbObj *pDb) { // SSuperTableObj *pMetric = pDb->pSTable; // while (pMetric) { // SSuperTableObj *pNext = pMetric->next; -// mgmtDropTable(pDb, pMetric->meterId, 0); +// mgmtDropTable(pDb, pMetric->tableId, 0); // pMetric = pNext; // } @@ -354,7 +355,7 @@ int32_t mgmtDropDb(SDbObj *pDb) { if (!finished) { SVgObj *pVgroup = pDb->pHead; while (pVgroup != NULL) { - mgmtSendFreeVnodeMsg(pVgroup); + mgmtSendRemoveVgroupMsg(pVgroup, NULL); pVgroup = pVgroup->next; } return TSDB_CODE_ACTION_IN_PROGRESS; @@ -462,9 +463,9 @@ int32_t mgmtAlterDb(SAcctObj *pAcct, SAlterDbMsg *pAlter) { } if (pAlter->maxSessions > 0) { //rebuild meterList in mgmtVgroup.c - sdbUpdateRow(tsVgroupSdb, pVgroup, tsVgUpdateSize, 0); + mgmtUpdateVgroup(pVgroup); } - mgmtSendVPeersMsg(pVgroup); +// mgmtSendCreateVnodeMsg(pVgroup); pVgroup = pVgroup->next; } mgmtStartBalanceTimer(10); @@ -472,20 +473,6 @@ int32_t mgmtAlterDb(SAcctObj *pAcct, SAlterDbMsg *pAlter) { return code; } -int32_t mgmtUseDb(SConnObj *pConn, char *name) { - SDbObj *pDb; - int32_t code = TSDB_CODE_INVALID_DB; - - // here change the default db for connect. - pDb = mgmtGetDb(name); - if (pDb) { - pConn->pDb = pDb; - code = 0; - } - - return code; -} - int32_t mgmtAddVgroupIntoDb(SDbObj *pDb, SVgObj *pVgroup) { pVgroup->next = pDb->pHead; pVgroup->prev = NULL; @@ -540,10 +527,12 @@ void mgmtCleanUpDbs() { sdbCloseTable(tsDbSdb); } -int32_t mgmtGetDbMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +int32_t mgmtGetDbMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { int32_t cols = 0; SSchema *pSchema = tsGetSchema(pMeta); + SUserObj *pUser = mgmtGetUserFromConn(pConn); + if (pUser == NULL) return 0; pShow->bytes[cols] = TSDB_DB_NAME_LEN; pSchema[cols].type = TSDB_DATA_TYPE_BINARY; @@ -564,7 +553,7 @@ int32_t mgmtGetDbMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { cols++; #ifndef __CLOUD_VERSION__ - if (strcmp(pConn->pAcct->user, "root") == 0) { + if (strcmp(pUser->user, "root") == 0) { #endif pShow->bytes[cols] = 4; pSchema[cols].type = TSDB_DATA_TYPE_INT; @@ -576,7 +565,7 @@ int32_t mgmtGetDbMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { #endif #ifndef __CLOUD_VERSION__ - if (strcmp(pConn->pAcct->user, "root") == 0) { + if (strcmp(pUser->user, "root") == 0) { #endif pShow->bytes[cols] = 2; pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT; @@ -600,7 +589,7 @@ int32_t mgmtGetDbMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { cols++; #ifndef __CLOUD_VERSION__ - if (strcmp(pConn->pAcct->user, "root") == 0) { + if (strcmp(pUser->user, "root") == 0) { #endif pShow->bytes[cols] = 4; pSchema[cols].type = TSDB_DATA_TYPE_INT; @@ -675,8 +664,8 @@ int32_t mgmtGetDbMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; - pShow->numOfRows = pConn->pAcct->acctInfo.numOfDbs; - pShow->pNode = pConn->pAcct->pHead; + pShow->numOfRows = pUser->pAcct->acctInfo.numOfDbs; + pShow->pNode = pUser->pAcct->pHead; return 0; } @@ -687,18 +676,20 @@ char *mgmtGetDbStr(char *src) { return ++pos; } -int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void *pConn) { int32_t numOfRows = 0; SDbObj *pDb = NULL; char * pWrite; int32_t cols = 0; + SUserObj *pUser = mgmtGetUserFromConn(pConn); + if (pUser == NULL) return 0; while (numOfRows < rows) { pDb = (SDbObj *)pShow->pNode; if (pDb == NULL) break; pShow->pNode = (void *)pDb->next; if (mgmtCheckIsMonitorDB(pDb->name, tsMonitorDbName)) { - if (strcmp(pConn->pUser->user, "root") != 0 && strcmp(pConn->pUser->user, "_root") != 0 && strcmp(pConn->pUser->user, "monitor") != 0 ) { + if (strcmp(pUser->user, "root") != 0 && strcmp(pUser->user, "_root") != 0 && strcmp(pUser->user, "monitor") != 0 ) { continue; } } @@ -718,7 +709,7 @@ int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, SConnObj *pCo cols++; #ifndef __CLOUD_VERSION__ - if (strcmp(pConn->pAcct->user, "root") == 0) { + if (strcmp(pUser->user, "root") == 0) { #endif pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; *(int32_t *)pWrite = pDb->numOfVgroups; @@ -728,7 +719,7 @@ int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, SConnObj *pCo #endif #ifndef __CLOUD_VERSION__ - if (strcmp(pConn->pAcct->user, "root") == 0) { + if (strcmp(pUser->user, "root") == 0) { #endif pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; *(int16_t *)pWrite = pDb->cfg.replications; @@ -746,7 +737,7 @@ int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, SConnObj *pCo cols++; #ifndef __CLOUD_VERSION__ - if (strcmp(pConn->pAcct->user, "root") == 0) { + if (strcmp(pUser->user, "root") == 0) { #endif pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; *(int32_t *)pWrite = pDb->cfg.maxSessions - 1; // table num can be created should minus 1 @@ -769,7 +760,7 @@ int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, SConnObj *pCo cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int16_t *)pWrite = pDb->cfg.blocksPerMeter; + *(int16_t *)pWrite = pDb->cfg.blocksPerTable; cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; @@ -832,12 +823,11 @@ void *mgmtDbActionUpdate(void *row, char *str, int32_t size, int32_t *ssize) { void *mgmtDbActionEncode(void *row, char *str, int32_t size, int32_t *ssize) { SDbObj *pDb = (SDbObj *) row; - int32_t tsize = pDb->updateEnd - (char *) pDb; - if (size < tsize) { + if (size < tsDbUpdateSize) { *ssize = -1; } else { - memcpy(str, pDb, tsize); - *ssize = tsize; + memcpy(str, pDb, tsDbUpdateSize); + *ssize = tsDbUpdateSize; } return NULL; @@ -847,16 +837,14 @@ void *mgmtDbActionDecode(void *row, char *str, int32_t size, int32_t *ssize) { if (pDb == NULL) return NULL; memset(pDb, 0, sizeof(SDbObj)); - int32_t tsize = pDb->updateEnd - (char *)pDb; - memcpy(pDb, str, tsize); + memcpy(pDb, str, tsDbUpdateSize); return (void *)pDb; } void *mgmtDbActionReset(void *row, char *str, int32_t size, int32_t *ssize) { SDbObj *pDb = (SDbObj *) row; - int32_t tsize = pDb->updateEnd - (char *) pDb; - memcpy(pDb, str, tsize); + memcpy(pDb, str, tsDbUpdateSize); return NULL; } @@ -865,3 +853,18 @@ void *mgmtDbActionDestroy(void *row, char *str, int32_t size, int32_t *ssize) { tfree(row); return NULL; } + +void mgmtAddSuperTableIntoDb(SDbObj *pDb) { + atomic_add_fetch_32(&pDb->numOfSuperTables, 1); +} + +void mgmtRemoveSuperTableFromDb(SDbObj *pDb) { + atomic_add_fetch_32(&pDb->numOfSuperTables, -1); +} +void mgmtAddTableIntoDb(SDbObj *pDb) { + atomic_add_fetch_32(&pDb->numOfTables, 1); +} + +void mgmtRemoveTableFromDb(SDbObj *pDb) { + atomic_add_fetch_32(&pDb->numOfTables, -1); +} diff --git a/src/mnode/src/mgmtDnode.c b/src/mnode/src/mgmtDnode.c index ba5c29452709108aa16984b0ee3655765a68744d..5a9e9aff358dfe686f23a4422c8200bc3bd87e36 100644 --- a/src/mnode/src/mgmtDnode.c +++ b/src/mnode/src/mgmtDnode.c @@ -21,6 +21,8 @@ #include "mnode.h" #include "mgmtDnode.h" #include "mgmtBalance.h" +#include "mgmtUser.h" +#include "mgmtVgroup.h" SDnodeObj tsDnodeObj; @@ -96,10 +98,13 @@ void mgmtUnSetDnodeVgid(SVnodeGid vnodeGid[], int32_t numOfVnodes) { } } -int32_t mgmtGetDnodeMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +int32_t mgmtGetDnodeMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { int32_t cols = 0; - if (strcmp(pConn->pAcct->user, "root") != 0) return TSDB_CODE_NO_RIGHTS; + SUserObj *pUser = mgmtGetUserFromConn(pConn); + if (pUser == NULL) return 0; + + if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_NO_RIGHTS; SSchema *pSchema = tsGetSchema(pMeta); @@ -158,7 +163,7 @@ int32_t mgmtGetDnodeMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return 0; } -int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn) { int32_t numOfRows = 0; SDnodeObj *pDnode = NULL; char *pWrite; @@ -208,10 +213,13 @@ int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, SConnObj * return numOfRows; } -int32_t mgmtGetModuleMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +int32_t mgmtGetModuleMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { int32_t cols = 0; - if (strcmp(pConn->pAcct->user, "root") != 0) return TSDB_CODE_NO_RIGHTS; + SUserObj *pUser = mgmtGetUserFromConn(pConn); + if (pUser == NULL) return 0; + + if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_NO_RIGHTS; SSchema *pSchema = tsGetSchema(pMeta); @@ -259,7 +267,7 @@ int32_t mgmtGetModuleMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return 0; } -int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pConn) { int32_t numOfRows = 0; SDnodeObj *pDnode = NULL; char * pWrite; @@ -298,10 +306,13 @@ int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, SConnObj return numOfRows; } -int32_t mgmtGetConfigMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +int32_t mgmtGetConfigMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { int32_t cols = 0; - if (strcmp(pConn->pAcct->user, "root") != 0) return TSDB_CODE_NO_RIGHTS; + SUserObj *pUser = mgmtGetUserFromConn(pConn); + if (pUser == NULL) return 0; + + if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_NO_RIGHTS; SSchema *pSchema = tsGetSchema(pMeta); @@ -336,7 +347,7 @@ int32_t mgmtGetConfigMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return 0; } -int32_t mgmtRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, void *pConn) { int32_t numOfRows = 0; for (int32_t i = tsGlobalConfigNum - 1; i >= 0 && numOfRows < rows; --i) { @@ -383,10 +394,11 @@ int32_t mgmtRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, SConnObj return numOfRows; } -int32_t mgmtGetVnodeMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +int32_t mgmtGetVnodeMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { int32_t cols = 0; - - if (strcmp(pConn->pAcct->user, "root") != 0) return TSDB_CODE_NO_RIGHTS; + SUserObj *pUser = mgmtGetUserFromConn(pConn); + if (pUser == NULL) return 0; + if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_NO_RIGHTS; SSchema *pSchema = tsGetSchema(pMeta); @@ -456,7 +468,7 @@ int32_t mgmtGetVnodeMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return 0; } -int32_t mgmtRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn) { int32_t numOfRows = 0; SDnodeObj *pDnode = NULL; char * pWrite; @@ -560,17 +572,17 @@ void *mgmtGetNextDnodeImp(SShowObj *pShow, SDnodeObj **pDnode) { void *(*mgmtGetNextDnode)(SShowObj *pShow, SDnodeObj **pDnode) = mgmtGetNextDnodeImp; -int32_t mgmtGetScoresMetaImp(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +int32_t mgmtGetScoresMetaImp(STableMeta *pMeta, SShowObj *pShow, void *pConn) { return TSDB_CODE_OPS_NOT_SUPPORT; } -int32_t (*mgmtGetScoresMeta)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) = mgmtGetScoresMetaImp; +int32_t (*mgmtGetScoresMeta)(STableMeta *pMeta, SShowObj *pShow, void *pConn) = mgmtGetScoresMetaImp; -int32_t mgmtRetrieveScoresImp(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveScoresImp(SShowObj *pShow, char *data, int32_t rows, void *pConn) { return 0; } -int32_t (*mgmtRetrieveScores)(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) = mgmtRetrieveScoresImp; +int32_t (*mgmtRetrieveScores)(SShowObj *pShow, char *data, int32_t rows, void *pConn) = mgmtRetrieveScoresImp; void mgmtSetDnodeUnRemoveImp(SDnodeObj *pDnode) { } @@ -585,4 +597,5 @@ bool mgmtCheckConfigShowImp(SGlobalConfig *cfg) { return true; } -bool (*mgmtCheckConfigShow)(SGlobalConfig *cfg) = mgmtCheckConfigShowImp; \ No newline at end of file +bool (*mgmtCheckConfigShow)(SGlobalConfig *cfg) = mgmtCheckConfigShowImp; + diff --git a/src/mnode/src/mgmtDnodeInt.c b/src/mnode/src/mgmtDnodeInt.c index 51cd120c361efae40fcf7b8f80b1f6d91c46f3b2..2169d6731d661afaf31a7794c393c167018435ff 100644 --- a/src/mnode/src/mgmtDnodeInt.c +++ b/src/mnode/src/mgmtDnodeInt.c @@ -15,451 +15,275 @@ #define _DEFAULT_SOURCE #include "os.h" - -#include "mnode.h" +#include "taoserror.h" +#include "tsched.h" +#include "tstatus.h" +#include "tsystem.h" +#include "tutil.h" #include "dnode.h" -#include "mgmtDnodeInt.h" +#include "mnode.h" #include "mgmtBalance.h" -#include "mgmtDnode.h" #include "mgmtDb.h" -#include "mgmtVgroup.h" +#include "mgmtDnode.h" +#include "mgmtDnodeInt.h" +#include "mgmtProfile.h" +#include "mgmtShell.h" #include "mgmtTable.h" -#include "tutil.h" -#include "tstatus.h" -#include "tsystem.h" -#include "tsched.h" -#include "taoserror.h" -#include "dnodeSystem.h" -#include "mgmtChildTable.h" -#include "mgmtNormalTable.h" -#include "mgmtStreamTable.h" - -void mgmtProcessMsgFromDnode(int8_t *pCont, int32_t contLen, int32_t msgType, void *pConn); -int mgmtSendVPeersMsg(SVgObj *pVgroup); -char *mgmtBuildVpeersIe(char *pMsg, SVgObj *pVgroup, int vnode); -char *mgmtBuildCreateMeterIe(STabObj *pTable, char *pMsg, int vnode); -extern void *tsDnodeMgmtQhandle; -void * mgmtStatusTimer = NULL; - -void mgmtSendMsgToDnodeImpFp(SSchedMsg *sched) { - int8_t msgType = *(int8_t *) (sched->msg - sizeof(int32_t) - sizeof(int8_t)); - int32_t contLen = *(int32_t *) (sched->msg - sizeof(int8_t)); - int8_t *pCont = sched->msg; - void *pConn = NULL; - - dnodeProcessMsgFromMgmt(pCont, contLen, msgType, pConn); - rpcFreeCont(sched->msg); -} - -int32_t mgmtSendMsgToDnodeImp(int8_t *pCont, int32_t contLen, int8_t msgType) { - mTrace("msg:%s is sent to dnode", taosMsg[msgType]); - *(int8_t *) (pCont - sizeof(int32_t) - sizeof(int8_t)) = msgType; - *(int32_t *) (pCont - sizeof(int8_t)) = contLen; +#include "mgmtVgroup.h" - SSchedMsg schedMsg = {0}; - schedMsg.fp = mgmtSendMsgToDnodeImpFp; - schedMsg.msg = pCont; +void (*mgmtSendMsgToDnodeFp)(SRpcIpSet *ipSet, int8_t msgType, void *pCont, int32_t contLen, void *ahandle) = NULL; +void (*mgmtSendRspToDnodeFp)(void *handle, int32_t code, void *pCont, int32_t contLen) = NULL; +void *mgmtStatusTimer = NULL; - taosScheduleTask(tsDnodeMgmtQhandle, &schedMsg); +static void mgmtSendMsgToDnodeQueueFp(SSchedMsg *sched) { + int32_t contLen = *(int32_t *) (sched->msg - 4); + int32_t code = *(int32_t *) (sched->msg - 8); + int8_t msgType = *(int8_t *) (sched->msg - 9); + void *ahandle = sched->ahandle; + int8_t *pCont = sched->msg; - return TSDB_CODE_SUCCESS; + dnodeProcessMsgFromMgmt(msgType, pCont, contLen, ahandle, code); } -int32_t (*mgmtSendMsgToDnode)(int8_t *pCont, int32_t contLen, int8_t msgType) = mgmtSendMsgToDnodeImp; - -int32_t mgmtSendSimpleRspToDnodeImp(void *pConn, int32_t msgType, int32_t code) { - int8_t *pCont = rpcMallocCont(sizeof(int32_t)); - *(int32_t *) pCont = code; +void mgmtSendMsgToDnode(SRpcIpSet *ipSet, int8_t msgType, void *pCont, int32_t contLen, void *ahandle) { + mTrace("msg:%d:%s is sent to dnode, ahandle:%p", msgType, taosMsg[msgType], ahandle); + if (mgmtSendMsgToDnodeFp) { + mgmtSendMsgToDnodeFp(ipSet, msgType, pCont, contLen, ahandle); + } else { + if (pCont == NULL) { + pCont = rpcMallocCont(1); + contLen = 0; + } + SSchedMsg schedMsg = {0}; + schedMsg.fp = mgmtSendMsgToDnodeQueueFp; + schedMsg.msg = pCont; + schedMsg.ahandle = ahandle; + *(int32_t *) (pCont - 4) = contLen; + *(int32_t *) (pCont - 8) = TSDB_CODE_SUCCESS; + *(int8_t *) (pCont - 9) = msgType; + taosScheduleTask(tsDnodeMgmtQhandle, &schedMsg); + } +} - mgmtSendMsgToDnodeImp(pCont, sizeof(int32_t), msgType); - return TSDB_CODE_SUCCESS; +void mgmtSendRspToDnode(void *pConn, int8_t msgType, int32_t code, void *pCont, int32_t contLen) { + mTrace("rsp:%d:%s is sent to dnode", msgType, taosMsg[msgType]); + if (mgmtSendRspToDnodeFp) { + mgmtSendRspToDnodeFp(pConn, code, pCont, contLen); + } else { + if (pCont == NULL) { + pCont = rpcMallocCont(1); + contLen = 0; + } + SSchedMsg schedMsg = {0}; + schedMsg.fp = mgmtSendMsgToDnodeQueueFp; + schedMsg.msg = pCont; + *(int32_t *) (pCont - 4) = contLen; + *(int32_t *) (pCont - 8) = code; + *(int8_t *) (pCont - 9) = msgType; + taosScheduleTask(tsDnodeMgmtQhandle, &schedMsg); + } } -int32_t (*mgmtSendSimpleRspToDnode)(void *pConn, int32_t msgType, int32_t code) = mgmtSendSimpleRspToDnodeImp; +static void mgmtProcessTableCfgMsg(int8_t msgType, int8_t *pCont, int32_t contLen, void *thandle) { + STableCfgMsg *pCfg = (STableCfgMsg *) pCont; + pCfg->dnode = htonl(pCfg->dnode); + pCfg->vnode = htonl(pCfg->vnode); + pCfg->sid = htonl(pCfg->sid); + mTrace("dnode:%s, vnode:%d, sid:%d, receive table config msg", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid); -int32_t mgmtProcessMeterCfgMsg(int8_t *pCont, int32_t contLen, void *pConn) { if (!sdbMaster) { - mgmtSendSimpleRspToDnode(pConn, TSDB_MSG_TYPE_TABLE_CFG_RSP, TSDB_CODE_REDIRECT); - return TSDB_CODE_REDIRECT; + mError("dnode:%s, vnode:%d, sid:%d, not master, redirect it", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid); + mgmtSendRspToDnode(thandle, msgType + 1, TSDB_CODE_REDIRECT, NULL, 0); + return; } - SMeterCfgMsg *cfg = (SMeterCfgMsg *) pConn; - int32_t vnode = htonl(cfg->vnode); - int32_t sid = htonl(cfg->sid); - - STableInfo *pTable = mgmtGetTableByPos(0, vnode, sid); + STableInfo *pTable = mgmtGetTableByPos(pCfg->dnode, pCfg->vnode, pCfg->sid); if (pTable == NULL) { - mgmtSendSimpleRspToDnode(pConn, TSDB_MSG_TYPE_TABLE_CFG_RSP, TSDB_CODE_INVALID_TABLE); - return TSDB_CODE_INVALID_TABLE_ID; + mError("dnode:%s, vnode:%d, sid:%d, table not found", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid); + mgmtSendRspToDnode(thandle, msgType + 1, TSDB_CODE_INVALID_TABLE, NULL, 0); + return; } - int8_t *pCreateTableMsg = NULL; - if (pTable->type == TSDB_TABLE_TYPE_NORMAL_TABLE) { - pCreateTableMsg = mgmtBuildCreateNormalTableMsg((SNormalTableObj *)pTable); - } else if (pTable->type == TSDB_TABLE_TYPE_CHILD_TABLE) { - pCreateTableMsg = mgmtBuildCreateNormalTableMsg((SNormalTableObj *)pTable); - } else if (pTable->type == TSDB_TABLE_TYPE_STREAM_TABLE) { - pCreateTableMsg = mgmtBuildCreateNormalTableMsg((SNormalTableObj *)pTable); - } else {} - - if (pCreateTableMsg != NULL) { - mgmtSendMsgToDnode(pCreateTableMsg, 0, TSDB_MSG_TYPE_TABLE_CFG_RSP); - return TSDB_CODE_SUCCESS; - } else { - mgmtSendSimpleRspToDnode(pConn, TSDB_MSG_TYPE_TABLE_CFG_RSP, TSDB_CODE_INVALID_TABLE); - return TSDB_CODE_INVALID_TABLE; - } + mgmtSendRspToDnode(thandle, msgType + 1, TSDB_CODE_SUCCESS, NULL, 0); + + //TODO + SRpcIpSet ipSet = mgmtGetIpSetFromIp(pCfg->dnode); + mgmtSendCreateTableMsg(NULL, &ipSet, NULL); } -int mgmtProcessVpeerCfgMsg(int8_t *pCont, int32_t contLen, void *pConn) { -// char * pMsg, *pStart; -// int msgLen = 0; -// SVpeerCfgMsg *pCfg = (SVpeerCfgMsg *)cont; -// SVgObj * pVgroup = NULL; -// -// if (!sdbMaster) { -// mgmtSendSimpleRspToDnode(pObj, TSDB_MSG_TYPE_VNODE_CFG_RSP, TSDB_CODE_REDIRECT); -// return 0; -// } -// -// int vnode = htonl(pCfg->vnode); -// -// pStart = taosBuildRspMsgToDnode(pObj, TSDB_MSG_TYPE_VNODE_CFG_RSP); -// if (pStart == NULL) { -// mgmtSendSimpleRspToDnode(pObj, TSDB_MSG_TYPE_VNODE_CFG_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// pMsg = pStart; -// -// if (vnode < pObj->numOfVnodes) pVgroup = mgmtGetVgroup(pObj->vload[vnode].vgId); -// -// if (pVgroup) { -// *pMsg = 0; -// pMsg++; -// pMsg = mgmtBuildVpeersIe(pMsg, pVgroup, vnode); -// mTrace("dnode:%s, vnode:%d, vgroup:%d, send create vnode msg, code:%d", taosIpStr(pObj->privateIp), vnode, pVgroup->vgId, *pMsg); -// } else { -// mTrace("dnode:%s, vnode:%d, no vgroup info, vgroup:%d", taosIpStr(pObj->privateIp), vnode, pObj->vload[vnode].vgId); -// *pMsg = TSDB_CODE_NOT_ACTIVE_VNODE; -// pMsg++; -// *(int32_t *)pMsg = htonl(vnode); -// pMsg += sizeof(int32_t); -// } -// -// msgLen = pMsg - pStart; -// mgmtSendMsgToDnode(pObj, pStart, msgLen); +static void mgmtProcessVnodeCfgMsg(int8_t msgType, int8_t *pCont, int32_t contLen, void *pConn) { + if (!sdbMaster) { + mgmtSendRspToDnode(pConn, msgType + 1, TSDB_CODE_REDIRECT, NULL, 0); + return; + } - return 0; -} + SVpeerCfgMsg *pCfg = (SVpeerCfgMsg *) pCont; + pCfg->dnode = htonl(pCfg->dnode); + pCfg->vnode = htonl(pCfg->vnode); -int mgmtProcessCreateRsp(int8_t *pCont, int32_t contLen, void *pConn) { return 0; } - -int mgmtProcessFreeVnodeRsp(int8_t *pCont, int32_t contLen, void *pConn) { return 0; } - -int mgmtProcessVPeersRsp(int8_t *pCont, int32_t contLen, void *pConn) { -// STaosRsp *pRsp = (STaosRsp *)msg; -// -// if (!sdbMaster) { -// mgmtSendSimpleRspToDnode(pObj, TSDB_MSG_TYPE_DNODE_VPEERS_RSP, TSDB_CODE_REDIRECT); -// return 0; -// } -// -// SDbObj *pDb = mgmtGetDb(pRsp->more); -// if (!pDb) { -// mError("dnode:%s, db:%s not find, code:%d", taosIpStr(pObj->privateIp), pRsp->more, pRsp->code); -// return 0; -// } -// -// if (pDb->vgStatus != TSDB_VG_STATUS_IN_PROGRESS) { -// mTrace("dnode:%s, db:%s vpeer rsp already disposed, vgroup status:%s code:%d", -// taosIpStr(pObj->privateIp), pRsp->more, taosGetVgroupStatusStr(pDb->vgStatus), pRsp->code); -// return 0; -// } -// -// if (pRsp->code == TSDB_CODE_SUCCESS) { -// pDb->vgStatus = TSDB_VG_STATUS_READY; -// mTrace("dnode:%s, db:%s vgroup is created in dnode", taosIpStr(pObj->privateIp), pRsp->more); -// return 0; -// } -// -// pDb->vgStatus = pRsp->code; -// mError("dnode:%s, db:%s vgroup init failed, code:%d %s", -// taosIpStr(pObj->privateIp), pRsp->more, pRsp->code, taosGetVgroupStatusStr(pDb->vgStatus)); + SVgObj *pVgroup = mgmtGetVgroupByVnode(pCfg->dnode, pCfg->vnode); + if (pVgroup == NULL) { + mTrace("dnode:%s, vnode:%d, no vgroup info", taosIpStr(pCfg->dnode), pCfg->vnode); + mgmtSendRspToDnode(pConn, msgType + 1, TSDB_CODE_NOT_ACTIVE_VNODE, NULL, 0); + return; + } - return 0; + mgmtSendRspToDnode(pConn, msgType + 1, TSDB_CODE_SUCCESS, NULL, 0); + + SRpcIpSet ipSet = mgmtGetIpSetFromIp(pCfg->dnode); + mgmtSendCreateVnodeMsg(pVgroup, pCfg->vnode, &ipSet, NULL); } -void mgmtProcessMsgFromDnode(int8_t *pCont, int32_t contLen, int32_t msgType, void *pConn) { - if (msgType == TSDB_MSG_TYPE_TABLE_CFG) { - mgmtProcessMeterCfgMsg(pCont, contLen, pConn); - } else if (msgType == TSDB_MSG_TYPE_VNODE_CFG) { - mgmtProcessVpeerCfgMsg(pCont, contLen, pConn); - } else if (msgType == TSDB_MSG_TYPE_DNODE_CREATE_TABLE_RSP) { - mgmtProcessCreateRsp(pCont, contLen, pConn); - } else if (msgType == TSDB_MSG_TYPE_DNODE_REMOVE_TABLE_RSP) { - // do nothing - } else if (msgType == TSDB_MSG_TYPE_DNODE_VPEERS_RSP) { - mgmtProcessVPeersRsp(pCont, contLen, pConn); - } else if (msgType == TSDB_MSG_TYPE_DNODE_FREE_VNODE_RSP) { - mgmtProcessFreeVnodeRsp(pCont, contLen, pConn); - } else if (msgType == TSDB_MSG_TYPE_DNODE_CFG_RSP) { - // do nothing; - } else if (msgType == TSDB_MSG_TYPE_ALTER_STREAM_RSP) { - // do nothing; + +static void mgmtProcessCreateTableRsp(int8_t msgType, int8_t *pCont, int32_t contLen, void *thandle, int32_t code) { + mTrace("create table rsp received, thandle:%p code:%d", thandle, code); + if (thandle == NULL) return; + + SProcessInfo *info = thandle; + assert(info->type == TSDB_PROCESS_CREATE_TABLE || info->type == TSDB_PROCESS_CREATE_TABLE_GET_META); + STableInfo *pTable = info->ahandle; + + if (code != TSDB_CODE_SUCCESS) { + mError("table:%s, failed to create in dnode, code:%d, set it dirty", pTable->tableId); + mgmtSetTableDirty(pTable, true); } else { - mError("%s from dnode is not processed", taosMsg[msgType]); + mTrace("table:%s, created in dnode", pTable->tableId); + mgmtSetTableDirty(pTable, false); } + + if (code != TSDB_CODE_SUCCESS) { + rpcSendResponse(info->thandle, code, NULL, 0); + } else { + if (info->type == TSDB_PROCESS_CREATE_TABLE_GET_META) { + mTrace("table:%s, start to process get meta", pTable->tableId); + mgmtProcessGetTableMeta(pTable, thandle); + } else { + rpcSendResponse(info->thandle, code, NULL, 0); + } + } + + free(info); } -int32_t mgmtSendCreateTableMsg(SChildTableObj *pTable, SVgObj *pVgroup) { -// uint64_t timeStamp = taosGetTimestampMs(); -// -// for (int32_t index = 0; index < pVgroup->numOfVnodes; ++index) { -// SDnodeObj *pObj = mgmtGetDnode(pVgroup->vnodeGid[index].ip); -// if (pObj == NULL) { -// continue; -// } -// -// int8_t *pStart = taosBuildReqMsgToDnodeWithSize(pObj, TSDB_MSG_TYPE_DNODE_CREATE_CHILD_TABLE, 64000); -// if (pStart == NULL) { -// continue; -// } -// -// int8_t *pMsg = mgmtBuildCreateChildTableMsg(pTable, pStart, pVgroup->vnodeGid[index].vnode, tagDataLen, pTagData); -// int32_t msgLen = pMsg - pStart; -// -// mgmtSendMsgToDnode(pObj, pStart, msgLen); -// } -// -// pVgroup->lastCreate = timeStamp; - return 0; +void mgmtSendCreateTableMsg(SDCreateTableMsg *pCreate, SRpcIpSet *ipSet, void *ahandle) { + mTrace("table:%s, send create table msg, ahandle:%p", pCreate->tableId, ahandle); + mgmtSendMsgToDnode(ipSet, TSDB_MSG_TYPE_DNODE_CREATE_TABLE, pCreate, htonl(pCreate->contLen), ahandle); } -int32_t mgmtSendCreateStreamTableMsg(SStreamTableObj *pTable, SVgObj *pVgroup) { -// uint64_t timeStamp = taosGetTimestampMs(); -// -// for (int32_t index = 0; index < pVgroup->numOfVnodes; ++index) { -// SDnodeObj *pObj = mgmtGetDnode(pVgroup->vnodeGid[index].ip); -// if (pObj == NULL) { -// continue; -// } -// -// int8_t *pStart = taosBuildReqMsgToDnodeWithSize(pObj, TSDB_MSG_TYPE_DNODE_CREATE_CHILD_TABLE, 64000); -// if (pStart == NULL) { -// continue; -// } -// -// int8_t *pMsg = mgmtBuildCreateStreamTableMsg(pTable, pStart, pVgroup->vnodeGid[index].vnode); -// int32_t msgLen = pMsg - pStart; -// -// mgmtSendMsgToDnode(pObj, pStart, msgLen); -// } -// -// pVgroup->lastCreate = timeStamp; - return 0; +static void mgmtProcessRemoveTableRsp(int8_t msgType, int8_t *pCont, int32_t contLen, void *thandle, int32_t code) { + mTrace("remove table rsp received, thandle:%p code:%d", thandle, code); } -int32_t mgmtSendCreateNormalTableMsg(SNormalTableObj *pTable, SVgObj *pVgroup) { -// uint64_t timeStamp = taosGetTimestampMs(); -// -// for (int32_t index = 0; index < pVgroup->numOfVnodes; ++index) { -// SDnodeObj *pObj = mgmtGetDnode(pVgroup->vnodeGid[index].ip); -// if (pObj == NULL) { -// continue; -// } -// -// int8_t *pStart = taosBuildReqMsgToDnodeWithSize(pObj, TSDB_MSG_TYPE_DNODE_CREATE_CHILD_TABLE, 64000); -// if (pStart == NULL) { -// continue; -// } -// -// int8_t *pMsg = mgmtBuildCreateNormalTableMsg(pTable, pStart, pVgroup->vnodeGid[index].vnode); -// int32_t msgLen = pMsg - pStart; -// -// mgmtSendMsgToDnode(pObj, pStart, msgLen); -// } -// -// pVgroup->lastCreate = timeStamp; -// return 0; - return 0; +void mgmtSendRemoveTableMsg(SDRemoveTableMsg *pRemove, SRpcIpSet *ipSet, void *ahandle) { + mTrace("table:%s, sid:%d send remove table msg, ahandle:%p", pRemove->tableId, htonl(pRemove->sid), ahandle); + if (pRemove != NULL) { + mgmtSendMsgToDnode(ipSet, TSDB_MSG_TYPE_DNODE_REMOVE_TABLE, pRemove, sizeof(SDRemoveTableMsg), ahandle); + } } -int mgmtSendRemoveMeterMsgToDnode(STableInfo *pTable, SVgObj *pVgroup) { -// SDRemoveTableMsg *pRemove; -// char * pMsg, *pStart; -// int i, msgLen = 0; -// SDnodeObj * pObj; -// char ipstr[20]; -// uint64_t timeStamp; -// -// timeStamp = taosGetTimestampMs(); -// -// for (i = 0; i < pVgroup->numOfVnodes; ++i) { -// //if (pVgroup->vnodeGid[i].ip == 0) continue; -// -// pObj = mgmtGetDnode(pVgroup->vnodeGid[i].ip); -// if (pObj == NULL) continue; -// -// pStart = taosBuildReqMsgToDnode(pObj, TSDB_MSG_TYPE_DNODE_REMOVE_CHILD_TABLE); -// if (pStart == NULL) continue; -// pMsg = pStart; -// -// pRemove = (SDRemoveTableMsg *)pMsg; -// pRemove->vnode = htons(pVgroup->vnodeGid[i].vnode); -// pRemove->sid = htonl(pTable->gid.sid); -// memcpy(pRemove->meterId, pTable->meterId, TSDB_TABLE_ID_LEN); -// -// pMsg += sizeof(SDRemoveTableMsg); -// msgLen = pMsg - pStart; -// -// mgmtSendMsgToDnode(pObj, pStart, msgLen); -// -// tinet_ntoa(ipstr, pVgroup->vnodeGid[i].ip); -// mTrace("dnode:%s vid:%d, send remove meter msg, sid:%d status:%d", ipstr, pVgroup->vnodeGid[i].vnode, -// pTable->gid.sid, pObj->status); -// } -// -// pVgroup->lastRemove = timeStamp; +static void mgmtProcessFreeVnodeRsp(int8_t msgType, int8_t *pCont, int32_t contLen, void *thandle, int32_t code) { + mTrace("free vnode rsp received, thandle:%p code:%d", thandle, code); +} - return 0; +static void mgmtProcessDropStableRsp(int8_t msgType, int8_t *pCont, int32_t contLen, void *thandle, int32_t code) { + mTrace("drop stable rsp received, thandle:%p code:%d", thandle, code); } -int mgmtSendAlterStreamMsgToDnode(STabObj *pTable, SVgObj *pVgroup) { -// SAlterStreamMsg *pAlter; -// char * pMsg, *pStart; -// int i, msgLen = 0; -// SDnodeObj * pObj; -// -// for (i = 0; i < pVgroup->numOfVnodes; ++i) { -// if (pVgroup->vnodeGid[i].ip == 0) continue; -// -// pObj = mgmtGetDnode(pVgroup->vnodeGid[i].ip); -// if (pObj == NULL) continue; -// -// pStart = taosBuildReqMsgToDnode(pObj, TSDB_MSG_TYPE_ALTER_STREAM); -// if (pStart == NULL) continue; -// pMsg = pStart; -// -// pAlter = (SAlterStreamMsg *)pMsg; -// pAlter->vnode = htons(pVgroup->vnodeGid[i].vnode); -// pAlter->sid = htonl(pTable->gid.sid); -// pAlter->uid = pTable->uid; -// pAlter->status = pTable->status; -// -// pMsg += sizeof(SAlterStreamMsg); -// msgLen = pMsg - pStart; -// -// mgmtSendMsgToDnode(pObj, pStart, msgLen); -// } +static void mgmtProcessCreateVnodeRsp(int8_t msgType, int8_t *pCont, int32_t contLen, void *thandle, int32_t code) { + mTrace("create vnode rsp received, thandle:%p code:%d", thandle, code); + if (thandle == NULL) return; - return 0; + SProcessInfo *info = thandle; + assert(info->type == TSDB_PROCESS_CREATE_VGROUP || info->type == TSDB_PROCESS_CREATE_VGROUP_GET_META); + info->received++; + SVgObj *pVgroup = info->ahandle; + + bool isGetMeta = false; + if (info->type == TSDB_PROCESS_CREATE_VGROUP_GET_META) { + isGetMeta = true; + } + + mTrace("vgroup:%d, received:%d numOfVnodes:%d", pVgroup->vgId, info->received, pVgroup->numOfVnodes); + if (info->received == pVgroup->numOfVnodes) { + mgmtProcessCreateTable(pVgroup, info->cont, info->contLen, info->thandle, isGetMeta); + free(info); + } } -char *mgmtBuildVpeersIe(char *pMsg, SVgObj *pVgroup, int vnode) { - SVPeersMsg *pVPeers = (SVPeersMsg *)pMsg; - SDbObj * pDb; - - pDb = mgmtGetDb(pVgroup->dbName); - pVPeers->vnode = htonl(vnode); - - pVPeers->cfg = pDb->cfg; - SVnodeCfg *pCfg = &pVPeers->cfg; - pCfg->vgId = htonl(pVgroup->vgId); - pCfg->maxSessions = htonl(pCfg->maxSessions); - pCfg->cacheBlockSize = htonl(pCfg->cacheBlockSize); - pCfg->cacheNumOfBlocks.totalBlocks = htonl(pCfg->cacheNumOfBlocks.totalBlocks); - pCfg->daysPerFile = htonl(pCfg->daysPerFile); - pCfg->daysToKeep1 = htonl(pCfg->daysToKeep1); - pCfg->daysToKeep2 = htonl(pCfg->daysToKeep2); - pCfg->daysToKeep = htonl(pCfg->daysToKeep); - pCfg->commitTime = htonl(pCfg->commitTime); - pCfg->blocksPerMeter = htons(pCfg->blocksPerMeter); - pCfg->replications = (char)pVgroup->numOfVnodes; - pCfg->rowsInFileBlock = htonl(pCfg->rowsInFileBlock); - - SVPeerDesc *vpeerDesc = pVPeers->vpeerDesc; - - pMsg = (char *)(pVPeers->vpeerDesc); - - for (int j = 0; j < pVgroup->numOfVnodes; ++j) { - vpeerDesc[j].ip = htonl(pVgroup->vnodeGid[j].ip); - vpeerDesc[j].vnode = htonl(pVgroup->vnodeGid[j].vnode); - pMsg += sizeof(SVPeerDesc); +void mgmtSendCreateVgroupMsg(SVgObj *pVgroup, void *ahandle) { + mTrace("vgroup:%d, send create all vnodes msg, ahandle:%p", pVgroup->vgId, ahandle); + for (int i = 0; i < pVgroup->numOfVnodes; ++i) { + SRpcIpSet ipSet = mgmtGetIpSetFromIp(pVgroup->vnodeGid[i].ip); + mgmtSendCreateVnodeMsg(pVgroup, pVgroup->vnodeGid[i].vnode, &ipSet, ahandle); } +} - return pMsg; +void mgmtSendCreateVnodeMsg(SVgObj *pVgroup, int32_t vnode, SRpcIpSet *ipSet, void *ahandle) { + mTrace("vgroup:%d, send create vnode:%d msg, ahandle:%p", pVgroup->vgId, vnode, ahandle); + SCreateVnodeMsg *pVpeer = mgmtBuildVpeersMsg(pVgroup, vnode); + if (pVpeer != NULL) { + mgmtSendMsgToDnode(ipSet, TSDB_MSG_TYPE_CREATE_VNODE, pVpeer, sizeof(SCreateVnodeMsg), ahandle); + } } -int mgmtSendVPeersMsg(SVgObj *pVgroup) { -// SDnodeObj *pDnode; -// char * pMsg, *pStart; -// int msgLen = 0; -// -// for (int i = 0; i < pVgroup->numOfVnodes; ++i) { -// pDnode = mgmtGetDnode(pVgroup->vnodeGid[i].ip); -// if (pDnode == NULL) { -// mError("dnode:%s not there", taosIpStr(pVgroup->vnodeGid[i].ip)); -// continue; -// } -// -// pDnode->vload[pVgroup->vnodeGid[i].vnode].vgId = pVgroup->vgId; -// mgmtUpdateDnode(pDnode); -// -// if (pDnode->thandle && pVgroup->numOfVnodes >= 1) { -// pStart = taosBuildReqMsgToDnode(pDnode, TSDB_MSG_TYPE_DNODE_VPEERS); -// if (pStart == NULL) continue; -// pMsg = mgmtBuildVpeersIe(pStart, pVgroup, pVgroup->vnodeGid[i].vnode); -// msgLen = pMsg - pStart; -// -// mgmtSendMsgToDnode(pDnode, pStart, msgLen); -// } -// } +void mgmtProcessMsgFromDnode(char msgType, void *pCont, int32_t contLen, void *pConn, int32_t code) { + if (msgType < 0 || msgType >= TSDB_MSG_TYPE_MAX) { + mError("invalid msg type:%d", msgType); + return; + } + + mTrace("msg:%d:%s is received from dnode, pConn:%p", msgType, taosMsg[(int8_t)msgType], pConn); - return 0; + if (msgType == TSDB_MSG_TYPE_TABLE_CFG) { + mgmtProcessTableCfgMsg(msgType, pCont, contLen, pConn); + } else if (msgType == TSDB_MSG_TYPE_VNODE_CFG) { + mgmtProcessVnodeCfgMsg(msgType, pCont, contLen, pConn); + } else if (msgType == TSDB_MSG_TYPE_DNODE_CREATE_TABLE_RSP) { + mgmtProcessCreateTableRsp(msgType, pCont, contLen, pConn, code); + } else if (msgType == TSDB_MSG_TYPE_DNODE_REMOVE_TABLE_RSP) { + mgmtProcessRemoveTableRsp(msgType, pCont, contLen, pConn, code); + } else if (msgType == TSDB_MSG_TYPE_CREATE_VNODE_RSP) { + mgmtProcessCreateVnodeRsp(msgType, pCont, contLen, pConn, code); + } else if (msgType == TSDB_MSG_TYPE_FREE_VNODE_RSP) { + mgmtProcessFreeVnodeRsp(msgType, pCont, contLen, pConn, code); + } else if (msgType == TSDB_MSG_TYPE_DROP_STABLE) { + mgmtProcessDropStableRsp(msgType, pCont, contLen, pConn, code); + } else if (msgType == TSDB_MSG_TYPE_DNODE_CFG_RSP) { + } else if (msgType == TSDB_MSG_TYPE_ALTER_STREAM_RSP) { + } else { + mError("%s from dnode is not processed", taosMsg[(int8_t)msgType]); + } + + //rpcFreeCont(pCont); } -int mgmtSendOneFreeVnodeMsg(SVnodeGid *pVnodeGid) { -// SFreeVnodeMsg *pFreeVnode; -// char * pMsg, *pStart; -// int msgLen = 0; -// SDnodeObj * pDnode; -// -// pDnode = mgmtGetDnode(pVnodeGid->ip); -// if (pDnode == NULL) { -// mError("dnode:%s not there", taosIpStr(pVnodeGid->ip)); -// return -1; -// } -// -// if (pDnode->thandle == NULL) { -// mTrace("dnode:%s offline, failed to send Vpeer msg", taosIpStr(pVnodeGid->ip)); -// return -1; -// } -// -// pStart = taosBuildReqMsgToDnode(pDnode, TSDB_MSG_TYPE_DNODE_FREE_VNODE); -// if (pStart == NULL) return -1; -// pMsg = pStart; -// -// pFreeVnode = (SFreeVnodeMsg *)pMsg; -// pFreeVnode->vnode = htons(pVnodeGid->vnode); -// -// pMsg += sizeof(SFreeVnodeMsg); -// -// msgLen = pMsg - pStart; -// mgmtSendMsgToDnode(pDnode, pStart, msgLen); - return 0; + +void mgmtSendAlterStreamMsg(STableInfo *pTable, SRpcIpSet *ipSet, void *ahandle) { + mTrace("table:%s, sid:%d send alter stream msg, ahandle:%p", pTable->tableId, pTable->sid, ahandle); } -int mgmtSendFreeVnodeMsg(SVgObj *pVgroup) { - for (int i = 0; i < pVgroup->numOfVnodes; ++i) { - mgmtSendOneFreeVnodeMsg(pVgroup->vnodeGid + i); +void mgmtSendOneFreeVnodeMsg(int32_t vnode, SRpcIpSet *ipSet, void *ahandle) { + mTrace("vnode:%d send free vnode msg, ahandle:%p", vnode, ahandle); + + SFreeVnodeMsg *pFreeVnode = rpcMallocCont(sizeof(SFreeVnodeMsg)); + if (pFreeVnode != NULL) { + pFreeVnode->vnode = htonl(vnode); + mgmtSendMsgToDnode(ipSet, TSDB_MSG_TYPE_FREE_VNODE, pFreeVnode, sizeof(SFreeVnodeMsg), ahandle); } +} - return 0; +void mgmtSendRemoveVgroupMsg(SVgObj *pVgroup, void *ahandle) { + mTrace("vgroup:%d send free vgroup msg, ahandle:%p", pVgroup->vgId, ahandle); + + for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { + SRpcIpSet ipSet = mgmtGetIpSetFromIp(pVgroup->vnodeGid[i].ip); + mgmtSendOneFreeVnodeMsg(pVgroup->vnodeGid[i].vnode, &ipSet, ahandle); + } } -int mgmtCfgDynamicOptions(SDnodeObj *pDnode, char *msg) { +int32_t mgmtCfgDynamicOptions(SDnodeObj *pDnode, char *msg) { char *option, *value; - int olen, valen; + int32_t olen, valen; paGetToken(msg, &option, &olen); if (strncasecmp(option, "unremove", 8) == 0) { @@ -468,7 +292,7 @@ int mgmtCfgDynamicOptions(SDnodeObj *pDnode, char *msg) { } else if (strncasecmp(option, "score", 5) == 0) { paGetToken(option + olen + 1, &value, &valen); if (valen > 0) { - int score = atoi(value); + int32_t score = atoi(value); mTrace("dnode:%s, custom score set from:%d to:%d", taosIpStr(pDnode->privateIp), pDnode->customScore, score); pDnode->customScore = score; mgmtUpdateDnode(pDnode); @@ -478,7 +302,7 @@ int mgmtCfgDynamicOptions(SDnodeObj *pDnode, char *msg) { } else if (strncasecmp(option, "bandwidth", 9) == 0) { paGetToken(msg, &value, &valen); if (valen > 0) { - int bandwidthMb = atoi(value); + int32_t bandwidthMb = atoi(value); if (bandwidthMb >= 0 && bandwidthMb < 10000000) { mTrace("dnode:%s, bandwidth(Mb) set from:%d to:%d", taosIpStr(pDnode->privateIp), pDnode->bandwidthMb, bandwidthMb); pDnode->bandwidthMb = bandwidthMb; @@ -492,14 +316,14 @@ int mgmtCfgDynamicOptions(SDnodeObj *pDnode, char *msg) { return -1; } -int mgmtSendCfgDnodeMsg(char *cont) { +int32_t mgmtSendCfgDnodeMsg(char *cont) { #ifdef CLUSTER char * pMsg, *pStart; - int msgLen = 0; + int32_t msgLen = 0; #endif SDnodeObj *pDnode; - SCfgMsg * pCfg = (SCfgMsg *)cont; + SCfgDnodeMsg * pCfg = (SCfgDnodeMsg *)cont; uint32_t ip; ip = inet_addr(pCfg->ip); @@ -510,7 +334,7 @@ int mgmtSendCfgDnodeMsg(char *cont) { } mTrace("dnode:%s, dynamic option received, content:%s", taosIpStr(pDnode->privateIp), pCfg->config); - int code = mgmtCfgDynamicOptions(pDnode, pCfg->config); + int32_t code = mgmtCfgDynamicOptions(pDnode, pCfg->config); if (code != -1) { return code; } @@ -520,8 +344,8 @@ int mgmtSendCfgDnodeMsg(char *cont) { if (pStart == NULL) return TSDB_CODE_NODE_OFFLINE; pMsg = pStart; - memcpy(pMsg, cont, sizeof(SCfgMsg)); - pMsg += sizeof(SCfgMsg); + memcpy(pMsg, cont, sizeof(SCfgDnodeMsg)); + pMsg += sizeof(SCfgDnodeMsg); msgLen = pMsg - pStart; mgmtSendMsgToDnode(pDnode, pStart, msgLen); @@ -547,7 +371,7 @@ void mgmtProcessDnodeStatusImp(void *handle, void *tmrId) { taosGetSysMemory(&memoryUsedMB); pObj->diskAvailable = tsAvailDataDirGB; - for (int vnode = 0; vnode < pObj->numOfVnodes; ++vnode) { + for (int32_t vnode = 0; vnode < pObj->numOfVnodes; ++vnode) { SVnodeLoad *pVload = &(pObj->vload[vnode]); SVnodeObj * pVnode = vnodeList + vnode; diff --git a/src/mnode/src/mgmtGrant.c b/src/mnode/src/mgmtGrant.c index 8beeae154d5ec0737f97b56a7c6768aae24bd488..37a0753c23eb77db07d054b6227f0457f2bcf289 100644 --- a/src/mnode/src/mgmtGrant.c +++ b/src/mnode/src/mgmtGrant.c @@ -25,11 +25,15 @@ int32_t (*mgmtCheckUserGrant)() = mgmtCheckUserGrantImp; int32_t mgmtCheckDbGrantImp() { return 0; } int32_t (*mgmtCheckDbGrant)() = mgmtCheckDbGrantImp; -void mgmtAddTimeSeriesImp(uint32_t timeSeriesNum) {} -void (*mgmtAddTimeSeries)(uint32_t timeSeriesNum) = mgmtAddTimeSeriesImp; +void mgmtAddTimeSeriesImp(SAcctObj *pAcct, uint32_t timeSeriesNum) { + pAcct->acctInfo.numOfTimeSeries += timeSeriesNum; +} +void (*mgmtAddTimeSeries)(SAcctObj *pAcct, uint32_t timeSeriesNum) = mgmtAddTimeSeriesImp; -void mgmtRestoreTimeSeriesImp(uint32_t timeSeriesNum) {} -void (*mgmtRestoreTimeSeries)(uint32_t timeSeriesNum) = mgmtRestoreTimeSeriesImp; +void mgmtRestoreTimeSeriesImp(SAcctObj *pAcct, uint32_t timeSeriesNum) { + pAcct->acctInfo.numOfTimeSeries -= timeSeriesNum; +} +void (*mgmtRestoreTimeSeries)(SAcctObj *pAcct, uint32_t timeSeriesNum) = mgmtRestoreTimeSeriesImp; int32_t mgmtCheckTimeSeriesImp(uint32_t timeseries) { return 0; } int32_t (*mgmtCheckTimeSeries)(uint32_t timeseries) = mgmtCheckTimeSeriesImp; @@ -37,9 +41,9 @@ int32_t (*mgmtCheckTimeSeries)(uint32_t timeseries) = mgmtCheckTimeSeriesImp; bool mgmtCheckExpiredImp() { return false; } bool (*mgmtCheckExpired)() = mgmtCheckExpiredImp; -int32_t mgmtGetGrantsMetaImp(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return TSDB_CODE_OPS_NOT_SUPPORT; } -int32_t (*mgmtGetGrantsMeta)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) = mgmtGetGrantsMetaImp; +int32_t mgmtGetGrantsMetaImp(STableMeta *pMeta, SShowObj *pShow, void *pConn) { return TSDB_CODE_OPS_NOT_SUPPORT; } +int32_t (*mgmtGetGrantsMeta)(STableMeta *pMeta, SShowObj *pShow, void *pConn) = mgmtGetGrantsMetaImp; -int32_t mgmtRetrieveGrantsImp(SShowObj *pShow, char *data, int rows, SConnObj *pConn) { return 0; } -int32_t (*mgmtRetrieveGrants)(SShowObj *pShow, char *data, int rows, SConnObj *pConn) = mgmtRetrieveGrantsImp; +int32_t mgmtRetrieveGrantsImp(SShowObj *pShow, char *data, int rows, void *pConn) { return 0; } +int32_t (*mgmtRetrieveGrants)(SShowObj *pShow, char *data, int rows, void *pConn) = mgmtRetrieveGrantsImp; diff --git a/src/mnode/src/mgmtMnode.c b/src/mnode/src/mgmtMnode.c index eda22b09ebfebce8af010e6f4a521a1ae0dd912d..cb9e99135ae992eae8f062bf738264d2d1e7e330 100644 --- a/src/mnode/src/mgmtMnode.c +++ b/src/mnode/src/mgmtMnode.c @@ -16,14 +16,14 @@ #define _DEFAULT_SOURCE #include "mgmtMnode.h" -int32_t mgmtGetMnodeMetaImp(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { +int32_t mgmtGetMnodeMetaImp(STableMeta *pMeta, SShowObj *pShow, void *pConn) { return TSDB_CODE_OPS_NOT_SUPPORT; } -int32_t (*mgmtGetMnodeMeta)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) = mgmtGetMnodeMetaImp; +int32_t (*mgmtGetMnodeMeta)(STableMeta *pMeta, SShowObj *pShow, void *pConn) = mgmtGetMnodeMetaImp; -int32_t mgmtRetrieveMnodesImp(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveMnodesImp(SShowObj *pShow, char *data, int32_t rows, void *pConn) { return 0; } -int32_t (*mgmtRetrieveMnodes)(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) = mgmtRetrieveMnodesImp; +int32_t (*mgmtRetrieveMnodes)(SShowObj *pShow, char *data, int32_t rows, void *pConn) = mgmtRetrieveMnodesImp; diff --git a/src/mnode/src/mgmtNormalTable.c b/src/mnode/src/mgmtNormalTable.c index ea482838a6d718983eff93f3740d198e93df80e0..aaabe0bcacf7e5353af0763b14585d5d35c7487f 100644 --- a/src/mnode/src/mgmtNormalTable.c +++ b/src/mnode/src/mgmtNormalTable.c @@ -36,6 +36,7 @@ #include "mgmtVgroup.h" void *tsNormalTableSdb; +int32_t tsNormalTableUpdateSize; void *(*mgmtNormalTableActionFp[SDB_MAX_ACTION_TYPES])(void *row, char *str, int32_t size, int32_t *ssize); void *mgmtNormalTableActionInsert(void *row, char *str, int32_t size, int32_t *ssize); @@ -48,6 +49,7 @@ void *mgmtNormalTableActionDestroy(void *row, char *str, int32_t size, int32_t * static void mgmtDestroyNormalTable(SNormalTableObj *pTable) { free(pTable->schema); + free(pTable->sql); free(pTable); } @@ -63,8 +65,13 @@ static void mgmtNormalTableActionInit() { void *mgmtNormalTableActionReset(void *row, char *str, int32_t size, int32_t *ssize) { SNormalTableObj *pTable = (SNormalTableObj *) row; - int32_t tsize = pTable->updateEnd - (int8_t *) pTable; - memcpy(pTable, str, tsize); + memcpy(pTable, str, tsNormalTableUpdateSize); + + int32_t schemaSize = sizeof(SSchema) * (pTable->numOfColumns) + pTable->sqlLen; + pTable->schema = realloc(pTable->schema, schemaSize); + pTable->sql = (char*)pTable->schema + sizeof(SSchema) * (pTable->numOfColumns); + memcpy(pTable->schema, str + tsNormalTableUpdateSize, schemaSize); + return NULL; } @@ -103,10 +110,9 @@ void *mgmtNormalTableActionInsert(void *row, char *str, int32_t size, int32_t *s } } - pAcct->acctInfo.numOfTimeSeries += (pTable->numOfColumns - 1); - pVgroup->numOfTables++; - pDb->numOfTables++; - pVgroup->tableList[pTable->sid] = (STableInfo *) pTable; + mgmtAddTimeSeries(pAcct, pTable->numOfColumns - 1); + mgmtAddTableIntoDb(pDb); + mgmtAddTableIntoVgroup(pVgroup, (STableInfo *) pTable); if (pVgroup->numOfTables >= pDb->cfg.maxSessions - 1 && pDb->numOfVgroups > 1) { mgmtMoveVgroupToTail(pDb, pVgroup); @@ -139,11 +145,9 @@ void *mgmtNormalTableActionDelete(void *row, char *str, int32_t size, int32_t *s return NULL; } - pAcct->acctInfo.numOfTimeSeries -= (pTable->numOfColumns - 1); - pVgroup->tableList[pTable->sid] = NULL; - pVgroup->numOfTables--; - pDb->numOfTables--; - taosFreeId(pVgroup->idPool, pTable->sid); + mgmtRestoreTimeSeries(pAcct, pTable->numOfColumns - 1); + mgmtRemoveTableFromDb(pDb); + mgmtRemoveTableFromVgroup(pVgroup, (STableInfo *) pTable); if (pVgroup->numOfTables > 0) { mgmtMoveVgroupToHead(pDb, pVgroup); @@ -160,16 +164,16 @@ void *mgmtNormalTableActionEncode(void *row, char *str, int32_t size, int32_t *s SNormalTableObj *pTable = (SNormalTableObj *) row; assert(row != NULL && str != NULL); - int32_t tsize = pTable->updateEnd - (int8_t *) pTable; int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - if (size < tsize + schemaSize + 1) { + if (size < tsNormalTableUpdateSize + schemaSize + 1) { *ssize = -1; return NULL; } - memcpy(str, pTable, tsize); - memcpy(str + tsize, pTable->schema, schemaSize); - *ssize = tsize + schemaSize; + memcpy(str, pTable, tsNormalTableUpdateSize); + memcpy(str + tsNormalTableUpdateSize, pTable->schema, schemaSize); + memcpy(str + tsNormalTableUpdateSize + schemaSize, pTable->sql, pTable->sqlLen); + *ssize = tsNormalTableUpdateSize + schemaSize + pTable->sqlLen; return NULL; } @@ -183,12 +187,11 @@ void *mgmtNormalTableActionDecode(void *row, char *str, int32_t size, int32_t *s } memset(pTable, 0, sizeof(SNormalTableObj)); - int32_t tsize = pTable->updateEnd - (int8_t *)pTable; - if (size < tsize) { + if (size < tsNormalTableUpdateSize) { mgmtDestroyNormalTable(pTable); return NULL; } - memcpy(pTable, str, tsize); + memcpy(pTable, str, tsNormalTableUpdateSize); int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); pTable->schema = (SSchema *)malloc(schemaSize); @@ -197,7 +200,14 @@ void *mgmtNormalTableActionDecode(void *row, char *str, int32_t size, int32_t *s return NULL; } - memcpy(pTable->schema, str + tsize, schemaSize); + memcpy(pTable->schema, str + tsNormalTableUpdateSize, schemaSize); + + pTable->sql = (char *)malloc(pTable->sqlLen); + if (pTable->sql == NULL) { + mgmtDestroyNormalTable(pTable); + return NULL; + } + memcpy(pTable->sql, str + tsNormalTableUpdateSize + schemaSize, pTable->sqlLen); return (void *)pTable; } @@ -211,36 +221,69 @@ void *mgmtNormalTableAction(char action, void *row, char *str, int32_t size, int int32_t mgmtInitNormalTables() { void *pNode = NULL; void *pLastNode = NULL; - SChildTableObj *pTable = NULL; + SNormalTableObj *pTable = NULL; mgmtNormalTableActionInit(); + SNormalTableObj tObj; + tsNormalTableUpdateSize = tObj.updateEnd - (int8_t *)&tObj; tsNormalTableSdb = sdbOpenTable(tsMaxTables, sizeof(SNormalTableObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS, "ntables", SDB_KEYTYPE_STRING, tsMgmtDirectory, mgmtNormalTableAction); if (tsNormalTableSdb == NULL) { - mError("failed to init normal table data"); + mError("failed to init ntables data"); return -1; } - pNode = NULL; while (1) { + pLastNode = pNode; pNode = sdbFetchRow(tsNormalTableSdb, pNode, (void **)&pTable); - if (pTable == NULL) { - break; - } + if (pTable == NULL) break; SDbObj *pDb = mgmtGetDbByTableId(pTable->tableId); if (pDb == NULL) { - mError("normal table:%s, failed to get db, discard it", pTable->tableId); + mError("ntable:%s, failed to get db, discard it", pTable->tableId); sdbDeleteRow(tsNormalTableSdb, pTable); pNode = pLastNode; continue; } - } - mgmtSetVgroupIdPool(); + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + mError("ntable:%s, failed to get vgroup:%d sid:%d, discard it", pTable->tableId, pTable->vgId, pTable->sid); + pTable->vgId = 0; + sdbDeleteRow(tsNormalTableSdb, pTable); + pNode = pLastNode; + continue; + } + + if (strcmp(pVgroup->dbName, pDb->name) != 0) { + mError("ntable:%s, db:%s not match with vgroup:%d db:%s sid:%d, discard it", + pTable->tableId, pDb->name, pTable->vgId, pVgroup->dbName, pTable->sid); + pTable->vgId = 0; + sdbDeleteRow(tsNormalTableSdb, pTable); + pNode = pLastNode; + continue; + } + + if (pVgroup->tableList == NULL) { + mError("ntable:%s, vgroup:%d tableList is null", pTable->tableId, pTable->vgId); + pTable->vgId = 0; + sdbDeleteRow(tsNormalTableSdb, pTable); + pNode = pLastNode; + continue; + } + + mgmtAddTableIntoVgroup(pVgroup, (STableInfo *)pTable); + //pVgroup->tableList[pTable->sid] = (STableInfo*)pTable; + taosIdPoolMarkStatus(pVgroup->idPool, pTable->sid, 1); + + pTable->sql = (char *)pTable->schema + sizeof(SSchema) * pTable->numOfColumns; - mTrace("normal table is initialized"); + SAcctObj *pAcct = mgmtGetAcct(pDb->cfg.acct); + mgmtAddTimeSeries(pAcct, pTable->numOfColumns - 1); + } + + mTrace("ntables is initialized"); return 0; } @@ -248,61 +291,77 @@ void mgmtCleanUpNormalTables() { sdbCloseTable(tsNormalTableSdb); } -int8_t *mgmtBuildCreateNormalTableMsg(SNormalTableObj *pTable) { -// int8_t *pMsg = NULL; -// SDCreateTableMsg *pCreateTable = (SDCreateTableMsg *) pMsg; -// memcpy(pCreateTable->tableId, pTable->tableId, TSDB_TABLE_ID_LEN); -// pCreateTable->vnode = htobe32(vnode); -// pCreateTable->sid = htobe32(pTable->sid); -// pCreateTable->uid = htobe64(pTable->uid); -// pCreateTable->createdTime = htobe64(pTable->createdTime); -// pCreateTable->sversion = htobe32(pTable->sversion); -// pCreateTable->numOfColumns = htobe16(pTable->numOfColumns); -// -// SSchema *pSchema = pTable->schema; -// int32_t totalCols = pCreateTable->numOfColumns; - -// for (int32_t col = 0; col < totalCols; ++col) { -// SMColumn *colData = &((SMColumn *) (pCreateTable->data))[col]; -// colData->type = pSchema[col].type; -// colData->bytes = htons(pSchema[col].bytes); -// colData->colId = htons(pSchema[col].colId); -// } - -// int32_t totalColsSize = sizeof(SMColumn *) * totalCols; -// pMsg = pCreateTable->data + totalColsSize; - -// return pMsg; - return NULL; +static void *mgmtBuildCreateNormalTableMsg(SNormalTableObj *pTable, SVgObj *pVgroup) { + int32_t totalCols = pTable->numOfColumns; + int32_t contLen = sizeof(SDCreateTableMsg) + totalCols * sizeof(SSchema) + pTable->sqlLen; + + SDCreateTableMsg *pCreateTable = rpcMallocCont(contLen); + if (pCreateTable == NULL) { + return NULL; + } + + memcpy(pCreateTable->tableId, pTable->tableId, TSDB_TABLE_ID_LEN); + pCreateTable->tableType = pTable->type; + pCreateTable->numOfColumns = htons(pTable->numOfColumns); + pCreateTable->numOfTags = htons(0); + pCreateTable->sid = htonl(pTable->sid); + pCreateTable->sversion = htonl(pTable->sversion); + pCreateTable->tagDataLen = htonl(0); + pCreateTable->sqlDataLen = htonl(pTable->sqlLen); + pCreateTable->contLen = htonl(contLen); + pCreateTable->numOfVPeers = htonl(pVgroup->numOfVnodes); + pCreateTable->uid = htobe64(pTable->uid); + pCreateTable->superTableUid = htobe64(0); + pCreateTable->createdTime = htobe64(pTable->createdTime); + + for (int i = 0; i < pVgroup->numOfVnodes; ++i) { + pCreateTable->vpeerDesc[i].ip = htonl(pVgroup->vnodeGid[i].ip); + pCreateTable->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); + } + + SSchema *pSchema = (SSchema *) pCreateTable->data; + memcpy(pSchema, pTable->schema, totalCols * sizeof(SSchema)); + for (int32_t col = 0; col < totalCols; ++col) { + pSchema->bytes = htons(pSchema->bytes); + pSchema->colId = htons(pSchema->colId); + pSchema++; + } + + memcpy(pCreateTable + sizeof(SDCreateTableMsg) + totalCols * sizeof(SSchema), pTable->sql, pTable->sqlLen); + + return pCreateTable; } -int32_t mgmtCreateNormalTable(SDbObj *pDb, SCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t sid) { - int32_t numOfTables = sdbGetNumOfRows(tsChildTableSdb); - if (numOfTables >= TSDB_MAX_TABLES) { - mError("normal table:%s, numOfTables:%d exceed maxTables:%d", pCreate->meterId, numOfTables, TSDB_MAX_TABLES); +int32_t mgmtCreateNormalTable(SCreateTableMsg *pCreate, int32_t contLen, SVgObj *pVgroup, int32_t sid, + SDCreateTableMsg **pDCreateOut, STableInfo **pTableOut) { + int32_t numOfTables = sdbGetNumOfRows(tsNormalTableSdb); + if (numOfTables >= TSDB_MAX_NORMAL_TABLES) { + mError("table:%s, numOfTables:%d exceed maxTables:%d", pCreate->tableId, numOfTables, TSDB_MAX_NORMAL_TABLES); return TSDB_CODE_TOO_MANY_TABLES; } SNormalTableObj *pTable = (SNormalTableObj *) calloc(sizeof(SNormalTableObj), 1); if (pTable == NULL) { + mError("table:%s, failed to alloc memory", pCreate->tableId); return TSDB_CODE_SERV_OUT_OF_MEMORY; } - strcpy(pTable->tableId, pCreate->meterId); + strcpy(pTable->tableId, pCreate->tableId); + pTable->type = TSDB_TABLE_TYPE_NORMAL_TABLE; pTable->createdTime = taosGetTimestampMs(); pTable->vgId = pVgroup->vgId; pTable->sid = sid; pTable->uid = (((uint64_t) pTable->createdTime) << 16) + ((uint64_t) sdbGetVersion() & ((1ul << 16) - 1ul)); pTable->sversion = 0; pTable->numOfColumns = pCreate->numOfColumns; + pTable->sqlLen = pTable->sqlLen; - int32_t numOfCols = pCreate->numOfColumns + pCreate->numOfTags; + int32_t numOfCols = pCreate->numOfColumns; int32_t schemaSize = numOfCols * sizeof(SSchema); pTable->schema = (SSchema *) calloc(1, schemaSize); if (pTable->schema == NULL) { free(pTable); - mError("table:%s, no schema input", pCreate->meterId); - return TSDB_CODE_INVALID_TABLE; + return TSDB_CODE_SERV_OUT_OF_MEMORY; } memcpy(pTable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); @@ -312,53 +371,78 @@ int32_t mgmtCreateNormalTable(SDbObj *pDb, SCreateTableMsg *pCreate, SVgObj *pVg tschema[col].colId = pTable->nextColId++; } + pTable->sqlLen = pCreate->sqlLen; + if (pTable->sqlLen != 0) { + pTable->type = TSDB_TABLE_TYPE_STREAM_TABLE; + pTable->sql = calloc(1, pTable->sqlLen); + if (pTable->sql == NULL) { + free(pTable); + return TSDB_CODE_SERV_OUT_OF_MEMORY; + } + memcpy(pTable->sql, (char *) (pCreate->schema) + numOfCols * sizeof(SSchema), pCreate->sqlLen); + pTable->sql[pCreate->sqlLen - 1] = 0; + mTrace("table:%s, stream sql len:%d sql:%s", pCreate->tableId, pCreate->sqlLen, pTable->sql); + } + if (sdbInsertRow(tsNormalTableSdb, pTable, 0) < 0) { - mError("table:%s, update sdb error", pCreate->meterId); + mError("table:%s, update sdb error", pCreate->tableId); return TSDB_CODE_SDB_ERROR; } - mgmtAddTimeSeries(pTable->numOfColumns - 1); + *pDCreateOut = mgmtBuildCreateNormalTableMsg(pTable, pVgroup); + if (*pDCreateOut == NULL) { + mError("table:%s, failed to build create table message", pCreate->tableId); + return TSDB_CODE_SERV_OUT_OF_MEMORY; + } - mgmtSendCreateNormalTableMsg(pTable, pVgroup); + *pTableOut = (STableInfo *) pTable; - mTrace("table:%s, create table in vgroup, vgId:%d sid:%d vnode:%d uid:%" - PRIu64 - " db:%s", - pTable->tableId, pVgroup->vgId, sid, pVgroup->vnodeGid[0].vnode, pTable->uid, pDb->name); + mTrace("table:%s, create table in vgroup, vgroup:%d sid:%d vnode:%d uid:%" PRIu64 , + pTable->tableId, pVgroup->vgId, sid, pVgroup->vnodeGid[0].vnode, pTable->uid); - return 0; + return TSDB_CODE_SUCCESS; } int32_t mgmtDropNormalTable(SDbObj *pDb, SNormalTableObj *pTable) { - SVgObj *pVgroup; - SAcctObj *pAcct; - - pAcct = mgmtGetAcct(pDb->cfg.acct); - - if (pAcct != NULL) { - pAcct->acctInfo.numOfTimeSeries -= (pTable->numOfColumns - 1); - } - - pVgroup = mgmtGetVgroup(pTable->vgId); + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); if (pVgroup == NULL) { + mError("table:%s, failed to drop normal table, vgroup not exist", pTable->tableId); return TSDB_CODE_OTHERS; } - mgmtRestoreTimeSeries(pTable->numOfColumns - 1); + SDRemoveTableMsg *pRemove = rpcMallocCont(sizeof(SDRemoveTableMsg)); + if (pRemove == NULL) { + mError("table:%s, failed to drop normal table, no enough memory", pTable->tableId); + return TSDB_CODE_SERV_OUT_OF_MEMORY; + } - mgmtSendRemoveMeterMsgToDnode((STableInfo *) pTable, pVgroup); + strcpy(pRemove->tableId, pTable->tableId); + pRemove->sid = htonl(pTable->sid); + pRemove->uid = htobe64(pTable->uid); - sdbDeleteRow(tsChildTableSdb, pTable); + pRemove->numOfVPeers = htonl(pVgroup->numOfVnodes); + for (int i = 0; i < pVgroup->numOfVnodes; ++i) { + pRemove->vpeerDesc[i].ip = htonl(pVgroup->vnodeGid[i].ip); + pRemove->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); + } + + SRpcIpSet ipSet = mgmtGetIpSetFromVgroup(pVgroup); + mgmtSendRemoveTableMsg(pRemove, &ipSet, NULL); + + if (sdbDeleteRow(tsNormalTableSdb, pTable) < 0) { + mError("table:%s, update ntables sdb error", pTable->tableId); + return TSDB_CODE_SDB_ERROR; + } if (pVgroup->numOfTables <= 0) { mgmtDropVgroup(pDb, pVgroup); } - return 0; + return TSDB_CODE_SUCCESS; } -SNormalTableObj* mgmtGetNormalTable(char *tableId) { - return (SNormalTableObj *)sdbGetRow(tsNormalTableSdb, tableId); +void* mgmtGetNormalTable(char *tableId) { + return sdbGetRow(tsNormalTableSdb, tableId); } static int32_t mgmtFindNormalTableColumnIndex(SNormalTableObj *pTable, char *colName) { @@ -442,3 +526,46 @@ int32_t mgmtDropNormalTableColumnByName(SNormalTableObj *pTable, char *colName) return TSDB_CODE_SUCCESS; } + +static int32_t mgmtSetSchemaFromNormalTable(SSchema *pSchema, SNormalTableObj *pTable) { + int32_t numOfCols = pTable->numOfColumns; + for (int32_t i = 0; i < numOfCols; ++i) { + strcpy(pSchema->name, pTable->schema[i].name); + pSchema->type = pTable->schema[i].type; + pSchema->bytes = htons(pTable->schema[i].bytes); + pSchema->colId = htons(pTable->schema[i].colId); + pSchema++; + } + + return numOfCols * sizeof(SSchema); +} + +int32_t mgmtGetNormalTableMeta(SDbObj *pDb, SNormalTableObj *pTable, STableMeta *pMeta, bool usePublicIp) { + pMeta->uid = htobe64(pTable->uid); + pMeta->sid = htonl(pTable->sid); + pMeta->vgid = htonl(pTable->vgId); + pMeta->sversion = htons(pTable->sversion); + pMeta->precision = pDb->cfg.precision; + pMeta->numOfTags = 0; + pMeta->numOfColumns = htons(pTable->numOfColumns); + pMeta->tableType = pTable->type; + pMeta->contLen = sizeof(STableMeta) + mgmtSetSchemaFromNormalTable(pMeta->schema, pTable); + + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + return TSDB_CODE_INVALID_TABLE; + } + for (int32_t i = 0; i < TSDB_VNODES_SUPPORT; ++i) { + if (usePublicIp) { + pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].publicIp; + pMeta->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); + } else { + pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].ip; + pMeta->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); + } + } + pMeta->numOfVpeers = pVgroup->numOfVnodes; + + return TSDB_CODE_SUCCESS; +} + diff --git a/src/mnode/src/mgmtProfile.c b/src/mnode/src/mgmtProfile.c index 298767d2eae8b674141f5a529929bb338b01b60d..6e9a6e9c07f6ce2b130aba3116fa2f6c8e01a311 100644 --- a/src/mnode/src/mgmtProfile.c +++ b/src/mnode/src/mgmtProfile.c @@ -28,97 +28,97 @@ typedef struct { } SCDesc; typedef struct { - int index; - int numOfQueries; + int32_t index; + int32_t numOfQueries; SCDesc * connInfo; SCDesc **cdesc; - SQDesc qdesc[]; + SQueryDesc qdesc[]; } SQueryShow; typedef struct { - int index; - int numOfStreams; + int32_t index; + int32_t numOfStreams; SCDesc * connInfo; SCDesc **cdesc; - SSDesc sdesc[]; + SStreamDesc sdesc[]; } SStreamShow; -int mgmtSaveQueryStreamList(char *cont, int contLen, SConnObj *pConn) { - SAcctObj *pAcct = pConn->pAcct; - - if (contLen <= 0 || pAcct == NULL) { - return 0; - } - - pthread_mutex_lock(&pAcct->mutex); - - if (pConn->pQList) { - pAcct->acctInfo.numOfQueries -= pConn->pQList->numOfQueries; - pAcct->acctInfo.numOfStreams -= pConn->pSList->numOfStreams; - } - - pConn->pQList = realloc(pConn->pQList, contLen); - memcpy(pConn->pQList, cont, contLen); - - pConn->pSList = (SSList *)(((char *)pConn->pQList) + pConn->pQList->numOfQueries * sizeof(SQDesc) + sizeof(SQList)); - - pAcct->acctInfo.numOfQueries += pConn->pQList->numOfQueries; - pAcct->acctInfo.numOfStreams += pConn->pSList->numOfStreams; - - pthread_mutex_unlock(&pAcct->mutex); - - return 0; +int32_t mgmtSaveQueryStreamList(SHeartBeatMsg *pHBMsg) { +// SAcctObj *pAcct = pConn->pAcct; +// +// if (contLen <= 0 || pAcct == NULL) { +// return 0; +// } +// +// pthread_mutex_lock(&pAcct->mutex); +// +// if (pConn->pQList) { +// pAcct->acctInfo.numOfQueries -= pConn->pQList->numOfQueries; +// pAcct->acctInfo.numOfStreams -= pConn->pSList->numOfStreams; +// } +// +// pConn->pQList = realloc(pConn->pQList, contLen); +// memcpy(pConn->pQList, cont, contLen); +// +// pConn->pSList = (SStreamList *)(((char *)pConn->pQList) + pConn->pQList->numOfQueries * sizeof(SQueryDesc) + sizeof(SQqueryList)); +// +// pAcct->acctInfo.numOfQueries += pConn->pQList->numOfQueries; +// pAcct->acctInfo.numOfStreams += pConn->pSList->numOfStreams; +// +// pthread_mutex_unlock(&pAcct->mutex); + + return TSDB_CODE_SUCCESS; } -int mgmtGetQueries(SShowObj *pShow, SConnObj *pConn) { - SAcctObj * pAcct = pConn->pAcct; - SQueryShow *pQueryShow; - - pthread_mutex_lock(&pAcct->mutex); - - pQueryShow = malloc(sizeof(SQDesc) * pAcct->acctInfo.numOfQueries + sizeof(SQueryShow)); - pQueryShow->numOfQueries = 0; - pQueryShow->index = 0; - pQueryShow->connInfo = NULL; - pQueryShow->cdesc = NULL; - - if (pAcct->acctInfo.numOfQueries > 0) { - pQueryShow->connInfo = (SCDesc *)malloc(pAcct->acctInfo.numOfConns * sizeof(SCDesc)); - pQueryShow->cdesc = (SCDesc **)malloc(pAcct->acctInfo.numOfQueries * sizeof(SCDesc *)); - - pConn = pAcct->pConn; - SQDesc * pQdesc = pQueryShow->qdesc; - SCDesc * pCDesc = pQueryShow->connInfo; - SCDesc **ppCDesc = pQueryShow->cdesc; - - while (pConn) { - if (pConn->pQList && pConn->pQList->numOfQueries > 0) { - pCDesc->ip = pConn->ip; - pCDesc->port = pConn->port; - strcpy(pCDesc->user, pConn->pUser->user); - - memcpy(pQdesc, pConn->pQList->qdesc, sizeof(SQDesc) * pConn->pQList->numOfQueries); - pQdesc += pConn->pQList->numOfQueries; - pQueryShow->numOfQueries += pConn->pQList->numOfQueries; - for (int i = 0; i < pConn->pQList->numOfQueries; ++i, ++ppCDesc) *ppCDesc = pCDesc; - - pCDesc++; - } - pConn = pConn->next; - } - } - - pthread_mutex_unlock(&pAcct->mutex); - - // sorting based on useconds - - pShow->pNode = pQueryShow; +int32_t mgmtGetQueries(SShowObj *pShow, void *pConn) { +// SAcctObj * pAcct = pConn->pAcct; +// SQueryShow *pQueryShow; +// +// pthread_mutex_lock(&pAcct->mutex); +// +// pQueryShow = malloc(sizeof(SQueryDesc) * pAcct->acctInfo.numOfQueries + sizeof(SQueryShow)); +// pQueryShow->numOfQueries = 0; +// pQueryShow->index = 0; +// pQueryShow->connInfo = NULL; +// pQueryShow->cdesc = NULL; +// +// if (pAcct->acctInfo.numOfQueries > 0) { +// pQueryShow->connInfo = (SCDesc *)malloc(pAcct->acctInfo.numOfConns * sizeof(SCDesc)); +// pQueryShow->cdesc = (SCDesc **)malloc(pAcct->acctInfo.numOfQueries * sizeof(SCDesc *)); +// +// pConn = pAcct->pConn; +// SQueryDesc * pQdesc = pQueryShow->qdesc; +// SCDesc * pCDesc = pQueryShow->connInfo; +// SCDesc **ppCDesc = pQueryShow->cdesc; +// +// while (pConn) { +// if (pConn->pQList && pConn->pQList->numOfQueries > 0) { +// pCDesc->ip = pConn->ip; +// pCDesc->port = pConn->port; +// strcpy(pCDesc->user, pConn->pUser->user); +// +// memcpy(pQdesc, pConn->pQList->qdesc, sizeof(SQueryDesc) * pConn->pQList->numOfQueries); +// pQdesc += pConn->pQList->numOfQueries; +// pQueryShow->numOfQueries += pConn->pQList->numOfQueries; +// for (int32_t i = 0; i < pConn->pQList->numOfQueries; ++i, ++ppCDesc) *ppCDesc = pCDesc; +// +// pCDesc++; +// } +// pConn = pConn->next; +// } +// } +// +// pthread_mutex_unlock(&pAcct->mutex); +// +// // sorting based on useconds +// +// pShow->pNode = pQueryShow; return 0; } -int mgmtGetQueryMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { - int cols = 0; +int32_t mgmtGetQueryMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { + int32_t cols = 0; SSchema *pSchema = tsGetSchema(pMeta); @@ -156,7 +156,7 @@ int mgmtGetQueryMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { pShow->numOfColumns = cols; pShow->offset[0] = 0; - for (int i = 1; i < cols; ++i) pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; + for (int32_t i = 1; i < cols; ++i) pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; pShow->numOfRows = 1000000; pShow->pNode = NULL; @@ -166,70 +166,70 @@ int mgmtGetQueryMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return 0; } -int mgmtKillQuery(char *qidstr, SConnObj *pConn) { - char *temp, *chr, idstr[64]; - strcpy(idstr, qidstr); - - temp = idstr; - chr = strchr(temp, ':'); - if (chr == NULL) goto _error; - *chr = 0; - uint32_t ip = inet_addr(temp); - - temp = chr + 1; - chr = strchr(temp, ':'); - if (chr == NULL) goto _error; - *chr = 0; - uint16_t port = htons(atoi(temp)); - - temp = chr + 1; - uint32_t queryId = atoi(temp); - - SAcctObj *pAcct = pConn->pAcct; - - pthread_mutex_lock(&pAcct->mutex); - - pConn = pAcct->pConn; - while (pConn) { - if (pConn->ip == ip && pConn->port == port && pConn->pQList) { - int i; - SQDesc *pQDesc = pConn->pQList->qdesc; - for (i = 0; i < pConn->pQList->numOfQueries; ++i, ++pQDesc) { - if (pQDesc->queryId == queryId) break; - } - - if (i < pConn->pQList->numOfQueries) break; - } - - pConn = pConn->next; - } - - if (pConn) pConn->queryId = queryId; - - pthread_mutex_unlock(&pAcct->mutex); - - if (pConn == NULL || pConn->pQList == NULL || pConn->pQList->numOfQueries == 0) goto _error; - - mTrace("query:%s is there, kill it", qidstr); - return 0; - -_error: - mTrace("query:%s is not there", qidstr); +int32_t mgmtKillQuery(char *qidstr, void *pConn) { +// char *temp, *chr, idstr[64]; +// strcpy(idstr, qidstr); +// +// temp = idstr; +// chr = strchr(temp, ':'); +// if (chr == NULL) goto _error; +// *chr = 0; +// uint32_t ip = inet_addr(temp); +// +// temp = chr + 1; +// chr = strchr(temp, ':'); +// if (chr == NULL) goto _error; +// *chr = 0; +// uint16_t port = htons(atoi(temp)); +// +// temp = chr + 1; +// uint32_t queryId = atoi(temp); +// +// SAcctObj *pAcct = pConn->pAcct; +// +// pthread_mutex_lock(&pAcct->mutex); +// +// pConn = pAcct->pConn; +// while (pConn) { +// if (pConn->ip == ip && pConn->port == port && pConn->pQList) { +// int32_t i; +// SQueryDesc *pQDesc = pConn->pQList->qdesc; +// for (i = 0; i < pConn->pQList->numOfQueries; ++i, ++pQDesc) { +// if (pQDesc->queryId == queryId) break; +// } +// +// if (i < pConn->pQList->numOfQueries) break; +// } +// +// pConn = pConn->next; +// } +// +// if (pConn) pConn->queryId = queryId; +// +// pthread_mutex_unlock(&pAcct->mutex); +// +// if (pConn == NULL || pConn->pQList == NULL || pConn->pQList->numOfQueries == 0) goto _error; +// +// mTrace("query:%s is there, kill it", qidstr); +// return 0; +// +//_error: +// mTrace("query:%s is not there", qidstr); return TSDB_CODE_INVALID_QUERY_ID; } -int mgmtRetrieveQueries(SShowObj *pShow, char *data, int rows, SConnObj *pConn) { - int numOfRows = 0; +int32_t mgmtRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, void *pConn) { + int32_t numOfRows = 0; char *pWrite; - int cols = 0; + int32_t cols = 0; SQueryShow *pQueryShow = (SQueryShow *)pShow->pNode; if (rows > pQueryShow->numOfQueries - pQueryShow->index) rows = pQueryShow->numOfQueries - pQueryShow->index; while (numOfRows < rows) { - SQDesc *pNode = pQueryShow->qdesc + pQueryShow->index; + SQueryDesc *pNode = pQueryShow->qdesc + pQueryShow->index; SCDesc *pCDesc = pQueryShow->cdesc[pQueryShow->index]; cols = 0; @@ -269,55 +269,55 @@ int mgmtRetrieveQueries(SShowObj *pShow, char *data, int rows, SConnObj *pConn) return numOfRows; } -int mgmtGetStreams(SShowObj *pShow, SConnObj *pConn) { - SAcctObj * pAcct = pConn->pAcct; - SStreamShow *pStreamShow; - - pthread_mutex_lock(&pAcct->mutex); - - pStreamShow = malloc(sizeof(SSDesc) * pAcct->acctInfo.numOfStreams + sizeof(SQueryShow)); - pStreamShow->numOfStreams = 0; - pStreamShow->index = 0; - pStreamShow->connInfo = NULL; - pStreamShow->cdesc = NULL; - - if (pAcct->acctInfo.numOfStreams > 0) { - pStreamShow->connInfo = (SCDesc *)malloc(pAcct->acctInfo.numOfConns * sizeof(SCDesc)); - pStreamShow->cdesc = (SCDesc **)malloc(pAcct->acctInfo.numOfStreams * sizeof(SCDesc *)); - - pConn = pAcct->pConn; - SSDesc * pSdesc = pStreamShow->sdesc; - SCDesc * pCDesc = pStreamShow->connInfo; - SCDesc **ppCDesc = pStreamShow->cdesc; - - while (pConn) { - if (pConn->pSList && pConn->pSList->numOfStreams > 0) { - pCDesc->ip = pConn->ip; - pCDesc->port = pConn->port; - strcpy(pCDesc->user, pConn->pUser->user); - - memcpy(pSdesc, pConn->pSList->sdesc, sizeof(SSDesc) * pConn->pSList->numOfStreams); - pSdesc += pConn->pSList->numOfStreams; - pStreamShow->numOfStreams += pConn->pSList->numOfStreams; - for (int i = 0; i < pConn->pSList->numOfStreams; ++i, ++ppCDesc) *ppCDesc = pCDesc; - - pCDesc++; - } - pConn = pConn->next; - } - } - - pthread_mutex_unlock(&pAcct->mutex); - - // sorting based on useconds - - pShow->pNode = pStreamShow; +int32_t mgmtGetStreams(SShowObj *pShow, void *pConn) { +// SAcctObj * pAcct = pConn->pAcct; +// SStreamShow *pStreamShow; +// +// pthread_mutex_lock(&pAcct->mutex); +// +// pStreamShow = malloc(sizeof(SStreamDesc) * pAcct->acctInfo.numOfStreams + sizeof(SQueryShow)); +// pStreamShow->numOfStreams = 0; +// pStreamShow->index = 0; +// pStreamShow->connInfo = NULL; +// pStreamShow->cdesc = NULL; +// +// if (pAcct->acctInfo.numOfStreams > 0) { +// pStreamShow->connInfo = (SCDesc *)malloc(pAcct->acctInfo.numOfConns * sizeof(SCDesc)); +// pStreamShow->cdesc = (SCDesc **)malloc(pAcct->acctInfo.numOfStreams * sizeof(SCDesc *)); +// +// pConn = pAcct->pConn; +// SStreamDesc * pSdesc = pStreamShow->sdesc; +// SCDesc * pCDesc = pStreamShow->connInfo; +// SCDesc **ppCDesc = pStreamShow->cdesc; +// +// while (pConn) { +// if (pConn->pSList && pConn->pSList->numOfStreams > 0) { +// pCDesc->ip = pConn->ip; +// pCDesc->port = pConn->port; +// strcpy(pCDesc->user, pConn->pUser->user); +// +// memcpy(pSdesc, pConn->pSList->sdesc, sizeof(SStreamDesc) * pConn->pSList->numOfStreams); +// pSdesc += pConn->pSList->numOfStreams; +// pStreamShow->numOfStreams += pConn->pSList->numOfStreams; +// for (int32_t i = 0; i < pConn->pSList->numOfStreams; ++i, ++ppCDesc) *ppCDesc = pCDesc; +// +// pCDesc++; +// } +// pConn = pConn->next; +// } +// } +// +// pthread_mutex_unlock(&pAcct->mutex); +// +// // sorting based on useconds +// +// pShow->pNode = pStreamShow; return 0; } -int mgmtGetStreamMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { - int cols = 0; +int32_t mgmtGetStreamMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { + int32_t cols = 0; SSchema *pSchema = tsGetSchema(pMeta); pShow->bytes[cols] = TSDB_USER_LEN; @@ -366,7 +366,7 @@ int mgmtGetStreamMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { pShow->numOfColumns = cols; pShow->offset[0] = 0; - for (int i = 1; i < cols; ++i) pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; + for (int32_t i = 1; i < cols; ++i) pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; pShow->numOfRows = 1000000; pShow->pNode = NULL; @@ -376,17 +376,17 @@ int mgmtGetStreamMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return 0; } -int mgmtRetrieveStreams(SShowObj *pShow, char *data, int rows, SConnObj *pConn) { - int numOfRows = 0; +int32_t mgmtRetrieveStreams(SShowObj *pShow, char *data, int32_t rows, void *pConn) { + int32_t numOfRows = 0; char *pWrite; - int cols = 0; + int32_t cols = 0; SStreamShow *pStreamShow = (SStreamShow *)pShow->pNode; if (rows > pStreamShow->numOfStreams - pStreamShow->index) rows = pStreamShow->numOfStreams - pStreamShow->index; while (numOfRows < rows) { - SSDesc *pNode = pStreamShow->sdesc + pStreamShow->index; + SStreamDesc *pNode = pStreamShow->sdesc + pStreamShow->index; SCDesc *pCDesc = pStreamShow->cdesc[pStreamShow->index]; cols = 0; @@ -434,101 +434,101 @@ int mgmtRetrieveStreams(SShowObj *pShow, char *data, int rows, SConnObj *pConn) return numOfRows; } -int mgmtKillStream(char *qidstr, SConnObj *pConn) { - char *temp, *chr, idstr[64]; - strcpy(idstr, qidstr); - - temp = idstr; - chr = strchr(temp, ':'); - if (chr == NULL) goto _error; - *chr = 0; - uint32_t ip = inet_addr(temp); - - temp = chr + 1; - chr = strchr(temp, ':'); - if (chr == NULL) goto _error; - *chr = 0; - uint16_t port = htons(atoi(temp)); - - temp = chr + 1; - uint32_t streamId = atoi(temp); - - SAcctObj *pAcct = pConn->pAcct; - - pthread_mutex_lock(&pAcct->mutex); - - pConn = pAcct->pConn; - while (pConn) { - if (pConn->ip == ip && pConn->port == port && pConn->pSList) { - int i; - SSDesc *pSDesc = pConn->pSList->sdesc; - for (i = 0; i < pConn->pSList->numOfStreams; ++i, ++pSDesc) { - if (pSDesc->streamId == streamId) break; - } - - if (i < pConn->pSList->numOfStreams) break; - } - - pConn = pConn->next; - } - - if (pConn) pConn->streamId = streamId; - - pthread_mutex_unlock(&pAcct->mutex); - - if (pConn == NULL || pConn->pSList == NULL || pConn->pSList->numOfStreams == 0) goto _error; - - mTrace("stream:%s is there, kill it", qidstr); - return 0; - -_error: - mTrace("stream:%s is not there", qidstr); +int32_t mgmtKillStream(char *qidstr, void *pConn) { +// char *temp, *chr, idstr[64]; +// strcpy(idstr, qidstr); +// +// temp = idstr; +// chr = strchr(temp, ':'); +// if (chr == NULL) goto _error; +// *chr = 0; +// uint32_t ip = inet_addr(temp); +// +// temp = chr + 1; +// chr = strchr(temp, ':'); +// if (chr == NULL) goto _error; +// *chr = 0; +// uint16_t port = htons(atoi(temp)); +// +// temp = chr + 1; +// uint32_t streamId = atoi(temp); +// +// SAcctObj *pAcct = pConn->pAcct; +// +// pthread_mutex_lock(&pAcct->mutex); +// +// pConn = pAcct->pConn; +// while (pConn) { +// if (pConn->ip == ip && pConn->port == port && pConn->pSList) { +// int32_t i; +// SStreamDesc *pSDesc = pConn->pSList->sdesc; +// for (i = 0; i < pConn->pSList->numOfStreams; ++i, ++pSDesc) { +// if (pSDesc->streamId == streamId) break; +// } +// +// if (i < pConn->pSList->numOfStreams) break; +// } +// +// pConn = pConn->next; +// } +// +// if (pConn) pConn->streamId = streamId; +// +// pthread_mutex_unlock(&pAcct->mutex); +// +// if (pConn == NULL || pConn->pSList == NULL || pConn->pSList->numOfStreams == 0) goto _error; +// +// mTrace("stream:%s is there, kill it", qidstr); +// return 0; +// +//_error: +// mTrace("stream:%s is not there", qidstr); return TSDB_CODE_INVALID_STREAM_ID; } -int mgmtKillConnection(char *qidstr, SConnObj *pConn) { - SConnObj *pConn1 = NULL; - char * temp, *chr, idstr[64]; - strcpy(idstr, qidstr); - - temp = idstr; - chr = strchr(temp, ':'); - if (chr == NULL) goto _error; - *chr = 0; - uint32_t ip = inet_addr(temp); - - temp = chr + 1; - uint16_t port = htons(atoi(temp)); - SAcctObj *pAcct = pConn->pAcct; - - pthread_mutex_lock(&pAcct->mutex); - - pConn = pAcct->pConn; - while (pConn) { - if (pConn->ip == ip && pConn->port == port) { - // there maybe two connections from a shell - if (pConn1 == NULL) - pConn1 = pConn; - else - break; - } - - pConn = pConn->next; - } - - if (pConn1) pConn1->killConnection = 1; - if (pConn) pConn->killConnection = 1; - - pthread_mutex_unlock(&pAcct->mutex); - - if (pConn1 == NULL) goto _error; - - mTrace("connection:%s is there, kill it", qidstr); - return 0; - -_error: - mTrace("connection:%s is not there", qidstr); +int32_t mgmtKillConnection(char *qidstr, void *pConn) { +// void *pConn1 = NULL; +// char * temp, *chr, idstr[64]; +// strcpy(idstr, qidstr); +// +// temp = idstr; +// chr = strchr(temp, ':'); +// if (chr == NULL) goto _error; +// *chr = 0; +// uint32_t ip = inet_addr(temp); +// +// temp = chr + 1; +// uint16_t port = htons(atoi(temp)); +// SAcctObj *pAcct = pConn->pAcct; +// +// pthread_mutex_lock(&pAcct->mutex); +// +// pConn = pAcct->pConn; +// while (pConn) { +// if (pConn->ip == ip && pConn->port == port) { +// // there maybe two connections from a shell +// if (pConn1 == NULL) +// pConn1 = pConn; +// else +// break; +// } +// +// pConn = pConn->next; +// } +// +// if (pConn1) pConn1->killConnection = 1; +// if (pConn) pConn->killConnection = 1; +// +// pthread_mutex_unlock(&pAcct->mutex); +// +// if (pConn1 == NULL) goto _error; +// +// mTrace("connection:%s is there, kill it", qidstr); +// return 0; +// +//_error: +// mTrace("connection:%s is not there", qidstr); return TSDB_CODE_INVALID_CONNECTION; } diff --git a/src/mnode/src/mgmtShell.c b/src/mnode/src/mgmtShell.c index 1ddf6500ee6a5f3f9892915b9fa7129a901b03b5..598ec600db73452549a880076eb286dce00d1390 100644 --- a/src/mnode/src/mgmtShell.c +++ b/src/mnode/src/mgmtShell.c @@ -15,87 +15,92 @@ #define _DEFAULT_SOURCE #include "os.h" - +#include "taosmsg.h" +#include "tlog.h" +#include "trpc.h" +#include "tstatus.h" +#include "tsched.h" #include "dnodeSystem.h" #include "mnode.h" #include "mgmtAcct.h" #include "mgmtBalance.h" +#include "mgmtChildTable.h" #include "mgmtConn.h" #include "mgmtDb.h" #include "mgmtDnode.h" +#include "mgmtDnodeInt.h" #include "mgmtGrant.h" #include "mgmtMnode.h" +#include "mgmtNormalTable.h" #include "mgmtProfile.h" #include "mgmtShell.h" +#include "mgmtSuperTable.h" #include "mgmtTable.h" #include "mgmtUser.h" #include "mgmtVgroup.h" -#include "taosmsg.h" -#include "tlog.h" -#include "tstatus.h" -#include "tsched.h" -#include "trpc.h" -#define MAX_LEN_OF_METER_META (sizeof(SMultiMeterMeta) + sizeof(SSchema) * TSDB_MAX_COLUMNS + sizeof(SSchema) * TSDB_MAX_TAGS + TSDB_MAX_TAGS_LEN) +typedef int32_t (*GetMateFp)(STableMeta *pMeta, SShowObj *pShow, void *pConn); +typedef int32_t (*RetrieveMetaFp)(SShowObj *pShow, char *data, int32_t rows, void *pConn); +static GetMateFp mgmtGetMetaFp[TSDB_MGMT_TABLE_MAX] = {0}; +static RetrieveMetaFp mgmtRetrieveFp[TSDB_MGMT_TABLE_MAX] = {0}; -typedef int32_t (*GetMateFp)(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn); -typedef int32_t (*RetrieveMetaFp)(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn); -static GetMateFp* mgmtGetMetaFp; -static RetrieveMetaFp* mgmtRetrieveFp; static void mgmtInitShowMsgFp(); +static void mgmtInitProcessShellMsg(); +static void mgmtProcessMsgFromShell(char type, void *pCont, int contLen, void *ahandle, int32_t code); +static void (*mgmtProcessShellMsg[TSDB_MSG_TYPE_MAX])(void *pCont, int32_t contLen, void *ahandle); +static void mgmtProcessUnSupportMsg(void *pCont, int32_t contLen, void *ahandle); +static int mgmtRetriveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey); + +void *tsShellConnServer = NULL; + +void mgmtProcessTranRequest(SSchedMsg *sched) { + int8_t msgType = *(int8_t *) (sched->msg); + int32_t contLen = *(int32_t *) (sched->msg + sizeof(int8_t)); + int8_t *pCont = sched->msg + sizeof(int32_t) + sizeof(int8_t); + void *pConn = sched->thandle; + + (*mgmtProcessShellMsg[msgType])(pCont, contLen, pConn); + if (sched->msg) { + free(sched->msg); + } +} -void * tsShellConn = NULL; -SConnObj *connList; -void mgmtProcessMsgFromShell(char type, void *pCont, int contLen, void *ahandle, int32_t code); -int mgmtRetriveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey); -int (*mgmtProcessShellMsg[TSDB_MSG_TYPE_MAX])(char *, int, SConnObj *); -void mgmtInitProcessShellMsg(); -int mgmtRedirectMsg(SConnObj *pConn, int msgType); -int mgmtKillQuery(char *queryId, SConnObj *pConn); - -void mgmtProcessTranRequest(SSchedMsg *pSchedMsg) { - SIntMsg * pMsg = (SIntMsg *)(pSchedMsg->msg); - SConnObj *pConn = (SConnObj *)(pSchedMsg->thandle); - - char *cont = (char *)pMsg->content + sizeof(SMgmtHead); - int contLen = pMsg->msgLen - sizeof(SIntMsg) - sizeof(SMgmtHead); - - if (pConn->pAcct) (*mgmtProcessShellMsg[pMsg->msgType])(cont, contLen, pConn); - - if (pSchedMsg->msg) free(pSchedMsg->msg); +void mgmtAddToTranRequest(int8_t type, void *pCont, int contLen, void *ahandle) { + SSchedMsg schedMsg; + schedMsg.msg = malloc(contLen + sizeof(int32_t) + sizeof(int8_t)); + schedMsg.fp = mgmtProcessTranRequest; + schedMsg.tfp = NULL; + schedMsg.thandle = ahandle; + *(int8_t *) (schedMsg.msg) = type; + *(int32_t *) (schedMsg.msg + sizeof(int8_t)) = contLen; + memcpy(schedMsg.msg + sizeof(int32_t) + sizeof(int8_t), pCont, contLen); + + taosScheduleTask(tsMgmtTranQhandle, &schedMsg); } -int mgmtInitShell() { +int32_t mgmtInitShell() { SRpcInit rpcInit; - mgmtInitProcessShellMsg(); mgmtInitShowMsgFp(); - int size = sizeof(SConnObj) * tsMaxShellConns; - connList = (SConnObj *)malloc(size); - if (connList == NULL) { - mError("failed to malloc for connList to shell"); - return -1; + int32_t numOfThreads = tsNumOfCores * tsNumOfThreadsPerCore / 4.0; + if (numOfThreads < 1) { + numOfThreads = 1; } - memset(connList, 0, size); - - int numOfThreads = tsNumOfCores * tsNumOfThreadsPerCore / 4.0; - if (numOfThreads < 1) numOfThreads = 1; memset(&rpcInit, 0, sizeof(rpcInit)); - - rpcInit.localIp = tsAnyIp ? "0.0.0.0" : tsPrivateIp;; - rpcInit.localPort = tsMgmtShellPort; - rpcInit.label = "MND-shell"; + rpcInit.localIp = tsAnyIp ? "0.0.0.0" : tsPrivateIp; + rpcInit.localPort = tsMgmtShellPort; + rpcInit.label = "MND-shell"; rpcInit.numOfThreads = numOfThreads; - rpcInit.cfp = mgmtProcessMsgFromShell; - rpcInit.sessions = tsMaxShellConns; - rpcInit.connType = TAOS_CONN_SOCKET_TYPE_S(); - rpcInit.idleTime = tsShellActivityTimer * 2000; - rpcInit.afp = mgmtRetriveUserAuthInfo; - - tsShellConn = rpcOpen(&rpcInit); - if (tsShellConn == NULL) { + rpcInit.cfp = mgmtProcessMsgFromShell; + rpcInit.sessions = tsMaxShellConns; + rpcInit.connType = TAOS_CONN_SERVER; + rpcInit.idleTime = tsShellActivityTimer * 2000; + rpcInit.afp = mgmtRetriveUserAuthInfo; + + tsShellConnServer = rpcOpen(&rpcInit); + if (tsShellConnServer == NULL) { mError("failed to init tcp connection to shell"); return -1; } @@ -104,1487 +109,1095 @@ int mgmtInitShell() { } void mgmtCleanUpShell() { - if (tsShellConn) { - rpcClose(tsShellConn); - tsShellConn = NULL; + if (tsShellConnServer) { + rpcClose(tsShellConnServer); + tsShellConnServer = NULL; } - tfree(connList); } -static void mgmtSetSchemaFromMeters(SSchema *pSchema, STabObj *pMeterObj, uint32_t numOfCols) { - SSchema *pMeterSchema = (SSchema *)(pMeterObj->schema); - for (int i = 0; i < numOfCols; ++i) { - pSchema->type = pMeterSchema[i].type; - strcpy(pSchema->name, pMeterSchema[i].name); - pSchema->bytes = htons(pMeterSchema[i].bytes); - pSchema->colId = htons(pMeterSchema[i].colId); - pSchema++; +void mgmtProcessTableMetaMsg(void *pCont, int32_t contLen, void *ahandle) { + STableInfoMsg *pInfo = pCont; + pInfo->createFlag = htons(pInfo->createFlag); + + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + mError("table:%s, failed to get table meta, invalid user", pInfo->tableId); + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + STableInfo *pTable = mgmtGetTable(pInfo->tableId); + if (pTable == NULL) { + if (pInfo->createFlag != 1) { + mError("table:%s, failed to get table meta, table not exist", pInfo->tableId); + rpcSendResponse(ahandle, TSDB_CODE_INVALID_TABLE, NULL, 0); + return; + } else { + // on demand create table from super table if table does not exists + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + mError("table:%s, failed to create table while get meta info, need redirect message", pInfo->tableId); + return; + } + + SCreateTableMsg *pCreateMsg = rpcMallocCont(sizeof(SCreateTableMsg) + sizeof(STagData)); + if (pCreateMsg == NULL) { + mError("table:%s, failed to create table while get meta info, no enough memory", pInfo->tableId); + rpcSendResponse(ahandle, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); + return; + } + + memcpy(pCreateMsg->schema, pInfo->tags, sizeof(STagData)); + strcpy(pCreateMsg->tableId, pInfo->tableId); + + mError("table:%s, start to create table while get meta info", pInfo->tableId); + mgmtCreateTable(pCreateMsg, contLen, ahandle, true); + } + } else { + mgmtProcessGetTableMeta(pTable, ahandle); } } -static uint32_t mgmtSetMeterTagValue(char *pTags, STabObj *pMetric, STabObj *pMeterObj) { - SSchema *pTagSchema = (SSchema *)(pMetric->schema + pMetric->numOfColumns * sizeof(SSchema)); +void mgmtProcessMultiTableMetaMsg(void *pCont, int32_t contLen, void *ahandle) { + SRpcConnInfo connInfo; + rpcGetConnInfo(ahandle, &connInfo); + + bool usePublicIp = (connInfo.serverIp == tsPublicIpInt); + SUserObj *pUser = mgmtGetUser(connInfo.user); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } - char *tagVal = pMeterObj->pTagData + TSDB_TABLE_ID_LEN; // tag start position + SMultiTableInfoMsg *pInfo = pCont; + pInfo->numOfTables = htonl(pInfo->numOfTables); - uint32_t tagsLen = 0; - for (int32_t i = 0; i < pMetric->numOfTags; ++i) { - tagsLen += pTagSchema[i].bytes; + int32_t totalMallocLen = 4*1024*1024; // first malloc 4 MB, subsequent reallocation as twice + SMultiTableMeta *pMultiMeta = rpcMallocCont(totalMallocLen); + if (pMultiMeta == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); + return; } - memcpy(pTags, tagVal, tagsLen); - return tagsLen; + pMultiMeta->contLen = sizeof(SMultiTableMeta); + pMultiMeta->numOfTables = 0; + + for (int t = 0; t < pInfo->numOfTables; ++t) { + char *tableId = (char*)(pInfo->tableIds + t * TSDB_TABLE_ID_LEN); + STableInfo *pTable = mgmtGetTable(tableId); + if (pTable == NULL) continue; + + SDbObj *pDb = mgmtGetDbByTableId(tableId); + if (pDb == NULL) continue; + + int availLen = totalMallocLen - pMultiMeta->contLen; + if (availLen <= sizeof(STableMeta) + sizeof(SSchema) * TSDB_MAX_COLUMNS) { + //TODO realloc + //totalMallocLen *= 2; + //pMultiMeta = rpcReMalloc(pMultiMeta, totalMallocLen); + //if (pMultiMeta == NULL) { + /// rpcSendResponse(ahandle, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); + // return TSDB_CODE_SERV_OUT_OF_MEMORY; + //} else { + // t--; + // continue; + //} + } + + STableMeta *pMeta = (STableMeta *)(pMultiMeta->metas + pMultiMeta->contLen); + int32_t code = mgmtGetTableMeta(pDb, pTable, pMeta, usePublicIp); + if (code == TSDB_CODE_SUCCESS) { + pMultiMeta->numOfTables ++; + pMultiMeta->contLen += pMeta->contLen; + } + } + + rpcSendResponse(ahandle, TSDB_CODE_SUCCESS, pMultiMeta, pMultiMeta->contLen); } -//static char *mgmtAllocMsg(SConnObj *pConn, int32_t size, char **pMsg, STaosRsp **pRsp) { -// char *pStart = taosBuildRspMsgWithSize(pConn->thandle, TSDB_MSG_TYPE_TABLE_META_RSP, size); -// if (pStart == NULL) return 0; -// *pMsg = pStart; -// *pRsp = (STaosRsp *)(*pMsg); -// -// return pStart; -// return 0; -//} - -//static char *mgmtForMultiAllocMsg(SConnObj *pConn, int32_t size, char **pMsg, STaosRsp **pRsp) { -// char *pStart = taosBuildRspMsgWithSize(pConn->thandle, TSDB_MSG_TYPE_MULTI_TABLE_META_RSP, size); -// if (pStart == NULL) return 0; -// *pMsg = pStart; -// *pRsp = (STaosRsp *)(*pMsg); -// -// return pStart; -// return 0; -//} +void mgmtProcessSuperTableMetaMsg(void *pCont, int32_t contLen, void *ahandle) { + SRpcConnInfo connInfo; + rpcGetConnInfo(ahandle, &connInfo); -/** - * check if we need to add mgmtProcessMeterMetaMsg into tranQueue, which will be executed one-by-one. - * - * @param pMsg - * @return - */ -bool mgmtCheckMeterMetaMsgType(char *pMsg) { -// SMeterInfoMsg *pInfo = (SMeterInfoMsg *)pMsg; -// -// int16_t autoCreate = htons(pInfo->createFlag); -// STableInfo *table = mgmtGetTable(pInfo->meterId); - -// If table does not exists and autoCreate flag is set, we add the handler into another task queue, namely tranQueue -// bool addIntoTranQueue = (pMeterObj == NULL && autoCreate == 1); -// if (addIntoTranQueue) { -// mTrace("meter:%s auto created task added", pInfo->meterId); -// } +// bool usePublicIp = (connInfo.serverIp == tsPublicIpInt); -// bool addIntoTranQueue = true; + SSuperTableInfoMsg *pInfo = pCont; + STableInfo *pTable = mgmtGetSuperTable(pInfo->tableId); + if (pTable == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_TABLE, NULL, 0); + return; + } -// return addIntoTranQueue; - return 0; + SSuperTableInfoRsp *pRsp = mgmtGetSuperTableVgroup((SSuperTableObj *) pTable); + if (pRsp != NULL) { + int32_t msgLen = sizeof(SSuperTableObj) + htonl(pRsp->numOfDnodes) * sizeof(int32_t); + rpcSendResponse(ahandle, TSDB_CODE_SUCCESS, pRsp, msgLen); + } else { + rpcSendResponse(ahandle, TSDB_CODE_SUCCESS, NULL, 0); + } } -int mgmtProcessMeterMetaMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SMeterInfoMsg *pInfo = (SMeterInfoMsg *)pMsg; -// STabObj * pMeterObj = NULL; -// SVgObj * pVgroup = NULL; -// SMeterMeta * pMeta = NULL; -// SSchema * pSchema = NULL; -// STaosRsp * pRsp = NULL; -// char * pStart = NULL; -// -// pInfo->createFlag = htons(pInfo->createFlag); -// -// int size = sizeof(STaosHeader) + sizeof(STaosRsp) + sizeof(SMeterMeta) + sizeof(SSchema) * TSDB_MAX_COLUMNS + -// sizeof(SSchema) * TSDB_MAX_TAGS + TSDB_MAX_TAGS_LEN + TSDB_EXTRA_PAYLOAD_SIZE; -// -// SDbObj *pDb = NULL; -// if (pConn->pDb != NULL) pDb = mgmtGetDb(pConn->pDb->name); -// -// // todo db check should be extracted -// if (pDb == NULL || (pDb != NULL && pDb->dropStatus != TSDB_DB_STATUS_READY)) { -// -// if ((pStart = mgmtAllocMsg(pConn, size, &pMsg, &pRsp)) == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_TABLE_META_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// -// pRsp->code = TSDB_CODE_INVALID_DB; -// pMsg++; -// -// goto _exit_code; -// } -// -// pMeterObj = mgmtGetTable(pInfo->meterId); -// -// // on demand create table from super table if meter does not exists -// if (pMeterObj == NULL && pInfo->createFlag == 1) { -// // write operation needs to redirect to master mnode -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_TABLE_META_RSP) != 0) { -// return 0; -// } -// -// SCreateTableMsg *pCreateMsg = calloc(1, sizeof(SCreateTableMsg) + sizeof(STagData)); -// if (pCreateMsg == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_TABLE_META_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// -// memcpy(pCreateMsg->schema, pInfo->tags, sizeof(STagData)); -// strcpy(pCreateMsg->meterId, pInfo->meterId); -// -// SDbObj* pMeterDb = mgmtGetDbByTableId(pCreateMsg->meterId); -// mTrace("meter:%s, pConnDb:%p, pConnDbName:%s, pMeterDb:%p, pMeterDbName:%s", -// pCreateMsg->meterId, pDb, pDb->name, pMeterDb, pMeterDb->name); -// assert(pDb == pMeterDb); -// -// int32_t code = mgmtCreateTable(pDb, pCreateMsg); -// -// char stableName[TSDB_TABLE_ID_LEN] = {0}; -// strncpy(stableName, pInfo->tags, TSDB_TABLE_ID_LEN); -// mTrace("meter:%s is automatically created by %s from %s, code:%d", pCreateMsg->meterId, pConn->pUser->user, -// stableName, code); -// -// tfree(pCreateMsg); -// -// if (code != TSDB_CODE_SUCCESS) { -// if ((pStart = mgmtAllocMsg(pConn, size, &pMsg, &pRsp)) == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_TABLE_META_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// -// pRsp->code = code; -// pMsg++; -// -// goto _exit_code; -// } -// -// pMeterObj = mgmtGetTable(pInfo->meterId); -// } -// -// if ((pStart = mgmtAllocMsg(pConn, size, &pMsg, &pRsp)) == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_TABLE_META_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// -// if (pMeterObj == NULL) { -// if (pDb) -// pRsp->code = TSDB_CODE_INVALID_TABLE; -// else -// pRsp->code = TSDB_CODE_DB_NOT_SELECTED; -// pMsg++; -// } else { -// mTrace("%s, uid:%" PRIu64 " meter meta is retrieved", pInfo->meterId, pMeterObj->uid); -// pRsp->code = 0; -// pMsg += sizeof(STaosRsp); -// *pMsg = TSDB_IE_TYPE_META; -// pMsg++; -// -// pMeta = (SMeterMeta *)pMsg; -// pMeta->uid = htobe64(pMeterObj->uid); -// pMeta->sid = htonl(pMeterObj->gid.sid); -// pMeta->vgid = htonl(pMeterObj->gid.vgId); -// pMeta->sversion = htons(pMeterObj->sversion); -// -// pMeta->precision = pDb->cfg.precision; -// -// pMeta->numOfTags = pMeterObj->numOfTags; -// pMeta->numOfColumns = htons(pMeterObj->numOfColumns); -// pMeta->tableType = pMeterObj->tableType; -// -// pMsg += sizeof(SMeterMeta); -// pSchema = (SSchema *)pMsg; // schema locates at the end of SMeterMeta struct -// -// if (mgmtTableCreateFromSuperTable(pMeterObj)) { -// assert(pMeterObj->numOfTags == 0); -// -// STabObj *pMetric = mgmtGetTable(pMeterObj->pTagData); -// uint32_t numOfTotalCols = (uint32_t)pMetric->numOfTags + pMetric->numOfColumns; -// -// pMeta->numOfTags = pMetric->numOfTags; // update the numOfTags info -// mgmtSetSchemaFromMeters(pSchema, pMetric, numOfTotalCols); -// pMsg += numOfTotalCols * sizeof(SSchema); -// -// // for meters created from metric, we need the metric tag schema to parse the tag data -// int32_t tagsLen = mgmtSetMeterTagValue(pMsg, pMetric, pMeterObj); -// pMsg += tagsLen; -// } else { -// /* -// * for metrics, or meters that are not created from metric, set the schema directly -// * for meters created from metric, we use the schema of metric instead -// */ -// uint32_t numOfTotalCols = (uint32_t)pMeterObj->numOfTags + pMeterObj->numOfColumns; -// mgmtSetSchemaFromMeters(pSchema, pMeterObj, numOfTotalCols); -// pMsg += numOfTotalCols * sizeof(SSchema); -// } -// -// if (mgmtIsNormalTable(pMeterObj)) { -// pVgroup = mgmtGetVgroup(pMeterObj->gid.vgId); -// if (pVgroup == NULL) { -// pRsp->code = TSDB_CODE_INVALID_TABLE; -// goto _exit_code; -// } -// for (int i = 0; i < TSDB_VNODES_SUPPORT; ++i) { -// if (pConn->usePublicIp) { -// pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].publicIp; -// pMeta->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); -// } else { -// pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].ip; -// pMeta->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); -// } -// } -// } -// } -// -//_exit_code: -// msgLen = pMsg - pStart; -// -// taosSendMsgToPeer(pConn->thandle, pStart, msgLen); -// -// return msgLen; - return 0; -} +void mgmtProcessCreateDbMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } -/** - * multi meter meta rsp pkg format: - * | STaosRsp | ieType | SMultiMeterInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2 - * 1B 1B 4B - * - * | STaosHeader | STaosRsp | ieType | SMultiMeterInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | ......................| - * ^ ^ ^ - * |<--------------------------------------size-----------------------------------------------|---------------------->| - * | | | - * pStart pCurMeter pTail - **/ -int mgmtProcessMultiMeterMetaMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SDbObj * pDbObj = NULL; -// STabObj * pMeterObj = NULL; -// SVgObj * pVgroup = NULL; -// SMultiMeterMeta * pMeta = NULL; -// SSchema * pSchema = NULL; -// STaosRsp * pRsp = NULL; -// char * pStart = NULL; -// -// SMultiMeterInfoMsg * pInfo = (SMultiMeterInfoMsg *)pMsg; -// char * str = pMsg + sizeof(SMultiMeterInfoMsg); -// pInfo->numOfMeters = htonl(pInfo->numOfMeters); -// -// int size = 4*1024*1024; // first malloc 4 MB, subsequent reallocation as twice -// -// char *pNewMsg; -// if ((pStart = mgmtForMultiAllocMsg(pConn, size, &pNewMsg, &pRsp)) == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_MULTI_TABLE_META_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// -// int32_t totalNum = 0; -// char tblName[TSDB_TABLE_ID_LEN]; -// char* nextStr; -// -// char* pCurMeter = pStart + sizeof(STaosRsp) + sizeof(SMultiMeterInfoMsg) + 1; // 1: ie type byte -// char* pTail = pStart + size; -// -// while (str - pMsg < msgLen) { -// nextStr = strchr(str, ','); -// if (nextStr == NULL) { -// break; -// } -// -// memcpy(tblName, str, nextStr - str); -// tblName[nextStr - str] = '\0'; -// str = nextStr + 1; -// -// // judge whether the remaining memory is adequate -// if ((pTail - pCurMeter) < MAX_LEN_OF_METER_META) { -// char* pMsgHdr = pStart - sizeof(STaosHeader); -// size *= 2; -// pMsgHdr = (char*)realloc(pMsgHdr, size); -// if (NULL == pMsgHdr) { -// char* pTmp = pStart - sizeof(STaosHeader); -// tfree(pTmp); -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_MULTI_TABLE_META_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// break; -// } -// -// pCurMeter = (char*)pMsgHdr + sizeof(STaosHeader) + (pCurMeter - pStart); -// pStart = (char*)pMsgHdr + sizeof(STaosHeader); -// pNewMsg = pStart; -// pRsp = (STaosRsp *)pStart; -// pTail = pMsgHdr + size; -// } -// -// // get meter schema, and fill into resp payload -// pMeterObj = mgmtGetTable(tblName); -// pDbObj = mgmtGetDbByTableId(tblName); -// -// if (pMeterObj == NULL || (pDbObj == NULL)) { -// continue; -// } else { -// mTrace("%s, uid:%" PRIu64 " sversion:%d meter meta is retrieved", tblName, pMeterObj->uid, pMeterObj->sversion); -// pMeta = (SMultiMeterMeta *)pCurMeter; -// -// memcpy(pMeta->meterId, tblName, strlen(tblName)); -// pMeta->meta.uid = htobe64(pMeterObj->uid); -// pMeta->meta.sid = htonl(pMeterObj->gid.sid); -// pMeta->meta.vgid = htonl(pMeterObj->gid.vgId); -// pMeta->meta.sversion = htons(pMeterObj->sversion); -// pMeta->meta.precision = pDbObj->cfg.precision; -// pMeta->meta.numOfTags = pMeterObj->numOfTags; -// pMeta->meta.numOfColumns = htons(pMeterObj->numOfColumns); -// pMeta->meta.tableType = pMeterObj->tableType; -// -// pCurMeter += sizeof(SMultiMeterMeta); -// pSchema = (SSchema *)pCurMeter; // schema locates at the end of SMeterMeta struct -// -// if (mgmtTableCreateFromSuperTable(pMeterObj)) { -// assert(pMeterObj->numOfTags == 0); -// -// STabObj *pMetric = mgmtGetTable(pMeterObj->pTagData); -// uint32_t numOfTotalCols = (uint32_t)pMetric->numOfTags + pMetric->numOfColumns; -// -// pMeta->meta.numOfTags = pMetric->numOfTags; // update the numOfTags info -// mgmtSetSchemaFromMeters(pSchema, pMetric, numOfTotalCols); -// pCurMeter += numOfTotalCols * sizeof(SSchema); -// -// // for meters created from metric, we need the metric tag schema to parse the tag data -// int32_t tagsLen = mgmtSetMeterTagValue(pCurMeter, pMetric, pMeterObj); -// pCurMeter += tagsLen; -// } else { -// /* -// * for metrics, or meters that are not created from metric, set the schema directly -// * for meters created from metric, we use the schema of metric instead -// */ -// uint32_t numOfTotalCols = (uint32_t)pMeterObj->numOfTags + pMeterObj->numOfColumns; -// mgmtSetSchemaFromMeters(pSchema, pMeterObj, numOfTotalCols); -// pCurMeter += numOfTotalCols * sizeof(SSchema); -// } -// -// if (mgmtIsNormalTable(pMeterObj)) { -// pVgroup = mgmtGetVgroup(pMeterObj->gid.vgId); -// if (pVgroup == NULL) { -// pRsp->code = TSDB_CODE_INVALID_TABLE; -// pNewMsg++; -// mError("%s, uid:%" PRIu64 " sversion:%d vgId:%d pVgroup is NULL", tblName, pMeterObj->uid, pMeterObj->sversion, -// pMeterObj->gid.vgId); -// goto _error_exit_code; -// } -// -// for (int i = 0; i < TSDB_VNODES_SUPPORT; ++i) { -// if (pConn->usePublicIp) { -// pMeta->meta.vpeerDesc[i].ip = pVgroup->vnodeGid[i].publicIp; -// pMeta->meta.vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); -// } else { -// pMeta->meta.vpeerDesc[i].ip = pVgroup->vnodeGid[i].ip; -// pMeta->meta.vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); -// } -// } -// } -// } -// -// totalNum++; -// if (totalNum > pInfo->numOfMeters) { -// pNewMsg++; -// break; -// } -// } -// -// // fill rsp code, ieType -// msgLen = pCurMeter - pNewMsg; -// -// pRsp->code = 0; -// pNewMsg += sizeof(STaosRsp); -// *pNewMsg = TSDB_IE_TYPE_META; -// pNewMsg++; -// -// SMultiMeterInfoMsg *pRspInfo = (SMultiMeterInfoMsg *)pNewMsg; -// -// pRspInfo->numOfMeters = htonl(totalNum); -// goto _exit_code; -// -//_error_exit_code: -// msgLen = pNewMsg - pStart; -// -//_exit_code: -// taosSendMsgToPeer(pConn->thandle, pStart, msgLen); -// -// return msgLen; - return 0; -} + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } -int mgmtProcessMetricMetaMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SSuperTableMetaMsg *pSuperTableMetaMsg = (SSuperTableMetaMsg *)pMsg; -// STabObj * pMetric; -// STaosRsp * pRsp; -// char * pStart; -// -// pSuperTableMetaMsg->numOfMeters = htonl(pSuperTableMetaMsg->numOfMeters); -// -// pSuperTableMetaMsg->join = htonl(pSuperTableMetaMsg->join); -// pSuperTableMetaMsg->joinCondLen = htonl(pSuperTableMetaMsg->joinCondLen); -// -// for (int32_t i = 0; i < pSuperTableMetaMsg->numOfMeters; ++i) { -// pSuperTableMetaMsg->metaElem[i] = htonl(pSuperTableMetaMsg->metaElem[i]); -// } -// -// SMetricMetaElemMsg *pElem = (SMetricMetaElemMsg *)(((char *)pSuperTableMetaMsg) + pSuperTableMetaMsg->metaElem[0]); -// pMetric = mgmtGetTable(pElem->meterId); -// -// SDbObj *pDb = NULL; -// if (pConn->pDb != NULL) pDb = mgmtGetDb(pConn->pDb->name); -// -// if (pMetric == NULL || (pDb != NULL && pDb->dropStatus != TSDB_DB_STATUS_READY)) { -// pStart = taosBuildRspMsg(pConn->thandle, TSDB_MSG_TYPE_STABLE_META_RSP); -// if (pStart == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_STABLE_META_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// -// pMsg = pStart; -// pRsp = (STaosRsp *)pMsg; -// if (pDb) -// pRsp->code = TSDB_CODE_INVALID_TABLE; -// else -// pRsp->code = TSDB_CODE_DB_NOT_SELECTED; -// pMsg++; -// -// msgLen = pMsg - pStart; -// } else { -// msgLen = mgmtRetrieveMetricMeta(pConn, &pStart, pSuperTableMetaMsg); -// if (msgLen <= 0) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_STABLE_META_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// } -// -// taosSendMsgToPeer(pConn->thandle, pStart, msgLen); -// -// return msgLen; - return 0; + SCreateDbMsg *pCreate = (SCreateDbMsg *) pCont; + + pCreate->maxSessions = htonl(pCreate->maxSessions); + pCreate->cacheBlockSize = htonl(pCreate->cacheBlockSize); + pCreate->daysPerFile = htonl(pCreate->daysPerFile); + pCreate->daysToKeep = htonl(pCreate->daysToKeep); + pCreate->daysToKeep1 = htonl(pCreate->daysToKeep1); + pCreate->daysToKeep2 = htonl(pCreate->daysToKeep2); + pCreate->commitTime = htonl(pCreate->commitTime); + pCreate->blocksPerTable = htons(pCreate->blocksPerTable); + pCreate->rowsInFileBlock = htonl(pCreate->rowsInFileBlock); + // pCreate->cacheNumOfBlocks = htonl(pCreate->cacheNumOfBlocks); + + int32_t code; + if (mgmtCheckExpired()) { + code = TSDB_CODE_GRANT_EXPIRED; + } else if (!pUser->writeAuth) { + code = TSDB_CODE_NO_RIGHTS; + } else { + code = mgmtCreateDb(pUser->pAcct, pCreate); + if (code == TSDB_CODE_SUCCESS) { + mLPrint("DB:%s is created by %s", pCreate->db, pUser->user); + } + } + + rpcSendResponse(ahandle, code, NULL, 0); } -int mgmtProcessCreateDbMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SCreateDbMsg *pCreate = (SCreateDbMsg *)pMsg; -// int code = 0; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_CREATE_DB_RSP) != 0) { -// return 0; -// } -// -// pCreate->maxSessions = htonl(pCreate->maxSessions); -// pCreate->cacheBlockSize = htonl(pCreate->cacheBlockSize); -// // pCreate->cacheNumOfBlocks = htonl(pCreate->cacheNumOfBlocks); -// pCreate->daysPerFile = htonl(pCreate->daysPerFile); -// pCreate->daysToKeep = htonl(pCreate->daysToKeep); -// pCreate->daysToKeep1 = htonl(pCreate->daysToKeep1); -// pCreate->daysToKeep2 = htonl(pCreate->daysToKeep2); -// pCreate->commitTime = htonl(pCreate->commitTime); -// pCreate->blocksPerMeter = htons(pCreate->blocksPerMeter); -// pCreate->rowsInFileBlock = htonl(pCreate->rowsInFileBlock); -// -// if (mgmtCheckExpired()) { -// code = TSDB_CODE_GRANT_EXPIRED; -// } else if (!pConn->writeAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// code = mgmtCreateDb(pConn->pAcct, pCreate); -// if (code == TSDB_CODE_SUCCESS) { -// mLPrint("DB:%s is created by %s", pCreate->db, pConn->pUser->user); -// } -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_CREATE_DB_RSP, code); +void mgmtProcessAlterDbMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } - return 0; -} + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } -int mgmtProcessCreateMnodeMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// return rpcSendResponse(pConn->thandle, TSDB_MSG_TYPE_CREATE_MNODE_RSP, TSDB_CODE_OPS_NOT_SUPPORT); - return 0; + SAlterDbMsg *pAlter = (SAlterDbMsg *) pCont; + pAlter->daysPerFile = htonl(pAlter->daysPerFile); + pAlter->daysToKeep = htonl(pAlter->daysToKeep); + pAlter->maxSessions = htonl(pAlter->maxSessions) + 1; + + int32_t code; + if (!pUser->writeAuth) { + code = TSDB_CODE_NO_RIGHTS; + } else { + code = mgmtAlterDb(pUser->pAcct, pAlter); + if (code == TSDB_CODE_SUCCESS) { + mLPrint("DB:%s is altered by %s", pAlter->db, pUser->user); + } + } + + rpcSendResponse(ahandle, code, NULL, 0); } -int mgmtProcessAlterDbMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SAlterDbMsg *pAlter = (SAlterDbMsg *)pMsg; -// int code = 0; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_ALTER_DB_RSP) != 0) { -// return 0; -// } -// -// pAlter->daysPerFile = htonl(pAlter->daysPerFile); -// pAlter->daysToKeep = htonl(pAlter->daysToKeep); -// pAlter->maxSessions = htonl(pAlter->maxSessions) + 1; -// -// if (!pConn->writeAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// code = mgmtAlterDb(pConn->pAcct, pAlter); -// if (code == TSDB_CODE_SUCCESS) { -// mLPrint("DB:%s is altered by %s", pAlter->db, pConn->pUser->user); -// } -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_DB_RSP, code); +void mgmtProcessKillQueryMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } - return 0; -} + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } -int mgmtProcessKillQueryMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// int code = 0; -// SKillQuery *pKill = (SKillQuery *)pMsg; -// -// if (!pConn->writeAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// code = mgmtKillQuery(pKill->queryId, pConn); -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_KILL_QUERY_RSP, code); + SKillQueryMsg *pKill = (SKillQueryMsg *) pCont; + int32_t code; - return 0; + if (!pUser->writeAuth) { + code = TSDB_CODE_NO_RIGHTS; + } else { + code = mgmtKillQuery(pKill->queryId, ahandle); + } + + rpcSendResponse(ahandle, code, NULL, 0); } -int mgmtProcessKillStreamMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// int code = 0; -// SKillStream *pKill = (SKillStream *)pMsg; -// -// if (!pConn->writeAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// code = mgmtKillStream(pKill->queryId, pConn); -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_KILL_STREAM_RSP, code); +void mgmtProcessKillStreamMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } - return 0; -} + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } -int mgmtProcessKillConnectionMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// int code = 0; -// SKillConnection *pKill = (SKillConnection *)pMsg; -// -// if (!pConn->superAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// code = mgmtKillConnection(pKill->queryId, pConn); -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_KILL_CONNECTION_RSP, code); + SKillStreamMsg *pKill = (SKillStreamMsg *) pCont; + int32_t code; - return 0; + if (!pUser->writeAuth) { + code = TSDB_CODE_NO_RIGHTS; + } else { + code = mgmtKillStream(pKill->queryId, ahandle); + } + + rpcSendResponse(ahandle, code, NULL, 0); } -int mgmtProcessCreateUserMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SCreateUserMsg *pCreate = (SCreateUserMsg *)pMsg; -// int code = 0; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_CREATE_USER_RSP) != 0) { -// return 0; -// } -// -// if (pConn->superAuth) { -// code = mgmtCreateUser(pConn->pAcct, pCreate->user, pCreate->pass); -// if (code == TSDB_CODE_SUCCESS) { -// mLPrint("user:%s is created by %s", pCreate->user, pConn->pUser->user); -// } -// } else { -// code = TSDB_CODE_NO_RIGHTS; -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_CREATE_USER_RSP, code); +void mgmtProcessKillConnectionMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } - return 0; + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + SKillConnectionMsg *pKill = (SKillConnectionMsg *) pCont; + int32_t code; + + if (!pUser->writeAuth) { + code = TSDB_CODE_NO_RIGHTS; + } else { + code = mgmtKillConnection(pKill->queryId, ahandle); + } + + rpcSendResponse(ahandle, code, NULL, 0); } -int mgmtProcessAlterUserMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SAlterUserMsg *pAlter = (SAlterUserMsg *)pMsg; -// int code = 0; -// SUserObj * pUser; -// SUserObj * pOperUser; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_ALTER_USER_RSP) != 0) { -// return 0; -// } -// -// pUser = mgmtGetUser(pAlter->user); -// pOperUser = mgmtGetUser(pConn->pUser->user); -// -// if (pUser == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_USER_RSP, TSDB_CODE_INVALID_USER); -// return 0; -// } -// -// if (pOperUser == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_USER_RSP, TSDB_CODE_INVALID_USER); -// return 0; -// } -// -// if (strcmp(pUser->user, "monitor") == 0 || (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) { -// code = TSDB_CODE_NO_RIGHTS; -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_USER_RSP, code); -// return 0; -// } -// -// if ((pAlter->flag & TSDB_ALTER_USER_PASSWD) != 0) { -// bool hasRight = false; -// if (strcmp(pOperUser->user, "root") == 0) { -// hasRight = true; -// } else if (strcmp(pUser->user, pOperUser->user) == 0) { -// hasRight = true; -// } else if (pOperUser->superAuth) { -// if (strcmp(pUser->user, "root") == 0) { -// hasRight = false; -// } else if (strcmp(pOperUser->acct, pUser->acct) != 0) { -// hasRight = false; -// } else { -// hasRight = true; -// } -// } -// -// if (hasRight) { -// memset(pUser->pass, 0, sizeof(pUser->pass)); -// taosEncryptPass((uint8_t*)pAlter->pass, strlen(pAlter->pass), pUser->pass); -// code = mgmtUpdateUser(pUser); -// mLPrint("user:%s password is altered by %s, code:%d", pAlter->user, pConn->pUser->user, code); -// } else { -// code = TSDB_CODE_NO_RIGHTS; -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_USER_RSP, code); -// return 0; -// } -// -// if ((pAlter->flag & TSDB_ALTER_USER_PRIVILEGES) != 0) { -// bool hasRight = false; -// -// if (strcmp(pUser->user, "root") == 0) { -// hasRight = false; -// } else if (strcmp(pUser->user, pUser->acct) == 0) { -// hasRight = false; -// } else if (strcmp(pOperUser->user, "root") == 0) { -// hasRight = true; -// } else if (strcmp(pUser->user, pOperUser->user) == 0) { -// hasRight = false; -// } else if (pOperUser->superAuth) { -// if (strcmp(pUser->user, "root") == 0) { -// hasRight = false; -// } else if (strcmp(pOperUser->acct, pUser->acct) != 0) { -// hasRight = false; -// } else { -// hasRight = true; -// } -// } -// -// if (pAlter->privilege == 1) { // super -// hasRight = false; -// } -// -// if (hasRight) { -// //if (pAlter->privilege == 1) { // super -// // pUser->superAuth = 1; -// // pUser->writeAuth = 1; -// //} -// if (pAlter->privilege == 2) { // read -// pUser->superAuth = 0; -// pUser->writeAuth = 0; -// } -// if (pAlter->privilege == 3) { // write -// pUser->superAuth = 0; -// pUser->writeAuth = 1; -// } -// -// code = mgmtUpdateUser(pUser); -// mLPrint("user:%s privilege is altered by %s, code:%d", pAlter->user, pConn->pUser->user, code); -// } else { -// code = TSDB_CODE_NO_RIGHTS; -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_USER_RSP, code); -// return 0; -// } -// -// code = TSDB_CODE_NO_RIGHTS; -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_USER_RSP, code); - return 0; +void mgmtProcessCreateUserMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } + + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + int32_t code; + if (pUser->superAuth) { + SCreateUserMsg *pCreate = pCont; + code = mgmtCreateUser(pUser->pAcct, pCreate->user, pCreate->pass); + if (code == TSDB_CODE_SUCCESS) { + mLPrint("user:%s is created by %s", pCreate->user, pUser->user); + } + } else { + code = TSDB_CODE_NO_RIGHTS; + } + + rpcSendResponse(ahandle, code, NULL, 0); } -int mgmtProcessDropUserMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SDropUserMsg *pDrop = (SDropUserMsg *)pMsg; -// int code = 0; -// SUserObj * pUser; -// SUserObj * pOperUser; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_DROP_USER_RSP) != 0) { -// return 0; -// } -// -// pUser = mgmtGetUser(pDrop->user); -// pOperUser = mgmtGetUser(pConn->pUser->user); -// -// if (pUser == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_USER_RSP, TSDB_CODE_INVALID_USER); -// return 0; -// } -// -// if (pOperUser == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_USER_RSP, TSDB_CODE_INVALID_USER); -// return 0; -// } -// -// if (strcmp(pUser->user, "monitor") == 0 || (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) { -// code = TSDB_CODE_NO_RIGHTS; -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_USER_RSP, code); -// return 0; -// } -// -// bool hasRight = false; -// if (strcmp(pUser->user, "root") == 0) { -// hasRight = false; -// } else if (strcmp(pOperUser->user, "root") == 0) { -// hasRight = true; -// } else if (strcmp(pUser->user, pOperUser->user) == 0) { -// hasRight = false; -// } else if (pOperUser->superAuth) { -// if (strcmp(pUser->user, "root") == 0) { -// hasRight = false; -// } else if (strcmp(pOperUser->acct, pUser->acct) != 0) { -// hasRight = false; -// } else { -// hasRight = true; -// } -// } -// -// if (hasRight) { -// code = mgmtDropUser(pConn->pAcct, pDrop->user); -// if (code == 0) { -// mLPrint("user:%s is dropped by %s", pDrop->user, pConn->pUser->user); -// } -// } else { -// code = TSDB_CODE_NO_RIGHTS; -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_USER_RSP, code); - return 0; +void mgmtProcessAlterUserMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } + + SUserObj *pOperUser = mgmtGetUserFromConn(ahandle); + if (pOperUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + SAlterUserMsg *pAlter = pCont; + SUserObj *pUser = mgmtGetUser(pAlter->user); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + if (strcmp(pUser->user, "monitor") == 0 || (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) { + rpcSendResponse(ahandle, TSDB_CODE_NO_RIGHTS, NULL, 0); + return; + } + + int code; + if ((pAlter->flag & TSDB_ALTER_USER_PASSWD) != 0) { + bool hasRight = false; + if (strcmp(pOperUser->user, "root") == 0) { + hasRight = true; + } else if (strcmp(pUser->user, pOperUser->user) == 0) { + hasRight = true; + } else if (pOperUser->superAuth) { + if (strcmp(pUser->user, "root") == 0) { + hasRight = false; + } else if (strcmp(pOperUser->acct, pUser->acct) != 0) { + hasRight = false; + } else { + hasRight = true; + } + } + + if (hasRight) { + memset(pUser->pass, 0, sizeof(pUser->pass)); + taosEncryptPass((uint8_t*)pAlter->pass, strlen(pAlter->pass), pUser->pass); + code = mgmtUpdateUser(pUser); + mLPrint("user:%s password is altered by %s, code:%d", pAlter->user, pUser->user, code); + } else { + code = TSDB_CODE_NO_RIGHTS; + } + + rpcSendResponse(ahandle, code, NULL, 0); + return; + } + + if ((pAlter->flag & TSDB_ALTER_USER_PRIVILEGES) != 0) { + bool hasRight = false; + + if (strcmp(pUser->user, "root") == 0) { + hasRight = false; + } else if (strcmp(pUser->user, pUser->acct) == 0) { + hasRight = false; + } else if (strcmp(pOperUser->user, "root") == 0) { + hasRight = true; + } else if (strcmp(pUser->user, pOperUser->user) == 0) { + hasRight = false; + } else if (pOperUser->superAuth) { + if (strcmp(pUser->user, "root") == 0) { + hasRight = false; + } else if (strcmp(pOperUser->acct, pUser->acct) != 0) { + hasRight = false; + } else { + hasRight = true; + } + } + + if (pAlter->privilege == 1) { // super + hasRight = false; + } + + if (hasRight) { + //if (pAlter->privilege == 1) { // super + // pUser->superAuth = 1; + // pUser->writeAuth = 1; + //} + if (pAlter->privilege == 2) { // read + pUser->superAuth = 0; + pUser->writeAuth = 0; + } + if (pAlter->privilege == 3) { // write + pUser->superAuth = 0; + pUser->writeAuth = 1; + } + + code = mgmtUpdateUser(pUser); + mLPrint("user:%s privilege is altered by %s, code:%d", pAlter->user, pUser->user, code); + } else { + code = TSDB_CODE_NO_RIGHTS; + } + + rpcSendResponse(ahandle, code, NULL, 0); + return; + } + + code = TSDB_CODE_NO_RIGHTS; + rpcSendResponse(ahandle, code, NULL, 0); } -int mgmtProcessDropDbMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SDropDbMsg *pDrop = (SDropDbMsg *)pMsg; -// int code; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_DROP_DB_RSP) != 0) { -// return 0; -// } -// -// if (!pConn->writeAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// code = mgmtDropDbByName(pConn->pAcct, pDrop->db, pDrop->ignoreNotExists); -// if (code == 0) { -// mLPrint("DB:%s is dropped by %s", pDrop->db, pConn->pUser->user); -// } -// } -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_DB_RSP, code); +void mgmtProcessDropUserMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return ; + } - return 0; + SUserObj *pOperUser = mgmtGetUserFromConn(ahandle); + if (pOperUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return ; + } + + SDropUserMsg *pDrop = pCont; + SUserObj *pUser = mgmtGetUser(pDrop->user); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return ; + } + + if (strcmp(pUser->user, "monitor") == 0 || (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) { + rpcSendResponse(ahandle, TSDB_CODE_NO_RIGHTS, NULL, 0); + return ; + } + + bool hasRight = false; + if (strcmp(pUser->user, "root") == 0) { + hasRight = false; + } else if (strcmp(pOperUser->user, "root") == 0) { + hasRight = true; + } else if (strcmp(pUser->user, pOperUser->user) == 0) { + hasRight = false; + } else if (pOperUser->superAuth) { + if (strcmp(pUser->user, "root") == 0) { + hasRight = false; + } else if (strcmp(pOperUser->acct, pUser->acct) != 0) { + hasRight = false; + } else { + hasRight = true; + } + } + + int32_t code; + if (hasRight) { + code = mgmtDropUser(pUser->pAcct, pDrop->user); + if (code == TSDB_CODE_SUCCESS) { + mLPrint("user:%s is dropped by %s", pDrop->user, pUser->user); + } + } else { + code = TSDB_CODE_NO_RIGHTS; + } + + rpcSendResponse(ahandle, code, NULL, 0); } -int mgmtProcessUseDbMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SUseDbMsg *pUse = (SUseDbMsg *)pMsg; -// int code; -// -// code = mgmtUseDb(pConn, pUse->db); -// if (code == 0) mTrace("DB is change to:%s by %s", pUse->db, pConn->pUser->user); -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_USE_DB_RSP, code); +void mgmtProcessDropDbMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return ; + } - return 0; + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return ; + } + + int32_t code; + if (pUser->superAuth) { + SDropDbMsg *pDrop = pCont; + code = mgmtDropDbByName(pUser->pAcct, pDrop->db, pDrop->ignoreNotExists); + if (code == TSDB_CODE_SUCCESS) { + mLPrint("DB:%s is dropped by %s", pDrop->db, pUser->user); + } + } else { + code = TSDB_CODE_NO_RIGHTS; + } + + rpcSendResponse(ahandle, code, NULL, 0); } static void mgmtInitShowMsgFp() { - mgmtGetMetaFp = (GetMateFp *)malloc(TSDB_MGMT_TABLE_MAX * sizeof(GetMateFp)); - mgmtGetMetaFp[TSDB_MGMT_TABLE_ACCT] = mgmtGetAcctMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_USER] = mgmtGetUserMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_DB] = mgmtGetDbMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_TABLE] = mgmtGetTableMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_DNODE] = mgmtGetDnodeMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_MNODE] = mgmtGetMnodeMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_VGROUP] = mgmtGetVgroupMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_METRIC] = mgmtGetSuperTableMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_MODULE] = mgmtGetModuleMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_ACCT] = mgmtGetAcctMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_USER] = mgmtGetUserMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_DB] = mgmtGetDbMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_TABLE] = mgmtGetShowTableMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_DNODE] = mgmtGetDnodeMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_MNODE] = mgmtGetMnodeMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_VGROUP] = mgmtGetVgroupMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_METRIC] = mgmtGetShowSuperTableMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_MODULE] = mgmtGetModuleMeta; mgmtGetMetaFp[TSDB_MGMT_TABLE_QUERIES] = mgmtGetQueryMeta; mgmtGetMetaFp[TSDB_MGMT_TABLE_STREAMS] = mgmtGetStreamMeta; mgmtGetMetaFp[TSDB_MGMT_TABLE_CONFIGS] = mgmtGetConfigMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_CONNS] = mgmtGetConnsMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_SCORES] = mgmtGetScoresMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_GRANTS] = mgmtGetGrantsMeta; - mgmtGetMetaFp[TSDB_MGMT_TABLE_VNODES] = mgmtGetVnodeMeta; - - mgmtRetrieveFp = (RetrieveMetaFp *)malloc(TSDB_MGMT_TABLE_MAX * sizeof(RetrieveMetaFp)); - mgmtRetrieveFp[TSDB_MGMT_TABLE_ACCT] = mgmtRetrieveAccts; - mgmtRetrieveFp[TSDB_MGMT_TABLE_USER] = mgmtRetrieveUsers; - mgmtRetrieveFp[TSDB_MGMT_TABLE_DB] = mgmtRetrieveDbs; - mgmtRetrieveFp[TSDB_MGMT_TABLE_TABLE] = mgmtRetrieveTables; - mgmtRetrieveFp[TSDB_MGMT_TABLE_DNODE] = mgmtRetrieveDnodes; - mgmtRetrieveFp[TSDB_MGMT_TABLE_MNODE] = mgmtRetrieveMnodes; - mgmtRetrieveFp[TSDB_MGMT_TABLE_VGROUP] = mgmtRetrieveVgroups; - mgmtRetrieveFp[TSDB_MGMT_TABLE_METRIC] = mgmtRetrieveSuperTables; - mgmtRetrieveFp[TSDB_MGMT_TABLE_MODULE] = mgmtRetrieveModules; + mgmtGetMetaFp[TSDB_MGMT_TABLE_CONNS] = mgmtGetConnsMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_SCORES] = mgmtGetScoresMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_GRANTS] = mgmtGetGrantsMeta; + mgmtGetMetaFp[TSDB_MGMT_TABLE_VNODES] = mgmtGetVnodeMeta; + + mgmtRetrieveFp[TSDB_MGMT_TABLE_ACCT] = mgmtRetrieveAccts; + mgmtRetrieveFp[TSDB_MGMT_TABLE_USER] = mgmtRetrieveUsers; + mgmtRetrieveFp[TSDB_MGMT_TABLE_DB] = mgmtRetrieveDbs; + mgmtRetrieveFp[TSDB_MGMT_TABLE_TABLE] = mgmtRetrieveShowTables; + mgmtRetrieveFp[TSDB_MGMT_TABLE_DNODE] = mgmtRetrieveDnodes; + mgmtRetrieveFp[TSDB_MGMT_TABLE_MNODE] = mgmtRetrieveMnodes; + mgmtRetrieveFp[TSDB_MGMT_TABLE_VGROUP] = mgmtRetrieveVgroups; + mgmtRetrieveFp[TSDB_MGMT_TABLE_METRIC] = mgmtRetrieveShowSuperTables; + mgmtRetrieveFp[TSDB_MGMT_TABLE_MODULE] = mgmtRetrieveModules; mgmtRetrieveFp[TSDB_MGMT_TABLE_QUERIES] = mgmtRetrieveQueries; mgmtRetrieveFp[TSDB_MGMT_TABLE_STREAMS] = mgmtRetrieveStreams; mgmtRetrieveFp[TSDB_MGMT_TABLE_CONFIGS] = mgmtRetrieveConfigs; - mgmtRetrieveFp[TSDB_MGMT_TABLE_CONNS] = mgmtRetrieveConns; - mgmtRetrieveFp[TSDB_MGMT_TABLE_SCORES] = mgmtRetrieveScores; - mgmtRetrieveFp[TSDB_MGMT_TABLE_GRANTS] = mgmtRetrieveGrants; - mgmtRetrieveFp[TSDB_MGMT_TABLE_VNODES] = mgmtRetrieveVnodes; + mgmtRetrieveFp[TSDB_MGMT_TABLE_CONNS] = mgmtRetrieveConns; + mgmtRetrieveFp[TSDB_MGMT_TABLE_SCORES] = mgmtRetrieveScores; + mgmtRetrieveFp[TSDB_MGMT_TABLE_GRANTS] = mgmtRetrieveGrants; + mgmtRetrieveFp[TSDB_MGMT_TABLE_VNODES] = mgmtRetrieveVnodes; } -int mgmtProcessShowMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SShowMsg * pShowMsg = (SShowMsg *)pMsg; -// STaosRsp * pRsp; -// char * pStart; -// int code = 0; -// SShowRspMsg *pShowRsp; -// SShowObj * pShow = NULL; -// -// if (pShowMsg->type == TSDB_MGMT_TABLE_DNODE || TSDB_MGMT_TABLE_GRANTS || TSDB_MGMT_TABLE_SCORES) { -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_SHOW_RSP) != 0) { -// return 0; -// } -// } -// -// int size = sizeof(STaosHeader) + sizeof(STaosRsp) + sizeof(SShowRspMsg) + sizeof(SSchema) * TSDB_MAX_COLUMNS + -// TSDB_EXTRA_PAYLOAD_SIZE; -// pStart = taosBuildRspMsgWithSize(pConn->thandle, TSDB_MSG_TYPE_SHOW_RSP, size); -// if (pStart == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_SHOW_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// -// pMsg = pStart; -// pRsp = (STaosRsp *)pMsg; -// pMsg = (char *)pRsp->more; -// -// if (pShowMsg->type >= TSDB_MGMT_TABLE_MAX) { -// code = -1; -// } else { -// pShow = (SShowObj *)calloc(1, sizeof(SShowObj) + htons(pShowMsg->payloadLen)); -// pShow->signature = pShow; -// pShow->type = pShowMsg->type; -// mTrace("pShow:%p is allocated", pShow); -// -// // set the table name query condition -// pShow->payloadLen = htons(pShowMsg->payloadLen); -// memcpy(pShow->payload, pShowMsg->payload, pShow->payloadLen); -// -// pShowRsp = (SShowRspMsg *)pMsg; -// pShowRsp->qhandle = (uint64_t)pShow; // qhandle; -// pConn->qhandle = pShowRsp->qhandle; -// -// code = (*mgmtGetMetaFp[(uint8_t)pShowMsg->type])(&pShowRsp->meterMeta, pShow, pConn); -// if (code == 0) { -// pMsg += sizeof(SShowRspMsg) + sizeof(SSchema) * pShow->numOfColumns; -// } else { -// mError("pShow:%p, type:%d %s, failed to get Meta, code:%d", pShow, pShowMsg->type, taosMsg[(uint8_t)pShowMsg->type], code); -// free(pShow); -// } -// } -// -// pRsp->code = code; -// msgLen = pMsg - pStart; -// taosSendMsgToPeer(pConn->thandle, pStart, msgLen); -// -// return msgLen; - return 0; +void mgmtProcessShowMsg(void *pCont, int32_t contLen, void *ahandle) { + SShowMsg *pShowMsg = pCont; + if (pShowMsg->type == TSDB_MGMT_TABLE_DNODE || TSDB_MGMT_TABLE_GRANTS || TSDB_MGMT_TABLE_SCORES) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } + } + + int32_t size = sizeof(SShowRsp) + sizeof(SSchema) * TSDB_MAX_COLUMNS + TSDB_EXTRA_PAYLOAD_SIZE; + SShowRsp *pShowRsp = rpcMallocCont(size); + if (pShowRsp == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); + return; + } + + int32_t code; + if (pShowMsg->type >= TSDB_MGMT_TABLE_MAX) { + code = TSDB_CODE_INVALID_MSG_TYPE; + } else { + SShowObj *pShow = (SShowObj *) calloc(1, sizeof(SShowObj) + htons(pShowMsg->payloadLen)); + pShow->signature = pShow; + pShow->type = pShowMsg->type; + strcpy(pShow->db, pShowMsg->db); + mTrace("pShow:%p is allocated", pShow); + + // set the table name query condition + pShow->payloadLen = htons(pShowMsg->payloadLen); + memcpy(pShow->payload, pShowMsg->payload, pShow->payloadLen); + + mgmtSaveQhandle(pShow); + pShowRsp->qhandle = htobe64((uint64_t) pShow); + code = (*mgmtGetMetaFp[(uint8_t) pShowMsg->type])(&pShowRsp->tableMeta, pShow, ahandle); + if (code == 0) { + size = sizeof(SShowRsp) + sizeof(SSchema) * pShow->numOfColumns; + } else { + mError("pShow:%p, type:%d %s, failed to get Meta, code:%d", pShow, pShowMsg->type, + taosMsg[(uint8_t) pShowMsg->type], code); + free(pShow); + } + } + + rpcSendResponse(ahandle, code, pShowRsp, size); } -int mgmtProcessRetrieveMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SRetrieveMeterMsg *pRetrieve; -// SRetrieveMeterRsp *pRsp; -// int rowsToRead = 0, size = 0, rowsRead = 0; -// char * pStart; -// int code = 0; -// SShowObj * pShow; -// -// pRetrieve = (SRetrieveMeterMsg *)pMsg; -// -// /* -// * in case of server restart, apps may hold qhandle created by server before -// * restart, which is actually invalid, therefore, signature check is required. -// */ -// if (pRetrieve->qhandle != pConn->qhandle) { -// mError("retrieve:%p, qhandle:%p is not matched with saved:%p", pRetrieve, pRetrieve->qhandle, pConn->qhandle); -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DNODE_RETRIEVE_RSP, TSDB_CODE_MEMORY_CORRUPTED); -// return -1; -// } -// -// pShow = (SShowObj *)pRetrieve->qhandle; -// if (pShow->signature != (void *)pShow) { -// mError("pShow:%p, signature:%p, query memory is corrupted", pShow, pShow->signature); -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DNODE_RETRIEVE_RSP, TSDB_CODE_MEMORY_CORRUPTED); -// return -1; -// } else { -// if ((pRetrieve->free & TSDB_QUERY_TYPE_FREE_RESOURCE) != TSDB_QUERY_TYPE_FREE_RESOURCE) { -// rowsToRead = pShow->numOfRows - pShow->numOfReads; -// } -// -// /* return no more than 100 meters in one round trip */ -// if (rowsToRead > 100) rowsToRead = 100; -// -// /* -// * the actual number of table may be larger than the value of pShow->numOfRows, if a query is -// * issued during a continuous create table operation. Therefore, rowToRead may be less than 0. -// */ -// if (rowsToRead < 0) rowsToRead = 0; -// size = pShow->rowSize * rowsToRead; -// } -// -// pStart = taosBuildRspMsgWithSize(pConn->thandle, TSDB_MSG_TYPE_DNODE_RETRIEVE_RSP, size + 100); -// if (pStart == NULL) { -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DNODE_RETRIEVE_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY); -// return 0; -// } -// -// pMsg = pStart; -// -// STaosRsp *pTaosRsp = (STaosRsp *)pStart; -// pTaosRsp->code = code; -// pMsg = pTaosRsp->more; -// -// if (code == 0) { -// pRsp = (SRetrieveMeterRsp *)pMsg; -// pMsg = pRsp->data; -// -// // if free flag is set, client wants to clean the resources -// if ((pRetrieve->free & TSDB_QUERY_TYPE_FREE_RESOURCE) != TSDB_QUERY_TYPE_FREE_RESOURCE) -// rowsRead = (*mgmtRetrieveFp[(uint8_t)pShow->type])(pShow, pRsp->data, rowsToRead, pConn); -// -// if (rowsRead < 0) { -// rowsRead = 0; -// pTaosRsp->code = TSDB_CODE_ACTION_IN_PROGRESS; -// } -// -// pRsp->numOfRows = htonl(rowsRead); -// pRsp->precision = htonl(TSDB_TIME_PRECISION_MILLI); // millisecond time precision -// pMsg += size; -// } -// -// msgLen = pMsg - pStart; -// taosSendMsgToPeer(pConn->thandle, pStart, msgLen); -// -// if (rowsToRead == 0) { -// uintptr_t oldSign = (uintptr_t)atomic_val_compare_exchange_ptr(&pShow->signature, pShow, 0); -// if (oldSign != (uintptr_t)pShow) { -// return msgLen; -// } -// // pShow->signature = 0; -// mTrace("pShow:%p is released", pShow); -// tfree(pShow); -// } -// -// return msgLen; - return 0; +void mgmtProcessRetrieveMsg(void *pCont, int32_t contLen, void *ahandle) { + int32_t rowsToRead = 0; + int32_t size = 0; + int32_t rowsRead = 0; + SRetrieveTableMsg *pRetrieve = (SRetrieveTableMsg *)pCont; + pRetrieve->qhandle = htobe64(pRetrieve->qhandle); + + /* + * in case of server restart, apps may hold qhandle created by server before + * restart, which is actually invalid, therefore, signature check is required. + */ + if (!mgmtCheckQhandle(pRetrieve->qhandle)) { + mError("retrieve:%p, qhandle:%p is invalid", pRetrieve, pRetrieve->qhandle); + rpcSendResponse(ahandle, TSDB_CODE_INVALID_QHANDLE, NULL, 0); + return; + } + + SShowObj *pShow = (SShowObj *)pRetrieve->qhandle; + if (pShow->signature != (void *)pShow) { + mError("pShow:%p, signature:%p, query memory is corrupted", pShow, pShow->signature); + rpcSendResponse(ahandle, TSDB_CODE_MEMORY_CORRUPTED, NULL, 0); + return; + } else { + if ((pRetrieve->free & TSDB_QUERY_TYPE_FREE_RESOURCE) != TSDB_QUERY_TYPE_FREE_RESOURCE) { + rowsToRead = pShow->numOfRows - pShow->numOfReads; + } + + /* return no more than 100 meters in one round trip */ + if (rowsToRead > 100) rowsToRead = 100; + + /* + * the actual number of table may be larger than the value of pShow->numOfRows, if a query is + * issued during a continuous create table operation. Therefore, rowToRead may be less than 0. + */ + if (rowsToRead < 0) rowsToRead = 0; + size = pShow->rowSize * rowsToRead; + } + + size += 100; + SRetrieveTableRsp *pRsp = rpcMallocCont(size); + + // if free flag is set, client wants to clean the resources + if ((pRetrieve->free & TSDB_QUERY_TYPE_FREE_RESOURCE) != TSDB_QUERY_TYPE_FREE_RESOURCE) + rowsRead = (*mgmtRetrieveFp[(uint8_t) pShow->type])(pShow, pRsp->data, rowsToRead, ahandle); + + if (rowsRead < 0) { + rowsRead = 0; // TSDB_CODE_ACTION_IN_PROGRESS; + rpcFreeCont(pRsp); + return; + } + + pRsp->numOfRows = htonl(rowsRead); + pRsp->precision = htonl(TSDB_TIME_PRECISION_MILLI); // millisecond time precision + + rpcSendResponse(ahandle, TSDB_CODE_SUCCESS, pRsp, size); + + if (rowsToRead == 0) { + mgmtFreeQhandle(pShow); + } } -int mgmtProcessCreateTableMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SCreateTableMsg *pCreate = (SCreateTableMsg *)pMsg; -// int code; -// SSchema * pSchema; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_CREATE_TABLE_RSP) != 0) { -// return 0; -// } -// -// if (!pConn->writeAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// pCreate->numOfColumns = htons(pCreate->numOfColumns); -// pCreate->numOfTags = htons(pCreate->numOfTags); -// -// pCreate->sqlLen = htons(pCreate->sqlLen); -// pSchema = pCreate->schema; -// for (int i = 0; i < pCreate->numOfColumns + pCreate->numOfTags; ++i) { -// pSchema->bytes = htons(pSchema->bytes); -// pSchema->colId = i; -// pSchema++; -// } -// -// SDbObj *pDb = NULL; -// if (pConn->pDb != NULL) pDb = mgmtGetDb(pConn->pDb->name); -// -// if (pDb) { -// code = mgmtCreateTable(pDb, pCreate); -// } else { -// code = TSDB_CODE_DB_NOT_SELECTED; -// } -// } -// -// if (code == 1) { -// //mTrace("table:%s, wait vgroup create finish", pCreate->meterId, code); -// } else if (code != TSDB_CODE_SUCCESS) { -// if (code == TSDB_CODE_TABLE_ALREADY_EXIST) { // table already created when the second attempt to create table -// -// STabObj* pTable = mgmtGetTable(pCreate->meterId); -// assert(pTable != NULL); -// -// mWarn("table:%s, table already created, failed to create table, ts:%" PRId64 ", code:%d", pCreate->meterId, -// pTable->createdTime, code); -// } else { // other errors -// mError("table:%s, failed to create table, code:%d", pCreate->meterId, code); -// } -// } else { -// mTrace("table:%s, table is created by %s", pCreate->meterId, pConn->pUser->user); -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_CREATE_TABLE_RSP, code); +void mgmtProcessCreateTableMsg(void *pCont, int32_t contLen, void *ahandle) { + SCreateTableMsg *pCreate = (SCreateTableMsg *) pCont; + pCreate->numOfColumns = htons(pCreate->numOfColumns); + pCreate->numOfTags = htons(pCreate->numOfTags); + pCreate->sqlLen = htons(pCreate->sqlLen); - return 0; + SSchema *pSchema = pCreate->schema; + for (int32_t i = 0; i < pCreate->numOfColumns + pCreate->numOfTags; ++i) { + pSchema->bytes = htons(pSchema->bytes); + pSchema->colId = i; + pSchema++; + } + + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + mError("table:%s, failed to create table, need redirect message", pCreate->tableId); + return; + } + + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + mError("table:%s, failed to create table, invalid user", pCreate->tableId); + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + if (!pUser->writeAuth) { + mError("table:%s, failed to create table, no rights", pCreate->tableId); + rpcSendResponse(ahandle, TSDB_CODE_NO_RIGHTS, NULL, 0); + return; + } + + int32_t code = mgmtCreateTable(pCreate, contLen, ahandle, false); + if (code != TSDB_CODE_ACTION_IN_PROGRESS) { + rpcSendResponse(ahandle, code, NULL, 0); + } } -int mgmtProcessDropTableMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SDropTableMsg *pDrop = (SDropTableMsg *)pMsg; -// int code; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_DROP_TABLE_RSP) != 0) { -// return 0; -// } -// -// if (!pConn->writeAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// SDbObj *pDb = NULL; -// if (pConn->pDb != NULL) pDb = mgmtGetDb(pConn->pDb->name); -// -// code = mgmtDropTable(pDb, pDrop->meterId, pDrop->igNotExists); -// if (code == 0) { -// mTrace("meter:%s is dropped by user:%s", pDrop->meterId, pConn->pUser->user); -// // mLPrint("meter:%s is dropped by user:%s", pDrop->meterId, pConn->pUser->user); -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_TABLE_RSP, code); -// } +void mgmtProcessDropTableMsg(void *pCont, int32_t contLen, void *ahandle) { + SDropTableMsg *pDrop = (SDropTableMsg *) pCont; - return 0; + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + mError("table:%s, failed to drop table, need redirect message", pDrop->tableId); + return; + } + + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + mError("table:%s, failed to drop table, invalid user", pDrop->tableId); + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + if (!pUser->writeAuth) { + mError("table:%s, failed to drop table, no rights", pDrop->tableId); + rpcSendResponse(ahandle, TSDB_CODE_NO_RIGHTS, NULL, 0); + return; + } + + SDbObj *pDb = mgmtGetDbByTableId(pDrop->tableId); + if (pDb == NULL) { + mError("table:%s, failed to drop table, db not selected", pDrop->tableId); + rpcSendResponse(ahandle, TSDB_CODE_DB_NOT_SELECTED, NULL, 0); + return; + } + + int32_t code = mgmtDropTable(pDb, pDrop->tableId, pDrop->igNotExists); + if (code != TSDB_CODE_ACTION_IN_PROGRESS) { + rpcSendResponse(ahandle, code, NULL, 0); + } } -int mgmtProcessAlterTableMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// SAlterTableMsg *pAlter = (SAlterTableMsg *)pMsg; -// int code; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_ALTER_TABLE_RSP) != 0) { -// return 0; -// } -// -// if (!pConn->writeAuth) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// pAlter->type = htons(pAlter->type); -// pAlter->numOfCols = htons(pAlter->numOfCols); -// -// if (pAlter->numOfCols > 2) { -// mError("meter:%s error numOfCols:%d in alter table", pAlter->meterId, pAlter->numOfCols); -// code = TSDB_CODE_APP_ERROR; -// } else { -// SDbObj *pDb = NULL; -// if (pConn->pDb != NULL) pDb = mgmtGetDb(pConn->pDb->name); -// -// if (pDb) { -// for (int32_t i = 0; i < pAlter->numOfCols; ++i) { -// pAlter->schema[i].bytes = htons(pAlter->schema[i].bytes); -// } -// -// code = mgmtAlterTable(pDb, pAlter); -// if (code == 0) { -// mLPrint("meter:%s is altered by %s", pAlter->meterId, pConn->pUser->user); -// } -// } else { -// code = TSDB_CODE_DB_NOT_SELECTED; -// } -// } -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_TABLE_RSP, code); +void mgmtProcessAlterTableMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } - return 0; + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + SAlterTableMsg *pAlter = (SAlterTableMsg *) pCont; + int32_t code; + + if (!pUser->writeAuth) { + code = TSDB_CODE_NO_RIGHTS; + } else { + pAlter->type = htons(pAlter->type); + pAlter->numOfCols = htons(pAlter->numOfCols); + + if (pAlter->numOfCols > 2) { + mError("table:%s error numOfCols:%d in alter table", pAlter->tableId, pAlter->numOfCols); + code = TSDB_CODE_APP_ERROR; + } else { + SDbObj *pDb = mgmtGetDb(pAlter->db); + if (pDb) { + for (int32_t i = 0; i < pAlter->numOfCols; ++i) { + pAlter->schema[i].bytes = htons(pAlter->schema[i].bytes); + } + + code = mgmtAlterTable(pDb, pAlter); + if (code == 0) { + mLPrint("table:%s is altered by %s", pAlter->tableId, pUser->user); + } + } else { + code = TSDB_CODE_DB_NOT_SELECTED; + } + } + } + + if (code != TSDB_CODE_SUCCESS) { + rpcSendResponse(ahandle, code, NULL, 0); + } } -int mgmtProcessCfgDnodeMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// int code = 0; -// SCfgMsg *pCfg = (SCfgMsg *)pMsg; -// -// if (mgmtCheckRedirectMsg(pConn, TSDB_MSG_TYPE_CFG_MNODE_RSP) != 0) { -// return 0; -// } -// -// if (strcmp(pConn->pAcct->user, "root") != 0) { -// code = TSDB_CODE_NO_RIGHTS; -// } else { -// code = mgmtSendCfgDnodeMsg(pMsg); -// } -// -// taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DNODE_CFG_RSP, code); -// -// if (code == 0) mTrace("dnode:%s is configured by %s", pCfg->ip, pConn->pUser->user); -// -// return 0; -//} -// -//int mgmtProcessHeartBeatMsg(char *cont, int contLen, SConnObj *pConn) { -// char * pStart, *pMsg; -// int msgLen; -// STaosRsp *pRsp; -// -// mgmtSaveQueryStreamList(cont, contLen, pConn); -// -// pStart = taosBuildRspMsgWithSize(pConn->thandle, TSDB_MSG_TYPE_HEARTBEAT_RSP, 128); -// if (pStart == NULL) return 0; -// pMsg = pStart; -// pRsp = (STaosRsp *)pMsg; -// pRsp->code = 0; -// pMsg = (char *)pRsp->more; -// -// SHeartBeatRsp *pHBRsp = (SHeartBeatRsp *)pRsp->more; -// pHBRsp->queryId = pConn->queryId; -// pConn->queryId = 0; -// pHBRsp->streamId = pConn->streamId; -// pHBRsp->streamId = pConn->streamId; -// pConn->streamId = 0; -// pHBRsp->killConnection = pConn->killConnection; -// -// if (pConn->usePublicIp) { -// if (pSdbPublicIpList != NULL) { -// int size = pSdbPublicIpList->numOfIps * 4; -// pHBRsp->ipList.numOfIps = pSdbPublicIpList->numOfIps; -// memcpy(pHBRsp->ipList.ip, pSdbPublicIpList->ip, size); -// pMsg += sizeof(SHeartBeatRsp) + size; -// } else { -// pHBRsp->ipList.numOfIps = 0; -// pMsg += sizeof(SHeartBeatRsp); -// } -// -// } else { -// if (pSdbIpList != NULL) { -// int size = pSdbIpList->numOfIps * 4; -// pHBRsp->ipList.numOfIps = pSdbIpList->numOfIps; -// memcpy(pHBRsp->ipList.ip, pSdbIpList->ip, size); -// pMsg += sizeof(SHeartBeatRsp) + size; -// } else { -// pHBRsp->ipList.numOfIps = 0; -// pMsg += sizeof(SHeartBeatRsp); -// } -// } -// msgLen = pMsg - pStart; -// -// taosSendMsgToPeer(pConn->thandle, pStart, msgLen); +void mgmtProcessCfgDnodeMsg(void *pCont, int32_t contLen, void *ahandle) { + if (mgmtCheckRedirectMsg(ahandle) != TSDB_CODE_SUCCESS) { + return; + } - return 0; + SUserObj *pUser = mgmtGetUserFromConn(ahandle); + if (pUser == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_INVALID_USER, NULL, 0); + return; + } + + SCfgDnodeMsg *pCfg = (SCfgDnodeMsg *)pCont; + int32_t code; + + if (strcmp(pUser->pAcct->user, "root") != 0) { + code = TSDB_CODE_NO_RIGHTS; + } else { + code = mgmtSendCfgDnodeMsg(pCont); + } + + if (code == TSDB_CODE_SUCCESS) { + mTrace("dnode:%s is configured by %s", pCfg->ip, pUser->user); + } + + rpcSendResponse(ahandle, code, NULL, 0); } -void mgmtEstablishConn(SConnObj *pConn) { -// atomic_fetch_add_32(&mgmtShellConns, 1); -// atomic_fetch_add_32(&sdbExtConns, 1); -// pConn->stime = taosGetTimestampMs(); -// -// if (strcmp(pConn->pUser->user, "root") == 0) { -// pConn->superAuth = 1; -// pConn->writeAuth = 1; -// } else { -// pConn->superAuth = pConn->pUser->superAuth; -// pConn->writeAuth = pConn->pUser->writeAuth; -// if (pConn->superAuth) { -// pConn->writeAuth = 1; -// } -// } -// -// int32_t tempint32; -// uint32_t tempuint32; -// taosGetRpcConnInfo(pConn->thandle, &tempuint32, &pConn->ip, &pConn->port, &tempint32, &tempint32); -// mgmtAddConnIntoAcct(pConn); +void mgmtProcessHeartBeatMsg(void *pCont, int32_t contLen, void *ahandle) { + SHeartBeatMsg *pHBMsg = (SHeartBeatMsg *) pCont; + mgmtSaveQueryStreamList(pHBMsg); + + SHeartBeatRsp *pHBRsp = (SHeartBeatRsp *) rpcMallocCont(contLen); + if (pHBRsp == NULL) { + rpcSendResponse(ahandle, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); + rpcFreeCont(pCont); + return; + } + + SRpcConnInfo connInfo; + rpcGetConnInfo(ahandle, &connInfo); + + pHBRsp->ipList.inUse = 0; + pHBRsp->ipList.port = htons(tsMgmtShellPort); + pHBRsp->ipList.numOfIps = 0; + if (pSdbPublicIpList != NULL && pSdbIpList != NULL) { + pHBRsp->ipList.numOfIps = htons(pSdbPublicIpList->numOfIps); + if (connInfo.serverIp == tsPublicIpInt) { + for (int i = 0; i < pSdbPublicIpList->numOfIps; ++i) { + pHBRsp->ipList.ip[i] = htonl(pSdbPublicIpList->ip[i]); + } + } else { + for (int i = 0; i < pSdbIpList->numOfIps; ++i) { + pHBRsp->ipList.ip[i] = htonl(pSdbIpList->ip[i]); + } + } + } + + /* + * TODO + * Dispose kill stream or kill query message + */ + pHBRsp->queryId = 0; + pHBRsp->streamId = 0; + pHBRsp->killConnection = 0; + + rpcSendResponse(ahandle, TSDB_CODE_SUCCESS, pHBRsp, sizeof(SHeartBeatMsg)); } int mgmtRetriveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey) { - SUserObj *pUser = NULL; - *spi = 0; *encrypt = 0; - secret[0] = 0; - ckey[0] = 0; + *ckey = 0; + + SUserObj *pUser = mgmtGetUser(user); + if (pUser == NULL) { + *secret = 0; + return TSDB_CODE_INVALID_USER; + } else { + memcpy(secret, pUser->pass, TSDB_KEY_LEN); + return TSDB_CODE_SUCCESS; + } +} - pUser = mgmtGetUser(user); - if (pUser == NULL) return TSDB_CODE_INVALID_USER; +static void mgmtProcessConnectMsg(void *pCont, int32_t contLen, void *thandle) { + SConnectMsg *pConnectMsg = (SConnectMsg *) pCont; + SRpcConnInfo connInfo; + rpcGetConnInfo(thandle, &connInfo); + int32_t code; - *spi = 1; - *encrypt = 0; - memcpy(secret, pUser->pass, TSDB_KEY_LEN); + SUserObj *pUser = mgmtGetUser(connInfo.user); + if (pUser == NULL) { + code = TSDB_CODE_INVALID_USER; + goto connect_over; + } - return 0; -} + if (mgmtCheckExpired()) { + code = TSDB_CODE_GRANT_EXPIRED; + goto connect_over; + } -int mgmtProcessConnectMsg(char *pMsg, int msgLen, SConnObj *pConn) { -// STaosRsp * pRsp; -// SConnectRsp *pConnectRsp; -// SConnectMsg *pConnectMsg; -// char * pStart; -// int code = TSDB_CODE_INVALID_USER; -// SAcctObj * pAcct = NULL; -// SUserObj * pUser = NULL; -// SDbObj * pDb = NULL; -// char dbName[256] = {0}; -// -// pConnectMsg = (SConnectMsg *)pMsg; -// -// pUser = mgmtGetUser(pConn->user); -// if (pUser == NULL) { -// code = TSDB_CODE_INVALID_USER; -// goto _rsp; -// } -// -// if (mgmtCheckExpired()) { -// code = TSDB_CODE_GRANT_EXPIRED; -// goto _rsp; -// } -// -// pAcct = mgmtGetAcct(pUser->acct); -// -// code = taosCheckVersion(pConnectMsg->clientVersion, version, 3); -// if (code != 0) { -// mError("invalid client version:%s", pConnectMsg->clientVersion); -// goto _rsp; -// } -// -// if (pConnectMsg->db[0]) { -// sprintf(dbName, "%x%s%s", pAcct->acctId, TS_PATH_DELIMITER, pConnectMsg->db); -// pDb = mgmtGetDb(dbName); -// if (pDb == NULL) { -// code = TSDB_CODE_INVALID_DB; -// goto _rsp; -// } -// } -// -// if (pConn->pAcct) { -// mgmtRemoveConnFromAcct(pConn); -// atomic_fetch_sub_32(&mgmtShellConns, 1); -// atomic_fetch_sub_32(&sdbExtConns, 1); -// } -// -// code = 0; -// pConn->pAcct = pAcct; -// pConn->pDb = pDb; -// pConn->pUser = pUser; -// mgmtEstablishConn(pConn); -// -//_rsp: -// pStart = taosBuildRspMsgWithSize(pConn->thandle, TSDB_MSG_TYPE_CONNECT_RSP, 128); -// if (pStart == NULL) return 0; -// -// pMsg = pStart; -// pRsp = (STaosRsp *)pMsg; -// pRsp->code = code; -// pMsg += sizeof(STaosRsp); -// -// if (code == 0) { -// pConnectRsp = (SConnectRsp *)pRsp->more; -// sprintf(pConnectRsp->acctId, "%x", pConn->pAcct->acctId); -// strcpy(pConnectRsp->version, version); -// pConnectRsp->writeAuth = pConn->writeAuth; -// pConnectRsp->superAuth = pConn->superAuth; -// pMsg += sizeof(SConnectRsp); -// -// int size; -// if (pSdbPublicIpList != NULL && pSdbIpList != NULL) { -// size = pSdbPublicIpList->numOfIps * 4 + sizeof(SIpList); -// if (pConn->usePublicIp) { -// memcpy(pMsg, pSdbPublicIpList, size); -// } else { -// memcpy(pMsg, pSdbIpList, size); -// } -// } else { -// SIpList tmpIpList; -// tmpIpList.numOfIps = 0; -// size = tmpIpList.numOfIps * 4 + sizeof(SIpList); -// memcpy(pMsg, &tmpIpList, size); -// } -// -// pMsg += size; -// -// // set the time resolution: millisecond or microsecond -// *((uint32_t *)pMsg) = tsTimePrecision; -// pMsg += sizeof(uint32_t); -// -// } else { -// pConn->pAcct = NULL; -// pConn->pUser = NULL; -// } -// -// msgLen = pMsg - pStart; -// taosSendMsgToPeer(pConn->thandle, pStart, msgLen); -// -// char ipstr[24]; -// tinet_ntoa(ipstr, pConn->ip); -// mLPrint("user:%s login from %s, code:%d", pConn->user, ipstr, code); -// -// return code; - return 0; -} + SAcctObj *pAcct = mgmtGetAcct(pUser->acct); + if (pAcct == NULL) { + code = TSDB_CODE_INVALID_ACCT; + goto connect_over; + } + + code = taosCheckVersion(pConnectMsg->clientVersion, version, 3); + if (code != TSDB_CODE_SUCCESS) { + goto connect_over; + } + + if (pConnectMsg->db[0]) { + char dbName[TSDB_TABLE_ID_LEN] = {0}; + sprintf(dbName, "%x%s%s", pAcct->acctId, TS_PATH_DELIMITER, pConnectMsg->db); + SDbObj *pDb = mgmtGetDb(dbName); + if (pDb == NULL) { + code = TSDB_CODE_INVALID_DB; + goto connect_over; + } + } -void mgmtProcessMsgFromShell(char type, void *pCont, int contLen, void *ahandle, int32_t code) { -// SIntMsg * pMsg = (SIntMsg *)msg; -// SConnObj *pConn = (SConnObj *)ahandle; -// -// if (msg == NULL) { -// if (pConn) { -// mgmtRemoveConnFromAcct(pConn); -// atomic_fetch_sub_32(&mgmtShellConns, 1); -// atomic_fetch_sub_32(&sdbExtConns, 1); -// mTrace("connection from %s is closed", pConn->pUser->user); -// memset(pConn, 0, sizeof(SConnObj)); -// } -// -// return NULL; -// } -// -//#ifdef CLUSTER -// if (sdbInited == NULL || sdbStatus != SDB_STATUS_SERVING) { -// taosSendSimpleRsp(thandle, pMsg->msgType + 1, TSDB_CODE_NOT_READY); -// mTrace("shell msg is ignored since SDB is not ready"); -// } -//#endif -// -// if (pConn == NULL) { -// pConn = connList + pMsg->destId; -// pConn->thandle = thandle; -// strcpy(pConn->user, pMsg->meterId); -// pConn->usePublicIp = (pMsg->destIp == tsPublicIpInt ? 1 : 0); -// mTrace("pConn:%p is rebuild, destIp:%s publicIp:%s usePublicIp:%u", -// pConn, taosIpStr(pMsg->destIp), taosIpStr(tsPublicIpInt), pConn->usePublicIp); -// } -// -// if (pMsg->msgType == TSDB_MSG_TYPE_CONNECT) { -// (*mgmtProcessShellMsg[pMsg->msgType])((char *)pMsg->content, pMsg->msgLen - sizeof(SIntMsg), pConn); -// } else { -// SMgmtHead *pHead = (SMgmtHead *)pMsg->content; -// if (pConn->pAcct == NULL) { -// pConn->pUser = mgmtGetUser(pConn->user); -// if (pConn->pUser) { -// pConn->pAcct = mgmtGetAcct(pConn->pUser->acct); -// mgmtEstablishConn(pConn); -// mTrace("login from:%x:%hu", pConn->ip, htons(pConn->port)); -// } -// } -// -// if (pConn->pAcct) { -// if (pConn->pDb == NULL || strncmp(pConn->pDb->name, pHead->db, tListLen(pConn->pDb->name)) != 0) { -// pConn->pDb = mgmtGetDb(pHead->db); -// } -// -// char *cont = (char *)pMsg->content + sizeof(SMgmtHead); -// int contLen = pMsg->msgLen - sizeof(SIntMsg) - sizeof(SMgmtHead); -// -// // read-only request can be executed concurrently -// if ((pMsg->msgType == TSDB_MSG_TYPE_TABLE_META && (!mgmtCheckMeterMetaMsgType(cont))) || -// pMsg->msgType == TSDB_MSG_TYPE_STABLE_META || pMsg->msgType == TSDB_MSG_TYPE_DNODE_RETRIEVE || -// pMsg->msgType == TSDB_MSG_TYPE_SHOW || pMsg->msgType == TSDB_MSG_TYPE_MULTI_TABLE_META) { -// (*mgmtProcessShellMsg[pMsg->msgType])(cont, contLen, pConn); -// } else { -// if (mgmtProcessShellMsg[pMsg->msgType]) { -// SSchedMsg schedMsg; -// schedMsg.msg = malloc(pMsg->msgLen); // Message to deal with -// memcpy(schedMsg.msg, pMsg, pMsg->msgLen); -// -// schedMsg.fp = mgmtProcessTranRequest; -// schedMsg.tfp = NULL; -// schedMsg.thandle = pConn; -// -// taosScheduleTask(tsMgmtTranQhandle, &schedMsg); -// } else { -// mError("%s from shell is not processed", taosMsg[pMsg->msgType]); -// } -// } -// } else { -// taosSendSimpleRsp(thandle, pMsg->msgType + 1, TSDB_CODE_DISCONNECTED); -// } -// } -// -// if (pConn->pAcct == NULL) { -// taosCloseRpcConn(pConn->thandle); -// memset(pConn, 0, sizeof(SConnObj)); // close the connection; -// pConn = NULL; -// } -// -// return pConn; + SConnectRsp *pConnectRsp = rpcMallocCont(sizeof(SConnectRsp)); + if (pConnectRsp == NULL) { + code = TSDB_CODE_SERV_OUT_OF_MEMORY; + goto connect_over; + } + + sprintf(pConnectRsp->acctId, "%x", pAcct->acctId); + strcpy(pConnectRsp->serverVersion, version); + pConnectRsp->writeAuth = pUser->writeAuth; + pConnectRsp->superAuth = pUser->superAuth; + pConnectRsp->ipList.inUse = 0; + pConnectRsp->ipList.port = htons(tsMgmtShellPort); + pConnectRsp->ipList.numOfIps = 0; + if (pSdbPublicIpList != NULL && pSdbIpList != NULL) { + pConnectRsp->ipList.numOfIps = htons(pSdbPublicIpList->numOfIps); + if (connInfo.serverIp == tsPublicIpInt) { + for (int i = 0; i < pSdbPublicIpList->numOfIps; ++i) { + pConnectRsp->ipList.ip[i] = htonl(pSdbPublicIpList->ip[i]); + } + } else { + for (int i = 0; i < pSdbIpList->numOfIps; ++i) { + pConnectRsp->ipList.ip[i] = htonl(pSdbIpList->ip[i]); + } + } + } + +connect_over: + if (code != TSDB_CODE_SUCCESS) { + mLError("user:%s login from %s, code:%d", connInfo.user, taosIpStr(connInfo.clientIp), code); + rpcSendResponse(thandle, code, NULL, 0); + } else { + mLPrint("user:%s login from %s, code:%d", connInfo.user, taosIpStr(connInfo.clientIp), code); + rpcSendResponse(thandle, code, pConnectRsp, sizeof(SConnectRsp)); + } } -void mgmtInitProcessShellMsg() { - mgmtProcessShellMsg[TSDB_MSG_TYPE_TABLE_META] = mgmtProcessMeterMetaMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_STABLE_META] = mgmtProcessMetricMetaMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_MULTI_TABLE_META] = mgmtProcessMultiMeterMetaMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_DB] = mgmtProcessCreateDbMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_ALTER_DB] = mgmtProcessAlterDbMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_USER] = mgmtProcessCreateUserMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_ALTER_USER] = mgmtProcessAlterUserMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_ACCT] = mgmtProcessCreateAcctMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_DB] = mgmtProcessDropDbMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_USER] = mgmtProcessDropUserMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_ACCT] = mgmtProcessDropAcctMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_ALTER_ACCT] = mgmtProcessAlterAcctMsg; - - mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_TABLE] = mgmtProcessCreateTableMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_TABLE] = mgmtProcessDropTableMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_ALTER_TABLE] = mgmtProcessAlterTableMsg; - - mgmtProcessShellMsg[TSDB_MSG_TYPE_USE_DB] = mgmtProcessUseDbMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_DNODE_RETRIEVE] = mgmtProcessRetrieveMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_SHOW] = mgmtProcessShowMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_CONNECT] = mgmtProcessConnectMsg; -// mgmtProcessShellMsg[TSDB_MSG_TYPE_HEARTBEAT] = mgmtProcessHeartBeatMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_DNODE] = mgmtProcessCreateDnodeMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_DNODE] = mgmtProcessDropDnodeMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_MNODE] = mgmtProcessCreateMnodeMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_MNODE] = mgmtProcessDropMnodeMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_CFG_MNODE] = mgmtProcessCfgMnodeMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_DNODE_CFG] = mgmtProcessCfgDnodeMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_KILL_QUERY] = mgmtProcessKillQueryMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_KILL_STREAM] = mgmtProcessKillStreamMsg; - mgmtProcessShellMsg[TSDB_MSG_TYPE_KILL_CONNECTION] = mgmtProcessKillConnectionMsg; +/** + * check if we need to add mgmtProcessTableMetaMsg into tranQueue, which will be executed one-by-one. + */ +static bool mgmtCheckMeterMetaMsgType(void *pMsg) { + STableInfoMsg *pInfo = (STableInfoMsg *) pMsg; + int16_t autoCreate = htons(pInfo->createFlag); + STableInfo *pTable = mgmtGetTable(pInfo->tableId); + + // If table does not exists and autoCreate flag is set, we add the handler into task queue + bool addIntoTranQueue = (pTable == NULL && autoCreate == 1); + if (addIntoTranQueue) { + mTrace("table:%s auto created task added", pInfo->tableId); + } + + return addIntoTranQueue; } -int32_t mgmtCheckRedirectMsgImp(SConnObj *pConn, int32_t msgType) { - return 0; +static bool mgmtCheckMsgReadOnly(int8_t type, void *pCont) { + if ((type == TSDB_MSG_TYPE_TABLE_META && (!mgmtCheckMeterMetaMsgType(pCont))) || + type == TSDB_MSG_TYPE_STABLE_META || type == TSDB_MSG_TYPE_RETRIEVE || + type == TSDB_MSG_TYPE_SHOW || type == TSDB_MSG_TYPE_MULTI_TABLE_META || + type == TSDB_MSG_TYPE_CONNECT) { + return true; + } + + return false; } -int32_t (*mgmtCheckRedirectMsg)(SConnObj *pConn, int32_t msgType) = mgmtCheckRedirectMsgImp; -int32_t mgmtProcessAlterAcctMsgImp(char *pMsg, int32_t msgLen, SConnObj *pConn) { - //return taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_ALTER_ACCT_RSP, TSDB_CODE_OPS_NOT_SUPPORT); - return 0; +static void mgmtProcessMsgFromShell(char type, void *pCont, int contLen, void *ahandle, int32_t code) { + if (sdbGetRunStatus() != SDB_STATUS_SERVING) { + mTrace("shell msg is ignored since SDB is not ready"); + rpcSendResponse(ahandle, TSDB_CODE_NOT_READY, NULL, 0); + rpcFreeCont(pCont); + return; + } + + if (mgmtCheckMsgReadOnly(type, pCont)) { + (*mgmtProcessShellMsg[(int8_t)type])(pCont, contLen, ahandle); + } else { + if (mgmtProcessShellMsg[(int8_t)type]) { + mgmtAddToTranRequest((int8_t)type, pCont, contLen, ahandle); + } else { + mError("%s from shell is not processed", taosMsg[(int8_t)type]); + } + } + + //TODO free may be cause segment fault + // + // rpcFreeCont(pCont); } -int32_t (*mgmtProcessAlterAcctMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn) = mgmtProcessAlterAcctMsgImp; -int32_t mgmtProcessCreateDnodeMsgImp(char *pMsg, int32_t msgLen, SConnObj *pConn) { - //return taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_CREATE_DNODE_RSP, TSDB_CODE_OPS_NOT_SUPPORT); - return 0; +void mgmtInitProcessShellMsg() { + mgmtProcessShellMsg[TSDB_MSG_TYPE_CONNECT] = mgmtProcessConnectMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_HEARTBEAT] = mgmtProcessHeartBeatMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_DB] = mgmtProcessCreateDbMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_ALTER_DB] = mgmtProcessAlterDbMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_DB] = mgmtProcessDropDbMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_USE_DB] = mgmtProcessUnSupportMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_USER] = mgmtProcessCreateUserMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_ALTER_USER] = mgmtProcessAlterUserMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_USER] = mgmtProcessDropUserMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_ACCT] = mgmtProcessCreateAcctMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_ACCT] = mgmtProcessDropAcctMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_ALTER_ACCT] = mgmtProcessAlterAcctMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_TABLE] = mgmtProcessCreateTableMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_TABLE] = mgmtProcessDropTableMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_ALTER_TABLE] = mgmtProcessAlterTableMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_DNODE] = mgmtProcessCreateDnodeMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_DNODE] = mgmtProcessDropDnodeMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_DNODE_CFG] = mgmtProcessCfgDnodeMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_CREATE_MNODE] = mgmtProcessUnSupportMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_DROP_MNODE] = mgmtProcessDropMnodeMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_CFG_MNODE] = mgmtProcessCfgMnodeMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_KILL_QUERY] = mgmtProcessKillQueryMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_KILL_STREAM] = mgmtProcessKillStreamMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_KILL_CONNECTION] = mgmtProcessKillConnectionMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_SHOW] = mgmtProcessShowMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_RETRIEVE] = mgmtProcessRetrieveMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_TABLE_META] = mgmtProcessTableMetaMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_MULTI_TABLE_META] = mgmtProcessMultiTableMetaMsg; + mgmtProcessShellMsg[TSDB_MSG_TYPE_STABLE_META] = mgmtProcessSuperTableMetaMsg; } -int32_t (*mgmtProcessCreateDnodeMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn) = mgmtProcessCreateDnodeMsgImp; -int32_t mgmtProcessCfgMnodeMsgImp(char *pMsg, int32_t msgLen, SConnObj *pConn) { - //return taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_CFG_MNODE_RSP, TSDB_CODE_OPS_NOT_SUPPORT); - return 0; +void mgmtProcessCreateVgroup(SCreateTableMsg *pCreate, int32_t contLen, void *thandle, bool isGetMeta) { + SDbObj *pDb = mgmtGetDb(pCreate->db); + if (pDb == NULL) { + mError("table:%s, failed to create vgroup, db not found", pCreate->tableId); + rpcSendResponse(thandle, TSDB_CODE_INVALID_DB, NULL, 0); + return; + } + + SVgObj *pVgroup = mgmtCreateVgroup(pDb); + if (pVgroup == NULL) { + mError("table:%s, failed to alloc vnode to vgroup", pCreate->tableId); + rpcSendResponse(thandle, TSDB_CODE_NO_ENOUGH_DNODES, NULL, 0); + return; + } + + void *cont = rpcMallocCont(contLen); + if (cont == NULL) { + mError("table:%s, failed to create table, can not alloc memory", pCreate->tableId); + rpcSendResponse(thandle, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); + return; + } + + memcpy(cont, pCreate, contLen); + + SProcessInfo *info = calloc(1, sizeof(SProcessInfo)); + info->type = TSDB_PROCESS_CREATE_VGROUP; + info->thandle = thandle; + info->ahandle = pVgroup; + info->cont = cont; + info->contLen = contLen; + + if (isGetMeta) { + info->type = TSDB_PROCESS_CREATE_VGROUP_GET_META; + } + + mgmtSendCreateVgroupMsg(pVgroup, info); } -int32_t (*mgmtProcessCfgMnodeMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn) = mgmtProcessCfgMnodeMsgImp; -int32_t mgmtProcessDropMnodeMsgImp(char *pMsg, int32_t msgLen, SConnObj *pConn) { - //return taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_MNODE_RSP, TSDB_CODE_OPS_NOT_SUPPORT); - return 0; +void mgmtProcessCreateTable(SVgObj *pVgroup, SCreateTableMsg *pCreate, int32_t contLen, void *thandle, bool isGetMeta) { + assert(pVgroup != NULL); + + int32_t sid = taosAllocateId(pVgroup->idPool); + if (sid < 0) { + mTrace("table:%s, no enough sid in vgroup:%d, start to create a new vgroup", pCreate->tableId, pVgroup->vgId); + mgmtProcessCreateVgroup(pCreate, contLen, thandle, isGetMeta); + return; + } + + int32_t code; + STableInfo *pTable; + SDCreateTableMsg *pDCreate = NULL; + + if (pCreate->numOfColumns == 0) { + mTrace("table:%s, start to create child table, vgroup:%d sid:%d", pCreate->tableId, pVgroup->vgId, sid); + code = mgmtCreateChildTable(pCreate, contLen, pVgroup, sid, &pDCreate, &pTable); + } else { + mTrace("table:%s, start to create normal table, vgroup:%d sid:%d", pCreate->tableId, pVgroup->vgId, sid); + code = mgmtCreateNormalTable(pCreate, contLen, pVgroup, sid, &pDCreate, &pTable); + } + + if (code != TSDB_CODE_SUCCESS) { + mTrace("table:%s, failed to create table in vgroup:%d sid:%d ", pCreate->tableId, pVgroup->vgId, sid); + rpcSendResponse(thandle, code, NULL, 0); + return; + } + + assert(pDCreate != NULL); + assert(pTable != NULL); + + SProcessInfo *info = calloc(1, sizeof(SProcessInfo)); + info->type = TSDB_PROCESS_CREATE_TABLE; + info->thandle = thandle; + info->ahandle = pTable; + SRpcIpSet ipSet = mgmtGetIpSetFromVgroup(pVgroup); + if (isGetMeta) { + info->type = TSDB_PROCESS_CREATE_TABLE_GET_META; + } + + mgmtSendCreateTableMsg(pDCreate, &ipSet, info); } -int32_t (*mgmtProcessDropMnodeMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn) = mgmtProcessDropMnodeMsgImp; -int32_t mgmtProcessDropDnodeMsgImp(char *pMsg, int32_t msgLen, SConnObj *pConn) { - //return taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_DNODE_RSP, TSDB_CODE_OPS_NOT_SUPPORT); - return 0; +void mgmtProcessGetTableMeta(STableInfo *pTable, void *thandle) { + SDbObj* pDb = mgmtGetDbByTableId(pTable->tableId); + if (pDb == NULL || pDb->dropStatus != TSDB_DB_STATUS_READY) { + mError("table:%s, failed to get table meta, db not selected", pTable->tableId); + rpcSendResponse(thandle, TSDB_CODE_DB_NOT_SELECTED, NULL, 0); + return; + } + + SRpcConnInfo connInfo; + rpcGetConnInfo(thandle, &connInfo); + bool usePublicIp = (connInfo.serverIp == tsPublicIpInt); + + STableMeta *pMeta = rpcMallocCont(sizeof(STableMeta) + sizeof(SSchema) * TSDB_MAX_COLUMNS); + int32_t code = mgmtGetTableMeta(pDb, pTable, pMeta, usePublicIp); + + if (code != TSDB_CODE_SUCCESS) { + rpcFreeCont(pMeta); + rpcSendResponse(thandle, TSDB_CODE_SUCCESS, NULL, 0); + } else { + pMeta->contLen = htons(pMeta->contLen); + rpcSendResponse(thandle, TSDB_CODE_SUCCESS, pMeta, pMeta->contLen); + } } -int32_t (*mgmtProcessDropDnodeMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn) = mgmtProcessDropDnodeMsgImp; -int32_t mgmtProcessDropAcctMsgImp(char *pMsg, int32_t msgLen, SConnObj *pConn) { -// return taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_DROP_ACCT_RSP, TSDB_CODE_OPS_NOT_SUPPORT); +static int32_t mgmtCheckRedirectMsgImp(void *pConn) { return 0; } -int32_t (*mgmtProcessDropAcctMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn) = mgmtProcessDropAcctMsgImp; -int32_t mgmtProcessCreateAcctMsgImp(char *pMsg, int32_t msgLen, SConnObj *pConn) { -// return taosSendSimpleRsp(pConn->thandle, TSDB_MSG_TYPE_CREATE_ACCT_RSP, TSDB_CODE_OPS_NOT_SUPPORT); - return 0; +int32_t (*mgmtCheckRedirectMsg)(void *pConn) = mgmtCheckRedirectMsgImp; + +static void mgmtProcessUnSupportMsg(void *pCont, int32_t contLen, void *ahandle) { + rpcSendResponse(ahandle, TSDB_CODE_OPS_NOT_SUPPORT, NULL, 0); } -int32_t (*mgmtProcessCreateAcctMsg)(char *pMsg, int32_t msgLen, SConnObj *pConn) = mgmtProcessCreateAcctMsgImp; \ No newline at end of file + +void (*mgmtProcessAlterAcctMsg)(void *pCont, int32_t contLen, void *ahandle) = mgmtProcessUnSupportMsg; +void (*mgmtProcessCreateDnodeMsg)(void *pCont, int32_t contLen, void *ahandle) = mgmtProcessUnSupportMsg; +void (*mgmtProcessCfgMnodeMsg)(void *pCont, int32_t contLen, void *ahandle) = mgmtProcessUnSupportMsg; +void (*mgmtProcessDropMnodeMsg)(void *pCont, int32_t contLen, void *ahandle) = mgmtProcessUnSupportMsg; +void (*mgmtProcessDropDnodeMsg)(void *pCont, int32_t contLen, void *ahandle) = mgmtProcessUnSupportMsg; +void (*mgmtProcessDropAcctMsg)(void *pCont, int32_t contLen, void *ahandle) = mgmtProcessUnSupportMsg; +void (*mgmtProcessCreateAcctMsg)(void *pCont, int32_t contLen, void *ahandle) = mgmtProcessUnSupportMsg; \ No newline at end of file diff --git a/src/mnode/src/mgmtStreamTable.c b/src/mnode/src/mgmtStreamTable.c deleted file mode 100644 index 031954bb1573ea5dae72233d0307f6624ad6df59..0000000000000000000000000000000000000000 --- a/src/mnode/src/mgmtStreamTable.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "taosmsg.h" -#include "tast.h" -#include "textbuffer.h" -#include "tschemautil.h" -#include "tscompression.h" -#include "tskiplist.h" -#include "tsqlfunction.h" -#include "ttime.h" -#include "tstatus.h" -#include "tutil.h" -#include "mnode.h" -#include "mgmtAcct.h" -#include "mgmtDb.h" -#include "mgmtDnodeInt.h" -#include "mgmtGrant.h" -#include "mgmtStreamTable.h" -#include "mgmtSuperTable.h" -#include "mgmtTable.h" -#include "mgmtVgroup.h" - -void *tsStreamTableSdb; -void *(*mgmtStreamTableActionFp[SDB_MAX_ACTION_TYPES])(void *row, char *str, int32_t size, int32_t *ssize); - -void *mgmtStreamTableActionInsert(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtStreamTableActionDelete(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtStreamTableActionUpdate(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtStreamTableActionEncode(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtStreamTableActionDecode(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtStreamTableActionReset(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtStreamTableActionDestroy(void *row, char *str, int32_t size, int32_t *ssize); - -static void mgmtDestroyStreamTable(SStreamTableObj *pTable) { - free(pTable->schema); - free(pTable->sql); - free(pTable); -} - -static void mgmtStreamTableActionInit() { - mgmtStreamTableActionFp[SDB_TYPE_INSERT] = mgmtStreamTableActionInsert; - mgmtStreamTableActionFp[SDB_TYPE_DELETE] = mgmtStreamTableActionDelete; - mgmtStreamTableActionFp[SDB_TYPE_UPDATE] = mgmtStreamTableActionUpdate; - mgmtStreamTableActionFp[SDB_TYPE_ENCODE] = mgmtStreamTableActionEncode; - mgmtStreamTableActionFp[SDB_TYPE_DECODE] = mgmtStreamTableActionDecode; - mgmtStreamTableActionFp[SDB_TYPE_RESET] = mgmtStreamTableActionReset; - mgmtStreamTableActionFp[SDB_TYPE_DESTROY] = mgmtStreamTableActionDestroy; -} - -void *mgmtStreamTableActionReset(void *row, char *str, int32_t size, int32_t *ssize) { - SStreamTableObj *pTable = (SStreamTableObj *) row; - int32_t tsize = pTable->updateEnd - (int8_t *) pTable; - memcpy(pTable, str, tsize); - - int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - pTable->schema = (SSchema *) realloc(pTable->schema, schemaSize); - memcpy(pTable->schema, str + tsize, schemaSize); - - pTable->sql = (char *) realloc(pTable->sql, pTable->sqlLen); - memcpy(pTable->sql, str + tsize + schemaSize, pTable->sqlLen); - return NULL; -} - -void *mgmtStreamTableActionDestroy(void *row, char *str, int32_t size, int32_t *ssize) { - SStreamTableObj *pTable = (SStreamTableObj *)row; - mgmtDestroyStreamTable(pTable); - return NULL; -} - -void *mgmtStreamTableActionInsert(void *row, char *str, int32_t size, int32_t *ssize) { - SNormalTableObj *pTable = (SNormalTableObj *) row; - - SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - mError("id:%s not in vgroup:%d", pTable->tableId, pTable->vgId); - return NULL; - } - - SDbObj *pDb = mgmtGetDb(pVgroup->dbName); - if (pDb == NULL) { - mError("vgroup:%d not in DB:%s", pVgroup->vgId, pVgroup->dbName); - return NULL; - } - - SAcctObj *pAcct = mgmtGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("account not exists"); - return NULL; - } - - if (!sdbMaster) { - int32_t sid = taosAllocateId(pVgroup->idPool); - if (sid != pTable->sid) { - mError("sid:%d is not matched from the master:%d", sid, pTable->sid); - return NULL; - } - } - - pAcct->acctInfo.numOfTimeSeries += (pTable->numOfColumns - 1); - pVgroup->numOfTables++; - pDb->numOfTables++; - pVgroup->tableList[pTable->sid] = (STableInfo *) pTable; - - if (pVgroup->numOfTables >= pDb->cfg.maxSessions - 1 && pDb->numOfVgroups > 1) { - mgmtMoveVgroupToTail(pDb, pVgroup); - } - - return NULL; -} - -void *mgmtStreamTableActionDelete(void *row, char *str, int32_t size, int32_t *ssize) { - SNormalTableObj *pTable = (SNormalTableObj *) row; - if (pTable->vgId == 0) { - return NULL; - } - - SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - mError("id:%s not in vgroup:%d", pTable->tableId, pTable->vgId); - return NULL; - } - - SDbObj *pDb = mgmtGetDb(pVgroup->dbName); - if (pDb == NULL) { - mError("vgroup:%d not in DB:%s", pVgroup->vgId, pVgroup->dbName); - return NULL; - } - - SAcctObj *pAcct = mgmtGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("account not exists"); - return NULL; - } - - pAcct->acctInfo.numOfTimeSeries -= (pTable->numOfColumns - 1); - pVgroup->tableList[pTable->sid] = NULL; - pVgroup->numOfTables--; - pDb->numOfTables--; - taosFreeId(pVgroup->idPool, pTable->sid); - - if (pVgroup->numOfTables > 0) { - mgmtMoveVgroupToHead(pDb, pVgroup); - } - - return NULL; -} - -void *mgmtStreamTableActionUpdate(void *row, char *str, int32_t size, int32_t *ssize) { - return mgmtStreamTableActionReset(row, str, size, NULL); -} - -void *mgmtStreamTableActionEncode(void *row, char *str, int32_t size, int32_t *ssize) { - SStreamTableObj *pTable = (SStreamTableObj *) row; - assert(row != NULL && str != NULL); - - int32_t tsize = pTable->updateEnd - (int8_t *) pTable; - int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - if (size < tsize + schemaSize + pTable->sqlLen + 1) { - *ssize = -1; - return NULL; - } - - memcpy(str, pTable, tsize); - memcpy(str + tsize, pTable->schema, schemaSize); - memcpy(str + tsize + schemaSize, pTable->sql, pTable->sqlLen); - *ssize = tsize + schemaSize + pTable->sqlLen; - - return NULL; -} - -void *mgmtStreamTableActionDecode(void *row, char *str, int32_t size, int32_t *ssize) { - assert(str != NULL); - - SStreamTableObj *pTable = (SStreamTableObj *)malloc(sizeof(SNormalTableObj)); - if (pTable == NULL) { - return NULL; - } - memset(pTable, 0, sizeof(STabObj)); - - int32_t tsize = pTable->updateEnd - (int8_t *)pTable; - if (size < tsize) { - mgmtDestroyStreamTable(pTable); - return NULL; - } - memcpy(pTable, str, tsize); - - int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - pTable->schema = (SSchema *)malloc(schemaSize); - if (pTable->schema == NULL) { - mgmtDestroyStreamTable(pTable); - return NULL; - } - memcpy(pTable->schema, str + tsize, schemaSize); - - pTable->sql = (char *)malloc(pTable->sqlLen); - if (pTable->sql == NULL) { - mgmtDestroyStreamTable(pTable); - return NULL; - } - memcpy(pTable->sql, str + tsize + schemaSize, pTable->sqlLen); - return (void *)pTable; -} - -void *mgmtStreamTableAction(char action, void *row, char *str, int32_t size, int32_t *ssize) { - if (mgmtStreamTableActionFp[(uint8_t)action] != NULL) { - return (*(mgmtStreamTableActionFp[(uint8_t)action]))(row, str, size, ssize); - } - return NULL; -} - -int32_t mgmtInitStreamTables() { - void *pNode = NULL; - void *pLastNode = NULL; - SChildTableObj *pTable = NULL; - - mgmtStreamTableActionInit(); - - tsStreamTableSdb = sdbOpenTable(tsMaxTables, sizeof(SStreamTableObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS + TSDB_MAX_SQL_LEN, - "streams", SDB_KEYTYPE_STRING, tsMgmtDirectory, mgmtStreamTableAction); - if (tsStreamTableSdb == NULL) { - mError("failed to init stream table data"); - return -1; - } - - pNode = NULL; - while (1) { - pNode = sdbFetchRow(tsStreamTableSdb, pNode, (void **)&pTable); - if (pTable == NULL) { - break; - } - - SDbObj *pDb = mgmtGetDbByTableId(pTable->tableId); - if (pDb == NULL) { - mError("stream table:%s, failed to get db, discard it", pTable->tableId); - sdbDeleteRow(tsStreamTableSdb, pTable); - pNode = pLastNode; - continue; - } - } - - mgmtSetVgroupIdPool(); - - mTrace("stream table is initialized"); - return 0; -} - -void mgmtCleanUpStreamTables() { -} - -int8_t *mgmtBuildCreateStreamTableMsg(SStreamTableObj *pTable, SVgObj *pVgroup) { -// SDCreateTableMsg *pCreateTable = (SDCreateTableMsg *) pMsg; -// memcpy(pCreateTable->tableId, pTable->tableId, TSDB_TABLE_ID_LEN); -// pCreateTable->vnode = htonl(vnode); -// pCreateTable->sid = htonl(pTable->sid); -// pCreateTable->uid = pTable->uid; -// pCreateTable->createdTime = htobe64(pTable->createdTime); -// pCreateTable->sversion = htonl(pTable->sversion); -// pCreateTable->numOfColumns = htons(pTable->numOfColumns); -// //pCreateTable->sqlLen = htons(pTable->sqlLen); -// -// SSchema *pSchema = pTable->schema; -// int32_t totalCols = pCreateTable->numOfColumns; - -// for (int32_t col = 0; col < totalCols; ++col) { -// SMColumn *colData = &((SMColumn *) (pCreateTable->data))[col]; -// colData->type = pSchema[col].type; -// colData->bytes = htons(pSchema[col].bytes); -// colData->colId = htons(pSchema[col].colId); -// } - -// int32_t totalColsSize = sizeof(SMColumn *) * totalCols; -// pMsg = pCreateTable->data + totalColsSize + pTable->sqlLen; - -// char *sql = pTable->schema + pTable->schemaSize; -// memcpy(pCreateTable->data + totalColsSize, pTable->sqlLen, sql); - -// return pMsg; - return NULL; -} - -int32_t mgmtCreateStreamTable(SDbObj *pDb, SCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t sid) { - int32_t numOfTables = sdbGetNumOfRows(tsStreamTableSdb); - if (numOfTables >= TSDB_MAX_TABLES) { - mError("stream table:%s, numOfTables:%d exceed maxTables:%d", pCreate->meterId, numOfTables, TSDB_MAX_TABLES); - return TSDB_CODE_TOO_MANY_TABLES; - } - - SStreamTableObj *pTable = (SStreamTableObj *) calloc(sizeof(SStreamTableObj), 1); - if (pTable == NULL) { - return TSDB_CODE_SERV_OUT_OF_MEMORY; - } - - strcpy(pTable->tableId, pCreate->meterId); - pTable->createdTime = taosGetTimestampMs(); - pTable->vgId = pVgroup->vgId; - pTable->sid = sid; - pTable->uid = (((uint64_t) pTable->createdTime) << 16) + ((uint64_t) sdbGetVersion() & ((1ul << 16) - 1ul)); - pTable->sversion = 0; - pTable->numOfColumns = pCreate->numOfColumns; - - int32_t numOfCols = pCreate->numOfColumns + pCreate->numOfTags; - int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - pTable->schema = (SSchema *) calloc(1, schemaSize); - if (pTable->schema == NULL) { - free(pTable); - mError("table:%s, no schema input", pCreate->meterId); - return TSDB_CODE_INVALID_TABLE; - } - memcpy(pTable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); - - pTable->nextColId = 0; - for (int32_t col = 0; col < pCreate->numOfColumns; col++) { - SSchema *tschema = (SSchema *) pTable->schema; - tschema[col].colId = pTable->nextColId++; - } - - pTable->sql = (char*)(pTable->schema + numOfCols * sizeof(SSchema)); - memcpy(pTable->sql, (char *) (pCreate->schema) + numOfCols * sizeof(SSchema), pCreate->sqlLen); - pTable->sql[pCreate->sqlLen - 1] = 0; - mTrace("table:%s, stream sql len:%d sql:%s", pCreate->meterId, pCreate->sqlLen, pTable->sql); - - if (sdbInsertRow(tsStreamTableSdb, pTable, 0) < 0) { - mError("table:%s, update sdb error", pCreate->meterId); - return TSDB_CODE_SDB_ERROR; - } - - mgmtAddTimeSeries(pTable->numOfColumns - 1); - - mgmtSendCreateStreamTableMsg(pTable, pVgroup); - - mTrace("table:%s, create table in vgroup, vgId:%d sid:%d vnode:%d uid:%" - PRIu64 - " db:%s", - pTable->tableId, pVgroup->vgId, sid, pVgroup->vnodeGid[0].vnode, pTable->uid, pDb->name); - - return 0; -} - -int32_t mgmtDropStreamTable(SDbObj *pDb, SStreamTableObj *pTable) { - SVgObj * pVgroup; - SAcctObj *pAcct; - - pAcct = mgmtGetAcct(pDb->cfg.acct); - - if (pAcct != NULL) { - pAcct->acctInfo.numOfTimeSeries -= (pTable->numOfColumns - 1); - } - - pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - return TSDB_CODE_OTHERS; - } - - mgmtRestoreTimeSeries(pTable->numOfColumns - 1); - - mgmtSendRemoveMeterMsgToDnode((STableInfo *) pTable, pVgroup); - - sdbDeleteRow(tsChildTableSdb, pTable); - - if (pVgroup->numOfTables <= 0) { - mgmtDropVgroup(pDb, pVgroup); - } - - return 0; -} - -SStreamTableObj* mgmtGetStreamTable(char *tableId) { - return (SStreamTableObj *)sdbGetRow(tsStreamTableSdb, tableId); -} \ No newline at end of file diff --git a/src/mnode/src/mgmtSuperTable.c b/src/mnode/src/mgmtSuperTable.c index efdda6f22351db9646427f481a4f2d6480de9bd0..6a74f7616d224749bf9e574c00542d50e34d24d7 100644 --- a/src/mnode/src/mgmtSuperTable.c +++ b/src/mnode/src/mgmtSuperTable.c @@ -29,22 +29,25 @@ #include "mgmtAcct.h" #include "mgmtChildTable.h" #include "mgmtDb.h" +#include "mgmtDnode.h" #include "mgmtDnodeInt.h" #include "mgmtGrant.h" #include "mgmtSuperTable.h" #include "mgmtTable.h" +#include "mgmtUser.h" #include "mgmtVgroup.h" -void *tsSuperTableSdb; -void *(*mgmtSuperTableActionFp[SDB_MAX_ACTION_TYPES])(void *row, char *str, int32_t size, int32_t *ssize); +static void *tsSuperTableSdb; +static int32_t tsSuperTableUpdateSize; -void *mgmtSuperTableActionInsert(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtSuperTableActionDelete(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtSuperTableActionUpdate(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtSuperTableActionEncode(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtSuperTableActionDecode(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtSuperTableActionReset(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtSuperTableActionDestroy(void *row, char *str, int32_t size, int32_t *ssize); +static void *(*mgmtSuperTableActionFp[SDB_MAX_ACTION_TYPES])(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtSuperTableActionInsert(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtSuperTableActionDelete(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtSuperTableActionUpdate(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtSuperTableActionEncode(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtSuperTableActionDecode(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtSuperTableActionReset(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtSuperTableActionDestroy(void *row, char *str, int32_t size, int32_t *ssize); static void mgmtDestroySuperTable(SSuperTableObj *pTable) { free(pTable->schema); @@ -52,23 +55,25 @@ static void mgmtDestroySuperTable(SSuperTableObj *pTable) { } static void mgmtSuperTableActionInit() { - mgmtSuperTableActionFp[SDB_TYPE_INSERT] = mgmtSuperTableActionInsert; - mgmtSuperTableActionFp[SDB_TYPE_DELETE] = mgmtSuperTableActionDelete; - mgmtSuperTableActionFp[SDB_TYPE_UPDATE] = mgmtSuperTableActionUpdate; - mgmtSuperTableActionFp[SDB_TYPE_ENCODE] = mgmtSuperTableActionEncode; - mgmtSuperTableActionFp[SDB_TYPE_DECODE] = mgmtSuperTableActionDecode; - mgmtSuperTableActionFp[SDB_TYPE_RESET] = mgmtSuperTableActionReset; + SSuperTableObj tObj; + tsSuperTableUpdateSize = tObj.updateEnd - (int8_t *)&tObj; + + mgmtSuperTableActionFp[SDB_TYPE_INSERT] = mgmtSuperTableActionInsert; + mgmtSuperTableActionFp[SDB_TYPE_DELETE] = mgmtSuperTableActionDelete; + mgmtSuperTableActionFp[SDB_TYPE_UPDATE] = mgmtSuperTableActionUpdate; + mgmtSuperTableActionFp[SDB_TYPE_ENCODE] = mgmtSuperTableActionEncode; + mgmtSuperTableActionFp[SDB_TYPE_DECODE] = mgmtSuperTableActionDecode; + mgmtSuperTableActionFp[SDB_TYPE_RESET] = mgmtSuperTableActionReset; mgmtSuperTableActionFp[SDB_TYPE_DESTROY] = mgmtSuperTableActionDestroy; } void *mgmtSuperTableActionReset(void *row, char *str, int32_t size, int32_t *ssize) { SSuperTableObj *pTable = (SSuperTableObj *) row; - int32_t tsize = pTable->updateEnd - (int8_t *) pTable; - memcpy(pTable, str, tsize); + memcpy(pTable, str, tsSuperTableUpdateSize); int32_t schemaSize = sizeof(SSchema) * (pTable->numOfColumns + pTable->numOfTags); pTable->schema = realloc(pTable->schema, schemaSize); - memcpy(pTable->schema, str + tsize, schemaSize); + memcpy(pTable->schema, str + tsSuperTableUpdateSize, schemaSize); return NULL; } @@ -80,10 +85,20 @@ void *mgmtSuperTableActionDestroy(void *row, char *str, int32_t size, int32_t *s } void *mgmtSuperTableActionInsert(void *row, char *str, int32_t size, int32_t *ssize) { + STableInfo *pTable = (STableInfo *) row; + SDbObj *pDb = mgmtGetDbByTableId(pTable->tableId); + if (pDb) { + mgmtAddSuperTableIntoDb(pDb); + } return NULL; } void *mgmtSuperTableActionDelete(void *row, char *str, int32_t size, int32_t *ssize) { + STableInfo *pTable = (STableInfo *) row; + SDbObj *pDb = mgmtGetDbByTableId(pTable->tableId); + if (pDb) { + mgmtRemoveSuperTableFromDb(pDb); + } return NULL; } @@ -95,17 +110,16 @@ void *mgmtSuperTableActionEncode(void *row, char *str, int32_t size, int32_t *ss SSuperTableObj *pTable = (SSuperTableObj *) row; assert(row != NULL && str != NULL); - int32_t tsize = pTable->updateEnd - (int8_t *) pTable; int32_t schemaSize = sizeof(SSchema) * (pTable->numOfColumns + pTable->numOfTags); - if (size < tsize + schemaSize + 1) { + if (size < tsSuperTableUpdateSize + schemaSize + 1) { *ssize = -1; return NULL; } - memcpy(str, pTable, tsize); - memcpy(str + tsize, pTable->schema, schemaSize); - *ssize = tsize + schemaSize; + memcpy(str, pTable, tsSuperTableUpdateSize); + memcpy(str + tsSuperTableUpdateSize, pTable->schema, schemaSize); + *ssize = tsSuperTableUpdateSize + schemaSize; return NULL; } @@ -113,18 +127,17 @@ void *mgmtSuperTableActionEncode(void *row, char *str, int32_t size, int32_t *ss void *mgmtSuperTableActionDecode(void *row, char *str, int32_t size, int32_t *ssize) { assert(str != NULL); - SSuperTableObj *pTable = (SSuperTableObj *)malloc(sizeof(SSuperTableObj)); + SSuperTableObj *pTable = (SSuperTableObj *) malloc(sizeof(SSuperTableObj)); if (pTable == NULL) { return NULL; } - memset(pTable, 0, sizeof(STabObj)); + memset(pTable, 0, sizeof(SSuperTableObj)); - int32_t tsize = pTable->updateEnd - (int8_t *)pTable; - if (size < tsize) { + if (size < tsSuperTableUpdateSize) { mgmtDestroySuperTable(pTable); return NULL; } - memcpy(pTable, str, tsize); + memcpy(pTable, str, tsSuperTableUpdateSize); int32_t schemaSize = sizeof(SSchema) * (pTable->numOfColumns + pTable->numOfTags); pTable->schema = malloc(schemaSize); @@ -133,34 +146,34 @@ void *mgmtSuperTableActionDecode(void *row, char *str, int32_t size, int32_t *ss return NULL; } - memcpy(pTable->schema, str + tsize, schemaSize); - return (void *)pTable; + memcpy(pTable->schema, str + tsSuperTableUpdateSize, schemaSize); + return (void *) pTable; } void *mgmtSuperTableAction(char action, void *row, char *str, int32_t size, int32_t *ssize) { - if (mgmtSuperTableActionFp[(uint8_t)action] != NULL) { - return (*(mgmtSuperTableActionFp[(uint8_t)action]))(row, str, size, ssize); + if (mgmtSuperTableActionFp[(uint8_t) action] != NULL) { + return (*(mgmtSuperTableActionFp[(uint8_t) action]))(row, str, size, ssize); } return NULL; } int32_t mgmtInitSuperTables() { - void * pNode = NULL; - void * pLastNode = NULL; - SSuperTableObj * pTable = NULL; + void *pNode = NULL; + void *pLastNode = NULL; + SSuperTableObj *pTable = NULL; mgmtSuperTableActionInit(); - tsSuperTableSdb = sdbOpenTable(tsMaxTables, sizeof(STabObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS, + tsSuperTableSdb = sdbOpenTable(tsMaxTables, tsSuperTableUpdateSize + sizeof(SSchema) * TSDB_MAX_COLUMNS, "stables", SDB_KEYTYPE_STRING, tsMgmtDirectory, mgmtSuperTableAction); if (tsSuperTableSdb == NULL) { - mError("failed to init super table data"); + mError("failed to init stables data"); return -1; } pNode = NULL; while (1) { - pNode = sdbFetchRow(tsSuperTableSdb, pNode, (void **)&pTable); + pNode = sdbFetchRow(tsSuperTableSdb, pNode, (void **) &pTable); if (pTable == NULL) { break; } @@ -172,22 +185,22 @@ int32_t mgmtInitSuperTables() { pNode = pLastNode; continue; } - pTable->numOfTables = 0; - } - mgmtSetVgroupIdPool(); + mgmtAddSuperTableIntoDb(pDb); + } - mTrace("super table is initialized"); + mTrace("stables is initialized"); return 0; } void mgmtCleanUpSuperTables() { + sdbCloseTable(tsSuperTableSdb); } int32_t mgmtCreateSuperTable(SDbObj *pDb, SCreateTableMsg *pCreate) { int32_t numOfTables = sdbGetNumOfRows(tsSuperTableSdb); - if (numOfTables >= TSDB_MAX_TABLES) { - mError("super table:%s, numOfTables:%d exceed maxTables:%d", pCreate->meterId, numOfTables, TSDB_MAX_TABLES); + if (numOfTables >= TSDB_MAX_SUPER_TABLES) { + mError("stable:%s, numOfTables:%d exceed maxTables:%d", pCreate->tableId, numOfTables, TSDB_MAX_SUPER_TABLES); return TSDB_CODE_TOO_MANY_TABLES; } @@ -196,7 +209,8 @@ int32_t mgmtCreateSuperTable(SDbObj *pDb, SCreateTableMsg *pCreate) { return TSDB_CODE_SERV_OUT_OF_MEMORY; } - strcpy(pStable->tableId, pCreate->meterId); + strcpy(pStable->tableId, pCreate->tableId); + pStable->type = TSDB_TABLE_TYPE_SUPER_TABLE; pStable->createdTime = taosGetTimestampMs(); pStable->vgId = 0; pStable->sid = 0; @@ -204,14 +218,13 @@ int32_t mgmtCreateSuperTable(SDbObj *pDb, SCreateTableMsg *pCreate) { pStable->sversion = 0; pStable->numOfColumns = pCreate->numOfColumns; pStable->numOfTags = pCreate->numOfTags; - pStable->numOfTables = 0; int32_t numOfCols = pCreate->numOfColumns + pCreate->numOfTags; int32_t schemaSize = numOfCols * sizeof(SSchema); pStable->schema = (SSchema *)calloc(1, schemaSize); if (pStable->schema == NULL) { free(pStable); - mError("table:%s, no schema input", pCreate->meterId); + mError("stable:%s, no schema input", pCreate->tableId); return TSDB_CODE_INVALID_TABLE; } memcpy(pStable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); @@ -223,20 +236,30 @@ int32_t mgmtCreateSuperTable(SDbObj *pDb, SCreateTableMsg *pCreate) { } if (sdbInsertRow(tsSuperTableSdb, pStable, 0) < 0) { - mError("table:%s, update sdb error", pCreate->meterId); + mError("table:%s, update sdb error", pCreate->tableId); return TSDB_CODE_SDB_ERROR; } - return 0; + return TSDB_CODE_SUCCESS; } int32_t mgmtDropSuperTable(SDbObj *pDb, SSuperTableObj *pSuperTable) { //TODO drop all child tables + + mgmtRemoveSuperTableFromDb(pDb); return sdbDeleteRow(tsSuperTableSdb, pSuperTable); } -SSuperTableObj* mgmtGetSuperTable(char *tableId) { - return (SSuperTableObj *)sdbGetRow(tsSuperTableSdb, tableId); +void* mgmtGetSuperTable(char *tableId) { + return sdbGetRow(tsSuperTableSdb, tableId); +} + +void *mgmtGetSuperTableVgroup(SSuperTableObj *pStable) { + //TODO get vgroup of dnodes + SSuperTableInfoRsp *rsp = rpcMallocCont(sizeof(SSuperTableInfoRsp) + sizeof(uint32_t) * mgmtGetDnodesNum()); + rsp->numOfDnodes = 1; + rsp->dnodeIps[0] = 0; + return rsp; } int32_t mgmtFindSuperTableTagIndex(SSuperTableObj *pStable, const char *tagName) { @@ -350,7 +373,7 @@ int32_t mgmtModifySuperTableTagNameByName(SSuperTableObj *pStable, char *oldTagN strncpy(schema->name, newTagName, TSDB_COL_NAME_LEN); // Encode string - int32_t size = 1 + sizeof(STabObj) + TSDB_MAX_BYTES_PER_ROW; + int32_t size = 1 + sizeof(SSuperTableObj) + TSDB_MAX_BYTES_PER_ROW; char *msg = (char *) malloc(size); if (msg == NULL) return TSDB_CODE_APP_ERROR; memset(msg, 0, size); @@ -457,17 +480,16 @@ int32_t mgmtDropSuperTableColumnByName(SSuperTableObj *pStable, char *colName) { return TSDB_CODE_SUCCESS; } -int32_t mgmtGetSuperTableMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { - int32_t cols = 0; - - SDbObj *pDb = NULL; - if (pConn->pDb != NULL) pDb = mgmtGetDb(pConn->pDb->name); - - if (pDb == NULL) return TSDB_CODE_DB_NOT_SELECTED; +int32_t mgmtGetShowSuperTableMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) { + return TSDB_CODE_DB_NOT_SELECTED; + } + int32_t cols = 0; SSchema *pSchema = tsGetSchema(pMeta); - pShow->bytes[cols] = TSDB_METER_NAME_LEN; + pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; pSchema[cols].type = TSDB_DATA_TYPE_BINARY; strcpy(pSchema[cols].name, "name"); pSchema[cols].bytes = htons(pShow->bytes[cols]); @@ -503,13 +525,13 @@ int32_t mgmtGetSuperTableMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pCon pShow->offset[0] = 0; for (int32_t i = 1; i < cols; ++i) pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; - pShow->numOfRows = pDb->numOfMetrics; + pShow->numOfRows = pDb->numOfSuperTables; pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; return 0; } -int32_t mgmtRetrieveSuperTables(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, void *pConn) { int32_t numOfRows = 0; char * pWrite; int32_t cols = 0; @@ -517,17 +539,13 @@ int32_t mgmtRetrieveSuperTables(SShowObj *pShow, char *data, int32_t rows, SConn char prefix[20] = {0}; int32_t prefixLen; - SDbObj *pDb = NULL; - if (pConn->pDb != NULL) { - pDb = mgmtGetDb(pConn->pDb->name); - } + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) return 0; - if (pDb == NULL) { - return 0; - } + SUserObj *pUser = mgmtGetUserFromConn(pConn); if (mgmtCheckIsMonitorDB(pDb->name, tsMonitorDbName)) { - if (strcmp(pConn->pUser->user, "root") != 0 && strcmp(pConn->pUser->user, "_root") != 0 && strcmp(pConn->pUser->user, "monitor") != 0 ) { + if (strcmp(pUser->user, "root") != 0 && strcmp(pUser->user, "_root") != 0 && strcmp(pUser->user, "monitor") != 0 ) { return 0; } } @@ -537,28 +555,26 @@ int32_t mgmtRetrieveSuperTables(SShowObj *pShow, char *data, int32_t rows, SConn prefixLen = strlen(prefix); SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER; - char metricName[TSDB_METER_NAME_LEN] = {0}; + char stableName[TSDB_TABLE_NAME_LEN] = {0}; while (numOfRows < rows) { - pTable = (SSuperTableObj *)pShow->pNode; + pShow->pNode = sdbFetchRow(tsSuperTableSdb, pShow->pNode, (void **) &pTable); if (pTable == NULL) break; - //pShow->pNode = (void *)pTable->next; - if (strncmp(pTable->tableId, prefix, prefixLen)) { continue; } - memset(metricName, 0, tListLen(metricName)); - extractTableName(pTable->tableId, metricName); + memset(stableName, 0, tListLen(stableName)); + extractTableName(pTable->tableId, stableName); if (pShow->payloadLen > 0 && - patternMatch(pShow->payload, metricName, TSDB_METER_NAME_LEN, &info) != TSDB_PATTERN_MATCH) + patternMatch(pShow->payload, stableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) continue; cols = 0; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - extractTableName(pTable->tableId, pWrite); + strncpy(pWrite, stableName, TSDB_TABLE_NAME_LEN); cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; @@ -592,13 +608,31 @@ void mgmtRemoveTableFromSuperTable(SSuperTableObj *pStable) { pStable->numOfTables--; } -int32_t mgmtGetTagsLength(SSuperTableObj* pSuperTable, int32_t col) { // length before column col - int32_t len = 0; - int32_t tagColumnIndexOffset = pSuperTable->numOfColumns; - - for (int32_t i = 0; i < pSuperTable->numOfTags && i < col; ++i) { - len += ((SSchema*)pSuperTable->schema)[tagColumnIndexOffset + i].bytes; +int32_t mgmtSetSchemaFromSuperTable(SSchema *pSchema, SSuperTableObj *pTable) { + int32_t numOfCols = pTable->numOfColumns + pTable->numOfTags; + for (int32_t i = 0; i < numOfCols; ++i) { + strcpy(pSchema->name, pTable->schema[i].name); + pSchema->type = pTable->schema[i].type; + pSchema->bytes = htons(pTable->schema[i].bytes); + pSchema->colId = htons(pTable->schema[i].colId); + pSchema++; } - return len; + return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema); +} + +int32_t mgmtGetSuperTableMeta(SDbObj *pDb, SSuperTableObj *pTable, STableMeta *pMeta, bool usePublicIp) { + pMeta->uid = htobe64(pTable->uid); + pMeta->sid = htonl(pTable->sid); + pMeta->vgid = htonl(pTable->vgId); + pMeta->sversion = htons(pTable->sversion); + pMeta->precision = pDb->cfg.precision; + pMeta->numOfTags = pTable->numOfTags; + pMeta->numOfColumns = htons(pTable->numOfColumns); + pMeta->tableType = pTable->type; + pMeta->contLen = sizeof(STableMeta) + mgmtSetSchemaFromSuperTable(pMeta->schema, pTable); + strcpy(pMeta->tableId, pTable->tableId); + + return TSDB_CODE_SUCCESS; } + diff --git a/src/mnode/src/mgmtSystem.c b/src/mnode/src/mgmtSystem.c index ce03bc9f337cd79b782417d2600143054d040f9b..1eb114aa8974f914b37fe73284858d8c43707fe7 100644 --- a/src/mnode/src/mgmtSystem.c +++ b/src/mnode/src/mgmtSystem.c @@ -125,8 +125,6 @@ int32_t mgmtStartSystem() { mError("failed to init dnode balance") } - mgmtCheckAcct(); - taosTmrReset(mgmtDoStatistic, tsStatusInterval * 30000, NULL, tsMgmtTmr, &tsMgmtStatisTimer); mPrint("TDengine mgmt is initialized successfully"); diff --git a/src/mnode/src/mgmtTable.c b/src/mnode/src/mgmtTable.c index f2a2e0cb9272fc2b8ca7473e5b79e75f3e56576f..cc95d9f8cc2488487ad1d2676fe2a010f8905364 100644 --- a/src/mnode/src/mgmtTable.c +++ b/src/mnode/src/mgmtTable.c @@ -33,11 +33,16 @@ #include "mgmtDnodeInt.h" #include "mgmtGrant.h" #include "mgmtNormalTable.h" -#include "mgmtStreamTable.h" +#include "mgmtProfile.h" +#include "mgmtShell.h" #include "mgmtSuperTable.h" #include "mgmtTable.h" +#include "mgmtUser.h" #include "mgmtVgroup.h" +extern void *tsNormalTableSdb; +extern void *tsChildTableSdb; + int32_t mgmtInitTables() { int32_t code = mgmtInitSuperTables(); if (code != TSDB_CODE_SUCCESS) { @@ -49,16 +54,13 @@ int32_t mgmtInitTables() { return code; } - code = mgmtInitStreamTables(); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - code = mgmtInitChildTables(); if (code != TSDB_CODE_SUCCESS) { return code; } + mgmtSetVgroupIdPool(); + return TSDB_CODE_SUCCESS; } @@ -73,12 +75,7 @@ STableInfo* mgmtGetTable(char *tableId) { return tableInfo; } - tableInfo = (STableInfo *) mgmtGetStreamTable(tableId); - if (tableInfo != NULL) { - return tableInfo; - } - - tableInfo = (STableInfo *) mgmtGetNormalTable(tableId); + tableInfo = (STableInfo *) mgmtGetChildTable(tableId); if (tableInfo != NULL) { return tableInfo; } @@ -99,88 +96,116 @@ STableInfo* mgmtGetTableByPos(uint32_t dnodeIp, int32_t vnode, int32_t sid) { return NULL; } -int32_t mgmtCreateTable(SDbObj *pDb, SCreateTableMsg *pCreate) { - STableInfo *pTable = mgmtGetTable(pCreate->meterId); +int32_t mgmtGetTableMeta(SDbObj *pDb, STableInfo *pTable, STableMeta *pMeta, bool usePublicIp) { + if (pTable->type == TSDB_TABLE_TYPE_CHILD_TABLE) { + mgmtGetChildTableMeta(pDb, (SChildTableObj *) pTable, pMeta, usePublicIp); + } else if (pTable->type == TSDB_TABLE_TYPE_NORMAL_TABLE) { + mgmtGetNormalTableMeta(pDb, (SNormalTableObj *) pTable, pMeta, usePublicIp); + } else if (pTable->type == TSDB_TABLE_TYPE_SUPER_TABLE) { + mgmtGetSuperTableMeta(pDb, (SSuperTableObj *) pTable, pMeta, usePublicIp); + } else { + mTrace("%s, uid:%" PRIu64 " table meta retrieve failed, invalid type", pTable->tableId, pTable->uid); + return TSDB_CODE_INVALID_TABLE; + } + + mTrace("%s, uid:%" PRIu64 " table meta is retrieved", pTable->tableId, pTable->uid); + return TSDB_CODE_SUCCESS; +} + +int32_t mgmtCreateTable(SCreateTableMsg *pCreate, int32_t contLen, void *thandle, bool isGetMeta) { + SDbObj *pDb = mgmtGetDb(pCreate->db); + if (pDb == NULL) { + mError("table:%s, failed to create table, db not selected", pCreate->tableId); + return TSDB_CODE_DB_NOT_SELECTED; + } + + STableInfo *pTable = mgmtGetTable(pCreate->tableId); if (pTable != NULL) { if (pCreate->igExists) { + mTrace("table:%s, table is already exist, think it success", pCreate->tableId); return TSDB_CODE_SUCCESS; } else { + mError("table:%s, failed to create table, table already exist", pCreate->tableId); return TSDB_CODE_TABLE_ALREADY_EXIST; } } SAcctObj *pAcct = mgmtGetAcct(pDb->cfg.acct); assert(pAcct != NULL); + int32_t code = mgmtCheckTableLimit(pAcct, pCreate); - if (code != 0) { - mError("table:%s, exceed the limit", pCreate->meterId); + if (code != TSDB_CODE_SUCCESS) { + mError("table:%s, failed to create table, table num exceed the limit", pCreate->tableId); return code; } if (mgmtCheckExpired()) { - mError("failed to create meter:%s, reason:grant expired", pCreate->meterId); + mError("table:%s, failed to create table, grant expired", pCreate->tableId); return TSDB_CODE_GRANT_EXPIRED; } - if (pCreate->numOfTags == 0) { - int32_t grantCode = mgmtCheckTimeSeries(pCreate->numOfColumns); - if (grantCode != 0) { - mError("table:%s, grant expired", pCreate->meterId); - return grantCode; - } - - SVgObj *pVgroup = mgmtGetAvailVgroup(pDb); - if (pVgroup == NULL) { - return terrno; - } + if (pCreate->numOfTags != 0) { + mTrace("table:%s, start to create super table, tags:%d columns:%d", + pCreate->tableId, pCreate->numOfTags, pCreate->numOfColumns); + return mgmtCreateSuperTable(pDb, pCreate); + } - int32_t sid = mgmtAllocateSid(pDb, pVgroup); - if (sid < 0) { - return terrno; - } + code = mgmtCheckTimeSeries(pCreate->numOfColumns); + if (code != TSDB_CODE_SUCCESS) { + mError("table:%s, failed to create table, timeseries exceed the limit", pCreate->tableId); + return TSDB_CODE_SUCCESS; + } - if (pCreate->numOfColumns == 0) { - return mgmtCreateChildTable(pDb, pCreate, pVgroup, sid); - } else if (pCreate->sqlLen > 0) { - return mgmtCreateStreamTable(pDb, pCreate, pVgroup, sid); - } else { - return mgmtCreateNormalTable(pDb, pCreate, pVgroup, sid); - } + SVgObj *pVgroup = mgmtGetAvailableVgroup(pDb); + if (pVgroup == NULL) { + mTrace("table:%s, no avaliable vgroup, start to create a new one", pCreate->tableId); + mgmtProcessCreateVgroup(pCreate, contLen, thandle, isGetMeta); } else { - return mgmtCreateSuperTable(pDb, pCreate); + mTrace("table:%s, try to create table in vgroup:%d", pCreate->tableId, pVgroup->vgId); + mgmtProcessCreateTable(pVgroup, pCreate, contLen, thandle, isGetMeta); } + + return TSDB_CODE_ACTION_IN_PROGRESS; } int32_t mgmtDropTable(SDbObj *pDb, char *tableId, int32_t ignore) { STableInfo *pTable = mgmtGetTable(tableId); if (pTable == NULL) { if (ignore) { + mTrace("table:%s, table is not exist, think it success", tableId); return TSDB_CODE_SUCCESS; } else { + mError("table:%s, failed to create table, table not exist", tableId); return TSDB_CODE_INVALID_TABLE; } } if (mgmtCheckIsMonitorDB(pDb->name, tsMonitorDbName)) { + mError("table:%s, failed to create table, in monitor database", tableId); return TSDB_CODE_MONITOR_DB_FORBIDDEN; } switch (pTable->type) { case TSDB_TABLE_TYPE_SUPER_TABLE: + mTrace("table:%s, start to drop super table", tableId); return mgmtDropSuperTable(pDb, (SSuperTableObj *) pTable); case TSDB_TABLE_TYPE_CHILD_TABLE: + mTrace("table:%s, start to drop child table", tableId); return mgmtDropChildTable(pDb, (SChildTableObj *) pTable); - case TSDB_TABLE_TYPE_STREAM_TABLE: - return mgmtDropStreamTable(pDb, (SStreamTableObj *) pTable); case TSDB_TABLE_TYPE_NORMAL_TABLE: + mTrace("table:%s, start to drop normal table", tableId); + return mgmtDropNormalTable(pDb, (SNormalTableObj *) pTable); + case TSDB_TABLE_TYPE_STREAM_TABLE: + mTrace("table:%s, start to drop stream table", tableId); return mgmtDropNormalTable(pDb, (SNormalTableObj *) pTable); default: + mError("table:%s, invalid table type:%d", tableId, pTable->type); return TSDB_CODE_INVALID_TABLE; } } int32_t mgmtAlterTable(SDbObj *pDb, SAlterTableMsg *pAlter) { - STableInfo *pTable = mgmtGetTable(pAlter->meterId); + STableInfo *pTable = mgmtGetTable(pAlter->tableId); if (pTable == NULL) { return TSDB_CODE_INVALID_TABLE; } @@ -224,26 +249,20 @@ int32_t mgmtAlterTable(SDbObj *pDb, SAlterTableMsg *pAlter) { void mgmtCleanUpMeters() { mgmtCleanUpNormalTables(); - mgmtCleanUpStreamTables(); mgmtCleanUpChildTables(); mgmtCleanUpSuperTables(); } -int32_t mgmtGetTableMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { - int32_t cols = 0; - - SDbObj *pDb = NULL; - if (pConn->pDb != NULL) { - pDb = mgmtGetDb(pConn->pDb->name); - } - +int32_t mgmtGetShowTableMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { + SDbObj *pDb = mgmtGetDb(pShow->db); if (pDb == NULL) { return TSDB_CODE_DB_NOT_SELECTED; } + int32_t cols = 0; SSchema *pSchema = tsGetSchema(pMeta); - pShow->bytes[cols] = TSDB_METER_NAME_LEN; + pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; pSchema[cols].type = TSDB_DATA_TYPE_BINARY; strcpy(pSchema[cols].name, "table_name"); pSchema[cols].bytes = htons(pShow->bytes[cols]); @@ -261,7 +280,7 @@ int32_t mgmtGetTableMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { pSchema[cols].bytes = htons(pShow->bytes[cols]); cols++; - pShow->bytes[cols] = TSDB_METER_NAME_LEN; + pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; pSchema[cols].type = TSDB_DATA_TYPE_BINARY; strcpy(pSchema[cols].name, "stable"); pSchema[cols].bytes = htons(pShow->bytes[cols]); @@ -292,42 +311,38 @@ static void mgmtVacuumResult(char *data, int32_t numOfCols, int32_t rows, int32_ } } -int32_t mgmtRetrieveTables(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { - int32_t numOfRows = 0; - int32_t numOfRead = 0; - int32_t cols = 0; - void *pTable = NULL; - char *pWrite = NULL; - - int16_t numOfColumns; - int64_t createdTime; - char *tableId; - char *superTableId; - SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER; - - SDbObj *pDb = NULL; - if (pConn->pDb != NULL) { - pDb = mgmtGetDb(pConn->pDb->name); - } +int32_t mgmtRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows, void *pConn) { + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) return 0; - if (pDb == NULL) { - return 0; - } + SUserObj *pUser = mgmtGetUserFromConn(pConn); + if (pUser == NULL) return 0; if (mgmtCheckIsMonitorDB(pDb->name, tsMonitorDbName)) { - if (strcmp(pConn->pUser->user, "root") != 0 && strcmp(pConn->pUser->user, "_root") != 0 && - strcmp(pConn->pUser->user, "monitor") != 0) { + if (strcmp(pUser->user, "root") != 0 && strcmp(pUser->user, "_root") != 0 && + strcmp(pUser->user, "monitor") != 0) { return 0; } } - char prefix[20] = {0}; + int32_t numOfRows = 0; + int32_t numOfRead = 0; + int32_t cols = 0; + void *pTable = NULL; + char *pWrite = NULL; + char prefix[20] = {0}; + SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER; + strcpy(prefix, pDb->name); strcat(prefix, TS_PATH_DELIMITER); int32_t prefixLen = strlen(prefix); while (numOfRows < rows) { - void *pNormalTableNode = sdbFetchRow(tsNormalTableSdb, pShow->pNode, (void **) &pTable); + int16_t numOfColumns = 0; + int64_t createdTime = 0; + char *tableId = NULL; + char *superTableId = NULL; + void *pNormalTableNode = sdbFetchRow(tsNormalTableSdb, pShow->pNode, (void **) &pTable); if (pTable != NULL) { SNormalTableObj *pNormalTable = (SNormalTableObj *) pTable; pShow->pNode = pNormalTableNode; @@ -336,26 +351,16 @@ int32_t mgmtRetrieveTables(SShowObj *pShow, char *data, int32_t rows, SConnObj * createdTime = pNormalTable->createdTime; numOfColumns = pNormalTable->numOfColumns; } else { - void *pStreamTableNode = sdbFetchRow(tsStreamTableSdb, pShow->pNode, (void **) &pTable); + void *pChildTableNode = sdbFetchRow(tsChildTableSdb, pShow->pNode, (void **) &pTable); if (pTable != NULL) { - SStreamTableObj *pChildTable = (SStreamTableObj *) pTable; - pShow->pNode = pStreamTableNode; + SChildTableObj *pChildTable = (SChildTableObj *) pTable; + pShow->pNode = pChildTableNode; tableId = pChildTable->tableId; - superTableId = NULL; + superTableId = pChildTable->superTableId; createdTime = pChildTable->createdTime; - numOfColumns = pChildTable->numOfColumns; + numOfColumns = pChildTable->superTable->numOfColumns; } else { - void *pChildTableNode = sdbFetchRow(tsChildTableSdb, pShow->pNode, (void **) &pTable); - if (pTable != NULL) { - SChildTableObj *pChildTable = (SChildTableObj *) pTable; - pShow->pNode = pChildTableNode; - tableId = pChildTable->tableId; - superTableId = NULL; - createdTime = pChildTable->createdTime; - numOfColumns = pChildTable->superTable->numOfColumns; - } else { - break; - } + break; } } @@ -364,22 +369,22 @@ int32_t mgmtRetrieveTables(SShowObj *pShow, char *data, int32_t rows, SConnObj * continue; } - char meterName[TSDB_METER_NAME_LEN] = {0}; - memset(meterName, 0, tListLen(meterName)); + char tableName[TSDB_TABLE_NAME_LEN] = {0}; + memset(tableName, 0, tListLen(tableName)); numOfRead++; // pattern compare for meter name - extractTableName(tableId, meterName); + extractTableName(tableId, tableName); if (pShow->payloadLen > 0 && - patternMatch(pShow->payload, meterName, TSDB_METER_NAME_LEN, &info) != TSDB_PATTERN_MATCH) { + patternMatch(pShow->payload, tableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) { continue; } cols = 0; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - strncpy(pWrite, meterName, TSDB_METER_NAME_LEN); + strncpy(pWrite, tableName, TSDB_TABLE_NAME_LEN); cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; @@ -406,3 +411,15 @@ int32_t mgmtRetrieveTables(SShowObj *pShow, char *data, int32_t rows, SConnObj * return numOfRows; } + +SDRemoveTableMsg *mgmtBuildRemoveTableMsg(STableInfo *pTable) { + SDRemoveTableMsg *pRemove = NULL; + + + return pRemove; +} + +void mgmtSetTableDirty(STableInfo *pTable, bool isDirty) { + pTable->dirty = isDirty; +} + diff --git a/src/mnode/src/mgmtUser.c b/src/mnode/src/mgmtUser.c index dde526f4e4621b4157bb3eec2a63beb81c198f89..33b6c06c514e67cac13809e36a2ae05eb331e670 100644 --- a/src/mnode/src/mgmtUser.c +++ b/src/mnode/src/mgmtUser.c @@ -24,6 +24,7 @@ #include "mgmtTable.h" void *tsUserSdb = NULL; +static int32_t tsUserUpdateSize = 0; void *(*mgmtUserActionFp[SDB_MAX_ACTION_TYPES])(void *row, char *str, int32_t size, int32_t *ssize); void *mgmtUserActionInsert(void *row, char *str, int32_t size, int32_t *ssize); @@ -59,7 +60,10 @@ int32_t mgmtInitUsers() { mgmtUserActionInit(); - tsUserSdb = sdbOpenTable(tsMaxUsers, sizeof(SUserObj), "user", SDB_KEYTYPE_STRING, tsMgmtDirectory, mgmtUserAction); + SUserObj tObj; + tsUserUpdateSize = tObj.updateEnd - (int8_t *)&tObj; + + tsUserSdb = sdbOpenTable(tsMaxUsers, tsUserUpdateSize, "user", SDB_KEYTYPE_STRING, tsMgmtDirectory, mgmtUserAction); if (tsUserSdb == NULL) { mError("failed to init user data"); return -1; @@ -78,6 +82,11 @@ int32_t mgmtInitUsers() { numOfUsers++; } + pAcct = mgmtGetAcct("root"); + mgmtCreateUser(pAcct, "root", "taosdata"); + mgmtCreateUser(pAcct, "monitor", tsInternalPass); + mgmtCreateUser(pAcct, "_root", tsInternalPass); + mTrace("user data is initialized"); return 0; } @@ -91,15 +100,16 @@ int32_t mgmtUpdateUser(SUserObj *pUser) { } int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass) { - SUserObj *pUser; - int32_t code; - - code = mgmtCheckUserLimit(pAcct); + int32_t code = mgmtCheckUserLimit(pAcct); if (code != 0) { return code; } - pUser = (SUserObj *)sdbGetRow(tsUserSdb, name); + if (name[0] == 0 || pass[0] == 0) { + return TSDB_CODE_INVALID_MSG; + } + + SUserObj *pUser = (SUserObj *)sdbGetRow(tsUserSdb, name); if (pUser != NULL) { mWarn("user:%s is already there", name); return TSDB_CODE_USER_ALREADY_EXIST; @@ -153,8 +163,13 @@ void mgmtCleanUpUsers() { sdbCloseTable(tsUserSdb); } -int32_t mgmtGetUserMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { - int32_t cols = 0; +int32_t mgmtGetUserMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { + SUserObj *pUser = mgmtGetUserFromConn(pConn); + if (pUser == NULL) { + return TSDB_CODE_INVALID_USER; + } + + int32_t cols = 0; SSchema *pSchema = tsGetSchema(pMeta); pShow->bytes[cols] = TSDB_USER_LEN; @@ -176,23 +191,26 @@ int32_t mgmtGetUserMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { cols++; pMeta->numOfColumns = htons(cols); + strcpy(pMeta->tableId, "show users"); pShow->numOfColumns = cols; pShow->offset[0] = 0; - for (int32_t i = 1; i < cols; ++i) pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; + for (int32_t i = 1; i < cols; ++i) { + pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; + } - pShow->numOfRows = pConn->pAcct->acctInfo.numOfUsers; - pShow->pNode = pConn->pAcct->pUser; + pShow->numOfRows = pUser->pAcct->acctInfo.numOfUsers; + pShow->pNode = pUser->pAcct->pUser; pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; return 0; } -int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { - int32_t numOfRows = 0; - SUserObj *pUser = NULL; - char * pWrite; - int32_t cols = 0; +int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, void *pConn) { + int32_t numOfRows = 0; + SUserObj *pUser = NULL; + int32_t cols = 0; + char *pWrite; while (numOfRows < rows) { pUser = (SUserObj *)pShow->pNode; @@ -226,16 +244,19 @@ int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, SConnObj *p } void *mgmtUserActionInsert(void *row, char *str, int32_t size, int32_t *ssize) { - SUserObj *pUser = (SUserObj *)row; + SUserObj *pUser = (SUserObj *) row; SAcctObj *pAcct = mgmtGetAcct(pUser->acct); + + pUser->pAcct = pAcct; mgmtAddUserIntoAcct(pAcct, pUser); return NULL; } void *mgmtUserActionDelete(void *row, char *str, int32_t size, int32_t *ssize) { - SUserObj *pUser = (SUserObj *)row; + SUserObj *pUser = (SUserObj *) row; SAcctObj *pAcct = mgmtGetAcct(pUser->acct); + mgmtRemoveUserFromAcct(pAcct, pUser); return NULL; @@ -246,36 +267,45 @@ void *mgmtUserActionUpdate(void *row, char *str, int32_t size, int32_t *ssize) { } void *mgmtUserActionEncode(void *row, char *str, int32_t size, int32_t *ssize) { - SUserObj *pUser = (SUserObj *)row; - int32_t tsize = pUser->updateEnd - (char *)pUser; - if (size < tsize) { + SUserObj *pUser = (SUserObj *) row; + + if (size < tsUserUpdateSize) { *ssize = -1; } else { - memcpy(str, pUser, tsize); - *ssize = tsize; + memcpy(str, pUser, tsUserUpdateSize); + *ssize = tsUserUpdateSize; } + return NULL; } void *mgmtUserActionDecode(void *row, char *str, int32_t size, int32_t *ssize) { - SUserObj *pUser = (SUserObj *)malloc(sizeof(SUserObj)); + SUserObj *pUser = (SUserObj *) malloc(sizeof(SUserObj)); if (pUser == NULL) return NULL; memset(pUser, 0, sizeof(SUserObj)); - int32_t tsize = pUser->updateEnd - (char *)pUser; - memcpy(pUser, str, tsize); + memcpy(pUser, str, tsUserUpdateSize); + return (void *)pUser; } void *mgmtUserActionReset(void *row, char *str, int32_t size, int32_t *ssize) { SUserObj *pUser = (SUserObj *)row; - int32_t tsize = pUser->updateEnd - (char *)pUser; - memcpy(pUser, str, tsize); + + memcpy(pUser, str, tsUserUpdateSize); return NULL; } void *mgmtUserActionDestroy(void *row, char *str, int32_t size, int32_t *ssize) { tfree(row); + return NULL; } + +SUserObj *mgmtGetUserFromConn(void *pConn) { + SRpcConnInfo connInfo; + rpcGetConnInfo(pConn, &connInfo); + + return mgmtGetUser(connInfo.user); +} diff --git a/src/mnode/src/mgmtVgroup.c b/src/mnode/src/mgmtVgroup.c index 701a1d66960f0ef3b8903a7107a165a76911ce4f..10b4244bf861fe06235048a92f949791ef440b11 100644 --- a/src/mnode/src/mgmtVgroup.c +++ b/src/mnode/src/mgmtVgroup.c @@ -27,47 +27,47 @@ #include "mgmtTable.h" #include "mgmtVgroup.h" -void *tsVgroupSdb = NULL; -int32_t tsVgUpdateSize; - -void *(*mgmtVgroupActionFp[SDB_MAX_ACTION_TYPES])(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtVgroupActionInsert(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtVgroupActionDelete(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtVgroupActionUpdate(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtVgroupActionEncode(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtVgroupActionDecode(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtVgroupActionReset(void *row, char *str, int32_t size, int32_t *ssize); -void *mgmtVgroupActionDestroy(void *row, char *str, int32_t size, int32_t *ssize); - -void mgmtVgroupActionInit() { - mgmtVgroupActionFp[SDB_TYPE_INSERT] = mgmtVgroupActionInsert; - mgmtVgroupActionFp[SDB_TYPE_DELETE] = mgmtVgroupActionDelete; - mgmtVgroupActionFp[SDB_TYPE_UPDATE] = mgmtVgroupActionUpdate; - mgmtVgroupActionFp[SDB_TYPE_ENCODE] = mgmtVgroupActionEncode; - mgmtVgroupActionFp[SDB_TYPE_DECODE] = mgmtVgroupActionDecode; - mgmtVgroupActionFp[SDB_TYPE_RESET] = mgmtVgroupActionReset; +static void *tsVgroupSdb = NULL; +static int32_t tsVgUpdateSize = 0; + +static void *(*mgmtVgroupActionFp[SDB_MAX_ACTION_TYPES])(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtVgroupActionInsert(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtVgroupActionDelete(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtVgroupActionUpdate(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtVgroupActionEncode(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtVgroupActionDecode(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtVgroupActionReset(void *row, char *str, int32_t size, int32_t *ssize); +static void *mgmtVgroupActionDestroy(void *row, char *str, int32_t size, int32_t *ssize); + +static void mgmtVgroupActionInit() { + SVgObj tObj; + tsVgUpdateSize = tObj.updateEnd - (int8_t *)&tObj; + + mgmtVgroupActionFp[SDB_TYPE_INSERT] = mgmtVgroupActionInsert; + mgmtVgroupActionFp[SDB_TYPE_DELETE] = mgmtVgroupActionDelete; + mgmtVgroupActionFp[SDB_TYPE_UPDATE] = mgmtVgroupActionUpdate; + mgmtVgroupActionFp[SDB_TYPE_ENCODE] = mgmtVgroupActionEncode; + mgmtVgroupActionFp[SDB_TYPE_DECODE] = mgmtVgroupActionDecode; + mgmtVgroupActionFp[SDB_TYPE_RESET] = mgmtVgroupActionReset; mgmtVgroupActionFp[SDB_TYPE_DESTROY] = mgmtVgroupActionDestroy; } -void *mgmtVgroupAction(char action, void *row, char *str, int32_t size, int32_t *ssize) { - if (mgmtVgroupActionFp[(uint8_t)action] != NULL) { - return (*(mgmtVgroupActionFp[(uint8_t)action]))(row, str, size, ssize); +static void *mgmtVgroupAction(char action, void *row, char *str, int32_t size, int32_t *ssize) { + if (mgmtVgroupActionFp[(uint8_t) action] != NULL) { + return (*(mgmtVgroupActionFp[(uint8_t) action]))(row, str, size, ssize); } return NULL; } int32_t mgmtInitVgroups() { - void * pNode = NULL; + void *pNode = NULL; SVgObj *pVgroup = NULL; mgmtVgroupActionInit(); - SVgObj tObj; - tsVgUpdateSize = tObj.updateEnd - (int8_t *)&tObj; - - tsVgroupSdb = sdbOpenTable(tsMaxVGroups, sizeof(SVgObj), "vgroups", SDB_KEYTYPE_AUTO, tsMgmtDirectory, mgmtVgroupAction); + tsVgroupSdb = sdbOpenTable(tsMaxVGroups, tsVgUpdateSize, "vgroups", SDB_KEYTYPE_AUTO, tsMgmtDirectory, mgmtVgroupAction); if (tsVgroupSdb == NULL) { - mError("failed to init vgroup data"); + mError("failed to init vgroups data"); return -1; } @@ -80,6 +80,7 @@ int32_t mgmtInitVgroups() { pVgroup->prev = NULL; pVgroup->next = NULL; + int32_t size = sizeof(STableInfo *) * pDb->cfg.maxSessions; pVgroup->tableList = (STableInfo **)malloc(size); if (pVgroup->tableList == NULL) { @@ -98,7 +99,7 @@ int32_t mgmtInitVgroups() { taosIdPoolReinit(pVgroup->idPool); - if (pVgroup->vnodeGid[0].publicIp == 0) { + if (tsIsCluster && pVgroup->vnodeGid[0].publicIp == 0) { pVgroup->vnodeGid[0].publicIp = inet_addr(tsPublicIp); pVgroup->vnodeGid[0].ip = inet_addr(tsPrivateIp); sdbUpdateRow(tsVgroupSdb, pVgroup, tsVgUpdateSize, 1); @@ -115,41 +116,6 @@ SVgObj *mgmtGetVgroup(int32_t vgId) { return (SVgObj *)sdbGetRow(tsVgroupSdb, &vgId); } -SVgObj *mgmtGetAvailVgroup(SDbObj *pDb) { - SVgObj *pVgroup = pDb->pHead; - - if (pDb->vgStatus == TSDB_VG_STATUS_IN_PROGRESS) { - terrno = TSDB_CODE_ACTION_IN_PROGRESS; - return NULL; - } - - if (pDb->vgStatus == TSDB_VG_STATUS_FULL) { - mError("db:%s, vgroup is full", pDb->name); - terrno = TSDB_CODE_NO_ENOUGH_DNODES; - return NULL; - } - - if (pDb->vgStatus == TSDB_VG_STATUS_NO_DISK_PERMISSIONS || - pDb->vgStatus == TSDB_VG_STATUS_SERVER_NO_PACE || - pDb->vgStatus == TSDB_VG_STATUS_SERV_OUT_OF_MEMORY || - pDb->vgStatus == TSDB_VG_STATUS_INIT_FAILED ) { - mError("db:%s, vgroup init failed, reason:%d %s", pDb->name, pDb->vgStatus, taosGetVgroupStatusStr(pDb->vgStatus)); - terrno = pDb->vgStatus; - return NULL; - } - - if (pVgroup == NULL) { - pDb->vgStatus = TSDB_VG_STATUS_IN_PROGRESS; - mgmtCreateVgroup(pDb); - mTrace("db:%s, vgroup malloced, wait for create progress finished", pDb->name); - terrno = TSDB_CODE_ACTION_IN_PROGRESS; - return NULL; - } - - terrno = 0; - return pVgroup; -} - int32_t mgmtAllocateSid(SDbObj *pDb, SVgObj *pVgroup) { int32_t sid = taosAllocateId(pVgroup->idPool); if (sid < 0) { @@ -163,6 +129,13 @@ int32_t mgmtAllocateSid(SDbObj *pDb, SVgObj *pVgroup) { return sid; } +/* + * TODO: check if there is enough sids + */ +SVgObj *mgmtGetAvailableVgroup(SDbObj *pDb) { + return pDb->pHead; +} + void mgmtProcessVgTimer(void *handle, void *tmrId) { SDbObj *pDb = (SDbObj *)handle; if (pDb == NULL) return; @@ -176,12 +149,7 @@ void mgmtProcessVgTimer(void *handle, void *tmrId) { } SVgObj *mgmtCreateVgroup(SDbObj *pDb) { - SVgObj *pVgroup; - int32_t size; - - size = sizeof(SVgObj); - pVgroup = (SVgObj *)malloc(size); - memset(pVgroup, 0, size); + SVgObj *pVgroup = (SVgObj *)calloc(sizeof(SVgObj), 1); strcpy(pVgroup->dbName, pDb->name); pVgroup->numOfVnodes = pDb->cfg.replications; pVgroup->createdTime = taosGetTimestampMs(); @@ -195,14 +163,19 @@ SVgObj *mgmtCreateVgroup(SDbObj *pDb) { return NULL; } + pVgroup->tableList = (STableInfo **) calloc(sizeof(STableInfo *), pDb->cfg.maxSessions); + pVgroup->numOfTables = 0; + pVgroup->idPool = taosInitIdPool(pDb->cfg.maxSessions); + + mgmtAddVgroupIntoDb(pDb, pVgroup); + mgmtSetDnodeVgid(pVgroup->vnodeGid, pVgroup->numOfVnodes, pVgroup->vgId); + sdbInsertRow(tsVgroupSdb, pVgroup, 0); mTrace("vgroup:%d, vgroup is created, db:%s replica:%d", pVgroup->vgId, pDb->name, pVgroup->numOfVnodes); for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) mTrace("vgroup:%d, dnode:%s vnode:%d is created", pVgroup->vgId, taosIpStr(pVgroup->vnodeGid[i].ip), pVgroup->vnodeGid[i].vnode); - mgmtSendVPeersMsg(pVgroup); - return pVgroup; } @@ -219,10 +192,12 @@ int32_t mgmtDropVgroup(SDbObj *pDb, SVgObj *pVgroup) { } mTrace("vgroup:%d, db:%s replica:%d is deleted", pVgroup->vgId, pDb->name, pVgroup->numOfVnodes); - mgmtSendFreeVnodeMsg(pVgroup); + + mgmtSendRemoveVgroupMsg(pVgroup, NULL); + sdbDeleteRow(tsVgroupSdb, pVgroup); - return 0; + return TSDB_CODE_SUCCESS; } void mgmtSetVgroupIdPool() { @@ -246,16 +221,17 @@ void mgmtSetVgroupIdPool() { } } -void mgmtCleanUpVgroups() { sdbCloseTable(tsVgroupSdb); } - -int32_t mgmtGetVgroupMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { - int32_t cols = 0; - - SDbObj *pDb = NULL; - if (pConn->pDb != NULL) pDb = mgmtGetDb(pConn->pDb->name); +void mgmtCleanUpVgroups() { + sdbCloseTable(tsVgroupSdb); +} - if (pDb == NULL) return TSDB_CODE_DB_NOT_SELECTED; +int32_t mgmtGetVgroupMeta(STableMeta *pMeta, SShowObj *pShow, void *pConn) { + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) { + return TSDB_CODE_DB_NOT_SELECTED; + } + int32_t cols = 0; SSchema *pSchema = tsGetSchema(pMeta); pShow->bytes[cols] = 4; @@ -266,7 +242,7 @@ int32_t mgmtGetVgroupMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { pShow->bytes[cols] = 4; pSchema[cols].type = TSDB_DATA_TYPE_INT; - strcpy(pSchema[cols].name, "meters"); + strcpy(pSchema[cols].name, "tables"); pSchema[cols].bytes = htons(pShow->bytes[cols]); cols++; @@ -342,39 +318,36 @@ int32_t mgmtGetVgroupMeta(SMeterMeta *pMeta, SShowObj *pShow, SConnObj *pConn) { return 0; } -int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, SConnObj *pConn) { +int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, void *pConn) { int32_t numOfRows = 0; SVgObj *pVgroup = NULL; - char * pWrite; + int32_t maxReplica = 0; int32_t cols = 0; char ipstr[20]; + char * pWrite; - int32_t maxReplica = 0; - - SDbObj *pDb = NULL; - if (pConn->pDb != NULL) pDb = mgmtGetDb(pConn->pDb->name); - assert(pDb != NULL); + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) return 0; pVgroup = pDb->pHead; while (pVgroup != NULL) { maxReplica = pVgroup->numOfVnodes > maxReplica ? pVgroup->numOfVnodes : maxReplica; - pVgroup = pVgroup->next; + pVgroup = pVgroup->next; } while (numOfRows < rows) { - // pShow->pNode = sdbFetchRow(tsVgroupSdb, pShow->pNode, (void **)&pVgroup); - pVgroup = (SVgObj *)pShow->pNode; + pVgroup = (SVgObj *) pShow->pNode; if (pVgroup == NULL) break; - pShow->pNode = (void *)pVgroup->next; + pShow->pNode = (void *) pVgroup->next; cols = 0; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int32_t *)pWrite = pVgroup->vgId; + *(int32_t *) pWrite = pVgroup->vgId; cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int32_t *)pWrite = pVgroup->numOfTables; + *(int32_t *) pWrite = pVgroup->numOfTables; cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; @@ -388,7 +361,7 @@ int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, SConnObj cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int16_t *)pWrite = pVgroup->vnodeGid[i].vnode; + *(int16_t *) pWrite = pVgroup->vnodeGid[i].vnode; cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; @@ -413,37 +386,28 @@ int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, SConnObj return numOfRows; } -void *mgmtVgroupActionInsert(void *row, char *str, int32_t size, int32_t *ssize) { - SVgObj *pVgroup = (SVgObj *)row; - SDbObj *pDb = mgmtGetDb(pVgroup->dbName); - - if (pDb == NULL) return NULL; - - int32_t tsize = sizeof(STableInfo *) * pDb->cfg.maxSessions; - pVgroup->tableList = (STableInfo **)malloc(tsize); - memset(pVgroup->tableList, 0, tsize); - pVgroup->numOfTables = 0; - pVgroup->idPool = taosInitIdPool(pDb->cfg.maxSessions); - mgmtAddVgroupIntoDb(pDb, pVgroup); - mgmtSetDnodeVgid(pVgroup->vnodeGid, pVgroup->numOfVnodes, pVgroup->vgId); - +static void *mgmtVgroupActionInsert(void *row, char *str, int32_t size, int32_t *ssize) { return NULL; } -void *mgmtVgroupActionDelete(void *row, char *str, int32_t size, int32_t *ssize) { - SVgObj *pVgroup = (SVgObj *)row; +static void *mgmtVgroupActionDelete(void *row, char *str, int32_t size, int32_t *ssize) { + SVgObj *pVgroup = row; SDbObj *pDb = mgmtGetDb(pVgroup->dbName); - if (pDb != NULL) mgmtRemoveVgroupFromDb(pDb, pVgroup); + if (pDb != NULL) { + mgmtRemoveVgroupFromDb(pDb, pVgroup); + } + mgmtUnSetDnodeVgid(pVgroup->vnodeGid, pVgroup->numOfVnodes); tfree(pVgroup->tableList); return NULL; } -void *mgmtVgroupActionUpdate(void *row, char *str, int32_t size, int32_t *ssize) { +static void *mgmtVgroupActionUpdate(void *row, char *str, int32_t size, int32_t *ssize) { mgmtVgroupActionReset(row, str, size, ssize); - SVgObj *pVgroup = (SVgObj *)row; + + SVgObj *pVgroup = (SVgObj *) row; int32_t oldTables = taosIdPoolMaxSize(pVgroup->idPool); SDbObj *pDb = mgmtGetDb(pVgroup->dbName); @@ -461,41 +425,37 @@ void *mgmtVgroupActionUpdate(void *row, char *str, int32_t size, int32_t *ssize) return NULL; } -void *mgmtVgroupActionEncode(void *row, char *str, int32_t size, int32_t *ssize) { - SVgObj *pVgroup = (SVgObj *)row; - int32_t tsize = pVgroup->updateEnd - (int8_t *)pVgroup; - if (size < tsize) { +static void *mgmtVgroupActionEncode(void *row, char *str, int32_t size, int32_t *ssize) { + SVgObj *pVgroup = (SVgObj *) row; + if (size < tsVgUpdateSize) { *ssize = -1; } else { - memcpy(str, pVgroup, tsize); - *ssize = tsize; + memcpy(str, pVgroup, tsVgUpdateSize); + *ssize = tsVgUpdateSize; } return NULL; } -void *mgmtVgroupActionDecode(void *row, char *str, int32_t size, int32_t *ssize) { - SVgObj *pVgroup = (SVgObj *)malloc(sizeof(SVgObj)); +static void *mgmtVgroupActionDecode(void *row, char *str, int32_t size, int32_t *ssize) { + SVgObj *pVgroup = (SVgObj *) malloc(sizeof(SVgObj)); if (pVgroup == NULL) return NULL; memset(pVgroup, 0, sizeof(SVgObj)); - int32_t tsize = pVgroup->updateEnd - (int8_t *)pVgroup; - memcpy(pVgroup, str, tsize); + int32_t tsVgUpdateSize = pVgroup->updateEnd - (int8_t *) pVgroup; + memcpy(pVgroup, str, tsVgUpdateSize); - return (void *)pVgroup; + return (void *) pVgroup; } -void *mgmtVgroupActionReset(void *row, char *str, int32_t size, int32_t *ssize) { - SVgObj *pVgroup = (SVgObj *)row; - int32_t tsize = pVgroup->updateEnd - (int8_t *)pVgroup; - - memcpy(pVgroup, str, tsize); - +static void *mgmtVgroupActionReset(void *row, char *str, int32_t size, int32_t *ssize) { + SVgObj *pVgroup = (SVgObj *) row; + memcpy(pVgroup, str, tsVgUpdateSize); return NULL; } -void *mgmtVgroupActionDestroy(void *row, char *str, int32_t size, int32_t *ssize) { - SVgObj *pVgroup = (SVgObj *)row; +static void *mgmtVgroupActionDestroy(void *row, char *str, int32_t size, int32_t *ssize) { + SVgObj *pVgroup = (SVgObj *) row; if (pVgroup->idPool) { taosIdPoolCleanUp(pVgroup->idPool); pVgroup->idPool = NULL; @@ -504,3 +464,80 @@ void *mgmtVgroupActionDestroy(void *row, char *str, int32_t size, int32_t *ssize tfree(row); return NULL; } + +void mgmtUpdateVgroup(SVgObj *pVgroup) { + sdbUpdateRow(tsVgroupSdb, pVgroup, tsVgUpdateSize, 0); +} + +void mgmtAddTableIntoVgroup(SVgObj *pVgroup, STableInfo *pTable) { + pVgroup->numOfTables++; + if (pTable->sid >= 0) + pVgroup->tableList[pTable->sid] = pTable; +} + +void mgmtRemoveTableFromVgroup(SVgObj *pVgroup, STableInfo *pTable) { + pVgroup->numOfTables--; + if (pTable->sid >= 0) + pVgroup->tableList[pTable->sid] = NULL; + taosFreeId(pVgroup->idPool, pTable->sid); +} + +SCreateVnodeMsg *mgmtBuildVpeersMsg(SVgObj *pVgroup, int32_t vnode) { + SDbObj *pDb = mgmtGetDb(pVgroup->dbName); + if (pDb == NULL) return NULL; + + SCreateVnodeMsg *pVPeers = rpcMallocCont(sizeof(SCreateVnodeMsg)); + if (pVPeers == NULL) return NULL; + + pVPeers->vnode = htonl(vnode); + pVPeers->cfg = pDb->cfg; + + SVnodeCfg *pCfg = &pVPeers->cfg; + pCfg->vgId = htonl(pVgroup->vgId); + pCfg->maxSessions = htonl(pCfg->maxSessions); + pCfg->cacheBlockSize = htonl(pCfg->cacheBlockSize); + pCfg->cacheNumOfBlocks.totalBlocks = htonl(pCfg->cacheNumOfBlocks.totalBlocks); + pCfg->daysPerFile = htonl(pCfg->daysPerFile); + pCfg->daysToKeep1 = htonl(pCfg->daysToKeep1); + pCfg->daysToKeep2 = htonl(pCfg->daysToKeep2); + pCfg->daysToKeep = htonl(pCfg->daysToKeep); + pCfg->commitTime = htonl(pCfg->commitTime); + pCfg->blocksPerTable = htons(pCfg->blocksPerTable); + pCfg->replications = (char) pVgroup->numOfVnodes; + pCfg->rowsInFileBlock = htonl(pCfg->rowsInFileBlock); + + SVPeerDesc *vpeerDesc = pVPeers->vpeerDesc; + for (int32_t j = 0; j < pVgroup->numOfVnodes; ++j) { + vpeerDesc[j].ip = htonl(pVgroup->vnodeGid[j].ip); + vpeerDesc[j].vnode = htonl(pVgroup->vnodeGid[j].vnode); + } + + return pVPeers; +} + +SVgObj *mgmtGetVgroupByVnode(uint32_t dnode, int32_t vnode) { + if (vnode < 0 || vnode >= TSDB_MAX_VNODES) { + return NULL; + } + + SDnodeObj *pDnode = mgmtGetDnode(dnode); + if (pDnode == NULL) { + return NULL; + } + + int32_t vgId = pDnode->vload[vnode].vgId; + return mgmtGetVgroup(vgId); +} + +SRpcIpSet mgmtGetIpSetFromVgroup(SVgObj *pVgroup) { + SRpcIpSet ipSet = {.numOfIps = pVgroup->numOfVnodes, .inUse = 0, .port = tsMgmtDnodePort + 1}; + for (int i = 0; i < pVgroup->numOfVnodes; ++i) { + ipSet.ip[i] = pVgroup->vnodeGid[i].ip; + } + return ipSet; +} + +SRpcIpSet mgmtGetIpSetFromIp(uint32_t ip) { + SRpcIpSet ipSet = {.ip[0] = ip, .numOfIps = 1, .inUse = 0, .port = tsMgmtDnodePort + 1}; + return ipSet; +} \ No newline at end of file diff --git a/src/plugins/http/inc/httpHandle.h b/src/plugins/http/inc/httpHandle.h index c564337187088b9ced276984c1a5cdec210c6af8..9c6a263c5bd328ca0fc59eb5365f7722324ef729 100644 --- a/src/plugins/http/inc/httpHandle.h +++ b/src/plugins/http/inc/httpHandle.h @@ -37,7 +37,7 @@ #define HTTP_STEP_SIZE 1024 //http message get process step by step #define HTTP_MAX_URL 5 //http url stack size #define HTTP_METHOD_SCANNER_SIZE 7 //http method fp size -#define HTTP_GC_TARGET_SIZE 128 +#define HTTP_GC_TARGET_SIZE 512 #define HTTP_VERSION_10 0 #define HTTP_VERSION_11 1 diff --git a/src/plugins/http/src/gcJson.c b/src/plugins/http/src/gcJson.c index 1a86c5d24f23ec62bb1c51aabdd0639940edc54a..8f596337146a3937df72287f332917b3bffa21ac 100644 --- a/src/plugins/http/src/gcJson.c +++ b/src/plugins/http/src/gcJson.c @@ -127,42 +127,43 @@ bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, // for group by if (groupFields != -1) { char target[HTTP_GC_TARGET_SIZE]; + int len; + len = snprintf(target,HTTP_GC_TARGET_SIZE,"%s{",aliasBuffer); + for (int i = dataFields + 1; ivaluestring); - if (nameLen == 0 || nameLen > TSDB_METER_NAME_LEN) { + if (nameLen == 0 || nameLen > TSDB_TABLE_NAME_LEN) { parsedOk = false; goto ParseEnd; } @@ -395,7 +395,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { httpSendErrorResp(pContext, HTTP_TG_METRIC_NAME_NULL); return false; } - if (nameLen >= TSDB_METER_NAME_LEN - 7) { + if (nameLen >= TSDB_TABLE_NAME_LEN - 7) { httpSendErrorResp(pContext, HTTP_TG_METRIC_NAME_LONG); return false; } @@ -484,7 +484,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { return false; } - if (strlen(host->valuestring) >= TSDB_METER_NAME_LEN) { + if (strlen(host->valuestring) >= TSDB_TABLE_NAME_LEN) { httpSendErrorResp(pContext, HTTP_TG_TABLE_SIZE); return false; } diff --git a/src/plugins/monitor/src/monitorSystem.c b/src/plugins/monitor/src/monitorSystem.c index f8653e4320ef12a8e26576240b3ecd8313e19d01..5a42d66493b56e6d3a252b2ededbc786b9445089 100644 --- a/src/plugins/monitor/src/monitorSystem.c +++ b/src/plugins/monitor/src/monitorSystem.c @@ -216,7 +216,8 @@ void monitorInitDatabaseCb(void *param, TAOS_RES *result, int code) { if (-code == TSDB_CODE_TABLE_ALREADY_EXIST || -code == TSDB_CODE_DB_ALREADY_EXIST || code >= 0) { monitorTrace("monitor:%p, sql success, code:%d, %s", monitor->conn, code, monitor->sql); if (monitor->cmdIndex == MONITOR_CMD_CREATE_TB_LOG) { - taosLogFp = monitorSaveLog; + //TODO + //taosLogFp = monitorSaveLog; taosLogSqlFp = monitorExecuteSQL; taosLogAcctFp = monitorSaveAcctLog; monitorLPrint("dnode:%s is started", tsPrivateIp); diff --git a/src/rpc/inc/rpcCache.h b/src/rpc/inc/rpcCache.h index 5fc7992e43f2dfdb887f46c334799be09d4b1990..2a386c066eb678cb4b4eb07b3887ad1fd4ce0b2a 100644 --- a/src/rpc/inc/rpcCache.h +++ b/src/rpc/inc/rpcCache.h @@ -22,8 +22,8 @@ extern "C" { void *rpcOpenConnCache(int maxSessions, void (*cleanFp)(void *), void *tmrCtrl, int64_t keepTimer); void rpcCloseConnCache(void *handle); -void rpcAddConnIntoCache(void *handle, void *data, uint32_t ip, uint16_t port, char *user); -void *rpcGetConnFromCache(void *handle, uint32_t ip, uint16_t port, char *user); +void rpcAddConnIntoCache(void *handle, void *data, uint32_t ip, uint16_t port, int8_t connType); +void *rpcGetConnFromCache(void *handle, uint32_t ip, uint16_t port, int8_t connType); #ifdef __cplusplus } diff --git a/src/rpc/inc/rpcClient.h b/src/rpc/inc/rpcClient.h index dc5e9f744a9b8bd8c1cc359af30884df4459ffdc..c87ae7931276c30a902a484406cc80c9c798ff6a 100644 --- a/src/rpc/inc/rpcClient.h +++ b/src/rpc/inc/rpcClient.h @@ -26,7 +26,7 @@ void *taosInitTcpClient(char *ip, uint16_t port, char *label, int num, void *fp, void taosCleanUpTcpClient(void *chandle); void *taosOpenTcpClientConnection(void *shandle, void *thandle, char *ip, uint16_t port); void taosCloseTcpClientConnection(void *chandle); -int taosSendTcpClientData(uint32_t ip, uint16_t port, char *data, int len, void *chandle); +int taosSendTcpClientData(uint32_t ip, uint16_t port, void *data, int len, void *chandle); #ifdef __cplusplus } diff --git a/src/rpc/inc/rpcHead.h b/src/rpc/inc/rpcHead.h index bfdcfb0beeae011215416ec08075d832dcd4880a..9bbcd60fc4d386b9afc1b52c82b9cbe645193f7a 100644 --- a/src/rpc/inc/rpcHead.h +++ b/src/rpc/inc/rpcHead.h @@ -20,24 +20,44 @@ extern "C" { #endif +#define RPC_CONN_UDPS 0 +#define RPC_CONN_UDPC 1 +#define RPC_CONN_TCPS 2 +#define RPC_CONN_TCPC 3 +#define RPC_CONN_TCP 2 + +extern int tsRpcOverhead; + +typedef struct { + void *msg; + int msgLen; + uint32_t ip; + uint16_t port; + int connType; + void *shandle; + void *thandle; + void *chandle; +} SRecvInfo; + #pragma pack(push, 1) typedef struct { char version:4; // RPC version char comp:4; // compression algorithm, 0:no compression 1:lz4 - char tcp:2; // tcp flag + char resflag:2; // reserved bits char spi:3; // security parameter index char encrypt:3; // encrypt algorithm, 0: no encryption uint16_t tranId; // transcation ID uint32_t uid; // for unique ID inside a client uint32_t sourceId; // source ID, an index for connection list uint32_t destId; // destination ID, an index for connection list - char meterId[TSDB_UNI_LEN]; + uint32_t destIp; // destination IP address, for NAT scenario + char user[TSDB_UNI_LEN]; // user ID uint16_t port; // for UDP only, port may be changed char empty[1]; // reserved uint8_t msgType; // message type int32_t msgLen; // message length including the header iteslf - int32_t code; + int32_t code; // code in response message uint8_t content[0]; // message body starts from here } SRpcHead; @@ -53,6 +73,7 @@ typedef struct { #pragma pack(pop) + #ifdef __cplusplus } #endif diff --git a/src/rpc/inc/rpcServer.h b/src/rpc/inc/rpcServer.h index eccbd7271affe18e590e9b9da5cba57996df7eef..6b238733a4773a0fd3676380bd683bc5f968d075 100644 --- a/src/rpc/inc/rpcServer.h +++ b/src/rpc/inc/rpcServer.h @@ -25,7 +25,7 @@ extern "C" { void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle); void taosCleanUpTcpServer(void *param); void taosCloseTcpServerConnection(void *param); -int taosSendTcpServerData(uint32_t ip, uint16_t port, char *data, int len, void *chandle); +int taosSendTcpServerData(uint32_t ip, uint16_t port, void *data, int len, void *chandle); #ifdef __cplusplus } diff --git a/src/rpc/inc/rpcUdp.h b/src/rpc/inc/rpcUdp.h index 03498ac69dc283e25131e50621aa76f52f781b1c..a84f7c4a49d56fc85128df887cc267d88a414f6d 100644 --- a/src/rpc/inc/rpcUdp.h +++ b/src/rpc/inc/rpcUdp.h @@ -22,10 +22,9 @@ extern "C" { #include "taosdef.h" -void *taosInitUdpServer(char *ip, uint16_t port, char *label, int, void *fp, void *shandle); -void *taosInitUdpClient(char *ip, uint16_t port, char *label, int, void *fp, void *shandle); +void *taosInitUdpConnection(char *ip, uint16_t port, char *label, int, void *fp, void *shandle); void taosCleanUpUdpConnection(void *handle); -int taosSendUdpData(uint32_t ip, uint16_t port, char *data, int dataLen, void *chandle); +int taosSendUdpData(uint32_t ip, uint16_t port, void *data, int dataLen, void *chandle); void *taosOpenUdpConnection(void *shandle, void *thandle, char *ip, uint16_t port); void taosFreeMsgHdr(void *hdr); diff --git a/src/mnode/inc/mgmtStreamTable.h b/src/rpc/inc/tqueue.h similarity index 53% rename from src/mnode/inc/mgmtStreamTable.h rename to src/rpc/inc/tqueue.h index e980f76742d16926dc792312134b0a7c929e8514..09a25e7e93af8d57a320db865ff90e0cb54fa671 100644 --- a/src/mnode/inc/mgmtStreamTable.h +++ b/src/rpc/inc/tqueue.h @@ -13,27 +13,27 @@ * along with this program. If not, see . */ -#ifndef TBASE_MNODE_STREAM_TABLE_H -#define TBASE_MNODE_STREAM_TABLE_H +#ifndef TDENGINE_TSCHED_H +#define TDENGINE_TSCHED_H #ifdef __cplusplus extern "C" { #endif -#include -#include -#include "mnode.h" +typedef struct _sched_msg { + void *msg; + int msgLen; + int8_t type; + int32_t code; + void *handle; +} SRpcMsg; -int32_t mgmtInitStreamTables(); -void mgmtCleanUpStreamTables(); -int32_t mgmtCreateStreamTable(SDbObj *pDb, SCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t sid); -int32_t mgmtDropStreamTable(SDbObj *pDb, SStreamTableObj *pTable); -int32_t mgmtAlterStreamTable(SDbObj *pDb, SAlterTableMsg *pAlter); -SStreamTableObj* mgmtGetStreamTable(char *tableId); -int8_t * mgmtBuildCreateStreamTableMsg(SStreamTableObj *pTable, SVgObj *pVgroup); +void *taosInitMsgQueue(int queueSize, void (*fp)(int num, SRpcMsg *), const char *label); +int taosPutIntoMsgQueue(void *qhandle, SRpcMsg *pMsg); +void taosCleanUpMsgQueue(void *param); #ifdef __cplusplus } #endif -#endif +#endif // TDENGINE_TSCHED_H diff --git a/src/rpc/src/rpcCache.c b/src/rpc/src/rpcCache.c index 6f5a8e9d539a0822a1adf5546a77f3dcd469e9f6..a397f6f84522b112fdc1bed028b748ff7d29cfcf 100644 --- a/src/rpc/src/rpcCache.c +++ b/src/rpc/src/rpcCache.c @@ -14,7 +14,6 @@ */ #include "os.h" - #include "tglobalcfg.h" #include "tlog.h" #include "tmempool.h" @@ -26,6 +25,7 @@ typedef struct _c_hash_t { uint32_t ip; uint16_t port; + char connType; struct _c_hash_t *prev; struct _c_hash_t *next; void * data; @@ -43,49 +43,77 @@ typedef struct { void (*cleanFp)(void *); void *tmrCtrl; void *pTimer; + int64_t *lockedBy; } SConnCache; -int rpcHashConn(void *handle, uint32_t ip, uint16_t port, char *user) { - SConnCache *pCache = (SConnCache *)handle; - int hash = 0; - // size_t user_len = strlen(user); +static int rpcHashConn(void *handle, uint32_t ip, uint16_t port, int8_t connType); +static void rpcLockCache(int64_t *lockedBy); +static void rpcUnlockCache(int64_t *lockedBy); +static void rpcCleanConnCache(void *handle, void *tmrId); +static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t time); - hash = ip >> 16; - hash += (unsigned short)(ip & 0xFFFF); - hash += port; - while (*user != '\0') { - hash += *user; - user++; +void *rpcOpenConnCache(int maxSessions, void (*cleanFp)(void *), void *tmrCtrl, int64_t keepTimer) { + SConnHash **connHashList; + mpool_h connHashMemPool; + SConnCache *pCache; + + connHashMemPool = taosMemPoolInit(maxSessions, sizeof(SConnHash)); + if (connHashMemPool == 0) return NULL; + + connHashList = calloc(sizeof(SConnHash *), maxSessions); + if (connHashList == 0) { + taosMemPoolCleanUp(connHashMemPool); + return NULL; } - hash = hash % pCache->maxSessions; + pCache = malloc(sizeof(SConnCache)); + if (pCache == NULL) { + taosMemPoolCleanUp(connHashMemPool); + free(connHashList); + return NULL; + } + memset(pCache, 0, sizeof(SConnCache)); - return hash; + pCache->count = calloc(sizeof(int), maxSessions); + pCache->total = 0; + pCache->keepTimer = keepTimer; + pCache->maxSessions = maxSessions; + pCache->connHashMemPool = connHashMemPool; + pCache->connHashList = connHashList; + pCache->cleanFp = cleanFp; + pCache->tmrCtrl = tmrCtrl; + pCache->lockedBy = calloc(sizeof(int64_t), maxSessions); + taosTmrReset(rpcCleanConnCache, pCache->keepTimer * 2, pCache, pCache->tmrCtrl, &pCache->pTimer); + + pthread_mutex_init(&pCache->mutex, NULL); + + return pCache; } -void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t time) { - if (pNode == NULL || (time < pCache->keepTimer + pNode->time) ) return; +void rpcCloseConnCache(void *handle) { + SConnCache *pCache; - SConnHash *pPrev = pNode->prev, *pNext; + pCache = (SConnCache *)handle; + if (pCache == NULL || pCache->maxSessions == 0) return; - while (pNode) { - (*pCache->cleanFp)(pNode->data); - pNext = pNode->next; - pCache->total--; - pCache->count[hash]--; - tTrace("%p ip:0x%x:%hu:%d:%p removed from cache, connections:%d", pNode->data, pNode->ip, pNode->port, hash, pNode, - pCache->count[hash]); - taosMemPoolFree(pCache->connHashMemPool, (char *)pNode); - pNode = pNext; - } + pthread_mutex_lock(&pCache->mutex); - if (pPrev) - pPrev->next = NULL; - else - pCache->connHashList[hash] = NULL; + taosTmrStopA(&(pCache->pTimer)); + + if (pCache->connHashMemPool) taosMemPoolCleanUp(pCache->connHashMemPool); + + tfree(pCache->connHashList); + tfree(pCache->count) + + pthread_mutex_unlock(&pCache->mutex); + + pthread_mutex_destroy(&pCache->mutex); + + memset(pCache, 0, sizeof(SConnCache)); + free(pCache); } -void rpcAddConnIntoCache(void *handle, void *data, uint32_t ip, uint16_t port, char *user) { +void rpcAddConnIntoCache(void *handle, void *data, uint32_t ip, uint16_t port, int8_t connType) { int hash; SConnHash * pNode; SConnCache *pCache; @@ -96,54 +124,34 @@ void rpcAddConnIntoCache(void *handle, void *data, uint32_t ip, uint16_t port, c assert(pCache); assert(data); - hash = rpcHashConn(pCache, ip, port, user); + hash = rpcHashConn(pCache, ip, port, connType); pNode = (SConnHash *)taosMemPoolMalloc(pCache->connHashMemPool); pNode->ip = ip; pNode->port = port; + pNode->connType = connType; pNode->data = data; pNode->prev = NULL; pNode->time = time; - pthread_mutex_lock(&pCache->mutex); + rpcLockCache(pCache->lockedBy+hash); pNode->next = pCache->connHashList[hash]; if (pCache->connHashList[hash] != NULL) (pCache->connHashList[hash])->prev = pNode; pCache->connHashList[hash] = pNode; - pCache->total++; pCache->count[hash]++; rpcRemoveExpiredNodes(pCache, pNode->next, hash, time); - pthread_mutex_unlock(&pCache->mutex); - - tTrace("%p ip:0x%x:%hu:%d:%p added into cache, connections:%d", data, ip, port, hash, pNode, pCache->count[hash]); - - return; -} - -void rpcCleanConnCache(void *handle, void *tmrId) { - int hash; - SConnHash * pNode; - SConnCache *pCache; + rpcUnlockCache(pCache->lockedBy+hash); - pCache = (SConnCache *)handle; - if (pCache == NULL || pCache->maxSessions == 0) return; - if (pCache->pTimer != tmrId) return; + pCache->total++; - uint64_t time = taosGetTimestampMs(); + tTrace("%p ip:0x%x:%hu:%d:%d:%p added into cache, connections:%d", data, ip, port, connType, hash, pNode, pCache->count[hash]); - for (hash = 0; hash < pCache->maxSessions; ++hash) { - pthread_mutex_lock(&pCache->mutex); - pNode = pCache->connHashList[hash]; - rpcRemoveExpiredNodes(pCache, pNode, hash, time); - pthread_mutex_unlock(&pCache->mutex); - } - - // tTrace("timer, total connections in cache:%d", pCache->total); - taosTmrReset(rpcCleanConnCache, pCache->keepTimer * 2, pCache, pCache->tmrCtrl, &pCache->pTimer); + return; } -void *rpcGetConnFromCache(void *handle, uint32_t ip, uint16_t port, char *user) { +void *rpcGetConnFromCache(void *handle, uint32_t ip, uint16_t port, int8_t connType) { int hash; SConnHash * pNode; SConnCache *pCache; @@ -154,8 +162,8 @@ void *rpcGetConnFromCache(void *handle, uint32_t ip, uint16_t port, char *user) uint64_t time = taosGetTimestampMs(); - hash = rpcHashConn(pCache, ip, port, user); - pthread_mutex_lock(&pCache->mutex); + hash = rpcHashConn(pCache, ip, port, connType); + rpcLockCache(pCache->lockedBy+hash); pNode = pCache->connHashList[hash]; while (pNode) { @@ -165,7 +173,7 @@ void *rpcGetConnFromCache(void *handle, uint32_t ip, uint16_t port, char *user) break; } - if (pNode->ip == ip && pNode->port == port) break; + if (pNode->ip == ip && pNode->port == port && pNode->connType == connType) break; pNode = pNode->next; } @@ -189,71 +197,87 @@ void *rpcGetConnFromCache(void *handle, uint32_t ip, uint16_t port, char *user) pCache->count[hash]--; } - pthread_mutex_unlock(&pCache->mutex); + rpcUnlockCache(pCache->lockedBy+hash); if (pData) { - tTrace("%p ip:0x%x:%hu:%d:%p retrieved from cache, connections:%d", pData, ip, port, hash, pNode, pCache->count[hash]); + tTrace("%p ip:0x%x:%hu:%d:%d:%p retrieved from cache, connections:%d", pData, ip, port, connType, hash, pNode, pCache->count[hash]); } return pData; } -void *rpcOpenConnCache(int maxSessions, void (*cleanFp)(void *), void *tmrCtrl, int64_t keepTimer) { - SConnHash **connHashList; - mpool_h connHashMemPool; +static void rpcCleanConnCache(void *handle, void *tmrId) { + int hash; + SConnHash * pNode; SConnCache *pCache; - connHashMemPool = taosMemPoolInit(maxSessions, sizeof(SConnHash)); - if (connHashMemPool == 0) return NULL; + pCache = (SConnCache *)handle; + if (pCache == NULL || pCache->maxSessions == 0) return; + if (pCache->pTimer != tmrId) return; - connHashList = calloc(sizeof(SConnHash *), maxSessions); - if (connHashList == 0) { - taosMemPoolCleanUp(connHashMemPool); - return NULL; - } + uint64_t time = taosGetTimestampMs(); - pCache = malloc(sizeof(SConnCache)); - if (pCache == NULL) { - taosMemPoolCleanUp(connHashMemPool); - free(connHashList); - return NULL; + for (hash = 0; hash < pCache->maxSessions; ++hash) { + rpcLockCache(pCache->lockedBy+hash); + pNode = pCache->connHashList[hash]; + rpcRemoveExpiredNodes(pCache, pNode, hash, time); + rpcUnlockCache(pCache->lockedBy+hash); } - memset(pCache, 0, sizeof(SConnCache)); - pCache->count = calloc(sizeof(int), maxSessions); - pCache->total = 0; - pCache->keepTimer = keepTimer; - pCache->maxSessions = maxSessions; - pCache->connHashMemPool = connHashMemPool; - pCache->connHashList = connHashList; - pCache->cleanFp = cleanFp; - pCache->tmrCtrl = tmrCtrl; + // tTrace("timer, total connections in cache:%d", pCache->total); taosTmrReset(rpcCleanConnCache, pCache->keepTimer * 2, pCache, pCache->tmrCtrl, &pCache->pTimer); - - pthread_mutex_init(&pCache->mutex, NULL); - - return pCache; } -void rpcCloseConnCache(void *handle) { - SConnCache *pCache; +static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t time) { + if (pNode == NULL || (time < pCache->keepTimer + pNode->time) ) return; - pCache = (SConnCache *)handle; - if (pCache == NULL || pCache->maxSessions == 0) return; + SConnHash *pPrev = pNode->prev, *pNext; - pthread_mutex_lock(&pCache->mutex); + while (pNode) { + (*pCache->cleanFp)(pNode->data); + pNext = pNode->next; + pCache->total--; + pCache->count[hash]--; + tTrace("%p ip:0x%x:%hu:%d:%d:%p removed from cache, connections:%d", pNode->data, pNode->ip, pNode->port, pNode->connType, hash, pNode, + pCache->count[hash]); + taosMemPoolFree(pCache->connHashMemPool, (char *)pNode); + pNode = pNext; + } - taosTmrStopA(&(pCache->pTimer)); + if (pPrev) + pPrev->next = NULL; + else + pCache->connHashList[hash] = NULL; +} - if (pCache->connHashMemPool) taosMemPoolCleanUp(pCache->connHashMemPool); +static int rpcHashConn(void *handle, uint32_t ip, uint16_t port, int8_t connType) { + SConnCache *pCache = (SConnCache *)handle; + int hash = 0; - tfree(pCache->connHashList); - tfree(pCache->count) + hash = ip >> 16; + hash += (unsigned short)(ip & 0xFFFF); + hash += port; + hash += connType; + + hash = hash % pCache->maxSessions; - pthread_mutex_unlock(&pCache->mutex); + return hash; +} - pthread_mutex_destroy(&pCache->mutex); +static void rpcLockCache(int64_t *lockedBy) { + int64_t tid = taosGetPthreadId(); + int i = 0; + while (atomic_val_compare_exchange_64(lockedBy, 0, tid) != 0) { + if (++i % 100 == 0) { + sched_yield(); + } + } +} - memset(pCache, 0, sizeof(SConnCache)); - free(pCache); +static void rpcUnlockCache(int64_t *lockedBy) { + int64_t tid = taosGetPthreadId(); + if (atomic_val_compare_exchange_64(lockedBy, tid, 0) != tid) { + assert(false); + } } + diff --git a/src/rpc/src/rpcClient.c b/src/rpc/src/rpcClient.c index f600004266a1d5edc10695d7b6aec6f9d54908fd..b362b1ba4494ad6dc0ba1b077f10ad06d3c18afb 100644 --- a/src/rpc/src/rpcClient.c +++ b/src/rpc/src/rpcClient.c @@ -45,158 +45,17 @@ typedef struct _tcp_client { int numOfFds; char label[12]; char ipstr[20]; - void * shandle; // handle passed by upper layer during server initialization - void *(*processData)(char *data, int dataLen, unsigned int ip, uint16_t port, void *shandle, void *thandle, - void *chandle); - // char buffer[128000]; + void *shandle; // handle passed by upper layer during server initialization + void *(*processData)(SRecvInfo *pRecv); } STcpClient; #define maxTcpEvents 100 -static void taosCleanUpTcpFdObj(STcpFd *pFdObj) { - STcpClient *pTcp; - - if (pFdObj == NULL) return; - if (pFdObj->signature != pFdObj) return; - - pTcp = pFdObj->pTcp; - if (pTcp == NULL) { - tError("double free TcpFdObj!!!!"); - return; - } - - epoll_ctl(pTcp->pollFd, EPOLL_CTL_DEL, pFdObj->fd, NULL); - close(pFdObj->fd); - - pthread_mutex_lock(&pTcp->mutex); - - pTcp->numOfFds--; - - if (pTcp->numOfFds < 0) tError("%s number of TCP FDs shall never be negative", pTcp->label); - - // remove from the FdObject list - - if (pFdObj->prev) { - (pFdObj->prev)->next = pFdObj->next; - } else { - pTcp->pHead = pFdObj->next; - } - - if (pFdObj->next) { - (pFdObj->next)->prev = pFdObj->prev; - } - - pthread_mutex_unlock(&pTcp->mutex); - - // notify the upper layer to clean the associated context - if (pFdObj->thandle) (*(pTcp->processData))(NULL, 0, 0, 0, pTcp->shandle, pFdObj->thandle, NULL); - - tTrace("%s TCP FD is cleaned up, numOfFds:%d", pTcp->label, pTcp->numOfFds); - - memset(pFdObj, 0, sizeof(STcpFd)); - - tfree(pFdObj); -} - -void taosCleanUpTcpClient(void *chandle) { - STcpClient *pTcp = (STcpClient *)chandle; - if (pTcp == NULL) return; - - while (pTcp->pHead) { - taosCleanUpTcpFdObj(pTcp->pHead); - pTcp->pHead = pTcp->pHead->next; - } - - close(pTcp->pollFd); - - pthread_cancel(pTcp->thread); - pthread_join(pTcp->thread, NULL); - - // tTrace (":%s, all connections are cleaned up", pTcp->label); - - tfree(pTcp); -} - -static void *taosReadTcpData(void *param) { - STcpClient * pTcp = (STcpClient *)param; - int i, fdNum; - STcpFd * pFdObj; - struct epoll_event events[maxTcpEvents]; - - while (1) { - pthread_mutex_lock(&pTcp->mutex); - if (pTcp->numOfFds < 1) pthread_cond_wait(&pTcp->fdReady, &pTcp->mutex); - pthread_mutex_unlock(&pTcp->mutex); - - fdNum = epoll_wait(pTcp->pollFd, events, maxTcpEvents, -1); - if (fdNum < 0) continue; - - for (i = 0; i < fdNum; ++i) { - pFdObj = events[i].data.ptr; - - if (events[i].events & EPOLLERR) { - tTrace("%s TCP error happened on FD\n", pTcp->label); - taosCleanUpTcpFdObj(pFdObj); - continue; - } - - if (events[i].events & EPOLLHUP) { - tTrace("%s TCP FD hang up\n", pTcp->label); - taosCleanUpTcpFdObj(pFdObj); - continue; - } - - void *buffer = malloc(1024); - if (NULL == buffer) { - tTrace("%s TCP malloc(size:1024) fail\n", pTcp->label); - taosCleanUpTcpFdObj(pFdObj); - continue; - } - - int headLen = taosReadMsg(pFdObj->fd, buffer, sizeof(SRpcHead)); - if (headLen != sizeof(SRpcHead)) { - tError("%s read error, headLen:%d", pTcp->label, headLen); - tfree(buffer); - taosCleanUpTcpFdObj(pFdObj); - continue; - } - - int dataLen = (int32_t)htonl((uint32_t)((SRpcHead *)buffer)->msgLen); - if (dataLen > 1024) { - void *b = realloc(buffer, (size_t)dataLen); - if (NULL == b) { - tTrace("%s TCP malloc(size:%d) fail\n", pTcp->label, dataLen); - tfree(buffer); - taosCleanUpTcpFdObj(pFdObj); - continue; - } - buffer = b; - } - - int leftLen = dataLen - headLen; - int retLen = taosReadMsg(pFdObj->fd, buffer + headLen, leftLen); - - // tTrace("%s TCP data is received, ip:%s port:%u len:%d", pTcp->label, pFdObj->ipstr, pFdObj->port, dataLen); - - if (leftLen != retLen) { - tError("%s read error, leftLen:%d retLen:%d", pTcp->label, leftLen, retLen); - tfree(buffer); - taosCleanUpTcpFdObj(pFdObj); - continue; - } - - pFdObj->thandle = - (*(pTcp->processData))(buffer, dataLen, pFdObj->ip, pFdObj->port, pTcp->shandle, pFdObj->thandle, pFdObj); - - if (pFdObj->thandle == NULL) taosCleanUpTcpFdObj(pFdObj); - } - } - - return NULL; -} +static void taosCleanUpTcpFdObj(STcpFd *pFdObj); +static void *taosReadTcpData(void *param); void *taosInitTcpClient(char *ip, uint16_t port, char *label, int num, void *fp, void *shandle) { - STcpClient * pTcp; + STcpClient *pTcp; pthread_attr_t thattr; pTcp = (STcpClient *)malloc(sizeof(STcpClient)); @@ -235,12 +94,23 @@ void *taosInitTcpClient(char *ip, uint16_t port, char *label, int num, void *fp, return pTcp; } -void taosCloseTcpClientConnection(void *chandle) { - STcpFd *pFdObj = (STcpFd *)chandle; +void taosCleanUpTcpClient(void *chandle) { + STcpClient *pTcp = (STcpClient *)chandle; + if (pTcp == NULL) return; - if (pFdObj == NULL) return; + while (pTcp->pHead) { + taosCleanUpTcpFdObj(pTcp->pHead); + pTcp->pHead = pTcp->pHead->next; + } - taosCleanUpTcpFdObj(pFdObj); + close(pTcp->pollFd); + + pthread_cancel(pTcp->thread); + pthread_join(pTcp->thread, NULL); + + // tTrace (":%s, all connections are cleaned up", pTcp->label); + + tfree(pTcp); } void *taosOpenTcpClientConnection(void *shandle, void *thandle, char *ip, uint16_t port) { @@ -250,16 +120,7 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, char *ip, uint16 struct in_addr destIp; int fd; - /* - if ( (strcmp(ip, "127.0.0.1") == 0 ) || (strcmp(ip, "localhost") == 0 ) ) { - fd = taosOpenUDClientSocket(ip, port); - } else { - fd = taosOpenTcpClientSocket(ip, port, pTcp->ipstr); - } - */ - fd = taosOpenTcpClientSocket(ip, port, pTcp->ipstr); - if (fd <= 0) return NULL; pFdObj = (STcpFd *)malloc(sizeof(STcpFd)); @@ -290,27 +151,161 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, char *ip, uint16 // notify the data process, add into the FdObj list pthread_mutex_lock(&(pTcp->mutex)); - pFdObj->next = pTcp->pHead; - if (pTcp->pHead) (pTcp->pHead)->prev = pFdObj; - pTcp->pHead = pFdObj; - pTcp->numOfFds++; pthread_cond_signal(&pTcp->fdReady); - pthread_mutex_unlock(&(pTcp->mutex)); - tTrace("%s TCP connection to ip:%s port:%hu is created, numOfFds:%d", pTcp->label, ip, port, pTcp->numOfFds); + tTrace("%s TCP connection to %s:%hu is created, FD:%p numOfFds:%d", pTcp->label, ip, port, pFdObj, pTcp->numOfFds); return pFdObj; } -int taosSendTcpClientData(uint32_t ip, uint16_t port, char *data, int len, void *chandle) { +void taosCloseTcpClientConnection(void *chandle) { + STcpFd *pFdObj = (STcpFd *)chandle; + + if (pFdObj == NULL) return; + + taosCleanUpTcpFdObj(pFdObj); +} + +int taosSendTcpClientData(uint32_t ip, uint16_t port, void *data, int len, void *chandle) { STcpFd *pFdObj = (STcpFd *)chandle; if (chandle == NULL) return -1; return (int)send(pFdObj->fd, data, (size_t)len, 0); } + +static void taosCleanUpTcpFdObj(STcpFd *pFdObj) { + STcpClient *pTcp; + SRecvInfo recvInfo; + + if (pFdObj == NULL) return; + if (pFdObj->signature != pFdObj) return; + + pTcp = pFdObj->pTcp; + if (pTcp == NULL) { + tError("double free TcpFdObj!!!!"); + return; + } + + epoll_ctl(pTcp->pollFd, EPOLL_CTL_DEL, pFdObj->fd, NULL); + close(pFdObj->fd); + + pthread_mutex_lock(&pTcp->mutex); + + pTcp->numOfFds--; + + if (pTcp->numOfFds < 0) + tError("%s number of TCP FDs shall never be negative, FD:%p", pTcp->label, pFdObj); + + if (pFdObj->prev) { + (pFdObj->prev)->next = pFdObj->next; + } else { + pTcp->pHead = pFdObj->next; + } + + if (pFdObj->next) { + (pFdObj->next)->prev = pFdObj->prev; + } + + pthread_mutex_unlock(&pTcp->mutex); + + recvInfo.msg = NULL; + recvInfo.msgLen = 0; + recvInfo.ip = 0; + recvInfo.port = 0; + recvInfo.shandle = pTcp->shandle; + recvInfo.thandle = pFdObj->thandle;; + recvInfo.chandle = NULL; + recvInfo.connType = RPC_CONN_TCP; + + if (pFdObj->thandle) (*(pTcp->processData))(&recvInfo); + tTrace("%s TCP is cleaned up, FD:%p numOfFds:%d", pTcp->label, pFdObj, pTcp->numOfFds); + + memset(pFdObj, 0, sizeof(STcpFd)); + tfree(pFdObj); +} + +static void *taosReadTcpData(void *param) { + STcpClient *pTcp = (STcpClient *)param; + int i, fdNum; + STcpFd *pFdObj; + struct epoll_event events[maxTcpEvents]; + SRecvInfo recvInfo; + SRpcHead rpcHead; + + while (1) { + pthread_mutex_lock(&pTcp->mutex); + if (pTcp->numOfFds < 1) pthread_cond_wait(&pTcp->fdReady, &pTcp->mutex); + pthread_mutex_unlock(&pTcp->mutex); + + fdNum = epoll_wait(pTcp->pollFd, events, maxTcpEvents, -1); + if (fdNum < 0) continue; + + for (i = 0; i < fdNum; ++i) { + pFdObj = events[i].data.ptr; + + if (events[i].events & EPOLLERR) { + tTrace("%s TCP error happened on FD\n", pTcp->label); + taosCleanUpTcpFdObj(pFdObj); + continue; + } + + if (events[i].events & EPOLLHUP) { + tTrace("%s TCP FD hang up\n", pTcp->label); + taosCleanUpTcpFdObj(pFdObj); + continue; + } + + int headLen = taosReadMsg(pFdObj->fd, &rpcHead, sizeof(SRpcHead)); + if (headLen != sizeof(SRpcHead)) { + tError("%s read error, headLen:%d", pTcp->label, headLen); + taosCleanUpTcpFdObj(pFdObj); + continue; + } + + int32_t msgLen = (int32_t)htonl((uint32_t)rpcHead.msgLen); + char *buffer = (char *)malloc((size_t)msgLen + tsRpcOverhead); + if (NULL == buffer) { + tTrace("%s TCP malloc(size:%d) fail\n", pTcp->label, msgLen); + taosCleanUpTcpFdObj(pFdObj); + continue; + } + + char *msg = buffer + tsRpcOverhead; + int32_t leftLen = msgLen - headLen; + int32_t retLen = taosReadMsg(pFdObj->fd, msg + headLen, leftLen); + + if (leftLen != retLen) { + tError("%s read error, leftLen:%d retLen:%d", pTcp->label, leftLen, retLen); + tfree(buffer); + taosCleanUpTcpFdObj(pFdObj); + continue; + } + + // tTrace("%s TCP data is received, ip:%s:%u len:%d", pTcp->label, pFdObj->ipstr, pFdObj->port, msgLen); + + memcpy(msg, &rpcHead, sizeof(SRpcHead)); + recvInfo.msg = msg; + recvInfo.msgLen = msgLen; + recvInfo.ip = pFdObj->ip; + recvInfo.port = pFdObj->port; + recvInfo.shandle = pTcp->shandle; + recvInfo.thandle = pFdObj->thandle;; + recvInfo.chandle = pFdObj; + recvInfo.connType = RPC_CONN_TCP; + + pFdObj->thandle = (*(pTcp->processData))(&recvInfo); + + if (pFdObj->thandle == NULL) taosCleanUpTcpFdObj(pFdObj); + } + } + + return NULL; +} + + diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index fcbf9e406831e4a17bd24f9f32cea95c6c85bd59..6ceb1f98bb8e524861c4a14633395e2e02853eb3 100755 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -41,28 +41,30 @@ #define rpcIsReq(type) (type & 1U) typedef struct { - int sessions; - int numOfThreads; - int idleTime; // milliseconds; + int sessions; // number of sessions allowed + int numOfThreads; // number of threads to process incoming messages + int idleTime; // milliseconds; char localIp[TSDB_IPv4ADDR_LEN]; uint16_t localPort; - int connType; + int8_t connType; + int index; // for UDP server only, round robin for multiple threads char label[12]; - char meterId[TSDB_UNI_LEN]; // meter ID - char spi; // security parameter index - char encrypt; // encrypt algorithm + char user[TSDB_UNI_LEN]; // meter ID + char spi; // security parameter index + char encrypt; // encrypt algorithm char secret[TSDB_KEY_LEN]; // secret for the link char ckey[TSDB_KEY_LEN]; // ciphering key void (*cfp)(char type, void *pCont, int contLen, void *ahandle, int32_t code); - int (*afp)(char *meterId, char *spi, char *encrypt, char *secret, char *ckey); + int (*afp)(char *user, char *spi, char *encrypt, char *secret, char *ckey); void (*ufp)(void *ahandle, SRpcIpSet *pIpSet); void *idPool; // handle to ID pool void *tmrCtrl; // handle to timer void *hash; // handle returned by hash utility - void *shandle; // returned handle from lower layer during initialization + void *tcphandle;// returned handle from TCP initialization + void *udphandle;// returned handle from UDP initialization void *pCache; // connection cache pthread_mutex_t mutex; struct _RpcConn *connList; // connection list @@ -77,8 +79,9 @@ typedef struct { int32_t contLen; // content length int32_t code; // error code int16_t numOfTry; // number of try for different servers - int8_t oldIndex; // server IP index passed by app + int8_t oldInUse; // server IP inUse passed by app int8_t redirect; // flag to indicate redirect + int8_t connType; // connection type char msg[0]; // RpcHead starts from here } SRpcReqContext; @@ -86,7 +89,7 @@ typedef struct _RpcConn { int sid; // session ID uint32_t ownId; // own link ID uint32_t peerId; // peer link ID - char meterId[TSDB_UNI_LEN]; // user ID for the link + char user[TSDB_UNI_LEN]; // user ID for the link char spi; // security parameter index char encrypt; // encryption, 0:1 char secret[TSDB_KEY_LEN]; // secret for the link @@ -94,8 +97,9 @@ typedef struct _RpcConn { uint16_t localPort; // for UDP only uint32_t peerUid; // peer UID uint32_t peerIp; // peer IP + uint32_t destIp; // server destination IP to handle NAT uint16_t peerPort; // peer port - char peerIpstr[20]; // peer IP string + char peerIpstr[TSDB_IPv4ADDR_LEN]; // peer IP string uint16_t tranId; // outgoing transcation ID, for build message uint16_t outTranId; // outgoing transcation ID uint16_t inTranId; // transcation ID for incoming msg @@ -112,6 +116,8 @@ typedef struct _RpcConn { char *pReqMsg; // request message including header int reqMsgLen; // request message length SRpcInfo *pRpc; // the associated SRpcInfo + int8_t connType; // connection type + int64_t lockedBy; // lock for connection SRpcReqContext *pContext; // request context } SRpcConn; @@ -120,10 +126,18 @@ int tsRpcProgressTime = 10; // milliseocnds // not configurable int tsRpcMaxRetry; int tsRpcHeadSize; +int tsRpcOverhead; + +// server:0 client:1 tcp:2 udp:0 +#define RPC_CONN_UDPS 0 +#define RPC_CONN_UDPC 1 +#define RPC_CONN_TCPS 2 +#define RPC_CONN_TCPC 3 +#define RPC_CONN_TCP 2 void *(*taosInitConn[])(char *ip, uint16_t port, char *label, int threads, void *fp, void *shandle) = { - taosInitUdpServer, - taosInitUdpClient, + taosInitUdpConnection, + taosInitUdpConnection, taosInitTcpServer, taosInitTcpClient }; @@ -135,7 +149,7 @@ void (*taosCleanUpConn[])(void *thandle) = { taosCleanUpTcpClient }; -int (*taosSendData[])(uint32_t ip, uint16_t port, char *data, int len, void *chandle) = { +int (*taosSendData[])(uint32_t ip, uint16_t port, void *data, int len, void *chandle) = { taosSendUdpData, taosSendUdpData, taosSendTcpServerData, @@ -156,36 +170,39 @@ void (*taosCloseConn[])(void *chandle) = { taosCloseTcpClientConnection }; -static SRpcConn *rpcOpenConn(SRpcInfo *pRpc, char *peerIpStr, uint16_t peerPort); +static SRpcConn *rpcOpenConn(SRpcInfo *pRpc, char *peerIpStr, uint16_t peerPort, int8_t connType); static void rpcCloseConn(void *thandle); -static SRpcConn *rpcSetConnToServer(SRpcInfo *pRpc, SRpcIpSet ipSet); +static SRpcConn *rpcSetupConnToServer(SRpcReqContext *pContext); static SRpcConn *rpcAllocateClientConn(SRpcInfo *pRpc); -static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, char *meterId, char *hashstr); -static SRpcConn *rpcGetConnObj(SRpcInfo *pRpc, int sid, char *meterId, char *hashstr); +static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, SRecvInfo *pRecv); +static SRpcConn *rpcGetConnObj(SRpcInfo *pRpc, int sid, SRecvInfo *pRecv); static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext); static void rpcSendQuickRsp(SRpcConn *pConn, int32_t code); -static void rpcSendErrorMsgToPeer(SRpcInfo *pRpc, char *pMsg, int32_t code, uint32_t ip, uint16_t port, void *chandle); +static void rpcSendErrorMsgToPeer(SRecvInfo *pRecv, int32_t code); static void rpcSendMsgToPeer(SRpcConn *pConn, void *data, int dataLen); -static void *rpcProcessMsgFromPeer(void *msg, int msgLen, uint32_t ip, uint16_t port, void *shandle, void *thandle, void *chandle); +static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv); static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead); static void rpcProcessConnError(void *param, void *id); static void rpcProcessRetryTimer(void *, void *); static void rpcProcessIdleTimer(void *param, void *tmrId); static void rpcProcessProgressTimer(void *param, void *tmrId); -static void rpcFreeOutMsg(void *msg); +static void rpcFreeMsg(void *msg); static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen); static SRpcHead *rpcDecompressRpcMsg(SRpcHead *pHead); static int rpcAddAuthPart(SRpcConn *pConn, char *msg, int msgLen); static int rpcCheckAuthentication(SRpcConn *pConn, char *msg, int msgLen); +static void rpcLockConn(SRpcConn *pConn); +static void rpcUnlockConn(SRpcConn *pConn); void *rpcOpen(SRpcInit *pInit) { SRpcInfo *pRpc; tsRpcMaxRetry = tsRpcMaxTime * 1000 / tsRpcProgressTime; tsRpcHeadSize = RPC_MSG_OVERHEAD; + tsRpcOverhead = sizeof(SRpcReqContext); pRpc = (SRpcInfo *)calloc(1, sizeof(SRpcInfo)); if (pRpc == NULL) return NULL; @@ -198,7 +215,7 @@ void *rpcOpen(SRpcInit *pInit) { pRpc->localPort = pInit->localPort; pRpc->afp = pInit->afp; pRpc->sessions = pInit->sessions; - if (pInit->meterId) strcpy(pRpc->meterId, pInit->meterId); + if (pInit->user) strcpy(pRpc->user, pInit->user); if (pInit->secret) strcpy(pRpc->secret, pInit->secret); if (pInit->ckey) strcpy(pRpc->ckey, pInit->ckey); pRpc->spi = pInit->spi; @@ -206,9 +223,12 @@ void *rpcOpen(SRpcInit *pInit) { pRpc->cfp = pInit->cfp; pRpc->afp = pInit->afp; - pRpc->shandle = (*taosInitConn[pRpc->connType])(pRpc->localIp, pRpc->localPort, pRpc->label, + pRpc->tcphandle = (*taosInitConn[pRpc->connType|RPC_CONN_TCP])(pRpc->localIp, pRpc->localPort, pRpc->label, + pRpc->numOfThreads, rpcProcessMsgFromPeer, pRpc); + pRpc->udphandle = (*taosInitConn[pRpc->connType])(pRpc->localIp, pRpc->localPort, pRpc->label, pRpc->numOfThreads, rpcProcessMsgFromPeer, pRpc); - if (pRpc->shandle == NULL) { + + if (pRpc->tcphandle == NULL || pRpc->udphandle == NULL) { tError("%s failed to init network, %s:%d", pRpc->label, pRpc->localIp, pRpc->localPort); rpcClose(pRpc); return NULL; @@ -236,18 +256,20 @@ void *rpcOpen(SRpcInit *pInit) { return NULL; } - pRpc->hash = taosInitStrHash(pRpc->sessions, sizeof(pRpc), taosHashString); - if (pRpc->hash == NULL) { - tError("%s failed to init string hash", pRpc->label); - rpcClose(pRpc); - return NULL; - } - - pRpc->pCache = rpcOpenConnCache(pRpc->sessions, rpcCloseConn, pRpc->tmrCtrl, tsShellActivityTimer*1000); - if ( pRpc->pCache == NULL ) { - tError("%s failed to init connection cache", pRpc->label); - rpcClose(pRpc); - return NULL; + if (pRpc->connType == TAOS_CONN_SERVER) { + pRpc->hash = taosInitStrHash(pRpc->sessions, sizeof(pRpc), taosHashString); + if (pRpc->hash == NULL) { + tError("%s failed to init string hash", pRpc->label); + rpcClose(pRpc); + return NULL; + } + } else { + pRpc->pCache = rpcOpenConnCache(pRpc->sessions, rpcCloseConn, pRpc->tmrCtrl, tsShellActivityTimer*1000); + if ( pRpc->pCache == NULL ) { + tError("%s failed to init connection cache", pRpc->label); + rpcClose(pRpc); + return NULL; + } } pthread_mutex_init(&pRpc->mutex, NULL); @@ -260,10 +282,11 @@ void *rpcOpen(SRpcInit *pInit) { void rpcClose(void *param) { SRpcInfo *pRpc = (SRpcInfo *)param; - (*taosCleanUpConn[pRpc->connType])(pRpc->shandle); + (*taosCleanUpConn[pRpc->connType | RPC_CONN_TCP])(pRpc->tcphandle); + (*taosCleanUpConn[pRpc->connType])(pRpc->udphandle); for (int i = 0; i < pRpc->sessions; ++i) { - if (pRpc->connList[i].meterId[0]) { + if (pRpc->connList[i].user[0]) { rpcCloseConn((void *)(pRpc->connList + i)); } } @@ -278,22 +301,41 @@ void rpcClose(void *param) { tfree(pRpc); } -void *rpcMallocCont(int size) { - char *pMsg = NULL; +void *rpcMallocCont(int contLen) { + int size = contLen + RPC_MSG_OVERHEAD; - size += RPC_MSG_OVERHEAD; - pMsg = (char *)calloc(1, (size_t)size); - if (pMsg == NULL) { + char *start = (char *)calloc(1, (size_t)size); + if (start == NULL) { tError("failed to malloc msg, size:%d", size); return NULL; } - return pMsg + sizeof(SRpcReqContext) + sizeof(SRpcHead); + return start + sizeof(SRpcReqContext) + sizeof(SRpcHead); } void rpcFreeCont(void *cont) { - char *msg = ((char *)cont) - sizeof(SRpcHead); - free(msg); + if ( cont ) { + char *temp = ((char *)cont) - sizeof(SRpcHead) - sizeof(SRpcReqContext); + free(temp); + } +} + +void *rpcReallocCont(void *ptr, int contLen) { + if (ptr == NULL) return rpcMallocCont(contLen); + + char *start = ((char *)ptr) - sizeof(SRpcReqContext) - sizeof(SRpcHead); + if (contLen == 0 ) { + free(start); + } + + int size = contLen + RPC_MSG_OVERHEAD; + start = realloc(start, size); + if (start == NULL) { + tError("failed to realloc cont, size:%d", size); + return NULL; + } + + return start + sizeof(SRpcReqContext) + sizeof(SRpcHead); } void rpcSendRequest(void *shandle, SRpcIpSet *pIpSet, char type, void *pCont, int contLen, void *ahandle) { @@ -308,8 +350,18 @@ void rpcSendRequest(void *shandle, SRpcIpSet *pIpSet, char type, void *pCont, in pContext->contLen = contLen; pContext->pCont = pCont; pContext->msgType = type; - pContext->oldIndex = pIpSet->index; + pContext->oldInUse = pIpSet->inUse; + pContext->connType = RPC_CONN_UDPC; + if (contLen > tsRpcMaxUdpSize) pContext->connType = RPC_CONN_TCPC; + + // connection type is application specific. + // for TDengine, all the query, show commands shall have TCP connection + if (type == TSDB_MSG_TYPE_QUERY || type == TSDB_MSG_TYPE_RETRIEVE || + type == TSDB_MSG_TYPE_STABLE_META || type == TSDB_MSG_TYPE_MULTI_TABLE_META || + type == TSDB_MSG_TYPE_SHOW ) + pContext->connType = RPC_CONN_TCPC; + rpcSendReqToServer(pRpc, pContext); return; @@ -331,37 +383,37 @@ void rpcSendResponse(void *handle, int32_t code, void *pCont, int contLen) { contLen = rpcCompressRpcMsg(pCont, contLen); msgLen = rpcMsgLenFromCont(contLen); - pthread_mutex_lock(&pRpc->mutex); + rpcLockConn(pConn); - if ( pConn->inType == 0 || pConn->meterId[0] == 0 ) { + if ( pConn->inType == 0 || pConn->user[0] == 0 ) { tTrace("%s %p, connection is already released, rsp wont be sent", pRpc->label, pConn); - pthread_mutex_lock(&pRpc->mutex); + rpcUnlockConn(pConn); return; } // set msg header pHead->version = 1; pHead->msgType = pConn->inType+1; - pHead->spi = 0; - pHead->tcp = 0; - pHead->encrypt = 0; + pHead->spi = pConn->spi; + pHead->encrypt = pConn->encrypt; pHead->tranId = pConn->inTranId; pHead->sourceId = pConn->ownId; pHead->destId = pConn->peerId; pHead->uid = 0; + pHead->port = htons(pConn->localPort); pHead->code = htonl(code); - memcpy(pHead->meterId, pConn->meterId, tListLen(pHead->meterId)); + memcpy(pHead->user, pConn->user, tListLen(pHead->user)); // set pConn parameters pConn->inType = 0; // response message is released until new response is sent - rpcFreeOutMsg(pConn->pRspMsg); + rpcFreeMsg(pConn->pRspMsg); pConn->pRspMsg = msg; pConn->rspMsgLen = msgLen; if (pHead->content[0] == TSDB_CODE_ACTION_IN_PROGRESS) pConn->inTranId--; - pthread_mutex_unlock(&pRpc->mutex); + rpcUnlockConn(pConn); taosTmrStopA(&pConn->pTimer); rpcSendMsgToPeer(pConn, msg, msgLen); @@ -383,7 +435,25 @@ void rpcSendRedirectRsp(void *thandle, SRpcIpSet *pIpSet) { return; } -static SRpcConn *rpcOpenConn(SRpcInfo *pRpc, char *peerIpStr, uint16_t peerPort) { +void rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo) { + SRpcConn *pConn = (SRpcConn *)thandle; + + pInfo->clientIp = pConn->peerIp; + pInfo->clientPort = pConn->peerPort; + pInfo->serverIp = pConn->destIp; + + assert(pConn->user[0]); + strcpy(pInfo->user, pConn->user); +} + +static void rpcFreeMsg(void *msg) { + if ( msg ) { + char *temp = (char *)msg - sizeof(SRpcReqContext); + free(temp); + } +} + +static SRpcConn *rpcOpenConn(SRpcInfo *pRpc, char *peerIpStr, uint16_t peerPort, int8_t connType) { SRpcConn *pConn; pConn = rpcAllocateClientConn(pRpc); @@ -392,16 +462,18 @@ static SRpcConn *rpcOpenConn(SRpcInfo *pRpc, char *peerIpStr, uint16_t peerPort) strcpy(pConn->peerIpstr, peerIpStr); pConn->peerIp = inet_addr(peerIpStr); pConn->peerPort = peerPort; - strcpy(pConn->meterId, pRpc->meterId); + strcpy(pConn->user, pRpc->user); + pConn->connType = connType; - if (taosOpenConn[pRpc->connType]) { - pConn->chandle = (*taosOpenConn[pRpc->connType])(pRpc->shandle, pConn, pConn->peerIpstr, pConn->peerPort); + if (taosOpenConn[connType]) { + void *shandle = (connType & RPC_CONN_TCP)? pRpc->tcphandle:pRpc->udphandle; + pConn->chandle = (*taosOpenConn[connType])(shandle, pConn, pConn->peerIpstr, pConn->peerPort); if (pConn->chandle) { - tTrace("%s %p, rpc connection is set up, sid:%d id:%s ip:%s:%hu localPort:%d", pRpc->label, - pConn, pConn->sid, pRpc->meterId, pConn->peerIpstr, pConn->peerPort, pConn->localPort); + tTrace("%s %p, rpc connection is set up, sid:%d id:%s ip:%s:%hu connType:%d", pRpc->label, + pConn, pConn->sid, pRpc->user, pConn->peerIpstr, pConn->peerPort, pConn->connType); } else { - tError("%s %p, failed to set up nw connection to ip:%s:%hu", pRpc->label, pConn, - pConn->sid, pRpc->meterId, pConn->peerIpstr, pConn->peerPort); + tError("%s %p, failed to set up connection to ip:%s:%hu", pRpc->label, pConn, + pConn->peerIpstr, pConn->peerPort); terrno = TSDB_CODE_NETWORK_UNAVAIL; rpcCloseConn(pConn); pConn = NULL; @@ -416,20 +488,20 @@ static void rpcCloseConn(void *thandle) { SRpcConn *pConn = (SRpcConn *)thandle; SRpcInfo *pRpc = pConn->pRpc; - pthread_mutex_lock(&pRpc->mutex); + rpcLockConn(pConn); - if (pConn->meterId[0]) { - pConn->meterId[0] = 0; - if (taosCloseConn[pRpc->connType]) (*taosCloseConn[pRpc->connType])(pConn->chandle); + if (pConn->user[0]) { + pConn->user[0] = 0; + if (taosCloseConn[pConn->connType]) (*taosCloseConn[pConn->connType])(pConn->chandle); taosTmrStopA(&pConn->pTimer); taosTmrStopA(&pConn->pIdleTimer); - if ( pRpc->connType == TAOS_CONN_UDPS || TAOS_CONN_TCPS) { + if ( pRpc->connType == TAOS_CONN_SERVER) { char hashstr[40] = {0}; - sprintf(hashstr, "%x:%x:%x", pConn->peerIp, pConn->peerUid, pConn->peerId); + sprintf(hashstr, "%x:%x:%x:%d", pConn->peerIp, pConn->peerUid, pConn->peerId, pConn->connType); taosDeleteStrHash(pRpc->hash, hashstr); - rpcFreeOutMsg(pConn->pRspMsg); // it may have a response msg saved, but not request msg + rpcFreeMsg(pConn->pRspMsg); // it may have a response msg saved, but not request msg pConn->pRspMsg = NULL; pConn->inType = 0; pConn->inTranId = 0; @@ -445,7 +517,7 @@ static void rpcCloseConn(void *thandle) { tTrace("%s %p, rpc connection is closed", pRpc->label, pConn); } - pthread_mutex_unlock(&pRpc->mutex); + rpcUnlockConn(pConn); } static SRpcConn *rpcAllocateClientConn(SRpcInfo *pRpc) { @@ -471,9 +543,13 @@ static SRpcConn *rpcAllocateClientConn(SRpcInfo *pRpc) { return pConn; } -static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, char *meterId, char *hashstr) { +static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, SRecvInfo *pRecv) { SRpcConn *pConn = NULL; + char hashstr[40] = {0}; + SRpcHead *pHead = (SRpcHead *)pRecv->msg; + sprintf(hashstr, "%x:%x:%x:%d", pRecv->ip, pHead->uid, pHead->sourceId, pRecv->connType); + // check if it is already allocated SRpcConn **ppConn = (SRpcConn **)(taosGetStrHashData(pRpc->hash, hashstr)); if (ppConn) pConn = *ppConn; @@ -486,13 +562,13 @@ static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, char *meterId, char *hash } else { pConn = pRpc->connList + sid; memset(pConn, 0, sizeof(SRpcConn)); - memcpy(pConn->meterId, meterId, tListLen(pConn->meterId)); + memcpy(pConn->user, pHead->user, tListLen(pConn->user)); pConn->pRpc = pRpc; pConn->sid = sid; pConn->tranId = (uint16_t)(rand() & 0xFFFF); pConn->ownId = htonl(pConn->sid); - if (pRpc->afp && (*pRpc->afp)(meterId, &pConn->spi, &pConn->encrypt, pConn->secret, pConn->ckey)) { - tWarn("%s %p, meterId not there", pRpc->label, pConn); + if (pRpc->afp && (*pRpc->afp)(pConn->user, &pConn->spi, &pConn->encrypt, pConn->secret, pConn->ckey) < 0) { + tWarn("%s %p, user not there", pRpc->label, pConn); taosFreeId(pRpc->idPool, sid); // sid shall be released terrno = TSDB_CODE_INVALID_USER; pConn = NULL; @@ -500,25 +576,33 @@ static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, char *meterId, char *hash } if (pConn) { + if (pRecv->connType == RPC_CONN_UDPS && pRpc->numOfThreads > 1) { + // UDP server, assign to new connection + pRpc->index = (pRpc->index+1) % pRpc->numOfThreads; + pConn->localPort = (pRpc->localPort + pRpc->index); + } + taosAddStrHash(pRpc->hash, hashstr, (char *)&pConn); - tTrace("%s %p, rpc connection is allocated, sid:%d id:%s", pRpc->label, pConn, sid, pConn->meterId); + tTrace("%s %p, rpc connection is allocated, sid:%d id:%s port:%u", + pRpc->label, pConn, sid, pConn->user, pConn->localPort); } return pConn; } -static SRpcConn *rpcGetConnObj(SRpcInfo *pRpc, int sid, char *meterId, char *hashstr) { +static SRpcConn *rpcGetConnObj(SRpcInfo *pRpc, int sid, SRecvInfo *pRecv) { SRpcConn *pConn = NULL; + SRpcHead *pHead = (SRpcHead *)pRecv->msg; if (sid) { pConn = pRpc->connList + sid; } else { - pConn = rpcAllocateServerConn(pRpc, meterId, hashstr); + pConn = rpcAllocateServerConn(pRpc, pRecv); } if (pConn) { - if (memcmp(pConn->meterId, meterId, tListLen(pConn->meterId)) != 0) { - tTrace("%s %p, meterId:%s is not matched, received:%s", pRpc->label, pConn, pConn->meterId, meterId); + if (memcmp(pConn->user, pHead->user, tListLen(pConn->user)) != 0) { + tTrace("%s %p, user:%s is not matched, received:%s", pRpc->label, pConn, pConn->user, pHead->user); terrno = TSDB_CODE_MISMATCHED_METER_ID; pConn = NULL; } @@ -527,15 +611,20 @@ static SRpcConn *rpcGetConnObj(SRpcInfo *pRpc, int sid, char *meterId, char *has return pConn; } -SRpcConn *rpcSetConnToServer(SRpcInfo *pRpc, SRpcIpSet ipSet) { - SRpcConn *pConn; +static SRpcConn *rpcSetupConnToServer(SRpcReqContext *pContext) { + SRpcConn *pConn; + SRpcInfo *pRpc = pContext->pRpc; + SRpcIpSet *pIpSet = &pContext->ipSet; - pConn = rpcGetConnFromCache(pRpc->pCache, ipSet.ip[ipSet.index], ipSet.port, pRpc->meterId); + pConn = rpcGetConnFromCache(pRpc->pCache, pIpSet->ip[pIpSet->inUse], pIpSet->port, pContext->connType); if ( pConn == NULL ) { char ipstr[20] = {0}; - tinet_ntoa(ipstr, ipSet.ip[ipSet.index]); - pConn = rpcOpenConn(pRpc, ipstr, ipSet.port); - } + tinet_ntoa(ipstr, pIpSet->ip[pIpSet->inUse]); + pConn = rpcOpenConn(pRpc, ipstr, pIpSet->port, pContext->connType); + if (pConn) pConn->destIp = pIpSet->ip[pIpSet->inUse]; + } else { + tTrace("%s %p, connection is retrieved from cache", pRpc->label, pConn); + } return pConn; } @@ -604,7 +693,7 @@ static int rpcProcessRspHead(SRpcConn *pConn, SRpcHead *pHead) { taosTmrStopA(&pConn->pTimer); pConn->retry = 0; - if (*pHead->content == TSDB_CODE_ACTION_IN_PROGRESS || pHead->tcp) { + if (*pHead->content == TSDB_CODE_ACTION_IN_PROGRESS) { if (pConn->tretry <= tsRpcMaxRetry) { pConn->tretry++; tTrace("%s %p, peer is still processing the transaction", pRpc->label, pConn); @@ -624,69 +713,72 @@ static int rpcProcessRspHead(SRpcConn *pConn, SRpcHead *pHead) { return TSDB_CODE_SUCCESS; } -static int32_t rpcProcessHead(SRpcInfo *pRpc, SRpcConn **ppConn, void *data, int dataLen, uint32_t ip) { - int32_t sid, code = 0; - SRpcConn * pConn = NULL; - char hashstr[40] = {0}; +static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv) { + int32_t sid; + SRpcConn *pConn = NULL; - *ppConn = NULL; - SRpcHead *pHead = (SRpcHead *)data; + SRpcHead *pHead = (SRpcHead *)pRecv->msg; sid = htonl(pHead->destId); - pHead->code = htonl(pHead->code); - pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen); if (pHead->msgType >= TSDB_MSG_TYPE_MAX || pHead->msgType <= 0) { tTrace("%s sid:%d, invalid message type:%d", pRpc->label, sid, pHead->msgType); - return TSDB_CODE_INVALID_MSG_TYPE; - } - - if (dataLen != pHead->msgLen) { - tTrace("%s sid:%d, %s has invalid length, dataLen:%d, msgLen:%d", pRpc->label, sid, - taosMsg[pHead->msgType], dataLen, pHead->msgLen); - return TSDB_CODE_INVALID_MSG_LEN; + terrno = TSDB_CODE_INVALID_MSG_TYPE; return NULL; } if (sid < 0 || sid >= pRpc->sessions) { tTrace("%s sid:%d, sid is out of range, max sid:%d, %s discarded", pRpc->label, sid, pRpc->sessions, taosMsg[pHead->msgType]); - return TSDB_CODE_INVALID_SESSION_ID; + terrno = TSDB_CODE_INVALID_SESSION_ID; return NULL; } - if (sid == 0) sprintf(hashstr, "%x:%x:%x", ip, pHead->uid, pHead->sourceId); - pConn = rpcGetConnObj(pRpc, sid, pHead->meterId, hashstr); - if (pConn == NULL ) return terrno; + pConn = rpcGetConnObj(pRpc, sid, pRecv); + if (pConn == NULL) return NULL; - *ppConn = pConn; + rpcLockConn(pConn); sid = pConn->sid; + pConn->chandle = pRecv->chandle; + if (pConn->peerIp != pRecv->ip) { + pConn->peerIp = pRecv->ip; + char ipstr[20] = {0}; + tinet_ntoa(ipstr, pRecv->ip); + strcpy(pConn->peerIpstr, ipstr); + } + + if (pRecv->port) pConn->peerPort = pRecv->port; + if (pHead->port) pConn->peerPort = htons(pHead->port); if (pHead->uid) pConn->peerUid = pHead->uid; - if (pHead->tcp) { - tTrace("%s %p, content will be transfered via TCP", pRpc->label, pConn); - if (pConn->outType) taosTmrReset(rpcProcessRetryTimer, tsRpcTimer, pConn, pRpc->tmrCtrl, &pConn->pTimer); - return TSDB_CODE_ALREADY_PROCESSED; - } + terrno = rpcCheckAuthentication(pConn, (char *)pHead, pRecv->msgLen); - code = rpcCheckAuthentication(pConn, (char *)pHead, dataLen); - if ( code != 0 ) return code; + // code can be transformed only after authentication + pHead->code = htonl(pHead->code); - if (pHead->msgType != TSDB_MSG_TYPE_REG && pHead->encrypt) { - // decrypt here - } + if (terrno == 0) { + if (pHead->msgType != TSDB_MSG_TYPE_REG && pHead->encrypt) { + // decrypt here + } - if ( rpcIsReq(pHead->msgType) ) { - code = rpcProcessReqHead(pConn, pHead); - } else { - code = rpcProcessRspHead(pConn, pHead); + if ( rpcIsReq(pHead->msgType) ) { + terrno = rpcProcessReqHead(pConn, pHead); + pConn->connType = pRecv->connType; + } else { + terrno = rpcProcessRspHead(pConn, pHead); + } } - return code; + rpcUnlockConn(pConn); + + return pConn; } static void rpcProcessBrokenLink(SRpcConn *pConn) { SRpcInfo *pRpc = pConn->pRpc; + tTrace("%s %p, link is broken", pRpc->label, pConn); + pConn->chandle = NULL; + if (pConn->outType) { SRpcReqContext *pContext = pConn->pContext; pContext->code = TSDB_CODE_NETWORK_UNAVAIL; @@ -696,73 +788,60 @@ static void rpcProcessBrokenLink(SRpcConn *pConn) { rpcCloseConn(pConn); } -static void *rpcProcessMsgFromPeer(void *msg, int msgLen, uint32_t ip, uint16_t port, void *shandle, void *thandle, void *chandle) { - SRpcHead *pHead = (SRpcHead *)msg; - SRpcInfo *pRpc = (SRpcInfo *)shandle; - SRpcConn *pConn = (SRpcConn *)thandle; - int32_t code = 0; +static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) { + SRpcHead *pHead = (SRpcHead *)pRecv->msg; + SRpcInfo *pRpc = (SRpcInfo *)pRecv->shandle; + SRpcConn *pConn = (SRpcConn *)pRecv->thandle; - tDump(msg, msgLen); + tDump(pRecv->msg, pRecv->msgLen); + + // underlying UDP layer does not know it is server or client + pRecv->connType = pRecv->connType | pRpc->connType; - if (ip==0 && pConn) { + if (pRecv->ip==0 && pConn) { rpcProcessBrokenLink(pConn); - tfree(msg); + tfree(pRecv->msg); return NULL; } - pthread_mutex_lock(&pRpc->mutex); - - code = rpcProcessHead(pRpc, &pConn, msg, msgLen, ip); - - if (pConn) { - // update connection info - pConn->chandle = chandle; - if (pConn->peerIp != ip) { - pConn->peerIp = ip; - char ipstr[20] = {0}; - tinet_ntoa(ipstr, ip); - strcpy(pConn->peerIpstr, ipstr); - } - - if (port) pConn->peerPort = port; - if (pHead->port) // port maybe changed by the peer - pConn->peerPort = pHead->port; - } - - pthread_mutex_unlock(&pRpc->mutex); + terrno = 0; + pConn = rpcProcessMsgHead(pRpc, pRecv); if (pHead->msgType < TSDB_MSG_TYPE_HEARTBEAT || (rpcDebugFlag & 16)) { - tTrace("%s %p, %s received from 0x%x:%hu, parse code:%x len:%d source:0x%08x dest:0x%08x tranId:%d", - pRpc->label, pConn, taosMsg[pHead->msgType], ip, port, code, - msgLen, pHead->sourceId, pHead->destId, pHead->tranId); + tTrace("%s %p, %s received from 0x%x:%hu, parse code:%x len:%d sig:0x%08x:0x%08x:%d", + pRpc->label, pConn, taosMsg[pHead->msgType], pRecv->ip, pRecv->port, terrno, + pRecv->msgLen, pHead->sourceId, pHead->destId, pHead->tranId, pHead->port); } if (pConn && pRpc->idleTime) { taosTmrReset(rpcProcessIdleTimer, pRpc->idleTime, pConn, pRpc->tmrCtrl, &pConn->pIdleTimer); } - if (code != TSDB_CODE_ALREADY_PROCESSED) { - if (code != 0) { // parsing error + if (terrno != TSDB_CODE_ALREADY_PROCESSED) { + if (terrno != 0) { // parsing error if ( rpcIsReq(pHead->msgType) ) { - rpcSendErrorMsgToPeer(pRpc, msg, code, ip, port, chandle); - tTrace("%s %p, %s is sent with error code:%x", pRpc->label, pConn, taosMsg[pHead->msgType+1], code); + rpcSendErrorMsgToPeer(pRecv, terrno); + tTrace("%s %p, %s is sent with error code:%x", pRpc->label, pConn, taosMsg[pHead->msgType+1], terrno); } } else { // parsing OK rpcProcessIncomingMsg(pConn, pHead); } } - if ( code != 0 ) free (msg); + if (terrno) rpcFreeMsg(pRecv->msg); return pConn; } static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead) { + SRpcInfo *pRpc = pConn->pRpc; + pHead = rpcDecompressRpcMsg(pHead); - int contLen = rpcContLenFromMsg(pHead->msgLen); - uint8_t *pCont = pHead->content; + int contLen = rpcContLenFromMsg(pHead->msgLen); + uint8_t *pCont = pHead->content; if ( rpcIsReq(pHead->msgType) ) { + pConn->destIp = pHead->destIp; taosTmrReset(rpcProcessProgressTimer, tsRpcTimer/2, pConn, pRpc->tmrCtrl, &pConn->pTimer); (*(pRpc->cfp))(pHead->msgType, pCont, contLen, pConn, 0); } else { @@ -770,7 +849,8 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead) { int32_t code = pHead->code; SRpcReqContext *pContext = pConn->pContext; pConn->pContext = NULL; - rpcAddConnIntoCache(pRpc->pCache, pConn, pConn->peerIp, pConn->peerPort, pConn->meterId); + // for UDP, port may be changed by server, the port in ipSet shall be used for cache + rpcAddConnIntoCache(pRpc->pCache, pConn, pConn->peerIp, pContext->ipSet.port, pConn->connType); if (code == TSDB_CODE_REDIRECT) { pContext->redirect = 1; @@ -779,10 +859,10 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead) { tTrace("%s %p, redirect is received, numOfIps:%d", pRpc->label, pConn, pContext->ipSet.numOfIps); rpcSendReqToServer(pRpc, pContext); } else { - if ( pRpc->ufp && (pContext->ipSet.index != pContext->oldIndex || pContext->redirect) ) + if ( pRpc->ufp && (pContext->ipSet.inUse != pContext->oldInUse || pContext->redirect) ) (*pRpc->ufp)(pContext->ahandle, &pContext->ipSet); // notify the update of ipSet (*pRpc->cfp)(pHead->msgType, pCont, contLen, pContext->ahandle, code); - rpcFreeOutMsg(rpcHeadFromCont(pContext->pCont)); // free the request msg + rpcFreeCont(pContext->pCont); // free the request msg } } } @@ -797,37 +877,35 @@ static void rpcSendQuickRsp(SRpcConn *pConn, int32_t code) { pHead->version = 1; pHead->msgType = pConn->inType+1; pHead->spi = 0; - pHead->tcp = 0; pHead->encrypt = 0; pHead->tranId = pConn->inTranId; pHead->sourceId = pConn->ownId; pHead->destId = pConn->peerId; pHead->uid = 0; - memcpy(pHead->meterId, pConn->meterId, tListLen(pHead->meterId)); + memcpy(pHead->user, pConn->user, tListLen(pHead->user)); pHead->code = htonl(code); rpcSendMsgToPeer(pConn, msg, 0); } -static void rpcSendErrorMsgToPeer(SRpcInfo *pRpc, char *pMsg, int32_t code, uint32_t ip, uint16_t port, void *chandle) { +static void rpcSendErrorMsgToPeer(SRecvInfo *pRecv, int32_t code) { SRpcHead *pRecvHead, *pReplyHead; char msg[sizeof(SRpcHead) + sizeof(SRpcDigest) + sizeof(uint32_t) ]; - uint32_t timeStamp; - int msgLen; + uint32_t timeStamp; + int msgLen; - pRecvHead = (SRpcHead *)pMsg; + pRecvHead = (SRpcHead *)pRecv->msg; pReplyHead = (SRpcHead *)msg; memset(msg, 0, sizeof(SRpcHead)); pReplyHead->version = pRecvHead->version; pReplyHead->msgType = (char)(pRecvHead->msgType + 1); - pReplyHead->tcp = 0; pReplyHead->spi = 0; - pReplyHead->encrypt = 0; + pReplyHead->encrypt = pRecvHead->encrypt; pReplyHead->tranId = pRecvHead->tranId; - pReplyHead->sourceId = 0; + pReplyHead->sourceId = pRecvHead->destId; pReplyHead->destId = pRecvHead->sourceId; - memcpy(pReplyHead->meterId, pRecvHead->meterId, tListLen(pReplyHead->meterId)); + memcpy(pReplyHead->user, pRecvHead->user, tListLen(pReplyHead->user)); pReplyHead->code = htonl(code); msgLen = sizeof(SRpcHead); @@ -835,13 +913,13 @@ static void rpcSendErrorMsgToPeer(SRpcInfo *pRpc, char *pMsg, int32_t code, uint if (code == TSDB_CODE_INVALID_TIME_STAMP) { // include a time stamp if client's time is not synchronized well uint8_t *pContent = pReplyHead->content; - timeStamp = taosGetTimestampSec(); + timeStamp = htonl(taosGetTimestampSec()); memcpy(pContent, &timeStamp, sizeof(timeStamp)); msgLen += sizeof(timeStamp); } pReplyHead->msgLen = (int32_t)htonl((uint32_t)msgLen); - (*taosSendData[pRpc->connType])(ip, port, msg, msgLen, chandle); + (*taosSendData[pRecv->connType])(pRecv->ip, pRecv->port, msg, msgLen, pRecv->chandle); return; } @@ -853,28 +931,28 @@ static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { char msgType = pContext->msgType; pContext->numOfTry++; - SRpcConn *pConn = rpcSetConnToServer(pRpc, pContext->ipSet); + SRpcConn *pConn = rpcSetupConnToServer(pContext); if (pConn == NULL) { pContext->code = terrno; taosTmrStart(rpcProcessConnError, 0, pContext, pRpc->tmrCtrl); return; } - pthread_mutex_lock(&pRpc->mutex); + rpcLockConn(pConn); // set the message header pHead->version = 1; pHead->msgType = msgType; - pHead->tcp = 0; pHead->encrypt = 0; pConn->tranId++; if ( pConn->tranId == 0 ) pConn->tranId++; pHead->tranId = pConn->tranId; pHead->sourceId = pConn->ownId; pHead->destId = pConn->peerId; + pHead->destIp = pConn->destIp; pHead->port = 0; pHead->uid = (uint32_t)((int64_t)pConn + (int64_t)getpid()); - memcpy(pHead->meterId, pConn->meterId, tListLen(pHead->meterId)); + memcpy(pHead->user, pConn->user, tListLen(pHead->user)); // set the connection parameters pConn->outType = msgType; @@ -883,7 +961,7 @@ static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { pConn->reqMsgLen = msgLen; pConn->pContext = pContext; - pthread_mutex_unlock(&pRpc->mutex); + rpcUnlockConn(pConn); rpcSendMsgToPeer(pConn, msg, msgLen); taosTmrReset(rpcProcessRetryTimer, tsRpcTimer, pConn, pRpc->tmrCtrl, &pConn->pTimer); @@ -898,17 +976,17 @@ static void rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { if ( rpcIsReq(pHead->msgType)) { if (pHead->msgType < TSDB_MSG_TYPE_HEARTBEAT || (rpcDebugFlag & 16)) - tTrace("%s %p, %s is sent to %s:%hu, len:%d source:0x%08x dest:0x%08x tranId:%d", + tTrace("%s %p, %s is sent to %s:%hu, len:%d sig:0x%08x:0x%08x:%d", pRpc->label, pConn, taosMsg[pHead->msgType], pConn->peerIpstr, pConn->peerPort, msgLen, pHead->sourceId, pHead->destId, pHead->tranId); } else { if (pHead->msgType < TSDB_MSG_TYPE_HEARTBEAT || (rpcDebugFlag & 16)) - tTrace( "%s %p, %s is sent to %s:%hu, code:%u len:%d source:0x%08x dest:0x%08x tranId:%d", + tTrace( "%s %p, %s is sent to %s:%hu, code:%u len:%d sig:0x%08x:0x%08x:%d", pRpc->label, pConn, taosMsg[pHead->msgType], pConn->peerIpstr, pConn->peerPort, (uint8_t)pHead->content[0], msgLen, pHead->sourceId, pHead->destId, pHead->tranId); } - writtenLen = (*taosSendData[pRpc->connType])(pConn->peerIp, pConn->peerPort, (char *)pHead, msgLen, pConn->chandle); + writtenLen = (*taosSendData[pConn->connType])(pConn->peerIp, pConn->peerPort, pHead, msgLen, pConn->chandle); if (writtenLen != msgLen) { tError("%s %p, failed to send, dataLen:%d writtenLen:%d, reason:%s", pRpc->label, pConn, @@ -921,14 +999,16 @@ static void rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { static void rpcProcessConnError(void *param, void *id) { SRpcReqContext *pContext = (SRpcReqContext *)param; SRpcInfo *pRpc = pContext->pRpc; + + tTrace("%s connection error happens", pRpc->label); if ( pContext->numOfTry >= pContext->ipSet.numOfIps ) { - rpcFreeOutMsg(rpcHeadFromCont(pContext->pCont)); // free the request msg (*(pRpc->cfp))(pContext->msgType+1, NULL, 0, pContext->ahandle, pContext->code); + rpcFreeCont(pContext->pCont); // free the request msg } else { // move to next IP - pContext->ipSet.index++; - pContext->ipSet.index = pContext->ipSet.index % pContext->ipSet.numOfIps; + pContext->ipSet.inUse++; + pContext->ipSet.inUse = pContext->ipSet.inUse % pContext->ipSet.numOfIps; rpcSendReqToServer(pRpc, pContext); } } @@ -938,18 +1018,18 @@ static void rpcProcessRetryTimer(void *param, void *tmrId) { SRpcInfo *pRpc = pConn->pRpc; int reportDisc = 0; - pthread_mutex_lock(&pRpc->mutex); + rpcLockConn(pConn); - if (pConn->outType && pConn->meterId[0]) { + if (pConn->outType && pConn->user[0]) { tTrace("%s %p, expected %s is not received", pRpc->label, pConn, taosMsg[(int)pConn->outType + 1]); pConn->pTimer = NULL; pConn->retry++; if (pConn->retry < 4) { - tTrace("%s %p, re-send msg:%s to %s:%hu", pRpc->label, pConn, - taosMsg[pConn->outType], pConn->peerIpstr, pConn->peerPort); + tTrace("%s %p, re-send msg:%s to %s:%hu retry:%d", pRpc->label, pConn, + taosMsg[pConn->outType], pConn->peerIpstr, pConn->peerPort, pConn->retry); rpcSendMsgToPeer(pConn, pConn->pReqMsg, pConn->reqMsgLen); - taosTmrReset(rpcProcessRetryTimer, tsRpcTimer<retry, pConn, pRpc->tmrCtrl, &pConn->pTimer); + taosTmrReset(rpcProcessRetryTimer, tsRpcTimer, pConn, pRpc->tmrCtrl, &pConn->pTimer); } else { // close the connection tTrace("%s %p, failed to send msg:%s to %s:%hu", pRpc->label, pConn, @@ -960,10 +1040,10 @@ static void rpcProcessRetryTimer(void *param, void *tmrId) { tTrace("%s %p, retry timer not processed", pRpc->label, pConn); } - pthread_mutex_unlock(&pRpc->mutex); + rpcUnlockConn(pConn); - pConn->pContext->code = TSDB_CODE_NETWORK_UNAVAIL; - if (reportDisc) { + if (reportDisc && pConn->pContext) { + pConn->pContext->code = TSDB_CODE_NETWORK_UNAVAIL; rpcProcessConnError(pConn->pContext, NULL); rpcCloseConn(pConn); } @@ -973,7 +1053,7 @@ static void rpcProcessIdleTimer(void *param, void *tmrId) { SRpcConn *pConn = (SRpcConn *)param; SRpcInfo *pRpc = pConn->pRpc; - if (pConn->meterId[0]) { + if (pConn->user[0]) { tTrace("%s %p, close the connection since no activity", pRpc->label, pConn); rpcCloseConn(pConn); } else { @@ -985,9 +1065,9 @@ static void rpcProcessProgressTimer(void *param, void *tmrId) { SRpcConn *pConn = (SRpcConn *)param; SRpcInfo *pRpc = pConn->pRpc; - pthread_mutex_lock(&pRpc->mutex); + rpcLockConn(pConn); - if (pConn->inType && pConn->meterId[0]) { + if (pConn->inType && pConn->user[0]) { tTrace("%s %p, progress timer expired, send progress", pRpc->label, pConn); rpcSendQuickRsp(pConn, TSDB_CODE_ACTION_IN_PROGRESS); taosTmrReset(rpcProcessProgressTimer, tsRpcTimer<retry, pConn, pRpc->tmrCtrl, &pConn->pTimer); @@ -995,13 +1075,7 @@ static void rpcProcessProgressTimer(void *param, void *tmrId) { tTrace("%s %p, progress timer:%p not processed", pRpc->label, pConn, tmrId); } - pthread_mutex_unlock(&pRpc->mutex); -} - -static void rpcFreeOutMsg(void *msg) { - if ( msg == NULL ) return; - char *req = ((char *)msg) - sizeof(SRpcReqContext); - free(req); + rpcUnlockConn(pConn); } static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen) { @@ -1015,7 +1089,7 @@ static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen) { char *buf = malloc (contLen + overhead + 8); // 8 extra bytes if (buf == NULL) { - tError("failed to allocate memory for rpc msg compression, contLen:%d, reason:%s", contLen, strerror(errno)); + tError("failed to allocate memory for rpc msg compression, contLen:%d", contLen); return contLen; } @@ -1033,7 +1107,6 @@ static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen) { pHead->comp = 1; tTrace("compress rpc msg, before:%d, after:%d", contLen, compLen); - finalLen = compLen + overhead; } else { finalLen = contLen; @@ -1055,34 +1128,35 @@ static SRpcHead *rpcDecompressRpcMsg(SRpcHead *pHead) { int contLen = htonl(pComp->contLen); // prepare the temporary buffer to decompress message - char *buf = rpcMallocCont(contLen); + char *temp = (char *)malloc(contLen + RPC_MSG_OVERHEAD); + pNewHead = (SRpcHead *)(temp + sizeof(SRpcReqContext)); // reserve SRpcReqContext - if (buf) { - pNewHead = rpcHeadFromCont(buf); + if (pNewHead) { int compLen = rpcContLenFromMsg(pHead->msgLen) - overhead; - int32_t originalLen = LZ4_decompress_safe((const char*)(pCont + overhead), buf, compLen, contLen); - assert(originalLen == contLen); + int origLen = LZ4_decompress_safe((char*)(pCont + overhead), (char *)pNewHead->content, compLen, contLen); + assert(origLen == contLen); memcpy(pNewHead, pHead, sizeof(SRpcHead)); - pNewHead->msgLen = rpcMsgLenFromCont(originalLen); - free(pHead); // free the compressed message buffer + pNewHead->msgLen = rpcMsgLenFromCont(origLen); + rpcFreeMsg(pHead); // free the compressed message buffer pHead = pNewHead; + tTrace("decompress rpc msg, compLen:%d, after:%d", compLen, contLen); } else { - tError("failed to allocate memory to decompress msg, contLen:%d, reason:%s", contLen, strerror(errno)); + tError("failed to allocate memory to decompress msg, contLen:%d", contLen); } } return pHead; } -static int rpcAuthenticateMsg(uint8_t *pMsg, int msgLen, uint8_t *pAuth, uint8_t *pKey) { +static int rpcAuthenticateMsg(void *pMsg, int msgLen, void *pAuth, void *pKey) { MD5_CTX context; int ret = -1; MD5Init(&context); - MD5Update(&context, pKey, TSDB_KEY_LEN); - MD5Update(&context, pMsg, msgLen); - MD5Update(&context, pKey, TSDB_KEY_LEN); + MD5Update(&context, (uint8_t *)pKey, TSDB_KEY_LEN); + MD5Update(&context, (uint8_t *)pMsg, msgLen); + MD5Update(&context, (uint8_t *)pKey, TSDB_KEY_LEN); MD5Final(&context); if (memcmp(context.digest, pAuth, sizeof(context.digest)) == 0) ret = 0; @@ -1090,18 +1164,16 @@ static int rpcAuthenticateMsg(uint8_t *pMsg, int msgLen, uint8_t *pAuth, uint8_t return ret; } -static int rpcBuildAuthHead(uint8_t *pMsg, int msgLen, uint8_t *pAuth, uint8_t *pKey) { +static void rpcBuildAuthHead(void *pMsg, int msgLen, void *pAuth, void *pKey) { MD5_CTX context; MD5Init(&context); - MD5Update(&context, pKey, TSDB_KEY_LEN); + MD5Update(&context, (uint8_t *)pKey, TSDB_KEY_LEN); MD5Update(&context, (uint8_t *)pMsg, msgLen); - MD5Update(&context, pKey, TSDB_KEY_LEN); + MD5Update(&context, (uint8_t *)pKey, TSDB_KEY_LEN); MD5Final(&context); memcpy(pAuth, context.digest, sizeof(context.digest)); - - return 0; } static int rpcAddAuthPart(SRpcConn *pConn, char *msg, int msgLen) { @@ -1114,7 +1186,7 @@ static int rpcAddAuthPart(SRpcConn *pConn, char *msg, int msgLen) { pDigest->timeStamp = htonl(taosGetTimestampSec()); msgLen += sizeof(SRpcDigest); pHead->msgLen = (int32_t)htonl((uint32_t)msgLen); - rpcBuildAuthHead((uint8_t *)pHead, msgLen - TSDB_AUTH_LEN, pDigest->auth, (uint8_t *)pConn->secret); + rpcBuildAuthHead(pHead, msgLen - TSDB_AUTH_LEN, pDigest->auth, pConn->secret); } else { pHead->msgLen = (int32_t)htonl((uint32_t)msgLen); } @@ -1127,7 +1199,21 @@ static int rpcCheckAuthentication(SRpcConn *pConn, char *msg, int msgLen) { SRpcInfo *pRpc = pConn->pRpc; int32_t code = 0; - if (pConn->spi == 0 ) return 0; + if (pConn->spi == 0) { + pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen); + return 0; + } + + if ( !rpcIsReq(pHead->msgType) ) { + // for response, if code is auth failure, it shall bypass the auth process + code = htonl(pHead->code); + if (code==TSDB_CODE_INVALID_TIME_STAMP || code==TSDB_CODE_AUTH_FAILURE || code==TSDB_CODE_INVALID_USER) { + pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen); + return 0; + } + } + + code = 0; if (pHead->spi == pConn->spi) { // authentication @@ -1137,26 +1223,38 @@ static int rpcCheckAuthentication(SRpcConn *pConn, char *msg, int msgLen) { delta = (int32_t)htonl(pDigest->timeStamp); delta -= (int32_t)taosGetTimestampSec(); if (abs(delta) > 900) { - tWarn("%s %p, time diff:%d is too big, msg discarded, timestamp:%d", pRpc->label, pConn, - delta, htonl(pDigest->timeStamp)); + tWarn("%s %p, time diff:%d is too big, msg discarded", pRpc->label, pConn, delta); code = TSDB_CODE_INVALID_TIME_STAMP; } else { - if (rpcAuthenticateMsg((uint8_t *)pHead, msgLen - TSDB_AUTH_LEN, pDigest->auth, (uint8_t *)pConn->secret) < 0) { + if (rpcAuthenticateMsg(pHead, msgLen-TSDB_AUTH_LEN, pDigest->auth, pConn->secret) < 0) { tError("%s %p, authentication failed, msg discarded", pRpc->label, pConn); code = TSDB_CODE_AUTH_FAILURE; } else { - pHead->msgLen -= sizeof(SRpcDigest); + pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen) - sizeof(SRpcDigest); } } } else { - // if it is request or response with code 0, msg shall be discarded - if (rpcIsReq(pHead->msgType) || (pHead->content[0] == 0)) { - tTrace("%s %p, auth spi not matched, msg discarded", pRpc->label, pConn); - code = TSDB_CODE_AUTH_FAILURE; - } + tTrace("%s %p, auth spi not matched, msg discarded", pRpc->label, pConn); + code = TSDB_CODE_AUTH_FAILURE; } return code; } +static void rpcLockConn(SRpcConn *pConn) { + int64_t tid = taosGetPthreadId(); + int i = 0; + while (atomic_val_compare_exchange_64(&(pConn->lockedBy), 0, tid) != 0) { + if (++i % 1000 == 0) { + sched_yield(); + } + } +} + +static void rpcUnlockConn(SRpcConn *pConn) { + int64_t tid = taosGetPthreadId(); + if (atomic_val_compare_exchange_64(&(pConn->lockedBy), tid, 0) != tid) { + assert(false); + } +} diff --git a/src/rpc/src/rpcServer.c b/src/rpc/src/rpcServer.c index 49992e5931a211f4ae075dcc2645ab9fc8f20883..1aadabc5f73f3a124261ca5af1c794dbd297d9d3 100644 --- a/src/rpc/src/rpcServer.c +++ b/src/rpc/src/rpcServer.c @@ -46,10 +46,8 @@ typedef struct _thread_obj { int numOfFds; int threadId; char label[12]; - // char buffer[128000]; // buffer to receive data - void *shandle; // handle passed by upper layer during server initialization - void *(*processData)(char *data, int dataLen, unsigned int ip, uint16_t port, void *shandle, void *thandle, - void *chandle); + void *shandle; // handle passed by upper layer during server initialization + void *(*processData)(SRecvInfo *pPacket); } SThreadObj; typedef struct { @@ -62,59 +60,81 @@ typedef struct { pthread_t thread; } SServerObj; -static void taosCleanUpFdObj(SFdObj *pFdObj) { - SThreadObj *pThreadObj; +static void taosCleanUpFdObj(SFdObj *pFdObj); +static void taosProcessTcpData(void *param); +static void taosAcceptTcpConnection(void *arg); - if (pFdObj == NULL) return; - if (pFdObj->signature != pFdObj) return; +void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle) { + int i; + SServerObj *pServerObj; + pthread_attr_t thattr; + SThreadObj *pThreadObj; - pThreadObj = pFdObj->pThreadObj; - if (pThreadObj == NULL) { - tError("FdObj double clean up!!!"); - return; + pServerObj = (SServerObj *)malloc(sizeof(SServerObj)); + strcpy(pServerObj->ip, ip); + pServerObj->port = port; + strcpy(pServerObj->label, label); + pServerObj->numOfThreads = numOfThreads; + + pServerObj->pThreadObj = (SThreadObj *)malloc(sizeof(SThreadObj) * (size_t)numOfThreads); + if (pServerObj->pThreadObj == NULL) { + tError("TCP:%s no enough memory", label); + return NULL; } + memset(pServerObj->pThreadObj, 0, sizeof(SThreadObj) * (size_t)numOfThreads); - epoll_ctl(pThreadObj->pollFd, EPOLL_CTL_DEL, pFdObj->fd, NULL); - close(pFdObj->fd); + pThreadObj = pServerObj->pThreadObj; + for (i = 0; i < numOfThreads; ++i) { + pThreadObj->processData = fp; + strcpy(pThreadObj->label, label); + pThreadObj->shandle = shandle; - pthread_mutex_lock(&pThreadObj->threadMutex); + if (pthread_mutex_init(&(pThreadObj->threadMutex), NULL) < 0) { + tError("%s failed to init TCP process data mutex, reason:%s", label, strerror(errno)); + return NULL; + } - pThreadObj->numOfFds--; + if (pthread_cond_init(&(pThreadObj->fdReady), NULL) != 0) { + tError("%s init TCP condition variable failed, reason:%s\n", label, strerror(errno)); + return NULL; + } - if (pThreadObj->numOfFds < 0) - tError("%s TCP thread:%d, number of FDs shall never be negative", pThreadObj->label, pThreadObj->threadId); + pThreadObj->pollFd = epoll_create(10); // size does not matter + if (pThreadObj->pollFd < 0) { + tError("%s failed to create TCP epoll", label); + return NULL; + } - // remove from the FdObject list + pthread_attr_init(&thattr); + pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); + if (pthread_create(&(pThreadObj->thread), &thattr, (void *)taosProcessTcpData, (void *)(pThreadObj)) != 0) { + tError("%s failed to create TCP process data thread, reason:%s", label, strerror(errno)); + return NULL; + } - if (pFdObj->prev) { - (pFdObj->prev)->next = pFdObj->next; - } else { - pThreadObj->pHead = pFdObj->next; + pThreadObj->threadId = i; + pThreadObj++; } - if (pFdObj->next) { - (pFdObj->next)->prev = pFdObj->prev; + pthread_attr_init(&thattr); + pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); + if (pthread_create(&(pServerObj->thread), &thattr, (void *)taosAcceptTcpConnection, (void *)(pServerObj)) != 0) { + tError("%s failed to create TCP accept thread, reason:%s", label, strerror(errno)); + return NULL; } - pthread_mutex_unlock(&pThreadObj->threadMutex); - - // notify the upper layer, so it will clean the associated context - if (pFdObj->thandle) (*(pThreadObj->processData))(NULL, 0, 0, 0, pThreadObj->shandle, pFdObj->thandle, NULL); - - tTrace("%s TCP thread:%d, FD is cleaned up, numOfFds:%d", pThreadObj->label, pThreadObj->threadId, - pThreadObj->numOfFds); - - memset(pFdObj, 0, sizeof(SFdObj)); - - tfree(pFdObj); -} - -void taosCloseTcpServerConnection(void *chandle) { - SFdObj *pFdObj = (SFdObj *)chandle; - - if (pFdObj == NULL) return; + /* + if ( pthread_create(&(pServerObj->thread), &thattr, + (void*)taosAcceptUDConnection, (void *)(pServerObj)) != 0 ) { + tError("%s failed to create UD accept thread, reason:%s", label, + strerror(errno)); + return NULL; + } + */ + pthread_attr_destroy(&thattr); + tTrace("%s TCP server is initialized, ip:%s port:%hu numOfThreads:%d", label, ip, port, numOfThreads); - taosCleanUpFdObj(pFdObj); + return (void *)pServerObj; } void taosCleanUpTcpServer(void *handle) { @@ -148,6 +168,22 @@ void taosCleanUpTcpServer(void *handle) { tfree(pServerObj); } +void taosCloseTcpServerConnection(void *chandle) { + SFdObj *pFdObj = (SFdObj *)chandle; + + if (pFdObj == NULL) return; + + taosCleanUpFdObj(pFdObj); +} + +int taosSendTcpServerData(uint32_t ip, uint16_t port, void *data, int len, void *chandle) { + SFdObj *pFdObj = (SFdObj *)chandle; + + if (chandle == NULL) return -1; + + return (int)send(pFdObj->fd, data, (size_t)len, 0); +} + #define maxEvents 10 static void taosProcessTcpData(void *param) { @@ -155,8 +191,9 @@ static void taosProcessTcpData(void *param) { int i, fdNum; SFdObj * pFdObj; struct epoll_event events[maxEvents]; - + SRecvInfo recvInfo; pThreadObj = (SThreadObj *)param; + SRpcHead rpcHead; while (1) { pthread_mutex_lock(&pThreadObj->threadMutex); @@ -183,24 +220,24 @@ static void taosProcessTcpData(void *param) { continue; } - void *buffer = malloc(1024); - int headLen = taosReadMsg(pFdObj->fd, buffer, sizeof(SRpcHead)); - + int32_t headLen = taosReadMsg(pFdObj->fd, &rpcHead, sizeof(SRpcHead)); if (headLen != sizeof(SRpcHead)) { tError("%s read error, headLen:%d, errno:%d", pThreadObj->label, headLen, errno); taosCleanUpFdObj(pFdObj); - tfree(buffer); continue; } - int dataLen = (int32_t)htonl((uint32_t)((SRpcHead *)buffer)->msgLen); - if (dataLen > 1024) buffer = realloc(buffer, (size_t)dataLen); - - int leftLen = dataLen - headLen; - int retLen = taosReadMsg(pFdObj->fd, buffer + headLen, leftLen); + int32_t msgLen = (int32_t)htonl((uint32_t)rpcHead.msgLen); + char *buffer = malloc(msgLen + tsRpcOverhead); + if ( NULL == buffer) { + tError("%s TCP malloc(size:%d) fail\n", pThreadObj->label, msgLen); + taosCleanUpFdObj(pFdObj); + continue; + } - // tTrace("%s TCP data is received, ip:%s port:%u len:%d", - // pThreadObj->label, pFdObj->ipstr, pFdObj->port, dataLen); + char *msg = buffer + tsRpcOverhead; + int32_t leftLen = msgLen - headLen; + int32_t retLen = taosReadMsg(pFdObj->fd, msg + headLen, leftLen); if (leftLen != retLen) { tError("%s read error, leftLen:%d retLen:%d", pThreadObj->label, leftLen, retLen); @@ -209,15 +246,25 @@ static void taosProcessTcpData(void *param) { continue; } - pFdObj->thandle = (*(pThreadObj->processData))(buffer, dataLen, pFdObj->ip, pFdObj->port, - pThreadObj->shandle, pFdObj->thandle, pFdObj); + // tTrace("%s TCP data is received, ip:%s:%u len:%d", pTcp->label, pFdObj->ipstr, pFdObj->port, msgLen); + + memcpy(msg, &rpcHead, sizeof(SRpcHead)); + recvInfo.msg = msg; + recvInfo.msgLen = msgLen; + recvInfo.ip = pFdObj->ip; + recvInfo.port = pFdObj->port; + recvInfo.shandle = pThreadObj->shandle; + recvInfo.thandle = pFdObj->thandle;; + recvInfo.chandle = pFdObj; + recvInfo.connType = RPC_CONN_TCP; + pFdObj->thandle = (*(pThreadObj->processData))(&recvInfo); if (pFdObj->thandle == NULL) taosCleanUpFdObj(pFdObj); } } } -void taosAcceptTcpConnection(void *arg) { +static void taosAcceptTcpConnection(void *arg) { int connFd = -1; struct sockaddr_in clientAddr; int sockFd; @@ -280,20 +327,15 @@ void taosAcceptTcpConnection(void *arg) { // notify the data process, add into the FdObj list pthread_mutex_lock(&(pThreadObj->threadMutex)); - pFdObj->next = pThreadObj->pHead; - if (pThreadObj->pHead) (pThreadObj->pHead)->prev = pFdObj; - pThreadObj->pHead = pFdObj; - pThreadObj->numOfFds++; pthread_cond_signal(&pThreadObj->fdReady); - pthread_mutex_unlock(&(pThreadObj->threadMutex)); - tTrace("%s TCP thread:%d, a new connection, ip:%s port:%hu, numOfFds:%d", pServerObj->label, pThreadObj->threadId, - pFdObj->ipstr, pFdObj->port, pThreadObj->numOfFds); + tTrace("%s TCP thread:%d, a new connection from %s:%hu, FD:%p, numOfFds:%d", pServerObj->label, + pThreadObj->threadId, pFdObj->ipstr, pFdObj->port, pFdObj, pThreadObj->numOfFds); // pick up next thread for next connection threadId++; @@ -301,7 +343,65 @@ void taosAcceptTcpConnection(void *arg) { } } -void taosAcceptUDConnection(void *arg) { +static void taosCleanUpFdObj(SFdObj *pFdObj) { + SThreadObj *pThreadObj; + + if (pFdObj == NULL) return; + if (pFdObj->signature != pFdObj) return; + + pThreadObj = pFdObj->pThreadObj; + if (pThreadObj == NULL) { + tError("FdObj double clean up!!!"); + return; + } + + epoll_ctl(pThreadObj->pollFd, EPOLL_CTL_DEL, pFdObj->fd, NULL); + close(pFdObj->fd); + + pthread_mutex_lock(&pThreadObj->threadMutex); + + pThreadObj->numOfFds--; + + if (pThreadObj->numOfFds < 0) + tError("%s TCP thread:%d, number of FDs shall never be negative", pThreadObj->label, pThreadObj->threadId); + + // remove from the FdObject list + + if (pFdObj->prev) { + (pFdObj->prev)->next = pFdObj->next; + } else { + pThreadObj->pHead = pFdObj->next; + } + + if (pFdObj->next) { + (pFdObj->next)->prev = pFdObj->prev; + } + + pthread_mutex_unlock(&pThreadObj->threadMutex); + + // notify the upper layer, so it will clean the associated context + SRecvInfo recvInfo; + recvInfo.msg = NULL; + recvInfo.msgLen = 0; + recvInfo.ip = 0; + recvInfo.port = 0; + recvInfo.shandle = pThreadObj->shandle; + recvInfo.thandle = pFdObj->thandle;; + recvInfo.chandle = NULL; + recvInfo.connType = RPC_CONN_TCP; + + if (pFdObj->thandle) (*(pThreadObj->processData))(&recvInfo); + + tTrace("%s TCP thread:%d, FD:%p is cleaned up, numOfFds:%d", pThreadObj->label, pThreadObj->threadId, + pFdObj, pThreadObj->numOfFds); + + memset(pFdObj, 0, sizeof(SFdObj)); + + tfree(pFdObj); +} + +#if 0 +static void taosAcceptUDConnection(void *arg) { int connFd = -1; int sockFd; int threadId = 0; @@ -353,16 +453,11 @@ void taosAcceptUDConnection(void *arg) { // notify the data process, add into the FdObj list pthread_mutex_lock(&(pThreadObj->threadMutex)); - pFdObj->next = pThreadObj->pHead; - if (pThreadObj->pHead) (pThreadObj->pHead)->prev = pFdObj; - pThreadObj->pHead = pFdObj; - pThreadObj->numOfFds++; pthread_cond_signal(&pThreadObj->fdReady); - pthread_mutex_unlock(&(pThreadObj->threadMutex)); tTrace("%s UD thread:%d, a new connection, numOfFds:%d", pServerObj->label, pThreadObj->threadId, @@ -373,79 +468,7 @@ void taosAcceptUDConnection(void *arg) { threadId = threadId % pServerObj->numOfThreads; } } - -void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle) { - int i; - SServerObj * pServerObj; - pthread_attr_t thattr; - SThreadObj * pThreadObj; - - pServerObj = (SServerObj *)malloc(sizeof(SServerObj)); - strcpy(pServerObj->ip, ip); - pServerObj->port = port; - strcpy(pServerObj->label, label); - pServerObj->numOfThreads = numOfThreads; - - pServerObj->pThreadObj = (SThreadObj *)malloc(sizeof(SThreadObj) * (size_t)numOfThreads); - if (pServerObj->pThreadObj == NULL) { - tError("TCP:%s no enough memory", label); - return NULL; - } - memset(pServerObj->pThreadObj, 0, sizeof(SThreadObj) * (size_t)numOfThreads); - - pThreadObj = pServerObj->pThreadObj; - for (i = 0; i < numOfThreads; ++i) { - pThreadObj->processData = fp; - strcpy(pThreadObj->label, label); - pThreadObj->shandle = shandle; - - if (pthread_mutex_init(&(pThreadObj->threadMutex), NULL) < 0) { - tError("%s failed to init TCP process data mutex, reason:%s", label, strerror(errno)); - return NULL; - } - - if (pthread_cond_init(&(pThreadObj->fdReady), NULL) != 0) { - tError("%s init TCP condition variable failed, reason:%s\n", label, strerror(errno)); - return NULL; - } - - pThreadObj->pollFd = epoll_create(10); // size does not matter - if (pThreadObj->pollFd < 0) { - tError("%s failed to create TCP epoll", label); - return NULL; - } - - pthread_attr_init(&thattr); - pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); - if (pthread_create(&(pThreadObj->thread), &thattr, (void *)taosProcessTcpData, (void *)(pThreadObj)) != 0) { - tError("%s failed to create TCP process data thread, reason:%s", label, strerror(errno)); - return NULL; - } - - pThreadObj->threadId = i; - pThreadObj++; - } - - pthread_attr_init(&thattr); - pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); - if (pthread_create(&(pServerObj->thread), &thattr, (void *)taosAcceptTcpConnection, (void *)(pServerObj)) != 0) { - tError("%s failed to create TCP accept thread, reason:%s", label, strerror(errno)); - return NULL; - } - - /* - if ( pthread_create(&(pServerObj->thread), &thattr, - (void*)taosAcceptUDConnection, (void *)(pServerObj)) != 0 ) { - tError("%s failed to create UD accept thread, reason:%s", label, - strerror(errno)); - return NULL; - } - */ - pthread_attr_destroy(&thattr); - tTrace("%s TCP server is initialized, ip:%s port:%hu numOfThreads:%d", label, ip, port, numOfThreads); - - return (void *)pServerObj; -} +#endif #if 0 void taosListTcpConnection(void *handle, char *buffer) { @@ -489,10 +512,4 @@ void taosListTcpConnection(void *handle, char *buffer) { } #endif -int taosSendTcpServerData(uint32_t ip, uint16_t port, char *data, int len, void *chandle) { - SFdObj *pFdObj = (SFdObj *)chandle; - if (chandle == NULL) return -1; - - return (int)send(pFdObj->fd, data, (size_t)len, 0); -} diff --git a/src/rpc/src/rpcUdp.c b/src/rpc/src/rpcUdp.c index 46cb768995f31b7e806b880e00291ef05f1929c6..64a4df0e735a9454f7e0f7f0030c931054bd40b1 100644 --- a/src/rpc/src/rpcUdp.c +++ b/src/rpc/src/rpcUdp.c @@ -40,13 +40,12 @@ typedef struct { char label[12]; // copy from udpConnSet; pthread_t thread; pthread_mutex_t mutex; - void * tmrCtrl; // copy from UdpConnSet; - void * hash; - void * shandle; // handle passed by upper layer during server initialization - void * pSet; - void *(*processData)(char *data, int dataLen, unsigned int ip, uint16_t port, void *shandle, void *thandle, - void *chandle); - char buffer[RPC_MAX_UDP_SIZE]; // buffer to receive data + void *tmrCtrl; // copy from UdpConnSet; + void *hash; + void *shandle; // handle passed by upper layer during server initialization + void *pSet; + void *(*processData)(SRecvInfo *pRecv); + char *buffer; // buffer to receive data } SUdpConn; typedef struct { @@ -58,10 +57,8 @@ typedef struct { int threads; char label[12]; void * tmrCtrl; - pthread_t tcpThread; - int tcpFd; - void *(*fp)(char *data, int dataLen, uint32_t ip, uint16_t port, void *shandle, void *thandle, void *chandle); - SUdpConn udpConn[]; + void *(*fp)(SRecvInfo *pPacket); + SUdpConn udpConn[]; } SUdpConnSet; typedef struct { @@ -76,420 +73,9 @@ typedef struct { int emptyNum; } SUdpBuf; -typedef struct { - uint64_t handle; - uint16_t port; - int32_t msgLen; -} SPacketInfo; - -typedef struct { - int fd; - uint32_t ip; - uint16_t port; - SUdpConnSet *pSet; -} STransfer; - -typedef struct { - void * pTimer; - SUdpConnSet *pSet; - SUdpConn * pConn; - int dataLen; - uint32_t ip; - uint16_t port; - char data[96]; -} SMonitor; - -typedef struct { - uint64_t handle; - uint64_t hash; -} SHandleViaTcp; - -void taosFreeMsgHdr(void *hdr) { - struct msghdr *msgHdr = (struct msghdr *)hdr; - free(msgHdr->msg_iov); -} - -int taosMsgHdrSize(void *hdr) { - struct msghdr *msgHdr = (struct msghdr *)hdr; - return (int)msgHdr->msg_iovlen; -} - -void taosSendMsgHdr(void *hdr, int fd) { - struct msghdr *msgHdr = (struct msghdr *)hdr; - sendmsg(fd, msgHdr, 0); - msgHdr->msg_iovlen = 0; -} - -void taosInitMsgHdr(void **hdr, void *dest, int maxPkts) { - struct msghdr *msgHdr = (struct msghdr *)malloc(sizeof(struct msghdr)); - memset(msgHdr, 0, sizeof(struct msghdr)); - *hdr = msgHdr; - struct sockaddr_in *destAdd = (struct sockaddr_in *)dest; - - msgHdr->msg_name = destAdd; - msgHdr->msg_namelen = sizeof(struct sockaddr_in); - int size = (int)sizeof(struct iovec) * maxPkts; - msgHdr->msg_iov = (struct iovec *)malloc((size_t)size); - memset(msgHdr->msg_iov, 0, (size_t)size); -} - -void taosSetMsgHdrData(void *hdr, char *data, int dataLen) { - struct msghdr *msgHdr = (struct msghdr *)hdr; - msgHdr->msg_iov[msgHdr->msg_iovlen].iov_base = data; - msgHdr->msg_iov[msgHdr->msg_iovlen].iov_len = (size_t)dataLen; - msgHdr->msg_iovlen++; -} -bool taosCheckHandleViaTcpValid(SHandleViaTcp *handleViaTcp) { - return handleViaTcp->hash == taosHashUInt64(handleViaTcp->handle); -} - -void taosInitHandleViaTcp(SHandleViaTcp *handleViaTcp, uint64_t handle) { - handleViaTcp->handle = handle; - handleViaTcp->hash = taosHashUInt64(handleViaTcp->handle); -} - -void taosProcessMonitorTimer(void *param, void *tmrId) { - SMonitor *pMonitor = (SMonitor *)param; - if (pMonitor->pTimer != tmrId) return; - - SUdpConnSet *pSet = pMonitor->pSet; - pMonitor->pTimer = NULL; - - if (pSet) { - char *data = malloc((size_t)pMonitor->dataLen); - memcpy(data, pMonitor->data, (size_t)pMonitor->dataLen); - - tTrace("%s monitor timer is expired, update the link status", pSet->label); - (*pSet->fp)(data, pMonitor->dataLen, pMonitor->ip, 0, pSet->shandle, NULL, NULL); - taosTmrReset(taosProcessMonitorTimer, 200, pMonitor, pSet->tmrCtrl, &pMonitor->pTimer); - } else { - taosTmrStopA(&pMonitor->pTimer); - free(pMonitor); - } -} - -void *taosReadTcpData(void *argv) { - SMonitor *pMonitor = (SMonitor *)argv; - SRpcHead *pHead = (SRpcHead *)pMonitor->data; - SPacketInfo *pInfo = (SPacketInfo *)pHead->content; - SUdpConnSet *pSet = pMonitor->pSet; - int retLen, fd; - char ipstr[64]; - - pInfo->msgLen = (int32_t)htonl((uint32_t)pInfo->msgLen); - - tinet_ntoa(ipstr, pMonitor->ip); - tTrace("%s receive packet via TCP:%s:%hu, msgLen:%d, handle:0x%x, source:0x%08x dest:0x%08x tranId:%d", pSet->label, - ipstr, pInfo->port, pInfo->msgLen, pInfo->handle, pHead->sourceId, pHead->destId, pHead->tranId); - - fd = taosOpenTcpClientSocket(ipstr, (int16_t)pInfo->port, tsLocalIp); - if (fd < 0) { - tError("%s failed to open TCP client socket ip:%s:%hu", pSet->label, ipstr, pInfo->port); - pMonitor->pSet = NULL; - return NULL; - } - - SHandleViaTcp handleViaTcp; - taosInitHandleViaTcp(&handleViaTcp, pInfo->handle); - retLen = (int)taosWriteSocket(fd, (char *)&handleViaTcp, sizeof(SHandleViaTcp)); - - if (retLen != (int)sizeof(SHandleViaTcp)) { - tError("%s failed to send handle:0x%x to server, retLen:%d", pSet->label, pInfo->handle, retLen); - pMonitor->pSet = NULL; - } else { - tTrace("%s handle:0x%x is sent to server", pSet->label, pInfo->handle); - char *buffer = malloc((size_t)pInfo->msgLen); - if (NULL == buffer) { - tError("%s failed to malloc(size:%d) for recv server data", pSet->label, pInfo->msgLen); - retLen = 0; - //taosCloseTcpSocket(fd); - //pMonitor->pSet = NULL; - //return NULL; - } else { - retLen = taosReadMsg(fd, buffer, pInfo->msgLen); - } - - pMonitor->pSet = NULL; - - if (retLen != pInfo->msgLen) { - tError("%s failed to read data from server, msgLen:%d retLen:%d", pSet->label, pInfo->msgLen, retLen); - tfree(buffer); - } else { - (*pSet->fp)(buffer, pInfo->msgLen, pMonitor->ip, pInfo->port, pSet->shandle, NULL, pMonitor->pConn); - } - } - - taosCloseTcpSocket(fd); - - return NULL; -} - -int taosReceivePacketViaTcp(uint32_t ip, SRpcHead *pHead, SUdpConn *pConn) { - SUdpConnSet * pSet = pConn->pSet; - SPacketInfo * pInfo = (SPacketInfo *)pHead->content; - int code = 0; - pthread_attr_t thattr; - pthread_t thread; - - tTrace("%s receive packet via TCP, handle:0x%x, source:0x%08x dest:0x%08x tranId:%d", pSet->label, pInfo->handle, - pHead->sourceId, pHead->destId, pHead->tranId); - - SMonitor *pMonitor = (SMonitor *)calloc(1, sizeof(SMonitor)); - pMonitor->dataLen = sizeof(SRpcHead) + sizeof(SPacketInfo); - memcpy(pMonitor->data, pHead, (size_t)pMonitor->dataLen); - pMonitor->pSet = pSet; - pMonitor->ip = ip; - pMonitor->port = pInfo->port; - pMonitor->pConn = pConn; - taosTmrReset(taosProcessMonitorTimer, 0, pMonitor, pSet->tmrCtrl, &pMonitor->pTimer); - - pthread_attr_init(&thattr); - pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED); - code = pthread_create(&(thread), &thattr, taosReadTcpData, (void *)pMonitor); - if (code < 0) { - tTrace("%s failed to create thread to read tcp data, reason:%s", pSet->label, strerror(errno)); - pMonitor->pSet = NULL; - } - - pthread_attr_destroy(&thattr); - return code; -} - -void *taosRecvUdpData(void *param) { - struct sockaddr_in sourceAdd; - unsigned int addLen, dataLen; - SUdpConn * pConn = (SUdpConn *)param; - uint16_t port; - int minSize = sizeof(SRpcHead); - - memset(&sourceAdd, 0, sizeof(sourceAdd)); - addLen = sizeof(sourceAdd); - tTrace("%s UDP thread is created, index:%d", pConn->label, pConn->index); - - while (1) { - dataLen = - (uint32_t)recvfrom(pConn->fd, pConn->buffer, sizeof(pConn->buffer), 0, (struct sockaddr *)&sourceAdd, &addLen); - tTrace("%s msg is recv from 0x%x:%hu len:%d", pConn->label, sourceAdd.sin_addr.s_addr, ntohs(sourceAdd.sin_port), - dataLen); - - if (dataLen < sizeof(SRpcHead)) { - tError("%s recvfrom failed, reason:%s\n", pConn->label, strerror(errno)); - continue; - } - - port = ntohs(sourceAdd.sin_port); - - int processedLen = 0, leftLen = 0; - int msgLen = 0; - int count = 0; - char *msg = pConn->buffer; - while (processedLen < (int)dataLen) { - leftLen = dataLen - processedLen; - SRpcHead *pHead = (SRpcHead *)msg; - msgLen = (int32_t)htonl((uint32_t)pHead->msgLen); - if (leftLen < minSize || msgLen > leftLen || msgLen < minSize) { - tError("%s msg is messed up, dataLen:%d processedLen:%d count:%d msgLen:%d", pConn->label, dataLen, - processedLen, count, msgLen); - break; - } - - if (pHead->tcp == 1) { - taosReceivePacketViaTcp(sourceAdd.sin_addr.s_addr, (SRpcHead *)msg, pConn); - } else { - char *data = malloc((size_t)msgLen); - memcpy(data, msg, (size_t)msgLen); - (*(pConn->processData))(data, msgLen, sourceAdd.sin_addr.s_addr, port, pConn->shandle, NULL, pConn); - } - - processedLen += msgLen; - msg += msgLen; - count++; - } - - // tTrace("%s %d UDP packets are received together", pConn->label, count); - } - - return NULL; -} - -void *taosTransferDataViaTcp(void *argv) { - STransfer * pTransfer = (STransfer *)argv; - int connFd = pTransfer->fd; - int msgLen, retLen, leftLen; - uint64_t handle; - SRpcHead *pHead = NULL, head; - SUdpConnSet *pSet = pTransfer->pSet; - - SHandleViaTcp handleViaTcp; - retLen = taosReadMsg(connFd, &handleViaTcp, sizeof(SHandleViaTcp)); - - if (retLen != sizeof(SHandleViaTcp)) { - tError("%s UDP server failed to read handle, retLen:%d", pSet->label, retLen); - taosCloseSocket(connFd); - free(pTransfer); - return NULL; - } - - if (!taosCheckHandleViaTcpValid(&handleViaTcp)) { - tError("%s UDP server read handle via tcp invalid, handle:%" PRIu64 ", hash:%" PRIu64, pSet->label, handleViaTcp.handle, - handleViaTcp.hash); - taosCloseSocket(connFd); - free(pTransfer); - return NULL; - } - - handle = handleViaTcp.handle; - - if (handle == 0) { - // receive a packet from client - tTrace("%s data will be received via TCP from 0x%x:%hu", pSet->label, pTransfer->ip, pTransfer->port); - retLen = taosReadMsg(connFd, &head, sizeof(SRpcHead)); - if (retLen != (int)sizeof(SRpcHead)) { - tError("%s failed to read msg header, retLen:%d", pSet->label, retLen); - } else { - SMonitor *pMonitor = (SMonitor *)calloc(1, sizeof(SMonitor)); - if (NULL == pMonitor) { - tError("%s malloc failed by TransferViaTcp from client", pSet->label); - taosCloseSocket(connFd); - free(pTransfer); - return NULL; - } - pMonitor->dataLen = sizeof(SRpcHead); - memcpy(pMonitor->data, &head, (size_t)pMonitor->dataLen); - ((SRpcHead *)pMonitor->data)->msgLen = (int32_t)htonl(sizeof(SRpcHead)); - ((SRpcHead *)pMonitor->data)->tcp = 1; - pMonitor->ip = pTransfer->ip; - pMonitor->port = head.port; - pMonitor->pSet = pSet; - taosTmrReset(taosProcessMonitorTimer, 0, pMonitor, pSet->tmrCtrl, &pMonitor->pTimer); - - msgLen = (int32_t)htonl((uint32_t)head.msgLen); - char *buffer = malloc((size_t)msgLen); - if (NULL == buffer) { - tError("%s malloc failed for msg by TransferViaTcp", pSet->label); - taosCloseSocket(connFd); - free(pTransfer); - return NULL; - } - - leftLen = msgLen - (int)sizeof(SRpcHead); - retLen = taosReadMsg(connFd, buffer + sizeof(SRpcHead), leftLen); - pMonitor->pSet = NULL; - - if (retLen != leftLen) { - tError("%s failed to read data from client, leftLen:%d retLen:%d, error:%s", pSet->label, leftLen, retLen, - strerror(errno)); - } else { - tTrace("%s data is received from client via TCP from 0x%x:%hu, msgLen:%d", pSet->label, pTransfer->ip, - pTransfer->port, msgLen); - pSet->index = (pSet->index + 1) % pSet->threads; - SUdpConn *pConn = pSet->udpConn + pSet->index; - memcpy(buffer, &head, sizeof(SRpcHead)); - (*pSet->fp)(buffer, msgLen, pTransfer->ip, head.port, pSet->shandle, NULL, pConn); - } - - taosWriteMsg(connFd, &handleViaTcp, sizeof(SHandleViaTcp)); - } - } else { - // send a packet to client - tTrace("%s send packet to client via TCP, handle:0x%x", pSet->label, handle); - pHead = (SRpcHead *)handle; - msgLen = (int32_t)htonl((uint32_t)pHead->msgLen); - - if (pHead->tcp != 0 || msgLen < 1024) { - tError("%s invalid handle:%p, connection shall be closed", pSet->label, pHead); - } else { - SMonitor *pMonitor = (SMonitor *)calloc(1, sizeof(SMonitor)); - if (NULL == pMonitor) { - tError("%s malloc failed by TransferViaTcp to client", pSet->label); - taosCloseSocket(connFd); - free(pTransfer); - return NULL; - } - pMonitor->dataLen = sizeof(SRpcHead); - memcpy(pMonitor->data, (void *)handle, (size_t)pMonitor->dataLen); - SRpcHead *pThead = (SRpcHead *)pMonitor->data; - pThead->tcp = 1; - pThead->msgType = (char)(pHead->msgType - 1); - pThead->msgLen = (int32_t)htonl(sizeof(SRpcHead)); - uint32_t id = pThead->sourceId; pThead->sourceId = pThead->destId; pThead->destId = id; - pMonitor->ip = pTransfer->ip; - pMonitor->port = pTransfer->port; - pMonitor->pSet = pSet; - taosTmrReset(taosProcessMonitorTimer, 200, pMonitor, pSet->tmrCtrl, &pMonitor->pTimer); - - retLen = taosWriteMsg(connFd, (void *)handle, msgLen); - pMonitor->pSet = NULL; - - if (retLen != msgLen) { - tError("%s failed to send data to client, msgLen:%d retLen:%d", pSet->label, msgLen, retLen); - } else { - tTrace("%s data is sent to client successfully via TCP to 0x%x:%hu, size:%d", pSet->label, pTransfer->ip, - pTransfer->port, msgLen); - } - } - } - - // retLen = taosReadMsg(connFd, &handleViaTcp, sizeof(handleViaTcp)); - free(pTransfer); - taosCloseSocket(connFd); - - return NULL; -} - -void *taosUdpTcpConnection(void *argv) { - int connFd = -1; - struct sockaddr_in clientAddr; - pthread_attr_t thattr; - pthread_t thread; - uint32_t sourceIp; - char ipstr[20]; - - SUdpConnSet *pSet = (SUdpConnSet *)argv; - - pSet->tcpFd = taosOpenTcpServerSocket(pSet->ip, pSet->port); - if (pSet->tcpFd < 0) { - tPrint("%s failed to create TCP socket %s:%hu for UDP server, reason:%s", pSet->label, pSet->ip, pSet->port, - strerror(errno)); - taosKillSystem(); - return NULL; - } - - tTrace("%s UDP server is created, ip:%s:%hu", pSet->label, pSet->ip, pSet->port); - - pthread_attr_init(&thattr); - pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED); - - while (1) { - if (pSet->tcpFd < 0) break; - socklen_t addrlen = sizeof(clientAddr); - connFd = accept(pSet->tcpFd, (struct sockaddr *)&clientAddr, &addrlen); - - if (connFd < 0) { - tError("%s UDP server TCP accept failure, reason:%s", pSet->label, strerror(errno)); - continue; - } - - sourceIp = clientAddr.sin_addr.s_addr; - tinet_ntoa(ipstr, sourceIp); - tTrace("%s UDP server TCP connection from ip:%s:%u", pSet->label, ipstr, htons(clientAddr.sin_port)); - - STransfer *pTransfer = malloc(sizeof(STransfer)); - pTransfer->fd = connFd; - pTransfer->ip = sourceIp; - pTransfer->port = clientAddr.sin_port; - pTransfer->pSet = pSet; - - if (pthread_create(&(thread), &thattr, taosTransferDataViaTcp, (void *)pTransfer) < 0) { - tTrace("%s failed to create thread for UDP server, reason:%s", pSet->label, strerror(errno)); - free(pTransfer); - taosCloseSocket(connFd); - } - } - - pthread_attr_destroy(&thattr); - return NULL; -} +static void *taosRecvUdpData(void *param); +static SUdpBuf *taosCreateUdpBuf(SUdpConn *pConn, uint32_t ip, uint16_t port); +static void taosProcessUdpBufTimer(void *param, void *tmrId); void *taosInitUdpConnection(char *ip, uint16_t port, char *label, int threads, void *fp, void *shandle) { pthread_attr_t thAttr; @@ -508,18 +94,17 @@ void *taosInitUdpConnection(char *ip, uint16_t port, char *label, int threads, v pSet->port = port; pSet->shandle = shandle; pSet->fp = fp; - pSet->tcpFd = -1; strcpy(pSet->label, label); - // if ( tsUdpDelay ) { - char udplabel[12]; - sprintf(udplabel, "%s.b", label); - pSet->tmrCtrl = taosTmrInit(RPC_MAX_UDP_CONNS * threads, 5, 5000, udplabel); - if (pSet->tmrCtrl == NULL) { - tError("%s failed to initialize tmrCtrl") taosCleanUpUdpConnection(pSet); - return NULL; + if ( tsUdpDelay ) { + char udplabel[12]; + sprintf(udplabel, "%s.b", label); + pSet->tmrCtrl = taosTmrInit(RPC_MAX_UDP_CONNS * threads, 5, 5000, udplabel); + if (pSet->tmrCtrl == NULL) { + tError("%s failed to initialize tmrCtrl") taosCleanUpUdpConnection(pSet); + return NULL; + } } - // } pthread_attr_init(&thAttr); pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE); @@ -535,6 +120,13 @@ void *taosInitUdpConnection(char *ip, uint16_t port, char *label, int threads, v return NULL; } + pConn->buffer = malloc(RPC_MAX_UDP_SIZE); + if (NULL == pConn->buffer) { + tError("%s failed to malloc recv buffer", label); + taosCleanUpUdpConnection(pSet); + return NULL; + } + struct sockaddr_in sin; unsigned int addrlen = sizeof(sin); if (getsockname(pConn->fd, (struct sockaddr *)&sin, &addrlen) == 0 && sin.sin_family == AF_INET && @@ -543,14 +135,6 @@ void *taosInitUdpConnection(char *ip, uint16_t port, char *label, int threads, v } strcpy(pConn->label, label); - - if (pthread_create(&pConn->thread, &thAttr, taosRecvUdpData, pConn) != 0) { - tError("%s failed to create thread to process UDP data, reason:%s", label, strerror(errno)); - taosCloseSocket(pConn->fd); - taosCleanUpUdpConnection(pSet); - return NULL; - } - pConn->shandle = shandle; pConn->processData = fp; pConn->index = i; @@ -561,6 +145,14 @@ void *taosInitUdpConnection(char *ip, uint16_t port, char *label, int threads, v pthread_mutex_init(&pConn->mutex, NULL); pConn->tmrCtrl = pSet->tmrCtrl; } + + if (pthread_create(&pConn->thread, &thAttr, taosRecvUdpData, pConn) != 0) { + tError("%s failed to create thread to process UDP data, reason:%s", label, strerror(errno)); + taosCloseSocket(pConn->fd); + taosCleanUpUdpConnection(pSet); + return NULL; + } + ++pSet->threads; } @@ -570,43 +162,16 @@ void *taosInitUdpConnection(char *ip, uint16_t port, char *label, int threads, v return pSet; } -void *taosInitUdpServer(char *ip, uint16_t port, char *label, int threads, void *fp, void *shandle) { - SUdpConnSet *pSet; - pSet = taosInitUdpConnection(ip, port, label, threads, fp, shandle); - if (pSet == NULL) return NULL; - - pSet->server = 1; - pSet->fp = fp; - - pthread_attr_t thattr; - pthread_attr_init(&thattr); - pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED); - - // not support by windows - // pthread_t thread; - // pSet->tcpThread = pthread_create(&(thread), &thattr, taosUdpTcpConnection, pSet); - pthread_create(&(pSet->tcpThread), &thattr, taosUdpTcpConnection, pSet); - pthread_attr_destroy(&thattr); - - return pSet; -} - -void *taosInitUdpClient(char *ip, uint16_t port, char *label, int threads, void *fp, void *shandle) { - return taosInitUdpConnection(ip, port, label, threads, fp, shandle); -} - void taosCleanUpUdpConnection(void *handle) { SUdpConnSet *pSet = (SUdpConnSet *)handle; SUdpConn * pConn; if (pSet == NULL) return; - if (pSet->server == 1) { - pthread_cancel(pSet->tcpThread); - } for (int i = 0; i < pSet->threads; ++i) { pConn = pSet->udpConn + i; pConn->signature = NULL; + free(pConn->buffer); pthread_cancel(pConn->thread); taosCloseSocket(pConn->fd); if (pConn->hash) { @@ -621,8 +186,6 @@ void taosCleanUpUdpConnection(void *handle) { tTrace("chandle:%p is closed", pConn); } - if (pSet->tcpFd >= 0) taosCloseTcpSocket(pSet->tcpFd); - pSet->tcpFd = -1; taosTmrCleanUp(pSet->tmrCtrl); tfree(pSet); } @@ -641,6 +204,154 @@ void *taosOpenUdpConnection(void *shandle, void *thandle, char *ip, uint16_t por return pConn; } +static void *taosRecvUdpData(void *param) { + struct sockaddr_in sourceAdd; + int dataLen; + unsigned int addLen; + SUdpConn * pConn = (SUdpConn *)param; + uint16_t port; + int minSize = sizeof(SRpcHead); + SRecvInfo recvInfo; + + memset(&sourceAdd, 0, sizeof(sourceAdd)); + addLen = sizeof(sourceAdd); + tTrace("%s UDP thread is created, index:%d", pConn->label, pConn->index); + + while (1) { + dataLen = recvfrom(pConn->fd, pConn->buffer, RPC_MAX_UDP_SIZE, 0, (struct sockaddr *)&sourceAdd, &addLen); + tTrace("%s msg is recv from 0x%x:%hu len:%d", pConn->label, sourceAdd.sin_addr.s_addr, ntohs(sourceAdd.sin_port), + dataLen); + + if (dataLen < sizeof(SRpcHead)) { + tError("%s recvfrom failed, reason:%s\n", pConn->label, strerror(errno)); + continue; + } + + port = ntohs(sourceAdd.sin_port); + + int processedLen = 0, leftLen = 0; + int msgLen = 0; + int count = 0; + char *msg = pConn->buffer; + while (processedLen < dataLen) { + leftLen = dataLen - processedLen; + SRpcHead *pHead = (SRpcHead *)msg; + msgLen = htonl((uint32_t)pHead->msgLen); + if (leftLen < minSize || msgLen > leftLen || msgLen < minSize) { + tError("%s msg is messed up, dataLen:%d processedLen:%d count:%d msgLen:%d", pConn->label, dataLen, + processedLen, count, msgLen); + break; + } + + char *tmsg = malloc((size_t)msgLen + tsRpcOverhead); + if (NULL == tmsg) { + tError("%s failed to allocate memory, size:%d", pConn->label, msgLen); + break; + } + + tmsg += tsRpcOverhead; // overhead for SRpcReqContext + memcpy(tmsg, msg, (size_t)msgLen); + recvInfo.msg = tmsg; + recvInfo.msgLen = msgLen; + recvInfo.ip = sourceAdd.sin_addr.s_addr; + recvInfo.port = port; + recvInfo.shandle = pConn->shandle; + recvInfo.thandle = NULL; + recvInfo.chandle = pConn; + recvInfo.connType = 0; + (*(pConn->processData))(&recvInfo); + + processedLen += msgLen; + msg += msgLen; + count++; + } + + // tTrace("%s %d UDP packets are received together", pConn->label, count); + } + + return NULL; +} + +int taosSendUdpData(uint32_t ip, uint16_t port, void *data, int dataLen, void *chandle) { + SUdpConn *pConn = (SUdpConn *)chandle; + SUdpBuf * pBuf; + + if (pConn == NULL || pConn->signature != pConn) return -1; + + if (pConn->hash == NULL) { + struct sockaddr_in destAdd; + memset(&destAdd, 0, sizeof(destAdd)); + destAdd.sin_family = AF_INET; + destAdd.sin_addr.s_addr = ip; + destAdd.sin_port = htons(port); + + //tTrace("%s msg is sent to 0x%x:%hu len:%d ret:%d localPort:%hu chandle:0x%x", pConn->label, destAdd.sin_addr.s_addr, + // port, dataLen, ret, pConn->localPort, chandle); + int ret = (int)sendto(pConn->fd, data, (size_t)dataLen, 0, (struct sockaddr *)&destAdd, sizeof(destAdd)); + + return ret; + } + + pthread_mutex_lock(&pConn->mutex); + + pBuf = (SUdpBuf *)rpcGetIpHash(pConn->hash, ip, port); + if (pBuf == NULL) { + pBuf = taosCreateUdpBuf(pConn, ip, port); + rpcAddIpHash(pConn->hash, pBuf, ip, port); + } + + if ((pBuf->totalLen + dataLen > RPC_MAX_UDP_SIZE) || (taosMsgHdrSize(pBuf->msgHdr) >= RPC_MAX_UDP_PKTS)) { + taosTmrReset(taosProcessUdpBufTimer, RPC_UDP_BUF_TIME, pBuf, pConn->tmrCtrl, &pBuf->timer); + + taosSendMsgHdr(pBuf->msgHdr, pConn->fd); + pBuf->totalLen = 0; + } + + taosSetMsgHdrData(pBuf->msgHdr, data, dataLen); + + pBuf->totalLen += dataLen; + + pthread_mutex_unlock(&pConn->mutex); + + return dataLen; +} + +void taosFreeMsgHdr(void *hdr) { + struct msghdr *msgHdr = (struct msghdr *)hdr; + free(msgHdr->msg_iov); +} + +int taosMsgHdrSize(void *hdr) { + struct msghdr *msgHdr = (struct msghdr *)hdr; + return (int)msgHdr->msg_iovlen; +} + +void taosSendMsgHdr(void *hdr, int fd) { + struct msghdr *msgHdr = (struct msghdr *)hdr; + sendmsg(fd, msgHdr, 0); + msgHdr->msg_iovlen = 0; +} + +void taosInitMsgHdr(void **hdr, void *dest, int maxPkts) { + struct msghdr *msgHdr = (struct msghdr *)malloc(sizeof(struct msghdr)); + memset(msgHdr, 0, sizeof(struct msghdr)); + *hdr = msgHdr; + struct sockaddr_in *destAdd = (struct sockaddr_in *)dest; + + msgHdr->msg_name = destAdd; + msgHdr->msg_namelen = sizeof(struct sockaddr_in); + int size = (int)sizeof(struct iovec) * maxPkts; + msgHdr->msg_iov = (struct iovec *)malloc((size_t)size); + memset(msgHdr->msg_iov, 0, (size_t)size); +} + +void taosSetMsgHdrData(void *hdr, char *data, int dataLen) { + struct msghdr *msgHdr = (struct msghdr *)hdr; + msgHdr->msg_iov[msgHdr->msg_iovlen].iov_base = data; + msgHdr->msg_iov[msgHdr->msg_iovlen].iov_len = (size_t)dataLen; + msgHdr->msg_iovlen++; +} + void taosRemoveUdpBuf(SUdpBuf *pBuf) { taosTmrStopA(&pBuf->timer); rpcDeleteIpHash(pBuf->pConn->hash, pBuf->ip, pBuf->port); @@ -679,7 +390,7 @@ void taosProcessUdpBufTimer(void *param, void *tmrId) { if (pBuf) taosTmrReset(taosProcessUdpBufTimer, RPC_UDP_BUF_TIME, pBuf, pConn->tmrCtrl, &pBuf->timer); } -SUdpBuf *taosCreateUdpBuf(SUdpConn *pConn, uint32_t ip, uint16_t port) { +static SUdpBuf *taosCreateUdpBuf(SUdpConn *pConn, uint32_t ip, uint16_t port) { SUdpBuf *pBuf = (SUdpBuf *)malloc(sizeof(SUdpBuf)); memset(pBuf, 0, sizeof(SUdpBuf)); @@ -700,121 +411,4 @@ SUdpBuf *taosCreateUdpBuf(SUdpConn *pConn, uint32_t ip, uint16_t port) { return pBuf; } -int taosSendPacketViaTcp(uint32_t ip, uint16_t port, char *data, int dataLen, void *chandle) { - SUdpConn * pConn = (SUdpConn *)chandle; - SUdpConnSet *pSet = (SUdpConnSet *)pConn->pSet; - int code = -1, retLen, msgLen; - char ipstr[64]; - char buffer[128]; - SRpcHead *pHead; - - if (pSet->server) { - // send from server - - pHead = (SRpcHead *)buffer; - memcpy(pHead, data, sizeof(SRpcHead)); - pHead->tcp = 1; - - SPacketInfo *pInfo = (SPacketInfo *)pHead->content; - pInfo->handle = (uint64_t)data; - pInfo->port = pSet->port; - pInfo->msgLen = pHead->msgLen; - - msgLen = sizeof(SRpcHead) + sizeof(SPacketInfo); - pHead->msgLen = (int32_t)htonl((uint32_t)msgLen); - code = taosSendUdpData(ip, port, buffer, msgLen, chandle); - tTrace("%s data from server will be sent via TCP:%hu, msgType:%d, length:%d, handle:0x%x", pSet->label, pInfo->port, - pHead->msgType, htonl((uint32_t)pInfo->msgLen), pInfo->handle); - if (code > 0) code = dataLen; - } else { - // send from client - tTrace("%s data will be sent via TCP from client", pSet->label); - - // send a UDP header first to set up the connection - pHead = (SRpcHead *)buffer; - memcpy(pHead, data, sizeof(SRpcHead)); - - pHead->tcp = 2; - - msgLen = sizeof(SRpcHead); - pHead->msgLen = (int32_t)htonl(msgLen); - code = taosSendUdpData(ip, port, buffer, msgLen, chandle); - - //pHead = (SRpcHead *)data; - - tinet_ntoa(ipstr, ip); - int fd = taosOpenTcpClientSocket(ipstr, pConn->port, tsLocalIp); - if (fd < 0) { - tError("%s failed to open TCP socket to:%s:%hu to send packet", pSet->label, ipstr, pConn->port); - } else { - SHandleViaTcp handleViaTcp; - taosInitHandleViaTcp(&handleViaTcp, 0); - retLen = (int)taosWriteSocket(fd, (char *)&handleViaTcp, sizeof(SHandleViaTcp)); - - if (retLen != (int)sizeof(handleViaTcp)) { - tError("%s failed to send handle to server, retLen:%d", pSet->label, retLen); - } else { - retLen = taosWriteMsg(fd, data, dataLen); - if (retLen != dataLen) { - tError("%s failed to send data via TCP, dataLen:%d, retLen:%d, error:%s", pSet->label, dataLen, retLen, - strerror(errno)); - } else { - code = dataLen; - tTrace("%s data is sent via TCP successfully", pSet->label); - } - } - taosReadMsg(fd, (char *)&handleViaTcp, sizeof(SHandleViaTcp)); - - taosCloseTcpSocket(fd); - } - } - - return code; -} - -int taosSendUdpData(uint32_t ip, uint16_t port, char *data, int dataLen, void *chandle) { - SUdpConn *pConn = (SUdpConn *)chandle; - SUdpBuf * pBuf; - - if (pConn == NULL || pConn->signature != pConn) return -1; - - if (dataLen >= RPC_MAX_UDP_SIZE) return taosSendPacketViaTcp(ip, port, data, dataLen, chandle); - - if (pConn->hash == NULL) { - struct sockaddr_in destAdd; - memset(&destAdd, 0, sizeof(destAdd)); - destAdd.sin_family = AF_INET; - destAdd.sin_addr.s_addr = ip; - destAdd.sin_port = htons(port); - - int ret = (int)sendto(pConn->fd, data, (size_t)dataLen, 0, (struct sockaddr *)&destAdd, sizeof(destAdd)); - tTrace("%s msg is sent to 0x%x:%hu len:%d ret:%d localPort:%hu chandle:0x%x", pConn->label, destAdd.sin_addr.s_addr, - port, dataLen, ret, pConn->localPort, chandle); - - return ret; - } - - pthread_mutex_lock(&pConn->mutex); - - pBuf = (SUdpBuf *)rpcGetIpHash(pConn->hash, ip, port); - if (pBuf == NULL) { - pBuf = taosCreateUdpBuf(pConn, ip, port); - rpcAddIpHash(pConn->hash, pBuf, ip, port); - } - - if ((pBuf->totalLen + dataLen > RPC_MAX_UDP_SIZE) || (taosMsgHdrSize(pBuf->msgHdr) >= RPC_MAX_UDP_PKTS)) { - taosTmrReset(taosProcessUdpBufTimer, RPC_UDP_BUF_TIME, pBuf, pConn->tmrCtrl, &pBuf->timer); - - taosSendMsgHdr(pBuf->msgHdr, pConn->fd); - pBuf->totalLen = 0; - } - - taosSetMsgHdrData(pBuf->msgHdr, data, dataLen); - - pBuf->totalLen += dataLen; - - pthread_mutex_unlock(&pConn->mutex); - - return dataLen; -} diff --git a/src/rpc/src/tqueue.c b/src/rpc/src/tqueue.c new file mode 100644 index 0000000000000000000000000000000000000000..2f6f9ac106df98c6d5da0092ddf42d1a50d19cac --- /dev/null +++ b/src/rpc/src/tqueue.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "os.h" +#include "tlog.h" +#include "tqueue.h" + +#define DUMP_SCHEDULER_TIME_WINDOW 30000 //every 30sec, take a snap shot of task queue. + +typedef struct { + char label[16]; + int num; + tsem_t emptySem; + tsem_t fullSem; + pthread_mutex_t queueMutex; + int fullSlot; + int emptySlot; + int queueSize; + SRpcMsg *queue; + SRpcMsg *oqueue; + pthread_t qthread; + void (*fp)(int num, SRpcMsg *); +} SRpcQueue; + +static void *taosProcessMsgQueue(void *param); + +void *taosInitMsgQueue(int queueSize, void (*fp)(int num, SRpcMsg *), const char *label) { + pthread_attr_t attr; + SRpcQueue * pQueue = (SRpcQueue *)malloc(sizeof(SRpcQueue)); + if (pQueue == NULL) { + pError("%s: no enough memory for pQueue, reason: %s", label, strerror(errno)); + goto _error; + } + + memset(pQueue, 0, sizeof(SRpcQueue)); + pQueue->queueSize = queueSize; + strncpy(pQueue->label, label, sizeof(pQueue->label)); // fix buffer overflow + pQueue->label[sizeof(pQueue->label)-1] = '\0'; + pQueue->fp = fp; + + if (pthread_mutex_init(&pQueue->queueMutex, NULL) < 0) { + pError("init %s:queueMutex failed, reason:%s", pQueue->label, strerror(errno)); + goto _error; + } + + if (tsem_init(&pQueue->emptySem, 0, (unsigned int)pQueue->queueSize) != 0) { + pError("init %s:empty semaphore failed, reason:%s", pQueue->label, strerror(errno)); + goto _error; + } + + if (tsem_init(&pQueue->fullSem, 0, 0) != 0) { + pError("init %s:full semaphore failed, reason:%s", pQueue->label, strerror(errno)); + goto _error; + } + + if ((pQueue->queue = (SRpcMsg *)malloc((size_t)pQueue->queueSize * sizeof(SRpcMsg))) == NULL) { + pError("%s: no enough memory for queue, reason:%s", pQueue->label, strerror(errno)); + goto _error; + } + + memset(pQueue->queue, 0, (size_t)pQueue->queueSize * sizeof(SRpcMsg)); + + if ((pQueue->oqueue = (SRpcMsg *)malloc((size_t)pQueue->queueSize * sizeof(SRpcMsg))) == NULL) { + pError("%s: no enough memory for queue, reason:%s", pQueue->label, strerror(errno)); + goto _error; + } + + memset(pQueue->oqueue, 0, (size_t)pQueue->queueSize * sizeof(SRpcMsg)); + + pQueue->fullSlot = 0; + pQueue->fullSlot = 0; + pQueue->emptySlot = 0; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + if (pthread_create(&pQueue->qthread, &attr, taosProcessMsgQueue, (void *)pQueue) != 0) { + pError("%s: failed to create taos thread, reason:%s", pQueue->label, strerror(errno)); + goto _error; + } + + pTrace("%s RPC msg queue is initialized", pQueue->label); + + return (void *)pQueue; + +_error: + taosCleanUpMsgQueue(pQueue); + return NULL; +} + +void *taosProcessMsgQueue(void *param) { + SRpcQueue *pQueue = (SRpcQueue *)param; + int num = 0; + + while (1) { + if (tsem_wait(&pQueue->fullSem) != 0) { + if (errno == EINTR) { + /* sem_wait is interrupted by interrupt, ignore and continue */ + pTrace("wait %s fullSem was interrupted", pQueue->label); + continue; + } + pError("wait %s fullSem failed, errno:%d, reason:%s", pQueue->label, errno, strerror(errno)); + } + + if (pthread_mutex_lock(&pQueue->queueMutex) != 0) + pError("lock %s queueMutex failed, reason:%s", pQueue->label, strerror(errno)); + + num = 0; + do { + pQueue->oqueue[num] = pQueue->queue[pQueue->fullSlot]; + pQueue->fullSlot = (pQueue->fullSlot + 1) % pQueue->queueSize; + ++num; + pQueue->num--; + } while (pQueue->fullSlot != pQueue->emptySlot); + + if (pthread_mutex_unlock(&pQueue->queueMutex) != 0) + pError("unlock %s queueMutex failed, reason:%s\n", pQueue->label, strerror(errno)); + + for (int i= 0; iemptySem) != 0) + pError("post %s emptySem failed, reason:%s\n", pQueue->label, strerror(errno)); + } + + for (int i=0; ifullSem) != 0) + pError("wait %s fullSem failed, reason:%s\n", pQueue->label, strerror(errno)); + } + + (*pQueue->fp)(num, pQueue->oqueue); + + } + + return NULL; +} + +int taosPutIntoMsgQueue(void *qhandle, SRpcMsg *pMsg) { + SRpcQueue *pQueue = (SRpcQueue *)qhandle; + if (pQueue == NULL) { + pError("sched is not ready, msg:%p is dropped", pMsg); + return 0; + } + + while (tsem_wait(&pQueue->emptySem) != 0) { + if (errno != EINTR) { + pError("wait %s emptySem failed, reason:%s", pQueue->label, strerror(errno)); + break; + } + } + + if (pthread_mutex_lock(&pQueue->queueMutex) != 0) + pError("lock %s queueMutex failed, reason:%s", pQueue->label, strerror(errno)); + + pQueue->queue[pQueue->emptySlot] = *pMsg; + pQueue->emptySlot = (pQueue->emptySlot + 1) % pQueue->queueSize; + pQueue->num++; + + if (pthread_mutex_unlock(&pQueue->queueMutex) != 0) + pError("unlock %s queueMutex failed, reason:%s", pQueue->label, strerror(errno)); + + if (tsem_post(&pQueue->fullSem) != 0) pError("post %s fullSem failed, reason:%s", pQueue->label, strerror(errno)); + + return 0; +} + +void taosCleanUpMsgQueue(void *param) { + SRpcQueue *pQueue = (SRpcQueue *)param; + if (pQueue == NULL) return; + + pthread_cancel(pQueue->qthread); + + tsem_destroy(&pQueue->emptySem); + tsem_destroy(&pQueue->fullSem); + pthread_mutex_destroy(&pQueue->queueMutex); + + free(pQueue->queue); + free(pQueue); +} + diff --git a/src/rpc/test/rclient.c b/src/rpc/test/rclient.c index 8092e06d011d54e31c14e83999152c9cce722367..63c23ce7bc755ef8e492d1b7ada6b49351dfbc2f 100644 --- a/src/rpc/test/rclient.c +++ b/src/rpc/test/rclient.c @@ -13,58 +13,194 @@ * along with this program. If not, see . */ -//#define _DEFAULT_SOURCE +#include +#include +#include +#include +#include +#include +#include #include "os.h" #include "tlog.h" #include "trpc.h" #include "taoserror.h" #include +#include -void processMsg(char type, void *pCont, int contLen, void *ahandle, int32_t code) { - dPrint("response is received, type:%d, contLen:%d code:%x:%s", type, contLen, code, tstrerror(code)); +typedef struct { + int index; + SRpcIpSet ipSet; + int num; + int numOfReqs; + int msgSize; + sem_t rspSem; + sem_t *pOverSem; + pthread_t thread; + void *pRpc; +} SInfo; + +void processResponse(char type, void *pCont, int contLen, void *ahandle, int32_t code) { + SInfo *pInfo = (SInfo *)ahandle; + tTrace("thread:%d, response is received, type:%d contLen:%d code:0x%x", pInfo->index, type, contLen, code); + + if (pCont) rpcFreeCont(pCont); + + sem_post(&pInfo->rspSem); } -void processUpdate(void *handle, SRpcIpSet *pIpSet) { - dPrint("ip set is changed, index:%d", pIpSet->index); +void processUpdateIpSet(void *handle, SRpcIpSet *pIpSet) { + SInfo *pInfo = (SInfo *)handle; + + tTrace("thread:%d, ip set is changed, index:%d", pInfo->index, pIpSet->inUse); + pInfo->ipSet = *pIpSet; } -int32_t main(int32_t argc, char *argv[]) { +int tcount = 0; - taosInitLog("client.log", 100000, 10); - dPrint("unit test for rpc module"); +void *sendRequest(void *param) { + SInfo *pInfo = (SInfo *)param; + char *cont; + + tTrace("thread:%d, start to send request", pInfo->index); + + while ( pInfo->numOfReqs == 0 || pInfo->num < pInfo->numOfReqs) { + pInfo->num++; + cont = rpcMallocCont(pInfo->msgSize); + tTrace("thread:%d, send request, contLen:%d num:%d", pInfo->index, pInfo->msgSize, pInfo->num); + rpcSendRequest(pInfo->pRpc, &pInfo->ipSet, 1, cont, pInfo->msgSize, pInfo); + if ( pInfo->num % 20000 == 0 ) + tPrint("thread:%d, %d requests have been sent", pInfo->index, pInfo->num); + sem_wait(&pInfo->rspSem); + } + + tTrace("thread:%d, it is over", pInfo->index); + tcount++; + + return NULL; +} - SRpcInit rpcInit; +int main(int argc, char *argv[]) { + SRpcInit rpcInit; + SRpcIpSet ipSet; + int msgSize = 128; + int numOfReqs = 0; + int appThreads = 1; + char serverIp[40] = "127.0.0.1"; + struct timeval systemTime; + int64_t startTime, endTime; + pthread_attr_t thattr; + + // server info + ipSet.numOfIps = 1; + ipSet.inUse = 0; + ipSet.port = 7000; + ipSet.ip[0] = inet_addr(serverIp); + ipSet.ip[1] = inet_addr("192.168.0.1"); + + // client info memset(&rpcInit, 0, sizeof(rpcInit)); rpcInit.localIp = "0.0.0.0"; rpcInit.localPort = 0; rpcInit.label = "APP"; rpcInit.numOfThreads = 1; - rpcInit.cfp = processMsg; - rpcInit.ufp = processUpdate; - rpcInit.sessions = 1000; - rpcInit.connType = TAOS_CONN_UDPC; + rpcInit.cfp = processResponse; + rpcInit.ufp = processUpdateIpSet; + rpcInit.sessions = 100; rpcInit.idleTime = 2000; - rpcInit.meterId = "jefftao"; - rpcInit.secret = "password"; + rpcInit.user = "michael"; + rpcInit.secret = "mypassword"; rpcInit.ckey = "key"; + rpcInit.spi = 1; + + for (int i=1; iindex = i; + pInfo->ipSet = ipSet; + pInfo->numOfReqs = numOfReqs; + pInfo->msgSize = msgSize; + sem_init(&pInfo->rspSem, 0, 0); + pInfo->pRpc = pRpc; + pthread_create(&pInfo->thread, &thattr, sendRequest, pInfo); + pInfo++; + } + + do { + usleep(1); + } while ( tcount < appThreads); + + gettimeofday(&systemTime, NULL); + endTime = systemTime.tv_sec*1000000 + systemTime.tv_usec; + float usedTime = (endTime - startTime)/1000.0; // mseconds - void *cont = rpcMallocCont(100); - rpcSendRequest(pRpc, &ipSet, 1, cont, 100, 1); + tPrint("it takes %.3f mseconds to send %d requests to server", usedTime, numOfReqs*appThreads); + tPrint("Performance: %.3f requests per second, msgSize:%d bytes", 1000.0*numOfReqs*appThreads/usedTime, msgSize); - getchar(); + taosCloseLog(); return 0; } diff --git a/src/rpc/test/rserver.c b/src/rpc/test/rserver.c index d62550592d59a692f15afe1ec26306d2fde793af..84f0d50d442e32e89357e80ec51fe5ef8cdca629 100644 --- a/src/rpc/test/rserver.c +++ b/src/rpc/test/rserver.c @@ -17,14 +17,46 @@ #include "os.h" #include "tlog.h" #include "trpc.h" +#include "tqueue.h" #include -void processMsg(char type, void *pCont, int contLen, void *ahandle, int32_t code) { - dPrint("request is received, type:%d, contLen:%d", type, contLen); - void *rsp = rpcMallocCont(128); +int msgSize = 128; +int commit = 0; +int dataFd = -1; +void *qhandle = NULL; + +void processShellMsg(int numOfMsgs, SRpcMsg *pMsg) { + static int num = 0; + + tTrace("%d shell msgs are received", numOfMsgs); + + for (int i=0; i=0) { + if ( write(dataFd, pMsg->msg, pMsg->msgLen) <0 ) { + tPrint("failed to write data file, reason:%s", strerror(errno)); + } + } + + void *rsp = rpcMallocCont(msgSize); + rpcSendResponse(pMsg->handle, 1, rsp, msgSize); + rpcFreeCont(pMsg->msg); + pMsg++; + } + + if (commit >=2) { + num += numOfMsgs; + if ( fsync(dataFd) < 0 ) { + tPrint("failed to flush data to file, reason:%s", strerror(errno)); + } + + if (num % 10000 == 0) { + tPrint("%d request have been written into disk", num); + } + } - //rpcSendResponse(ahandle, 1, rsp, 128); +/* SRpcIpSet ipSet; ipSet.numOfIps = 1; ipSet.index = 0; @@ -32,46 +64,118 @@ void processMsg(char type, void *pCont, int contLen, void *ahandle, int32_t code ipSet.ip[0] = inet_addr("192.168.0.2"); rpcSendRedirectRsp(ahandle, &ipSet); +*/ - rpcFreeCont(pCont); } -int32_t main(int32_t argc, char *argv[]) { - taosInitLog("server.log", 100000, 10); +int retrieveAuthInfo(char *meterId, char *spi, char *encrypt, char *secret, char *ckey) { + // app shall retrieve the auth info based on meterID from DB or a data file + // demo code here only for simple demo + int ret = 0; + + if (strcmp(meterId, "michael") == 0) { + *spi = 1; + *encrypt = 0; + strcpy(secret, "mypassword"); + strcpy(ckey, "key"); + } else if (strcmp(meterId, "jeff") == 0) { + *spi = 0; + *encrypt = 0; + } else { + ret = -1; // user not there + } - dPrint("unit test for rpc module"); + return ret; +} + +void processRequestMsg(char type, void *pCont, int contLen, void *thandle, int32_t code) { + tTrace("request is received, type:%d, contLen:%d", type, contLen); + SRpcMsg rpcMsg; + rpcMsg.msg = pCont; + rpcMsg.msgLen = contLen; + rpcMsg.code = code; + rpcMsg.handle = thandle; + rpcMsg.type = type; + taosPutIntoMsgQueue(qhandle, &rpcMsg); +} +int main(int argc, char *argv[]) { SRpcInit rpcInit; + char dataName[20] = "server.data"; + memset(&rpcInit, 0, sizeof(rpcInit)); rpcInit.localIp = "0.0.0.0"; rpcInit.localPort = 7000; - rpcInit.label = "APP"; + rpcInit.label = "SER"; rpcInit.numOfThreads = 1; - rpcInit.cfp = processMsg; + rpcInit.cfp = processRequestMsg; rpcInit.sessions = 1000; - rpcInit.connType = TAOS_CONN_UDPS; rpcInit.idleTime = 2000; - rpcInit.meterId = "jefftao"; - rpcInit.secret = "password"; - rpcInit.ckey = "key"; + rpcInit.afp = retrieveAuthInfo; + + for (int i=1; i= 0) { + close(dataFd); + remove(dataName); + } return 0; } diff --git a/src/sdb/src/sdbEngine.c b/src/sdb/src/sdbEngine.c index fdf79607249f3721aa487fb0344ca0bafb2d2642..4b000a30ebd5406809dbe7d37575236d7af08162 100644 --- a/src/sdb/src/sdbEngine.c +++ b/src/sdb/src/sdbEngine.c @@ -24,8 +24,9 @@ extern char version[]; const int16_t sdbFileVersion = 0; int sdbExtConns = 0; -SIpList *pSdbIpList = NULL; -SIpList *pSdbPublicIpList = NULL; +SRpcIpSet *pSdbIpList = NULL; +SRpcIpSet *pSdbPublicIpList = NULL; +SSdbPeer * sdbPeer[SDB_MAX_PEERS]; // first slot for self #ifdef CLUSTER int sdbMaster = 0; @@ -57,6 +58,17 @@ int64_t sdbGetVersion() { return sdbVersion; }; +int32_t sdbGetRunStatus() { + if (!tsIsCluster) { + return SDB_STATUS_SERVING; + } + + if (sdbInited == NULL) { + return SDB_STATUS_OFFLINE; + } + return sdbStatus; +} + void sdbFinishCommit(void *handle) { SSdbTable *pTable = (SSdbTable *)handle; uint32_t sdbEcommit = SDB_ENDCOMMIT; diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index d39878cfcbbc08722f57fe5ec6cdd5e4aff422a2..9cca2f2db11f0cb01ff036257aaf9dc8b372a3bb 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -108,9 +108,9 @@ ELSEIF(TD_DARWIN_64) TARGET_LINK_LIBRARIES(tutil iconv pthread os) ENDIF() -IF (TD_CLUSTER) - TARGET_LINK_LIBRARIES(tutil mstorage) -ENDIF () +#IF (TD_CLUSTER) +# TARGET_LINK_LIBRARIES(tutil mstorage) +#ENDIF () diff --git a/src/util/inc/hash.h b/src/util/inc/hash.h index 14c73fb37015042f2be0dd31be89ba59374ce098..3d60abe9c69769541bc26d70c7d0b787ed2252d6 100644 --- a/src/util/inc/hash.h +++ b/src/util/inc/hash.h @@ -16,6 +16,10 @@ #ifndef TDENGINE_HASH_H #define TDENGINE_HASH_H +#ifdef __cplusplus +extern "C" { +#endif + #include "hashutil.h" #define HASH_MAX_CAPACITY (1024 * 1024 * 16) @@ -64,11 +68,12 @@ int32_t taosNumElemsInHashTable(HashObj *pObj); char *taosGetDataFromHashTable(HashObj *pObj, const char *key, uint32_t keyLen); - void taosCleanUpHashTable(void *handle); int32_t taosGetHashMaxOverflowLength(HashObj *pObj); -int32_t taosCheckHashTable(HashObj *pObj); +#ifdef __cplusplus +} +#endif #endif // TDENGINE_HASH_H diff --git a/src/util/inc/tast.h b/src/util/inc/tast.h index d7950b54f6536258d9c5c64ed54a209e04305be7..aa5cfa2d705f3eee1e5afff0f3ffd6d888b1747e 100644 --- a/src/util/inc/tast.h +++ b/src/util/inc/tast.h @@ -26,6 +26,7 @@ extern "C" { #include "taosmsg.h" #include "ttypes.h" +#include "os.h" struct tSQLBinaryExpr; struct SSchema; @@ -103,6 +104,8 @@ void tSQLBinaryExprCalcTraverse(tSQLBinaryExpr *pExprs, int32_t numOfRows, char void tSQLBinaryExprTrv(tSQLBinaryExpr *pExprs, int32_t *val, int16_t *ids); void tQueryResultClean(tQueryResultset *pRes); +uint8_t getBinaryExprOptr(SSQLToken *pToken); + #ifdef __cplusplus } #endif diff --git a/src/util/inc/textbuffer.h b/src/util/inc/textbuffer.h index 9690ce2ba8f828dca3c3a0e5ac28639fc652a52b..1f2955ba0d231c1aa5c2abefb72f4b2bc4c10c8b 100644 --- a/src/util/inc/textbuffer.h +++ b/src/util/inc/textbuffer.h @@ -124,7 +124,7 @@ typedef struct tTagSchema { typedef struct tSidSet { int32_t numOfSids; int32_t numOfSubSet; - SMeterSidExtInfo **pSids; + STableSidExtInfo **pSids; int32_t * starterPos; // position of each subgroup, generated according to SColumnModel *pColumnModel; diff --git a/src/util/inc/tglobalcfg.h b/src/util/inc/tglobalcfg.h index fa823c5a3b96017f1199534cd5b0baecc274f1f9..018f5dbcbb75b8a7ba7577f36bdf88f43c7b7e3b 100644 --- a/src/util/inc/tglobalcfg.h +++ b/src/util/inc/tglobalcfg.h @@ -58,7 +58,7 @@ extern char osName[]; extern char tsMasterIp[]; extern char tsSecondIp[]; -extern uint16_t tsMgmtVnodePort; +extern uint16_t tsMgmtDnodePort; extern uint16_t tsMgmtShellPort; extern uint16_t tsVnodeShellPort; extern uint16_t tsVnodeVnodePort; @@ -178,6 +178,7 @@ extern uint32_t taosMaxTmrCtrl; extern int tsRpcTimer; extern int tsRpcMaxTime; +extern int tsRpcMaxUdpSize; extern int tsUdpDelay; extern char version[]; extern char compatible_version[]; diff --git a/src/util/inc/tlog.h b/src/util/inc/tlog.h index 8bd4333f16c619b83e9aaba7cd52fa029213bb22..350a2c700e0dddb15f1726eb50d47117f9228603 100644 --- a/src/util/inc/tlog.h +++ b/src/util/inc/tlog.h @@ -101,7 +101,7 @@ extern uint32_t cdebugFlag; #define tscError(...) \ if (cdebugFlag & DEBUG_ERROR) { \ - tprintf("ERROR TSC ", cdebugFlag, __VA_ARGS__); \ + tprintf("ERROR TSC ", 255, __VA_ARGS__); \ } #define tscWarn(...) \ if (cdebugFlag & DEBUG_WARN) { \ diff --git a/src/util/inc/tsched.h b/src/util/inc/tsched.h index b46a0c455ab50a0b42decb7f700438507e9192b8..c9ce6b388f9374bf21abab9036c4f0707d547f14 100644 --- a/src/util/inc/tsched.h +++ b/src/util/inc/tsched.h @@ -25,7 +25,7 @@ typedef struct _sched_msg { void (*tfp)(void *, void *); - int8_t *msg; + void *msg; void *ahandle; void *thandle; } SSchedMsg; diff --git a/src/util/inc/tschemautil.h b/src/util/inc/tschemautil.h index 0031b4fa2590496ca59b02e877f755f273591d08..64bbf94f4245f7c9886dec9514ff11a101872517 100644 --- a/src/util/inc/tschemautil.h +++ b/src/util/inc/tschemautil.h @@ -42,20 +42,20 @@ struct SSchema; */ bool isValidSchema(struct SSchema *pSchema, int32_t numOfCols); -struct SSchema *tsGetSchema(SMeterMeta *pMeta); +struct SSchema *tsGetSchema(STableMeta *pMeta); -struct SSchema *tsGetTagSchema(SMeterMeta *pMeta); +struct SSchema *tsGetTagSchema(STableMeta *pMeta); -struct SSchema *tsGetColumnSchema(SMeterMeta *pMeta, int32_t startCol); +struct SSchema *tsGetColumnSchema(STableMeta *pMeta, int32_t startCol); struct SSchema tsGetTbnameColumnSchema(); -char *tsGetTagsValue(SMeterMeta *pMeta); +char *tsGetTagsValue(STableMeta *pMeta); -bool tsMeterMetaIdentical(SMeterMeta *p1, SMeterMeta *p2); +bool tsMeterMetaIdentical(STableMeta *p1, STableMeta *p2); -void extractTableName(char *meterId, char *name); +void extractTableName(char *tableId, char *name); -SSQLToken extractDBName(char *meterId, char *name); +SSQLToken extractDBName(char *tableId, char *name); void extractTableNameFromToken(SSQLToken *pToken, SSQLToken* pTable); diff --git a/src/util/inc/tsqlfunction.h b/src/util/inc/tsqlfunction.h index 2caecb6309d11065653666e786218ca87e5bcce9..b42358967213ae182574cd6a4c806fc090431af4 100644 --- a/src/util/inc/tsqlfunction.h +++ b/src/util/inc/tsqlfunction.h @@ -107,10 +107,11 @@ extern "C" { #define TOP_BOTTOM_QUERY_LIMIT 100 enum { - MASTER_SCAN = 0x0, - SUPPLEMENTARY_SCAN = 0x1, - FIRST_STAGE_MERGE = 0x10, - SECONDARY_STAGE_MERGE = 0x20, + MASTER_SCAN = 0x0u, + SUPPLEMENTARY_SCAN = 0x1u, + REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan + FIRST_STAGE_MERGE = 0x10u, + SECONDARY_STAGE_MERGE = 0x20u, }; #define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0) @@ -168,10 +169,10 @@ typedef struct SExtTagsInfo { // sql function runtime context typedef struct SQLFunctionCtx { - int32_t startOffset; - int32_t size; // number of rows - int32_t order; // asc|desc - int32_t scanFlag; // TODO merge with currentStage + int32_t startOffset; + int32_t size; // number of rows + uint32_t order; // asc|desc + uint32_t scanFlag; // TODO merge with currentStage int16_t inputType; int16_t inputBytes; @@ -304,6 +305,9 @@ void getStatistics(char *priData, char *data, int32_t size, int32_t numOfRow, in bool top_bot_datablock_filter(SQLFunctionCtx *pCtx, int32_t functionId, char *minval, char *maxval); +bool stableQueryFunctChanged(int32_t funcId); + + void resetResultInfo(SResultInfo *pResInfo); void initResultInfo(SResultInfo *pResInfo); void setResultInfoBuf(SResultInfo *pResInfo, int32_t size, bool superTable); diff --git a/src/util/inc/tsystem.h b/src/util/inc/tsystem.h index 9261261e1b860f51d731a8ba911ce07e3bcaa5a3..3ffa2312969d212f7cac79ab22a8965fed6fd736 100644 --- a/src/util/inc/tsystem.h +++ b/src/util/inc/tsystem.h @@ -23,7 +23,7 @@ extern "C" { #include #include -extern char dataDir[TSDB_FILENAME_LEN]; +extern char dataDir[]; bool taosGetSysMemory(float *memoryUsedMB); diff --git a/src/util/src/hash.c b/src/util/src/hash.c index 99643c92cc68d2964db90fdbf259b37c174bb5f9..2f643f17fa7c866a224bfe4b2ed969c485123800 100644 --- a/src/util/src/hash.c +++ b/src/util/src/hash.c @@ -340,10 +340,6 @@ static void doAddToHashTable(HashObj *pObj, SHashNode *pNode) { pEntry->num++; pObj->size++; - -// char key[512] = {0}; -// memcpy(key, pNode->key, MIN(512, pNode->keyLen)); -// pTrace("key:%s %p add to hash table", key, pNode); } int32_t taosNumElemsInHashTable(HashObj *pObj) { @@ -525,29 +521,3 @@ int32_t taosGetHashMaxOverflowLength(HashObj* pObj) { return num; } - -int32_t taosCheckHashTable(HashObj *pObj) { - for(int32_t i = 0; i < pObj->capacity; ++i) { - SHashEntry *pEntry = pObj->hashList[i]; - - SHashNode* pNode = pEntry->next; - if (pNode != NULL) { - assert(pEntry == pNode->prev1); - int32_t num = 1; - - SHashNode* pNext = pNode->next; - - while(pNext) { - assert(pNext->prev == pNode); - - pNode = pNext; - pNext = pNext->next; - num ++; - } - - assert(num == pEntry->num); - } - } - - return 0; -} diff --git a/src/util/src/textbuffer.c b/src/util/src/textbuffer.c index 860de6782be97ce83032cf60d3d2f303af18c795..8ce090d335ea8105d22d2342de9d9a3e61b4592f 100644 --- a/src/util/src/textbuffer.c +++ b/src/util/src/textbuffer.c @@ -468,8 +468,8 @@ int32_t compare_a(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1, return ret; } } else { - SSchema *pSchema = &pDescriptor->pColumnModel->pFields[colIdx]; - int32_t ret = columnValueAscendingComparator(f1, f2, pSchema->type, pSchema->bytes); + SSchemaEx *pSchema = &pDescriptor->pColumnModel->pFields[colIdx]; + int32_t ret = columnValueAscendingComparator(f1, f2, pSchema->field.type, pSchema->field.bytes); if (ret == 0) { continue; } else { @@ -500,8 +500,8 @@ int32_t compare_d(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1, return ret; } } else { - SSchema *pSchema = &pDescriptor->pColumnModel->pFields[colIdx]; - int32_t ret = columnValueAscendingComparator(f1, f2, pSchema->type, pSchema->bytes); + SSchemaEx *pSchema = &pDescriptor->pColumnModel->pFields[colIdx]; + int32_t ret = columnValueAscendingComparator(f1, f2, pSchema->field.type, pSchema->field.bytes); if (ret == 0) { continue; } else { diff --git a/src/util/src/tglobalcfg.c b/src/util/src/tglobalcfg.c index 04978d537dbb9bf61513647215f592181bc648b4..cdb8d7c8f2f93821342cf052728c0335b52090b8 100644 --- a/src/util/src/tglobalcfg.c +++ b/src/util/src/tglobalcfg.c @@ -60,7 +60,7 @@ char tsMasterIp[TSDB_IPv4ADDR_LEN] = {0}; char tsSecondIp[TSDB_IPv4ADDR_LEN] = {0}; uint16_t tsMgmtShellPort = 6030; // udp[6030-6034] tcp[6030] uint16_t tsVnodeShellPort = 6035; // udp[6035-6039] tcp[6035] -uint16_t tsMgmtVnodePort = 6040; // udp[6040-6044] tcp[6040] +uint16_t tsMgmtDnodePort = 6040; // udp[6040-6044] tcp[6040] uint16_t tsVnodeVnodePort = 6045; // tcp[6045] uint16_t tsMgmtMgmtPort = 6050; // udp, numOfVnodes fixed to 1, range udp[6050] uint16_t tsMgmtSyncPort = 6050; // tcp, range tcp[6050] @@ -199,6 +199,7 @@ int tsIsCluster = 0; int tsRpcTimer = 300; int tsRpcMaxTime = 600; // seconds; +int tsRpcMaxUdpSize = 15000; // bytes char tsMonitorDbName[TSDB_DB_NAME_LEN] = "log"; int tsMonitorInterval = 30; // seconds @@ -494,7 +495,7 @@ static void doInitGlobalConfig() { tsInitConfigOption(cfg++, "vnodeShellPort", &tsVnodeShellPort, TSDB_CFG_VTYPE_SHORT, TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT, 1, 65535, 0, TSDB_CFG_UTYPE_NONE); - tsInitConfigOption(cfg++, "mgmtVnodePort", &tsMgmtVnodePort, TSDB_CFG_VTYPE_SHORT, + tsInitConfigOption(cfg++, "mgmtVnodePort", &tsMgmtDnodePort, TSDB_CFG_VTYPE_SHORT, TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLUSTER, 1, 65535, 0, TSDB_CFG_UTYPE_NONE); tsInitConfigOption(cfg++, "vnodeVnodePort", &tsVnodeVnodePort, TSDB_CFG_VTYPE_SHORT, diff --git a/src/util/src/tinterpolation.c b/src/util/src/tinterpolation.c index 82cc52cd42ef2a4c8c40d61d40aa6e956b96a1be..cb7c8854ce914d22680db5429871857ac445f1fe 100644 --- a/src/util/src/tinterpolation.c +++ b/src/util/src/tinterpolation.c @@ -13,9 +13,6 @@ * along with this program. If not, see . */ -#include -#include - #include "os.h" #include "taosmsg.h" #include "textbuffer.h" @@ -47,7 +44,7 @@ int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t timeRange, char char** tzname = _tzname; #endif - int64_t t = (precision == TSDB_TIME_PRECISION_MILLI)?MILLISECOND_PER_SECOND:MILLISECOND_PER_SECOND*1000L; + int64_t t = (precision == TSDB_TIME_PRECISION_MILLI) ? MILLISECOND_PER_SECOND : MILLISECOND_PER_SECOND * 1000L; int64_t revStartime = (startTime / timeRange) * timeRange + timezone * t; int64_t revEndtime = revStartime + timeRange - 1; @@ -78,14 +75,14 @@ void taosInitInterpoInfo(SInterpolationInfo* pInterpoInfo, int32_t order, int64_ } // the SInterpolationInfo itself will not be released -void taosDestoryInterpoInfo(SInterpolationInfo *pInterpoInfo) { +void taosDestoryInterpoInfo(SInterpolationInfo* pInterpoInfo) { if (pInterpoInfo == NULL) { return; } - + tfree(pInterpoInfo->prevValues); tfree(pInterpoInfo->nextValues); - + tfree(pInterpoInfo->pTags); } @@ -94,7 +91,7 @@ void taosInterpoSetStartInfo(SInterpolationInfo* pInterpoInfo, int32_t numOfRawD return; } - pInterpoInfo->rowIdx = 0;//INTERPOL_IS_ASC_INTERPOL(pInterpoInfo) ? 0 : numOfRawDataInRows - 1; + pInterpoInfo->rowIdx = 0; pInterpoInfo->numOfRawDataInRows = numOfRawDataInRows; } @@ -118,14 +115,9 @@ int32_t taosGetNumOfResWithoutLimit(SInterpolationInfo* pInterpoInfo, int64_t* p if (numOfAvailRawData > 0) { int32_t finalNumOfResult = 0; -// if (pInterpoInfo->order == TSQL_SO_ASC) { - // get last timestamp, calculate the result size - int64_t lastKey = pPrimaryKeyArray[pInterpoInfo->numOfRawDataInRows - 1]; - finalNumOfResult = (int32_t)(labs(lastKey - pInterpoInfo->startTimestamp) / nInterval) + 1; -// } else { // todo error less than one!!! -// TSKEY lastKey = pPrimaryKeyArray[0]; -// finalNumOfResult = (int32_t)((pInterpoInfo->startTimestamp - lastKey) / nInterval) + 1; -// } + // get last timestamp, calculate the result size + int64_t lastKey = pPrimaryKeyArray[pInterpoInfo->numOfRawDataInRows - 1]; + finalNumOfResult = (int32_t)(labs(lastKey - pInterpoInfo->startTimestamp) / nInterval) + 1; assert(finalNumOfResult >= numOfAvailRawData); return finalNumOfResult; @@ -140,7 +132,9 @@ int32_t taosGetNumOfResWithoutLimit(SInterpolationInfo* pInterpoInfo, int64_t* p } } -bool taosHasRemainsDataForInterpolation(SInterpolationInfo* pInterpoInfo) { return taosNumOfRemainPoints(pInterpoInfo) > 0; } +bool taosHasRemainsDataForInterpolation(SInterpolationInfo* pInterpoInfo) { + return taosNumOfRemainPoints(pInterpoInfo) > 0; +} int32_t taosNumOfRemainPoints(SInterpolationInfo* pInterpoInfo) { if (pInterpoInfo->rowIdx == -1 || pInterpoInfo->numOfRawDataInRows == 0) { @@ -197,28 +191,22 @@ int taosDoLinearInterpolation(int32_t type, SPoint* point1, SPoint* point2, SPoi return 0; } -static char* getPos(char* data, int32_t bytes, int32_t order, int32_t capacity, int32_t index) { -// if (order == TSQL_SO_ASC) { - return data + index * bytes; -// } else { -// return data + (capacity - index - 1) * bytes; -// } -} +static char* getPos(char* data, int32_t bytes, int32_t index) { return data + index * bytes; } -static void setTagsValueInInterpolation(tFilePage** data, char** pTags, SColumnModel* pModel, int32_t order, int32_t start, - int32_t capacity, int32_t num) { +static void setTagsValueInInterpolation(tFilePage** data, char** pTags, SColumnModel* pModel, int32_t order, + int32_t start, int32_t capacity, int32_t num) { for (int32_t j = 0, i = start; i < pModel->numOfCols; ++i, ++j) { SSchema* pSchema = getColumnModelSchema(pModel, i); - - char* val1 = getPos(data[i]->data, pSchema->bytes, order, capacity, num); + + char* val1 = getPos(data[i]->data, pSchema->bytes, num); assignVal(val1, pTags[j], pSchema->bytes, pSchema->type); } } static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interpoType, tFilePage** data, - SColumnModel* pModel, int32_t* num, char** srcData, int64_t nInterval, int64_t* defaultVal, - int64_t currentTimestamp, int32_t capacity, int32_t numOfTags, char** pTags, - bool outOfBound) { + SColumnModel* pModel, int32_t* num, char** srcData, int64_t nInterval, + int64_t* defaultVal, int64_t currentTimestamp, int32_t capacity, int32_t numOfTags, + char** pTags, bool outOfBound) { char** prevValues = &pInterpoInfo->prevValues; char** nextValues = &pInterpoInfo->nextValues; @@ -226,7 +214,7 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp int32_t step = GET_FORWARD_DIRECTION_FACTOR(pInterpoInfo->order); - char* val = getPos(data[0]->data, TSDB_KEYSIZE, pInterpoInfo->order, capacity, *num); + char* val = getPos(data[0]->data, TSDB_KEYSIZE, *num); *(TSKEY*)val = pInterpoInfo->startTimestamp; int32_t numOfValCols = pModel->numOfCols - numOfTags; @@ -237,9 +225,9 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp if (pInterpolationData != NULL) { for (int32_t i = 1; i < numOfValCols; ++i) { SSchema* pSchema = getColumnModelSchema(pModel, i); - int16_t offset = getColumnModelOffset(pModel, i); - - char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num); + int16_t offset = getColumnModelOffset(pModel, i); + + char* val1 = getPos(data[i]->data, pSchema->bytes, *num); if (isNull(pInterpolationData + offset, pSchema->type)) { setNull(val1, pSchema->type, pSchema->bytes); @@ -250,8 +238,8 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp } else { /* no prev value yet, set the value for null */ for (int32_t i = 1; i < numOfValCols; ++i) { SSchema* pSchema = getColumnModelSchema(pModel, i); - - char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num); + + char* val1 = getPos(data[i]->data, pSchema->bytes, *num); setNull(val1, pSchema->type, pSchema->bytes); } } @@ -262,10 +250,10 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp if (*prevValues != NULL && !outOfBound) { for (int32_t i = 1; i < numOfValCols; ++i) { SSchema* pSchema = getColumnModelSchema(pModel, i); - int16_t offset = getColumnModelOffset(pModel, i); - + int16_t offset = getColumnModelOffset(pModel, i); + int16_t type = pSchema->type; - char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num); + char* val1 = getPos(data[i]->data, pSchema->bytes, *num); if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BOOL) { setNull(val1, type, pSchema->bytes); @@ -283,8 +271,8 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp } else { for (int32_t i = 1; i < numOfValCols; ++i) { SSchema* pSchema = getColumnModelSchema(pModel, i); - - char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num); + + char* val1 = getPos(data[i]->data, pSchema->bytes, *num); setNull(val1, pSchema->type, pSchema->bytes); } @@ -293,8 +281,8 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp } else { /* default value interpolation */ for (int32_t i = 1; i < numOfValCols; ++i) { SSchema* pSchema = getColumnModelSchema(pModel, i); - - char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num); + + char* val1 = getPos(data[i]->data, pSchema->bytes, *num); assignVal(val1, (char*)&defaultVal[i], pSchema->bytes, pSchema->type); } @@ -307,6 +295,20 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp (*num) += 1; } +static void initBeforeAfterDataBuf(SColumnModel* pModel, char** nextValues) { + if (*nextValues != NULL) { + return; + } + + *nextValues = calloc(1, pModel->rowSize); + for (int i = 1; i < pModel->numOfCols; i++) { + int16_t offset = getColumnModelOffset(pModel, i); + SSchema* pSchema = getColumnModelSchema(pModel, i); + + setNull(*nextValues + offset, pSchema->type, pSchema->bytes); + } +} + int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoType, tFilePage** data, int32_t numOfRawDataInRows, int32_t outputRows, int64_t nInterval, const int64_t* pPrimaryKeyArray, SColumnModel* pModel, char** srcData, int64_t* defaultVal, @@ -341,71 +343,58 @@ int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoTyp if ((pInterpoInfo->startTimestamp < currentTimestamp && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || (pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) { /* set the next value for interpolation */ - if (*nextValues == NULL) { - *nextValues = calloc(1, pModel->rowSize); - for (int i = 1; i < pModel->numOfCols; i++) { - int16_t offset = getColumnModelOffset(pModel, i); - SSchema* pSchema = getColumnModelSchema(pModel, i); - - setNull(*nextValues + offset, pSchema->type, pSchema->bytes); - } - } - + initBeforeAfterDataBuf(pModel, nextValues); + int32_t offset = pInterpoInfo->rowIdx; for (int32_t tlen = 0, i = 0; i < pModel->numOfCols - numOfTags; ++i) { SSchema* pSchema = getColumnModelSchema(pModel, i); - + memcpy(*nextValues + tlen, srcData[i] + offset * pSchema->bytes, pSchema->bytes); tlen += pSchema->bytes; } } - while (((pInterpoInfo->startTimestamp < currentTimestamp && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || - (pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) && - num < outputRows) { - doInterpoResultImpl(pInterpoInfo, interpoType, data, pModel, &num, srcData, nInterval, defaultVal, - currentTimestamp, bufSize, numOfTags, pTags, false); - } - - /* output buffer is full, abort */ - if ((num == outputRows && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || - (num < 0 && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) { - pInterpoInfo->numOfTotalInterpo += pInterpoInfo->numOfCurrentInterpo; - return outputRows; - } - - if (pInterpoInfo->startTimestamp == currentTimestamp) { - if (*prevValues == NULL) { - *prevValues = calloc(1, pModel->rowSize); - for (int i = 1; i < pModel->numOfCols; i++) { - int16_t offset = getColumnModelOffset(pModel, i); - SSchema* pSchema = getColumnModelSchema(pModel, i); - - setNull(*prevValues + offset, pSchema->type, pSchema->bytes); - } + if (((pInterpoInfo->startTimestamp < currentTimestamp && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || + (pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) && + num < outputRows) { + while (((pInterpoInfo->startTimestamp < currentTimestamp && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || + (pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) && + num < outputRows) { + doInterpoResultImpl(pInterpoInfo, interpoType, data, pModel, &num, srcData, nInterval, defaultVal, + currentTimestamp, bufSize, numOfTags, pTags, false); } + /* output buffer is full, abort */ + if ((num == outputRows && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || + (num < 0 && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) { + pInterpoInfo->numOfTotalInterpo += pInterpoInfo->numOfCurrentInterpo; + return outputRows; + } + } else { + assert(pInterpoInfo->startTimestamp == currentTimestamp); + + initBeforeAfterDataBuf(pModel, prevValues); + // assign rows to dst buffer int32_t i = 0; for (int32_t tlen = 0; i < pModel->numOfCols - numOfTags; ++i) { - int16_t offset = getColumnModelOffset(pModel, i); + int16_t offset = getColumnModelOffset(pModel, i); SSchema* pSchema = getColumnModelSchema(pModel, i); - - char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, bufSize, num); + char* val1 = getPos(data[i]->data, pSchema->bytes, num); + char* src = srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes; + if (i == 0 || - (functionIDs[i] != TSDB_FUNC_COUNT && - !isNull(srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->type)) || - (functionIDs[i] == TSDB_FUNC_COUNT && - *(int64_t*)(srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes) != 0)) { - - assignVal(val1, srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->bytes, pSchema->type); - memcpy(*prevValues + tlen, srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->bytes); - } else { // i > 0 and isNULL, do interpolation + (functionIDs[i] != TSDB_FUNC_COUNT && !isNull(src, pSchema->type)) || + (functionIDs[i] == TSDB_FUNC_COUNT && *(int64_t*)(src) != 0)) { + assignVal(val1, src, pSchema->bytes, pSchema->type); + memcpy(*prevValues + tlen, src, pSchema->bytes); + } else { // i > 0 and data is null , do interpolation if (interpoType == TSDB_INTERPO_PREV) { assignVal(val1, *prevValues + offset, pSchema->bytes, pSchema->type); } else if (interpoType == TSDB_INTERPO_LINEAR) { - // TODO: + assignVal(val1, src, pSchema->bytes, pSchema->type); + memcpy(*prevValues + tlen, src, pSchema->bytes); } else { assignVal(val1, (char*)&defaultVal[i], pSchema->bytes, pSchema->type); } @@ -416,11 +405,11 @@ int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoTyp /* set the tag value for final result */ setTagsValueInInterpolation(data, pTags, pModel, pInterpoInfo->order, pModel->numOfCols - numOfTags, bufSize, num); - } - pInterpoInfo->startTimestamp += (nInterval * step); - pInterpoInfo->rowIdx += 1; - num += 1; + pInterpoInfo->startTimestamp += (nInterval * step); + pInterpoInfo->rowIdx += 1; + num += 1; + } if ((pInterpoInfo->rowIdx >= pInterpoInfo->numOfRawDataInRows && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || (pInterpoInfo->rowIdx < 0 && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || num >= outputRows) { diff --git a/src/util/src/tresultBuf.c b/src/util/src/tresultBuf.c index 31218670acc0a95c865de27ea945d1ed5ee19e29..a7377f16575147934f68148adb2d16126288ffc9 100644 --- a/src/util/src/tresultBuf.c +++ b/src/util/src/tresultBuf.c @@ -7,8 +7,8 @@ #define DEFAULT_INTERN_BUF_SIZE 16384L -int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowSize) { - SQueryResultBuf* pResBuf = calloc(1, sizeof(SQueryResultBuf)); +int32_t createDiskbasedResultBuffer(SQueryDiskbasedResultBuf** pResultBuf, int32_t size, int32_t rowSize) { + SQueryDiskbasedResultBuf* pResBuf = calloc(1, sizeof(SQueryDiskbasedResultBuf)); pResBuf->numOfRowsPerPage = (DEFAULT_INTERN_BUF_SIZE - sizeof(tFilePage)) / rowSize; pResBuf->numOfPages = size; @@ -50,17 +50,17 @@ int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowS return TSDB_CODE_SUCCESS; } -tFilePage* getResultBufferPageById(SQueryResultBuf* pResultBuf, int32_t id) { +tFilePage* getResultBufferPageById(SQueryDiskbasedResultBuf* pResultBuf, int32_t id) { assert(id < pResultBuf->numOfPages && id >= 0); return (tFilePage*)(pResultBuf->pBuf + DEFAULT_INTERN_BUF_SIZE * id); } -int32_t getNumOfResultBufGroupId(SQueryResultBuf* pResultBuf) { return taosNumElemsInHashTable(pResultBuf->idsTable); } +int32_t getNumOfResultBufGroupId(SQueryDiskbasedResultBuf* pResultBuf) { return taosNumElemsInHashTable(pResultBuf->idsTable); } -int32_t getResBufSize(SQueryResultBuf* pResultBuf) { return pResultBuf->totalBufSize; } +int32_t getResBufSize(SQueryDiskbasedResultBuf* pResultBuf) { return pResultBuf->totalBufSize; } -static int32_t extendDiskFileSize(SQueryResultBuf* pResultBuf, int32_t numOfPages) { +static int32_t extendDiskFileSize(SQueryDiskbasedResultBuf* pResultBuf, int32_t numOfPages) { assert(pResultBuf->numOfPages * DEFAULT_INTERN_BUF_SIZE == pResultBuf->totalBufSize); int32_t ret = munmap(pResultBuf->pBuf, pResultBuf->totalBufSize); @@ -88,11 +88,11 @@ static int32_t extendDiskFileSize(SQueryResultBuf* pResultBuf, int32_t numOfPage return TSDB_CODE_SUCCESS; } -static bool noMoreAvailablePages(SQueryResultBuf* pResultBuf) { +static bool noMoreAvailablePages(SQueryDiskbasedResultBuf* pResultBuf) { return (pResultBuf->allocateId == pResultBuf->numOfPages - 1); } -static int32_t getGroupIndex(SQueryResultBuf* pResultBuf, int32_t groupId) { +static int32_t getGroupIndex(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId) { assert(pResultBuf != NULL); char* p = taosGetDataFromHashTable(pResultBuf->idsTable, (const char*)&groupId, sizeof(int32_t)); @@ -106,7 +106,7 @@ static int32_t getGroupIndex(SQueryResultBuf* pResultBuf, int32_t groupId) { return slot; } -static int32_t addNewGroupId(SQueryResultBuf* pResultBuf, int32_t groupId) { +static int32_t addNewGroupId(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId) { int32_t num = getNumOfResultBufGroupId(pResultBuf); // the num is the newest allocated group id slot if (pResultBuf->numOfAllocGroupIds <= num) { @@ -148,7 +148,7 @@ static int32_t doRegisterId(SIDList* pList, int32_t id) { return 0; } -static void registerPageId(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t pageId) { +static void registerPageId(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t pageId) { int32_t slot = getGroupIndex(pResultBuf, groupId); if (slot < 0) { slot = addNewGroupId(pResultBuf, groupId); @@ -158,7 +158,7 @@ static void registerPageId(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t doRegisterId(pList, pageId); } -tFilePage* getNewDataBuf(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t* pageId) { +tFilePage* getNewDataBuf(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t* pageId) { if (noMoreAvailablePages(pResultBuf)) { if (extendDiskFileSize(pResultBuf, pResultBuf->incStep) != TSDB_CODE_SUCCESS) { return NULL; @@ -177,9 +177,9 @@ tFilePage* getNewDataBuf(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t* return page; } -int32_t getNumOfRowsPerPage(SQueryResultBuf* pResultBuf) { return pResultBuf->numOfRowsPerPage; } +int32_t getNumOfRowsPerPage(SQueryDiskbasedResultBuf* pResultBuf) { return pResultBuf->numOfRowsPerPage; } -SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId) { +SIDList getDataBufPagesIdList(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId) { SIDList list = {0}; int32_t slot = getGroupIndex(pResultBuf, groupId); if (slot < 0) { @@ -189,7 +189,7 @@ SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId) { } } -void destroyResultBuf(SQueryResultBuf* pResultBuf) { +void destroyResultBuf(SQueryDiskbasedResultBuf* pResultBuf) { if (pResultBuf == NULL) { return; } diff --git a/src/util/src/tstring.c b/src/util/src/tstring.c index 536e8489ac9eac61be01689b58d27a482df65100..a5ab7fbf67d9124e0fa2fa85b60a2e2f70a22eb5 100644 --- a/src/util/src/tstring.c +++ b/src/util/src/tstring.c @@ -28,8 +28,8 @@ char *taosMsg[] = { "remove-table", "remove-table-rsp", - "vpeers", - "vpeers-rsp", + "create-vnode", + "create-vnode-rsp", "free-vnode", "free-vnode-rsp", "cfg-dnode", @@ -41,8 +41,8 @@ char *taosMsg[] = { "sync-rsp", "forward", "forward-rsp", - "", - "", + "drop-stable", + "drop-stable-rsp", "", "", "", diff --git a/src/vnode/detail/inc/vnode.h b/src/vnode/detail/inc/vnode.h index 481dbb19ddc0823b8be84b378fcaf8b6ae88f85e..ecd9e3f39275bb495a884442f221256e62ba5ee0 100644 --- a/src/vnode/detail/inc/vnode.h +++ b/src/vnode/detail/inc/vnode.h @@ -259,7 +259,7 @@ typedef struct SQuery { int64_t blockId; TSKEY skey; TSKEY ekey; - int64_t nAggTimeInterval; + int64_t intervalTime; int64_t slidingTime; // sliding time for sliding window query char intervalTimeUnit; // interval data type, used for daytime revise int8_t precision; diff --git a/src/vnode/detail/inc/vnodeQueryImpl.h b/src/vnode/detail/inc/vnodeQueryImpl.h index cce66786fd993b1b300a5a2abbe27e5f4eff37de..e3507d5f82e8c156ffdc5a3babae8ea5af079398 100644 --- a/src/vnode/detail/inc/vnodeQueryImpl.h +++ b/src/vnode/detail/inc/vnodeQueryImpl.h @@ -25,7 +25,7 @@ extern "C" { #include "hash.h" #include "hashutil.h" -#define GET_QINFO_ADDR(x) ((char*)(x)-offsetof(SQInfo, query)) +#define GET_QINFO_ADDR(x) ((char*)(x)-offsetof(SQInfo, query)) #define Q_STATUS_EQUAL(p, s) (((p) & (s)) != 0) /* @@ -33,10 +33,10 @@ extern "C" { * The page size should be sufficient for at least one output result or intermediate result. * Some intermediate results may be extremely large, such as top/bottom(100) query. */ -#define DEFAULT_INTERN_BUF_SIZE 16384L +#define DEFAULT_INTERN_BUF_SIZE 16384L -#define INIT_ALLOCATE_DISK_PAGES 60L -#define DEFAULT_DATA_FILE_MAPPING_PAGES 2L +#define INIT_ALLOCATE_DISK_PAGES 60L +#define DEFAULT_DATA_FILE_MAPPING_PAGES 2L #define DEFAULT_DATA_FILE_MMAP_WINDOW_SIZE (DEFAULT_DATA_FILE_MAPPING_PAGES * DEFAULT_INTERN_BUF_SIZE) #define IO_ENGINE_MMAP 0 @@ -56,7 +56,7 @@ typedef enum { * the program will call this function again, if this status is set. * used to transfer from QUERY_RESBUF_FULL */ - QUERY_NOT_COMPLETED = 0x1, + QUERY_NOT_COMPLETED = 0x1u, /* * output buffer is full, so, the next query will be employed, @@ -66,7 +66,7 @@ typedef enum { * this status is only exist in group-by clause and * diff/add/division/multiply/ query. */ - QUERY_RESBUF_FULL = 0x2, + QUERY_RESBUF_FULL = 0x2u, /* * query is over @@ -76,14 +76,13 @@ typedef enum { * 2. when the query range on timestamp is satisfied, it is also denoted as * query_compeleted */ - QUERY_COMPLETED = 0x4, + QUERY_COMPLETED = 0x4u, /* * all data has been scanned, so current search is stopped, * At last, the function will transfer this status to QUERY_COMPLETED */ - QUERY_NO_DATA_TO_CHECK = 0x8, - + QUERY_NO_DATA_TO_CHECK = 0x8u, } vnodeQueryStatus; typedef struct SPointInterpoSupporter { @@ -112,15 +111,15 @@ typedef enum { DISK_DATA_DISCARDED = 0x01, } vnodeDiskLoadStatus; -#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN) -#define IS_SUPPLEMENT_SCAN(runtime) (!IS_MASTER_SCAN(runtime)) +#define IS_MASTER_SCAN(runtime) (((runtime)->scanFlag & 1u) == MASTER_SCAN) +#define IS_SUPPLEMENT_SCAN(runtime) ((runtime)->scanFlag == SUPPLEMENTARY_SCAN) #define SET_SUPPLEMENT_SCAN_FLAG(runtime) ((runtime)->scanFlag = SUPPLEMENTARY_SCAN) #define SET_MASTER_SCAN_FLAG(runtime) ((runtime)->scanFlag = MASTER_SCAN) typedef int (*__block_search_fn_t)(char* data, int num, int64_t key, int order); static FORCE_INLINE SMeterObj* getMeterObj(void* hashHandle, int32_t sid) { - return *(SMeterObj**)taosGetDataFromHashTable(hashHandle, (const char*) &sid, sizeof(sid)); + return *(SMeterObj**)taosGetDataFromHashTable(hashHandle, (const char*)&sid, sizeof(sid)); } bool isQueryKilled(SQuery* pQuery); @@ -130,7 +129,7 @@ bool isSumAvgRateQuery(SQuery *pQuery); bool isTopBottomQuery(SQuery* pQuery); bool isFirstLastRowQuery(SQuery* pQuery); bool isTSCompQuery(SQuery* pQuery); -bool notHasQueryTimeRange(SQuery *pQuery); +bool notHasQueryTimeRange(SQuery* pQuery); bool needSupplementaryScan(SQuery* pQuery); bool onDemandLoadDatablock(SQuery* pQuery, int16_t queryRangeSet); @@ -149,16 +148,15 @@ void vnodeScanAllData(SQueryRuntimeEnv* pRuntimeEnv); int32_t vnodeQueryResultInterpolate(SQInfo* pQInfo, tFilePage** pDst, tFilePage** pDataSrc, int32_t numOfRows, int32_t* numOfInterpo); -void copyResToQueryResultBuf(SMeterQuerySupportObj* pSupporter, SQuery* pQuery); +void copyResToQueryResultBuf(STableQuerySupportObj* pSupporter, SQuery* pQuery); -void doSkipResults(SQueryRuntimeEnv* pRuntimeEnv); -void doFinalizeResult(SQueryRuntimeEnv* pRuntimeEnv); +void doSkipResults(SQueryRuntimeEnv* pRuntimeEnv); +void doFinalizeResult(SQueryRuntimeEnv* pRuntimeEnv); int64_t getNumOfResult(SQueryRuntimeEnv* pRuntimeEnv); -void forwardIntervalQueryRange(SMeterQuerySupportObj* pSupporter, SQueryRuntimeEnv* pRuntimeEnv); void forwardQueryStartPosition(SQueryRuntimeEnv* pRuntimeEnv); -bool normalizedFirstQueryRange(bool dataInDisk, bool dataInCache, SMeterQuerySupportObj* pSupporter, +bool normalizedFirstQueryRange(bool dataInDisk, bool dataInCache, STableQuerySupportObj* pSupporter, SPointInterpoSupporter* pPointInterpSupporter, int64_t* key); void pointInterpSupporterInit(SQuery* pQuery, SPointInterpoSupporter* pInterpoSupport); @@ -166,41 +164,42 @@ void pointInterpSupporterDestroy(SPointInterpoSupporter* pPointInterpSupport); void pointInterpSupporterSetData(SQInfo* pQInfo, SPointInterpoSupporter* pPointInterpSupport); int64_t loadRequiredBlockIntoMem(SQueryRuntimeEnv* pRuntimeEnv, SPositionInfo* position); -int32_t doCloseAllOpenedResults(SMeterQuerySupportObj* pSupporter); -void disableFunctForSuppleScan(SQueryRuntimeEnv* pRuntimeEnv, int32_t order); -void enableFunctForMasterScan(SQueryRuntimeEnv* pRuntimeEnv, int32_t order); +void disableFunctForSuppleScan(STableQuerySupportObj* pSupporter, int32_t order); +void enableFunctForMasterScan(SQueryRuntimeEnv* pRuntimeEnv, int32_t order); + +int32_t mergeMetersResultToOneGroups(STableQuerySupportObj* pSupporter); +void copyFromWindowResToSData(SQInfo* pQInfo, SWindowResult* result); -int32_t mergeMetersResultToOneGroups(SMeterQuerySupportObj* pSupporter); -void copyFromGroupBuf(SQInfo* pQInfo, SOutputRes* result); +SBlockInfo getBlockInfo(SQueryRuntimeEnv *pRuntimeEnv); +SBlockInfo getBlockBasicInfo(SQueryRuntimeEnv *pRuntimeEnv, void* pBlock, int32_t type); -SBlockInfo getBlockBasicInfo(SQueryRuntimeEnv* pRuntimeEnv, void* pBlock, int32_t blockType); SCacheBlock* getCacheDataBlock(SMeterObj* pMeterObj, SQueryRuntimeEnv* pRuntimeEnv, int32_t slot); -void queryOnBlock(SMeterQuerySupportObj* pSupporter, int64_t* primaryKeys, int32_t blockStatus, - SBlockInfo* pBlockBasicInfo, SMeterDataInfo* pDataHeadInfoEx, SField* pFields, - __block_search_fn_t searchFn); +void stableApplyFunctionsOnBlock(STableQuerySupportObj* pSupporter, SMeterDataInfo* pMeterDataInfo, + SBlockInfo* pBlockInfo, SField* pFields, __block_search_fn_t searchFn); -int32_t vnodeFilterQualifiedMeters(SQInfo *pQInfo, int32_t vid, tSidSet *pSidSet, SMeterDataInfo *pMeterDataInfo, - int32_t *numOfMeters, SMeterDataInfo ***pReqMeterDataInfo); -int32_t vnodeGetVnodeHeaderFileIdx(int32_t* fid, SQueryRuntimeEnv* pRuntimeEnv, int32_t order); +int32_t vnodeFilterQualifiedMeters(SQInfo* pQInfo, int32_t vid, tSidSet* pSidSet, SMeterDataInfo* pMeterDataInfo, + int32_t* numOfMeters, SMeterDataInfo*** pReqMeterDataInfo); +int32_t vnodeGetVnodeHeaderFileIndex(int32_t* fid, SQueryRuntimeEnv* pRuntimeEnv, int32_t order); int32_t createDataBlocksInfoEx(SMeterDataInfo** pMeterDataInfo, int32_t numOfMeters, SMeterDataBlockInfoEx** pDataBlockInfoEx, int32_t numOfCompBlocks, int32_t* nAllocBlocksInfoSize, int64_t addr); -void freeMeterBlockInfoEx(SMeterDataBlockInfoEx* pDataBlockInfoEx, int32_t len); +void freeMeterBlockInfoEx(SMeterDataBlockInfoEx* pDataBlockInfoEx, int32_t len); -void setExecutionContext(SMeterQuerySupportObj* pSupporter, SOutputRes* outputRes, int32_t meterIdx, int32_t groupIdx, - SMeterQueryInfo* sqinfo); -int32_t setIntervalQueryExecutionContext(SMeterQuerySupportObj* pSupporter, int32_t meterIdx, SMeterQueryInfo* sqinfo); +void setExecutionContext(STableQuerySupportObj* pSupporter, SMeterQueryInfo* pMeterQueryInfo, int32_t meterIdx, + int32_t groupIdx, TSKEY nextKey); +int32_t setAdditionalInfo(STableQuerySupportObj *pSupporter, int32_t meterIdx, SMeterQueryInfo *pMeterQueryInfo); +void doGetAlignedIntervalQueryRangeImpl(SQuery* pQuery, int64_t pKey, int64_t keyFirst, int64_t keyLast, + int64_t* actualSkey, int64_t* actualEkey, int64_t* skey, int64_t* ekey); int64_t getQueryStartPositionInCache(SQueryRuntimeEnv* pRuntimeEnv, int32_t* slot, int32_t* pos, bool ignoreQueryRange); -int64_t getNextAccessedKeyInData(SQuery* pQuery, int64_t* pPrimaryCol, SBlockInfo* pBlockInfo, int32_t blockStatus); -int32_t getDataBlocksForMeters(SMeterQuerySupportObj* pSupporter, SQuery* pQuery, int32_t numOfMeters, - const char* filePath, SMeterDataInfo** pMeterDataInfo, uint32_t* numOfBlocks); +int32_t getDataBlocksForMeters(STableQuerySupportObj* pSupporter, SQuery* pQuery, int32_t numOfMeters, + const char* filePath, SMeterDataInfo** pMeterDataInfo, uint32_t* numOfBlocks); int32_t LoadDatablockOnDemand(SCompBlock* pBlock, SField** pFields, uint8_t* blkStatus, SQueryRuntimeEnv* pRuntimeEnv, int32_t fileIdx, int32_t slotIdx, __block_search_fn_t searchFn, bool onDemand); -int32_t vnodeGetHeaderFile(SQueryRuntimeEnv *pRuntimeEnv, int32_t fileIndex); +int32_t vnodeGetHeaderFile(SQueryRuntimeEnv* pRuntimeEnv, int32_t fileIndex); /** * Create SMeterQueryInfo. @@ -210,14 +209,14 @@ int32_t vnodeGetHeaderFile(SQueryRuntimeEnv *pRuntimeEnv, int32_t fileIndex); * @param ekey * @return */ -SMeterQueryInfo* createMeterQueryInfo(SQuery* pQuery, int32_t sid, TSKEY skey, TSKEY ekey); +SMeterQueryInfo* createMeterQueryInfo(STableQuerySupportObj* pSupporter, int32_t sid, TSKEY skey, TSKEY ekey); /** * Destroy meter query info * @param pMeterQInfo * @param numOfCols */ -void destroyMeterQueryInfo(SMeterQueryInfo *pMeterQueryInfo, int32_t numOfCols); +void destroyMeterQueryInfo(SMeterQueryInfo* pMeterQueryInfo, int32_t numOfCols); /** * change the meter query info for supplement scan @@ -225,7 +224,8 @@ void destroyMeterQueryInfo(SMeterQueryInfo *pMeterQueryInfo, int32_t numOfCols); * @param skey * @param ekey */ -void changeMeterQueryInfoForSuppleQuery(SQueryResultBuf* pResultBuf, SMeterQueryInfo *pMeterQueryInfo, TSKEY skey, TSKEY ekey); +void changeMeterQueryInfoForSuppleQuery(SQuery* pQuery, SMeterQueryInfo* pMeterQueryInfo, + TSKEY skey, TSKEY ekey); /** * add the new allocated disk page to meter query info @@ -234,14 +234,8 @@ void changeMeterQueryInfoForSuppleQuery(SQueryResultBuf* pResultBuf, SMeterQuery * @param pMeterQueryInfo * @param pSupporter */ -tFilePage* addDataPageForMeterQueryInfo(SQuery* pQuery, SMeterQueryInfo *pMeterQueryInfo, SMeterQuerySupportObj *pSupporter); - -/** - * save the query range data into SMeterQueryInfo - * @param pRuntimeEnv - * @param pMeterQueryInfo - */ -void saveIntervalQueryRange(SQueryRuntimeEnv* pRuntimeEnv, SMeterQueryInfo* pMeterQueryInfo); +tFilePage* addDataPageForMeterQueryInfo(SQuery* pQuery, SMeterQueryInfo* pMeterQueryInfo, + STableQuerySupportObj* pSupporter); /** * restore the query range data from SMeterQueryInfo to runtime environment @@ -258,7 +252,7 @@ void restoreIntervalQueryRange(SQueryRuntimeEnv* pRuntimeEnv, SMeterQueryInfo* p * @param pSupporter * @param key */ -void setIntervalQueryRange(SMeterQueryInfo *pMeterQueryInfo, SMeterQuerySupportObj* pSupporter, int64_t key); +void setIntervalQueryRange(SMeterQueryInfo* pMeterQueryInfo, STableQuerySupportObj* pSupporter, int64_t key); /** * set the meter data information @@ -275,16 +269,22 @@ void vnodeCheckIfDataExists(SQueryRuntimeEnv* pRuntimeEnv, SMeterObj* pMeterObj, void displayInterResult(SData** pdata, SQuery* pQuery, int32_t numOfRows); -void vnodePrintQueryStatistics(SMeterQuerySupportObj* pSupporter); +void vnodePrintQueryStatistics(STableQuerySupportObj* pSupporter); + +void clearTimeWindowResBuf(SQueryRuntimeEnv* pRuntimeEnv, SWindowResult* pOneOutputRes); +void copyTimeWindowResBuf(SQueryRuntimeEnv* pRuntimeEnv, SWindowResult* dst, const SWindowResult* src); + +int32_t initWindowResInfo(SWindowResInfo* pWindowResInfo, SQueryRuntimeEnv* pRuntimeEnv, int32_t size, + int32_t threshold, int16_t type); -void clearGroupResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes *pOneOutputRes); -void copyGroupResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes* dst, const SOutputRes* src); +void cleanupTimeWindowInfo(SWindowResInfo* pWindowResInfo, SQueryRuntimeEnv* pRuntimeEnv); +void resetTimeWindowInfo(SQueryRuntimeEnv* pRuntimeEnv, SWindowResInfo* pWindowResInfo); +void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num); -void resetSlidingWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SSlidingWindowInfo* pSlidingWindowInfo); -void clearCompletedSlidingWindows(SQueryRuntimeEnv* pRuntimeEnv); -int32_t numOfClosedSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo); -void closeSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo, int32_t slot); -void closeAllSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo); +void clearClosedTimeWindow(SQueryRuntimeEnv* pRuntimeEnv); +int32_t numOfClosedTimeWindow(SWindowResInfo* pWindowResInfo); +void closeTimeWindow(SWindowResInfo* pWindowResInfo, int32_t slot); +void closeAllTimeWindow(SWindowResInfo* pWindowResInfo); #ifdef __cplusplus } diff --git a/src/vnode/detail/inc/vnodeRead.h b/src/vnode/detail/inc/vnodeRead.h index 2765ff76fc5f120ca7f8ccc2214196b54dfd8507..2758cfe1d9610257c7ddf0658874a7ee57511fc0 100644 --- a/src/vnode/detail/inc/vnodeRead.h +++ b/src/vnode/detail/inc/vnodeRead.h @@ -86,16 +86,26 @@ typedef struct SQueryCostSummary { } SQueryCostSummary; typedef struct SPosInfo { - int64_t pageId; - int32_t rowId; + int16_t pageId; + int16_t rowId; } SPosInfo; -typedef struct SOutputRes { +typedef struct STimeWindow { + TSKEY skey; + TSKEY ekey; +} STimeWindow; + +typedef struct SWindowStatus { + bool closed; +} SWindowStatus; + +typedef struct SWindowResult { uint16_t numOfRows; - int32_t nAlloc; - SPosInfo pos; - SResultInfo* resultInfo; -} SOutputRes; + SPosInfo pos; // Position of current result in disk-based output buffer + SResultInfo* resultInfo; // For each result column, there is a resultInfo + STimeWindow window; // The time window that current result covers. + SWindowStatus status; +} SWindowResult; /* * header files info, avoid to iterate the directory, the data is acquired @@ -118,19 +128,8 @@ typedef struct SQueryFilesInfo { char dbFilePathPrefix[PATH_MAX]; } SQueryFilesInfo; -typedef struct STimeWindow { - TSKEY skey; - TSKEY ekey; -} STimeWindow; - -typedef struct SWindowStatus { - STimeWindow window; - bool closed; -} SWindowStatus; - -typedef struct SSlidingWindowInfo { - SOutputRes* pResult; // reference to SQuerySupporter->pResult - SWindowStatus* pStatus; // current query window closed or not? +typedef struct SWindowResInfo { + SWindowResult* pResult; // reference to SQuerySupporter->pResult void* hashList; // hash list for quick access int16_t type; // data type for hash key int32_t capacity; // max capacity @@ -140,14 +139,14 @@ typedef struct SSlidingWindowInfo { int64_t startTime; // start time of the first time window for sliding query int64_t prevSKey; // previous (not completed) sliding window start key int64_t threshold; // threshold for return completed results. -} SSlidingWindowInfo; +} SWindowResInfo; typedef struct SQueryRuntimeEnv { SPositionInfo startPos; /* the start position, used for secondary/third iteration */ SPositionInfo endPos; /* the last access position in query, served as the start pos of reversed order query */ SPositionInfo nextPos; /* start position of the next scan */ SData* colDataBuffer[TSDB_MAX_COLUMNS]; - SResultInfo* resultInfo; + SResultInfo* resultInfo; // todo refactor to merge with SWindowResInfo uint8_t blockStatus; // Indicate if data block is loaded, the block is first/last/internal block int32_t unzipBufSize; SData* primaryColBuffer; @@ -161,28 +160,25 @@ typedef struct SQueryRuntimeEnv { SQueryFilesInfo vnodeFileInfo; int16_t numOfRowsPerPage; int16_t offset[TSDB_MAX_COLUMNS]; - int16_t scanFlag; // denotes reversed scan of data or not + uint16_t scanFlag; // denotes reversed scan of data or not SInterpolationInfo interpoInfo; SData** pInterpoBuf; - SSlidingWindowInfo swindowResInfo; + SWindowResInfo windowResInfo; STSBuf* pTSBuf; STSCursor cur; SQueryCostSummary summary; - - STimeWindow intervalWindow; // the complete time window, not affected by the actual data distribution + bool stableQuery; // is super table query or not + SQueryDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file /* * Temporarily hold the in-memory cache block info during scan cache blocks - * Here we do not use the cacheblock info from pMeterObj, simple because it may change anytime - * during the query by the subumit/insert handling threads. + * Here we do not use the cache block info from pMeterObj, simple because it may change anytime + * during the query by the submit/insert handling threads. * So we keep a copy of the support structure as well as the cache block data itself. */ SCacheBlock cacheBlock; - - SQueryResultBuf* pResultBuf; - bool stableQuery; // is super table query or not } SQueryRuntimeEnv; /* intermediate pos during multimeter query involves interval */ @@ -191,14 +187,12 @@ typedef struct SMeterQueryInfo { int64_t skey; int64_t ekey; int32_t numOfRes; - int32_t reverseIndex; // reversed output indicator, start from (numOfRes-1) - int16_t reverseFillRes; // denote if reverse fill the results in supplementary scan required or not int16_t queryRangeSet; // denote if the query range is set, only available for interval query - int16_t lastResRows; int64_t tag; STSCursor cur; - SResultInfo* resultInfo; int32_t sid; // for retrieve the page id list + + SWindowResInfo windowResInfo; } SMeterQueryInfo; typedef struct SMeterDataInfo { @@ -212,7 +206,7 @@ typedef struct SMeterDataInfo { SMeterQueryInfo* pMeterQInfo; } SMeterDataInfo; -typedef struct SMeterQuerySupportObj { +typedef struct STableQuerySupportObj { void* pMetersHashTable; // meter table hash list SMeterSidExtInfo** pMeterSidExtInfo; @@ -225,13 +219,11 @@ typedef struct SMeterQuerySupportObj { * rows may be generated by a specific subgroup. When query on all subgroups is executed, * the result is copy to output buffer. This attribution is not used during single meter query processing. */ - SOutputRes* pResult; SQueryRuntimeEnv runtimeEnv; int64_t rawSKey; int64_t rawEKey; int32_t subgroupIdx; int32_t offset; /* offset in group result set of subgroup */ - tSidSet* pSidSet; /* @@ -247,7 +239,7 @@ typedef struct SMeterQuerySupportObj { SMeterDataInfo* pMeterDataInfo; TSKEY* tsList; -} SMeterQuerySupportObj; +} STableQuerySupportObj; typedef struct _qinfo { uint64_t signature; @@ -273,18 +265,18 @@ typedef struct _qinfo { SMeterObj* pObj; sem_t dataReady; - SMeterQuerySupportObj* pMeterQuerySupporter; + STableQuerySupportObj* pTableQuerySupporter; int (*fp)(SMeterObj*, SQuery*); } SQInfo; -int32_t vnodeQuerySingleMeterPrepare(SQInfo* pQInfo, SMeterObj* pMeterObj, SMeterQuerySupportObj* pSMultiMeterObj, +int32_t vnodeQueryTablePrepare(SQInfo* pQInfo, SMeterObj* pMeterObj, STableQuerySupportObj* pSMultiMeterObj, void* param); void vnodeQueryFreeQInfoEx(SQInfo* pQInfo); bool vnodeParametersSafetyCheck(SQuery* pQuery); -int32_t vnodeMultiMeterQueryPrepare(SQInfo* pQInfo, SQuery* pQuery, void* param); +int32_t vnodeSTableQueryPrepare(SQInfo* pQInfo, SQuery* pQuery, void* param); /** * decrease the numofQuery of each table that is queried, enable the diff --git a/src/vnode/detail/src/vnodeQueryImpl.c b/src/vnode/detail/src/vnodeQueryImpl.c index 104e4b859e3009fd3741957b32583162a3f32ceb..f761205719c8020b871448942461b2df2dc265d9 100644 --- a/src/vnode/detail/src/vnodeQueryImpl.c +++ b/src/vnode/detail/src/vnodeQueryImpl.c @@ -13,9 +13,9 @@ * along with this program. If not, see . */ -#include "os.h" #include "hash.h" #include "hashutil.h" +#include "os.h" #include "taosmsg.h" #include "textbuffer.h" #include "ttime.h" @@ -55,7 +55,7 @@ static int32_t readDataFromDiskFile(int fd, SQInfo *pQInfo, SQueryFilesInfo *pQu static void vnodeInitLoadCompBlockInfo(SLoadCompBlockInfo *pCompBlockLoadInfo); static int32_t moveToNextBlock(SQueryRuntimeEnv *pRuntimeEnv, int32_t step, __block_search_fn_t searchFn, bool loadData); -static int32_t doMergeMetersResultsToGroupRes(SMeterQuerySupportObj *pSupporter, SQuery *pQuery, +static int32_t doMergeMetersResultsToGroupRes(STableQuerySupportObj *pSupporter, SQuery *pQuery, SQueryRuntimeEnv *pRuntimeEnv, SMeterDataInfo *pMeterDataInfo, int32_t start, int32_t end); @@ -65,25 +65,22 @@ static TSKEY getTimestampInDiskBlock(SQueryRuntimeEnv *pRuntimeEnv, int32_t inde static void savePointPosition(SPositionInfo *position, int32_t fileId, int32_t slot, int32_t pos); static int32_t getNextDataFileCompInfo(SQueryRuntimeEnv *pRuntimeEnv, SMeterObj *pMeterObj, int32_t step); -static void setGroupOutputBuffer(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes *pResult); - -static void getAlignedIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY keyInData, TSKEY skey, TSKEY ekey); - -static int32_t saveResult(SMeterQuerySupportObj *pSupporter, SMeterQueryInfo *pMeterQueryInfo, int32_t numOfResult); -static void applyIntervalQueryOnBlock(SMeterQuerySupportObj *pSupporter, SMeterDataInfo *pMeterDataInfo, - SBlockInfo *pBlockInfo, int32_t blockStatus, SField *pFields, - __block_search_fn_t searchFn); +static void setWindowResOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pResult); -static void resetMergeResultBuf(SQuery *pQuery, SQLFunctionCtx *pCtx); -static int32_t flushFromResultBuf(SMeterQuerySupportObj *pSupporter, const SQuery *pQuery, +static void resetMergeResultBuf(SQuery *pQuery, SQLFunctionCtx *pCtx, SResultInfo *pResultInfo); +static int32_t flushFromResultBuf(STableQuerySupportObj *pSupporter, const SQuery *pQuery, const SQueryRuntimeEnv *pRuntimeEnv); -static void validateTimestampForSupplementResult(SQueryRuntimeEnv *pRuntimeEnv, int64_t numOfIncrementRes); static void getBasicCacheInfoSnapshot(SQuery *pQuery, SCacheInfo *pCacheInfo, int32_t vid); static TSKEY getQueryPositionForCacheInvalid(SQueryRuntimeEnv *pRuntimeEnv, __block_search_fn_t searchFn); static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t functionId); -static void doGetAlignedIntervalQueryRangeImpl(SQuery *pQuery, int64_t pKey, int64_t keyFirst, int64_t keyLast, - int64_t *actualSkey, int64_t *actualEkey, int64_t *skey, int64_t *ekey); -static void getNextLogicalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow* pTimeWindow); +static void getNextTimeWindow(SQuery *pQuery, STimeWindow *pTimeWindow); + +static int32_t getGroupResultId(int32_t groupIndex) { + int32_t base = 200000; + return base + (groupIndex * 10000); +} + +static FORCE_INLINE bool isIntervalQuery(SQuery *pQuery) { return pQuery->intervalTime > 0; } // check the offset value integrity static FORCE_INLINE int32_t validateHeaderOffsetSegment(SQInfo *pQInfo, char *filePath, int32_t vid, char *data, @@ -248,7 +245,7 @@ static void vnodeInitLoadCompBlockInfo(SLoadCompBlockInfo *pCompBlockLoadInfo) { } static int32_t vnodeIsDatablockLoaded(SQueryRuntimeEnv *pRuntimeEnv, SMeterObj *pMeterObj, int32_t fileIndex, - bool loadPrimaryTS) { + bool loadTS) { SQuery * pQuery = pRuntimeEnv->pQuery; SLoadDataBlockInfo *pLoadInfo = &pRuntimeEnv->loadBlockInfo; @@ -256,7 +253,7 @@ static int32_t vnodeIsDatablockLoaded(SQueryRuntimeEnv *pRuntimeEnv, SMeterObj * if (pLoadInfo->fileId == pQuery->fileId && pLoadInfo->slotIdx == pQuery->slot && pQuery->slot != -1 && pLoadInfo->sid == pMeterObj->sid && pLoadInfo->fileListIndex == fileIndex) { // previous load operation does not load the primary timestamp column, we only need to load the timestamp column - if (pLoadInfo->tsLoaded == false && pLoadInfo->tsLoaded != loadPrimaryTS) { + if (pLoadInfo->tsLoaded == false && pLoadInfo->tsLoaded != loadTS) { return DISK_BLOCK_LOAD_TS; } else { return DISK_BLOCK_NO_NEED_TO_LOAD; @@ -402,7 +399,6 @@ static void doCloseQueryFiles(SQueryFilesInfo *pVnodeFileInfo) { assert(pVnodeFileInfo->current < pVnodeFileInfo->numOfFiles && pVnodeFileInfo->current >= 0); pVnodeFileInfo->headerFileSize = -1; - doCloseQueryFileInfoFD(pVnodeFileInfo); } @@ -461,11 +457,12 @@ static int vnodeGetCompBlockInfo(SMeterObj *pMeterObj, SQueryRuntimeEnv *pRuntim SHeaderFileInfo *pHeadeFileInfo = &pRuntimeEnv->vnodeFileInfo.pFileInfo[fileIndex]; int64_t st = taosGetTimestampUs(); - - if (vnodeIsCompBlockInfoLoaded(pRuntimeEnv, pMeterObj, fileIndex)) { + + // if the corresponding data/header files are already closed, re-open them here + if (vnodeIsCompBlockInfoLoaded(pRuntimeEnv, pMeterObj, fileIndex) && + pRuntimeEnv->vnodeFileInfo.current == fileIndex) { dTrace("QInfo:%p vid:%d sid:%d id:%s, fileId:%d compBlock info is loaded, not reload", GET_QINFO_ADDR(pQuery), pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pHeadeFileInfo->fileID); - return pQuery->numOfBlocks; } @@ -586,9 +583,9 @@ static void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, int64_t StartQue char *primaryColumnData, int32_t size, int32_t functionId, SField *pField, bool hasNull, int32_t blockStatus, void *param, int32_t scanFlag); -void createQueryResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes *pResultRow, bool isSTableQuery, SPosInfo *posInfo); +void createQueryResultInfo(SQuery *pQuery, SWindowResult *pResultRow, bool isSTableQuery, SPosInfo *posInfo); -static void destroyGroupResultBuf(SOutputRes *pOneOutputRes, int32_t nOutputCols); +static void destroyTimeWindowRes(SWindowResult *pOneOutputRes, int32_t nOutputCols); static int32_t binarySearchForBlockImpl(SCompBlock *pBlock, int32_t numOfBlocks, TSKEY skey, int32_t order) { int32_t firstSlot = 0; @@ -921,7 +918,7 @@ static int32_t loadDataBlockIntoMem(SCompBlock *pBlock, SField **pField, SQueryR int32_t ret = 0; /* the first round always be 1, the secondary round is determined by queried function */ - int32_t round = pRuntimeEnv->scanFlag; + int32_t round = (IS_MASTER_SCAN(pRuntimeEnv)) ? 0 : 1; while (j < pBlock->numOfCols && i < pQuery->numOfCols) { if ((*pField)[j].colId < pQuery->colList[i].data.colId) { @@ -988,7 +985,6 @@ static int32_t loadDataBlockIntoMem(SCompBlock *pBlock, SField **pField, SQueryR return ret; } -// todo ignore the blockType, pass the pQuery into this function SBlockInfo getBlockBasicInfo(SQueryRuntimeEnv *pRuntimeEnv, void *pBlock, int32_t blockType) { SBlockInfo blockInfo = {0}; if (IS_FILE_BLOCK(blockType)) { @@ -1010,22 +1006,6 @@ SBlockInfo getBlockBasicInfo(SQueryRuntimeEnv *pRuntimeEnv, void *pBlock, int32_ return blockInfo; } -static bool checkQueryRangeAgainstNextBlock(SBlockInfo *pBlockInfo, SQueryRuntimeEnv *pRuntimeEnv) { - SQuery *pQuery = pRuntimeEnv->pQuery; - - if ((QUERY_IS_ASC_QUERY(pQuery) && pBlockInfo->keyFirst > pQuery->ekey) || - (!QUERY_IS_ASC_QUERY(pQuery) && pBlockInfo->keyLast < pQuery->ekey)) { - int32_t pos = QUERY_IS_ASC_QUERY(pQuery) ? 0 : pBlockInfo->size - 1; - - savePointPosition(&pRuntimeEnv->nextPos, pQuery->fileId, pQuery->slot, pos); - setQueryStatus(pQuery, QUERY_COMPLETED); - - return false; - } - - return true; -} - /** * * @param pQuery @@ -1033,29 +1013,34 @@ static bool checkQueryRangeAgainstNextBlock(SBlockInfo *pBlockInfo, SQueryRuntim * @param forwardStep * @return TRUE means query not completed, FALSE means query is completed */ -static bool queryCompleteInBlock(SQuery *pQuery, SBlockInfo *pBlockInfo, int32_t forwardStep) { - if (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)) { - // assert(pQuery->checkBufferInLoop == 1 && pQuery->over == QUERY_RESBUF_FULL && pQuery->pointsOffset == 0); +static bool queryPausedInCurrentBlock(SQuery *pQuery, SBlockInfo *pBlockInfo, int32_t forwardStep) { + // current query completed + if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { + setQueryStatus(pQuery, QUERY_COMPLETED); + return true; + } + // output buffer is full, pause current query + if (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)) { assert((QUERY_IS_ASC_QUERY(pQuery) && forwardStep + pQuery->pos <= pBlockInfo->size) || (!QUERY_IS_ASC_QUERY(pQuery) && pQuery->pos - forwardStep + 1 >= 0)); - // current query completed - if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { - setQueryStatus(pQuery, QUERY_COMPLETED); - } + return true; + } + if (Q_STATUS_EQUAL(pQuery->over, QUERY_COMPLETED)) { return true; - } else { // query completed - if ((pQuery->ekey <= pBlockInfo->keyLast && QUERY_IS_ASC_QUERY(pQuery)) || - (pQuery->ekey >= pBlockInfo->keyFirst && !QUERY_IS_ASC_QUERY(pQuery))) { - setQueryStatus(pQuery, QUERY_COMPLETED); - return true; - } + } - return false; + // query completed + if ((pQuery->ekey <= pBlockInfo->keyLast && QUERY_IS_ASC_QUERY(pQuery)) || + (pQuery->ekey >= pBlockInfo->keyFirst && !QUERY_IS_ASC_QUERY(pQuery))) { + setQueryStatus(pQuery, QUERY_COMPLETED); + return true; } + + return false; } /** @@ -1072,7 +1057,7 @@ void savePointPosition(SPositionInfo *position, int32_t fileId, int32_t slot, in position->pos = pos; } -bool isCacheBlockValid(SQuery *pQuery, SCacheBlock *pBlock, SMeterObj *pMeterObj) { +bool isCacheBlockValid(SQuery *pQuery, SCacheBlock *pBlock, SMeterObj *pMeterObj, int32_t slot) { if (pMeterObj != pBlock->pMeterObj || pBlock->blockId > pQuery->blockId) { SMeterObj *pNewMeterObj = pBlock->pMeterObj; char * id = (pNewMeterObj != NULL) ? pNewMeterObj->meterId : NULL; @@ -1096,11 +1081,19 @@ bool isCacheBlockValid(SQuery *pQuery, SCacheBlock *pBlock, SMeterObj *pMeterObj dWarn( "QInfo:%p vid:%d sid:%d id:%s, cache block is empty. slot:%d first:%d, last:%d, numOfBlocks:%d," "allocated but not write data yet.", - GET_QINFO_ADDR(pQuery), pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->slot, pQuery->firstSlot, + GET_QINFO_ADDR(pQuery), pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, slot, pQuery->firstSlot, pQuery->currentSlot, pQuery->numOfBlocks); return false; } + + SCacheInfo* pCacheInfo = (SCacheInfo*) pMeterObj->pCache; + if (pCacheInfo->commitPoint == pMeterObj->pointsPerBlock && pQuery->slot == pCacheInfo->currentSlot) { + dWarn("QInfo:%p vid:%d sid:%d id:%s, cache block is committed, ignore. slot:%d first:%d, last:%d, numOfBlocks:%d", + GET_QINFO_ADDR(pQuery), pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, slot, pQuery->firstSlot, + pQuery->currentSlot, pQuery->numOfBlocks); + return false; + } return true; } @@ -1114,6 +1107,7 @@ SCacheBlock *getCacheDataBlock(SMeterObj *pMeterObj, SQueryRuntimeEnv *pRuntimeE return NULL; } + vnodeFreeFields(pQuery); getBasicCacheInfoSnapshot(pQuery, pCacheInfo, pMeterObj->vnode); SCacheBlock *pBlock = pCacheInfo->cacheBlocks[slot]; @@ -1131,7 +1125,7 @@ SCacheBlock *getCacheDataBlock(SMeterObj *pMeterObj, SQueryRuntimeEnv *pRuntimeE } // block is empty or block does not belongs to current table, return NULL value - if (!isCacheBlockValid(pQuery, pBlock, pMeterObj)) { + if (!isCacheBlockValid(pQuery, pBlock, pMeterObj, slot)) { return NULL; } @@ -1217,7 +1211,7 @@ SCacheBlock *getCacheDataBlock(SMeterObj *pMeterObj, SQueryRuntimeEnv *pRuntimeE pQuery->fileId = -1; pQuery->slot = slot; - if (!isCacheBlockValid(pQuery, pNewBlock, pMeterObj)) { + if (!isCacheBlockValid(pQuery, pNewBlock, pMeterObj, slot)) { return NULL; } @@ -1252,6 +1246,16 @@ static void *getGenericDataBlock(SMeterObj *pMeterObj, SQueryRuntimeEnv *pRuntim } } +SBlockInfo getBlockInfo(SQueryRuntimeEnv *pRuntimeEnv) { + SQuery *pQuery = pRuntimeEnv->pQuery; + + void *pBlock = getGenericDataBlock(pRuntimeEnv->pMeterObj, pRuntimeEnv, pQuery->slot); + assert(pBlock != NULL); + + int32_t blockType = IS_DISK_DATA_BLOCK(pQuery) ? BLK_FILE_BLOCK : BLK_CACHE_BLOCK; + return getBlockBasicInfo(pRuntimeEnv, pBlock, blockType); +} + static int32_t getFileIdFromKey(int32_t vid, TSKEY key) { SVnodeObj *pVnode = &vnodeList[vid]; int64_t delta = (int64_t)pVnode->cfg.daysPerFile * tsMsPerDay[(uint8_t)pVnode->cfg.precision]; @@ -1438,403 +1442,737 @@ static char *getDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, SArithmeticSupport *sa return dataBlock; } -/** - * - * @param pRuntimeEnv - * @param forwardStep - * @param primaryKeyCol - * @param pFields - * @param isDiskFileBlock - * @return the incremental number of output value, so it maybe 0 for fixed number of query, - * such as count/min/max etc. - */ -static int32_t blockwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t forwardStep, TSKEY *primaryKeyCol, - SField *pFields, SBlockInfo *pBlockInfo) { - SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; - SQuery * pQuery = pRuntimeEnv->pQuery; - - bool isDiskFileBlock = IS_FILE_BLOCK(pRuntimeEnv->blockStatus); - int64_t prevNumOfRes = getNumOfResult(pRuntimeEnv); - - SArithmeticSupport *sasArray = calloc((size_t)pQuery->numOfOutputCols, sizeof(SArithmeticSupport)); +static SWindowResult *getWindowResult(SWindowResInfo *pWindowResInfo, int32_t slot) { + assert(pWindowResInfo != NULL && slot >= 0 && slot < pWindowResInfo->size); + return &pWindowResInfo->pResult[slot]; +} - for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { - int32_t functionId = pQuery->pSelectExpr[k].pBase.functionId; +static bool isWindowResClosed(SWindowResInfo *pWindowResInfo, int32_t slot) { + return (getWindowResult(pWindowResInfo, slot)->status.closed == true); +} - SField dummyField = {0}; +static int32_t curTimeWindow(SWindowResInfo *pWindowResInfo) { + assert(pWindowResInfo->curIndex >= 0 && pWindowResInfo->curIndex < pWindowResInfo->size); + return pWindowResInfo->curIndex; +} - bool hasNull = hasNullVal(pQuery, k, pBlockInfo, pFields, isDiskFileBlock); - char *dataBlock = getDataBlocks(pRuntimeEnv, &sasArray[k], k, forwardStep); +static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo, char *pData, + int16_t bytes) { + SQuery *pQuery = pRuntimeEnv->pQuery; - SField *tpField = NULL; + int32_t *p1 = (int32_t *)taosGetDataFromHashTable(pWindowResInfo->hashList, pData, bytes); + if (p1 != NULL) { + pWindowResInfo->curIndex = *p1; + } else { // more than the capacity, reallocate the resources + if (pWindowResInfo->size >= pWindowResInfo->capacity) { + int64_t newCap = pWindowResInfo->capacity * 2; - if (pFields != NULL) { - tpField = getFieldInfo(pQuery, pBlockInfo, pFields, k); - /* - * Field info not exist, the required column is not present in current block, - * so all data must be null value in current block. - */ - if (tpField == NULL) { - tpField = &dummyField; - tpField->numOfNullPoints = (int32_t)forwardStep; + char *t = realloc(pWindowResInfo->pResult, newCap * sizeof(SWindowResult)); + if (t != NULL) { + pWindowResInfo->pResult = (SWindowResult *)t; + memset(&pWindowResInfo->pResult[pWindowResInfo->capacity], 0, sizeof(SWindowResult) * pWindowResInfo->capacity); + } else { + // todo } - } - TSKEY ts = QUERY_IS_ASC_QUERY(pQuery) ? pRuntimeEnv->intervalWindow.skey : pRuntimeEnv->intervalWindow.ekey; - setExecParams(pQuery, &pCtx[k], ts, dataBlock, (char *)primaryKeyCol, forwardStep, functionId, tpField, hasNull, - pRuntimeEnv->blockStatus, &sasArray[k], pRuntimeEnv->scanFlag); - } + for (int32_t i = pWindowResInfo->capacity; i < newCap; ++i) { + SPosInfo pos = {-1, -1}; + createQueryResultInfo(pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, &pos); + } - /* - * the sqlfunctionCtx parameters should be set done before all functions are invoked, - * since the selectivity + tag_prj query needs all parameters been set done. - * tag_prj function are changed to be TSDB_FUNC_TAG_DUMMY - */ - for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { - int32_t functionId = pQuery->pSelectExpr[k].pBase.functionId; - if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) { - aAggs[functionId].xFunction(&pCtx[k]); + pWindowResInfo->capacity = newCap; } - } - int64_t numOfIncrementRes = getNumOfResult(pRuntimeEnv) - prevNumOfRes; - validateTimestampForSupplementResult(pRuntimeEnv, numOfIncrementRes); - - tfree(sasArray); + // add a new result set for a new group + pWindowResInfo->curIndex = pWindowResInfo->size++; + taosAddToHashTable(pWindowResInfo->hashList, pData, bytes, (char *)&pWindowResInfo->curIndex, sizeof(int32_t)); + } - return (int32_t)numOfIncrementRes; + return getWindowResult(pWindowResInfo, pWindowResInfo->curIndex); } -/** - * if sfields is null - * 1. count(*)/spread(ts) is invoked - * 2. this column does not exists - * - * first filter the data block according to the value filter condition, then, if the top/bottom query applied, - * invoke the filter function to decide if the data block need to be accessed or not. - * TODO handle the whole data block is NULL situation - * @param pQuery - * @param pField - * @return - */ -static bool needToLoadDataBlock(SQuery *pQuery, SField *pField, SQLFunctionCtx *pCtx, int32_t numOfTotalPoints) { - if (pField == NULL) { - return false; // no need to load data - } +// get the correct time window according to the handled timestamp +static STimeWindow getActiveTimeWindow(SWindowResInfo *pWindowResInfo, int64_t ts, SQuery *pQuery) { + STimeWindow w = {0}; - for (int32_t k = 0; k < pQuery->numOfFilterCols; ++k) { - SSingleColumnFilterInfo *pFilterInfo = &pQuery->pFilterInfo[k]; - int32_t colIndex = pFilterInfo->info.colIdx; + if (pWindowResInfo->curIndex == -1) { // the first window, from the previous stored value + w.skey = pWindowResInfo->prevSKey; + w.ekey = w.skey + pQuery->intervalTime - 1; + } else { + int32_t slot = curTimeWindow(pWindowResInfo); + w = getWindowResult(pWindowResInfo, slot)->window; + } - // this column not valid in current data block - if (colIndex < 0 || pField[colIndex].colId != pFilterInfo->info.data.colId) { - continue; - } + if (w.skey > ts || w.ekey < ts) { + int64_t st = w.skey; - // not support pre-filter operation on binary/nchar data type - if (!vnodeSupportPrefilter(pFilterInfo->info.data.type)) { - continue; + if (st > ts) { + st -= ((st - ts + pQuery->slidingTime - 1) / pQuery->slidingTime) * pQuery->slidingTime; } - // all points in current column are NULL, no need to check its boundary value - if (pField[colIndex].numOfNullPoints == numOfTotalPoints) { - continue; + int64_t et = st + pQuery->intervalTime - 1; + if (et < ts) { + st += ((ts - et + pQuery->slidingTime - 1) / pQuery->slidingTime) * pQuery->slidingTime; } - if (pFilterInfo->info.data.type == TSDB_DATA_TYPE_FLOAT) { - float minval = *(double *)(&pField[colIndex].min); - float maxval = *(double *)(&pField[colIndex].max); - - for (int32_t i = 0; i < pFilterInfo->numOfFilters; ++i) { - if (pFilterInfo->pFilters[i].fp(&pFilterInfo->pFilters[i], (char *)&minval, (char *)&maxval)) { - return true; - } - } - } else { - for (int32_t i = 0; i < pFilterInfo->numOfFilters; ++i) { - if (pFilterInfo->pFilters[i].fp(&pFilterInfo->pFilters[i], (char *)&pField[colIndex].min, - (char *)&pField[colIndex].max)) { - return true; - } - } - } + w.skey = st; + w.ekey = w.skey + pQuery->intervalTime - 1; } - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - int32_t functId = pQuery->pSelectExpr[i].pBase.functionId; - if (functId == TSDB_FUNC_TOP || functId == TSDB_FUNC_BOTTOM) { - return top_bot_datablock_filter(&pCtx[i], functId, (char *)&pField[i].min, (char *)&pField[i].max); - } + /* + * query border check, skey should not be bounded by the query time range, since the value skey will + * be used as the time window index value. So we only change ekey of time window accordingly. + */ + if (w.ekey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) { + w.ekey = pQuery->ekey; } - return true; -} + assert(ts >= w.skey && ts <= w.ekey && w.skey != 0); -static SOutputRes *doSetSlidingWindowFromKey(SSlidingWindowInfo *pSlidingWindowInfo, char *pData, int16_t bytes, - SWindowStatus **pStatus) { - int32_t p = -1; + return w; +} - int32_t *p1 = (int32_t *)taosGetDataFromHashTable(pSlidingWindowInfo->hashList, pData, bytes); - if (p1 != NULL) { - p = *p1; +static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SQueryDiskbasedResultBuf *pResultBuf, int32_t sid, + int32_t numOfRowsPerPage) { + if (pWindowRes->pos.pageId != -1) { + return 0; + } - pSlidingWindowInfo->curIndex = p; - if (pStatus != NULL) { - *pStatus = &pSlidingWindowInfo->pStatus[p]; - } - } else { // more than the capacity, reallocate the resources - if (pSlidingWindowInfo->size >= pSlidingWindowInfo->capacity) { - int64_t newCap = pSlidingWindowInfo->capacity * 2; + tFilePage *pData = NULL; - char *t = realloc(pSlidingWindowInfo->pStatus, newCap * sizeof(SWindowStatus)); - if (t != NULL) { - pSlidingWindowInfo->pStatus = (SWindowStatus *)t; - memset(&pSlidingWindowInfo->pStatus[pSlidingWindowInfo->capacity], 0, sizeof(SWindowStatus) * pSlidingWindowInfo->capacity); - } else { - // todo - } + // in the first scan, new space needed for results + int32_t pageId = -1; + SIDList list = getDataBufPagesIdList(pResultBuf, sid); - pSlidingWindowInfo->capacity = newCap; - } + if (list.size == 0) { + pData = getNewDataBuf(pResultBuf, sid, &pageId); + } else { + pageId = getLastPageId(&list); + pData = getResultBufferPageById(pResultBuf, pageId); - // add a new result set for a new group - if (pStatus != NULL) { - *pStatus = &pSlidingWindowInfo->pStatus[pSlidingWindowInfo->size]; + if (pData->numOfElems >= numOfRowsPerPage) { + pData = getNewDataBuf(pResultBuf, sid, &pageId); + if (pData != NULL) { + assert(pData->numOfElems == 0); // number of elements must be 0 for new allocated buffer + } } + } - p = pSlidingWindowInfo->size; - pSlidingWindowInfo->curIndex = pSlidingWindowInfo->size; + if (pData == NULL) { + return -1; + } - pSlidingWindowInfo->size += 1; - taosAddToHashTable(pSlidingWindowInfo->hashList, pData, bytes, (char *)&pSlidingWindowInfo->curIndex, sizeof(int32_t)); + // set the number of rows in current disk page + if (pWindowRes->pos.pageId == -1) { // not allocated yet, allocate new buffer + pWindowRes->pos.pageId = pageId; + pWindowRes->pos.rowId = pData->numOfElems++; } - return &pSlidingWindowInfo->pResult[p]; + return 0; } -static int32_t initSlidingWindowInfo(SSlidingWindowInfo *pSlidingWindowInfo, int32_t threshold, int16_t type, int32_t rowSizes, - SOutputRes *pRes) { - pSlidingWindowInfo->capacity = threshold; - pSlidingWindowInfo->threshold = threshold; +static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo, int32_t sid, + STimeWindow *win) { + assert(win->skey <= win->ekey); + SQueryDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf; - pSlidingWindowInfo->type = type; + SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&win->skey, TSDB_KEYSIZE); + if (pWindowRes == NULL) { + return -1; + } - _hash_fn_t fn = taosGetDefaultHashFunction(type); - pSlidingWindowInfo->hashList = taosInitHashTable(threshold, fn, false); + // not assign result buffer yet, add new result buffer + if (pWindowRes->pos.pageId == -1) { + int32_t ret = addNewWindowResultBuf(pWindowRes, pResultBuf, sid, pRuntimeEnv->numOfRowsPerPage); + if (ret != 0) { + return -1; + } + } - pSlidingWindowInfo->curIndex = -1; - pSlidingWindowInfo->size = 0; - pSlidingWindowInfo->pResult = pRes; + // set time window for current result + pWindowRes->window = *win; -// createResultBuf(&pSlidingWindowInfo->pResultBuf, 10, rowSizes); - - pSlidingWindowInfo->pStatus = calloc(threshold, sizeof(SWindowStatus)); -// pSlidingWindowInfo->pResultInfo = calloc(threshold, POINTER_BYTES); - -// for(int32_t i = 0; i < threshold; ++i) { -// pSlidingWindowInfo->pResultInfo[i] = calloc((size_t)numOfOutput, sizeof(SResultInfo)); - - -// } - - if (pSlidingWindowInfo->pStatus == NULL || pSlidingWindowInfo->hashList == NULL) { - return -1; - } + setWindowResOutputBuf(pRuntimeEnv, pWindowRes); + initCtxOutputBuf(pRuntimeEnv); return TSDB_CODE_SUCCESS; } -static void destroySlidingWindowInfo(SSlidingWindowInfo *pSlidingWindowInfo) { - if (pSlidingWindowInfo == NULL || pSlidingWindowInfo->capacity == 0) { - assert(pSlidingWindowInfo->hashList == NULL && pSlidingWindowInfo->pResult == NULL); - return; +static SWindowStatus *getTimeWindowResStatus(SWindowResInfo *pWindowResInfo, int32_t slot) { + assert(slot >= 0 && slot < pWindowResInfo->size); + return &pWindowResInfo->pResult[slot].status; +} + +static int32_t getForwardStepsInBlock(int32_t numOfPoints, __block_search_fn_t searchFn, TSKEY ekey, int16_t pos, + int16_t order, int64_t *pData) { + int32_t endPos = searchFn((char *)pData, numOfPoints, ekey, order); + int32_t forwardStep = 0; + + if (endPos >= 0) { + forwardStep = (order == TSQL_SO_ASC) ? (endPos - pos) : (pos - endPos); + assert(forwardStep >= 0); + + // endPos data is equalled to the key so, we do need to read the element in endPos + if (pData[endPos] == ekey) { + forwardStep += 1; + } } - taosCleanUpHashTable(pSlidingWindowInfo->hashList); -// destroyResultBuf(pSlidingWindowInfo->pResultBuf); - - tfree(pSlidingWindowInfo->pStatus); + return forwardStep; } -void resetSlidingWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SSlidingWindowInfo *pSlidingWindowInfo) { - if (pSlidingWindowInfo == NULL || pSlidingWindowInfo->capacity == 0) { +/** + * NOTE: the query status only set for the first scan of master scan. + */ +static void doCheckQueryCompleted(SQueryRuntimeEnv *pRuntimeEnv, TSKEY lastKey, SWindowResInfo *pWindowResInfo) { + SQuery *pQuery = pRuntimeEnv->pQuery; + if (pRuntimeEnv->scanFlag != MASTER_SCAN || (!isIntervalQuery(pQuery))) { return; } - - for (int32_t i = 0; i < pSlidingWindowInfo->size; ++i) { - SOutputRes *pOneRes = &pSlidingWindowInfo->pResult[i]; - clearGroupResultBuf(pRuntimeEnv, pOneRes); + + // no qualified results exist, abort check + if (pWindowResInfo->size == 0) { + return; } - memset(pSlidingWindowInfo->pStatus, 0, sizeof(SWindowStatus) * pSlidingWindowInfo->capacity); + // query completed + if ((lastKey >= pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (lastKey <= pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { + closeAllTimeWindow(pWindowResInfo); - pSlidingWindowInfo->curIndex = -1; - taosCleanUpHashTable(pSlidingWindowInfo->hashList); - pSlidingWindowInfo->size = 0; - - _hash_fn_t fn = taosGetDefaultHashFunction(pSlidingWindowInfo->type); - pSlidingWindowInfo->hashList = taosInitHashTable(pSlidingWindowInfo->capacity, fn, false); + pWindowResInfo->curIndex = pWindowResInfo->size - 1; + setQueryStatus(pQuery, QUERY_COMPLETED | QUERY_RESBUF_FULL); + } else { // set the current index to be the last unclosed window + int32_t i = 0; + int64_t skey = 0; - pSlidingWindowInfo->startTime = 0; - pSlidingWindowInfo->prevSKey = 0; -} + for (i = 0; i < pWindowResInfo->size; ++i) { + SWindowResult *pResult = &pWindowResInfo->pResult[i]; + if (pResult->status.closed) { + continue; + } -void clearCompletedSlidingWindows(SQueryRuntimeEnv* pRuntimeEnv) { - SSlidingWindowInfo* pSlidingWindowInfo = &pRuntimeEnv->swindowResInfo; - if (pSlidingWindowInfo == NULL || pSlidingWindowInfo->capacity == 0 || pSlidingWindowInfo->size == 0) { - return; - } + if ((pResult->window.ekey <= lastKey && QUERY_IS_ASC_QUERY(pQuery)) || + (pResult->window.skey >= lastKey && !QUERY_IS_ASC_QUERY(pQuery))) { + closeTimeWindow(pWindowResInfo, i); + } else { + skey = pResult->window.skey; + break; + } + } - int32_t i = 0; - for (i = 0; i < pSlidingWindowInfo->size; ++i) { - SWindowStatus *pStatus = &pSlidingWindowInfo->pStatus[i]; - if (pStatus->closed) { // remove the window slot from hash table - taosDeleteFromHashTable(pSlidingWindowInfo->hashList, (const char *)&pStatus->window.skey, TSDB_KEYSIZE); + // all windows are closed, set the last one to be the skey + if (skey == 0) { + assert(i == pWindowResInfo->size); + pWindowResInfo->curIndex = pWindowResInfo->size - 1; } else { - break; + pWindowResInfo->curIndex = i; } - } - if (i == 0) { - return; - } - - int32_t remain = pSlidingWindowInfo->size - i; - - //clear remain list - memmove(pSlidingWindowInfo->pStatus, &pSlidingWindowInfo->pStatus[i], remain * sizeof(SWindowStatus)); - memset(&pSlidingWindowInfo->pStatus[remain], 0, (pSlidingWindowInfo->capacity - remain) * sizeof(SWindowStatus)); - - for(int32_t k = 0; k < remain; ++k) { - copyGroupResultBuf(pRuntimeEnv, &pSlidingWindowInfo->pResult[k], &pSlidingWindowInfo->pResult[i + k]); - } - - for(int32_t k = remain; k < pSlidingWindowInfo->size; ++k) { - SOutputRes *pOneRes = &pSlidingWindowInfo->pResult[k]; - clearGroupResultBuf(pRuntimeEnv, pOneRes); - } + pWindowResInfo->prevSKey = pWindowResInfo->pResult[pWindowResInfo->curIndex].window.skey; - pSlidingWindowInfo->size = remain; + // the number of completed slots are larger than the threshold, dump to client immediately. + int32_t n = numOfClosedTimeWindow(pWindowResInfo); + if (n > pWindowResInfo->threshold) { + setQueryStatus(pQuery, QUERY_RESBUF_FULL); + } - for(int32_t k = 0; k < pSlidingWindowInfo->size; ++k) { - SWindowStatus* pStatus = &pSlidingWindowInfo->pStatus[k]; - int32_t *p = (int32_t*) taosGetDataFromHashTable(pSlidingWindowInfo->hashList, (const char*)&pStatus->window.skey, TSDB_KEYSIZE); - int32_t v = *p; - v = (v - i); - - taosDeleteFromHashTable(pSlidingWindowInfo->hashList, (const char *)&pStatus->window.skey, TSDB_KEYSIZE); - - taosAddToHashTable(pSlidingWindowInfo->hashList, (const char*)&pStatus->window.skey, TSDB_KEYSIZE, - (char *)&v, sizeof(int32_t)); + dTrace("QInfo:%p total window:%d, closed:%d", GET_QINFO_ADDR(pQuery), pWindowResInfo->size, n); } - - pSlidingWindowInfo->curIndex = -1; -} -int32_t numOfClosedSlidingWindow(SSlidingWindowInfo *pSlidingWindowInfo) { - int32_t i = 0; - while(i < pSlidingWindowInfo->size && pSlidingWindowInfo->pStatus[i].closed) { - ++i; - } - - return i; + assert(pWindowResInfo->prevSKey != 0); } -void closeSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo, int32_t slot) { - assert(slot >= 0 && slot < pSlidingWindowInfo->size); - SWindowStatus* pStatus = &pSlidingWindowInfo->pStatus[slot]; - pStatus->closed = true; -} +static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SBlockInfo *pBlockInfo, TSKEY *pPrimaryColumn, int32_t startPos, + TSKEY ekey, __block_search_fn_t searchFn, bool updateLastKey) { + assert(startPos >= 0 && startPos < pBlockInfo->size); -void closeAllSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo) { - assert(pSlidingWindowInfo->size >=0 && pSlidingWindowInfo->capacity >= pSlidingWindowInfo->size); - - for(int32_t i = 0; i < pSlidingWindowInfo->size; ++i) { - SWindowStatus* pStatus = &pSlidingWindowInfo->pStatus[i]; - pStatus->closed = true; + int32_t num = -1; + int32_t order = pQuery->order.order; + + int32_t step = GET_FORWARD_DIRECTION_FACTOR(order); + + if (QUERY_IS_ASC_QUERY(pQuery)) { + if (ekey < pBlockInfo->keyLast) { + num = getForwardStepsInBlock(pBlockInfo->size, searchFn, ekey, startPos, order, pPrimaryColumn); + if (num == 0) { // no qualified data in current block, do not update the lastKey value + assert(ekey < pPrimaryColumn[startPos]); + } else { + if (updateLastKey) { + pQuery->lastKey = pPrimaryColumn[startPos + (num - 1)] + step; + } + } + } else { + num = pBlockInfo->size - startPos; + if (updateLastKey) { + pQuery->lastKey = pBlockInfo->keyLast + step; + } + } + } else { // desc + if (ekey > pBlockInfo->keyFirst) { + num = getForwardStepsInBlock(pBlockInfo->size, searchFn, ekey, startPos, order, pPrimaryColumn); + if (num == 0) { // no qualified data in current block, do not update the lastKey value + assert(ekey > pPrimaryColumn[startPos]); + } else { + if (updateLastKey) { + pQuery->lastKey = pPrimaryColumn[startPos - (num - 1)] + step; + } + } + } else { + num = startPos + 1; + if (updateLastKey) { + pQuery->lastKey = pBlockInfo->keyFirst + step; + } + } } + + assert(num >= 0); + return num; } -static SWindowStatus* getSlidingWindowStatus(SSlidingWindowInfo *pSlidingWindowInfo, int32_t slot) { - return &pSlidingWindowInfo->pStatus[slot]; +static void doBlockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SWindowStatus *pStatus, STimeWindow *pWin, + int32_t startPos, int32_t forwardStep) { + SQuery * pQuery = pRuntimeEnv->pQuery; + SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; + + if (IS_MASTER_SCAN(pRuntimeEnv) || pStatus->closed) { + for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { + pCtx[k].nStartQueryTimestamp = pWin->skey; + pCtx[k].size = forwardStep; + pCtx[k].startOffset = (QUERY_IS_ASC_QUERY(pQuery)) ? startPos : startPos - (forwardStep - 1); + + int32_t functionId = pQuery->pSelectExpr[k].pBase.functionId; + if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) { + aAggs[functionId].xFunction(&pCtx[k]); + } + } + } } -static bool slidingWindowClosed(SSlidingWindowInfo* pSlidingWindowInfo, int32_t slot) { - return (pSlidingWindowInfo->pStatus[slot].closed == true); +static void doRowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SWindowStatus *pStatus, STimeWindow *pWin, + int32_t offset) { + SQuery * pQuery = pRuntimeEnv->pQuery; + SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; + + if (IS_MASTER_SCAN(pRuntimeEnv) || pStatus->closed) { + for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { + pCtx[k].nStartQueryTimestamp = pWin->skey; + + int32_t functionId = pQuery->pSelectExpr[k].pBase.functionId; + if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) { + aAggs[functionId].xFunctionF(&pCtx[k], offset); + } + } + } } -static int32_t curSlidingWindow(SSlidingWindowInfo *pSlidingWindowInfo) { - assert(pSlidingWindowInfo->curIndex >= 0 && pSlidingWindowInfo->curIndex < pSlidingWindowInfo->size); - - return pSlidingWindowInfo->curIndex; +static int32_t getNextQualifiedWindow(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow *pNextWin, + SWindowResInfo *pWindowResInfo, SBlockInfo *pBlockInfo, TSKEY *primaryKeys, + __block_search_fn_t searchFn) { + SQuery *pQuery = pRuntimeEnv->pQuery; + + while (1) { + getNextTimeWindow(pQuery, pNextWin); + + if (pWindowResInfo->startTime > pNextWin->skey || (pNextWin->skey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (pNextWin->ekey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { + return -1; + } + + // next time window is not in current block + if ((pNextWin->skey > pBlockInfo->keyLast && QUERY_IS_ASC_QUERY(pQuery)) || + (pNextWin->ekey < pBlockInfo->keyFirst && !QUERY_IS_ASC_QUERY(pQuery))) { + return -1; + } + + TSKEY startKey = QUERY_IS_ASC_QUERY(pQuery) ? pNextWin->skey : pNextWin->ekey; + int32_t startPos = searchFn((char *)primaryKeys, pBlockInfo->size, startKey, pQuery->order.order); + + /* + * This time window does not cover any data, try next time window, + * this case may happen when the time window is too small + */ + if ((primaryKeys[startPos] > pNextWin->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (primaryKeys[startPos] < pNextWin->skey && !QUERY_IS_ASC_QUERY(pQuery))) { + continue; + } + +// if (pNextWin->ekey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) { +// pNextWin->ekey = pQuery->ekey; +// } +// if (pNextWin->skey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery)) { +// pNextWin->skey = pQuery->ekey; +// } + + return startPos; + } } -// get the correct sliding window according to the handled timestamp -static STimeWindow getActiveSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo, int64_t ts, SQuery* pQuery) { - STimeWindow w = {0}; - - if (pSlidingWindowInfo->curIndex == -1) { // the first window, from the prevous stored value - w.skey = pSlidingWindowInfo->prevSKey; - w.ekey = w.skey + pQuery->nAggTimeInterval - 1; - +static TSKEY reviseWindowEkey(SQuery *pQuery, STimeWindow *pWindow) { + TSKEY ekey = -1; + if (QUERY_IS_ASC_QUERY(pQuery)) { + ekey = pWindow->ekey; + if (ekey > pQuery->ekey) { + ekey = pQuery->ekey; + } } else { - SWindowStatus* pStatus = getSlidingWindowStatus(pSlidingWindowInfo, curSlidingWindow(pSlidingWindowInfo)); - - if (pStatus->window.skey <= ts && pStatus->window.ekey >= ts) { - w = pStatus->window; - } else { - int64_t st = pStatus->window.skey; - - while (st > ts) { - st -= pQuery->slidingTime; + ekey = pWindow->skey; + if (ekey < pQuery->ekey) { + ekey = pQuery->ekey; + } + } + + return ekey; +} + +/** + * + * @param pRuntimeEnv + * @param forwardStep + * @param primaryKeyCol + * @param pFields + * @param isDiskFileBlock + * @return the incremental number of output value, so it maybe 0 for fixed number of query, + * such as count/min/max etc. + */ +static int32_t blockwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t forwardStep, SField *pFields, + SBlockInfo *pBlockInfo, SWindowResInfo *pWindowResInfo, + __block_search_fn_t searchFn) { + SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; + SQuery * pQuery = pRuntimeEnv->pQuery; + TSKEY * primaryKeyCol = (TSKEY *)pRuntimeEnv->primaryColBuffer->data; + + bool isDiskFileBlock = IS_FILE_BLOCK(pRuntimeEnv->blockStatus); + int64_t prevNumOfRes = getNumOfResult(pRuntimeEnv); + + SArithmeticSupport *sasArray = calloc((size_t)pQuery->numOfOutputCols, sizeof(SArithmeticSupport)); + + for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { + int32_t functionId = pQuery->pSelectExpr[k].pBase.functionId; + + SField dummyField = {0}; + + bool hasNull = hasNullVal(pQuery, k, pBlockInfo, pFields, isDiskFileBlock); + char *dataBlock = getDataBlocks(pRuntimeEnv, &sasArray[k], k, forwardStep); + + SField *tpField = NULL; + + if (pFields != NULL) { + tpField = getFieldInfo(pQuery, pBlockInfo, pFields, k); + /* + * Field info not exist, the required column is not present in current block, + * so all data must be null value in current block. + */ + if (tpField == NULL) { + tpField = &dummyField; + tpField->numOfNullPoints = (int32_t)forwardStep; } - - while ((st + pQuery->nAggTimeInterval - 1) < ts) { - st += pQuery->slidingTime; + } + + setExecParams(pQuery, &pCtx[k], pQuery->skey, dataBlock, (char *)primaryKeyCol, forwardStep, functionId, tpField, + hasNull, pRuntimeEnv->blockStatus, &sasArray[k], pRuntimeEnv->scanFlag); + } + + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + if (isIntervalQuery(pQuery)) { + int32_t offset = GET_COL_DATA_POS(pQuery, 0, step); + TSKEY ts = primaryKeyCol[offset]; + + STimeWindow win = getActiveTimeWindow(pWindowResInfo, ts, pQuery); + if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pRuntimeEnv->pMeterObj->sid, &win) != TSDB_CODE_SUCCESS) { + return 0; + } + + TSKEY ekey = reviseWindowEkey(pQuery, &win); + forwardStep = getNumOfRowsInTimeWindow(pQuery, pBlockInfo, primaryKeyCol, pQuery->pos, ekey, searchFn, true); + + SWindowStatus *pStatus = getTimeWindowResStatus(pWindowResInfo, curTimeWindow(pWindowResInfo)); + doBlockwiseApplyFunctions(pRuntimeEnv, pStatus, &win, pQuery->pos, forwardStep); + + int32_t index = pWindowResInfo->curIndex; + STimeWindow nextWin = win; + + while (1) { + int32_t startPos = + getNextQualifiedWindow(pRuntimeEnv, &nextWin, pWindowResInfo, pBlockInfo, primaryKeyCol, searchFn); + if (startPos < 0) { + break; + } + + // null data, failed to allocate more memory buffer + int32_t sid = pRuntimeEnv->pMeterObj->sid; + if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, sid, &nextWin) != TSDB_CODE_SUCCESS) { + break; + } + + ekey = reviseWindowEkey(pQuery, &nextWin); + forwardStep = getNumOfRowsInTimeWindow(pQuery, pBlockInfo, primaryKeyCol, startPos, ekey, searchFn, true); + + pStatus = getTimeWindowResStatus(pWindowResInfo, curTimeWindow(pWindowResInfo)); + doBlockwiseApplyFunctions(pRuntimeEnv, pStatus, &nextWin, startPos, forwardStep); + } + + pWindowResInfo->curIndex = index; + } else { + /* + * the sqlfunctionCtx parameters should be set done before all functions are invoked, + * since the selectivity + tag_prj query needs all parameters been set done. + * tag_prj function are changed to be TSDB_FUNC_TAG_DUMMY + */ + for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { + int32_t functionId = pQuery->pSelectExpr[k].pBase.functionId; + if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) { + aAggs[functionId].xFunction(&pCtx[k]); } - - w.skey = st; - w.ekey = w.skey + pQuery->nAggTimeInterval - 1; } } - - assert(ts >= w.skey && ts <= w.ekey); - return w; + + /* + * No need to calculate the number of output results for group-by normal columns, interval query + * because the results of group by normal column is put into intermediate buffer. + */ + int32_t num = 0; + if (!isIntervalQuery(pQuery)) { + num = getNumOfResult(pRuntimeEnv) - prevNumOfRes; + } + + tfree(sasArray); + return (int32_t)num; } -static int32_t setGroupResultFromKey(SQueryRuntimeEnv *pRuntimeEnv, char *pData, int16_t type, int16_t bytes) { - if (isNull(pData, type)) { // ignore the null value - return -1; +/** + * if sfields is null + * 1. count(*)/spread(ts) is invoked + * 2. this column does not exists + * + * first filter the data block according to the value filter condition, then, if the top/bottom query applied, + * invoke the filter function to decide if the data block need to be accessed or not. + * TODO handle the whole data block is NULL situation + * @param pQuery + * @param pField + * @return + */ +static bool needToLoadDataBlock(SQuery *pQuery, SField *pField, SQLFunctionCtx *pCtx, int32_t numOfTotalPoints) { + if (pField == NULL) { + return false; // no need to load data } - SOutputRes *pOutputRes = doSetSlidingWindowFromKey(&pRuntimeEnv->swindowResInfo, pData, bytes, NULL); - if (pOutputRes == NULL) { - return -1; + for (int32_t k = 0; k < pQuery->numOfFilterCols; ++k) { + SSingleColumnFilterInfo *pFilterInfo = &pQuery->pFilterInfo[k]; + int32_t colIndex = pFilterInfo->info.colIdx; + + // this column not valid in current data block + if (colIndex < 0 || pField[colIndex].colId != pFilterInfo->info.data.colId) { + continue; + } + + // not support pre-filter operation on binary/nchar data type + if (!vnodeSupportPrefilter(pFilterInfo->info.data.type)) { + continue; + } + + // all points in current column are NULL, no need to check its boundary value + if (pField[colIndex].numOfNullPoints == numOfTotalPoints) { + continue; + } + + if (pFilterInfo->info.data.type == TSDB_DATA_TYPE_FLOAT) { + float minval = *(double *)(&pField[colIndex].min); + float maxval = *(double *)(&pField[colIndex].max); + + for (int32_t i = 0; i < pFilterInfo->numOfFilters; ++i) { + if (pFilterInfo->pFilters[i].fp(&pFilterInfo->pFilters[i], (char *)&minval, (char *)&maxval)) { + return true; + } + } + } else { + for (int32_t i = 0; i < pFilterInfo->numOfFilters; ++i) { + if (pFilterInfo->pFilters[i].fp(&pFilterInfo->pFilters[i], (char *)&pField[colIndex].min, + (char *)&pField[colIndex].max)) { + return true; + } + } + } } - setGroupOutputBuffer(pRuntimeEnv, pOutputRes); - initCtxOutputBuf(pRuntimeEnv); + // todo disable this opt code block temporarily + // for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { + // int32_t functId = pQuery->pSelectExpr[i].pBase.functionId; + // if (functId == TSDB_FUNC_TOP || functId == TSDB_FUNC_BOTTOM) { + // return top_bot_datablock_filter(&pCtx[i], functId, (char *)&pField[i].min, (char *)&pField[i].max); + // } + // } + + return true; +} + +int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRuntimeEnv, int32_t size, + int32_t threshold, int16_t type) { + if (size < threshold) { + size = threshold; + } + + pWindowResInfo->capacity = size; + pWindowResInfo->threshold = threshold; + + pWindowResInfo->type = type; + + _hash_fn_t fn = taosGetDefaultHashFunction(type); + pWindowResInfo->hashList = taosInitHashTable(threshold, fn, false); + + pWindowResInfo->curIndex = -1; + pWindowResInfo->size = 0; + + // use the pointer arraylist + pWindowResInfo->pResult = calloc(threshold, sizeof(SWindowResult)); + for (int32_t i = 0; i < threshold; ++i) { + SPosInfo posInfo = {-1, -1}; + createQueryResultInfo(pRuntimeEnv->pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, &posInfo); + } return TSDB_CODE_SUCCESS; } -static int32_t setSlidingWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow *pTimeWindow) { - assert(pTimeWindow->skey < pTimeWindow->ekey); - - int64_t st = pTimeWindow->skey; - - SWindowStatus *pStatus = NULL; - SOutputRes* pOutputRes = doSetSlidingWindowFromKey(&pRuntimeEnv->swindowResInfo, (char *)&st, TSDB_KEYSIZE, - &pStatus); - - if (pOutputRes == NULL) { +void cleanupTimeWindowInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRuntimeEnv) { + if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0) { + assert(pWindowResInfo->hashList == NULL && pWindowResInfo->pResult == NULL); + return; + } + + for (int32_t i = 0; i < pWindowResInfo->size; ++i) { + SWindowResult *pResult = &pWindowResInfo->pResult[i]; + destroyTimeWindowRes(pResult, pRuntimeEnv->pQuery->numOfOutputCols); + } + + taosCleanUpHashTable(pWindowResInfo->hashList); + tfree(pWindowResInfo->pResult); +} + +void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo) { + if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0) { + return; + } + + for (int32_t i = 0; i < pWindowResInfo->size; ++i) { + SWindowResult *pWindowRes = &pWindowResInfo->pResult[i]; + clearTimeWindowResBuf(pRuntimeEnv, pWindowRes); + } + + pWindowResInfo->curIndex = -1; + taosCleanUpHashTable(pWindowResInfo->hashList); + pWindowResInfo->size = 0; + + _hash_fn_t fn = taosGetDefaultHashFunction(pWindowResInfo->type); + pWindowResInfo->hashList = taosInitHashTable(pWindowResInfo->capacity, fn, false); + + pWindowResInfo->startTime = 0; + pWindowResInfo->prevSKey = 0; +} + +void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) { + SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; + if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0 || pWindowResInfo->size == 0 || num == 0) { + return; + } + + int32_t numOfClosed = numOfClosedTimeWindow(pWindowResInfo); + assert(num >= 0 && num <= numOfClosed); + + for (int32_t i = 0; i < num; ++i) { + SWindowResult *pResult = &pWindowResInfo->pResult[i]; + if (pResult->status.closed) { // remove the window slot from hash table + taosDeleteFromHashTable(pWindowResInfo->hashList, (const char *)&pResult->window.skey, TSDB_KEYSIZE); + } else { + break; + } + } + + int32_t remain = pWindowResInfo->size - num; + + // clear all the closed windows from the window list + for (int32_t k = 0; k < remain; ++k) { + copyTimeWindowResBuf(pRuntimeEnv, &pWindowResInfo->pResult[k], &pWindowResInfo->pResult[num + k]); + } + + // move the unclosed window in the front of the window list + for (int32_t k = remain; k < pWindowResInfo->size; ++k) { + SWindowResult *pWindowRes = &pWindowResInfo->pResult[k]; + clearTimeWindowResBuf(pRuntimeEnv, pWindowRes); + } + + pWindowResInfo->size = remain; + + for (int32_t k = 0; k < pWindowResInfo->size; ++k) { + SWindowResult *pResult = &pWindowResInfo->pResult[k]; + int32_t *p = (int32_t *)taosGetDataFromHashTable(pWindowResInfo->hashList, (const char *)&pResult->window.skey, + TSDB_KEYSIZE); + int32_t v = (*p - num); + assert(v >= 0 && v <= pWindowResInfo->size); + + // todo add the update function for hash table + taosDeleteFromHashTable(pWindowResInfo->hashList, (const char *)&pResult->window.skey, TSDB_KEYSIZE); + taosAddToHashTable(pWindowResInfo->hashList, (const char *)&pResult->window.skey, TSDB_KEYSIZE, (char *)&v, + sizeof(int32_t)); + } + + pWindowResInfo->curIndex = -1; +} + +void clearClosedTimeWindow(SQueryRuntimeEnv *pRuntimeEnv) { + SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; + if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0 || pWindowResInfo->size == 0) { + return; + } + + int32_t numOfClosed = numOfClosedTimeWindow(pWindowResInfo); + clearFirstNTimeWindow(pRuntimeEnv, numOfClosed); +} + +int32_t numOfClosedTimeWindow(SWindowResInfo *pWindowResInfo) { + int32_t i = 0; + while (i < pWindowResInfo->size && pWindowResInfo->pResult[i].status.closed) { + ++i; + } + + return i; +} + +void closeTimeWindow(SWindowResInfo *pWindowResInfo, int32_t slot) { + getWindowResult(pWindowResInfo, slot)->status.closed = true; +} + +void closeAllTimeWindow(SWindowResInfo *pWindowResInfo) { + assert(pWindowResInfo->size >= 0 && pWindowResInfo->capacity >= pWindowResInfo->size); + + for (int32_t i = 0; i < pWindowResInfo->size; ++i) { + pWindowResInfo->pResult[i].status.closed = true; + } +} + +static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pData, int16_t type, int16_t bytes) { + if (isNull(pData, type)) { // ignore the null value return -1; } - pStatus->window = *pTimeWindow; - setGroupOutputBuffer(pRuntimeEnv, pOutputRes); - initCtxOutputBuf(pRuntimeEnv); + int32_t GROUPRESULTID = 1; + + SQueryDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf; + + SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, pData, bytes); + if (pWindowRes == NULL) { + return -1; + } + // not assign result buffer yet, add new result buffer + if (pWindowRes->pos.pageId == -1) { + int32_t ret = addNewWindowResultBuf(pWindowRes, pResultBuf, GROUPRESULTID, pRuntimeEnv->numOfRowsPerPage); + if (ret != 0) { + return -1; + } + } + + setWindowResOutputBuf(pRuntimeEnv, pWindowRes); + initCtxOutputBuf(pRuntimeEnv); return TSDB_CODE_SUCCESS; } @@ -1915,7 +2253,7 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx } // in the supplementary scan, only the following functions need to be executed - if (!IS_MASTER_SCAN(pRuntimeEnv) && + if (IS_SUPPLEMENT_SCAN(pRuntimeEnv) && !(functionId == TSDB_FUNC_LAST_DST || functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_FIRST || functionId == TSDB_FUNC_LAST || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS)) { return false; @@ -1924,10 +2262,11 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx return true; } -static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t *forwardStep, TSKEY *primaryKeyCol, - SField *pFields, SBlockInfo *pBlockInfo) { +static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t *forwardStep, SField *pFields, + SBlockInfo *pBlockInfo, SWindowResInfo *pWindowResInfo) { SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; SQuery * pQuery = pRuntimeEnv->pQuery; + TSKEY * primaryKeyCol = (TSKEY *)pRuntimeEnv->primaryColBuffer->data; bool isDiskFileBlock = IS_FILE_BLOCK(pRuntimeEnv->blockStatus); SData **data = pRuntimeEnv->colDataBuffer; @@ -1955,7 +2294,8 @@ static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t * bool hasNull = hasNullVal(pQuery, k, pBlockInfo, pFields, isDiskFileBlock); char *dataBlock = getDataBlocks(pRuntimeEnv, &sasArray[k], k, *forwardStep); - TSKEY ts = QUERY_IS_ASC_QUERY(pQuery) ? pRuntimeEnv->intervalWindow.skey : pRuntimeEnv->intervalWindow.ekey; + TSKEY ts = pQuery->skey; // QUERY_IS_ASC_QUERY(pQuery) ? pRuntimeEnv->intervalWindow.skey : + // pRuntimeEnv->intervalWindow.ekey; setExecParams(pQuery, &pCtx[k], ts, dataBlock, (char *)primaryKeyCol, (*forwardStep), functionId, pFields, hasNull, pRuntimeEnv->blockStatus, &sasArray[k], pRuntimeEnv->scanFlag); } @@ -1982,14 +2322,13 @@ static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t * } int32_t j = 0; - int64_t lastKey = 0; - + TSKEY lastKey = -1; + for (j = 0; j < (*forwardStep); ++j) { int32_t offset = GET_COL_DATA_POS(pQuery, j, step); if (pRuntimeEnv->pTSBuf != NULL) { int32_t r = doTSJoinFilter(pRuntimeEnv, offset); - if (r == TS_JOIN_TAG_NOT_EQUALS) { break; } else if (r == TS_JOIN_TS_NOT_EQUALS) { @@ -2003,15 +2342,13 @@ static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t * continue; } - // sliding window query - if (pQuery->slidingTime > 0 && pQuery->nAggTimeInterval > 0) { + // interval window query + if (isIntervalQuery(pQuery)) { // decide the time window according to the primary timestamp - int64_t ts = primaryKeyCol[offset]; - - SSlidingWindowInfo* pSlidingWindowInfo = &pRuntimeEnv->swindowResInfo; - STimeWindow win = getActiveSlidingWindow(pSlidingWindowInfo, ts, pQuery); + int64_t ts = primaryKeyCol[offset]; + STimeWindow win = getActiveTimeWindow(pWindowResInfo, ts, pQuery); - int32_t ret = setSlidingWindowFromKey(pRuntimeEnv, &win); + int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pRuntimeEnv->pMeterObj->sid, &win); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code continue; } @@ -2019,73 +2356,49 @@ static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t * // all startOffset are identical offset -= pCtx[0].startOffset; - for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { - int32_t functionId = pQuery->pSelectExpr[k].pBase.functionId; - pCtx[k].nStartQueryTimestamp = win.skey; - - SWindowStatus* pStatus = getSlidingWindowStatus(pSlidingWindowInfo, curSlidingWindow(pSlidingWindowInfo)); - - if (!IS_MASTER_SCAN(pRuntimeEnv) && !pStatus->closed) { -// qTrace("QInfo:%p not completed in supplementary scan, ignore funcId:%d, window:%lld-%lld", -// GET_QINFO_ADDR(pQuery), functionId, pStatus->window.skey, pStatus->window.ekey); - continue; - } - - if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) { - aAggs[functionId].xFunctionF(&pCtx[k], offset); - } - } + SWindowStatus *pStatus = getTimeWindowResStatus(pWindowResInfo, curTimeWindow(pWindowResInfo)); + doRowwiseApplyFunctions(pRuntimeEnv, pStatus, &win, offset); lastKey = ts; - int32_t index = pRuntimeEnv->swindowResInfo.curIndex; - STimeWindow nextWin = win; + int32_t index = pWindowResInfo->curIndex; + int32_t sid = pRuntimeEnv->pMeterObj->sid; + while (1) { - getNextLogicalQueryRange(pRuntimeEnv, &nextWin); - if (pSlidingWindowInfo->startTime > nextWin.skey || (nextWin.skey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + getNextTimeWindow(pQuery, &nextWin); + if (pWindowResInfo->startTime > nextWin.skey || (nextWin.skey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || (nextWin.skey > pQuery->skey && !QUERY_IS_ASC_QUERY(pQuery))) { - pRuntimeEnv->swindowResInfo.curIndex = index; break; } - if (ts >= nextWin.skey && ts <= nextWin.ekey) { - // null data, failed to allocate more memory buffer - if (setSlidingWindowFromKey(pRuntimeEnv, &nextWin) != TSDB_CODE_SUCCESS) { - pRuntimeEnv->swindowResInfo.curIndex = index; - break; - } + if (ts < nextWin.skey || ts > nextWin.ekey) { + break; + } - for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { - int32_t functionId = pQuery->pSelectExpr[k].pBase.functionId; - pCtx[k].nStartQueryTimestamp = nextWin.skey; - - SWindowStatus* pStatus = getSlidingWindowStatus(pSlidingWindowInfo, curSlidingWindow(pSlidingWindowInfo)); - if (!IS_MASTER_SCAN(pRuntimeEnv) && !pStatus->closed) { -// qTrace("QInfo:%p not completed in supplementary scan, ignore funcId:%d, window:%lld-%lld", -// GET_QINFO_ADDR(pQuery), functionId, pStatus->window.skey, pStatus->window.ekey); - continue; - } - - if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) { - aAggs[functionId].xFunctionF(&pCtx[k], offset); - } - } - } else { - pRuntimeEnv->swindowResInfo.curIndex = index; + // null data, failed to allocate more memory buffer + if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, sid, &nextWin) != TSDB_CODE_SUCCESS) { break; } + + pStatus = getTimeWindowResStatus(pWindowResInfo, curTimeWindow(pWindowResInfo)); + doRowwiseApplyFunctions(pRuntimeEnv, pStatus, &nextWin, offset); } + + pWindowResInfo->curIndex = index; } else { // other queries // decide which group this rows belongs to according to current state value if (groupbyStateValue) { char *stateVal = groupbyColumnData + bytes * offset; - int32_t ret = setGroupResultFromKey(pRuntimeEnv, stateVal, type, bytes); + int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, stateVal, type, bytes); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code continue; } } + // update the lastKey + lastKey = primaryKeyCol[offset]; + // all startOffset are identical offset -= pCtx[0].startOffset; @@ -2110,7 +2423,7 @@ static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t * * requires checking buffer during loop */ if ((pQuery->checkBufferInLoop == 1) && (++numOfRes) >= pQuery->pointsOffset) { - pQuery->lastKey = primaryKeyCol[pQuery->pos + j * step] + step; + pQuery->lastKey = lastKey + step; *forwardStep = j + 1; break; } @@ -2118,72 +2431,18 @@ static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, int32_t * free(sasArray); - if (pQuery->slidingTime > 0 && pQuery->nAggTimeInterval > 0 && IS_MASTER_SCAN(pRuntimeEnv)) { - SSlidingWindowInfo *pSlidingWindowInfo = &pRuntimeEnv->swindowResInfo; - - // query completed - if ((lastKey >= pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (lastKey <= pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { - closeAllSlidingWindow(pSlidingWindowInfo); - - pSlidingWindowInfo->curIndex = pSlidingWindowInfo->size - 1; - setQueryStatus(pQuery, QUERY_COMPLETED | QUERY_RESBUF_FULL); - } else { - int32_t i = 0; - int64_t skey = 0; - - for (i = 0; i < pSlidingWindowInfo->size; ++i) { - SWindowStatus *pStatus = &pSlidingWindowInfo->pStatus[i]; - if ((pStatus->window.ekey <= lastKey && QUERY_IS_ASC_QUERY(pQuery)) || - (pStatus->window.skey >= lastKey && !QUERY_IS_ASC_QUERY(pQuery))) { - closeSlidingWindow(pSlidingWindowInfo, i); - } else { - skey = pStatus->window.skey; - break; - } - } - - pSlidingWindowInfo->prevSKey = skey; - - // the number of completed slots are larger than the threshold, dump to client immediately. - int32_t v = numOfClosedSlidingWindow(pSlidingWindowInfo); - if (v > pSlidingWindowInfo->threshold) { - setQueryStatus(pQuery, QUERY_RESBUF_FULL); - } - - dTrace("QInfo:%p total window:%d, closed:%d", GET_QINFO_ADDR(pQuery), pSlidingWindowInfo->size, v); - } - } - /* - * No need to calculate the number of output results for groupby normal columns + * No need to calculate the number of output results for group-by normal columns, interval query * because the results of group by normal column is put into intermediate buffer. */ int32_t num = 0; - if (!groupbyStateValue && !(pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { + if (!groupbyStateValue && !isIntervalQuery(pQuery)) { num = getNumOfResult(pRuntimeEnv) - prevNumOfRes; } return num; } -static int32_t getForwardStepsInBlock(int32_t numOfPoints, __block_search_fn_t searchFn, SQuery *pQuery, - int64_t *pData) { - int32_t endPos = searchFn((char *)pData, numOfPoints, pQuery->ekey, pQuery->order.order); - int32_t forwardStep = 0; - - if (endPos >= 0) { - forwardStep = QUERY_IS_ASC_QUERY(pQuery) ? (endPos - pQuery->pos) : (pQuery->pos - endPos); - assert(forwardStep >= 0); - - // endPos data is equalled to the key so, we do need to read the element in endPos - if (pData[endPos] == pQuery->ekey) { - forwardStep += 1; - } - } - return forwardStep; -} - static int32_t reviseForwardSteps(SQueryRuntimeEnv *pRuntimeEnv, int32_t forwardStep) { /* * 1. If value filter exists, we try all data in current block, and do not set the QUERY_RESBUF_FULL flag. @@ -2229,51 +2488,18 @@ static void validateQueryRangeAndData(SQueryRuntimeEnv *pRuntimeEnv, const TSKEY !QUERY_IS_ASC_QUERY(pQuery))); } -static int32_t applyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SBlockInfo *pBlockInfo, int64_t *pPrimaryColumn, - SField *pFields, __block_search_fn_t searchFn, int32_t *numOfRes) { - int32_t forwardStep = 0; +static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SBlockInfo *pBlockInfo, SField *pFields, + __block_search_fn_t searchFn, int32_t *numOfRes, + SWindowResInfo *pWindowResInfo) { SQuery *pQuery = pRuntimeEnv->pQuery; - - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + TSKEY * pPrimaryColumn = (TSKEY *)pRuntimeEnv->primaryColBuffer->data; validateQueryRangeAndData(pRuntimeEnv, pPrimaryColumn, pBlockInfo); - if (QUERY_IS_ASC_QUERY(pQuery)) { - if (pQuery->ekey < pBlockInfo->keyLast) { - forwardStep = getForwardStepsInBlock(pBlockInfo->size, searchFn, pQuery, pPrimaryColumn); - assert(forwardStep >= 0); - - if (forwardStep == 0) { - // no qualified data in current block, do not update the lastKey value - assert(pQuery->ekey < pPrimaryColumn[pQuery->pos]); - } else { - pQuery->lastKey = pQuery->ekey + step;//pPrimaryColumn[pQuery->pos + (forwardStep - 1)] + step; - } - - } else { - forwardStep = pBlockInfo->size - pQuery->pos; - assert(forwardStep > 0); - - pQuery->lastKey = pBlockInfo->keyLast + step; - } - } else { // desc - if (pQuery->ekey > pBlockInfo->keyFirst) { - forwardStep = getForwardStepsInBlock(pBlockInfo->size, searchFn, pQuery, pPrimaryColumn); - assert(forwardStep >= 0); - - if (forwardStep == 0) { - // no qualified data in current block, do not update the lastKey value - assert(pQuery->ekey > pPrimaryColumn[pQuery->pos]); - } else { - pQuery->lastKey = pQuery->ekey + step;//pPrimaryColumn[pQuery->pos - (forwardStep - 1)] + step; - } - } else { - forwardStep = pQuery->pos + 1; - assert(forwardStep > 0); - - pQuery->lastKey = pBlockInfo->keyFirst + step; - } - } + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + int32_t forwardStep = + getNumOfRowsInTimeWindow(pQuery, pBlockInfo, pPrimaryColumn, pQuery->pos, pQuery->ekey, searchFn, true); + assert(forwardStep >= 0); int32_t newForwardStep = reviseForwardSteps(pRuntimeEnv, forwardStep); assert(newForwardStep <= forwardStep && newForwardStep >= 0); @@ -2283,11 +2509,20 @@ static int32_t applyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SBlockInfo * pQuery->lastKey = pPrimaryColumn[pQuery->pos + (newForwardStep - 1) * step] + step; } - if (pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTSBuf != NULL || isGroupbyNormalCol(pQuery->pGroupbyExpr) || - (pQuery->slidingTime != -1 && pQuery->nAggTimeInterval > 0)) { - *numOfRes = rowwiseApplyAllFunctions(pRuntimeEnv, &newForwardStep, pPrimaryColumn, pFields, pBlockInfo); + if (pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTSBuf != NULL || isGroupbyNormalCol(pQuery->pGroupbyExpr)) { + *numOfRes = rowwiseApplyAllFunctions(pRuntimeEnv, &newForwardStep, pFields, pBlockInfo, pWindowResInfo); } else { - *numOfRes = blockwiseApplyAllFunctions(pRuntimeEnv, newForwardStep, pPrimaryColumn, pFields, pBlockInfo); + *numOfRes = blockwiseApplyAllFunctions(pRuntimeEnv, newForwardStep, pFields, pBlockInfo, pWindowResInfo, searchFn); + } + + TSKEY lastKey = (QUERY_IS_ASC_QUERY(pQuery)) ? pBlockInfo->keyLast : pBlockInfo->keyFirst; + doCheckQueryCompleted(pRuntimeEnv, lastKey, pWindowResInfo); // todo refactor merge + + // interval query with limit applied + if (isIntervalQuery(pQuery) && pQuery->limit.limit > 0 && + (pQuery->limit.limit + pQuery->limit.offset) <= numOfClosedTimeWindow(pWindowResInfo) && + pRuntimeEnv->scanFlag == MASTER_SCAN) { + setQueryStatus(pQuery, QUERY_COMPLETED); } assert(*numOfRes >= 0); @@ -2304,7 +2539,7 @@ static int32_t applyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SBlockInfo * return newForwardStep; } -int32_t vnodeGetVnodeHeaderFileIdx(int32_t *fid, SQueryRuntimeEnv *pRuntimeEnv, int32_t order) { +int32_t vnodeGetVnodeHeaderFileIndex(int32_t *fid, SQueryRuntimeEnv *pRuntimeEnv, int32_t order) { if (pRuntimeEnv->vnodeFileInfo.numOfFiles == 0) { return -1; } @@ -2365,7 +2600,7 @@ int32_t getNextDataFileCompInfo(SQueryRuntimeEnv *pRuntimeEnv, SMeterObj *pMeter int32_t fileIndex = 0; int32_t order = (step == QUERY_ASC_FORWARD_STEP) ? TSQL_SO_ASC : TSQL_SO_DESC; while (1) { - fileIndex = vnodeGetVnodeHeaderFileIdx(&pQuery->fileId, pRuntimeEnv, order); + fileIndex = vnodeGetVnodeHeaderFileIndex(&pQuery->fileId, pRuntimeEnv, order); // no files left, abort if (fileIndex < 0) { @@ -2438,9 +2673,8 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, int64_t startQueryTimes // store the first&last timestamp into the intermediate buffer [1], the true // value may be null but timestamp will never be null pCtx->ptsList = (int64_t *)(primaryColumnData + startOffset * TSDB_KEYSIZE); - } else if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || - functionId == TSDB_FUNC_TWA || functionId == TSDB_FUNC_DIFF || - (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) { + } else if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_TWA || + functionId == TSDB_FUNC_DIFF || (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) { /* * leastsquares function needs two columns of input, currently, the x value of linear equation is set to * timestamp column, and the y-value is the column specified in pQuery->pSelectExpr[i].colIdxInBuffer @@ -2484,8 +2718,8 @@ static void setCtxTagColumnInfo(SQuery *pQuery, SQLFunctionCtx *pCtx) { if (isSelectivityWithTagsQuery(pQuery)) { int32_t num = 0; SQLFunctionCtx *p = NULL; - - int16_t tagLen = 0; + + int16_t tagLen = 0; SQLFunctionCtx **pTagCtx = calloc(pQuery->numOfOutputCols, POINTER_BYTES); for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { @@ -2510,6 +2744,12 @@ static void setCtxTagColumnInfo(SQuery *pQuery, SQLFunctionCtx *pCtx) { } } +static void setWindowResultInfo(SResultInfo *pResultInfo, SQuery *pQuery, bool isStableQuery) { + for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { + setResultInfoBuf(&pResultInfo[i], pQuery->pSelectExpr[i].interResBytes, isStableQuery); + } +} + static int32_t setupQueryRuntimeEnv(SMeterObj *pMeterObj, SQuery *pQuery, SQueryRuntimeEnv *pRuntimeEnv, SColumnModel *pTagsSchema, int16_t order, bool isSTableQuery) { dTrace("QInfo:%p setup runtime env", GET_QINFO_ADDR(pQuery)); @@ -2532,8 +2772,8 @@ static int32_t setupQueryRuntimeEnv(SMeterObj *pMeterObj, SQuery *pQuery, SQuery SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i]; if (TSDB_COL_IS_TAG(pSqlFuncMsg->colInfo.flag)) { // process tag column info - SSchema* pSchema = getColumnModelSchema(pTagsSchema, pColIndexEx->colIdx); - + SSchema *pSchema = getColumnModelSchema(pTagsSchema, pColIndexEx->colIdx); + pCtx->inputType = pSchema->type; pCtx->inputBytes = pSchema->bytes; } else { @@ -2578,12 +2818,11 @@ static int32_t setupQueryRuntimeEnv(SMeterObj *pMeterObj, SQuery *pQuery, SQuery if (i > 0) { pRuntimeEnv->offset[i] = pRuntimeEnv->offset[i - 1] + pRuntimeEnv->pCtx[i - 1].outputBytes; } - - // set the intermediate result output buffer - SResultInfo *pResInfo = &pRuntimeEnv->resultInfo[i]; - setResultInfoBuf(pResInfo, pQuery->pSelectExpr[i].interResBytes, isSTableQuery); } + // set the intermediate result output buffer + setWindowResultInfo(pRuntimeEnv->resultInfo, pQuery, isSTableQuery); + // if it is group by normal column, do not set output buffer, the output buffer is pResult if (!isGroupbyNormalCol(pQuery->pGroupbyExpr) && !isSTableQuery) { resetCtxOutputBuf(pRuntimeEnv); @@ -2613,7 +2852,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { } tfree(pRuntimeEnv->secondaryUnzipBuffer); - destroySlidingWindowInfo(&pRuntimeEnv->swindowResInfo); + cleanupTimeWindowInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv); if (pRuntimeEnv->pCtx != NULL) { for (int32_t i = 0; i < pRuntimeEnv->pQuery->numOfOutputCols; ++i) { @@ -2665,7 +2904,6 @@ static int64_t getOldestKey(int32_t numOfFiles, int64_t fileId, SVnodeCfg *pCfg) } bool isQueryKilled(SQuery *pQuery) { - return false; SQInfo *pQInfo = (SQInfo *)GET_QINFO_ADDR(pQuery); /* @@ -2682,7 +2920,7 @@ bool isQueryKilled(SQuery *pQuery) { } bool isFixedOutputQuery(SQuery *pQuery) { - if (pQuery->nAggTimeInterval != 0) { + if (pQuery->intervalTime != 0) { return false; } @@ -2731,8 +2969,8 @@ bool isSumAvgRateQuery(SQuery *pQuery) { continue; } - if (functionId == TSDB_FUNC_SUM_RATE || functionId == TSDB_FUNC_SUM_IRATE || - functionId == TSDB_FUNC_AVG_RATE || functionId == TSDB_FUNC_AVG_IRATE) { + if (functionId == TSDB_FUNC_SUM_RATE || functionId == TSDB_FUNC_SUM_IRATE || functionId == TSDB_FUNC_AVG_RATE || + functionId == TSDB_FUNC_AVG_IRATE) { return true; } } @@ -3060,17 +3298,17 @@ void vnodeCheckIfDataExists(SQueryRuntimeEnv *pRuntimeEnv, SMeterObj *pMeterObj, setQueryStatus(pQuery, QUERY_NOT_COMPLETED); } -static void doGetAlignedIntervalQueryRangeImpl(SQuery *pQuery, int64_t pKey, int64_t keyFirst, int64_t keyLast, - int64_t *actualSkey, int64_t *actualEkey, int64_t *skey, int64_t *ekey) { +void doGetAlignedIntervalQueryRangeImpl(SQuery *pQuery, int64_t pKey, int64_t keyFirst, int64_t keyLast, + int64_t *actualSkey, int64_t *actualEkey, int64_t *skey, int64_t *ekey) { assert(pKey >= keyFirst && pKey <= keyLast); - *skey = taosGetIntervalStartTimestamp(pKey, pQuery->nAggTimeInterval, pQuery->intervalTimeUnit, pQuery->precision); + *skey = taosGetIntervalStartTimestamp(pKey, pQuery->intervalTime, pQuery->intervalTimeUnit, pQuery->precision); - if (keyFirst > (INT64_MAX - pQuery->nAggTimeInterval)) { + if (keyFirst > (INT64_MAX - pQuery->intervalTime)) { /* - * if the actualSkey > INT64_MAX - pQuery->nAggTimeInterval, the query duration between + * if the actualSkey > INT64_MAX - pQuery->intervalTime, the query duration between * actualSkey and actualEkey must be less than one interval.Therefore, no need to adjust the query ranges. */ - assert(keyLast - keyFirst < pQuery->nAggTimeInterval); + assert(keyLast - keyFirst < pQuery->intervalTime); *actualSkey = keyFirst; *actualEkey = keyLast; @@ -3079,7 +3317,7 @@ static void doGetAlignedIntervalQueryRangeImpl(SQuery *pQuery, int64_t pKey, int return; } - *ekey = *skey + pQuery->nAggTimeInterval - 1; + *ekey = *skey + pQuery->intervalTime - 1; if (*skey < keyFirst) { *actualSkey = keyFirst; @@ -3094,42 +3332,6 @@ static void doGetAlignedIntervalQueryRangeImpl(SQuery *pQuery, int64_t pKey, int } } -static void getAlignedIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key, TSKEY skey, TSKEY ekey) { - SQuery *pQuery = pRuntimeEnv->pQuery; - if (pQuery->nAggTimeInterval == 0 || (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { - return; - } - - TSKEY skey2 = MIN(skey, ekey); - TSKEY ekey2 = MAX(skey, ekey); - - // the actual first query range in skey1 and ekey1 - TSKEY skey1, ekey1; - - TSKEY windowSKey = 0, windowEKey = 0; - doGetAlignedIntervalQueryRangeImpl(pQuery, key, skey2, ekey2, &skey1, &ekey1, &windowSKey, &windowEKey); - - if (QUERY_IS_ASC_QUERY(pQuery)) { - pQuery->skey = skey1; - pQuery->ekey = ekey1; - - pRuntimeEnv->intervalWindow = (STimeWindow) {.skey = windowSKey, .ekey = windowEKey}; - - assert(pQuery->skey <= pQuery->ekey && - pRuntimeEnv->intervalWindow.skey + (pQuery->nAggTimeInterval - 1) == pRuntimeEnv->intervalWindow.ekey); - } else { - pQuery->skey = ekey1; - pQuery->ekey = skey1; - - pRuntimeEnv->intervalWindow = (STimeWindow) {.skey = windowEKey, .ekey = windowSKey}; - - assert(pQuery->skey >= pQuery->ekey && - pRuntimeEnv->intervalWindow.skey - (pQuery->nAggTimeInterval - 1) == pRuntimeEnv->intervalWindow.ekey); - } - - pQuery->lastKey = pQuery->skey; -} - static void getOneRowFromDataBlock(SQueryRuntimeEnv *pRuntimeEnv, char **dst, int32_t pos) { SQuery *pQuery = pRuntimeEnv->pQuery; @@ -3139,7 +3341,7 @@ static void getOneRowFromDataBlock(SQueryRuntimeEnv *pRuntimeEnv, char **dst, in } } -static bool getNeighborPoints(SMeterQuerySupportObj *pSupporter, SMeterObj *pMeterObj, +static bool getNeighborPoints(STableQuerySupportObj *pSupporter, SMeterObj *pMeterObj, SPointInterpoSupporter *pPointInterpSupporter) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; @@ -3244,7 +3446,7 @@ static bool getNeighborPoints(SMeterQuerySupportObj *pSupporter, SMeterObj *pMet return true; } -static bool doGetQueryPos(TSKEY key, SMeterQuerySupportObj *pSupporter, SPointInterpoSupporter *pPointInterpSupporter) { +static bool doGetQueryPos(TSKEY key, STableQuerySupportObj *pSupporter, SPointInterpoSupporter *pPointInterpSupporter) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; SMeterObj * pMeterObj = pRuntimeEnv->pMeterObj; @@ -3254,7 +3456,6 @@ static bool doGetQueryPos(TSKEY key, SMeterQuerySupportObj *pSupporter, SPointIn if (isPointInterpoQuery(pQuery)) { /* no qualified data in this query range */ return getNeighborPoints(pSupporter, pMeterObj, pPointInterpSupporter); } else { - getAlignedIntervalQueryRange(pRuntimeEnv, key, pQuery->skey, pQuery->ekey); return true; } } else { // key > pQuery->ekey, abort for normal query, continue for interp query @@ -3266,7 +3467,7 @@ static bool doGetQueryPos(TSKEY key, SMeterQuerySupportObj *pSupporter, SPointIn } } -static bool doSetDataInfo(SMeterQuerySupportObj *pSupporter, SPointInterpoSupporter *pPointInterpSupporter, +static bool doSetDataInfo(STableQuerySupportObj *pSupporter, SPointInterpoSupporter *pPointInterpSupporter, SMeterObj *pMeterObj, TSKEY nextKey) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; @@ -3286,13 +3487,12 @@ static bool doSetDataInfo(SMeterQuerySupportObj *pSupporter, SPointInterpoSuppor return getNeighborPoints(pSupporter, pMeterObj, pPointInterpSupporter); } else { - getAlignedIntervalQueryRange(pRuntimeEnv, nextKey, pQuery->skey, pQuery->ekey); return true; } } // TODO refactor code, the best way to implement the last_row is utilizing the iterator -bool normalizeUnBoundLastRowQuery(SMeterQuerySupportObj *pSupporter, SPointInterpoSupporter *pPointInterpSupporter) { +bool normalizeUnBoundLastRowQuery(STableQuerySupportObj *pSupporter, SPointInterpoSupporter *pPointInterpSupporter) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; @@ -3354,12 +3554,49 @@ bool normalizeUnBoundLastRowQuery(SMeterQuerySupportObj *pSupporter, SPointInter return getNeighborPoints(pSupporter, pMeterObj, pPointInterpSupporter); } +static int64_t getGreaterEqualTimestamp(SQueryRuntimeEnv *pRuntimeEnv) { + SQuery * pQuery = pRuntimeEnv->pQuery; + SMeterObj * pMeterObj = pRuntimeEnv->pMeterObj; + __block_search_fn_t searchFn = vnodeSearchKeyFunc[pMeterObj->searchAlgorithm]; + + if (QUERY_IS_ASC_QUERY(pQuery)) { + return -1; + } + + TSKEY key = -1; + + SPositionInfo p = {0}; + { // todo refactor save the context + savePointPosition(&p, pQuery->fileId, pQuery->slot, pQuery->pos); + } + + SWAP(pQuery->skey, pQuery->ekey, TSKEY); + pQuery->lastKey = pQuery->skey; + pQuery->order.order ^= 1u; + + if (getQualifiedDataBlock(pMeterObj, pRuntimeEnv, QUERY_RANGE_GREATER_EQUAL, searchFn)) { + key = getTimestampInDiskBlock(pRuntimeEnv, pQuery->pos); + } else { // set no data in file + key = getQueryStartPositionInCache(pRuntimeEnv, &pQuery->slot, &pQuery->pos, false); + } + + SWAP(pQuery->skey, pQuery->ekey, TSKEY); + pQuery->order.order ^= 1u; + pQuery->lastKey = pQuery->skey; + + pQuery->fileId = p.fileId; + pQuery->pos = p.pos; + pQuery->slot = p.slot; + + return key; +} + /** * determine the first query range, according to raw query range [skey, ekey] and group-by interval. * the time interval for aggregating is not enforced to check its validation, the minimum interval is not less than * 10ms, which is guaranteed by parser at client-side */ -bool normalizedFirstQueryRange(bool dataInDisk, bool dataInCache, SMeterQuerySupportObj *pSupporter, +bool normalizedFirstQueryRange(bool dataInDisk, bool dataInCache, STableQuerySupportObj *pSupporter, SPointInterpoSupporter *pPointInterpSupporter, int64_t *key) { SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; @@ -3473,7 +3710,7 @@ int64_t loadRequiredBlockIntoMem(SQueryRuntimeEnv *pRuntimeEnv, SPositionInfo *p * load the file metadata into buffer first, then the specific data block. * currently opened file is not the start file, reset to the start file */ - int32_t fileIdx = vnodeGetVnodeHeaderFileIdx(&pQuery->fileId, pRuntimeEnv, pQuery->order.order); + int32_t fileIdx = vnodeGetVnodeHeaderFileIndex(&pQuery->fileId, pRuntimeEnv, pQuery->order.order); if (fileIdx < 0) { // ignore the files on disk dError("QInfo:%p failed to get data file:%d", GET_QINFO_ADDR(pQuery), pQuery->fileId); position->fileId = -1; @@ -3565,7 +3802,7 @@ static void vnodeRecordAllFiles(SQInfo *pQInfo, int32_t vnodeId) { struct dirent *pEntry = NULL; size_t alloc = 4; // default allocated size - SQueryFilesInfo *pVnodeFilesInfo = &(pQInfo->pMeterQuerySupporter->runtimeEnv.vnodeFileInfo); + SQueryFilesInfo *pVnodeFilesInfo = &(pQInfo->pTableQuerySupporter->runtimeEnv.vnodeFileInfo); pVnodeFilesInfo->vnodeId = vnodeId; sprintf(pVnodeFilesInfo->dbFilePathPrefix, "%s/vnode%d/db/", tsDirectory, vnodeId); @@ -3721,9 +3958,9 @@ static void changeExecuteScanOrder(SQuery *pQuery, bool metricQuery) { // in case of point-interpolation query, use asc order scan char msg[] = "QInfo:%p scan order changed for %s query, old:%d, new:%d, qrange exchanged, old qrange:%" PRId64 "-%" PRId64 - ", " - "new qrange:%" PRId64 "-%" PRId64; + ", new qrange:%" PRId64 "-%" PRId64; + // todo handle the case the the order irrelevant query type mixed up with order critical query type // descending order query for last_row query if (isFirstLastRowQuery(pQuery)) { dTrace("QInfo:%p scan order changed for last_row query, old:%d, new:%d", GET_QINFO_ADDR(pQuery), @@ -3740,7 +3977,7 @@ static void changeExecuteScanOrder(SQuery *pQuery, bool metricQuery) { return; } - if (isPointInterpoQuery(pQuery) && pQuery->nAggTimeInterval == 0) { + if (isPointInterpoQuery(pQuery) && pQuery->intervalTime == 0) { if (!QUERY_IS_ASC_QUERY(pQuery)) { dTrace(msg, GET_QINFO_ADDR(pQuery), "interp", pQuery->order.order, TSQL_SO_ASC, pQuery->skey, pQuery->ekey, pQuery->ekey, pQuery->skey); @@ -3751,7 +3988,7 @@ static void changeExecuteScanOrder(SQuery *pQuery, bool metricQuery) { return; } - if (pQuery->nAggTimeInterval == 0) { + if (pQuery->intervalTime == 0) { if (onlyFirstQuery(pQuery)) { if (!QUERY_IS_ASC_QUERY(pQuery)) { dTrace(msg, GET_QINFO_ADDR(pQuery), "only-first", pQuery->order.order, TSQL_SO_ASC, pQuery->skey, pQuery->ekey, @@ -3812,8 +4049,7 @@ static int32_t doSkipDataBlock(SQueryRuntimeEnv *pRuntimeEnv) { void *pBlock = getGenericDataBlock(pMeterObj, pRuntimeEnv, pQuery->slot); assert(pBlock != NULL); - int32_t blockType = IS_DISK_DATA_BLOCK(pQuery) ? BLK_FILE_BLOCK : BLK_CACHE_BLOCK; - SBlockInfo blockInfo = getBlockBasicInfo(pRuntimeEnv, pBlock, blockType); + SBlockInfo blockInfo = getBlockInfo(pRuntimeEnv); int32_t maxReads = (QUERY_IS_ASC_QUERY(pQuery)) ? blockInfo.size - pQuery->pos : pQuery->pos + 1; assert(maxReads >= 0); @@ -3843,9 +4079,9 @@ void forwardQueryStartPosition(SQueryRuntimeEnv *pRuntimeEnv) { } void *pBlock = getGenericDataBlock(pMeterObj, pRuntimeEnv, pQuery->slot); + assert(pBlock != NULL); - int32_t blockType = (IS_DISK_DATA_BLOCK(pQuery)) ? BLK_FILE_BLOCK : BLK_CACHE_BLOCK; - SBlockInfo blockInfo = getBlockBasicInfo(pRuntimeEnv, pBlock, blockType); + SBlockInfo blockInfo = getBlockInfo(pRuntimeEnv); // get the qualified data that can be skipped int32_t maxReads = (QUERY_IS_ASC_QUERY(pQuery)) ? blockInfo.size - pQuery->pos : pQuery->pos + 1; @@ -3855,71 +4091,186 @@ void forwardQueryStartPosition(SQueryRuntimeEnv *pRuntimeEnv) { updateOffsetVal(pRuntimeEnv, &blockInfo, pBlock); } else { pQuery->limit.offset -= maxReads; + // update the lastkey, since the following skip operation may traverse to another media. update the lastkey first. pQuery->lastKey = (QUERY_IS_ASC_QUERY(pQuery)) ? blockInfo.keyLast + 1 : blockInfo.keyFirst - 1; doSkipDataBlock(pRuntimeEnv); } } -static bool forwardQueryStartPosIfNeeded(SQInfo *pQInfo, SMeterQuerySupportObj *pSupporter, bool dataInDisk, +static bool forwardQueryStartPosIfNeeded(SQInfo *pQInfo, STableQuerySupportObj *pSupporter, bool dataInDisk, bool dataInCache) { - SQuery *pQuery = &pQInfo->query; + SQuery * pQuery = &pQInfo->query; + SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; /* if queried with value filter, do NOT forward query start position */ - if (pQuery->numOfFilterCols > 0 || pSupporter->runtimeEnv.pTSBuf != NULL) { + if (pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTSBuf != NULL) { return true; } if (pQuery->limit.offset > 0 && (!isTopBottomQuery(pQuery)) && pQuery->interpoType == TSDB_INTERPO_NONE) { /* * 1. for top/bottom query, the offset applies to the final result, not here - * 2. for interval without interpolation query we forward pQuery->nAggTimeInterval at a time for - * pQuery->limit.offset times. Since hole exists, pQuery->nAggTimeInterval*pQuery->limit.offset value is + * 2. for interval without interpolation query we forward pQuery->intervalTime at a time for + * pQuery->limit.offset times. Since hole exists, pQuery->intervalTime*pQuery->limit.offset value is * not valid. otherwise, we only forward pQuery->limit.offset number of points */ - if (pQuery->nAggTimeInterval > 0) { - while (1) { - /* - * the skey may not be the aligned start time - * 1. it is the value of first existed data point, therefore, the range - * between skey and ekey may be less than the interval value. - * 2. the ekey may not be the actual end value of time interval, in case of the - */ - if (QUERY_IS_ASC_QUERY(pQuery)) { - pQuery->skey = pQuery->ekey + 1; - } else { - pQuery->skey = pQuery->ekey - 1; - } + if (isIntervalQuery(pQuery)) { + int16_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + __block_search_fn_t searchFn = vnodeSearchKeyFunc[pRuntimeEnv->pMeterObj->searchAlgorithm]; + SWindowResInfo * pWindowResInfo = &pRuntimeEnv->windowResInfo; - // boundary check - if ((pQuery->skey > pSupporter->rawEKey && QUERY_IS_ASC_QUERY(pQuery)) || - (pQuery->skey < pSupporter->rawEKey && !QUERY_IS_ASC_QUERY(pQuery))) { - setQueryStatus(pQuery, QUERY_COMPLETED); + TSKEY * primaryKey = (TSKEY *)pRuntimeEnv->primaryColBuffer->data; + STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQuery); - sem_post(&pQInfo->dataReady); - pQInfo->over = 1; - return false; - } + while (pQuery->limit.offset > 0) { + SBlockInfo blockInfo = getBlockInfo(pRuntimeEnv); + + STimeWindow tw = win; + getNextTimeWindow(pQuery, &tw); + + // next time window starts from current data block + if ((tw.skey <= blockInfo.keyLast && QUERY_IS_ASC_QUERY(pQuery)) || + (tw.ekey >= blockInfo.keyFirst && !QUERY_IS_ASC_QUERY(pQuery))) { + + // query completed + if ((tw.skey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (tw.ekey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { + setQueryStatus(pQuery, QUERY_COMPLETED); + break; + } - /* - * NOTE: the end key must be set the last value, to cover all possible - * data. Otherwise, it may contain no data with only one interval time range - */ - pQuery->ekey = pSupporter->rawEKey; - pQuery->lastKey = pQuery->skey; - - // todo opt performance - if (normalizedFirstQueryRange(dataInDisk, dataInCache, pSupporter, NULL, NULL) == false) { - sem_post(&pQInfo->dataReady); // hack for next read for empty return - pQInfo->over = 1; - return false; + // check its position in this block to make sure this time window covers data. + if (IS_DISK_DATA_BLOCK(pQuery)) { + getTimestampInDiskBlock(pRuntimeEnv, 0); + } + + tw = win; + int32_t startPos = getNextQualifiedWindow(pRuntimeEnv, &tw, pWindowResInfo, &blockInfo, primaryKey, searchFn); + assert(startPos >= 0); + + pQuery->limit.offset -= 1; + + // set the abort info + pQuery->pos = startPos; + pQuery->lastKey = primaryKey[startPos]; + pWindowResInfo->prevSKey = tw.skey; + win = tw; + continue; + } else { + moveToNextBlock(pRuntimeEnv, step, searchFn, false); + if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)) { + break; + } + + blockInfo = getBlockInfo(pRuntimeEnv); + if ((blockInfo.keyFirst > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (blockInfo.keyLast < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { + setQueryStatus(pQuery, QUERY_COMPLETED); + break; + } + + // set the window that start from the next data block + TSKEY key = (QUERY_IS_ASC_QUERY(pQuery))? blockInfo.keyFirst:blockInfo.keyLast; + STimeWindow n = getActiveTimeWindow(pWindowResInfo, key, pQuery); + + // next data block are still covered by current time window + if (n.skey == win.skey && n.ekey == win.ekey) { + // do nothing + } else { + pQuery->limit.offset -= 1; + + // query completed + if ((n.skey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (n.ekey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { + setQueryStatus(pQuery, QUERY_COMPLETED); + break; + } + + // set the abort info + pQuery->pos = QUERY_IS_ASC_QUERY(pQuery)? 0:blockInfo.size-1; + pQuery->lastKey = QUERY_IS_ASC_QUERY(pQuery)? blockInfo.keyFirst:blockInfo.keyLast; + pWindowResInfo->prevSKey = n.skey; + + win = n; + + if (pQuery->limit.offset == 0 && IS_DISK_DATA_BLOCK(pQuery)) { + getTimestampInDiskBlock(pRuntimeEnv, 0); + } + } } + +// if (win.ekey <= blockInfo.keyLast) { +// pQuery->limit.offset -= 1; +// +// if (win.ekey == blockInfo.keyLast) { +// moveToNextBlock(pRuntimeEnv, step, searchFn, false); +// if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)) { +// break; +// } +// +// // next block does not included in time range, abort query +// blockInfo = getBlockInfo(pRuntimeEnv); +// if ((blockInfo.keyFirst > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || +// (blockInfo.keyLast < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { +// setQueryStatus(pQuery, QUERY_COMPLETED); +// break; +// } +// +// // set the window that start from the next data block +// win = getActiveTimeWindow(pWindowResInfo, blockInfo.keyFirst, pQuery); +// } else { +// // the time window is closed in current data block, load disk file block into memory to +// // check the next time window +// if (IS_DISK_DATA_BLOCK(pQuery)) { +// getTimestampInDiskBlock(pRuntimeEnv, 0); +// } +// +// STimeWindow nextWin = win; +// int32_t startPos = +// getNextQualifiedWindow(pRuntimeEnv, &nextWin, pWindowResInfo, &blockInfo, primaryKey, searchFn); +// +// if (startPos < 0) { // failed to find the qualified time window +// assert((nextWin.skey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || +// (nextWin.ekey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))); +// +// setQueryStatus(pQuery, QUERY_COMPLETED); +// break; +// } else { // set the abort info +// pQuery->pos = startPos; +// pQuery->lastKey = primaryKey[startPos]; +// win = nextWin; +// } +// } +// +// continue; +// } +// +// moveToNextBlock(pRuntimeEnv, step, searchFn, false); +// if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)) { +// break; +// } +// +// blockInfo = getBlockInfo(pRuntimeEnv); +// if ((blockInfo.keyFirst > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || +// (blockInfo.keyLast < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { +// setQueryStatus(pQuery, QUERY_COMPLETED); +// break; +// } + } - if (--pQuery->limit.offset == 0) { - break; + if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK | QUERY_COMPLETED) || pQuery->limit.offset > 0) { + setQueryStatus(pQuery, QUERY_COMPLETED); + + sem_post(&pQInfo->dataReady); // hack for next read for empty return; + pQInfo->over = 1; + return false; + } else { + if (IS_DISK_DATA_BLOCK(pQuery)) { + getTimestampInDiskBlock(pRuntimeEnv, 0); } } - } else { + } else { // forward the start position for projection query forwardQueryStartPosition(&pSupporter->runtimeEnv); if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)) { setQueryStatus(pQuery, QUERY_COMPLETED); @@ -4005,7 +4356,7 @@ void pointInterpSupporterSetData(SQInfo *pQInfo, SPointInterpoSupporter *pPointI } SQuery * pQuery = &pQInfo->query; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; int32_t count = 1; @@ -4136,71 +4487,37 @@ void pointInterpSupporterDestroy(SPointInterpoSupporter *pPointInterpSupport) { pPointInterpSupport->numOfCols = 0; } -static void allocMemForInterpo(SMeterQuerySupportObj *pSupporter, SQuery *pQuery, SMeterObj *pMeterObj) { - if (pQuery->interpoType != TSDB_INTERPO_NONE) { - assert(pQuery->nAggTimeInterval > 0 || (pQuery->nAggTimeInterval == 0 && isPointInterpoQuery(pQuery))); - - if (pQuery->nAggTimeInterval > 0) { - pSupporter->runtimeEnv.pInterpoBuf = malloc(POINTER_BYTES * pQuery->numOfOutputCols); - - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - pSupporter->runtimeEnv.pInterpoBuf[i] = - calloc(1, sizeof(tFilePage) + pQuery->pSelectExpr[i].resBytes * pMeterObj->pointsPerFileBlock); - } - } - } -} - -static int32_t createQueryOutputBuffer(SMeterQuerySupportObj *pSupporter, SQuery *pQuery, bool isSTableQuery) { - SQueryRuntimeEnv* pRuntimeEnv = &pSupporter->runtimeEnv; - - int32_t numOfRows = 0; - - if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { - numOfRows = 10000; - } else { - numOfRows = pSupporter->pSidSet->numOfSubSet; - } - - createResultBuf(&pRuntimeEnv->pResultBuf, 100, pQuery->rowSize); - - // total number of initial results - pSupporter->pResult = calloc(numOfRows, sizeof(SOutputRes)); - if (pSupporter->pResult == NULL) { - return TSDB_CODE_SERV_OUT_OF_MEMORY; - } - - int32_t pageId = -1; - tFilePage* page = NULL; - - for (int32_t k = 0; k < numOfRows; ++k) { - SOutputRes *pOneRes = &pSupporter->pResult[k]; - pOneRes->nAlloc = 1; +static void allocMemForInterpo(STableQuerySupportObj *pSupporter, SQuery *pQuery, SMeterObj *pMeterObj) { + if (pQuery->interpoType != TSDB_INTERPO_NONE) { + assert(isIntervalQuery(pQuery) || (pQuery->intervalTime == 0 && isPointInterpoQuery(pQuery))); - /* - * for single table top/bottom query, the output for group by normal column, the output rows is - * equals to the maximum rows, instead of 1. - */ - if (!isSTableQuery && isTopBottomQuery(pQuery)) { - assert(pQuery->numOfOutputCols > 1); + if (isIntervalQuery(pQuery)) { + pSupporter->runtimeEnv.pInterpoBuf = malloc(POINTER_BYTES * pQuery->numOfOutputCols); - SSqlFunctionExpr *pExpr = &pQuery->pSelectExpr[1]; - pOneRes->nAlloc = pExpr->pBase.arg[0].argValue.i64; + for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { + pSupporter->runtimeEnv.pInterpoBuf[i] = + calloc(1, sizeof(tFilePage) + pQuery->pSelectExpr[i].resBytes * pMeterObj->pointsPerFileBlock); + } } + } +} - if (page == NULL || page->numOfElems >= pRuntimeEnv->numOfRowsPerPage) { - page = getNewDataBuf(pRuntimeEnv->pResultBuf, 0, &pageId); - } - - assert(pageId >= 0); - - SPosInfo posInfo = {.pageId = pageId, .rowId = page->numOfElems}; - - createQueryResultBuf(pRuntimeEnv, pOneRes, isSTableQuery, &posInfo); - page->numOfElems += 1; // next row is available +static int32_t getInitialPageNum(STableQuerySupportObj *pSupporter) { + SQuery *pQuery = pSupporter->runtimeEnv.pQuery; + + int32_t num = 0; + + if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) { + num = 128; + } else if (isIntervalQuery(pQuery)) { // time window query, allocate one page for each table + num = pSupporter->numOfMeters; + } else { // for super table query, one page for each subset + num = pSupporter->pSidSet->numOfSubSet; } - return TSDB_CODE_SUCCESS; + assert(num > 0); + + return num; } static int32_t allocateRuntimeEnvBuf(SQueryRuntimeEnv *pRuntimeEnv, SMeterObj *pMeterObj) { @@ -4259,34 +4576,35 @@ _error_clean: return TSDB_CODE_SERV_OUT_OF_MEMORY; } -static int32_t getRowParamForMultiRowsOutput(SQuery* pQuery, bool isSTableQuery) { +static int32_t getRowParamForMultiRowsOutput(SQuery *pQuery, bool isSTableQuery) { int32_t rowparam = 1; - + if (isTopBottomQuery(pQuery) && (!isSTableQuery)) { rowparam = pQuery->pSelectExpr[1].pBase.arg->argValue.i64; } - + return rowparam; } -static int32_t getNumOfRowsInResultPage(SQuery* pQuery, bool isSTableQuery) { +static int32_t getNumOfRowsInResultPage(SQuery *pQuery, bool isSTableQuery) { int32_t rowSize = pQuery->rowSize * getRowParamForMultiRowsOutput(pQuery, isSTableQuery); return (DEFAULT_INTERN_BUF_SIZE - sizeof(tFilePage)) / rowSize; } -static char* getPosInResultPage(SQueryRuntimeEnv* pRuntimeEnv, int32_t columnIndex, SOutputRes* pResult) { - SQuery* pQuery = pRuntimeEnv->pQuery; - tFilePage* page = getResultBufferPageById(pRuntimeEnv->pResultBuf, pResult->pos.pageId); - +static char *getPosInResultPage(SQueryRuntimeEnv *pRuntimeEnv, int32_t columnIndex, SWindowResult *pResult) { + assert(pResult != NULL && pRuntimeEnv != NULL); + + SQuery * pQuery = pRuntimeEnv->pQuery; + tFilePage *page = getResultBufferPageById(pRuntimeEnv->pResultBuf, pResult->pos.pageId); + int32_t numOfRows = getNumOfRowsInResultPage(pQuery, pRuntimeEnv->stableQuery); int32_t realRowId = pResult->pos.rowId * getRowParamForMultiRowsOutput(pQuery, pRuntimeEnv->stableQuery); - - return ((char*)page->data) + pRuntimeEnv->offset[columnIndex] * numOfRows + - pQuery->pSelectExpr[columnIndex].resBytes * realRowId; + + return ((char *)page->data) + pRuntimeEnv->offset[columnIndex] * numOfRows + + pQuery->pSelectExpr[columnIndex].resBytes * realRowId; } -int32_t vnodeQuerySingleMeterPrepare(SQInfo *pQInfo, SMeterObj *pMeterObj, SMeterQuerySupportObj *pSupporter, - void *param) { +int32_t vnodeQueryTablePrepare(SQInfo *pQInfo, SMeterObj *pMeterObj, STableQuerySupportObj *pSupporter, void *param) { SQuery *pQuery = &pQInfo->query; int32_t code = TSDB_CODE_SUCCESS; @@ -4354,10 +4672,13 @@ int32_t vnodeQuerySingleMeterPrepare(SQInfo *pQInfo, SMeterObj *pMeterObj, SMete } vnodeRecordAllFiles(pQInfo, pMeterObj->vnode); - + pRuntimeEnv->numOfRowsPerPage = getNumOfRowsInResultPage(pQuery, false); - if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { - if ((code = createQueryOutputBuffer(pSupporter, pQuery, false)) != TSDB_CODE_SUCCESS) { + if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || isIntervalQuery(pQuery)) { + int32_t rows = getInitialPageNum(pSupporter); + + code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, rows, pQuery->rowSize); + if (code != TSDB_CODE_SUCCESS) { return code; } @@ -4368,7 +4689,7 @@ int32_t vnodeQuerySingleMeterPrepare(SQInfo *pQInfo, SMeterObj *pMeterObj, SMete type = TSDB_DATA_TYPE_TIMESTAMP; } - initSlidingWindowInfo(&pRuntimeEnv->swindowResInfo, 3, type, pQuery->rowSize, pSupporter->pResult); + initWindowResInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv, rows, 4096, type); } pSupporter->rawSKey = pQuery->skey; @@ -4394,17 +4715,20 @@ int32_t vnodeQuerySingleMeterPrepare(SQInfo *pQInfo, SMeterObj *pMeterObj, SMete pointInterpSupporterDestroy(&interpInfo); return TSDB_CODE_SUCCESS; } - } else { - // find the skey and ekey in case of sliding query - // todo refactor - if (pQuery->slidingTime > 0 && pQuery->nAggTimeInterval > 0) { - int64_t skey = 0; + } else { // find the skey and ekey in case of sliding query + if (isIntervalQuery(pQuery)) { + STimeWindow win = {0}; - SWAP(pQuery->skey, pQuery->ekey, int64_t); - pQuery->order.order ^= 1; - pQuery->lastKey = pQuery->skey; + // find the minimum value for descending order query + TSKEY minKey = -1; + if (!QUERY_IS_ASC_QUERY(pQuery)) { + minKey = getGreaterEqualTimestamp(pRuntimeEnv); + } - if (normalizedFirstQueryRange(dataInDisk, dataInCache, pSupporter, &interpInfo, &skey) == false) { + int64_t skey = 0; + if ((normalizedFirstQueryRange(dataInDisk, dataInCache, pSupporter, &interpInfo, &skey) == false) || + (isFixedOutputQuery(pQuery) && !isTopBottomQuery(pQuery) && (pQuery->limit.offset > 0)) || + (isTopBottomQuery(pQuery) && pQuery->limit.offset >= pQuery->pSelectExpr[1].pBase.arg[0].argValue.i64)) { sem_post(&pQInfo->dataReady); pQInfo->over = 1; @@ -4412,36 +4736,29 @@ int32_t vnodeQuerySingleMeterPrepare(SQInfo *pQInfo, SMeterObj *pMeterObj, SMete return TSDB_CODE_SUCCESS; } - pQuery->skey = skey; - - pQuery->order.order ^= 1; - SWAP(pQuery->skey, pQuery->ekey, int64_t); - - int64_t ekey = 0; - pQuery->lastKey = pQuery->skey; - if (normalizedFirstQueryRange(dataInDisk, dataInCache, pSupporter, &interpInfo, &ekey) == false) { - // + if (!QUERY_IS_ASC_QUERY(pQuery)) { + win.skey = minKey; + win.ekey = skey; + } else { + win.skey = skey; + win.ekey = pQuery->ekey; } - pQuery->skey = ekey; - TSKEY skey1, ekey1; TSKEY windowSKey = 0, windowEKey = 0; - TSKEY minKey = MIN(pQuery->skey, pQuery->ekey); - TSKEY maxKey = MAX(pQuery->skey, pQuery->ekey); - - doGetAlignedIntervalQueryRangeImpl(pQuery, minKey, minKey, maxKey, &skey1, &ekey1, &windowSKey, &windowEKey); - pRuntimeEnv->swindowResInfo.startTime = windowSKey; - - pSupporter->rawSKey = pQuery->skey; - pSupporter->rawEKey = pQuery->ekey; + doGetAlignedIntervalQueryRangeImpl(pQuery, win.skey, win.skey, win.ekey, &skey1, &ekey1, &windowSKey, + &windowEKey); + pRuntimeEnv->windowResInfo.startTime = windowSKey; if (QUERY_IS_ASC_QUERY(pQuery)) { - pRuntimeEnv->swindowResInfo.prevSKey = windowSKey; + pRuntimeEnv->windowResInfo.prevSKey = windowSKey; } else { - pRuntimeEnv->swindowResInfo.prevSKey = windowSKey + ((pQuery->skey - windowSKey) / pQuery->slidingTime) * pQuery->slidingTime; + pRuntimeEnv->windowResInfo.prevSKey = + windowSKey + ((win.ekey - windowSKey) / pQuery->slidingTime) * pQuery->slidingTime; } + + pQuery->over = QUERY_NOT_COMPLETED; } else { int64_t ekey = 0; if ((normalizedFirstQueryRange(dataInDisk, dataInCache, pSupporter, &interpInfo, &ekey) == false) || @@ -4467,7 +4784,7 @@ int32_t vnodeQuerySingleMeterPrepare(SQInfo *pQInfo, SMeterObj *pMeterObj, SMete return TSDB_CODE_SUCCESS; } - int64_t rs = taosGetIntervalStartTimestamp(pSupporter->rawSKey, pQuery->nAggTimeInterval, pQuery->intervalTimeUnit, + int64_t rs = taosGetIntervalStartTimestamp(pSupporter->rawSKey, pQuery->intervalTime, pQuery->intervalTimeUnit, pQuery->precision); taosInitInterpoInfo(&pRuntimeEnv->interpoInfo, pQuery->order.order, rs, 0, 0); allocMemForInterpo(pSupporter, pQuery, pMeterObj); @@ -4479,17 +4796,17 @@ int32_t vnodeQuerySingleMeterPrepare(SQInfo *pQInfo, SMeterObj *pMeterObj, SMete // the pQuery->skey is changed during normalizedFirstQueryRange, so set the newest lastkey value pQuery->lastKey = pQuery->skey; pRuntimeEnv->stableQuery = false; - + return TSDB_CODE_SUCCESS; } void vnodeQueryFreeQInfoEx(SQInfo *pQInfo) { - if (pQInfo == NULL || pQInfo->pMeterQuerySupporter == NULL) { + if (pQInfo == NULL || pQInfo->pTableQuerySupporter == NULL) { return; } SQuery * pQuery = &pQInfo->query; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; teardownQueryRuntimeEnv(&pSupporter->runtimeEnv); tfree(pSupporter->pMeterSidExtInfo); @@ -4500,16 +4817,16 @@ void vnodeQueryFreeQInfoEx(SQInfo *pQInfo) { } if (pSupporter->pSidSet != NULL || isGroupbyNormalCol(pQInfo->query.pGroupbyExpr) || - (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { + isIntervalQuery(pQuery)) { int32_t size = 0; - if (isGroupbyNormalCol(pQInfo->query.pGroupbyExpr) || (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { + if (isGroupbyNormalCol(pQInfo->query.pGroupbyExpr) || isIntervalQuery(pQuery)) { size = 10000; } else if (pSupporter->pSidSet != NULL) { size = pSupporter->pSidSet->numOfSubSet; } for (int32_t i = 0; i < size; ++i) { - destroyGroupResultBuf(&pSupporter->pResult[i], pQInfo->query.numOfOutputCols); + // destroyTimeWindowRes(&pSupporter->pResult[i], pQInfo->query.numOfOutputCols); } } @@ -4524,12 +4841,11 @@ void vnodeQueryFreeQInfoEx(SQInfo *pQInfo) { tfree(pSupporter->pMeterDataInfo); - tfree(pSupporter->pResult); - tfree(pQInfo->pMeterQuerySupporter); + tfree(pQInfo->pTableQuerySupporter); } -int32_t vnodeMultiMeterQueryPrepare(SQInfo *pQInfo, SQuery *pQuery, void *param) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; +int32_t vnodeSTableQueryPrepare(SQInfo *pQInfo, SQuery *pQuery, void *param) { + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; if ((QUERY_IS_ASC_QUERY(pQuery) && (pQuery->skey > pQuery->ekey)) || (!QUERY_IS_ASC_QUERY(pQuery) && (pQuery->ekey > pQuery->skey))) { @@ -4592,35 +4908,36 @@ int32_t vnodeMultiMeterQueryPrepare(SQInfo *pQInfo, SQuery *pQuery, void *param) tSidSetSort(pSupporter->pSidSet); vnodeRecordAllFiles(pQInfo, pTable->vnode); - if ((ret = createQueryOutputBuffer(pSupporter, pQuery, true)) != TSDB_CODE_SUCCESS) { + int32_t size = getInitialPageNum(pSupporter); + ret = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, size, pQuery->rowSize); + if (ret != TSDB_CODE_SUCCESS) { return ret; } - if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) { // group by columns not tags; - int16_t type = getGroupbyColumnType(pQuery, pQuery->pGroupbyExpr); - initSlidingWindowInfo(&pRuntimeEnv->swindowResInfo, 4096, type, pQuery->rowSize, pSupporter->pResult); - } + if (pQuery->intervalTime == 0) { + int16_t type = TSDB_DATA_TYPE_NULL; - if (pQuery->nAggTimeInterval != 0 || isSumAvgRateQuery(pQuery)) { - // one page for each table at least - ret = createResultBuf(&pRuntimeEnv->pResultBuf, pSupporter->numOfMeters, pQuery->rowSize); - if (ret != TSDB_CODE_SUCCESS) { - return ret; + if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) { // group by columns not tags; + type = getGroupbyColumnType(pQuery, pQuery->pGroupbyExpr); + } else { + type = TSDB_DATA_TYPE_INT; // group id } + + initWindowResInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv, 512, 4096, type); } - + pRuntimeEnv->numOfRowsPerPage = getNumOfRowsInResultPage(pQuery, true); - + // metric query do not invoke interpolation, it will be done at the second-stage merge if (!isPointInterpoQuery(pQuery)) { pQuery->interpoType = TSDB_INTERPO_NONE; } - TSKEY revisedStime = taosGetIntervalStartTimestamp(pSupporter->rawSKey, pQuery->nAggTimeInterval, + TSKEY revisedStime = taosGetIntervalStartTimestamp(pSupporter->rawSKey, pQuery->intervalTime, pQuery->intervalTimeUnit, pQuery->precision); taosInitInterpoInfo(&pRuntimeEnv->interpoInfo, pQuery->order.order, revisedStime, 0, 0); pRuntimeEnv->stableQuery = true; - + return TSDB_CODE_SUCCESS; } @@ -4629,7 +4946,7 @@ int32_t vnodeMultiMeterQueryPrepare(SQInfo *pQInfo, SQuery *pQuery, void *param) * @param pQInfo */ void vnodeDecMeterRefcnt(SQInfo *pQInfo) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; if (pSupporter == NULL || pSupporter->numOfMeters == 1) { atomic_fetch_sub_32(&pQInfo->pObj->numOfQueries, 1); @@ -4685,7 +5002,7 @@ TSKEY getTimestampInDiskBlock(SQueryRuntimeEnv *pRuntimeEnv, int32_t index) { SMeterObj *pMeterObj = pRuntimeEnv->pMeterObj; - int32_t fileIndex = vnodeGetVnodeHeaderFileIdx(&pQuery->fileId, pRuntimeEnv, pQuery->order.order); + int32_t fileIndex = vnodeGetVnodeHeaderFileIndex(&pQuery->fileId, pRuntimeEnv, pQuery->order.order); dTrace("QInfo:%p vid:%d sid:%d id:%s, fileId:%d, slot:%d load data block due to primary key required", GET_QINFO_ADDR(pQuery), pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->fileId, pQuery->slot); @@ -4902,7 +5219,7 @@ static int32_t moveToNextBlock(SQueryRuntimeEnv *pRuntimeEnv, int32_t step, __bl } } else { // next block in the same file int32_t fid = pQuery->fileId; - fileIndex = vnodeGetVnodeHeaderFileIdx(&fid, pRuntimeEnv, pQuery->order.order); + fileIndex = vnodeGetVnodeHeaderFileIndex(&fid, pRuntimeEnv, pQuery->order.order); pQuery->slot += step; pQuery->pos = (step == QUERY_ASC_FORWARD_STEP) ? 0 : pQuery->pBlock[pQuery->slot].numOfPoints - 1; @@ -4929,59 +5246,58 @@ static int32_t moveToNextBlock(SQueryRuntimeEnv *pRuntimeEnv, int32_t step, __bl return DISK_DATA_LOADED; } -static void doHandleDataBlockImpl(SQueryRuntimeEnv *pRuntimeEnv, SBlockInfo *pblockInfo, __block_search_fn_t searchFn, - int32_t *numOfRes, int32_t blockLoadStatus, int32_t *forwardStep) { +static int32_t doHandleDataBlockImpl(SQueryRuntimeEnv *pRuntimeEnv, SBlockInfo *pBlockInfo, + __block_search_fn_t searchFn, int32_t blockLoadStatus, int32_t *forwardStep) { SQuery * pQuery = pRuntimeEnv->pQuery; SQueryCostSummary *pSummary = &pRuntimeEnv->summary; + int32_t numOfRes = 0; - TSKEY * primaryKeys = (TSKEY *)pRuntimeEnv->primaryColBuffer->data; - int64_t start = taosGetTimestampUs(); + if (IS_DISK_DATA_BLOCK(pQuery) && blockLoadStatus != DISK_DATA_LOADED) { + *forwardStep = pBlockInfo->size; + return numOfRes; + } + SField *pFields = NULL; if (IS_DISK_DATA_BLOCK(pQuery)) { - SCompBlock *pBlock = getDiskDataBlock(pQuery, pQuery->slot); - *pblockInfo = getBlockBasicInfo(pRuntimeEnv, pBlock, BLK_FILE_BLOCK); - - if (blockLoadStatus == DISK_DATA_LOADED) { - *forwardStep = applyFunctionsOnBlock(pRuntimeEnv, pblockInfo, primaryKeys, pQuery->pFields[pQuery->slot], - searchFn, numOfRes); - } else { - *forwardStep = pblockInfo->size; - } - - pSummary->fileTimeUs += (taosGetTimestampUs() - start); - } else { + pFields = pQuery->pFields[pQuery->slot]; + } else { // in case of cache data block, no need to load operation assert(vnodeIsDatablockLoaded(pRuntimeEnv, pRuntimeEnv->pMeterObj, -1, true) == DISK_BLOCK_NO_NEED_TO_LOAD); + pFields = NULL; + } + + int64_t start = taosGetTimestampUs(); - SCacheBlock *pBlock = getCacheDataBlock(pRuntimeEnv->pMeterObj, pRuntimeEnv, pQuery->slot); - *pblockInfo = getBlockBasicInfo(pRuntimeEnv, pBlock, BLK_CACHE_BLOCK); + *forwardStep = + tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, pFields, searchFn, &numOfRes, &pRuntimeEnv->windowResInfo); - *forwardStep = applyFunctionsOnBlock(pRuntimeEnv, pblockInfo, primaryKeys, NULL, searchFn, numOfRes); + int64_t elapsedTime = taosGetTimestampUs() - start; - pSummary->cacheTimeUs += (taosGetTimestampUs() - start); + if (IS_DISK_DATA_BLOCK(pQuery)) { + pSummary->fileTimeUs += elapsedTime; + } else { + pSummary->cacheTimeUs += elapsedTime; } -} -static void getNextLogicalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow* pTimeWindow) { - SQuery *pQuery = pRuntimeEnv->pQuery; + return numOfRes; +} +// previous time window may not be of the same size of pQuery->intervalTime +static void getNextTimeWindow(SQuery *pQuery, STimeWindow *pTimeWindow) { int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); - + pTimeWindow->skey += (pQuery->slidingTime * factor); - pTimeWindow->ekey += (pQuery->slidingTime * factor); + pTimeWindow->ekey = pTimeWindow->skey + (pQuery->intervalTime - 1); } static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) { - SQuery *pQuery = pRuntimeEnv->pQuery; - bool LOAD_DATA = true; + SQuery * pQuery = pRuntimeEnv->pQuery; + SMeterObj *pMeterObj = pRuntimeEnv->pMeterObj; - int32_t forwardStep = 0; + bool LOAD_DATA = true; int64_t cnt = 0; - SMeterObj *pMeterObj = pRuntimeEnv->pMeterObj; - __block_search_fn_t searchFn = vnodeSearchKeyFunc[pMeterObj->searchAlgorithm]; int32_t blockLoadStatus = DISK_DATA_LOADED; - SQueryCostSummary * pSummary = &pRuntimeEnv->summary; int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); @@ -5001,9 +5317,9 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) { return cnt; } - int32_t numOfRes = 0; - SBlockInfo blockInfo = {0}; - doHandleDataBlockImpl(pRuntimeEnv, &blockInfo, searchFn, &numOfRes, blockLoadStatus, &forwardStep); + int32_t forwardStep = 0; + SBlockInfo blockInfo = getBlockInfo(pRuntimeEnv); + /*int32_t numOfRes = */ doHandleDataBlockImpl(pRuntimeEnv, &blockInfo, searchFn, blockLoadStatus, &forwardStep); dTrace("QInfo:%p check data block, brange:%" PRId64 "-%" PRId64 ", fileId:%d, slot:%d, pos:%d, bstatus:%d, rows:%d, checked:%d", @@ -5016,90 +5332,66 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) { cnt += forwardStep; - if (queryCompleteInBlock(pQuery, &blockInfo, forwardStep)) { + if (queryPausedInCurrentBlock(pQuery, &blockInfo, forwardStep)) { int32_t nextPos = accessPos + step; /* - * set the next access position, nextPos only required by - * 1. interval query. - * 2. multi-output query that may cause buffer overflow. + * set the next access position, nextPos only required when the interval query and projection query + * that cause output buffer overflow. When the query is completed, no need to load the next block any more. */ - if (pQuery->nAggTimeInterval > 0 || - (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL) && pQuery->checkBufferInLoop == 1)) { + if (!Q_STATUS_EQUAL(pQuery->over, QUERY_COMPLETED) && Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)) { if (nextPos >= blockInfo.size || nextPos < 0) { moveToNextBlock(pRuntimeEnv, step, searchFn, !LOAD_DATA); // slot/pos/fileId is updated in moveToNextBlock function savePointPosition(&pRuntimeEnv->nextPos, pQuery->fileId, pQuery->slot, pQuery->pos); } else { - savePointPosition(&pRuntimeEnv->nextPos, pQuery->fileId, pQuery->slot, accessPos + step); + savePointPosition(&pRuntimeEnv->nextPos, pQuery->fileId, pQuery->slot, nextPos); } } + break; } else { // query not completed, move to next block - int64_t start = taosGetTimestampUs(); - blockLoadStatus = moveToNextBlock(pRuntimeEnv, step, searchFn, LOAD_DATA); if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK | QUERY_COMPLETED)) { - savePointPosition(&pRuntimeEnv->nextPos, pQuery->fileId, pQuery->slot, pQuery->pos); setQueryStatus(pQuery, QUERY_COMPLETED); break; } - - int64_t delta = (taosGetTimestampUs() - start); - if (IS_DISK_DATA_BLOCK(pQuery)) { - pSummary->fileTimeUs += delta; - } else { - pSummary->cacheTimeUs += delta; - } } // check next block - void *pNextBlock = getGenericDataBlock(pMeterObj, pRuntimeEnv, pQuery->slot); + blockInfo = getBlockInfo(pRuntimeEnv); - int32_t blockType = (IS_DISK_DATA_BLOCK(pQuery)) ? BLK_FILE_BLOCK : BLK_CACHE_BLOCK; - blockInfo = getBlockBasicInfo(pRuntimeEnv, pNextBlock, blockType); - if (!checkQueryRangeAgainstNextBlock(&blockInfo, pRuntimeEnv)) { + if ((QUERY_IS_ASC_QUERY(pQuery) && blockInfo.keyFirst > pQuery->ekey) || + (!QUERY_IS_ASC_QUERY(pQuery) && blockInfo.keyLast < pQuery->ekey)) { + setQueryStatus(pQuery, QUERY_COMPLETED); break; } - } // while(1) - - return cnt; -} - -static void updatelastkey(SQuery *pQuery, SMeterQueryInfo *pMeterQInfo) { pMeterQInfo->lastKey = pQuery->lastKey; } -void queryOnBlock(SMeterQuerySupportObj *pSupporter, int64_t *primaryKeys, int32_t blockStatus, - SBlockInfo *pBlockBasicInfo, SMeterDataInfo *pMeterDataInfo, SField *pFields, - __block_search_fn_t searchFn) { - /* cache blocks may be assign to other meter, abort */ - if (pBlockBasicInfo->size <= 0) { - return; - } - - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - SQuery * pQuery = pRuntimeEnv->pQuery; + if (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)) { + break; + } - if (pQuery->nAggTimeInterval == 0) { // not interval query - int32_t numOfRes = 0; - applyFunctionsOnBlock(pRuntimeEnv, pBlockBasicInfo, primaryKeys, pFields, searchFn, &numOfRes); + } // while(1) - // note: only fixed number of output for each group by operation - if (numOfRes > 0) { - pSupporter->pResult[pMeterDataInfo->groupIdx].numOfRows = numOfRes; - } + if (isIntervalQuery(pQuery) && IS_MASTER_SCAN(pRuntimeEnv)) { + if (Q_STATUS_EQUAL(pQuery->over, QUERY_COMPLETED | QUERY_NO_DATA_TO_CHECK)) { + closeAllTimeWindow(&pRuntimeEnv->windowResInfo); + pRuntimeEnv->windowResInfo.curIndex = pRuntimeEnv->windowResInfo.size - 1; + } else if (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)) { // check if window needs to be closed + SBlockInfo blockInfo = getBlockInfo(pRuntimeEnv); - // used to decide the correct start position in cache after check all data in files - updatelastkey(pQuery, pMeterDataInfo->pMeterQInfo); - if (pRuntimeEnv->pTSBuf != NULL) { - pMeterDataInfo->pMeterQInfo->cur = tsBufGetCursor(pRuntimeEnv->pTSBuf); + // check if need to close window result or not + TSKEY t = (QUERY_IS_ASC_QUERY(pQuery)) ? blockInfo.keyFirst : blockInfo.keyLast; + doCheckQueryCompleted(pRuntimeEnv, t, &pRuntimeEnv->windowResInfo); } - - } else { - applyIntervalQueryOnBlock(pSupporter, pMeterDataInfo, pBlockBasicInfo, blockStatus, pFields, searchFn); } + + return cnt; } +static void updatelastkey(SQuery *pQuery, SMeterQueryInfo *pMeterQInfo) { pMeterQInfo->lastKey = pQuery->lastKey; } + /* * set tag value in SQLFunctionCtx * e.g.,tag information into input buffer @@ -5109,7 +5401,7 @@ static void doSetTagValueInParam(SColumnModel *pTagSchema, int32_t tagColIdx, SM assert(tagColIdx >= 0); int16_t offset = getColumnModelOffset(pTagSchema, tagColIdx); - + void * pStr = (char *)pMeterSidInfo->tags + offset; SSchema *pCol = getColumnModelSchema(pTagSchema, tagColIdx); @@ -5123,7 +5415,7 @@ static void doSetTagValueInParam(SColumnModel *pTagSchema, int32_t tagColIdx, SM } void vnodeSetTagValueInParam(tSidSet *pSidSet, SQueryRuntimeEnv *pRuntimeEnv, SMeterSidExtInfo *pMeterSidInfo) { - SQuery * pQuery = pRuntimeEnv->pQuery; + SQuery * pQuery = pRuntimeEnv->pQuery; SColumnModel *pTagSchema = pSidSet->pColumnModel; SSqlFuncExprMsg *pFuncMsg = &pQuery->pSelectExpr[0].pBase; @@ -5153,8 +5445,7 @@ void vnodeSetTagValueInParam(tSidSet *pSidSet, SQueryRuntimeEnv *pRuntimeEnv, SM } } -static void doMerge(SQueryRuntimeEnv *pRuntimeEnv, int64_t timestamp, tFilePage *inputSrc, int32_t inputIdx, - bool mergeFlag) { +static void doMerge(SQueryRuntimeEnv *pRuntimeEnv, int64_t timestamp, SWindowResult *pWindowRes, bool mergeFlag) { SQuery * pQuery = pRuntimeEnv->pQuery; SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; @@ -5170,9 +5461,10 @@ static void doMerge(SQueryRuntimeEnv *pRuntimeEnv, int64_t timestamp, tFilePage pCtx[i].hasNull = true; pCtx[i].nStartQueryTimestamp = timestamp; - pCtx[i].aInputElemBuf = ((char *)inputSrc->data) + - ((int32_t)pRuntimeEnv->offset[i] * pRuntimeEnv->numOfRowsPerPage) + - pCtx[i].outputBytes * inputIdx; + pCtx[i].aInputElemBuf = getPosInResultPage(pRuntimeEnv, i, pWindowRes); + // pCtx[i].aInputElemBuf = ((char *)inputSrc->data) + + // ((int32_t)pRuntimeEnv->offset[i] * pRuntimeEnv->numOfRowsPerPage) + + // pCtx[i].outputBytes * inputIdx; // in case of tag column, the tag information should be extracted from input buffer if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TAG) { @@ -5262,7 +5554,7 @@ static void printBinaryData(int32_t functionId, char *data, int32_t srcDataType) void UNUSED_FUNC displayInterResult(SData **pdata, SQuery *pQuery, int32_t numOfRows) { int32_t numOfCols = pQuery->numOfOutputCols; - printf("metric query intern-result, total:%d\n", numOfRows); + printf("super table query intermediate result, total:%d\n", numOfRows); SQInfo * pQInfo = (SQInfo *)(GET_QINFO_ADDR(pQuery)); SMeterObj *pMeterObj = pQInfo->pObj; @@ -5302,55 +5594,54 @@ void UNUSED_FUNC displayInterResult(SData **pdata, SQuery *pQuery, int32_t numOf } } -static tFilePage *getMeterDataPage(SQueryResultBuf* pResultBuf, SMeterQueryInfo *pMeterQueryInfo, int32_t index) { - SIDList pList = getDataBufPagesIdList(pResultBuf, pMeterQueryInfo->sid); - return getResultBufferPageById(pResultBuf, pList.pData[index]); -} +// static tFilePage *getMeterDataPage(SQueryDiskbasedResultBuf *pResultBuf, SMeterQueryInfo *pMeterQueryInfo, +// int32_t index) { +// SIDList pList = getDataBufPagesIdList(pResultBuf, pMeterQueryInfo->sid); +// return getResultBufferPageById(pResultBuf, pList.pData[index]); +//} -typedef struct Position { - int32_t pageIdx; - int32_t rowIdx; -} Position; +// typedef struct Position { +// int32_t pageIdx; +// int32_t rowIdx; +//} Position; typedef struct SCompSupporter { SMeterDataInfo ** pMeterDataInfo; - Position * pPosition; - SMeterQuerySupportObj *pSupporter; + int32_t * position; + STableQuerySupportObj *pSupporter; } SCompSupporter; -int64_t getCurrentTimestamp(SCompSupporter *pSupportor, int32_t meterIdx) { - Position * pPos = &pSupportor->pPosition[meterIdx]; - tFilePage *pPage = getMeterDataPage(pSupportor->pSupporter->runtimeEnv.pResultBuf, - pSupportor->pMeterDataInfo[meterIdx]->pMeterQInfo, pPos->pageIdx); - - return *(int64_t *)(pPage->data + TSDB_KEYSIZE * pPos->rowIdx); -} - -int32_t meterResultComparator(const void *pLeft, const void *pRight, void *param) { +int32_t tableResultComparFn(const void *pLeft, const void *pRight, void *param) { int32_t left = *(int32_t *)pLeft; int32_t right = *(int32_t *)pRight; - SCompSupporter *supporter = (SCompSupporter *)param; - SQueryResultBuf* pResultBuf = supporter->pSupporter->runtimeEnv.pResultBuf; - - Position leftPos = supporter->pPosition[left]; - Position rightPos = supporter->pPosition[right]; + SCompSupporter * supporter = (SCompSupporter *)param; + SQueryRuntimeEnv *pRuntimeEnv = &supporter->pSupporter->runtimeEnv; + + int32_t leftPos = supporter->position[left]; + int32_t rightPos = supporter->position[right]; /* left source is exhausted */ - if (leftPos.pageIdx == -1 && leftPos.rowIdx == -1) { + if (leftPos == -1) { return 1; } /* right source is exhausted*/ - if (rightPos.pageIdx == -1 && rightPos.rowIdx == -1) { + if (rightPos == -1) { return -1; } - tFilePage *pPageLeft = getMeterDataPage(pResultBuf, supporter->pMeterDataInfo[left]->pMeterQInfo, leftPos.pageIdx); - int64_t leftTimestamp = *(int64_t *)(pPageLeft->data + TSDB_KEYSIZE * leftPos.rowIdx); + SWindowResInfo *pWindowResInfo1 = &supporter->pMeterDataInfo[left]->pMeterQInfo->windowResInfo; + SWindowResult * pWindowRes1 = getWindowResult(pWindowResInfo1, leftPos); + + char *b1 = getPosInResultPage(pRuntimeEnv, PRIMARYKEY_TIMESTAMP_COL_INDEX, pWindowRes1); + TSKEY leftTimestamp = GET_INT64_VAL(b1); - tFilePage *pPageRight = getMeterDataPage(pResultBuf, supporter->pMeterDataInfo[right]->pMeterQInfo, rightPos.pageIdx); - int64_t rightTimestamp = *(int64_t *)(pPageRight->data + TSDB_KEYSIZE * rightPos.rowIdx); + SWindowResInfo *pWindowResInfo2 = &supporter->pMeterDataInfo[right]->pMeterQInfo->windowResInfo; + SWindowResult * pWindowRes2 = getWindowResult(pWindowResInfo2, rightPos); + + char *b2 = getPosInResultPage(pRuntimeEnv, PRIMARYKEY_TIMESTAMP_COL_INDEX, pWindowRes2); + TSKEY rightTimestamp = GET_INT64_VAL(b2); if (leftTimestamp == rightTimestamp) { return 0; @@ -5359,7 +5650,7 @@ int32_t meterResultComparator(const void *pLeft, const void *pRight, void *param return leftTimestamp > rightTimestamp ? 1 : -1; } -int32_t mergeMetersResultToOneGroups(SMeterQuerySupportObj *pSupporter) { +int32_t mergeMetersResultToOneGroups(STableQuerySupportObj *pSupporter) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; @@ -5392,7 +5683,7 @@ int32_t mergeMetersResultToOneGroups(SMeterQuerySupportObj *pSupporter) { return TSDB_CODE_SUCCESS; } -void copyResToQueryResultBuf(SMeterQuerySupportObj *pSupporter, SQuery *pQuery) { +void copyResToQueryResultBuf(STableQuerySupportObj *pSupporter, SQuery *pQuery) { if (pSupporter->offset == pSupporter->numOfGroupResultPages) { pSupporter->numOfGroupResultPages = 0; @@ -5408,142 +5699,153 @@ void copyResToQueryResultBuf(SMeterQuerySupportObj *pSupporter, SQuery *pQuery) } } - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - SQueryResultBuf* pResultBuf = pRuntimeEnv->pResultBuf; - - SIDList list = getDataBufPagesIdList(pResultBuf, 200000 + pSupporter->offset + (pSupporter->subgroupIdx - 1)* 10000); - + SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; + SQueryDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf; + + int32_t id = getGroupResultId(pSupporter->subgroupIdx - 1); + SIDList list = getDataBufPagesIdList(pResultBuf, pSupporter->offset + id); + int32_t total = 0; - for(int32_t i = 0; i < list.size; ++i) { - tFilePage* pData = getResultBufferPageById(pResultBuf, list.pData[i]); + for (int32_t i = 0; i < list.size; ++i) { + tFilePage *pData = getResultBufferPageById(pResultBuf, list.pData[i]); total += pData->numOfElems; } - + pQuery->sdata[0]->len = total; - + int32_t offset = 0; - for(int32_t num = 0; num < list.size; ++num) { - tFilePage* pData = getResultBufferPageById(pResultBuf, list.pData[num]); - + for (int32_t num = 0; num < list.size; ++num) { + tFilePage *pData = getResultBufferPageById(pResultBuf, list.pData[num]); + for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { int32_t bytes = pRuntimeEnv->pCtx[i].outputBytes; - char* pDest = pQuery->sdata[i]->data; - - memcpy(pDest + offset*bytes, pData->data + pRuntimeEnv->offset[i] * pData->numOfElems, bytes * pData->numOfElems); + char * pDest = pQuery->sdata[i]->data; + + memcpy(pDest + offset * bytes, pData->data + pRuntimeEnv->offset[i] * pData->numOfElems, + bytes * pData->numOfElems); } - + offset += pData->numOfElems; } assert(pQuery->pointsRead == 0); - + pQuery->pointsRead += pQuery->sdata[0]->len; pSupporter->offset += 1; } -int32_t doMergeMetersResultsToGroupRes(SMeterQuerySupportObj *pSupporter, SQuery *pQuery, SQueryRuntimeEnv *pRuntimeEnv, - SMeterDataInfo *pMeterDataInfo, int32_t start, int32_t end) { - // calculate the maximum required space - if (pSupporter->groupResultSize == 0) { - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - pSupporter->groupResultSize += sizeof(tFilePage) + pQuery->pointsToRead * pRuntimeEnv->pCtx[i].outputBytes; +int64_t getNumOfResultWindowRes(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pWindowRes) { + SQuery *pQuery = pRuntimeEnv->pQuery; + + int64_t maxOutput = 0; + for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { + int32_t functionId = pQuery->pSelectExpr[j].pBase.functionId; + + /* + * ts, tag, tagprj function can not decide the output number of current query + * the number of output result is decided by main output + */ + if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ) { + continue; + } + + SResultInfo *pResultInfo = &pWindowRes->resultInfo[j]; + if (pResultInfo != NULL && maxOutput < pResultInfo->numOfRes) { + maxOutput = pResultInfo->numOfRes; } } + return maxOutput; +} + +int32_t doMergeMetersResultsToGroupRes(STableQuerySupportObj *pSupporter, SQuery *pQuery, SQueryRuntimeEnv *pRuntimeEnv, + SMeterDataInfo *pMeterDataInfo, int32_t start, int32_t end) { tFilePage ** buffer = (tFilePage **)pQuery->sdata; - Position * posArray = calloc(1, sizeof(Position) * (end - start)); - SMeterDataInfo **pValidMeter = malloc(POINTER_BYTES * (end - start)); + int32_t * posList = calloc((end - start), sizeof(int32_t)); + SMeterDataInfo **pTableList = malloc(POINTER_BYTES * (end - start)); + // todo opt for the case of one table per group int32_t numOfMeters = 0; for (int32_t i = start; i < end; ++i) { int32_t sid = pMeterDataInfo[i].pMeterQInfo->sid; + SIDList list = getDataBufPagesIdList(pRuntimeEnv->pResultBuf, sid); - - if (list.size > 0 && pMeterDataInfo[i].pMeterQInfo->numOfRes > 0) { - pValidMeter[numOfMeters] = &pMeterDataInfo[i]; - // set the merge start position: page:0, index:0 - posArray[numOfMeters].pageIdx = 0; - posArray[numOfMeters++].rowIdx = 0; + if (list.size > 0 && pMeterDataInfo[i].pMeterQInfo->windowResInfo.size > 0) { + pTableList[numOfMeters] = &pMeterDataInfo[i]; + numOfMeters += 1; } } if (numOfMeters == 0) { - tfree(posArray); - tfree(pValidMeter); + tfree(posList); + tfree(pTableList); + assert(pSupporter->numOfGroupResultPages == 0); return 0; } - SCompSupporter cs = {pValidMeter, posArray, pSupporter}; - SLoserTreeInfo *pTree = NULL; + SCompSupporter cs = {pTableList, posList, pSupporter}; - tLoserTreeCreate(&pTree, numOfMeters, &cs, meterResultComparator); + SLoserTreeInfo *pTree = NULL; + tLoserTreeCreate(&pTree, numOfMeters, &cs, tableResultComparFn); - SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; - resetMergeResultBuf(pQuery, pCtx); + SResultInfo *pResultInfo = calloc(pQuery->numOfOutputCols, sizeof(SResultInfo)); + setWindowResultInfo(pResultInfo, pQuery, pRuntimeEnv->stableQuery); + resetMergeResultBuf(pQuery, pRuntimeEnv->pCtx, pResultInfo); int64_t lastTimestamp = -1; int64_t startt = taosGetTimestampMs(); while (1) { - int32_t pos = pTree->pNode[0].index; - Position * position = &cs.pPosition[pos]; - SQueryResultBuf* pResultBuf = cs.pSupporter->runtimeEnv.pResultBuf; - tFilePage *pPage = getMeterDataPage(pResultBuf, pValidMeter[pos]->pMeterQInfo, position->pageIdx); - - int64_t ts = getCurrentTimestamp(&cs, pos); - if (ts == lastTimestamp) {// merge with the last one - doMerge(pRuntimeEnv, ts, pPage, position->rowIdx, true); - } else { - // copy data to disk buffer - if (buffer[0]->numOfElems == pQuery->pointsToRead) { - if (flushFromResultBuf(pSupporter, pQuery, pRuntimeEnv) != TSDB_CODE_SUCCESS) { - return -1; - } + int32_t pos = pTree->pNode[0].index; - resetMergeResultBuf(pQuery, pCtx); - } + SWindowResInfo *pWindowResInfo = &pTableList[pos]->pMeterQInfo->windowResInfo; + SWindowResult * pWindowRes = getWindowResult(pWindowResInfo, cs.position[pos]); - pPage = getMeterDataPage(pResultBuf, pValidMeter[pos]->pMeterQInfo, position->pageIdx); - if (pPage->numOfElems <= 0) { // current source data page is empty - // do nothing - } else { - doMerge(pRuntimeEnv, ts, pPage, position->rowIdx, false); - buffer[0]->numOfElems += 1; - } - } + char *b = getPosInResultPage(pRuntimeEnv, PRIMARYKEY_TIMESTAMP_COL_INDEX, pWindowRes); + TSKEY ts = GET_INT64_VAL(b); - lastTimestamp = ts; + assert(ts == pWindowRes->window.skey); + int64_t num = getNumOfResultWindowRes(pRuntimeEnv, pWindowRes); + if (num <= 0) { + cs.position[pos] += 1; - if (cs.pPosition[pos].rowIdx >= pPage->numOfElems - 1) { - cs.pPosition[pos].rowIdx = 0; - cs.pPosition[pos].pageIdx += 1; // try next page + if (cs.position[pos] >= pWindowResInfo->size) { + cs.position[pos] = -1; - // check if current page is empty or not. if it is empty, ignore it and try next - SIDList list = getDataBufPagesIdList(pRuntimeEnv->pResultBuf, cs.pMeterDataInfo[pos]->pMeterQInfo->sid); - if (cs.pPosition[pos].pageIdx <= list.size - 1) { - tFilePage *newPage = getMeterDataPage(pResultBuf, pValidMeter[pos]->pMeterQInfo, position->pageIdx); - - // if current source data page is null, it must be the last page of source output page - if (newPage->numOfElems <= 0) { - cs.pPosition[pos].pageIdx += 1; - assert(cs.pPosition[pos].pageIdx >= list.size - 1); + // all input sources are exhausted + if (--numOfMeters == 0) { + break; + } + } + } else { + if (ts == lastTimestamp) { // merge with the last one + doMerge(pRuntimeEnv, ts, pWindowRes, true); + } else { // copy data to disk buffer + if (buffer[0]->numOfElems == pQuery->pointsToRead) { + if (flushFromResultBuf(pSupporter, pQuery, pRuntimeEnv) != TSDB_CODE_SUCCESS) { + return -1; + } + + resetMergeResultBuf(pQuery, pRuntimeEnv->pCtx, pResultInfo); } + + doMerge(pRuntimeEnv, ts, pWindowRes, false); + buffer[0]->numOfElems += 1; } - // the following code must be executed if current source pages are exhausted - if (cs.pPosition[pos].pageIdx >= list.size) { - cs.pPosition[pos].pageIdx = -1; - cs.pPosition[pos].rowIdx = -1; + lastTimestamp = ts; + + cs.position[pos] += 1; + if (cs.position[pos] >= pWindowResInfo->size) { + cs.position[pos] = -1; // all input sources are exhausted if (--numOfMeters == 0) { break; } } - } else { - cs.pPosition[pos].rowIdx += 1; } tLoserTreeAdjust(pTree, pos + pTree->numOfEntries); @@ -5551,11 +5853,12 @@ int32_t doMergeMetersResultsToGroupRes(SMeterQuerySupportObj *pSupporter, SQuery if (buffer[0]->numOfElems != 0) { // there are data in buffer if (flushFromResultBuf(pSupporter, pQuery, pRuntimeEnv) != TSDB_CODE_SUCCESS) { -// dError("QInfo:%p failed to flush data into temp file, abort query", GET_QINFO_ADDR(pQuery), -// pSupporter->extBufFile); + // dError("QInfo:%p failed to flush data into temp file, abort query", GET_QINFO_ADDR(pQuery), + // pSupporter->extBufFile); tfree(pTree); - tfree(pValidMeter); - tfree(posArray); + tfree(pTableList); + tfree(posList); + tfree(pResultInfo); return -1; } @@ -5569,56 +5872,59 @@ int32_t doMergeMetersResultsToGroupRes(SMeterQuerySupportObj *pSupporter, SQuery dTrace("QInfo:%p result merge completed, elapsed time:%" PRId64 " ms", GET_QINFO_ADDR(pQuery), endt - startt); tfree(pTree); - tfree(pValidMeter); - tfree(posArray); + tfree(pTableList); + tfree(posList); + tfree(pResultInfo); pSupporter->offset = 0; return pSupporter->numOfGroupResultPages; } -int32_t flushFromResultBuf(SMeterQuerySupportObj *pSupporter, const SQuery *pQuery, +int32_t flushFromResultBuf(STableQuerySupportObj *pSupporter, const SQuery *pQuery, const SQueryRuntimeEnv *pRuntimeEnv) { - SQueryResultBuf* pResultBuf = pRuntimeEnv->pResultBuf; - int32_t capacity = (DEFAULT_INTERN_BUF_SIZE - sizeof(tFilePage))/ pQuery->rowSize; - + SQueryDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf; + int32_t capacity = (DEFAULT_INTERN_BUF_SIZE - sizeof(tFilePage)) / pQuery->rowSize; + // the base value for group result, since the maximum number of table for each vnode will not exceed 100,000. - int32_t base = 200000; int32_t pageId = -1; - + int32_t remain = pQuery->sdata[0]->len; int32_t offset = 0; - - while(remain > 0) { + + while (remain > 0) { int32_t r = remain; if (r > capacity) { r = capacity; } - - tFilePage* buf = getNewDataBuf(pResultBuf, base + pSupporter->subgroupIdx*10000 + pSupporter->numOfGroupResultPages, &pageId); - - //pagewise copy to dest buffer + + int32_t id = getGroupResultId(pSupporter->subgroupIdx) + pSupporter->numOfGroupResultPages; + tFilePage *buf = getNewDataBuf(pResultBuf, id, &pageId); + + // pagewise copy to dest buffer for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { int32_t bytes = pRuntimeEnv->pCtx[i].outputBytes; buf->numOfElems = r; - - memcpy(buf->data + pRuntimeEnv->offset[i] * buf->numOfElems, ((char*)pQuery->sdata[i]->data) + offset * bytes, - buf->numOfElems * bytes); + + memcpy(buf->data + pRuntimeEnv->offset[i] * buf->numOfElems, ((char *)pQuery->sdata[i]->data) + offset * bytes, + buf->numOfElems * bytes); } - + offset += r; remain -= r; } - + pSupporter->numOfGroupResultPages += 1; return TSDB_CODE_SUCCESS; } -void resetMergeResultBuf(SQuery *pQuery, SQLFunctionCtx *pCtx) { +void resetMergeResultBuf(SQuery *pQuery, SQLFunctionCtx *pCtx, SResultInfo *pResultInfo) { for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { pCtx[k].aOutputBuf = pQuery->sdata[k]->data - pCtx[k].outputBytes; pCtx[k].size = 1; pCtx[k].startOffset = 0; + pCtx[k].resultInfo = &pResultInfo[k]; + pQuery->sdata[k]->len = 0; } } @@ -5629,167 +5935,165 @@ void setMeterDataInfo(SMeterDataInfo *pMeterDataInfo, SMeterObj *pMeterObj, int3 pMeterDataInfo->meterOrderIdx = meterIdx; } -int32_t doCloseAllOpenedResults(SMeterQuerySupportObj *pSupporter) { - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - SQuery * pQuery = pRuntimeEnv->pQuery; - - /* for interval query, close all unclosed results */ - if (pQuery->nAggTimeInterval > 0) { - SMeterDataInfo *pMeterInfo = pSupporter->pMeterDataInfo; - for (int32_t i = 0; i < pSupporter->numOfMeters; ++i) { - if (pMeterInfo[i].pMeterQInfo != NULL && pMeterInfo[i].pMeterQInfo->lastResRows > 0) { - int32_t index = pMeterInfo[i].meterOrderIdx; +static void doDisableFunctsForSupplementaryScan(SQuery *pQuery, SWindowResInfo *pWindowResInfo, int32_t order) { + for (int32_t i = 0; i < pWindowResInfo->size; ++i) { + SWindowStatus *pStatus = getTimeWindowResStatus(pWindowResInfo, i); + if (!pStatus->closed) { + continue; + } - pRuntimeEnv->pMeterObj = getMeterObj(pSupporter->pMetersHashTable, pSupporter->pSidSet->pSids[index]->sid); - assert(pRuntimeEnv->pMeterObj == pMeterInfo[i].pMeterObj); + SWindowResult *buf = getWindowResult(pWindowResInfo, i); - int32_t ret = setIntervalQueryExecutionContext(pSupporter, i, pMeterInfo[i].pMeterQInfo); - if (ret != TSDB_CODE_SUCCESS) { - return ret; - } + // open/close the specified query for each group result + for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { + int32_t functId = pQuery->pSelectExpr[j].pBase.functionId; - ret = saveResult(pSupporter, pMeterInfo[i].pMeterQInfo, pMeterInfo[i].pMeterQInfo->lastResRows); - if (ret != TSDB_CODE_SUCCESS) { - return ret; - } + if (((functId == TSDB_FUNC_FIRST || functId == TSDB_FUNC_FIRST_DST) && order == TSQL_SO_DESC) || + ((functId == TSDB_FUNC_LAST || functId == TSDB_FUNC_LAST_DST) && order == TSQL_SO_ASC)) { + buf->resultInfo[j].complete = false; + } else if (functId != TSDB_FUNC_TS && functId != TSDB_FUNC_TAG) { + buf->resultInfo[j].complete = true; } } } - - return TSDB_CODE_SUCCESS; } -void disableFunctForSuppleScan(SQueryRuntimeEnv *pRuntimeEnv, int32_t order) { +void disableFunctForTableSuppleScan(SQueryRuntimeEnv *pRuntimeEnv, int32_t order) { SQuery *pQuery = pRuntimeEnv->pQuery; - if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (pQuery->slidingTime > 0 && pQuery->nAggTimeInterval > 0)) { - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - pRuntimeEnv->pCtx[i].order = (pRuntimeEnv->pCtx[i].order) ^ 1; - } - - SSlidingWindowInfo *pSlidingWindowInfo = &pRuntimeEnv->swindowResInfo; - - for (int32_t i = 0; i < pSlidingWindowInfo->size; ++i) { - SWindowStatus *pStatus = &pSlidingWindowInfo->pStatus[i]; - if (!pStatus->closed) { - continue; - } - - SOutputRes *buf = &pSlidingWindowInfo->pResult[i]; - - // open/close the specified query for each group result - for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { - int32_t functId = pQuery->pSelectExpr[j].pBase.functionId; + // group by normal columns and interval query on normal table + for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { + pRuntimeEnv->pCtx[i].order = (pRuntimeEnv->pCtx[i].order) ^ 1u; + } - if (((functId == TSDB_FUNC_FIRST || functId == TSDB_FUNC_FIRST_DST) && order == TSQL_SO_DESC) || - ((functId == TSDB_FUNC_LAST || functId == TSDB_FUNC_LAST_DST) && order == TSQL_SO_ASC)) { - buf->resultInfo[j].complete = false; - } else if (functId != TSDB_FUNC_TS && functId != TSDB_FUNC_TAG) { - buf->resultInfo[j].complete = true; - } + SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; + if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || isIntervalQuery(pQuery)) { + doDisableFunctsForSupplementaryScan(pQuery, pWindowResInfo, order); + } else { // for simple result of table query, + for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { + int32_t functId = pQuery->pSelectExpr[j].pBase.functionId; + SQLFunctionCtx* pCtx = &pRuntimeEnv->pCtx[j]; + + if (((functId == TSDB_FUNC_FIRST || functId == TSDB_FUNC_FIRST_DST) && order == TSQL_SO_DESC) || + ((functId == TSDB_FUNC_LAST || functId == TSDB_FUNC_LAST_DST) && order == TSQL_SO_ASC)) { + pCtx->resultInfo->complete = false; + } else if (functId != TSDB_FUNC_TS && functId != TSDB_FUNC_TAG) { + pCtx->resultInfo->complete = true; } } - } else { // TODO ERROR!! - // need to handle for each query result, not just the single runtime ctx. - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - pRuntimeEnv->pCtx[i].order = (pRuntimeEnv->pCtx[i].order) ^ 1; - int32_t functId = pQuery->pSelectExpr[i].pBase.functionId; + } - SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[i]); - if (((functId == TSDB_FUNC_FIRST || functId == TSDB_FUNC_FIRST_DST) && order == TSQL_SO_DESC) || - ((functId == TSDB_FUNC_LAST || functId == TSDB_FUNC_LAST_DST) && order == TSQL_SO_ASC)) { - pResInfo->complete = false; + pQuery->order.order = pQuery->order.order ^ 1u; +} + +void disableFunctForSuppleScan(STableQuerySupportObj *pSupporter, int32_t order) { + SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; + SQuery * pQuery = pRuntimeEnv->pQuery; + + for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { + pRuntimeEnv->pCtx[i].order = (pRuntimeEnv->pCtx[i].order) ^ 1u; + } + + if (isIntervalQuery(pQuery)) { + for (int32_t i = 0; i < pSupporter->numOfMeters; ++i) { + SMeterQueryInfo *pMeterQueryInfo = pSupporter->pMeterDataInfo[i].pMeterQInfo; + SWindowResInfo * pWindowResInfo = &pMeterQueryInfo->windowResInfo; - } else if (functId != TSDB_FUNC_TS && functId != TSDB_FUNC_TAG) { - pResInfo->complete = true; - } + doDisableFunctsForSupplementaryScan(pQuery, pWindowResInfo, order); } + } else { + SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; + doDisableFunctsForSupplementaryScan(pQuery, pWindowResInfo, order); } - pQuery->order.order = pQuery->order.order ^ 1; + pQuery->order.order = (pQuery->order.order) ^ 1u; } void enableFunctForMasterScan(SQueryRuntimeEnv *pRuntimeEnv, int32_t order) { SQuery *pQuery = pRuntimeEnv->pQuery; for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - pRuntimeEnv->pCtx[i].order = (pRuntimeEnv->pCtx[i].order) ^ 1; + pRuntimeEnv->pCtx[i].order = (pRuntimeEnv->pCtx[i].order) ^ 1u; } - pQuery->order.order = (pQuery->order.order ^ 1); + pQuery->order.order = (pQuery->order.order) ^ 1u; } -void createQueryResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes *pResultRow, bool isSTableQuery, SPosInfo *posInfo) { - SQuery* pQuery = pRuntimeEnv->pQuery; - +void createQueryResultInfo(SQuery *pQuery, SWindowResult *pResultRow, bool isSTableQuery, SPosInfo *posInfo) { int32_t numOfCols = pQuery->numOfOutputCols; pResultRow->resultInfo = calloc((size_t)numOfCols, sizeof(SResultInfo)); - pResultRow->pos = *posInfo;//page->data + (pRuntimeEnv->offset[i] * pRuntimeEnv->numOfRowsPerPage) + page->numOfElems*s1; - - for (int32_t i = 0; i < numOfCols; ++i) { - SResultInfo *pResultInfo = &pResultRow->resultInfo[i]; - size_t size = pQuery->pSelectExpr[i].interResBytes; - setResultInfoBuf(pResultInfo, (int32_t)size, isSTableQuery); - } + pResultRow->pos = *posInfo; + + // set the intermediate result output buffer + setWindowResultInfo(pResultRow->resultInfo, pQuery, isSTableQuery); } -void clearGroupResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes *pOneOutputRes) { - if (pOneOutputRes == NULL) { +void clearTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pWindowRes) { + if (pWindowRes == NULL) { return; } for (int32_t i = 0; i < pRuntimeEnv->pQuery->numOfOutputCols; ++i) { - SResultInfo *pResultInfo = &pOneOutputRes->resultInfo[i]; -// int32_t size = sizeof(tFilePage) + pResultInfo->bufLen * pOneOutputRes->nAlloc; + SResultInfo *pResultInfo = &pWindowRes->resultInfo[i]; -// memset(pOneOutputRes->pos[i], 0, (size_t)size); - char* s = getPosInResultPage(pRuntimeEnv, i, pOneOutputRes); + char * s = getPosInResultPage(pRuntimeEnv, i, pWindowRes); size_t size = pRuntimeEnv->pQuery->pSelectExpr[i].resBytes; memset(s, 0, size); - + resetResultInfo(pResultInfo); } + + pWindowRes->numOfRows = 0; + // pWindowRes->nAlloc = 0; + pWindowRes->pos = (SPosInfo){-1, -1}; + pWindowRes->status.closed = false; + pWindowRes->window = (STimeWindow){0, 0}; } -void copyGroupResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes* dst, const SOutputRes* src) { +/** + * The source window result pos attribution of the source window result does not assign to the destination, + * since the attribute of "Pos" is bound to each window result when the window result is created in the + * disk-based result buffer. + */ +void copyTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *dst, const SWindowResult *src) { dst->numOfRows = src->numOfRows; - dst->nAlloc = src->nAlloc; - + // dst->nAlloc = src->nAlloc; + dst->window = src->window; + dst->status = src->status; + int32_t nOutputCols = pRuntimeEnv->pQuery->numOfOutputCols; - - for(int32_t i = 0; i < nOutputCols; ++i) { + + for (int32_t i = 0; i < nOutputCols; ++i) { SResultInfo *pDst = &dst->resultInfo[i]; SResultInfo *pSrc = &src->resultInfo[i]; - - char* buf = pDst->interResultBuf; + + char *buf = pDst->interResultBuf; memcpy(pDst, pSrc, sizeof(SResultInfo)); pDst->interResultBuf = buf; // restore the allocated buffer - + // copy the result info struct memcpy(pDst->interResultBuf, pSrc->interResultBuf, pDst->bufLen); // copy the output buffer data from src to dst, the position info keep unchanged - char* dstBuf = getPosInResultPage(pRuntimeEnv, i, dst); - char* srcBuf = getPosInResultPage(pRuntimeEnv, i, src); + char * dstBuf = getPosInResultPage(pRuntimeEnv, i, dst); + char * srcBuf = getPosInResultPage(pRuntimeEnv, i, (SWindowResult *)src); size_t s = pRuntimeEnv->pQuery->pSelectExpr[i].resBytes; - + memcpy(dstBuf, srcBuf, s); } } -void destroyGroupResultBuf(SOutputRes *pOneOutputRes, int32_t nOutputCols) { - if (pOneOutputRes == NULL) { +void destroyTimeWindowRes(SWindowResult *pWindowRes, int32_t nOutputCols) { + if (pWindowRes == NULL) { return; } for (int32_t i = 0; i < nOutputCols; ++i) { -// free(pOneOutputRes->pos[i]); - free(pOneOutputRes->resultInfo[i].interResultBuf); + free(pWindowRes->resultInfo[i].interResultBuf); } - free(pOneOutputRes->resultInfo); -// free(pOneOutputRes->result); + free(pWindowRes->resultInfo); } void resetCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) { @@ -5829,7 +6133,7 @@ void forwardCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, int64_t output) { // set next output position if (IS_OUTER_FORWARD(aAggs[functionId].nStatus)) { - pRuntimeEnv->pCtx[j].aOutputBuf += pRuntimeEnv->pCtx[j].outputBytes * output /** factor*/; + pRuntimeEnv->pCtx[j].aOutputBuf += pRuntimeEnv->pCtx[j].outputBytes * output; } if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { @@ -5840,7 +6144,7 @@ void forwardCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, int64_t output) { * * diff function is handled in multi-output function */ - pRuntimeEnv->pCtx[j].ptsOutputBuf += TSDB_KEYSIZE * output/* * factor*/; + pRuntimeEnv->pCtx[j].ptsOutputBuf += TSDB_KEYSIZE * output; } resetResultInfo(pRuntimeEnv->pCtx[j].resultInfo); @@ -5853,7 +6157,7 @@ void initCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) { for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { int32_t functionId = pQuery->pSelectExpr[j].pBase.functionId; pRuntimeEnv->pCtx[j].currentStage = 0; - + aAggs[functionId].init(&pRuntimeEnv->pCtx[j]); } } @@ -5898,24 +6202,17 @@ typedef struct SQueryStatus { SPositionInfo start; SPositionInfo next; SPositionInfo end; - - TSKEY skey; - TSKEY ekey; - int8_t overStatus; - TSKEY lastKey; - - STSCursor cur; + int8_t overStatus; + TSKEY lastKey; + STSCursor cur; } SQueryStatus; - +// todo refactor static void queryStatusSave(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus *pStatus) { SQuery *pQuery = pRuntimeEnv->pQuery; pStatus->overStatus = pQuery->over; pStatus->lastKey = pQuery->lastKey; - pStatus->skey = pQuery->skey; - pStatus->ekey = pQuery->ekey; - pStatus->start = pRuntimeEnv->startPos; pStatus->next = pRuntimeEnv->nextPos; pStatus->end = pRuntimeEnv->endPos; @@ -5923,7 +6220,7 @@ static void queryStatusSave(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus *pStatus pStatus->cur = tsBufGetCursor(pRuntimeEnv->pTSBuf); // save the cursor if (pRuntimeEnv->pTSBuf) { - pRuntimeEnv->pTSBuf->cur.order ^= 1; + pRuntimeEnv->pTSBuf->cur.order ^= 1u; tsBufNextPos(pRuntimeEnv->pTSBuf); } @@ -5932,19 +6229,13 @@ static void queryStatusSave(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus *pStatus SWAP(pQuery->skey, pQuery->ekey, TSKEY); pQuery->lastKey = pQuery->skey; pRuntimeEnv->startPos = pRuntimeEnv->endPos; - - SWAP(pRuntimeEnv->intervalWindow.skey, pRuntimeEnv->intervalWindow.ekey, TSKEY); } static void queryStatusRestore(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus *pStatus) { SQuery *pQuery = pRuntimeEnv->pQuery; SWAP(pQuery->skey, pQuery->ekey, TSKEY); - SWAP(pRuntimeEnv->intervalWindow.skey, pRuntimeEnv->intervalWindow.ekey, TSKEY); - - pQuery->lastKey = pStatus->lastKey; - pQuery->skey = pStatus->skey; - pQuery->ekey = pStatus->ekey; + pQuery->lastKey = pStatus->lastKey; pQuery->over = pStatus->overStatus; pRuntimeEnv->startPos = pStatus->start; @@ -5963,7 +6254,7 @@ static void doSingleMeterSupplementScan(SQueryRuntimeEnv *pRuntimeEnv) { } dTrace("QInfo:%p start to supp scan", GET_QINFO_ADDR(pQuery)); - + SET_SUPPLEMENT_SCAN_FLAG(pRuntimeEnv); // usually this load operation will incur load disk block operation @@ -5973,7 +6264,7 @@ static void doSingleMeterSupplementScan(SQueryRuntimeEnv *pRuntimeEnv) { (!QUERY_IS_ASC_QUERY(pQuery) && endKey >= pQuery->ekey)); // close necessary function execution during supplementary scan - disableFunctForSuppleScan(pRuntimeEnv, pQuery->order.order); + disableFunctForTableSuppleScan(pRuntimeEnv, pQuery->order.order); queryStatusSave(pRuntimeEnv, &qStatus); doScanAllDataBlocks(pRuntimeEnv); @@ -5998,60 +6289,90 @@ void setQueryStatus(SQuery *pQuery, int8_t status) { } } -void vnodeScanAllData(SQueryRuntimeEnv *pRuntimeEnv) { +bool needScanDataBlocksAgain(SQueryRuntimeEnv *pRuntimeEnv) { SQuery *pQuery = pRuntimeEnv->pQuery; - setQueryStatus(pQuery, QUERY_NOT_COMPLETED); - - /* store the start query position */ - savePointPosition(&pRuntimeEnv->startPos, pQuery->fileId, pQuery->slot, pQuery->pos); - int64_t skey = pQuery->lastKey; - - while (1) { - doScanAllDataBlocks(pRuntimeEnv); + bool toContinue = false; - bool toContinue = true; + if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || isIntervalQuery(pQuery)) { + // for each group result, call the finalize function for each column + SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; - if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { - // for each group result, call the finalize function for each column - SSlidingWindowInfo *pSlidingWindowInfo = &pRuntimeEnv->swindowResInfo; + for (int32_t i = 0; i < pWindowResInfo->size; ++i) { + SWindowResult *pResult = getWindowResult(pWindowResInfo, i); + if (!pResult->status.closed) { + continue; + } - for (int32_t i = 0; i < pSlidingWindowInfo->size; ++i) { - SOutputRes *buf = &pSlidingWindowInfo->pResult[i]; + setWindowResOutputBuf(pRuntimeEnv, pResult); - SWindowStatus *pStatus = &pSlidingWindowInfo->pStatus[i]; - if (!pStatus->closed) { + for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { + int16_t functId = pQuery->pSelectExpr[j].pBase.functionId; + if (functId == TSDB_FUNC_TS) { continue; } + + aAggs[functId].xNextStep(&pRuntimeEnv->pCtx[j]); + SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]); + + toContinue |= (!pResInfo->complete); + } + } + } else { + for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { + int16_t functId = pQuery->pSelectExpr[j].pBase.functionId; + if (functId == TSDB_FUNC_TS) { + continue; + } + + aAggs[functId].xNextStep(&pRuntimeEnv->pCtx[j]); + SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]); - setGroupOutputBuffer(pRuntimeEnv, buf); + toContinue |= (!pResInfo->complete); + } + } - for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { - aAggs[pQuery->pSelectExpr[j].pBase.functionId].xNextStep(&pRuntimeEnv->pCtx[j]); - SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]); + return toContinue; +} - toContinue &= (pResInfo->complete); - } - } - } else { - for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { - aAggs[pQuery->pSelectExpr[j].pBase.functionId].xNextStep(&pRuntimeEnv->pCtx[j]); - SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]); +void vnodeScanAllData(SQueryRuntimeEnv *pRuntimeEnv) { + SQuery *pQuery = pRuntimeEnv->pQuery; + setQueryStatus(pQuery, QUERY_NOT_COMPLETED); - toContinue &= (pResInfo->complete); - } - } + /* store the start query position */ + savePointPosition(&pRuntimeEnv->startPos, pQuery->fileId, pQuery->slot, pQuery->pos); + int64_t oldSkey = pQuery->skey; + int64_t oldEkey = pQuery->ekey; + + int64_t skey = pQuery->lastKey; + int32_t status = pQuery->over; + + SET_MASTER_SCAN_FLAG(pRuntimeEnv); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + + while (1) { + doScanAllDataBlocks(pRuntimeEnv); - if (toContinue) { + if (!needScanDataBlocksAgain(pRuntimeEnv)) { + // restore the status + if (pRuntimeEnv->scanFlag == REPEAT_SCAN) { + pQuery->over = status; + } break; } - // set the correct start position, and load the corresponding block in buffer if required. - TSKEY actKey = loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->startPos); - assert((QUERY_IS_ASC_QUERY(pQuery) && actKey >= pQuery->skey) || - (!QUERY_IS_ASC_QUERY(pQuery) && actKey <= pQuery->skey)); + /* + * set the correct start position, and load the corresponding block in buffer for next + * round scan all data blocks. + */ + TSKEY key = loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->startPos); + assert((QUERY_IS_ASC_QUERY(pQuery) && key >= pQuery->skey) || (!QUERY_IS_ASC_QUERY(pQuery) && key <= pQuery->skey)); - setQueryStatus(pQuery, QUERY_NOT_COMPLETED); + status = pQuery->over; + pQuery->ekey = pQuery->lastKey - step; pQuery->lastKey = pQuery->skey; + + setQueryStatus(pQuery, QUERY_NOT_COMPLETED); + pRuntimeEnv->scanFlag = REPEAT_SCAN; /* check if query is killed or not */ if (isQueryKilled(pQuery)) { @@ -6060,33 +6381,36 @@ void vnodeScanAllData(SQueryRuntimeEnv *pRuntimeEnv) { } } - int64_t newSkey = pQuery->skey; + // no need to set the end key + int64_t curLastKey = pQuery->lastKey; pQuery->skey = skey; + pQuery->ekey = pQuery->lastKey - step; doSingleMeterSupplementScan(pRuntimeEnv); - - // update the pQuery->skey/pQuery->ekey to limit the scan scope of sliding query during - // supplementary scan - pQuery->skey = newSkey; + + // update the pQuery->skey/pQuery->ekey to limit the scan scope of sliding query during supplementary scan + pQuery->skey = oldSkey; + pQuery->ekey = oldEkey; + pQuery->lastKey = curLastKey; } void doFinalizeResult(SQueryRuntimeEnv *pRuntimeEnv) { SQuery *pQuery = pRuntimeEnv->pQuery; - if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { + if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || isIntervalQuery(pQuery)) { // for each group result, call the finalize function for each column - SSlidingWindowInfo *pSlidingWindowInfo = &pRuntimeEnv->swindowResInfo; + SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) { - closeAllSlidingWindow(pSlidingWindowInfo); + closeAllTimeWindow(pWindowResInfo); } - - for (int32_t i = 0; i < pSlidingWindowInfo->size; ++i) { - SOutputRes *buf = &pSlidingWindowInfo->pResult[i]; - if (!slidingWindowClosed(pSlidingWindowInfo, i)) { + + for (int32_t i = 0; i < pWindowResInfo->size; ++i) { + SWindowResult *buf = &pWindowResInfo->pResult[i]; + if (!isWindowResClosed(pWindowResInfo, i)) { continue; } - - setGroupOutputBuffer(pRuntimeEnv, buf); + + setWindowResOutputBuf(pRuntimeEnv, buf); for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { aAggs[pQuery->pSelectExpr[j].pBase.functionId].xFinalize(&pRuntimeEnv->pCtx[j]); @@ -6144,89 +6468,6 @@ int64_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv) { return maxOutput; } -static int32_t getNextIntervalQueryRange(SMeterQuerySupportObj *pSupporter, SQueryRuntimeEnv *pRuntimeEnv, - int64_t *skey, int64_t *ekey) { - SQuery *pQuery = pRuntimeEnv->pQuery; - - int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); - - *skey = pRuntimeEnv->intervalWindow.skey + (pQuery->slidingTime * factor); - *ekey = pRuntimeEnv->intervalWindow.ekey + (pQuery->slidingTime * factor); - - if (pQuery->slidingTime > 0) { - if (QUERY_IS_ASC_QUERY(pQuery)) { - // the next sliding window is not contained in the query time range - if (*skey < pSupporter->rawSKey) { - *skey = pSupporter->rawSKey; - } - - if (*skey > pSupporter->rawEKey) { - return QUERY_COMPLETED; - } - - if (*ekey > pSupporter->rawEKey) { - *ekey = pSupporter->rawEKey; - } - } else { - if (*skey > pSupporter->rawSKey) { - *skey = pSupporter->rawSKey; - } - - if (*skey < pSupporter->rawEKey) { - return QUERY_COMPLETED; - } - - if (*ekey < pSupporter->rawEKey) { - *ekey = pSupporter->rawEKey; - } - } - } - - return QUERY_NOT_COMPLETED; -} - -/* - * forward the query range for next interval query - */ -void forwardIntervalQueryRange(SMeterQuerySupportObj *pSupporter, SQueryRuntimeEnv *pRuntimeEnv) { - SQuery *pQuery = pRuntimeEnv->pQuery; - if (pQuery->slidingTime > 0 && pQuery->nAggTimeInterval > 0) { - if ((QUERY_IS_ASC_QUERY(pQuery) && pQuery->lastKey >= pQuery->ekey) || - (!QUERY_IS_ASC_QUERY(pQuery) && pQuery->lastKey <= pQuery->ekey)) { - setQueryStatus(pQuery, QUERY_COMPLETED); - } else { - /*TSKEY nextTimestamp =*/ loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->nextPos); - } - - return; - } - - int32_t r = getNextIntervalQueryRange(pSupporter, pRuntimeEnv, &pQuery->skey, &pQuery->ekey); - if (r == QUERY_COMPLETED) { - setQueryStatus(pQuery, QUERY_COMPLETED); - return; - } - - getNextLogicalQueryRange(pRuntimeEnv, &pRuntimeEnv->intervalWindow); - - /* ensure the search in cache will return right position */ - pQuery->lastKey = pQuery->skey; - - TSKEY nextTimestamp = loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->nextPos); - if ((nextTimestamp > pSupporter->rawEKey && QUERY_IS_ASC_QUERY(pQuery)) || - (nextTimestamp < pSupporter->rawEKey && !QUERY_IS_ASC_QUERY(pQuery)) || - Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)) { - setQueryStatus(pQuery, QUERY_COMPLETED); - return; - } - - // bridge the gap in group by time function - if ((nextTimestamp > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (nextTimestamp < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { - getAlignedIntervalQueryRange(pRuntimeEnv, nextTimestamp, pSupporter->rawSKey, pSupporter->rawEKey); - } -} - static int32_t offsetComparator(const void *pLeft, const void *pRight) { SMeterDataInfo **pLeft1 = (SMeterDataInfo **)pLeft; SMeterDataInfo **pRight1 = (SMeterDataInfo **)pRight; @@ -6252,7 +6493,7 @@ int32_t vnodeFilterQualifiedMeters(SQInfo *pQInfo, int32_t vid, tSidSet *pSidSet int32_t *numOfMeters, SMeterDataInfo ***pReqMeterDataInfo) { SQuery *pQuery = &pQInfo->query; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SMeterSidExtInfo ** pMeterSidExtInfo = pSupporter->pMeterSidExtInfo; SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; @@ -6348,7 +6589,8 @@ int32_t vnodeFilterQualifiedMeters(SQInfo *pQInfo, int32_t vid, tSidSet *pSidSet pOneMeterDataInfo->offsetInHeaderFile = (uint64_t)compHeader->compInfoOffset; if (pOneMeterDataInfo->pMeterQInfo == NULL) { - pOneMeterDataInfo->pMeterQInfo = createMeterQueryInfo(pQuery, pMeterObj->sid, pSupporter->rawSKey, pSupporter->rawEKey); + pOneMeterDataInfo->pMeterQInfo = + createMeterQueryInfo(pSupporter, pMeterObj->sid, pSupporter->rawSKey, pSupporter->rawEKey); } (*pReqMeterDataInfo)[*numOfMeters] = pOneMeterDataInfo; @@ -6367,26 +6609,19 @@ int32_t vnodeFilterQualifiedMeters(SQInfo *pQInfo, int32_t vid, tSidSet *pSidSet return TSDB_CODE_SUCCESS; } -SMeterQueryInfo *createMeterQueryInfo(SQuery *pQuery, int32_t sid, TSKEY skey, TSKEY ekey) { +SMeterQueryInfo *createMeterQueryInfo(STableQuerySupportObj *pSupporter, int32_t sid, TSKEY skey, TSKEY ekey) { + SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; + SMeterQueryInfo *pMeterQueryInfo = calloc(1, sizeof(SMeterQueryInfo)); pMeterQueryInfo->skey = skey; pMeterQueryInfo->ekey = ekey; pMeterQueryInfo->lastKey = skey; -// pMeterQueryInfo->numOfPages = 0; -// pMeterQueryInfo->numOfAlloc = INIT_ALLOCATE_DISK_PAGES; -// pMeterQueryInfo->pageList = calloc(pMeterQueryInfo->numOfAlloc, sizeof(uint32_t)); - pMeterQueryInfo->lastResRows = 0; pMeterQueryInfo->sid = sid; pMeterQueryInfo->cur.vnodeIndex = -1; - pMeterQueryInfo->resultInfo = calloc((size_t)pQuery->numOfOutputCols, sizeof(SResultInfo)); - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - SResultInfo *pResInfo = &pMeterQueryInfo->resultInfo[i]; - setResultInfoBuf(pResInfo, pQuery->pSelectExpr[i].interResBytes, true); - } - + initWindowResInfo(&pMeterQueryInfo->windowResInfo, pRuntimeEnv, 100, 100, TSDB_DATA_TYPE_INT); return pMeterQueryInfo; } @@ -6395,53 +6630,35 @@ void destroyMeterQueryInfo(SMeterQueryInfo *pMeterQueryInfo, int32_t numOfCols) return; } -// free(pMeterQueryInfo->pageList); - for (int32_t i = 0; i < numOfCols; ++i) { - tfree(pMeterQueryInfo->resultInfo[i].interResultBuf); - } + // free(pMeterQueryInfo->pageList); + // for (int32_t i = 0; i < numOfCols; ++i) { + // tfree(pMeterQueryInfo->[i].interResultBuf); + // } - free(pMeterQueryInfo->resultInfo); + // free(pMeterQueryInfo->resultInfo); free(pMeterQueryInfo); } -void changeMeterQueryInfoForSuppleQuery(SQueryResultBuf* pResultBuf, SMeterQueryInfo *pMeterQueryInfo, TSKEY skey, - TSKEY ekey) { +void changeMeterQueryInfoForSuppleQuery(SQuery *pQuery, SMeterQueryInfo *pMeterQueryInfo, TSKEY skey, TSKEY ekey) { if (pMeterQueryInfo == NULL) { return; } - pMeterQueryInfo->skey = skey; - pMeterQueryInfo->ekey = ekey; - pMeterQueryInfo->lastKey = pMeterQueryInfo->skey; - - pMeterQueryInfo->queryRangeSet = 0; - pMeterQueryInfo->cur.order = pMeterQueryInfo->cur.order ^ 1; - pMeterQueryInfo->cur.vnodeIndex = -1; - - // previous does not generate any results - SIDList list = getDataBufPagesIdList(pResultBuf, pMeterQueryInfo->sid); - - if (list.size == 0) { - pMeterQueryInfo->reverseFillRes = 0; + // order has change already! + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + if (!QUERY_IS_ASC_QUERY(pQuery)) { + assert(pMeterQueryInfo->ekey >= pMeterQueryInfo->lastKey + step); } else { - pMeterQueryInfo->reverseIndex = pMeterQueryInfo->numOfRes; - pMeterQueryInfo->reverseFillRes = 1; + assert(pMeterQueryInfo->ekey <= pMeterQueryInfo->lastKey + step); } -} -void saveIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, SMeterQueryInfo *pMeterQueryInfo) { - SQuery *pQuery = pRuntimeEnv->pQuery; - - pMeterQueryInfo->skey = pQuery->skey; - pMeterQueryInfo->ekey = pQuery->ekey; - pMeterQueryInfo->lastKey = pQuery->lastKey; + pMeterQueryInfo->ekey = pMeterQueryInfo->lastKey + step; - assert(((pQuery->lastKey >= pQuery->skey) && QUERY_IS_ASC_QUERY(pQuery)) || - ((pQuery->lastKey <= pQuery->skey) && !QUERY_IS_ASC_QUERY(pQuery))); + SWAP(pMeterQueryInfo->skey, pMeterQueryInfo->ekey, TSKEY); + pMeterQueryInfo->lastKey = pMeterQueryInfo->skey; - if (pRuntimeEnv->pTSBuf != NULL) { - pMeterQueryInfo->cur = tsBufGetCursor(pRuntimeEnv->pTSBuf); - } + pMeterQueryInfo->cur.order = pMeterQueryInfo->cur.order ^ 1u; + pMeterQueryInfo->cur.vnodeIndex = -1; } void restoreIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, SMeterQueryInfo *pMeterQueryInfo) { @@ -6555,7 +6772,7 @@ static bool setCurrentQueryRange(SMeterDataInfo *pMeterDataInfo, SQuery *pQuery, * @param pMeterDataInfo * @return */ -int32_t getDataBlocksForMeters(SMeterQuerySupportObj *pSupporter, SQuery *pQuery, int32_t numOfMeters, +int32_t getDataBlocksForMeters(STableQuerySupportObj *pSupporter, SQuery *pQuery, int32_t numOfMeters, const char *filePath, SMeterDataInfo **pMeterDataInfo, uint32_t *numOfBlocks) { SQInfo * pQInfo = (SQInfo *)GET_QINFO_ADDR(pQuery); SQueryCostSummary *pSummary = &pSupporter->runtimeEnv.summary; @@ -6590,13 +6807,13 @@ int32_t getDataBlocksForMeters(SMeterQuerySupportObj *pSupporter, SQuery *pQuery size_t bufferSize = size + sizeof(TSCKSUM); pMeterDataInfo[j]->numOfBlocks = compInfo.numOfBlocks; - char* p = realloc(pMeterDataInfo[j]->pBlock, bufferSize); + char *p = realloc(pMeterDataInfo[j]->pBlock, bufferSize); if (p == NULL) { clearAllMeterDataBlockInfo(pMeterDataInfo, 0, numOfMeters); return TSDB_CODE_SERV_OUT_OF_MEMORY; } else { memset(p, 0, bufferSize); - pMeterDataInfo[j]->pBlock = (SCompBlock*) p; + pMeterDataInfo[j]->pBlock = (SCompBlock *)p; } read(pVnodeFileInfo->headerFd, pMeterDataInfo[j]->pBlock, bufferSize); @@ -6633,7 +6850,7 @@ int32_t getDataBlocksForMeters(SMeterQuerySupportObj *pSupporter, SQuery *pQuery if (!setValidDataBlocks(pMeterDataInfo[j], end)) { clearAllMeterDataBlockInfo(pMeterDataInfo, 0, numOfMeters); - + pQInfo->killed = 1; // set query kill, abort current query since no memory available return TSDB_CODE_SERV_OUT_OF_MEMORY; } @@ -6756,10 +6973,10 @@ int32_t createDataBlocksInfoEx(SMeterDataInfo **pMeterDataInfo, int32_t numOfMet for (int32_t k = 0; k < pMeterDataInfo[j]->numOfBlocks; ++k) { SMeterDataBlockInfoEx *pBlockInfoEx = &supporter.pDataBlockInfoEx[numOfQualMeters][k]; - + pBlockInfoEx->pBlock.compBlock = &pBlock[k]; pBlockInfoEx->pBlock.fields = NULL; - + pBlockInfoEx->pMeterDataInfo = pMeterDataInfo[j]; pBlockInfoEx->groupIdx = pMeterDataInfo[j]->groupIdx; // set the group index pBlockInfoEx->blockIndex = pMeterDataInfo[j]->start + k; // set the block index in original meter @@ -6803,516 +7020,97 @@ int32_t createDataBlocksInfoEx(SMeterDataInfo **pMeterDataInfo, int32_t numOfMet * for(int32_t i = 0; i < cnt - 1; ++i) { * assert((*pDataBlockInfoEx)[i].pBlock.compBlock->offset < (*pDataBlockInfoEx)[i+1].pBlock.compBlock->offset); * } - */ - - dTrace("QInfo %p %d data blocks sort completed", addr, cnt); - cleanBlockOrderSupporter(&supporter, numOfMeters); - free(pTree); - - return TSDB_CODE_SUCCESS; -} - -/** - * set output buffer for different group - * @param pRuntimeEnv - * @param pDataBlockInfoEx - */ -void setExecutionContext(SMeterQuerySupportObj *pSupporter, SOutputRes *outputRes, int32_t meterIdx, int32_t groupIdx, - SMeterQueryInfo *pMeterQueryInfo) { - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - - setGroupOutputBuffer(pRuntimeEnv, &outputRes[groupIdx]); - initCtxOutputBuf(pRuntimeEnv); - - vnodeSetTagValueInParam(pSupporter->pSidSet, pRuntimeEnv, pSupporter->pMeterSidExtInfo[meterIdx]); - - // set the right cursor position for ts buffer - if (pSupporter->runtimeEnv.pTSBuf != NULL) { - if (pMeterQueryInfo->cur.vnodeIndex == -1) { - pMeterQueryInfo->tag = pRuntimeEnv->pCtx[0].tag.i64Key; - - tsBufGetElemStartPos(pSupporter->runtimeEnv.pTSBuf, 0, pMeterQueryInfo->tag); - } else { - tsBufSetCursor(pSupporter->runtimeEnv.pTSBuf, &pMeterQueryInfo->cur); - } - } -} - -static void setGroupOutputBuffer(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes *pResult) { - SQuery *pQuery = pRuntimeEnv->pQuery; - - // Note: pResult->pos[i]->numOfElems == 0, there is only fixed number of results for each group - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i]; - pCtx->aOutputBuf = getPosInResultPage(pRuntimeEnv, i, pResult); - - int32_t functionId = pQuery->pSelectExpr[i].pBase.functionId; - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { - pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].aOutputBuf; - } - - /* - * set the output buffer information and intermediate buffer - * not all queries require the interResultBuf, such as COUNT - */ - pCtx->resultInfo = &pResult->resultInfo[i]; - - // set super table query flag - SResultInfo *pResInfo = GET_RES_INFO(pCtx); - if (!isGroupbyNormalCol(pQuery->pGroupbyExpr)) { - pResInfo->superTableQ = true; - } - } -} - -static char *getOutputResPos(SQueryRuntimeEnv *pRuntimeEnv, tFilePage *pData, int32_t row, int32_t col) { - // the output for each record should be less than the DEFAULT_INTERN_BUF_SIZE - assert(pRuntimeEnv->pCtx[col].outputBytes <= DEFAULT_INTERN_BUF_SIZE); - - return (char *)pData->data + pRuntimeEnv->offset[col] * pRuntimeEnv->numOfRowsPerPage + - pRuntimeEnv->pCtx[col].outputBytes * row; -} - -void setCtxOutputPointerForSupplementScan(SMeterQuerySupportObj *pSupporter, SMeterQueryInfo *pMeterQueryInfo) { - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - SQuery * pQuery = pRuntimeEnv->pQuery; - - int32_t index = pMeterQueryInfo->reverseIndex; - tFilePage *pData = NULL; - int32_t i = 0; - - SQueryResultBuf* pResultBuf = pRuntimeEnv->pResultBuf; - - // find the position for this output result - SIDList list = getDataBufPagesIdList(pResultBuf, pMeterQueryInfo->sid); - for (; i < list.size; ++i) { - pData = getResultBufferPageById(pResultBuf, list.pData[i]); - if (index <= pData->numOfElems) { - break; - } - - index -= pData->numOfElems; - } - - assert(index >= 0); - - /* - * if it is the first records in master scan, no next results exist, so no need to init the result buffer - * all data are processed and save to buffer during supplementary scan. - */ - if (index == 0) { - return; - } - - for (int32_t k = 0; k < pQuery->numOfOutputCols; ++k) { - SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[k]; - - pCtx->aOutputBuf = getOutputResPos(pRuntimeEnv, pData, index - 1, k); - SResultInfo *pResInfo = GET_RES_INFO(pCtx); - if (pResInfo->complete) { - continue; - } - - int32_t functId = pQuery->pSelectExpr[k].pBase.functionId; - - // setup runtime environment - if ((QUERY_IS_ASC_QUERY(pQuery) && functId == TSDB_FUNC_FIRST_DST) || - (!QUERY_IS_ASC_QUERY(pQuery) && functId == TSDB_FUNC_LAST_DST)) { - if (pMeterQueryInfo->lastResRows == 0) { - pCtx->currentStage = 0; - - resetResultInfo(pResInfo); - aAggs[functId].init(pCtx); - } - } - } - - // the first column is always the timestamp for interval query - TSKEY ts = *(TSKEY *)pRuntimeEnv->pCtx[0].aOutputBuf; - SMeterObj *pMeterObj = pRuntimeEnv->pMeterObj; - qTrace("QInfo:%p vid:%d sid:%d id:%s, set output result pointer, ts:%" PRId64 ", index:%d", GET_QINFO_ADDR(pQuery), - pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, ts, pMeterQueryInfo->reverseIndex); -} + */ -void validateTimestampForSupplementResult(SQueryRuntimeEnv *pRuntimeEnv, int64_t numOfIncrementRes) { - SQuery * pQuery = pRuntimeEnv->pQuery; - SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; + dTrace("QInfo %p %d data blocks sort completed", addr, cnt); + cleanBlockOrderSupporter(&supporter, numOfMeters); + free(pTree); - if (pRuntimeEnv->scanFlag == SUPPLEMENTARY_SCAN && numOfIncrementRes > 0) { - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - int32_t functionId = pQuery->pSelectExpr[i].pBase.functionId; - if (functionId == TSDB_FUNC_TS) { - assert(*(TSKEY *)pCtx[i].aOutputBuf == pCtx[i].nStartQueryTimestamp); - } - } - } + return TSDB_CODE_SUCCESS; } -int32_t setOutputBufferForIntervalQuery(SMeterQuerySupportObj *pSupporter, SMeterQueryInfo *pMeterQueryInfo) { +/** + * set output buffer for different group + * @param pRuntimeEnv + * @param pDataBlockInfoEx + */ +void setExecutionContext(STableQuerySupportObj *pSupporter, SMeterQueryInfo *pMeterQueryInfo, int32_t meterIdx, + int32_t groupIdx, TSKEY nextKey) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - tFilePage * pData = NULL; - - SQueryResultBuf* pResultBuf = pRuntimeEnv->pResultBuf; - - // in the first scan, new space needed for results - SIDList list = getDataBufPagesIdList(pResultBuf, pMeterQueryInfo->sid); - int32_t pageId = -1; - if (list.size == 0) { - pData = getNewDataBuf(pResultBuf, pMeterQueryInfo->sid, &pageId); - } else { - pData = getResultBufferPageById(pResultBuf, getLastPageId(&list)); + SWindowResInfo * pWindowResInfo = &pRuntimeEnv->windowResInfo; + int32_t GROUPRESULTID = 1; - if (pData->numOfElems >= pRuntimeEnv->numOfRowsPerPage) { - pData = getNewDataBuf(pResultBuf, pMeterQueryInfo->sid, &pageId); - if (pData != NULL) { - assert(pData->numOfElems == 0); // number of elements must be 0 for new allocated buffer - } - } + SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&groupIdx, sizeof(groupIdx)); + if (pWindowRes == NULL) { + return; } - if (pData == NULL) { - return -1; + /* + * not assign result buffer yet, add new result buffer + * all group belong to one result set, and each group result has different group id so set the id to be one + */ + if (pWindowRes->pos.pageId == -1) { + if (addNewWindowResultBuf(pWindowRes, pRuntimeEnv->pResultBuf, GROUPRESULTID, pRuntimeEnv->numOfRowsPerPage) != + TSDB_CODE_SUCCESS) { + return; + } } - for (int32_t i = 0; i < pRuntimeEnv->pQuery->numOfOutputCols; ++i) { - pRuntimeEnv->pCtx[i].aOutputBuf = getOutputResPos(pRuntimeEnv, pData, pData->numOfElems, i); - pRuntimeEnv->pCtx[i].resultInfo = &pMeterQueryInfo->resultInfo[i]; - } + setWindowResOutputBuf(pRuntimeEnv, pWindowRes); + initCtxOutputBuf(pRuntimeEnv); - return TSDB_CODE_SUCCESS; + pMeterQueryInfo->lastKey = nextKey; + setAdditionalInfo(pSupporter, meterIdx, pMeterQueryInfo); } -int32_t setIntervalQueryExecutionContext(SMeterQuerySupportObj *pSupporter, int32_t meterIdx, - SMeterQueryInfo *pMeterQueryInfo) { - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; +static void setWindowResOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pResult) { + SQuery *pQuery = pRuntimeEnv->pQuery; - if (IS_MASTER_SCAN(pRuntimeEnv)) { - if (setOutputBufferForIntervalQuery(pSupporter, pMeterQueryInfo) != TSDB_CODE_SUCCESS) { - // not enough disk space or memory buffer for intermediate results - return -1; - } + // Note: pResult->pos[i]->numOfElems == 0, there is only fixed number of results for each group + for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { + SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i]; + pCtx->aOutputBuf = getPosInResultPage(pRuntimeEnv, i, pResult); - if (pMeterQueryInfo->lastResRows == 0) { - initCtxOutputBuf(pRuntimeEnv); + int32_t functionId = pQuery->pSelectExpr[i].pBase.functionId; + if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { + pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].aOutputBuf; } - } else { - if (pMeterQueryInfo->reverseFillRes) { - setCtxOutputPointerForSupplementScan(pSupporter, pMeterQueryInfo); - } else { - /* - * set output buffer for reverse scan data blocks - * find the correct output position of existed results during - * - * If the master scan does not produce any results, new spaces needed to be allocated during supplement scan - */ - if (setOutputBufferForIntervalQuery(pSupporter, pMeterQueryInfo) != TSDB_CODE_SUCCESS) { - return -1; - } - } + /* + * set the output buffer information and intermediate buffer + * not all queries require the interResultBuf, such as COUNT + */ + pCtx->resultInfo = &pResult->resultInfo[i]; + + // set super table query flag + SResultInfo *pResInfo = GET_RES_INFO(pCtx); + pResInfo->superTableQ = pRuntimeEnv->stableQuery; } +} + +int32_t setAdditionalInfo(STableQuerySupportObj *pSupporter, int32_t meterIdx, SMeterQueryInfo *pMeterQueryInfo) { + SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; + assert(pMeterQueryInfo->lastKey > 0); vnodeSetTagValueInParam(pSupporter->pSidSet, pRuntimeEnv, pSupporter->pMeterSidExtInfo[meterIdx]); // both the master and supplement scan needs to set the correct ts comp start position - if (pSupporter->runtimeEnv.pTSBuf != NULL) { + if (pRuntimeEnv->pTSBuf != NULL) { if (pMeterQueryInfo->cur.vnodeIndex == -1) { pMeterQueryInfo->tag = pRuntimeEnv->pCtx[0].tag.i64Key; - tsBufGetElemStartPos(pSupporter->runtimeEnv.pTSBuf, 0, pMeterQueryInfo->tag); + tsBufGetElemStartPos(pRuntimeEnv->pTSBuf, 0, pMeterQueryInfo->tag); // keep the cursor info of current meter - pMeterQueryInfo->cur = pSupporter->runtimeEnv.pTSBuf->cur; + pMeterQueryInfo->cur = pRuntimeEnv->pTSBuf->cur; } else { - tsBufSetCursor(pSupporter->runtimeEnv.pTSBuf, &pMeterQueryInfo->cur); + tsBufSetCursor(pRuntimeEnv->pTSBuf, &pMeterQueryInfo->cur); } } return 0; } -//static void doApplyIntervalQueryOnBlock(SMeterQuerySupportObj *pSupporter, SMeterQueryInfo *pMeterQueryInfo, -// SBlockInfo *pBlockInfo, int64_t *pPrimaryCol, SField *pFields, -// __block_search_fn_t searchFn) { -// SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; -// SQuery * pQuery = pRuntimeEnv->pQuery; -// int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); -// -// int64_t nextKey = -1; -// bool queryCompleted = false; -// -// while (1) { -// int32_t numOfRes = 0; -// int32_t steps = applyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, pPrimaryCol, pFields, searchFn, &numOfRes); -// assert(steps > 0); -// -// // NOTE: in case of stable query, only ONE(or ZERO) row of pos generated for each query range -// if (pMeterQueryInfo->lastResRows == 0) { -// pMeterQueryInfo->lastResRows = numOfRes; -// } else { -// assert(pMeterQueryInfo->lastResRows == 1); -// } -// -// int32_t pos = pQuery->pos + steps * factor; -// -// // query does not reach the end of current block -// if ((pos < pBlockInfo->size && QUERY_IS_ASC_QUERY(pQuery)) || (pos >= 0 && !QUERY_IS_ASC_QUERY(pQuery))) { -// nextKey = pPrimaryCol[pos]; -// } else { -// assert((pQuery->lastKey > pBlockInfo->keyLast && QUERY_IS_ASC_QUERY(pQuery)) || -// (pQuery->lastKey < pBlockInfo->keyFirst && !QUERY_IS_ASC_QUERY(pQuery))); -// } -// -// // all data satisfy current query are checked, query completed -// if (QUERY_IS_ASC_QUERY(pQuery)) { -// queryCompleted = (nextKey > pQuery->ekey || pQuery->ekey <= pBlockInfo->keyLast); -// } else { -// queryCompleted = (nextKey < pQuery->ekey || pQuery->ekey >= pBlockInfo->keyFirst); -// } -// -// /* -// * 1. there may be more date that satisfy current query interval, other than -// * current block, we need to try next data blocks -// * 2. query completed, since reaches the upper bound of the main query range -// */ -// if (QUERY_IS_ASC_QUERY(pQuery)) { -// if (pQuery->lastKey > pBlockInfo->keyLast || pQuery->lastKey > pSupporter->rawEKey || -// nextKey > pSupporter->rawEKey) { -// /* -// * current interval query is completed, set query pos flag closed and -// * try next data block if pQuery->ekey == pSupporter->rawEKey, whole query is completed -// */ -// if (pQuery->lastKey > pBlockInfo->keyLast) { -// assert(pQuery->ekey >= pBlockInfo->keyLast); -// } -// -// if (pQuery->lastKey > pSupporter->rawEKey || nextKey > pSupporter->rawEKey) { -// /* whole query completed, save pos and abort */ -// assert(queryCompleted); -// saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); -// -// // save the pQuery->lastKey for retrieve data in cache, actually, there will be no qualified data in cache. -// saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); -// } else if (pQuery->ekey == pBlockInfo->keyLast) { -// /* current interval query is completed, set the next query range on other data blocks if exist */ -// int64_t prevEKey = pQuery->ekey; -// -// getAlignedIntervalQueryRange(pRuntimeEnv, pQuery->lastKey, pSupporter->rawSKey, pSupporter->rawEKey); -// saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); -// -// assert(queryCompleted && prevEKey < pQuery->skey); -// if (pMeterQueryInfo->lastResRows > 0) { -// saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); -// } -// } else { -// /* -// * Data that satisfy current query range may locate in current block and blocks that are directly right -// * next to current block. Therefore, we need to keep the query range(interval) unchanged until reaching -// * the direct next data block, while only forwards the pQuery->lastKey. -// * -// * With the information of the directly next data block, whether locates in cache or disk, -// * current interval query being completed or not can be decided. -// */ -// saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); -// assert(pQuery->lastKey > pBlockInfo->keyLast && pQuery->lastKey <= pQuery->ekey); -// -// /* -// * if current block is the last block of current file, we still close the pos flag, and -// * merge with other meters in the same group -// */ -// if (queryCompleted) { -// saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); -// } -// } -// -// break; -// } -// } else { -// if (pQuery->lastKey < pBlockInfo->keyFirst || pQuery->lastKey < pSupporter->rawEKey || -// nextKey < pSupporter->rawEKey) { -// if (pQuery->lastKey < pBlockInfo->keyFirst) { -// assert(pQuery->ekey <= pBlockInfo->keyFirst); -// } -// -// if (pQuery->lastKey < pSupporter->rawEKey || (nextKey < pSupporter->rawEKey && nextKey != -1)) { -// /* whole query completed, save pos and abort */ -// assert(queryCompleted); -// saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); -// -// /* -// * save the pQuery->lastKey for retrieve data in cache, actually, -// * there will be no qualified data in cache. -// */ -// saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); -// } else if (pQuery->ekey == pBlockInfo->keyFirst) { -// // current interval query is completed, set the next query range on other data blocks if exist -// int64_t prevEKey = pQuery->ekey; -// -// getAlignedIntervalQueryRange(pRuntimeEnv, pQuery->lastKey, pSupporter->rawSKey, pSupporter->rawEKey); -// saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); -// -// assert(queryCompleted && prevEKey > pQuery->skey); -// if (pMeterQueryInfo->lastResRows > 0) { -// saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); -// } -// } else { -// /* -// * Data that satisfy current query range may locate in current block and blocks that are -// * directly right next to current block. Therefore, we need to keep the query range(interval) -// * unchanged until reaching the direct next data block, while only forwards the pQuery->lastKey. -// * -// * With the information of the directly next data block, whether locates in cache or disk, -// * current interval query being completed or not can be decided. -// */ -// saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); -// assert(pQuery->lastKey < pBlockInfo->keyFirst && pQuery->lastKey >= pQuery->ekey); -// -// /* -// * if current block is the last block of current file, we still close the pos -// * flag, and merge with other meters in the same group -// */ -// if (queryCompleted) { -// saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); -// } -// } -// -// break; -// } -// } -// -// assert(queryCompleted); -// saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); -// -// assert((nextKey >= pQuery->lastKey && QUERY_IS_ASC_QUERY(pQuery)) || -// (nextKey <= pQuery->lastKey && !QUERY_IS_ASC_QUERY(pQuery))); -// -// /* still in the same block to query */ -// getAlignedIntervalQueryRange(pRuntimeEnv, nextKey, pSupporter->rawSKey, pSupporter->rawEKey); -// saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); -// -// int32_t newPos = searchFn((char *)pPrimaryCol, pBlockInfo->size, pQuery->skey, pQuery->order.order); -// assert(newPos == pQuery->pos + steps * factor); -// -// pQuery->pos = newPos; -// } -//} - -static void doApplyIntervalQueryOnBlock_rv(SMeterQuerySupportObj *pSupporter, SMeterQueryInfo *pMeterQueryInfo, - SBlockInfo *pBlockInfo, int64_t *pPrimaryCol, SField *pFields, - __block_search_fn_t searchFn) { - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - SQuery * pQuery = pRuntimeEnv->pQuery; - int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); - - while (1) { - int64_t nextKey = -1; - int32_t numOfRes = 0; - - int32_t steps = applyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, pPrimaryCol, pFields, searchFn, &numOfRes); - assert(steps > 0); - - // NOTE: in case of stable query, only ONE(or ZERO) row of result generated for each query range - if (pMeterQueryInfo->lastResRows == 0) { - pMeterQueryInfo->lastResRows = numOfRes; - } else { - assert(pMeterQueryInfo->lastResRows == 1); - } - - int32_t pos = pQuery->pos + steps * factor; - - // query does not reach the end of current block - if ((pos < pBlockInfo->size && QUERY_IS_ASC_QUERY(pQuery)) || (pos >= 0 && !QUERY_IS_ASC_QUERY(pQuery))) { - nextKey = pPrimaryCol[pos]; - } else { - assert((pQuery->lastKey > pBlockInfo->keyLast && QUERY_IS_ASC_QUERY(pQuery)) || - (pQuery->lastKey < pBlockInfo->keyFirst && !QUERY_IS_ASC_QUERY(pQuery))); - } - - // all data satisfy current query are checked, query completed - bool completed = false; - if (QUERY_IS_ASC_QUERY(pQuery)) { - completed = (pQuery->lastKey > pQuery->ekey); - } else { - completed = (pQuery->lastKey < pQuery->ekey); - } - - /* - * 1. there may be more date that satisfy current query interval, other than - * current block, we need to try next data blocks - * 2. query completed, since reaches the upper bound of the main query range - */ - if (!completed) { - /* - * Data that satisfy current query range may locate in current block and blocks that are directly right - * next to current block. Therefore, we need to keep the query range(interval) unchanged until reaching - * the direct next data block, while only forwards the pQuery->lastKey. - * - * With the information of the directly next data block, whether locates in cache or disk, - * current interval query being completed or not can be decided. - */ - saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); - - if (QUERY_IS_ASC_QUERY(pQuery)) { - assert(pQuery->lastKey > pBlockInfo->keyLast && pQuery->lastKey <= pQuery->ekey); - } else { - assert(pQuery->lastKey < pBlockInfo->keyFirst && pQuery->lastKey >= pQuery->ekey); - } - - break; - } - - assert(completed); - - // while the interval time window is less than the time range gap between two points, nextKey may be greater than - // pSupporter->rawEKey - if (pQuery->ekey == pSupporter->rawEKey || (nextKey > pSupporter->rawEKey && QUERY_IS_ASC_QUERY(pQuery)) || - (nextKey < pSupporter->rawEKey && !QUERY_IS_ASC_QUERY(pQuery))) { - /* whole query completed, save result and abort */ - saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); - - // save the pQuery->lastKey for retrieve data in cache, actually, there will be no qualified data in cache. - saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); - - return; - } else if ((QUERY_IS_ASC_QUERY(pQuery) && pQuery->ekey == pBlockInfo->keyLast) || - (!QUERY_IS_ASC_QUERY(pQuery) && pQuery->ekey == pBlockInfo->keyFirst)) { - /* current interval query is completed, set the next query range on other data blocks if exist */ - saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); - return; - } - - saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); - - assert(pos >= 0 && pos < pBlockInfo->size); - assert((nextKey >= pQuery->lastKey && QUERY_IS_ASC_QUERY(pQuery)) || - (nextKey <= pQuery->lastKey && !QUERY_IS_ASC_QUERY(pQuery))); - - /* still in the same block to query */ - getAlignedIntervalQueryRange(pRuntimeEnv, nextKey, pSupporter->rawSKey, pSupporter->rawEKey); - saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); - - int32_t newPos = searchFn((char *)pPrimaryCol, pBlockInfo->size, pQuery->skey, pQuery->order.order); - assert(newPos == pQuery->pos + steps * factor); - - pQuery->pos = newPos; - } - -} -int64_t getNextAccessedKeyInData(SQuery *pQuery, int64_t *pPrimaryCol, SBlockInfo *pBlockInfo, int32_t blockStatus) { - assert(pQuery->pos >= 0 && pQuery->pos <= pBlockInfo->size - 1); - - TSKEY key = -1; - if (IS_DATA_BLOCK_LOADED(blockStatus)) { - key = pPrimaryCol[pQuery->pos]; - } else { - assert(pQuery->pos == pBlockInfo->size - 1 || pQuery->pos == 0); - key = QUERY_IS_ASC_QUERY(pQuery) ? pBlockInfo->keyFirst : pBlockInfo->keyLast; - } - - assert((key >= pQuery->skey && QUERY_IS_ASC_QUERY(pQuery)) || (key <= pQuery->skey && !QUERY_IS_ASC_QUERY(pQuery))); - return key; -} - /* * There are two cases to handle: * @@ -7322,42 +7120,61 @@ int64_t getNextAccessedKeyInData(SQuery *pQuery, int64_t *pPrimaryCol, SBlockInf * merged during merge stage. In this case, we need the pMeterQueryInfo->lastResRows to decide if there * is a previous result generated or not. */ -void setIntervalQueryRange(SMeterQueryInfo *pMeterQueryInfo, SMeterQuerySupportObj *pSupporter, TSKEY key) { +void setIntervalQueryRange(SMeterQueryInfo *pMeterQueryInfo, STableQuerySupportObj *pSupporter, TSKEY key) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; if (pMeterQueryInfo->queryRangeSet) { - assert((QUERY_IS_ASC_QUERY(pQuery) && pQuery->lastKey >= pQuery->skey) || - (!QUERY_IS_ASC_QUERY(pQuery) && pQuery->lastKey <= pQuery->skey)); - - if ((pQuery->ekey < key && QUERY_IS_ASC_QUERY(pQuery)) || (pQuery->ekey > key && !QUERY_IS_ASC_QUERY(pQuery))) { - /* - * last query on this block of the meter is done, start next interval on this block - * otherwise, keep the previous query range and proceed - */ - getAlignedIntervalQueryRange(pRuntimeEnv, key, pSupporter->rawSKey, pSupporter->rawEKey); - saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); - - // previous query does not be closed, save the results and close it - if (pMeterQueryInfo->lastResRows > 0) { - saveResult(pSupporter, pMeterQueryInfo, pMeterQueryInfo->lastResRows); - } - } else { - /* current query not completed, continue. do nothing with respect to query range, */ - } + pQuery->lastKey = key; + pMeterQueryInfo->lastKey = key; } else { pQuery->skey = key; - assert(pMeterQueryInfo->lastResRows == 0); + STimeWindow win = {.skey = key, pSupporter->rawEKey}; + // for too small query range, no data in this interval. if ((QUERY_IS_ASC_QUERY(pQuery) && (pQuery->ekey < pQuery->skey)) || (!QUERY_IS_ASC_QUERY(pQuery) && (pQuery->skey < pQuery->ekey))) { - // for too small query range, no data in this interval. return; } - getAlignedIntervalQueryRange(pRuntimeEnv, pQuery->skey, pSupporter->rawSKey, pSupporter->rawEKey); - saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); + /** + * In handling the both ascending and descending order super table query, we need to find the first qualified + * timestamp of this table, and then set the first qualified start timestamp. + * In ascending query, key is the first qualified timestamp. However, in the descending order query, additional + * operations involve. + */ + if (!QUERY_IS_ASC_QUERY(pQuery)) { + TSKEY k = getGreaterEqualTimestamp(pRuntimeEnv); + win.skey = k; + win.ekey = key; // current key is the last timestamp value that are contained in query time window + + SPositionInfo p = {.fileId = pQuery->fileId, .slot = pQuery->slot, .pos = pQuery->pos}; + loadRequiredBlockIntoMem(pRuntimeEnv, &p); + } + + TSKEY skey1, ekey1; + TSKEY windowSKey = 0, windowEKey = 0; + + SWindowResInfo *pWindowResInfo = &pMeterQueryInfo->windowResInfo; + + doGetAlignedIntervalQueryRangeImpl(pQuery, win.skey, win.skey, win.ekey, &skey1, &ekey1, &windowSKey, &windowEKey); + pWindowResInfo->startTime = windowSKey; // windowSKey may be 0 in case of 1970 timestamp + // assert(pWindowResInfo->startTime > 0); + + if (pWindowResInfo->prevSKey == 0) { + if (QUERY_IS_ASC_QUERY(pQuery)) { + pWindowResInfo->prevSKey = windowSKey; + } else { + assert(win.ekey == pQuery->skey); + pWindowResInfo->prevSKey = windowSKey + ((win.ekey - windowSKey) / pQuery->slidingTime) * pQuery->slidingTime; + } + } + pMeterQueryInfo->queryRangeSet = 1; + pMeterQueryInfo->lastKey = pQuery->skey; + pMeterQueryInfo->skey = pQuery->skey; + + pQuery->lastKey = pQuery->skey; } } @@ -7415,7 +7232,7 @@ int32_t LoadDatablockOnDemand(SCompBlock *pBlock, SField **pFields, uint8_t *blk if (((pQuery->lastKey <= pBlock->keyFirst && pQuery->ekey >= pBlock->keyLast && QUERY_IS_ASC_QUERY(pQuery)) || (pQuery->ekey <= pBlock->keyFirst && pQuery->lastKey >= pBlock->keyLast && !QUERY_IS_ASC_QUERY(pQuery))) && onDemand) { - int32_t req = 0; + uint32_t req = 0; if (pQuery->numOfFilterCols > 0) { req = BLK_DATA_ALL_NEEDED; } else { @@ -7425,7 +7242,7 @@ int32_t LoadDatablockOnDemand(SCompBlock *pBlock, SField **pFields, uint8_t *blk pQuery->pSelectExpr[i].pBase.colInfo.colId, *blkStatus); } - if (pRuntimeEnv->pTSBuf > 0 || (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { + if (pRuntimeEnv->pTSBuf > 0 || isIntervalQuery(pQuery)) { req |= BLK_DATA_ALL_NEEDED; } } @@ -7487,9 +7304,8 @@ int32_t LoadDatablockOnDemand(SCompBlock *pBlock, SField **pFields, uint8_t *blk /* find first qualified record position in this block */ if (loadTS) { - /* find first qualified record position in this block */ - pQuery->pos = - searchFn(pRuntimeEnv->primaryColBuffer->data, pBlock->numOfPoints, pQuery->lastKey, pQuery->order.order); + pQuery->pos = searchFn((char *)primaryKeys, pBlock->numOfPoints, pQuery->lastKey, pQuery->order.order); + /* boundary timestamp check */ assert(pBlock->keyFirst == primaryKeys[0] && pBlock->keyLast == primaryKeys[pBlock->numOfPoints - 1]); } @@ -7509,121 +7325,15 @@ int32_t LoadDatablockOnDemand(SCompBlock *pBlock, SField **pFields, uint8_t *blk } bool onDemandLoadDatablock(SQuery *pQuery, int16_t queryRangeSet) { - return (pQuery->nAggTimeInterval == 0) || ((queryRangeSet == 1) && (pQuery->nAggTimeInterval > 0)); -} - -static void validateResultBuf(SMeterQuerySupportObj *pSupporter, SMeterQueryInfo *pMeterQueryInfo) { - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - SQuery * pQuery = pSupporter->runtimeEnv.pQuery; - SQueryResultBuf* pResultBuf = pRuntimeEnv->pResultBuf; - - SIDList list = getDataBufPagesIdList(pResultBuf, pMeterQueryInfo->sid); - int32_t id = getLastPageId(&list); - - tFilePage* newOutput = getResultBufferPageById(pResultBuf, id); - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - assert(pRuntimeEnv->pCtx[i].aOutputBuf - newOutput->data < DEFAULT_INTERN_BUF_SIZE); - } -} - -int32_t saveResult(SMeterQuerySupportObj *pSupporter, SMeterQueryInfo *pMeterQueryInfo, int32_t numOfResult) { - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - SQuery * pQuery = pRuntimeEnv->pQuery; - - // no results generated, do nothing for master scan - if (numOfResult <= 0) { - if (IS_MASTER_SCAN(pRuntimeEnv)) { - return TSDB_CODE_SUCCESS; - } else { - /* - * There is a case that no result generated during the the supplement scan, and during the main - * scan also no result generated. The index can be backwards moved. - * - * However, if during the main scan, there is a result generated, such as applies count to timestamp, which - * always generates a result, but applies last query to a NULL column may fail to generate results during the - * supplement scan. - * - * NOTE: - * nStartQueryTimestamp is the actually timestamp of current interval, if the actually interval timestamp - * equals to the recorded timestamp that is acquired during the master scan, backwards one step even - * there is no results during the supplementary scan. - */ - TSKEY ts = *(TSKEY *)pRuntimeEnv->pCtx[0].aOutputBuf; - if (ts == pRuntimeEnv->pCtx[0].nStartQueryTimestamp && pMeterQueryInfo->reverseIndex > 0) { - assert(pMeterQueryInfo->numOfRes >= 0 && pMeterQueryInfo->reverseIndex > 0 && - pMeterQueryInfo->reverseIndex <= pMeterQueryInfo->numOfRes); - - // backward one step from the previous position, the start position is (pMeterQueryInfo->numOfRows-1); - pMeterQueryInfo->reverseIndex -= 1; - setCtxOutputPointerForSupplementScan(pSupporter, pMeterQueryInfo); - } - - return TSDB_CODE_SUCCESS; - } - } - - assert(pMeterQueryInfo->lastResRows == 1); - numOfResult = 1; - pMeterQueryInfo->lastResRows = 0; - - if (IS_SUPPLEMENT_SCAN(pRuntimeEnv) && pMeterQueryInfo->reverseFillRes == 1) { - assert(pMeterQueryInfo->numOfRes > 0 && pMeterQueryInfo->reverseIndex > 0 && - pMeterQueryInfo->reverseIndex <= pMeterQueryInfo->numOfRes); - // backward one step from the previous position, the start position is (pMeterQueryInfo->numOfRows-1); - pMeterQueryInfo->reverseIndex -= 1; - setCtxOutputPointerForSupplementScan(pSupporter, pMeterQueryInfo); - } else { - SIDList list = getDataBufPagesIdList(pRuntimeEnv->pResultBuf, pMeterQueryInfo->sid); - - int32_t pageId = getLastPageId(&list); - tFilePage* pData = getResultBufferPageById(pRuntimeEnv->pResultBuf, pageId); - - // in handling records occuring around '1970-01-01', the aligned start timestamp may be 0. - TSKEY ts = *(TSKEY *)getOutputResPos(pRuntimeEnv, pData, pData->numOfElems, 0); - - SMeterObj *pMeterObj = pRuntimeEnv->pMeterObj; - qTrace("QInfo:%p vid:%d sid:%d id:%s, save results, ts:%" PRId64 ", total:%d", GET_QINFO_ADDR(pQuery), - pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, ts, pMeterQueryInfo->numOfRes + 1); - - pData->numOfElems += numOfResult; - pMeterQueryInfo->numOfRes += numOfResult; - assert(pData->numOfElems <= pRuntimeEnv->numOfRowsPerPage); - - if (setOutputBufferForIntervalQuery(pSupporter, pMeterQueryInfo) != TSDB_CODE_SUCCESS) { - return -1; - } - - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - resetResultInfo(&pMeterQueryInfo->resultInfo[i]); - } - - validateResultBuf(pSupporter, pMeterQueryInfo); - initCtxOutputBuf(pRuntimeEnv); -#if 0 - SSchema sc[TSDB_MAX_COLUMNS] = {0}; - sc[0].type = TSDB_DATA_TYPE_BIGINT; - sc[0].bytes = 8; - - sc[1].type = TSDB_DATA_TYPE_BIGINT; - sc[1].bytes = 8; - - UNUSED(sc); - SColumnModel *cm = createColumnModel(sc, pQuery->numOfOutputCols, pRuntimeEnv->numOfRowsPerPage); - -// if (outputPage->numOfElems + numOfResult >= pRuntimeEnv->numOfRowsPerPage) - tColModelDisplay(cm, outputPage->data, outputPage->numOfElems, pRuntimeEnv->numOfRowsPerPage); -#endif - } - - return TSDB_CODE_SUCCESS; + return (pQuery->intervalTime == 0) || ((queryRangeSet == 1) && (isIntervalQuery(pQuery))); } -static int32_t getNumOfSubset(SMeterQuerySupportObj *pSupporter) { +static int32_t getNumOfSubset(STableQuerySupportObj *pSupporter) { SQuery *pQuery = pSupporter->runtimeEnv.pQuery; int32_t totalSubset = 0; - if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (pQuery->nAggTimeInterval > 0 && pQuery->slidingTime > 0)) { - totalSubset = numOfClosedSlidingWindow(&pSupporter->runtimeEnv.swindowResInfo); + if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (isIntervalQuery(pQuery))) { + totalSubset = numOfClosedTimeWindow(&pSupporter->runtimeEnv.windowResInfo); } else { totalSubset = pSupporter->pSidSet->numOfSubSet; } @@ -7631,26 +7341,26 @@ static int32_t getNumOfSubset(SMeterQuerySupportObj *pSupporter) { return totalSubset; } -static int32_t doCopyFromGroupBuf(SMeterQuerySupportObj *pSupporter, SOutputRes *result, int32_t orderType) { +static int32_t doCopyToSData(STableQuerySupportObj *pSupporter, SWindowResult *result, int32_t orderType) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; int32_t numOfResult = 0; int32_t startIdx = 0; - int32_t forward = 1; - - dTrace("QInfo:%p start to copy data to dest buf", GET_QINFO_ADDR(pSupporter->runtimeEnv.pQuery)); + int32_t step = -1; + dTrace("QInfo:%p start to copy data from windowResInfo to pQuery buf", GET_QINFO_ADDR(pQuery)); int32_t totalSubset = getNumOfSubset(pSupporter); if (orderType == TSQL_SO_ASC) { startIdx = pSupporter->subgroupIdx; - } else { // desc + step = 1; + } else { // desc order copy all data startIdx = totalSubset - pSupporter->subgroupIdx - 1; - forward = -1; + step = -1; } - for (int32_t i = startIdx; (i < totalSubset) && (i >= 0); i += forward) { + for (int32_t i = startIdx; (i < totalSubset) && (i >= 0); i += step) { if (result[i].numOfRows == 0) { pSupporter->offset = 0; pSupporter->subgroupIdx += 1; @@ -7662,8 +7372,11 @@ static int32_t doCopyFromGroupBuf(SMeterQuerySupportObj *pSupporter, SOutputRes int32_t numOfRowsToCopy = result[i].numOfRows - pSupporter->offset; int32_t oldOffset = pSupporter->offset; + /* + * current output space is not enough to keep all the result data of this group, only copy partial results + * to SQuery object's result buffer + */ if (numOfRowsToCopy > pQuery->pointsToRead - numOfResult) { - // current output space is not enough for the keep the data of this group numOfRowsToCopy = pQuery->pointsToRead - numOfResult; pSupporter->offset += numOfRowsToCopy; } else { @@ -7672,10 +7385,11 @@ static int32_t doCopyFromGroupBuf(SMeterQuerySupportObj *pSupporter, SOutputRes } for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { - int32_t elemSize = pRuntimeEnv->pCtx[j].outputBytes; - char * outputBuf = pQuery->sdata[j]->data + numOfResult * elemSize; - char* p = getPosInResultPage(pRuntimeEnv, j, &result[i]); - memcpy(outputBuf, p + oldOffset * elemSize, elemSize * numOfRowsToCopy); + int32_t size = pRuntimeEnv->pCtx[j].outputBytes; + + char *out = pQuery->sdata[j]->data + numOfResult * size; + char *in = getPosInResultPage(pRuntimeEnv, j, &result[i]); + memcpy(out, in + oldOffset * size, size * numOfRowsToCopy); } numOfResult += numOfRowsToCopy; @@ -7684,7 +7398,7 @@ static int32_t doCopyFromGroupBuf(SMeterQuerySupportObj *pSupporter, SOutputRes } } - dTrace("QInfo:%p done copy data to dst buf", GET_QINFO_ADDR(pSupporter->runtimeEnv.pQuery)); + dTrace("QInfo:%p copy data to SQuery buf completed", GET_QINFO_ADDR(pQuery)); #ifdef _DEBUG_VIEW displayInterResult(pQuery->sdata, pQuery, numOfResult); @@ -7693,58 +7407,63 @@ static int32_t doCopyFromGroupBuf(SMeterQuerySupportObj *pSupporter, SOutputRes } /** - * copyFromGroupBuf support copy data in ascending/descending order + * copyFromWindowResToSData support copy data in ascending/descending order + * For interval query of both super table and table, copy the data in ascending order, since the output results are + * ordered in SWindowResutl already. While handling the group by query for both table and super table, + * all group result are completed already. + * * @param pQInfo * @param result */ -void copyFromGroupBuf(SQInfo *pQInfo, SOutputRes *result) { +void copyFromWindowResToSData(SQInfo *pQInfo, SWindowResult *result) { SQuery * pQuery = &pQInfo->query; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; int32_t orderType = (pQuery->pGroupbyExpr != NULL) ? pQuery->pGroupbyExpr->orderType : TSQL_SO_ASC; - int32_t numOfResult = doCopyFromGroupBuf(pSupporter, result, orderType); + int32_t numOfResult = doCopyToSData(pSupporter, result, orderType); pQuery->pointsRead += numOfResult; assert(pQuery->pointsRead <= pQuery->pointsToRead); } -static void applyIntervalQueryOnBlock(SMeterQuerySupportObj *pSupporter, SMeterDataInfo *pMeterDataInfo, - SBlockInfo *pBlockInfo, int32_t blockStatus, SField *pFields, - __block_search_fn_t searchFn) { - SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; - SQuery * pQuery = pRuntimeEnv->pQuery; - SMeterQueryInfo * pMeterQueryInfo = pMeterDataInfo->pMeterQInfo; +static void updateWindowResNumOfRes(SQueryRuntimeEnv *pRuntimeEnv, SMeterDataInfo *pMeterDataInfo) { + SQuery *pQuery = pRuntimeEnv->pQuery; - int64_t* pPrimaryKey = (int64_t*) pRuntimeEnv->primaryColBuffer->data; - /* - * for each block, we need to handle the previous query, since the determination of previous query being completed - * or not is based on the start key of current block. - */ - TSKEY key = getNextAccessedKeyInData(pQuery, pPrimaryKey, pBlockInfo, blockStatus); - setIntervalQueryRange(pMeterDataInfo->pMeterQInfo, pSupporter, key); + // update the number of result for each, only update the number of rows for the corresponding window result. + if (pQuery->intervalTime == 0) { + int32_t g = pMeterDataInfo->groupIdx; + assert(pRuntimeEnv->windowResInfo.size > 0); - if (((pQuery->skey > pQuery->ekey) && QUERY_IS_ASC_QUERY(pQuery)) || - ((pQuery->skey < pQuery->ekey) && !QUERY_IS_ASC_QUERY(pQuery))) { - return; + SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, (char *)&g, sizeof(g)); + if (pWindowRes->numOfRows == 0) { + pWindowRes->numOfRows = getNumOfResult(pRuntimeEnv); + } } +} + +void stableApplyFunctionsOnBlock(STableQuerySupportObj *pSupporter, SMeterDataInfo *pMeterDataInfo, + SBlockInfo *pBlockInfo, SField *pFields, __block_search_fn_t searchFn) { + SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; + SQuery * pQuery = pRuntimeEnv->pQuery; + SMeterQueryInfo * pMeterQueryInfo = pMeterDataInfo->pMeterQInfo; + SWindowResInfo * pWindowResInfo = &pMeterQueryInfo->windowResInfo; - if (((pBlockInfo->keyLast < pQuery->ekey) && QUERY_IS_ASC_QUERY(pQuery)) || - ((pBlockInfo->keyFirst > pQuery->ekey) && !QUERY_IS_ASC_QUERY(pQuery))) { - int32_t numOfRes = 0; - /* current block is included in this interval */ - int32_t steps = applyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, pPrimaryKey, pFields, searchFn, &numOfRes); - assert(numOfRes <= 1 && numOfRes >= 0 && steps > 0); + int64_t *pPrimaryKey = (int64_t *)pRuntimeEnv->primaryColBuffer->data; - if (pMeterQueryInfo->lastResRows == 0) { - pMeterQueryInfo->lastResRows = numOfRes; - } else { - assert(pMeterQueryInfo->lastResRows == 1); - } + int32_t forwardStep = + getNumOfRowsInTimeWindow(pQuery, pBlockInfo, pPrimaryKey, pQuery->pos, pQuery->ekey, searchFn, true); - saveIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); + int32_t numOfRes = 0; + if (pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTSBuf != NULL) { + numOfRes = rowwiseApplyAllFunctions(pRuntimeEnv, &forwardStep, pFields, pBlockInfo, pWindowResInfo); } else { - doApplyIntervalQueryOnBlock_rv(pSupporter, pMeterQueryInfo, pBlockInfo, pPrimaryKey, pFields, searchFn); + numOfRes = blockwiseApplyAllFunctions(pRuntimeEnv, forwardStep, pFields, pBlockInfo, pWindowResInfo, searchFn); } + + assert(numOfRes >= 0); + + updateWindowResNumOfRes(pRuntimeEnv, pMeterDataInfo); + updatelastkey(pQuery, pMeterQueryInfo); } // we need to split the refstatsult into different packages. @@ -7758,7 +7477,7 @@ int32_t vnodeGetResultSize(void *thandle, int32_t *numOfRows) { * * TODO handle the case that the file is too large to send back one time */ - if (pQInfo->pMeterQuerySupporter != NULL && isTSCompQuery(pQuery) && (*numOfRows) > 0) { + if (pQInfo->pTableQuerySupporter != NULL && isTSCompQuery(pQuery) && (*numOfRows) > 0) { struct stat fstat; if (stat(pQuery->sdata[0]->data, &fstat) == 0) { *numOfRows = fstat.st_size; @@ -7779,7 +7498,7 @@ int64_t vnodeGetOffsetVal(void *thandle) { bool vnodeHasRemainResults(void *handle) { SQInfo * pQInfo = (SQInfo *)handle; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; if (pSupporter == NULL || pQInfo->query.interpoType == TSDB_INTERPO_NONE) { return false; @@ -7803,10 +7522,10 @@ bool vnodeHasRemainResults(void *handle) { // query has completed if (Q_STATUS_EQUAL(pQuery->over, QUERY_COMPLETED | QUERY_NO_DATA_TO_CHECK)) { - TSKEY ekey = taosGetRevisedEndKey(pSupporter->rawEKey, pQuery->order.order, pQuery->nAggTimeInterval, + TSKEY ekey = taosGetRevisedEndKey(pSupporter->rawEKey, pQuery->order.order, pQuery->intervalTime, pQuery->intervalTimeUnit, pQuery->precision); int32_t numOfTotal = taosGetNumOfResultWithInterpo(pInterpoInfo, (TSKEY *)pRuntimeEnv->pInterpoBuf[0]->data, - remain, pQuery->nAggTimeInterval, ekey, pQuery->pointsToRead); + remain, pQuery->intervalTime, ekey, pQuery->pointsToRead); return numOfTotal > 0; } @@ -7817,7 +7536,7 @@ bool vnodeHasRemainResults(void *handle) { static int32_t resultInterpolate(SQInfo *pQInfo, tFilePage **data, tFilePage **pDataSrc, int32_t numOfRows, int32_t outputRows) { SQuery * pQuery = &pQInfo->query; - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv; + SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pTableQuerySupporter->runtimeEnv; assert(pRuntimeEnv->pCtx[0].outputBytes == TSDB_KEYSIZE); @@ -7839,7 +7558,7 @@ static int32_t resultInterpolate(SQInfo *pQInfo, tFilePage **data, tFilePage **p } int32_t numOfRes = taosDoInterpoResult(&pRuntimeEnv->interpoInfo, pQuery->interpoType, data, numOfRows, outputRows, - pQuery->nAggTimeInterval, (int64_t *)pDataSrc[0]->data, pModel, srcData, + pQuery->intervalTime, (int64_t *)pDataSrc[0]->data, pModel, srcData, pQuery->defaultVal, functions, pRuntimeEnv->pMeterObj->pointsPerFileBlock); destroyColumnModel(pModel); @@ -7907,18 +7626,17 @@ int32_t vnodeCopyQueryResultToMsg(void *handle, char *data, int32_t numOfRows) { int32_t vnodeQueryResultInterpolate(SQInfo *pQInfo, tFilePage **pDst, tFilePage **pDataSrc, int32_t numOfRows, int32_t *numOfInterpo) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; while (1) { numOfRows = taosNumOfRemainPoints(&pRuntimeEnv->interpoInfo); - TSKEY ekey = taosGetRevisedEndKey(pSupporter->rawEKey, pQuery->order.order, pQuery->nAggTimeInterval, + TSKEY ekey = taosGetRevisedEndKey(pSupporter->rawEKey, pQuery->order.order, pQuery->intervalTime, pQuery->intervalTimeUnit, pQuery->precision); - int32_t numOfFinalRows = - taosGetNumOfResultWithInterpo(&pRuntimeEnv->interpoInfo, (TSKEY *)pDataSrc[0]->data, numOfRows, - pQuery->nAggTimeInterval, ekey, pQuery->pointsToRead); + int32_t numOfFinalRows = taosGetNumOfResultWithInterpo(&pRuntimeEnv->interpoInfo, (TSKEY *)pDataSrc[0]->data, + numOfRows, pQuery->intervalTime, ekey, pQuery->pointsToRead); int32_t ret = resultInterpolate(pQInfo, pDst, pDataSrc, numOfRows, numOfFinalRows); assert(ret == numOfFinalRows); @@ -7949,7 +7667,7 @@ int32_t vnodeQueryResultInterpolate(SQInfo *pQInfo, tFilePage **pDst, tFilePage } } -void vnodePrintQueryStatistics(SMeterQuerySupportObj *pSupporter) { +void vnodePrintQueryStatistics(STableQuerySupportObj *pSupporter) { SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery *pQuery = pRuntimeEnv->pQuery; diff --git a/src/vnode/detail/src/vnodeQueryProcess.c b/src/vnode/detail/src/vnodeQueryProcess.c index c243a78e837cbc0f1ad60d83a7786da3aae54d3a..ae51365918b142e392dcffa27a6b071543f3d02e 100644 --- a/src/vnode/detail/src/vnodeQueryProcess.c +++ b/src/vnode/detail/src/vnodeQueryProcess.c @@ -26,8 +26,9 @@ #include "vnodeQueryImpl.h" -#define ALL_CACHE_BLOCKS_CHECKED(q) \ - (((q)->slot == (q)->currentSlot && QUERY_IS_ASC_QUERY(q)) || ((q)->slot == (q)->firstSlot && (!QUERY_IS_ASC_QUERY(q)))) +#define ALL_CACHE_BLOCKS_CHECKED(q) \ + (((q)->slot == (q)->currentSlot && QUERY_IS_ASC_QUERY(q)) || \ + ((q)->slot == (q)->firstSlot && (!QUERY_IS_ASC_QUERY(q)))) #define FORWARD_CACHE_BLOCK_CHECK_SLOT(slot, step, maxblocks) (slot) = ((slot) + (step) + (maxblocks)) % (maxblocks); @@ -47,23 +48,10 @@ static bool isGroupbyEachTable(SSqlGroupbyExpr *pGroupbyExpr, tSidSet *pSidset) return false; } -static bool doCheckWithPrevQueryRange(SQInfo *pQInfo, TSKEY nextKey, SMeterDataInfo *pMeterInfo) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; - SQuery * pQuery = &pQInfo->query; - SMeterObj * pMeterObj = pMeterInfo->pMeterObj; - - /* no data for current query */ +static bool doCheckWithPrevQueryRange(SQuery *pQuery, TSKEY nextKey) { if ((nextKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || (nextKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { - if (((nextKey > pSupporter->rawEKey) && QUERY_IS_ASC_QUERY(pQuery)) || - ((nextKey < pSupporter->rawEKey) && (!QUERY_IS_ASC_QUERY(pQuery)))) { - dTrace("QInfo:%p vid:%d sid:%d id:%s, no data qualified in block, ignore", pQInfo, pMeterObj->vnode, - pMeterObj->sid, pMeterObj->meterId); - - return false; - } else { // in case of interval query, forward the query range - setIntervalQueryRange(pMeterInfo->pMeterQInfo, pSupporter, nextKey); - } + return false; } return true; @@ -86,8 +74,8 @@ static void setStartPositionForCacheBlock(SQuery *pQuery, SCacheBlock *pBlock, b } static void enableExecutionForNextTable(SQueryRuntimeEnv *pRuntimeEnv) { - SQuery* pQuery = pRuntimeEnv->pQuery; - + SQuery *pQuery = pRuntimeEnv->pQuery; + for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[i]); if (pResInfo != NULL) { @@ -96,10 +84,10 @@ static void enableExecutionForNextTable(SQueryRuntimeEnv *pRuntimeEnv) { } } -static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) { +static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo) { SQuery * pQuery = &pQInfo->query; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; - SQueryRuntimeEnv * pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; + SQueryRuntimeEnv * pRuntimeEnv = &pQInfo->pTableQuerySupporter->runtimeEnv; SMeterSidExtInfo **pMeterSidExtInfo = pSupporter->pMeterSidExtInfo; @@ -131,17 +119,18 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) { pQInfo->pObj = pMeterObj; pRuntimeEnv->pMeterObj = pMeterObj; - if (pMeterInfo[k].pMeterQInfo == NULL) { - pMeterInfo[k].pMeterQInfo = createMeterQueryInfo(pQuery, pMeterObj->sid, pSupporter->rawSKey, pSupporter->rawEKey); + if (pMeterDataInfo[k].pMeterQInfo == NULL) { + pMeterDataInfo[k].pMeterQInfo = + createMeterQueryInfo(pSupporter, pMeterObj->sid, pSupporter->rawSKey, pSupporter->rawEKey); } - if (pMeterInfo[k].pMeterObj == NULL) { // no data in disk for this meter, set its pointer - setMeterDataInfo(&pMeterInfo[k], pMeterObj, k, groupIdx); + if (pMeterDataInfo[k].pMeterObj == NULL) { // no data in disk for this meter, set its pointer + setMeterDataInfo(&pMeterDataInfo[k], pMeterObj, k, groupIdx); } - assert(pMeterInfo[k].meterOrderIdx == k && pMeterObj == pMeterInfo[k].pMeterObj); + assert(pMeterDataInfo[k].meterOrderIdx == k && pMeterObj == pMeterDataInfo[k].pMeterObj); - SMeterQueryInfo *pMeterQueryInfo = pMeterInfo[k].pMeterQInfo; + SMeterQueryInfo *pMeterQueryInfo = pMeterDataInfo[k].pMeterQInfo; restoreIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); /* @@ -154,29 +143,18 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) { vnodeUpdateQueryColumnIndex(pQuery, pMeterObj); vnodeUpdateFilterColumnIndex(pQuery); - if (pQuery->nAggTimeInterval == 0) { - if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { - dTrace( - "QInfo:%p vid:%d sid:%d id:%s, query completed, ignore data in cache. qrange:%" PRId64 "-%" PRId64 ", " - "lastKey:%" PRId64, - pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, - pQuery->lastKey); - - continue; - } + if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { + dTrace("QInfo:%p vid:%d sid:%d id:%s, query completed, ignore data in cache. qrange:%" PRId64 "-%" PRId64 + ", lastKey:%" PRId64, + pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, + pQuery->lastKey); - setExecutionContext(pSupporter, pSupporter->pResult, k, pMeterInfo[k].groupIdx, pMeterQueryInfo); - } else { - int32_t ret = setIntervalQueryExecutionContext(pSupporter, k, pMeterQueryInfo); - if (ret != TSDB_CODE_SUCCESS) { - pQInfo->killed = 1; - return; - } + continue; } - qTrace("QInfo:%p vid:%d sid:%d id:%s, query in cache, qrange:%" PRId64 "-%" PRId64 ", lastKey:%" PRId64, pQInfo, pMeterObj->vnode, - pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery->lastKey); + qTrace("QInfo:%p vid:%d sid:%d id:%s, query in cache, qrange:%" PRId64 "-%" PRId64 ", lastKey:%" PRId64, pQInfo, + pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery->lastKey); /* * find the appropriated start position in cache @@ -186,7 +164,7 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) { * should be ignored (the fourth parameter). */ TSKEY nextKey = getQueryStartPositionInCache(pRuntimeEnv, &pQuery->slot, &pQuery->pos, true); - if (nextKey < 0) { + if (nextKey < 0 || !doCheckWithPrevQueryRange(pQuery, nextKey)) { qTrace("QInfo:%p vid:%d sid:%d id:%s, no data qualified in cache, cache blocks:%d, lastKey:%" PRId64, pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->numOfBlocks, pQuery->lastKey); continue; @@ -199,10 +177,6 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) { continue; } - if (!doCheckWithPrevQueryRange(pQInfo, nextKey, &pMeterInfo[k])) { - continue; - } - bool firstCheckSlot = true; SCacheInfo *pCacheInfo = (SCacheInfo *)pMeterObj->pCache; @@ -224,24 +198,39 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) { setStartPositionForCacheBlock(pQuery, pBlock, &firstCheckSlot); - TSKEY* primaryKeys = (TSKEY*) pRuntimeEnv->primaryColBuffer->data; - + TSKEY *primaryKeys = (TSKEY *)pRuntimeEnv->primaryColBuffer->data; + TSKEY key = primaryKeys[pQuery->pos]; + // in handling file data block, the timestamp range validation is done during fetching candidate file blocks - if ((primaryKeys[pQuery->pos] > pSupporter->rawEKey && QUERY_IS_ASC_QUERY(pQuery)) || - (primaryKeys[pQuery->pos] < pSupporter->rawEKey && !QUERY_IS_ASC_QUERY(pQuery))) { + if ((key > pSupporter->rawEKey && QUERY_IS_ASC_QUERY(pQuery)) || + (key < pSupporter->rawEKey && !QUERY_IS_ASC_QUERY(pQuery))) { break; } + if (pQuery->intervalTime == 0) { + setExecutionContext(pSupporter, pMeterQueryInfo, k, pMeterDataInfo[k].groupIdx, key); + } else { + setIntervalQueryRange(pMeterQueryInfo, pSupporter, key); + int32_t ret = setAdditionalInfo(pSupporter, k, pMeterQueryInfo); + if (ret != TSDB_CODE_SUCCESS) { + pQInfo->killed = 1; + return; + } + } + + qTrace("QInfo:%p vid:%d sid:%d id:%s, query in cache, qrange:%" PRId64 "-%" PRId64 ", lastKey:%" PRId64, pQInfo, + pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery->lastKey); + // only record the key on last block SET_CACHE_BLOCK_FLAG(pRuntimeEnv->blockStatus); - SBlockInfo binfo = getBlockBasicInfo(pRuntimeEnv, pBlock, BLK_CACHE_BLOCK); + SBlockInfo binfo = getBlockInfo(pRuntimeEnv); dTrace("QInfo:%p check data block, brange:%" PRId64 "-%" PRId64 ", fileId:%d, slot:%d, pos:%d, bstatus:%d", GET_QINFO_ADDR(pQuery), binfo.keyFirst, binfo.keyLast, pQuery->fileId, pQuery->slot, pQuery->pos, pRuntimeEnv->blockStatus); totalBlocks++; - queryOnBlock(pSupporter, primaryKeys, pRuntimeEnv->blockStatus, &binfo, &pMeterInfo[k], NULL, searchFn); + stableApplyFunctionsOnBlock(pSupporter, &pMeterDataInfo[k], &binfo, NULL, searchFn); if (ALL_CACHE_BLOCKS_CHECKED(pQuery)) { break; @@ -266,7 +255,7 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) { static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo) { SQuery * pQuery = &pQInfo->query; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; SMeterDataBlockInfoEx *pDataBlockInfoEx = NULL; int32_t nAllocBlocksInfoSize = 0; @@ -274,9 +263,9 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo SMeterObj * pTempMeter = getMeterObj(pSupporter->pMetersHashTable, pSupporter->pMeterSidExtInfo[0]->sid); __block_search_fn_t searchFn = vnodeSearchKeyFunc[pTempMeter->searchAlgorithm]; - int32_t vnodeId = pTempMeter->vnode; - SQueryFilesInfo* pVnodeFileInfo = &pRuntimeEnv->vnodeFileInfo; - + int32_t vnodeId = pTempMeter->vnode; + SQueryFilesInfo *pVnodeFileInfo = &pRuntimeEnv->vnodeFileInfo; + dTrace("QInfo:%p start to check data blocks in %d files", pQInfo, pVnodeFileInfo->numOfFiles); int32_t fid = QUERY_IS_ASC_QUERY(pQuery) ? -1 : INT32_MAX; @@ -291,7 +280,7 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo break; } - int32_t fileIdx = vnodeGetVnodeHeaderFileIdx(&fid, pRuntimeEnv, pQuery->order.order); + int32_t fileIdx = vnodeGetVnodeHeaderFileIndex(&fid, pRuntimeEnv, pQuery->order.order); if (fileIdx < 0) { // no valid file, abort current search break; } @@ -304,25 +293,25 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo fid += step; continue; } - + int32_t numOfQualifiedMeters = 0; assert(fileIdx == pRuntimeEnv->vnodeFileInfo.current); - + SMeterDataInfo **pReqMeterDataInfo = NULL; - int32_t ret = vnodeFilterQualifiedMeters(pQInfo, vnodeId, pSupporter->pSidSet, pMeterDataInfo, + int32_t ret = vnodeFilterQualifiedMeters(pQInfo, vnodeId, pSupporter->pSidSet, pMeterDataInfo, &numOfQualifiedMeters, &pReqMeterDataInfo); if (ret != TSDB_CODE_SUCCESS) { dError("QInfo:%p failed to create meterdata struct to perform query processing, abort", pQInfo); - + tfree(pReqMeterDataInfo); pQInfo->code = -ret; pQInfo->killed = 1; - + return; } dTrace("QInfo:%p file:%s, %d meters qualified", pQInfo, pVnodeFileInfo->dataFilePath, numOfQualifiedMeters); - + // none of meters in query set have pHeaderFileData in this file, try next file if (numOfQualifiedMeters == 0) { fid += step; @@ -335,17 +324,17 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo pReqMeterDataInfo, &numOfBlocks); if (ret != TSDB_CODE_SUCCESS) { dError("QInfo:%p failed to get data block before scan data blocks, abort", pQInfo); - + tfree(pReqMeterDataInfo); pQInfo->code = -ret; pQInfo->killed = 1; - + return; } dTrace("QInfo:%p file:%s, %d meters contains %d blocks to be checked", pQInfo, pVnodeFileInfo->dataFilePath, numOfQualifiedMeters, numOfBlocks); - + if (numOfBlocks == 0) { fid += step; tfree(pReqMeterDataInfo); @@ -353,7 +342,7 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo } ret = createDataBlocksInfoEx(pReqMeterDataInfo, numOfQualifiedMeters, &pDataBlockInfoEx, numOfBlocks, - &nAllocBlocksInfoSize, (int64_t)pQInfo); + &nAllocBlocksInfoSize, (int64_t)pQInfo); if (ret != TSDB_CODE_SUCCESS) { // failed to create data blocks dError("QInfo:%p build blockInfoEx failed, abort", pQInfo); tfree(pReqMeterDataInfo); @@ -383,8 +372,8 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo stimeUnit = taosGetTimestampMs(); } else if ((j % TRACE_OUTPUT_BLOCK_CNT) == 0) { etimeUnit = taosGetTimestampMs(); - dTrace("QInfo:%p load and check %" PRId64 " blocks, and continue. elapsed:%" PRId64 " ms", pQInfo, TRACE_OUTPUT_BLOCK_CNT, - etimeUnit - stimeUnit); + dTrace("QInfo:%p load and check %" PRId64 " blocks, and continue. elapsed:%" PRId64 " ms", pQInfo, + TRACE_OUTPUT_BLOCK_CNT, etimeUnit - stimeUnit); stimeUnit = taosGetTimestampMs(); } @@ -398,56 +387,60 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo restoreIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo); - if (pQuery->nAggTimeInterval == 0 && !isSumAvgRateQuery(pQuery)) { // normal query - if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { - qTrace( - "QInfo:%p vid:%d sid:%d id:%s, query completed, no need to scan this data block. qrange:%" PRId64 "-%" PRId64 ", " - "lastKey:%" PRId64, - pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, - pQuery->lastKey); + if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || + (pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) { + qTrace("QInfo:%p vid:%d sid:%d id:%s, query completed, no need to scan this data block. qrange:%" PRId64 + "-%" PRId64 ", lastKey:%" PRId64, + pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, + pQuery->lastKey); - continue; - } - - setExecutionContext(pSupporter, pSupporter->pResult, pOneMeterDataInfo->meterOrderIdx, - pOneMeterDataInfo->groupIdx, pMeterQueryInfo); - } else { // interval query - ret = setIntervalQueryExecutionContext(pSupporter, pOneMeterDataInfo->meterOrderIdx, pMeterQueryInfo); - if (ret != TSDB_CODE_SUCCESS) { - tfree(pReqMeterDataInfo); // error code has been set - pQInfo->killed = 1; - return; - } + continue; } SCompBlock *pBlock = pInfoEx->pBlock.compBlock; bool ondemandLoad = onDemandLoadDatablock(pQuery, pMeterQueryInfo->queryRangeSet); - int32_t ret = LoadDatablockOnDemand(pBlock, &pInfoEx->pBlock.fields, &pRuntimeEnv->blockStatus, pRuntimeEnv, - fileIdx, pInfoEx->blockIndex, searchFn, ondemandLoad); + ret = LoadDatablockOnDemand(pBlock, &pInfoEx->pBlock.fields, &pRuntimeEnv->blockStatus, pRuntimeEnv, fileIdx, + pInfoEx->blockIndex, searchFn, ondemandLoad); if (ret != DISK_DATA_LOADED) { pSummary->skippedFileBlocks++; continue; } SBlockInfo binfo = getBlockBasicInfo(pRuntimeEnv, pBlock, BLK_FILE_BLOCK); + int64_t nextKey = -1; assert(pQuery->pos >= 0 && pQuery->pos < pBlock->numOfPoints); TSKEY *primaryKeys = (TSKEY *)pRuntimeEnv->primaryColBuffer->data; if (IS_DATA_BLOCK_LOADED(pRuntimeEnv->blockStatus) && needPrimaryTimestampCol(pQuery, &binfo)) { - TSKEY nextKey = primaryKeys[pQuery->pos]; - if (!doCheckWithPrevQueryRange(pQInfo, nextKey, pOneMeterDataInfo)) { + nextKey = primaryKeys[pQuery->pos]; + + if (!doCheckWithPrevQueryRange(pQuery, nextKey)) { + qTrace("QInfo:%p vid:%d sid:%d id:%s, no data qualified in data file, lastKey:%" PRId64, pQInfo, + pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->numOfBlocks, pQuery->lastKey); continue; } } else { // if data block is not loaded, it must be the intermediate blocks assert((pBlock->keyFirst >= pQuery->lastKey && pBlock->keyLast <= pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || (pBlock->keyFirst >= pQuery->ekey && pBlock->keyLast <= pQuery->lastKey && !QUERY_IS_ASC_QUERY(pQuery))); + nextKey = QUERY_IS_ASC_QUERY(pQuery) ? pBlock->keyFirst : pBlock->keyLast; } - queryOnBlock(pSupporter, primaryKeys, pRuntimeEnv->blockStatus, &binfo, pOneMeterDataInfo, pInfoEx->pBlock.fields, - searchFn); + if (pQuery->intervalTime == 0) { + setExecutionContext(pSupporter, pMeterQueryInfo, pOneMeterDataInfo->meterOrderIdx, pOneMeterDataInfo->groupIdx, + nextKey); + } else { // interval query + setIntervalQueryRange(pMeterQueryInfo, pSupporter, nextKey); + ret = setAdditionalInfo(pSupporter, pOneMeterDataInfo->meterOrderIdx, pMeterQueryInfo); + if (ret != TSDB_CODE_SUCCESS) { + tfree(pReqMeterDataInfo); // error code has been set + pQInfo->killed = 1; + return; + } + } + + stableApplyFunctionsOnBlock(pSupporter, pOneMeterDataInfo, &binfo, pInfoEx->pBlock.fields, searchFn); } tfree(pReqMeterDataInfo); @@ -470,7 +463,7 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool *dataInCache, int32_t index, int32_t start) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SMeterSidExtInfo **pMeterSidExtInfo = pSupporter->pMeterSidExtInfo; SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; @@ -486,13 +479,13 @@ static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool * vnodeSetTagValueInParam(pSupporter->pSidSet, pRuntimeEnv, pMeterSidExtInfo[index]); - dTrace("QInfo:%p query on (%d): vid:%d sid:%d meterId:%s, qrange:%" PRId64 "-%" PRId64, pQInfo, index - start, pMeterObj->vnode, - pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey); + dTrace("QInfo:%p query on (%d): vid:%d sid:%d meterId:%s, qrange:%" PRId64 "-%" PRId64, pQInfo, index - start, + pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey); pQInfo->pObj = pMeterObj; pQuery->lastKey = pQuery->skey; pRuntimeEnv->pMeterObj = pMeterObj; - + vnodeUpdateQueryColumnIndex(pQuery, pRuntimeEnv->pMeterObj); vnodeUpdateFilterColumnIndex(pQuery); @@ -500,8 +493,8 @@ static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool * // data in file or cache is not qualified for the query. abort if (!(dataInCache || dataInDisk)) { - dTrace("QInfo:%p vid:%d sid:%d meterId:%s, qrange:%" PRId64 "-%" PRId64 ", nores, %p", pQInfo, pMeterObj->vnode, pMeterObj->sid, - pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery); + dTrace("QInfo:%p vid:%d sid:%d meterId:%s, qrange:%" PRId64 "-%" PRId64 ", nores, %p", pQInfo, pMeterObj->vnode, + pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery); return false; } @@ -525,7 +518,7 @@ static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool * static int64_t doCheckMetersInGroup(SQInfo *pQInfo, int32_t index, int32_t start) { SQuery * pQuery = &pQInfo->query; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; bool dataInDisk = true; @@ -556,7 +549,7 @@ static int64_t doCheckMetersInGroup(SQInfo *pQInfo, int32_t index, int32_t start pointInterpSupporterDestroy(&pointInterpSupporter); vnodeScanAllData(pRuntimeEnv); - + // first/last_row query, do not invoke the finalize for super table query doFinalizeResult(pRuntimeEnv); @@ -580,7 +573,7 @@ static int64_t doCheckMetersInGroup(SQInfo *pQInfo, int32_t index, int32_t start * @param pQInfo */ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SMeterSidExtInfo **pMeterSidExtInfo = pSupporter->pMeterSidExtInfo; SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; @@ -589,10 +582,10 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { tSidSet *pSids = pSupporter->pSidSet; int32_t vid = getMeterObj(pSupporter->pMetersHashTable, pMeterSidExtInfo[0]->sid)->vnode; - + if (isPointInterpoQuery(pQuery)) { resetCtxOutputBuf(pRuntimeEnv); - + assert(pQuery->limit.offset == 0 && pQuery->limit.limit != 0); while (pSupporter->subgroupIdx < pSids->numOfSubSet) { @@ -600,8 +593,8 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { int32_t end = pSids->starterPos[pSupporter->subgroupIdx + 1] - 1; if (isFirstLastRowQuery(pQuery)) { - dTrace("QInfo:%p last_row query on vid:%d, numOfGroups:%d, current group:%d", pQInfo, vid, - pSids->numOfSubSet, pSupporter->subgroupIdx); + dTrace("QInfo:%p last_row query on vid:%d, numOfGroups:%d, current group:%d", pQInfo, vid, pSids->numOfSubSet, + pSupporter->subgroupIdx); TSKEY key = -1; int32_t index = -1; @@ -633,8 +626,8 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { int64_t num = doCheckMetersInGroup(pQInfo, index, start); assert(num >= 0); } else { - dTrace("QInfo:%p interp query on vid:%d, numOfGroups:%d, current group:%d", pQInfo, vid, - pSids->numOfSubSet, pSupporter->subgroupIdx); + dTrace("QInfo:%p interp query on vid:%d, numOfGroups:%d, current group:%d", pQInfo, vid, pSids->numOfSubSet, + pSupporter->subgroupIdx); for (int32_t k = start; k <= end; ++k) { if (isQueryKilled(pQuery)) { @@ -670,7 +663,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { * we need to return it to client in the first place. */ if (pSupporter->subgroupIdx > 0) { - copyFromGroupBuf(pQInfo, pSupporter->pResult); + copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult); pQInfo->pointsRead += pQuery->pointsRead; if (pQuery->pointsRead > 0) { @@ -681,10 +674,10 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { if (pSupporter->meterIdx >= pSids->numOfSids) { return; } - + resetCtxOutputBuf(pRuntimeEnv); - resetSlidingWindowInfo(pRuntimeEnv, &pRuntimeEnv->swindowResInfo); - + resetTimeWindowInfo(pRuntimeEnv, &pRuntimeEnv->windowResInfo); + while (pSupporter->meterIdx < pSupporter->numOfMeters) { int32_t k = pSupporter->meterIdx; @@ -692,9 +685,8 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { setQueryStatus(pQuery, QUERY_NO_DATA_TO_CHECK); return; } - - TSKEY skey = pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[k]->key; + TSKEY skey = pQInfo->pTableQuerySupporter->pMeterSidExtInfo[k]->key; if (skey > 0) { pQuery->skey = skey; } @@ -747,10 +739,10 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { pSupporter->meterIdx = pSupporter->pSidSet->numOfSids; break; } - + // enable execution for next table, when handling the projection query enableExecutionForNextTable(pRuntimeEnv); - + if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK | QUERY_COMPLETED)) { /* * query range is identical in terms of all meters involved in query, @@ -762,7 +754,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { pQuery->ekey = pSupporter->rawEKey; pSupporter->meterIdx++; - pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey; + pQInfo->pTableQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey; // if the buffer is full or group by each table, we need to jump out of the loop if (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL) || @@ -770,7 +762,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { break; } - } else { // forward query range + } else { // forward query range pQuery->skey = pQuery->lastKey; // all data in the result buffer are skipped due to the offset, continue to retrieve data from current meter @@ -778,7 +770,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { assert(!Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)); continue; } else { - pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey; + pQInfo->pTableQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey; // buffer is full, wait for the next round to retrieve data from current meter assert(Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)); break; @@ -808,20 +800,21 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { // todo refactor if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) { - SSlidingWindowInfo* pSlidingWindowInfo = &pRuntimeEnv->swindowResInfo; - - for (int32_t i = 0; i < pSlidingWindowInfo->size; ++i) { - SOutputRes *buf = &pSlidingWindowInfo->pResult[i]; - pSlidingWindowInfo->pStatus[i].closed = true; // enable return all results for group by normal columns - + SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; + + for (int32_t i = 0; i < pWindowResInfo->size; ++i) { + SWindowStatus *pStatus = &pWindowResInfo->pResult[i].status; + pStatus->closed = true; // enable return all results for group by normal columns + + SWindowResult *pResult = &pWindowResInfo->pResult[i]; for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) { - buf->numOfRows = MAX(buf->numOfRows, buf->resultInfo[j].numOfRes); + pResult->numOfRows = MAX(pResult->numOfRows, pResult->resultInfo[j].numOfRes); } } - pQInfo->pMeterQuerySupporter->subgroupIdx = 0; + pQInfo->pTableQuerySupporter->subgroupIdx = 0; pQuery->pointsRead = 0; - copyFromGroupBuf(pQInfo, pSlidingWindowInfo->pResult); + copyFromWindowResToSData(pQInfo, pWindowResInfo->pResult); } pQInfo->pointsRead += pQuery->pointsRead; @@ -830,12 +823,12 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) { dTrace( "QInfo %p vid:%d, numOfMeters:%d, index:%d, numOfGroups:%d, %d points returned, totalRead:%d totalReturn:%d," "next skey:%" PRId64 ", offset:%" PRId64, - pQInfo, vid, pSids->numOfSids, pSupporter->meterIdx, pSids->numOfSubSet, pQuery->pointsRead, - pQInfo->pointsRead, pQInfo->pointsReturned, pQuery->skey, pQuery->limit.offset); + pQInfo, vid, pSids->numOfSids, pSupporter->meterIdx, pSids->numOfSubSet, pQuery->pointsRead, pQInfo->pointsRead, + pQInfo->pointsReturned, pQuery->skey, pQuery->limit.offset); } static void doOrderedScan(SQInfo *pQInfo) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SQuery * pQuery = &pQInfo->query; if (QUERY_IS_ASC_QUERY(pQuery)) { @@ -855,17 +848,17 @@ static void doOrderedScan(SQInfo *pQInfo) { } } -static void setupMeterQueryInfoForSupplementQuery(SMeterQuerySupportObj *pSupporter) { +static void setupMeterQueryInfoForSupplementQuery(STableQuerySupportObj *pSupporter) { + SQuery *pQuery = pSupporter->runtimeEnv.pQuery; + for (int32_t i = 0; i < pSupporter->numOfMeters; ++i) { SMeterQueryInfo *pMeterQueryInfo = pSupporter->pMeterDataInfo[i].pMeterQInfo; - SQueryResultBuf* pResultBuf = pSupporter->runtimeEnv.pResultBuf; - - changeMeterQueryInfoForSuppleQuery(pResultBuf, pMeterQueryInfo, pSupporter->rawSKey, pSupporter->rawEKey); + changeMeterQueryInfoForSuppleQuery(pQuery, pMeterQueryInfo, pSupporter->rawSKey, pSupporter->rawEKey); } } static void doMultiMeterSupplementaryScan(SQInfo *pQInfo) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = &pQInfo->query; @@ -876,17 +869,19 @@ static void doMultiMeterSupplementaryScan(SQInfo *pQInfo) { } SET_SUPPLEMENT_SCAN_FLAG(pRuntimeEnv); - disableFunctForSuppleScan(pRuntimeEnv, pQuery->order.order); + disableFunctForSuppleScan(pSupporter, pQuery->order.order); if (pRuntimeEnv->pTSBuf != NULL) { - pRuntimeEnv->pTSBuf->cur.order = pRuntimeEnv->pTSBuf->cur.order ^ 1; + pRuntimeEnv->pTSBuf->cur.order = pRuntimeEnv->pTSBuf->cur.order ^ 1u; } SWAP(pSupporter->rawSKey, pSupporter->rawEKey, TSKEY); setupMeterQueryInfoForSupplementQuery(pSupporter); int64_t st = taosGetTimestampMs(); + doOrderedScan(pQInfo); + int64_t et = taosGetTimestampMs(); dTrace("QInfo:%p supplementary scan completed, elapsed time: %lldms", pQInfo, et - st); @@ -905,7 +900,8 @@ static void doMultiMeterSupplementaryScan(SQInfo *pQInfo) { } static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) { - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; + SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; SQuery * pQuery = &pQInfo->query; if (pSupporter->subgroupIdx > 0) { @@ -913,14 +909,14 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) { * if the subgroupIdx > 0, the query process must be completed yet, we only need to * copy the data into output buffer */ - if (pQuery->nAggTimeInterval > 0) { + if (pQuery->intervalTime > 0) { copyResToQueryResultBuf(pSupporter, pQuery); #ifdef _DEBUG_VIEW displayInterResult(pQuery->sdata, pQuery, pQuery->sdata[0]->len); #endif } else { - copyFromGroupBuf(pQInfo, pSupporter->pResult); + copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult); } pQInfo->pointsRead += pQuery->pointsRead; @@ -941,22 +937,25 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) { return; } - dTrace("QInfo:%p query start, qrange:%" PRId64 "-%" PRId64 ", order:%d, group:%d", pQInfo, pSupporter->rawSKey, pSupporter->rawEKey, - pQuery->order.order, pSupporter->pSidSet->numOfSubSet); + dTrace("QInfo:%p query start, qrange:%" PRId64 "-%" PRId64 ", order:%d, group:%d", pQInfo, pSupporter->rawSKey, + pSupporter->rawEKey, pQuery->order.order, pSupporter->pSidSet->numOfSubSet); dTrace("QInfo:%p main query scan start", pQInfo); int64_t st = taosGetTimestampMs(); doOrderedScan(pQInfo); int64_t et = taosGetTimestampMs(); dTrace("QInfo:%p main scan completed, elapsed time: %lldms, supplementary scan start, order:%d", pQInfo, et - st, - pQuery->order.order ^ 1); + pQuery->order.order ^ 1u); - // failed to save all intermediate results into disk, abort further query processing - if (doCloseAllOpenedResults(pSupporter) != TSDB_CODE_SUCCESS) { - dError("QInfo:%p failed to save intermediate results, abort further query processing", pQInfo); - return; + if (pQuery->intervalTime > 0) { + for (int32_t i = 0; i < pSupporter->numOfMeters; ++i) { + SMeterQueryInfo *pMeterQueryInfo = pSupporter->pMeterDataInfo[i].pMeterQInfo; + closeAllTimeWindow(&pMeterQueryInfo->windowResInfo); + } + } else { // close results for group result + closeAllTimeWindow(&pRuntimeEnv->windowResInfo); } - + doMultiMeterSupplementaryScan(pQInfo); if (isQueryKilled(pQuery)) { @@ -964,18 +963,18 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) { return; } - if (pQuery->nAggTimeInterval > 0 || isSumAvgRateQuery(pQuery)) { + if (pQuery->intervalTime > 0 || isSumAvgRateQuery(pQuery)) { assert(pSupporter->subgroupIdx == 0 && pSupporter->numOfGroupResultPages == 0); if (mergeMetersResultToOneGroups(pSupporter) == TSDB_CODE_SUCCESS) { copyResToQueryResultBuf(pSupporter, pQuery); - + #ifdef _DEBUG_VIEW displayInterResult(pQuery->sdata, pQuery, pQuery->sdata[0]->len); #endif } } else { // not a interval query - copyFromGroupBuf(pQInfo, pSupporter->pResult); + copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult); } // handle the limitation of output buffer @@ -992,7 +991,7 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) { */ static void vnodeSingleTableFixedOutputProcessor(SQInfo *pQInfo) { SQuery * pQuery = &pQInfo->query; - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv; + SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pTableQuerySupporter->runtimeEnv; assert(pQuery->slot >= 0 && pQuery->pos >= 0); @@ -1023,7 +1022,7 @@ static void vnodeSingleTableMultiOutputProcessor(SQInfo *pQInfo) { SQuery * pQuery = &pQInfo->query; SMeterObj *pMeterObj = pQInfo->pObj; - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv; + SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pTableQuerySupporter->runtimeEnv; // for ts_comp query, re-initialized is not allowed if (!isTSCompQuery(pQuery)) { @@ -1054,8 +1053,9 @@ static void vnodeSingleTableMultiOutputProcessor(SQInfo *pQInfo) { TSKEY nextTimestamp = loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->nextPos); assert(nextTimestamp > 0 || ((nextTimestamp < 0) && Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK))); - dTrace("QInfo:%p vid:%d sid:%d id:%s, skip current result, offset:%" PRId64 ", next qrange:%" PRId64 "-%" PRId64, pQInfo, - pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->limit.offset, pQuery->lastKey, pQuery->ekey); + dTrace("QInfo:%p vid:%d sid:%d id:%s, skip current result, offset:%" PRId64 ", next qrange:%" PRId64 "-%" PRId64, + pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->limit.offset, pQuery->lastKey, + pQuery->ekey); resetCtxOutputBuf(pRuntimeEnv); } @@ -1067,8 +1067,8 @@ static void vnodeSingleTableMultiOutputProcessor(SQInfo *pQInfo) { TSKEY nextTimestamp = loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->nextPos); assert(nextTimestamp > 0 || ((nextTimestamp < 0) && Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK))); - dTrace("QInfo:%p vid:%d sid:%d id:%s, query abort due to buffer limitation, next qrange:%" PRId64 "-%" PRId64, pQInfo, - pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->lastKey, pQuery->ekey); + dTrace("QInfo:%p vid:%d sid:%d id:%s, query abort due to buffer limitation, next qrange:%" PRId64 "-%" PRId64, + pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->lastKey, pQuery->ekey); } dTrace("QInfo:%p vid:%d sid:%d id:%s, %d points returned, totalRead:%d totalReturn:%d", pQInfo, pMeterObj->vnode, @@ -1080,58 +1080,39 @@ static void vnodeSingleTableMultiOutputProcessor(SQInfo *pQInfo) { } } -static void vnodeSingleMeterIntervalMainLooper(SMeterQuerySupportObj *pSupporter, SQueryRuntimeEnv *pRuntimeEnv) { +static void vnodeSingleMeterIntervalMainLooper(STableQuerySupportObj *pSupporter, SQueryRuntimeEnv *pRuntimeEnv) { SQuery *pQuery = pRuntimeEnv->pQuery; while (1) { - assert((pQuery->skey <= pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (pQuery->skey >= pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))); - initCtxOutputBuf(pRuntimeEnv); - clearCompletedSlidingWindows(pRuntimeEnv); - vnodeScanAllData(pRuntimeEnv); + if (isQueryKilled(pQuery)) { return; } assert(!Q_STATUS_EQUAL(pQuery->over, QUERY_NOT_COMPLETED)); - - // clear tag, used to decide if the whole interval query is completed or not - pQuery->over &= (~QUERY_COMPLETED); doFinalizeResult(pRuntimeEnv); - int64_t maxOutput = getNumOfResult(pRuntimeEnv); - // here we can ignore the records in case of no interpolation + // todo handle offset, in case of top/bottom interval query if ((pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTSBuf != NULL) && pQuery->limit.offset > 0 && - pQuery->interpoType == TSDB_INTERPO_NONE) { // maxOutput <= 0, means current query does not generate any results - // todo handle offset, in case of top/bottom interval query - if (maxOutput > 0) { - pQuery->limit.offset--; - } - } else { - pQuery->pointsRead += maxOutput; - forwardCtxOutputBuf(pRuntimeEnv, maxOutput); - } + pQuery->interpoType == TSDB_INTERPO_NONE) { + // maxOutput <= 0, means current query does not generate any results + int32_t numOfClosed = numOfClosedTimeWindow(&pRuntimeEnv->windowResInfo); - if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)) { - break; + int32_t c = MIN(numOfClosed, pQuery->limit.offset); + clearFirstNTimeWindow(pRuntimeEnv, c); + pQuery->limit.offset -= c; } - forwardIntervalQueryRange(pSupporter, pRuntimeEnv); - if (Q_STATUS_EQUAL(pQuery->over, QUERY_COMPLETED|QUERY_RESBUF_FULL)) { + if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK | QUERY_COMPLETED)) { break; } - /* - * the scan limitation mechanism is upon here, - * 1. since there is only one(k) record is generated in one scan operation - * 2. remain space is not sufficient for next query output, abort - */ - if ((pQuery->pointsRead % pQuery->pointsToRead == 0 && pQuery->pointsRead != 0) || - ((pQuery->pointsRead + maxOutput) > pQuery->pointsToRead)) { - setQueryStatus(pQuery, QUERY_RESBUF_FULL); + // load the data block for the next retrieve + loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->nextPos); + if (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)) { break; } } @@ -1142,7 +1123,7 @@ static void vnodeSingleTableIntervalProcessor(SQInfo *pQInfo) { SQuery * pQuery = &(pQInfo->query); SMeterObj *pMeterObj = pQInfo->pObj; - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; int32_t numOfInterpo = 0; @@ -1151,6 +1132,14 @@ static void vnodeSingleTableIntervalProcessor(SQInfo *pQInfo) { resetCtxOutputBuf(pRuntimeEnv); vnodeSingleMeterIntervalMainLooper(pSupporter, pRuntimeEnv); + if (pQuery->intervalTime > 0) { + pSupporter->subgroupIdx = 0; // always start from 0 + pQuery->pointsRead = 0; + copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult); + + clearFirstNTimeWindow(pRuntimeEnv, pSupporter->subgroupIdx); + } + // the offset is handled at prepare stage if no interpolation involved if (pQuery->interpoType == TSDB_INTERPO_NONE) { doRevisedResultsByLimit(pQInfo); @@ -1177,11 +1166,13 @@ static void vnodeSingleTableIntervalProcessor(SQInfo *pQInfo) { pQuery->pointsRead = 0; } } - - if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (pQuery->slidingTime > 0 && pQuery->nAggTimeInterval > 0)) { - pQInfo->pMeterQuerySupporter->subgroupIdx = 0; + + // all data scanned, the group by normal column can return + if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) {//todo refactor with merge interval time result + pSupporter->subgroupIdx = 0; pQuery->pointsRead = 0; - copyFromGroupBuf(pQInfo, pRuntimeEnv->swindowResInfo.pResult); + copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult); + clearFirstNTimeWindow(pRuntimeEnv, pSupporter->subgroupIdx); } pQInfo->pointsRead += pQuery->pointsRead; @@ -1195,7 +1186,7 @@ static void vnodeSingleTableIntervalProcessor(SQInfo *pQInfo) { void vnodeSingleTableQuery(SSchedMsg *pMsg) { SQInfo *pQInfo = (SQInfo *)pMsg->ahandle; - if (pQInfo == NULL || pQInfo->pMeterQuerySupporter == NULL) { + if (pQInfo == NULL || pQInfo->pTableQuerySupporter == NULL) { dTrace("%p freed abort query", pQInfo); return; } @@ -1203,21 +1194,22 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) { if (pQInfo->killed) { dTrace("QInfo:%p it is already killed, abort", pQInfo); vnodeDecRefCount(pQInfo); - + return; } assert(pQInfo->refCount >= 1); - SQuery * pQuery = &pQInfo->query; - SMeterObj *pMeterObj = pQInfo->pObj; + SQuery * pQuery = &pQInfo->query; + SMeterObj * pMeterObj = pQInfo->pObj; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; + SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv; + + assert(pRuntimeEnv->pMeterObj == pMeterObj); dTrace("vid:%d sid:%d id:%s, query thread is created, numOfQueries:%d, QInfo:%p", pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pMeterObj->numOfQueries, pQInfo); - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv; - assert(pRuntimeEnv->pMeterObj == pMeterObj); - if (vnodeHasRemainResults(pQInfo)) { /* * There are remain results that are not returned due to result interpolation @@ -1249,12 +1241,18 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) { // here we have scan all qualified data in both data file and cache if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK | QUERY_COMPLETED)) { // continue to get push data from the group result - if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) { + if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || + (pQuery->intervalTime > 0 && pQInfo->pointsReturned < pQuery->limit.limit)) { + //todo limit the output for interval query? pQuery->pointsRead = 0; - if (pQInfo->pMeterQuerySupporter->subgroupIdx > 0) { - copyFromGroupBuf(pQInfo, pQInfo->pMeterQuerySupporter->pResult); + pSupporter->subgroupIdx = 0; // always start from 0 + + if (pRuntimeEnv->windowResInfo.size > 0) { + copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult); pQInfo->pointsRead += pQuery->pointsRead; + clearFirstNTimeWindow(pRuntimeEnv, pSupporter->subgroupIdx); + if (pQuery->pointsRead > 0) { dTrace("QInfo:%p vid:%d sid:%d id:%s, %d points returned %d from group results, totalRead:%d totalReturn:%d", pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->pointsRead, pQInfo->pointsRead, @@ -1262,19 +1260,19 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) { sem_post(&pQInfo->dataReady); vnodeDecRefCount(pQInfo); - + return; } } } pQInfo->over = 1; - dTrace("QInfo:%p vid:%d sid:%d id:%s, query over, %d points are returned", pQInfo, - pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQInfo->pointsRead); + dTrace("QInfo:%p vid:%d sid:%d id:%s, query over, %d points are returned", pQInfo, pMeterObj->vnode, pMeterObj->sid, + pMeterObj->meterId, pQInfo->pointsRead); - vnodePrintQueryStatistics(pQInfo->pMeterQuerySupporter); + vnodePrintQueryStatistics(pSupporter); sem_post(&pQInfo->dataReady); - + vnodeDecRefCount(pQInfo); return; } @@ -1286,7 +1284,7 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) { int64_t st = taosGetTimestampUs(); // group by normal column, sliding window query, interval query are handled by interval query processor - if (pQuery->nAggTimeInterval != 0 || isGroupbyNormalCol(pQuery->pGroupbyExpr)) { // interval (down sampling operation) + if (pQuery->intervalTime != 0 || isGroupbyNormalCol(pQuery->pGroupbyExpr)) { // interval (down sampling operation) assert(pQuery->checkBufferInLoop == 0 && pQuery->pointsOffset == pQuery->pointsToRead); vnodeSingleTableIntervalProcessor(pQInfo); } else { @@ -1307,8 +1305,8 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) { dTrace("QInfo:%p query is killed", pQInfo); pQInfo->over = 1; } else { - dTrace("QInfo:%p vid:%d sid:%d id:%s, meter query thread completed, %d points are returned", - pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->pointsRead); + dTrace("QInfo:%p vid:%d sid:%d id:%s, meter query thread completed, %d points are returned", pQInfo, + pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->pointsRead); } sem_post(&pQInfo->dataReady); @@ -1318,7 +1316,7 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) { void vnodeMultiMeterQuery(SSchedMsg *pMsg) { SQInfo *pQInfo = (SQInfo *)pMsg->ahandle; - if (pQInfo == NULL || pQInfo->pMeterQuerySupporter == NULL) { + if (pQInfo == NULL || pQInfo->pTableQuerySupporter == NULL) { return; } @@ -1334,12 +1332,12 @@ void vnodeMultiMeterQuery(SSchedMsg *pMsg) { pQuery->pointsRead = 0; int64_t st = taosGetTimestampUs(); - if (pQuery->nAggTimeInterval > 0 || + if (pQuery->intervalTime > 0 || (isFixedOutputQuery(pQuery) && (!isPointInterpoQuery(pQuery)) && !isGroupbyNormalCol(pQuery->pGroupbyExpr))) { assert(pQuery->checkBufferInLoop == 0); vnodeMultiMeterQueryProcessor(pQInfo); } else { - assert((pQuery->checkBufferInLoop == 1 && pQuery->nAggTimeInterval == 0) || isPointInterpoQuery(pQuery) || + assert((pQuery->checkBufferInLoop == 1 && pQuery->intervalTime == 0) || isPointInterpoQuery(pQuery) || isGroupbyNormalCol(pQuery->pGroupbyExpr)); vnodeSTableSeqProcessor(pQInfo); @@ -1349,10 +1347,10 @@ void vnodeMultiMeterQuery(SSchedMsg *pMsg) { pQInfo->useconds += (taosGetTimestampUs() - st); pQInfo->over = isQueryKilled(pQuery) ? 1 : 0; - taosInterpoSetStartInfo(&pQInfo->pMeterQuerySupporter->runtimeEnv.interpoInfo, pQuery->pointsRead, + taosInterpoSetStartInfo(&pQInfo->pTableQuerySupporter->runtimeEnv.interpoInfo, pQuery->pointsRead, pQInfo->query.interpoType); - SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter; + STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter; if (pQuery->pointsRead == 0) { pQInfo->over = 1; diff --git a/src/vnode/detail/src/vnodeRead.c b/src/vnode/detail/src/vnodeRead.c index e4a8b898ec3266c0a89b24357a4eec08632644a1..fb7c85e61c61272159202a2bda4ef7f30fdd93d0 100644 --- a/src/vnode/detail/src/vnodeRead.c +++ b/src/vnode/detail/src/vnodeRead.c @@ -266,7 +266,7 @@ static SQInfo *vnodeAllocateQInfoEx(SQueryMeterMsg *pQueryMsg, SSqlGroupbyExpr * } pQuery->pGroupbyExpr = pGroupbyExpr; - pQuery->nAggTimeInterval = pQueryMsg->nAggTimeInterval; + pQuery->intervalTime = pQueryMsg->intervalTime; pQuery->slidingTime = pQueryMsg->slidingTime; pQuery->interpoType = pQueryMsg->interpoType; pQuery->intervalTimeUnit = pQueryMsg->intervalTimeUnit; @@ -648,7 +648,7 @@ void *vnodeQueryOnSingleTable(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE goto _error; } - SMeterQuerySupportObj *pSupporter = (SMeterQuerySupportObj *)calloc(1, sizeof(SMeterQuerySupportObj)); + STableQuerySupportObj *pSupporter = (STableQuerySupportObj *)calloc(1, sizeof(STableQuerySupportObj)); pSupporter->numOfMeters = 1; pSupporter->pMetersHashTable = taosInitHashTable(pSupporter->numOfMeters, taosIntHash_32, false); @@ -659,7 +659,7 @@ void *vnodeQueryOnSingleTable(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE pSupporter->subgroupIdx = -1; pSupporter->pMeterSidExtInfo = NULL; - pQInfo->pMeterQuerySupporter = pSupporter; + pQInfo->pTableQuerySupporter = pSupporter; STSBuf *pTSBuf = NULL; if (pQueryMsg->tsLen > 0) { @@ -670,7 +670,7 @@ void *vnodeQueryOnSingleTable(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE tsBufNextPos(pTSBuf); } - if (((*code) = vnodeQuerySingleMeterPrepare(pQInfo, pQInfo->pObj, pSupporter, pTSBuf)) != TSDB_CODE_SUCCESS) { + if (((*code) = vnodeQueryTablePrepare(pQInfo, pQInfo->pObj, pSupporter, pTSBuf)) != TSDB_CODE_SUCCESS) { goto _error; } @@ -739,7 +739,7 @@ void *vnodeQueryOnMultiMeters(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE SSchedMsg schedMsg = {0}; - SMeterQuerySupportObj *pSupporter = (SMeterQuerySupportObj *)calloc(1, sizeof(SMeterQuerySupportObj)); + STableQuerySupportObj *pSupporter = (STableQuerySupportObj *)calloc(1, sizeof(STableQuerySupportObj)); pSupporter->numOfMeters = pQueryMsg->numOfSids; pSupporter->pMetersHashTable = taosInitHashTable(pSupporter->numOfMeters, taosIntHash_32, false); @@ -784,7 +784,7 @@ void *vnodeQueryOnMultiMeters(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE (SSchema *)pQueryMsg->pTagSchema, pQueryMsg->numOfTagsCols, NULL, 0); } - pQInfo->pMeterQuerySupporter = pSupporter; + pQInfo->pTableQuerySupporter = pSupporter; STSBuf *pTSBuf = NULL; if (pQueryMsg->tsLen > 0) { @@ -794,7 +794,7 @@ void *vnodeQueryOnMultiMeters(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE tsBufResetPos(pTSBuf); } - if (((*code) = vnodeMultiMeterQueryPrepare(pQInfo, pQuery, pTSBuf)) != TSDB_CODE_SUCCESS) { + if (((*code) = vnodeSTableQueryPrepare(pQInfo, pQuery, pTSBuf)) != TSDB_CODE_SUCCESS) { goto _error; } @@ -898,8 +898,8 @@ int vnodeSaveQueryResult(void *handle, char *data, int32_t *size) { SSchedMsg schedMsg = {0}; - if (pQInfo->pMeterQuerySupporter != NULL) { - if (pQInfo->pMeterQuerySupporter->pSidSet == NULL) { + if (pQInfo->pTableQuerySupporter != NULL) { + if (pQInfo->pTableQuerySupporter->pSidSet == NULL) { schedMsg.fp = vnodeSingleTableQuery; } else { // group by tag schedMsg.fp = vnodeMultiMeterQuery; @@ -920,8 +920,8 @@ int vnodeSaveQueryResult(void *handle, char *data, int32_t *size) { } static int32_t validateQueryMeterMsg(SQueryMeterMsg *pQueryMsg) { - if (pQueryMsg->nAggTimeInterval < 0) { - dError("qmsg:%p illegal value of aggTimeInterval %" PRId64 "", pQueryMsg, pQueryMsg->nAggTimeInterval); + if (pQueryMsg->intervalTime < 0) { + dError("qmsg:%p illegal value of aggTimeInterval %" PRId64 "", pQueryMsg, pQueryMsg->intervalTime); return -1; } @@ -975,7 +975,7 @@ int32_t vnodeConvertQueryMeterMsg(SQueryMeterMsg *pQueryMsg) { pQueryMsg->queryType = htons(pQueryMsg->queryType); - pQueryMsg->nAggTimeInterval = htobe64(pQueryMsg->nAggTimeInterval); + pQueryMsg->intervalTime = htobe64(pQueryMsg->intervalTime); pQueryMsg->slidingTime = htobe64(pQueryMsg->slidingTime); pQueryMsg->numOfTagsCols = htons(pQueryMsg->numOfTagsCols); @@ -1146,7 +1146,7 @@ int32_t vnodeConvertQueryMeterMsg(SQueryMeterMsg *pQueryMsg) { "offset:%" PRId64, pQueryMsg, pQueryMsg->numOfSids, pQueryMsg->skey, pQueryMsg->ekey, pQueryMsg->numOfGroupCols, pQueryMsg->numOfTagsCols, pQueryMsg->order, pQueryMsg->orderType, pQueryMsg->orderByIdx, - pQueryMsg->numOfOutputCols, pQueryMsg->numOfCols, pQueryMsg->nAggTimeInterval, pQueryMsg->interpoType, + pQueryMsg->numOfOutputCols, pQueryMsg->numOfCols, pQueryMsg->intervalTime, pQueryMsg->interpoType, pQueryMsg->tsLen, pQueryMsg->limit, pQueryMsg->offset); return 0; diff --git a/src/vnode/detail/src/vnodeUtil.c b/src/vnode/detail/src/vnodeUtil.c index 17a94e5b9a392a250cf126c411d471fa5d010370..feef9ed47324c8c32b64f7c5fb156e5a7c52bf21 100644 --- a/src/vnode/detail/src/vnodeUtil.c +++ b/src/vnode/detail/src/vnodeUtil.c @@ -372,18 +372,22 @@ void vnodeUpdateFilterColumnIndex(SQuery* pQuery) { } // set the column index in buffer for arithmetic operation - if (pQuery->pSelectExpr != NULL) { - for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { - SSqlBinaryExprInfo* pBinExprInfo = &pQuery->pSelectExpr[i].pBinExprInfo; - if (pBinExprInfo->pBinExpr != NULL) { - for (int16_t j = 0; j < pBinExprInfo->numOfCols; ++j) { - for (int32_t k = 0; k < pQuery->numOfCols; ++k) { - if (pBinExprInfo->pReqColumns[j].colId == pQuery->colList[k].data.colId) { - pBinExprInfo->pReqColumns[j].colIdxInBuf = pQuery->colList[k].colIdxInBuf; - assert(pQuery->colList[k].colIdxInBuf == k); - break; - } - } + if (pQuery->pSelectExpr == NULL) { + return; + } + + for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { + SSqlBinaryExprInfo* pBinExprInfo = &pQuery->pSelectExpr[i].pBinExprInfo; + if (pBinExprInfo->pBinExpr == NULL) { + continue; + } + + for (int16_t j = 0; j < pBinExprInfo->numOfCols; ++j) { + for (int32_t k = 0; k < pQuery->numOfCols; ++k) { + if (pBinExprInfo->pReqColumns[j].colId == pQuery->colList[k].data.colId) { + pBinExprInfo->pReqColumns[j].colIdxInBuf = pQuery->colList[k].colIdxInBuf; + assert(pQuery->colList[k].colIdxInBuf == k); + break; } } }