TD-13747 New SQL model integration

This commit is contained in:
Xiaoyu Wang 2022-02-28 04:02:43 -05:00
parent 42d91c3dbb
commit 768e05939c
60 changed files with 826 additions and 14800 deletions

View File

@ -23,6 +23,7 @@ extern "C" {
#include "os.h"
#include "thash.h"
#include "executor.h"
#include "plannodes.h"
#define DS_BUF_LOW 1
#define DS_BUF_FULL 2
@ -59,7 +60,7 @@ typedef struct SOutputData {
* @param pHandle output
* @return error code
*/
int32_t dsCreateDataSinker(const struct SDataSink *pDataSink, DataSinkHandle* pHandle);
int32_t dsCreateDataSinker(const SDataSinkNode* pDataSink, DataSinkHandle* pHandle);
/**
* Put the result set returned by the executor into datasinker.

View File

@ -70,6 +70,7 @@ typedef enum ENodeType {
QUERY_NODE_SET_OPERATOR,
QUERY_NODE_SELECT_STMT,
QUERY_NODE_SHOW_STMT,
QUERY_NODE_VNODE_MODIF_STMT,
// logic plan node
QUERY_NODE_LOGIC_PLAN_SCAN,
@ -80,9 +81,15 @@ typedef enum ENodeType {
// physical plan node
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN,
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN,
QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN,
QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN,
QUERY_NODE_PHYSICAL_PLAN_PROJECT,
QUERY_NODE_PHYSICAL_PLAN_JOIN,
QUERY_NODE_PHYSICAL_PLAN_AGG
QUERY_NODE_PHYSICAL_PLAN_AGG,
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE,
QUERY_NODE_PHYSICAL_PLAN_SORT,
QUERY_NODE_DSINK_DISPATCH
} ENodeType;
/**

View File

@ -21,6 +21,7 @@ extern "C" {
#endif
#include "querynodes.h"
#include "query.h"
#include "tmsg.h"
typedef struct SLogicNode {
@ -78,6 +79,8 @@ typedef struct SDataBlockDescNode {
ENodeType type;
int16_t dataBlockId;
SNodeList* pSlots;
int32_t resultRowSize;
int16_t precision;
} SDataBlockDescNode;
typedef struct SPhysiNode {
@ -129,6 +132,34 @@ typedef struct SAggPhysiNode {
SNodeList* pAggFuncs;
} SAggPhysiNode;
typedef struct SDownstreamSource {
SQueryNodeAddr addr;
uint64_t taskId;
uint64_t schedId;
} SDownstreamSource;
typedef struct SExchangePhysiNode {
SPhysiNode node;
uint64_t srcTemplateId; // template id of datasource suplans
SArray* pSrcEndPoints; // SArray<SDownstreamSource>, scheduler fill by calling qSetSuplanExecutionNode
} SExchangePhysiNode;
typedef struct SDataSinkNode {
ENodeType type;;
SDataBlockDescNode inputDataBlockDesc;
} SDataSinkNode;
typedef struct SDataDispatcherNode {
SDataSinkNode sink;
} SDataDispatcherNode;
typedef struct SDataInserterNode {
SDataSinkNode sink;
int32_t numOfTables;
uint32_t size;
char *pData;
} SDataInserterNode;
#ifdef __cplusplus
}
#endif

View File

@ -21,6 +21,7 @@ extern "C" {
#endif
#include "nodes.h"
#include "tmsg.h"
typedef struct SRawExprNode {
ENodeType nodeType;
@ -248,6 +249,28 @@ typedef enum ESqlClause {
SQL_CLAUSE_ORDER_BY
} ESqlClause;
typedef enum {
PAYLOAD_TYPE_KV = 0,
PAYLOAD_TYPE_RAW = 1,
} EPayloadType;
typedef struct SVgDataBlocks {
SVgroupInfo vg;
int32_t numOfTables; // number of tables in current submit block
uint32_t size;
char *pData; // SMsgDesc + SSubmitReq + SSubmitBlk + ...
} SVgDataBlocks;
typedef struct SVnodeModifOpStmt {
ENodeType nodeType;
SArray* pDataBlocks; // data block for each vgroup, SArray<SVgDataBlocks*>.
int8_t schemaAttache; // denote if submit block is built with table schema or not
uint8_t payloadType; // EPayloadType. 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert
uint32_t insertType; // insert data from [file|sql statement| bound statement]
const char* sql; // current sql statement position
} SVnodeModifOpStmt;
void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext);
void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewriter rewriter, void* pContext);

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_NEW_PARSER_H_
#define _TD_NEW_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "parser.h"
typedef enum EStmtType {
STMT_TYPE_CMD = 1,
STMT_TYPE_QUERY
} EStmtType;
typedef struct SQuery {
EStmtType stmtType;
SNode* pRoot;
int32_t numOfResCols;
SSchema* pResSchema;
} SQuery;
int32_t parser(SParseContext* pParseCxt, SQuery* pQuery);
#ifdef __cplusplus
}
#endif
#endif /*_TD_NEW_PARSER_H_*/

View File

@ -1,163 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_PARSENODES_H_
#define _TD_PARSENODES_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "catalog.h"
#include "common.h"
#include "function.h"
#include "tmsgtype.h"
#include "tname.h"
#include "tvariant.h"
/**
* The first field of a node of any type is guaranteed to be the int16_t.
* Hence the type of any node can be gotten by casting it to SQueryNode.
*/
typedef struct SQueryNode {
int16_t type;
} SQueryNode;
#define queryNodeType(nodeptr) (((const SQueryNode*)(nodeptr))->type)
typedef struct SFieldInfo {
int16_t numOfOutput; // number of column in result
SField *final;
SArray *internalField; // SArray<SInternalField>
} SFieldInfo;
typedef struct SCond {
uint64_t uid;
int32_t len; // length of tag query condition data
char * cond;
} SCond;
typedef struct SJoinNode {
uint64_t uid;
int16_t tagColId;
SArray* tsJoin;
SArray* tagJoin;
} SJoinNode;
typedef struct SJoinInfo {
bool hasJoin;
SJoinNode *joinTables[TSDB_MAX_JOIN_TABLE_NUM];
} SJoinInfo;
typedef struct STagCond {
int16_t relType; // relation between tbname list and query condition, including : TK_AND or TK_OR
SCond tbnameCond; // tbname query condition, only support tbname query condition on one table
SJoinInfo joinInfo; // join condition, only support two tables join currently
SArray *pCond; // for different table, the query condition must be seperated
} STagCond;
typedef struct STableMetaInfo {
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
SVgroupsInfo *vgroupList;
SName name;
char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
SArray *tagColList; // SArray<SColumn*>, involved tag columns
} STableMetaInfo;
typedef struct SColumnIndex {
int16_t tableIndex;
int16_t columnIndex;
int16_t type; // normal column/tag/ user input constant column
} SColumnIndex;
// select statement
typedef struct SQueryStmtInfo {
int16_t command; // the command may be different for each subclause, so keep it seperately.
uint32_t type; // query/insert type
STimeWindow window; // the whole query time window
SInterval interval; // tumble time window
SSessionWindow sessionWindow; // session time window
SStateWindow stateWindow; // state window query
SGroupbyExpr groupbyExpr; // groupby tags info
SArray * colList; // SArray<SColumn*>
SFieldInfo fieldsInfo;
SArray** exprList; // SArray<SExprInfo*>
SLimit limit;
SLimit slimit;
STagCond tagCond;
SArray * colCond;
SArray * order;
int16_t numOfTables;
int16_t curTableIdx;
STableMetaInfo **pTableMetaInfo;
struct STSBuf *tsBuf;
int16_t fillType; // final result fill type
int64_t * fillVal; // default value for fill
int32_t numOfFillVal; // fill value size
char * msg; // pointer to the pCmd->payload to keep error message temporarily
int64_t clauseLimit; // limit for current sub clause
int64_t prjOffset; // offset value in the original sql expression, only applied at client side
int64_t vgroupLimit; // table limit in case of super table projection query + global order + limit
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
int32_t bufLen;
char* buf;
SArray *pUdfInfo;
struct SQueryStmtInfo *sibling; // sibling
SMultiFunctionsDesc info;
SArray *pDownstream; // SArray<struct SQueryStmtInfo>
int32_t havingFieldNum;
int32_t exprListLevelIndex;
} SQueryStmtInfo;
typedef enum {
PAYLOAD_TYPE_KV = 0,
PAYLOAD_TYPE_RAW = 1,
} EPayloadType;
typedef struct SVgDataBlocks {
SVgroupInfo vg;
int32_t numOfTables; // number of tables in current submit block
uint32_t size;
char *pData; // SMsgDesc + SSubmitReq + SSubmitBlk + ...
} SVgDataBlocks;
typedef struct SVnodeModifOpStmtInfo {
int16_t nodeType;
SArray* pDataBlocks; // data block for each vgroup, SArray<SVgDataBlocks*>.
int8_t schemaAttache; // denote if submit block is built with table schema or not
uint8_t payloadType; // EPayloadType. 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert
uint32_t insertType; // insert data from [file|sql statement| bound statement]
const char* sql; // current sql statement position
} SVnodeModifOpStmtInfo;
typedef struct SDclStmtInfo {
int16_t nodeType;
int16_t msgType;
SEpSet epSet;
char* pMsg;
int32_t msgLen;
void* pExtension; // todo remove it soon
} SDclStmtInfo;
#ifdef __cplusplus
}
#endif
#endif /*_TD_PARSENODES_H_*/

View File

@ -20,6 +20,8 @@
extern "C" {
#endif
#if 0
#include "parsenodes.h"
typedef struct SParseContext {
@ -94,6 +96,37 @@ int32_t getNewResColId();
void addIntoSourceParam(SSourceParam* pSourceParam, tExprNode* pNode, SColumn* pColumn);
SExprInfo* createBinaryExprInfo(struct tExprNode* pNode, SSchema* pResSchema);
#else
#include "querynodes.h"
#include "tmsg.h"
typedef struct SParseContext {
uint64_t requestId;
int32_t acctId;
const char *db;
void *pTransporter;
SEpSet mgmtEpSet;
const char *pSql; // sql string
size_t sqlLen; // length of the sql string
char *pMsg; // extended error message if exists to help identifying the problem in sql statement.
int32_t msgLen; // max length of the msg
struct SCatalog *pCatalog;
} SParseContext;
typedef struct SQuery {
bool isCmd;
SNode* pRoot;
int32_t numOfResCols;
SSchema* pResSchema;
} SQuery;
int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery);
void qDestroyQuery(SQuery* pQueryNode);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -20,6 +20,8 @@
extern "C" {
#endif
#if 0
#include "query.h"
#include "tmsg.h"
#include "tarray.h"
@ -207,6 +209,65 @@ void qDestroyQueryDag(SQueryDag* pDag);
char* qDagToString(const SQueryDag* pDag);
SQueryDag* qStringToDag(const char* pStr);
#else
#include "plannodes.h"
#include "query.h"
#define QUERY_TYPE_MERGE 1
#define QUERY_TYPE_PARTIAL 2
#define QUERY_TYPE_SCAN 3
#define QUERY_TYPE_MODIFY 4
typedef struct SSubplanId {
uint64_t queryId;
uint64_t templateId;
uint64_t subplanId;
} SSubplanId;
typedef struct SSubplan {
SSubplanId id; // unique id of the subplan
int32_t type; // QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL|QUERY_TYPE_SCAN|QUERY_TYPE_MODIFY
int32_t msgType; // message type for subplan, used to denote the send message type to vnode.
int32_t level; // the execution level of current subplan, starting from 0 in a top-down manner.
SQueryNodeAddr execNode; // for the scan/modify subplan, the optional execution node
SArray* pChildren; // the datasource subplan,from which to fetch the result
SArray* pParents; // the data destination subplan, get data from current subplan
SPhysiNode* pNode; // physical plan of current subplan
SDataSinkNode* pDataSink; // data of the subplan flow into the datasink
} SSubplan;
typedef struct SQueryPlan {
uint64_t queryId;
int32_t numOfSubplans;
SArray* pSubplans; // SArray*<SArray*<SSubplan*>>. The execution level of subplan, starting from 0.
} SQueryPlan;
typedef struct SPlanContext {
uint64_t queryId;
SNode* pAstRoot;
} SPlanContext;
// Create the physical plan for the query, according to the AST.
int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan);
// Set datasource of this subplan, multiple calls may be made to a subplan.
// @subplan subplan to be schedule
// @templateId templateId of a group of datasource subplans of this @subplan
// @ep one execution location of this group of datasource subplans
void qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SDownstreamSource* pSource);
// Convert to subplan to string for the scheduler to send to the executor
int32_t qSubPlanToString(const SSubplan* subplan, char** str, int32_t* len);
int32_t qStringToSubplan(const char* str, SSubplan** subplan);
char* qQueryPlanToString(const SQueryPlan* pPlan);
SQueryPlan* qStringToQueryPlan(const char* pStr);
void qDestroyQueryPlan(SQueryPlan* pPlan);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(INCLUDE_AS_ENUM) // enum define mode
#undef OP_ENUM_MACRO
#define OP_ENUM_MACRO(op) OP_##op,
#elif defined(INCLUDE_AS_NAME) // comment define mode
#undef OP_ENUM_MACRO
#define OP_ENUM_MACRO(op) #op,
#else
#error To use this include file, first define either INCLUDE_AS_ENUM or INCLUDE_AS_NAME
#endif
OP_ENUM_MACRO(StreamScan)
OP_ENUM_MACRO(TableScan)
OP_ENUM_MACRO(TableSeqScan)
OP_ENUM_MACRO(TagScan)
OP_ENUM_MACRO(SystemTableScan)
OP_ENUM_MACRO(StreamBlockScan)
OP_ENUM_MACRO(Aggregate)
OP_ENUM_MACRO(Project)
// OP_ENUM_MACRO(Groupby)
OP_ENUM_MACRO(Limit)
OP_ENUM_MACRO(SLimit)
OP_ENUM_MACRO(TimeWindow)
OP_ENUM_MACRO(SessionWindow)
OP_ENUM_MACRO(StateWindow)
OP_ENUM_MACRO(Fill)
OP_ENUM_MACRO(MultiTableAggregate)
OP_ENUM_MACRO(MultiTableTimeInterval)
OP_ENUM_MACRO(Filter)
OP_ENUM_MACRO(Distinct)
OP_ENUM_MACRO(Join)
OP_ENUM_MACRO(AllTimeWindow)
OP_ENUM_MACRO(AllMultiTableTimeInterval)
OP_ENUM_MACRO(Order)
OP_ENUM_MACRO(Exchange)
//OP_ENUM_MACRO(TableScan)

View File

@ -72,7 +72,7 @@ int32_t schedulerInit(SSchedulerCfg *cfg);
* @param nodeList Qnode/Vnode address list, element is SQueryNodeAddr
* @return
*/
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, struct SSchJob** pJob, const char* sql, SQueryResult *pRes);
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan* pDag, struct SSchJob** pJob, const char* sql, SQueryResult *pRes);
/**
* Process the query job, generated according to the query physical plan.
@ -80,7 +80,7 @@ int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, str
* @param pNodeList Qnode/Vnode address list, element is SQueryNodeAddr
* @return
*/
int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryDag* pDag, const char* sql, struct SSchJob** pJob);
int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryPlan* pDag, const char* sql, struct SSchJob** pJob);
/**
* Fetch query result from the remote query executor
@ -112,7 +112,7 @@ void schedulerDestroy(void);
* @param pTasks SArray**<STaskInfo>
* @return
*/
int32_t schedulerConvertDagToTaskList(SQueryDag* pDag, SArray **pTasks);
int32_t schedulerConvertDagToTaskList(SQueryPlan* pDag, SArray **pTasks);
/**
* make one task info's multiple copies

View File

@ -8,7 +8,7 @@ target_include_directories(
target_link_libraries(
taos
INTERFACE api
PRIVATE os util common transport parser planner catalog scheduler function qcom
PRIVATE os util common transport nodes parser planner catalog scheduler function qcom
)
if(${BUILD_TEST})

View File

@ -172,7 +172,7 @@ typedef struct SRequestSendRecvBody {
SShowReqInfo showInfo; // todo this attribute will be removed after the query framework being completed.
SDataBuf requestMsg;
struct SSchJob* pQueryJob; // query job, created according to sql query DAG.
struct SQueryDag* pDag; // the query dag, generated according to the sql statement.
struct SQueryPlan* pDag; // the query dag, generated according to the sql statement.
SReqResultInfo resInfo;
} SRequestSendRecvBody;
@ -232,7 +232,7 @@ void setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32_t
int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj** pRequest);
int32_t parseSql(SRequestObj* pRequest, SQueryNode** pQuery);
int32_t parseSql(SRequestObj* pRequest, SQuery** pQuery);
// --- heartbeat
// global, called by mgmt

View File

@ -184,7 +184,7 @@ static void doDestroyRequest(void *p) {
tfree(pRequest->pInfo);
doFreeReqResultInfo(&pRequest->body.resInfo);
qDestroyQueryDag(pRequest->body.pDag);
qDestroyQueryPlan(pRequest->body.pDag);
if (pRequest->body.showInfo.pArray != NULL) {
taosArrayDestroy(pRequest->body.showInfo.pArray);

View File

@ -139,7 +139,7 @@ int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj*
return TSDB_CODE_SUCCESS;
}
int32_t parseSql(SRequestObj* pRequest, SQueryNode** pQuery) {
int32_t parseSql(SRequestObj* pRequest, SQuery** pQuery) {
STscObj* pTscObj = pRequest->pTscObj;
SParseContext cxt = {
@ -161,54 +161,57 @@ int32_t parseSql(SRequestObj* pRequest, SQueryNode** pQuery) {
}
code = qParseQuerySql(&cxt, pQuery);
if (TSDB_CODE_SUCCESS == code) {
setResSchemaInfo(&pRequest->body.resInfo, (*pQuery)->pResSchema, (*pQuery)->numOfResCols);
}
tfree(cxt.db);
return code;
}
int32_t execDdlQuery(SRequestObj* pRequest, SQueryNode* pQuery) {
SDclStmtInfo* pDcl = (SDclStmtInfo*)pQuery;
pRequest->type = pDcl->msgType;
pRequest->body.requestMsg = (SDataBuf){.pData = pDcl->pMsg, .len = pDcl->msgLen, .handle = NULL};
int32_t execDdlQuery(SRequestObj* pRequest, SQuery* pQuery) {
// SDclStmtInfo* pDcl = (SDclStmtInfo*)pQuery;
// pRequest->type = pDcl->msgType;
// pRequest->body.requestMsg = (SDataBuf){.pData = pDcl->pMsg, .len = pDcl->msgLen, .handle = NULL};
STscObj* pTscObj = pRequest->pTscObj;
SMsgSendInfo* pSendMsg = buildMsgInfoImpl(pRequest);
// STscObj* pTscObj = pRequest->pTscObj;
// SMsgSendInfo* pSendMsg = buildMsgInfoImpl(pRequest);
int64_t transporterId = 0;
if (pDcl->msgType == TDMT_VND_CREATE_TABLE || pDcl->msgType == TDMT_VND_SHOW_TABLES) {
if (pDcl->msgType == TDMT_VND_SHOW_TABLES) {
SShowReqInfo* pShowReqInfo = &pRequest->body.showInfo;
if (pShowReqInfo->pArray == NULL) {
pShowReqInfo->currentIndex = 0; // set the first vnode/ then iterate the next vnode
pShowReqInfo->pArray = pDcl->pExtension;
}
}
asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pDcl->epSet, &transporterId, pSendMsg);
} else {
asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pDcl->epSet, &transporterId, pSendMsg);
}
// int64_t transporterId = 0;
// if (pDcl->msgType == TDMT_VND_CREATE_TABLE || pDcl->msgType == TDMT_VND_SHOW_TABLES) {
// if (pDcl->msgType == TDMT_VND_SHOW_TABLES) {
// SShowReqInfo* pShowReqInfo = &pRequest->body.showInfo;
// if (pShowReqInfo->pArray == NULL) {
// pShowReqInfo->currentIndex = 0; // set the first vnode/ then iterate the next vnode
// pShowReqInfo->pArray = pDcl->pExtension;
// }
// }
// asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pDcl->epSet, &transporterId, pSendMsg);
// } else {
// asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pDcl->epSet, &transporterId, pSendMsg);
// }
tsem_wait(&pRequest->body.rspSem);
// tsem_wait(&pRequest->body.rspSem);
return TSDB_CODE_SUCCESS;
}
int32_t getPlan(SRequestObj* pRequest, SQueryNode* pQueryNode, SQueryDag** pDag, SArray* pNodeList) {
pRequest->type = pQueryNode->type;
int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pDag, SArray* pNodeList) {
// pRequest->type = pQuery->type;
SSchema* pSchema = NULL;
int32_t numOfCols = 0;
int32_t code = qCreateQueryDag(pQueryNode, pDag, &pSchema, &numOfCols, pNodeList, pRequest->requestId);
if (code != 0) {
return code;
}
// SSchema* pSchema = NULL;
// int32_t numOfCols = 0;
// int32_t code = qCreateQueryDag(pQuery, pDag, &pSchema, &numOfCols, pNodeList, pRequest->requestId);
// if (code != 0) {
// return code;
// }
if (pQueryNode->type == TSDB_SQL_SELECT) {
setResSchemaInfo(&pRequest->body.resInfo, pSchema, numOfCols);
pRequest->type = TDMT_VND_QUERY;
}
// if (pQuery->type == TSDB_SQL_SELECT) {
// setResSchemaInfo(&pRequest->body.resInfo, pSchema, numOfCols);
// pRequest->type = TDMT_VND_QUERY;
// }
tfree(pSchema);
return code;
// tfree(pSchema);
// return code;
}
void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t numOfCols) {
@ -224,7 +227,7 @@ void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t
}
}
int32_t scheduleQuery(SRequestObj* pRequest, SQueryDag* pDag, SArray* pNodeList) {
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
if (TSDB_SQL_INSERT == pRequest->type || TSDB_SQL_CREATE_TABLE == pRequest->type) {
SQueryResult res = {.code = 0, .numOfRows = 0, .msgSize = ERROR_MSG_BUF_DEFAULT_SIZE, .msg = pRequest->msgBuf};
@ -254,24 +257,24 @@ TAOS_RES* taos_query_l(TAOS* taos, const char* sql, int sqlLen) {
}
SRequestObj* pRequest = NULL;
SQueryNode* pQueryNode = NULL;
SArray* pNodeList = taosArrayInit(4, sizeof(struct SQueryNodeAddr));
SQuery* pQuery;
SArray* pNodeList = taosArrayInit(4, sizeof(struct SQueryNodeAddr));
terrno = TSDB_CODE_SUCCESS;
CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return);
CHECK_CODE_GOTO(parseSql(pRequest, &pQueryNode), _return);
CHECK_CODE_GOTO(parseSql(pRequest, &pQuery), _return);
if (qIsDdlQuery(pQueryNode)) {
CHECK_CODE_GOTO(execDdlQuery(pRequest, pQueryNode), _return);
if (pQuery->isCmd) {
CHECK_CODE_GOTO(execDdlQuery(pRequest, pQuery), _return);
} else {
CHECK_CODE_GOTO(getPlan(pRequest, pQueryNode, &pRequest->body.pDag, pNodeList), _return);
CHECK_CODE_GOTO(getPlan(pRequest, pQuery, &pRequest->body.pDag, pNodeList), _return);
CHECK_CODE_GOTO(scheduleQuery(pRequest, pRequest->body.pDag, pNodeList), _return);
pRequest->code = terrno;
}
_return:
taosArrayDestroy(pNodeList);
qDestroyQuery(pQueryNode);
qDestroyQuery(pQuery);
if (NULL != pRequest && TSDB_CODE_SUCCESS != terrno) {
pRequest->code = terrno;
}

View File

@ -424,7 +424,7 @@ SArray* tmqGetConnInfo(SClientHbKey connKey, void* param) {
TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, int sqlLen) {
STscObj* pTscObj = (STscObj*)taos;
SRequestObj* pRequest = NULL;
SQueryNode* pQueryNode = NULL;
SQuery* pQueryNode = NULL;
char* pStr = NULL;
terrno = TSDB_CODE_SUCCESS;
@ -447,7 +447,7 @@ TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, i
}
tscDebug("start to create topic, %s", topicName);
#if 0
CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return);
CHECK_CODE_GOTO(parseSql(pRequest, &pQueryNode), _return);
@ -503,7 +503,7 @@ TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, i
asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo);
tsem_wait(&pRequest->body.rspSem);
#endif
_return:
qDestroyQuery(pQueryNode);
/*if (sendInfo != NULL) {*/

View File

@ -760,9 +760,9 @@ static int32_t mndProcessDoRebalanceMsg(SMnodeMsg *pMsg) {
static int32_t mndInitUnassignedVg(SMnode *pMnode, const SMqTopicObj *pTopic, SMqSubscribeObj *pSub) {
SSdb *pSdb = pMnode->pSdb;
SVgObj *pVgroup = NULL;
SQueryDag *pDag = qStringToDag(pTopic->physicalPlan);
SQueryPlan *pPlan = qStringToQueryPlan(pTopic->physicalPlan);
SArray *pArray = NULL;
SArray *inner = taosArrayGet(pDag->pSubplans, 0);
SArray *inner = taosArrayGet(pPlan->pSubplans, 0);
SSubplan *plan = taosArrayGetP(inner, 0);
SArray *unassignedVg = pSub->unassignedVg;
@ -779,7 +779,7 @@ static int32_t mndInitUnassignedVg(SMnode *pMnode, const SMqTopicObj *pTopic, SM
plan->execNode.nodeId = pVgroup->vgId;
plan->execNode.epset = mndGetVgroupEpset(pMnode, pVgroup);
if (schedulerConvertDagToTaskList(pDag, &pArray) < 0) {
if (schedulerConvertDagToTaskList(pPlan, &pArray) < 0) {
terrno = TSDB_CODE_MND_UNSUPPORTED_TOPIC;
mError("unsupport topic: %s, sql: %s", pTopic->name, pTopic->sql);
return -1;

View File

@ -22,6 +22,7 @@ extern "C" {
#include "common.h"
#include "dataSinkMgt.h"
#include "plannodes.h"
struct SDataSink;
struct SDataSinkHandle;
@ -45,7 +46,7 @@ typedef struct SDataSinkHandle {
FDestroyDataSinker fDestroy;
} SDataSinkHandle;
int32_t createDataDispatcher(SDataSinkManager* pManager, const struct SDataSink* pDataSink, DataSinkHandle* pHandle);
int32_t createDataDispatcher(SDataSinkManager* pManager, const SDataSinkNode* pDataSink, DataSinkHandle* pHandle);
#ifdef __cplusplus
}

View File

@ -39,7 +39,7 @@ typedef struct SDataCacheEntry {
typedef struct SDataDispatchHandle {
SDataSinkHandle sink;
SDataSinkManager* pManager;
SDataBlockSchema schema;
SDataBlockDescNode schema;
STaosQueue* pDataBlocks;
SDataDispatchBuf nextOutput;
int32_t status;
@ -48,12 +48,13 @@ typedef struct SDataDispatchHandle {
pthread_mutex_t mutex;
} SDataDispatchHandle;
static bool needCompress(const SSDataBlock* pData, const SDataBlockSchema* pSchema) {
static bool needCompress(const SSDataBlock* pData, const SDataBlockDescNode* pSchema) {
if (tsCompressColData < 0 || 0 == pData->info.rows) {
return false;
}
for (int32_t col = 0; col < pSchema->numOfCols; ++col) {
int32_t numOfCols = LIST_LENGTH(pSchema->pSlots);
for (int32_t col = 0; col < numOfCols; ++col) {
SColumnInfoData* pColRes = taosArrayGet(pData->pDataBlock, col);
int32_t colSize = pColRes->info.bytes * pData->info.rows;
if (NEEDTO_COMPRESS_QUERY(colSize)) {
@ -70,13 +71,14 @@ static int32_t compressColData(SColumnInfoData *pColRes, int32_t numOfRows, char
pColRes->pData, colSize, numOfRows, data, colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0);
}
static void copyData(const SInputData* pInput, const SDataBlockSchema* pSchema, char* data, int8_t compressed, int32_t *compLen) {
static void copyData(const SInputData* pInput, const SDataBlockDescNode* pSchema, char* data, int8_t compressed, int32_t *compLen) {
int32_t numOfCols = LIST_LENGTH(pSchema->pSlots);
int32_t *compSizes = (int32_t*)data;
if (compressed) {
data += pSchema->numOfCols * sizeof(int32_t);
data += numOfCols * sizeof(int32_t);
}
for (int32_t col = 0; col < pSchema->numOfCols; ++col) {
for (int32_t col = 0; col < numOfCols; ++col) {
SColumnInfoData* pColRes = taosArrayGet(pInput->pData->pDataBlock, col);
if (compressed) {
compSizes[col] = compressColData(pColRes, pInput->pData->info.rows, data, compressed);
@ -224,7 +226,7 @@ static int32_t destroyDataSinker(SDataSinkHandle* pHandle) {
pthread_mutex_destroy(&pDispatcher->mutex);
}
int32_t createDataDispatcher(SDataSinkManager* pManager, const SDataSink* pDataSink, DataSinkHandle* pHandle) {
int32_t createDataDispatcher(SDataSinkManager* pManager, const SDataSinkNode* pDataSink, DataSinkHandle* pHandle) {
SDataDispatchHandle* dispatcher = calloc(1, sizeof(SDataDispatchHandle));
if (NULL == dispatcher) {
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
@ -236,7 +238,7 @@ int32_t createDataDispatcher(SDataSinkManager* pManager, const SDataSink* pDataS
dispatcher->sink.fGetData = getDataBlock;
dispatcher->sink.fDestroy = destroyDataSinker;
dispatcher->pManager = pManager;
dispatcher->schema = pDataSink->schema;
dispatcher->schema = pDataSink->inputDataBlockDesc;
dispatcher->status = DS_BUF_EMPTY;
dispatcher->queryEnd = false;
dispatcher->pDataBlocks = taosOpenQueue();

View File

@ -25,8 +25,8 @@ int32_t dsDataSinkMgtInit(SDataSinkMgtCfg *cfg) {
pthread_mutex_init(&gDataSinkManager.mutex, NULL);
}
int32_t dsCreateDataSinker(const struct SDataSink *pDataSink, DataSinkHandle* pHandle) {
if (DSINK_Dispatch == pDataSink->info.type) {
int32_t dsCreateDataSinker(const SDataSinkNode *pDataSink, DataSinkHandle* pHandle) {
if (QUERY_NODE_DSINK_DISPATCH == nodeType(pDataSink)) {
return createDataDispatcher(&gDataSinkManager, pDataSink, pHandle);
}
return TSDB_CODE_FAILED;

View File

@ -20,7 +20,7 @@
static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, char* id) {
ASSERT(pOperator != NULL);
if (pOperator->operatorType != OP_StreamScan) {
if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
if (pOperator->numOfDownstream == 0) {
qError("failed to find stream scan operator to set the input data block, %s" PRIx64, id);
return TSDB_CODE_QRY_APP_ERROR;

View File

@ -5285,7 +5285,7 @@ SOperatorInfo* createExchangeOperatorInfo(const SArray* pSources, const SArray*
tsem_init(&pInfo->ready, 0, 0);
pOperator->name = "ExchangeOperator";
pOperator->operatorType = OP_Exchange;
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
pOperator->blockingOptr = false;
pOperator->status = OP_IN_EXECUTING;
pOperator->info = pInfo;
@ -5365,7 +5365,7 @@ SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order,
pInfo->scanFlag = MAIN_SCAN;
pOperator->name = "TableScanOperator";
pOperator->operatorType = OP_TableScan;
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
pOperator->blockingOptr = false;
pOperator->status = OP_IN_EXECUTING;
pOperator->info = pInfo;
@ -5389,7 +5389,7 @@ SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntim
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
pOperator->name = "TableSeqScanOperator";
pOperator->operatorType = OP_TableSeqScan;
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN;
pOperator->blockingOptr = false;
pOperator->status = OP_IN_EXECUTING;
pOperator->info = pInfo;
@ -5452,7 +5452,7 @@ SOperatorInfo* createStreamScanOperatorInfo(void *streamReadHandle, SArray* pExp
pInfo->readerHandle = streamReadHandle;
pOperator->name = "StreamBlockScanOperator";
pOperator->operatorType = OP_StreamScan;
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN;
pOperator->blockingOptr = false;
pOperator->status = OP_IN_EXECUTING;
pOperator->info = pInfo;
@ -6236,7 +6236,7 @@ SOperatorInfo *createOrderOperatorInfo(SOperatorInfo* downstream, SArray* pExprI
}
pOperator->name = "Order";
pOperator->operatorType = OP_Order;
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT;
pOperator->blockingOptr = true;
pOperator->status = OP_IN_EXECUTING;
pOperator->info = pInfo;
@ -7193,6 +7193,21 @@ static int32_t initAggInfo(SAggOperatorInfo* pInfo, SArray* pExprInfo, int32_t n
return TSDB_CODE_SUCCESS;
}
static void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
assert(dst != NULL && src != NULL);
*dst = *src;
dst->pExpr = exprdup(src->pExpr);
dst->base.pColumns = calloc(src->base.numOfCols, sizeof(SColumn));
memcpy(dst->base.pColumns, src->base.pColumns, sizeof(SColumn) * src->base.numOfCols);
memset(dst->base.param, 0, sizeof(SVariant) * tListLen(dst->base.param));
for (int32_t j = 0; j < src->base.numOfParams; ++j) {
taosVariantAssign(&dst->base.param[j], &src->base.param[j]);
}
}
static SExprInfo* exprArrayDup(SArray* pExprInfo) {
size_t numOfOutput = taosArrayGetSize(pExprInfo);
SExprInfo* p = calloc(numOfOutput, sizeof(SExprInfo));
@ -7215,7 +7230,7 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SArray* pE
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
pOperator->name = "TableAggregate";
pOperator->operatorType = OP_Aggregate;
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG;
pOperator->blockingOptr = true;
pOperator->status = OP_IN_EXECUTING;
pOperator->info = pInfo;
@ -7316,7 +7331,7 @@ SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SArray
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
pOperator->name = "MultiTableAggregate";
pOperator->operatorType = OP_MultiTableAggregate;
// pOperator->operatorType = OP_MultiTableAggregate;
pOperator->blockingOptr = true;
pOperator->status = OP_IN_EXECUTING;
pOperator->info = pInfo;
@ -7690,7 +7705,7 @@ SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorI
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
pOperator->name = "SLimitOperator";
pOperator->operatorType = OP_SLimit;
// pOperator->operatorType = OP_SLimit;
pOperator->blockingOptr = false;
pOperator->status = OP_IN_EXECUTING;
// pOperator->exec = doSLimit;
@ -7846,7 +7861,7 @@ SOperatorInfo* createTagScanOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
pOperator->name = "SeqTableTagScan";
pOperator->operatorType = OP_TagScan;
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN;
pOperator->blockingOptr = false;
pOperator->status = OP_IN_EXECUTING;
pOperator->info = pInfo;
@ -8164,25 +8179,25 @@ static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId) {
return pTaskInfo;
}
static tsdbReaderT doCreateDataReader(STableScanPhyNode* pTableScanNode, SReadHandle* pHandle, uint64_t queryId, uint64_t taskId);
static tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle, uint64_t queryId, uint64_t taskId);
static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo, uint64_t queryId, uint64_t taskId);
SOperatorInfo* doCreateOperatorTreeNode(SPhyNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) {
if (pPhyNode->pChildren == NULL || taosArrayGetSize(pPhyNode->pChildren) == 0) {
if (pPhyNode->info.type == OP_TableScan) {
SScanPhyNode* pScanPhyNode = (SScanPhyNode*)pPhyNode;
SOperatorInfo* doCreateOperatorTreeNode(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) {
if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == nodeType(pPhyNode)) {
SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode;
size_t numOfCols = taosArrayGetSize(pPhyNode->pTargets);
tsdbReaderT pDataReader = doCreateDataReader((STableScanPhyNode*) pPhyNode, pHandle, (uint64_t) queryId, taskId);
size_t numOfCols = LIST_LENGTH(pScanPhyNode->pScanCols);
tsdbReaderT pDataReader = doCreateDataReader((STableScanPhysiNode*) pPhyNode, pHandle, (uint64_t) queryId, taskId);
int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, queryId, taskId);
return createTableScanOperatorInfo(pDataReader, pScanPhyNode->order, numOfCols, pScanPhyNode->count, pScanPhyNode->reverse, pTaskInfo);
} else if (pPhyNode->info.type == OP_Exchange) {
SExchangePhyNode* pEx = (SExchangePhyNode*) pPhyNode;
return createExchangeOperatorInfo(pEx->pSrcEndPoints, pEx->node.pTargets, pTaskInfo);
} else if (pPhyNode->info.type == OP_StreamScan) {
SScanPhyNode* pScanPhyNode = (SScanPhyNode*)pPhyNode; // simple child table.
} else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == nodeType(pPhyNode)) {
// SExchangePhysiNode* pEx = (SExchangePhysiNode*) pPhyNode;
// return createExchangeOperatorInfo(pEx->pSrcEndPoints, pEx->node.pTargets, pTaskInfo);
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == nodeType(pPhyNode)) {
SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode; // simple child table.
STableGroupInfo groupInfo = {0};
int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, &groupInfo, queryId, taskId);
@ -8198,58 +8213,58 @@ SOperatorInfo* doCreateOperatorTreeNode(SPhyNode* pPhyNode, SExecTaskInfo* pTask
taosArrayPush(idList, &pkeyInfo->uid);
}
SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pPhyNode->pTargets, idList, pTaskInfo);
taosArrayDestroy(idList);
// SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pScanPhyNode->pScanCols, idList, pTaskInfo);
// taosArrayDestroy(idList);
//TODO destroy groupInfo
return pOperator;
// //TODO destroy groupInfo
// return pOperator;
}
}
if (pPhyNode->info.type == OP_Aggregate) {
size_t size = taosArrayGetSize(pPhyNode->pChildren);
if (QUERY_NODE_PHYSICAL_PLAN_AGG == nodeType(pPhyNode)) {
size_t size = LIST_LENGTH(pPhyNode->pChildren);
assert(size == 1);
// TODO single table agg
for (int32_t i = 0; i < size; ++i) {
SPhyNode* pChildNode = taosArrayGetP(pPhyNode->pChildren, i);
SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
SOperatorInfo* op = doCreateOperatorTreeNode(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
return createAggregateOperatorInfo(op, pPhyNode->pTargets, pTaskInfo, pTableGroupInfo);
// return createAggregateOperatorInfo(op, pPhyNode->pTargets, pTaskInfo, pTableGroupInfo);
}
} else if (pPhyNode->info.type == OP_MultiTableAggregate) {
} /*else if (pPhyNode->info.type == OP_MultiTableAggregate) {
size_t size = taosArrayGetSize(pPhyNode->pChildren);
assert(size == 1);
for (int32_t i = 0; i < size; ++i) {
SPhyNode* pChildNode = taosArrayGetP(pPhyNode->pChildren, i);
SPhysiNode* pChildNode = taosArrayGetP(pPhyNode->pChildren, i);
SOperatorInfo* op = doCreateOperatorTreeNode(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
return createMultiTableAggOperatorInfo(op, pPhyNode->pTargets, pTaskInfo, pTableGroupInfo);
}
}
}*/
}
static tsdbReaderT createDataReaderImpl(STableScanPhyNode* pTableScanNode, STableGroupInfo* pGroupInfo, void* readHandle, uint64_t queryId, uint64_t taskId) {
static tsdbReaderT createDataReaderImpl(STableScanPhysiNode* pTableScanNode, STableGroupInfo* pGroupInfo, void* readHandle, uint64_t queryId, uint64_t taskId) {
STsdbQueryCond cond = {.loadExternalRows = false};
cond.order = pTableScanNode->scan.order;
cond.numOfCols = taosArrayGetSize(pTableScanNode->scan.node.pTargets);
cond.numOfCols = LIST_LENGTH(pTableScanNode->scan.pScanCols);
cond.colList = calloc(cond.numOfCols, sizeof(SColumnInfo));
if (cond.colList == NULL) {
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
return NULL;
}
cond.twindow = pTableScanNode->window;
cond.twindow = pTableScanNode->scanRange;
cond.type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
for (int32_t i = 0; i < cond.numOfCols; ++i) {
SExprInfo* pExprInfo = taosArrayGetP(pTableScanNode->scan.node.pTargets, i);
assert(pExprInfo->pExpr->nodeType == TEXPR_COL_NODE);
// SExprInfo* pExprInfo = taosArrayGetP(pTableScanNode->scan.node.pTargets, i);
// assert(pExprInfo->pExpr->nodeType == TEXPR_COL_NODE);
SSchema* pSchema = pExprInfo->pExpr->pSchema;
cond.colList[i].type = pSchema->type;
cond.colList[i].bytes = pSchema->bytes;
cond.colList[i].colId = pSchema->colId;
// SSchema* pSchema = pExprInfo->pExpr->pSchema;
// cond.colList[i].type = pSchema->type;
// cond.colList[i].bytes = pSchema->bytes;
// cond.colList[i].colId = pSchema->colId;
}
return tsdbQueryTables(readHandle, &cond, pGroupInfo, queryId, taskId);
@ -8266,7 +8281,7 @@ static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t
return code;
}
static tsdbReaderT doCreateDataReader(STableScanPhyNode* pTableScanNode, SReadHandle* pHandle, uint64_t queryId, uint64_t taskId) {
static tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle, uint64_t queryId, uint64_t taskId) {
STableGroupInfo groupInfo = {0};
uint64_t uid = pTableScanNode->scan.uid;

View File

@ -1,369 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_ASTGENERATOR_H
#define TDENGINE_ASTGENERATOR_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ttoken.h"
#include "tvariant.h"
#include "parser.h"
#define ParseTOKENTYPE SToken
#define NON_ARITHMEIC_EXPR 0
#define NORMAL_ARITHMETIC 1
#define AGG_ARIGHTMEIC 2
enum SQL_NODE_TYPE {
SQL_NODE_TABLE_COLUMN= 1,
SQL_NODE_SQLFUNCTION = 2,
SQL_NODE_VALUE = 3,
SQL_NODE_EXPR = 4,
};
enum SQL_FROM_NODE_TYPE {
SQL_FROM_NODE_SUBQUERY = 1,
SQL_FROM_NODE_TABLES = 2,
};
enum SQL_UNION_TYPE {
SQL_TYPE_UNIONALL = 1,
SQL_TYPE_UNION = 2,
};
extern char tTokenTypeSwitcher[13];
#define toTSDBType(x) \
do { \
if ((x) >= tListLen(tTokenTypeSwitcher)) { \
(x) = TSDB_DATA_TYPE_BINARY; \
} else { \
(x) = tTokenTypeSwitcher[(x)]; \
} \
} while (0)
#define TPARSER_HAS_TOKEN(_t) ((_t).n > 0)
#define TPARSER_SET_NONE_TOKEN(_t) ((_t).n = 0)
typedef struct SListItem {
SVariant pVar;
uint8_t sortOrder;
} SListItem;
typedef struct SIntervalVal {
int32_t token;
SToken interval;
SToken offset;
} SIntervalVal;
typedef struct SSessionWindowVal {
SToken col;
SToken gap;
} SSessionWindowVal;
typedef struct SWindowStateVal {
SToken col;
} SWindowStateVal;
struct SRelationInfo;
typedef struct SSqlNode {
struct SRelationInfo *from; // from clause SArray<SSqlNode>
struct SArray *pSelNodeList; // select clause
struct tSqlExpr *pWhere; // where clause [optional]
SArray *pGroupby; // groupby clause, only for tags[optional], SArray<SListItem>
SArray *pSortOrder; // orderby [optional], SArray<SListItem>
SArray *fillType; // fill type[optional], SArray<SListItem>
SIntervalVal interval; // (interval, interval_offset) [optional]
SSessionWindowVal sessionVal; // session window [optional]
SWindowStateVal windowstateVal; // window_state(col) [optional]
SToken sliding; // sliding window [optional]
SLimit limit; // limit offset [optional]
SLimit slimit; // group limit offset [optional]
SToken sqlstr; // sql string in select clause
struct tSqlExpr *pHaving; // having clause [optional]
} SSqlNode;
typedef struct SSubclause {
int32_t unionType;
SArray *node;
} SSubclause;
typedef struct SRelElement {
union {
SToken tableName;
SSubclause *pSubquery;
};
SToken aliasName;
} SRelElement;
typedef struct SRelationInfo {
int32_t type; // nested query|table name list
SArray *list; // SArray<SRelElement>
} SRelationInfo;
typedef struct SCreatedTableInfo {
SToken name; // table name token
SToken stbName; // super table name token , for using clause
SArray *pTagNames; // create by using super table, tag name
SArray *pTagVals; // create by using super table, tag value. SArray<SToken>
char *fullname; // table full name
int8_t igExist; // ignore if exists
} SCreatedTableInfo;
typedef struct SCreateTableSql {
SToken name; // table name, create table [name] xxx
int8_t type; // create normal table/from super table/ stream
bool existCheck;
struct {
SArray *pTagColumns; // SArray<SField>
SArray *pColumns; // SArray<SField>
} colInfo;
SArray *childTableInfo; // SArray<SCreatedTableInfo>
SSqlNode *pSelect;
} SCreateTableSql;
typedef struct SAlterTableInfo {
SToken name;
int16_t tableType;
int16_t type;
STagData tagData;
SArray *pAddColumns; // SArray<SField>
SArray *varList; // set t=val or: change src dst, SArray<SListItem>
} SAlterTableInfo;
typedef struct SCreateDbInfo {
SToken dbname;
int32_t replica;
int32_t cacheBlockSize;
int32_t numOfVgroups;
int32_t numOfBlocks;
int32_t daysPerFile;
int32_t minRowsPerBlock;
int32_t maxRowsPerBlock;
int32_t fsyncPeriod;
int64_t commitTime;
int32_t walLevel;
int32_t quorum;
int32_t compressionLevel;
SToken precision;
bool ignoreExists;
int8_t update;
int8_t cachelast;
SArray *keep;
int8_t streamMode;
} SCreateDbInfo;
typedef struct SCreateFuncInfo {
SToken name;
SToken path;
int32_t type;
int32_t bufSize;
SField output;
} SCreateFuncInfo;
typedef struct SCreateAcctInfo {
int32_t maxUsers;
int32_t maxDbs;
int32_t maxTimeSeries;
int32_t maxStreams;
int32_t maxPointsPerSecond;
int64_t maxStorage;
int64_t maxQueryTime;
int32_t maxConnections;
SToken stat;
} SCreateAcctInfo;
typedef struct SShowInfo {
uint8_t showType;
SToken prefix;
SToken pattern;
} SShowInfo;
typedef struct SUserInfo {
SToken user;
SToken passwd;
SToken privilege;
int16_t type;
} SUserInfo;
typedef struct SMiscInfo {
SArray *a; // SArray<SToken>
bool existsCheck;
int16_t dbType;
int16_t tableType;
SUserInfo user;
union {
SCreateDbInfo dbOpt;
SCreateAcctInfo acctOpt;
SCreateFuncInfo funcOpt;
SShowInfo showOpt;
SToken id;
};
} SMiscInfo;
typedef struct SSqlInfo {
int32_t type;
bool valid;
SSubclause sub;
char msg[256];
SArray *funcs;
union {
SCreateTableSql *pCreateTableInfo;
SAlterTableInfo *pAlterInfo;
SMiscInfo *pMiscInfo;
};
} SSqlInfo;
typedef struct tSqlExpr {
uint16_t type; // sql node type
uint32_t tokenId; // TK_LE: less than(binary expr)
// The complete string of the function(col, param), and the function name is kept in exprToken
struct {
SToken operand;
struct SArray *paramList; // function parameters list
} Expr;
SToken columnName; // table column info
SVariant value; // the use input value
SToken exprToken; // original sql expr string or function name of sql function
struct tSqlExpr *pLeft; // the left child
struct tSqlExpr *pRight; // the right child
} tSqlExpr;
// used in select clause. select <SArray> from xxx
typedef struct tSqlExprItem {
tSqlExpr *pNode; // The list of expressions
int32_t functionId;
char *aliasName; // alias name, null-terminated string
bool distinct;
} tSqlExprItem;
SArray *tListItemAppend(SArray *pList, SVariant *pVar, uint8_t sortOrder);
SArray *tListItemInsert(SArray *pList, SVariant *pVar, uint8_t sortOrder, int32_t index);
SArray *tListItemAppendToken(SArray *pList, SToken *pAliasToken, uint8_t sortOrder);
SRelationInfo *setTableNameList(SRelationInfo *pRelationInfo, SToken *pName, SToken *pAlias);
void * destroyRelationInfo(SRelationInfo *pFromInfo);
SRelationInfo *addSubquery(SRelationInfo *pRelationInfo, SSubclause *pSub, SToken *pAlias);
// sql expr leaf node
tSqlExpr *tSqlExprCreateIdValue(SToken *pToken, int32_t optrType);
tSqlExpr *tSqlExprCreateFunction(SArray *pParam, SToken *pFuncToken, SToken *endToken, int32_t optType);
SArray * tRecordFuncName(SArray *pList, SToken *pToken);
tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType);
tSqlExpr *tSqlExprClone(tSqlExpr *pSrc);
void tSqlExprCompact(tSqlExpr **pExpr);
bool tSqlExprIsLeaf(tSqlExpr *pExpr);
bool tSqlExprIsParentOfLeaf(tSqlExpr *pExpr);
void tSqlExprDestroy(tSqlExpr *pExpr);
SArray * tSqlExprListAppend(SArray *pList, tSqlExpr *pNode, SToken *pDistinct, SToken *pToken);
void tSqlExprListDestroy(SArray *pList);
void tSqlExprEvaluate(tSqlExpr* pExpr);
SSqlNode *tSetQuerySqlNode(SToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps,
SWindowStateVal *pw, SToken *pSliding, SArray *pFill, SLimit *pLimit, SLimit *pgLimit, tSqlExpr *pHaving);
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right);
SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SSqlNode *pSelect, int32_t type);
SAlterTableInfo * tSetAlterTableInfo(SToken *pTableName, SArray *pCols, SArray *pVals, int32_t type, int16_t tableType);
SCreatedTableInfo createNewChildTableInfo(SToken *pTableName, SArray *pTagNames, SArray *pTagVals, SToken *pToken,
SToken *igExists);
/*!
* test
* @param pSqlNode
*/
void destroyAllSqlNode(struct SSubclause *pSqlNode);
void destroySqlNode(SSqlNode *pSql);
void freeCreateTableInfo(void* p);
SSqlInfo *setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SToken *pTableName, int32_t type);
SSubclause* setSubclause(SSubclause* sub, void *pSqlNode);
SSubclause* appendSelectClause(SSubclause *sub, int32_t unionType, void *pSubclause);
void setCreatedTableName(SSqlInfo *pInfo, SToken *pTableNameToken, SToken *pIfNotExists);
void* destroyCreateTableSql(SCreateTableSql* pCreate);
void setDropFuncInfo(SSqlInfo *pInfo, int32_t type, SToken* pToken);
void setCreateFuncInfo(SSqlInfo *pInfo, int32_t type, SToken *pName, SToken *pPath, SField *output, SToken* bufSize, int32_t funcType);
void destroySqlInfo(SSqlInfo *pInfo);
void setDCLSqlElems(SSqlInfo *pInfo, int32_t type, int32_t nParams, ...);
void setDropDbTableInfo(SSqlInfo *pInfo, int32_t type, SToken* pToken, SToken* existsCheck,int16_t dbType,int16_t tableType);
void setShowOptions(SSqlInfo *pInfo, int32_t type, SToken* prefix, SToken* pPatterns);
void setCreateDbInfo(SSqlInfo *pInfo, int32_t type, SToken *pToken, SCreateDbInfo *pDB, SToken *pIgExists);
void setCreateAcctSql(SSqlInfo *pInfo, int32_t type, SToken *pName, SToken *pPwd, SCreateAcctInfo *pAcctInfo);
void setCreateUserSql(SSqlInfo *pInfo, SToken *pName, SToken *pPasswd);
void setKillSql(SSqlInfo *pInfo, int32_t type, SToken *ip);
void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SToken *pName, SToken* pPwd, SToken *pPrivilege);
void setCompactVnodeSql(SSqlInfo *pInfo, int32_t type, SArray *pParam);
void setDefaultCreateDbOption(SCreateDbInfo *pDBInfo);
void setDefaultCreateTopicOption(SCreateDbInfo *pDBInfo);
// prefix show db.tables;
void tSetDbName(SToken *pCpxName, SToken *pDb);
void tSetColumnInfo(struct SField *pField, SToken *pName, struct SField *pType);
void tSetColumnType(struct SField *pField, SToken *type);
/**
* The main parse function.
* @param yyp The parser
* @param yymajor The major token code number
* @param yyminor The value for the token
*/
void Parse(void *yyp, int yymajor, ParseTOKENTYPE yyminor, SSqlInfo *);
/**
* Free the allocated resources in case of failure.
* @param p The parser to be deleted
* @param freeProc Function used to reclaim memory
*/
void ParseFree(void *p, void (*freeProc)(void *));
/**
* Allocated callback function.
* @param mallocProc The parser allocator
* @return
*/
void *ParseAlloc(void *(*mallocProc)(size_t));
/**
*
* @param str sql string
* @return sql ast
*/
SSqlInfo doGenerateAST(const char *str);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_ASTGENERATOR_H

View File

@ -1,32 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_ASTTOMSG_H
#define TDENGINE_ASTTOMSG_H
#include "parserInt.h"
#include "tmsg.h"
char* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen);
char* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen);
char* buildDropUserMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen);
char* buildShowMsg(SShowInfo* pShowInfo, int32_t* outputLen, SParseContext* pParseCtx, SMsgBuf* pMsgBuf);
char* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, int32_t* outputLen, SParseContext* pCtx, SMsgBuf* pMsgBuf);
char* buildCreateStbReq(SCreateTableSql* pCreateTableSql, int32_t* outputLen, SParseContext* pParseCtx, SMsgBuf* pMsgBuf);
char* buildDropStableReq(SSqlInfo* pInfo, int32_t* outputLen, SParseContext* pParseCtx, SMsgBuf* pMsgBuf);
char* buildCreateDnodeMsg(SSqlInfo* pInfo, int32_t* outputLen, SMsgBuf* pMsgBuf);
char* buildDropDnodeMsg(SSqlInfo* pInfo, int32_t* outputLen, SMsgBuf* pMsgBuf);
#endif // TDENGINE_ASTTOMSG_H

View File

@ -22,7 +22,7 @@ extern "C" {
#include "parser.h"
int32_t parseInsertSql(SParseContext* pContext, SVnodeModifOpStmtInfo** pInfo);
int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery);
#ifdef __cplusplus
}

View File

@ -20,11 +20,11 @@
extern "C" {
#endif
#include "querynodes.h"
#include "newParser.h"
#include "parser.h"
int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery);
int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery);
int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery);
int32_t parseQuerySql(SParseContext* pCxt, SQuery** pQuery);
#ifdef __cplusplus
}

View File

@ -1,113 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_PARSER_INT_H_
#define _TD_PARSER_INT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "catalog.h"
#include "tname.h"
#include "astGenerator.h"
struct SSqlNode;
typedef struct SInternalField {
TAOS_FIELD field;
bool visible;
SExprInfo *pExpr;
} SInternalField;
typedef struct SMsgBuf {
int32_t len;
char *buf;
} SMsgBuf;
void clearTableMetaInfo(STableMetaInfo* pTableMetaInfo);
void clearAllTableMetaInfo(SQueryStmtInfo* pQueryInfo, bool removeMeta, uint64_t id);
/**
* Validate the sql info, according to the corresponding metadata info from catalog.
* @param pCtx
* @param pInfo
* @param pQueryInfo
* @param msgBuf
* @param msgBufLen
* @return
*/
int32_t qParserValidateSqlNode(SParseContext *pCtx, SSqlInfo* pInfo, SQueryStmtInfo* pQueryInfo, char* msgBuf, int32_t msgBufLen);
/**
* validate the ddl ast, and convert the ast to the corresponding message format
* @param pSqlInfo
* @param output
* @param type
* @return
*/
SDclStmtInfo* qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseContext* pCtx, char* msgBuf, int32_t msgBufLen);
/**
*
* @param pInfo
* @param pCtx
* @param msgBuf
* @param msgBufLen
* @return
*/
SVnodeModifOpStmtInfo* qParserValidateCreateTbSqlNode(SSqlInfo* pInfo, SParseContext* pCtx, char* msgBuf, int32_t msgBufLen);
/**
* Evaluate the numeric and timestamp arithmetic expression in the WHERE clause.
* @param pNode
* @param tsPrecision
* @param msg
* @param msgBufLen
* @return
*/
int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf);
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
SQueryStmtInfo* createQueryInfo();
void destroyQueryInfo(SQueryStmtInfo* pQueryInfo);
int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
/**
* Extract request meta info from the sql statement
* @param pSqlInfo
* @param pMetaInfo
* @param msg
* @param msgBufLen
* @return
*/
int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SCatalogReq* pMetaInfo, SParseContext *pCtx, char* msg, int32_t msgBufLen);
/**
* Destroy the meta data request structure.
* @param pMetaInfo
*/
void qParserCleanupMetaRequestInfo(SCatalogReq* pMetaInfo);
#ifdef __cplusplus
}
#endif
#endif /*_TD_PARSER_INT_H_*/

View File

@ -21,54 +21,19 @@ extern "C" {
#endif
#include "os.h"
#include "query.h"
#include "tmsg.h"
#include "ttoken.h"
#include "parserInt.h"
#define UTIL_TABLE_IS_SUPER_TABLE(metaInfo) \
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_SUPER_TABLE))
#define UTIL_TABLE_IS_CHILD_TABLE(metaInfo) \
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_CHILD_TABLE))
#define UTIL_TABLE_IS_NORMAL_TABLE(metaInfo) \
(!(UTIL_TABLE_IS_SUPER_TABLE(metaInfo) || UTIL_TABLE_IS_CHILD_TABLE(metaInfo)))
#define UTIL_TABLE_IS_TMP_TABLE(metaInfo) \
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE))
TAOS_FIELD createField(const SSchema* pSchema);
void setColumn(SColumn* pColumn, uint64_t uid, const char* tableName, int8_t flag, const SSchema* pSchema);
SColumn createColumn(uint64_t uid, const char* tableName, int8_t flag, const SSchema* pSchema);
SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, SSchema* field);
int32_t getNumOfFields(SFieldInfo* pFieldInfo);
SInternalField* getInternalField(SFieldInfo* pFieldInfo, int32_t index);
int32_t parserValidateIdToken(SToken* pToken);
int32_t parserValidatePassword(SToken* pToken, SMsgBuf* pMsgBuf);
int32_t parserValidateNameToken(SToken* pToken);
typedef struct SMsgBuf {
int32_t len;
char *buf;
} SMsgBuf;
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr);
STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
void columnListCopyAll(SArray* dst, const SArray* src);
SColumn* columnListInsert(SArray* pColumnList, uint64_t uid, SSchema* pSchema, int32_t flag);
SColumn* insertPrimaryTsColumn(SArray* pColumnList, const char* colName, uint64_t tableUid);
void cleanupTagCond(STagCond* pTagCond);
void cleanupColumnCond(SArray** pCond);
uint32_t convertRelationalOperator(SToken *pToken);
int32_t getExprFunctionId(SExprInfo *pExprInfo);
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
bool isDclSqlStatement(SSqlInfo* pSqlInfo);
bool isDdlSqlStatement(SSqlInfo* pSqlInfo);
bool isDqlSqlStatement(SSqlInfo* pSqlInfo);
int32_t parserValidateIdToken(SToken* pToken);
typedef struct SKvParam {
SKVRowBuilder *builder;
@ -78,10 +43,12 @@ typedef struct SKvParam {
int32_t KvRowAppend(const void *value, int32_t len, void *param);
typedef int32_t (*_row_append_fn_t)(const void *value, int32_t len, void *param);
int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, char* tmpTokenBuf, _row_append_fn_t func, void* param, SMsgBuf* pMsgBuf);
int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pParseCtx, SMsgBuf* pMsgBuf);
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
SSchema *getTableColumnSchema(const STableMeta *pTableMeta);
SSchema *getTableTagSchema(const STableMeta* pTableMeta);
int32_t getNumOfColumns(const STableMeta* pTableMeta);
int32_t getNumOfTags(const STableMeta* pTableMeta);
STableComInfo getTableInfo(const STableMeta* pTableMeta);
#ifdef __cplusplus
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_QUERYINFOUTIL_H
#define TDENGINE_QUERYINFOUTIL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "parserInt.h"
SSchema* getTbnameColumnSchema();
int32_t getNumOfColumns(const STableMeta* pTableMeta);
int32_t getNumOfTags(const STableMeta* pTableMeta);
SSchema *getTableColumnSchema(const STableMeta *pTableMeta);
SSchema *getTableTagSchema(const STableMeta* pTableMeta);
SArray *getCurrentExprList(SQueryStmtInfo* pQueryInfo);
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
void addExprInfo(SArray* pExprList, int32_t index, SExprInfo* pExprInfo, int32_t level);
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize);
SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index);
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
void cleanupFieldInfo(SFieldInfo* pFieldInfo);
STableComInfo getTableInfo(const STableMeta* pTableMeta);
SArray *extractFunctionList(SArray* pExprInfoList);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_QUERYINFOUTIL_H

File diff suppressed because it is too large Load Diff

View File

@ -1,520 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "astGenerator.h"
#include "parserInt.h"
#include "parserUtil.h"
char* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen) {
SCreateUserReq createReq = {0};
SUserInfo* pUser = &pInfo->pMiscInfo->user;
strncpy(createReq.user, pUser->user.z, pUser->user.n);
createReq.createType = pUser->type;
createReq.superUser = (int8_t)pUser->type;
if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
// pMsg->privilege = (char)pCmd->count;
} else {
strncpy(createReq.pass, pUser->passwd.z, pUser->passwd.n);
}
int32_t tlen = tSerializeSCreateUserReq(NULL, 0, &createReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSCreateUserReq(pReq, tlen, &createReq);
*outputLen = tlen;
return pReq;
}
char* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen) {
SCreateAcctReq createReq = {0};
SToken* pName = &pInfo->pMiscInfo->user.user;
SToken* pPwd = &pInfo->pMiscInfo->user.passwd;
strncpy(createReq.user, pName->z, pName->n);
strncpy(createReq.pass, pPwd->z, pPwd->n);
SCreateAcctInfo* pAcctOpt = &pInfo->pMiscInfo->acctOpt;
createReq.maxUsers = pAcctOpt->maxUsers;
createReq.maxDbs = pAcctOpt->maxDbs;
createReq.maxTimeSeries = pAcctOpt->maxTimeSeries;
createReq.maxStreams = pAcctOpt->maxStreams;
createReq.maxStorage = pAcctOpt->maxStorage;
if (pAcctOpt->stat.n == 0) {
createReq.accessState = -1;
} else {
if (pAcctOpt->stat.z[0] == 'r' && pAcctOpt->stat.n == 1) {
createReq.accessState = TSDB_VN_READ_ACCCESS;
} else if (pAcctOpt->stat.z[0] == 'w' && pAcctOpt->stat.n == 1) {
createReq.accessState = TSDB_VN_WRITE_ACCCESS;
} else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) {
createReq.accessState = TSDB_VN_ALL_ACCCESS;
} else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) {
createReq.accessState = 0;
}
}
int32_t tlen = tSerializeSCreateAcctReq(NULL, 0, &createReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSCreateAcctReq(pReq, tlen, &createReq);
*outputLen = tlen;
return pReq;
}
char* buildDropUserMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgBufLen) {
SDropUserReq dropReq = {0};
SToken* pName = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (pName->n >= TSDB_USER_LEN) {
return NULL;
}
strncpy(dropReq.user, pName->z, pName->n);
int32_t tlen = tSerializeSDropUserReq(NULL, 0, &dropReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSDropUserReq(pReq, tlen, &dropReq);
*outputLen = tlen;
return pReq;
}
char* buildShowMsg(SShowInfo* pShowInfo, int32_t* outputLen, SParseContext* pCtx, SMsgBuf* pMsgBuf) {
SShowReq showReq = {.type = pShowInfo->showType};
if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) {
SToken* pPattern = &pShowInfo->pattern;
if (pPattern->type > 0) { // only show tables support wildcard query
showReq.payloadLen = pPattern->n;
showReq.payload = malloc(showReq.payloadLen);
strncpy(showReq.payload, pPattern->z, pPattern->n);
}
} else {
SToken* pEpAddr = &pShowInfo->prefix;
assert(pEpAddr->n > 0 && pEpAddr->type > 0);
showReq.payloadLen = pEpAddr->n;
showReq.payload = malloc(showReq.payloadLen);
strncpy(showReq.payload, pEpAddr->z, pEpAddr->n);
}
if (pShowInfo->showType == TSDB_MGMT_TABLE_STB || pShowInfo->showType == TSDB_MGMT_TABLE_VGROUP) {
SName n = {0};
if (pShowInfo->prefix.n > 0) {
if (pShowInfo->prefix.n >= TSDB_DB_FNAME_LEN) {
terrno = buildInvalidOperationMsg(pMsgBuf, "prefix name is too long");
tFreeSShowReq(&showReq);
return NULL;
}
tNameSetDbName(&n, pCtx->acctId, pShowInfo->prefix.z, pShowInfo->prefix.n);
} else if (pCtx->db == NULL || strlen(pCtx->db) == 0) {
terrno = buildInvalidOperationMsg(pMsgBuf, "database is not specified");
tFreeSShowReq(&showReq);
return NULL;
} else {
tNameSetDbName(&n, pCtx->acctId, pCtx->db, strlen(pCtx->db));
}
tNameGetFullDbName(&n, showReq.db);
}
int32_t tlen = tSerializeSShowReq(NULL, 0, &showReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSShowReq(pReq, tlen, &showReq);
tFreeSShowReq(&showReq);
*outputLen = tlen;
return pReq;
}
static int32_t setKeepOption(SCreateDbReq* pMsg, const SCreateDbInfo* pCreateDb, SMsgBuf* pMsgBuf) {
const char* msg1 = "invalid number of keep options";
const char* msg2 = "invalid keep value";
const char* msg3 = "invalid keep value, should be keep0 <= keep1 <= keep2";
pMsg->daysToKeep0 = -1;
pMsg->daysToKeep1 = -1;
pMsg->daysToKeep2 = -1;
SArray* pKeep = pCreateDb->keep;
if (pKeep != NULL) {
size_t s = taosArrayGetSize(pKeep);
#ifdef _STORAGE
if (s >= 4 || s <= 0) {
#else
if (s != 1) {
#endif
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
// tListI* p0 = taosArrayGet(pKeep, 0);
// tVariantListItem* p1 = (s > 1) ? taosArrayGet(pKeep, 1) : p0;
// tVariantListItem* p2 = (s > 2) ? taosArrayGet(pKeep, 2) : p1;
//
// if ((int32_t)p0->pVar.i64 <= 0 || (int32_t)p1->pVar.i64 <= 0 || (int32_t)p2->pVar.i64 <= 0) {
// return buildInvalidOperationMsg(pMsgBuf, msg2);
// }
// if (!(((int32_t)p0->pVar.i64 <= (int32_t)p1->pVar.i64) && ((int32_t)p1->pVar.i64 <= (int32_t)p2->pVar.i64))) {
// return buildInvalidOperationMsg(pMsgBuf, msg3);
// }
//
// pMsg->daysToKeep0 = htonl((int32_t)p0->pVar.i64);
// pMsg->daysToKeep1 = htonl((int32_t)p1->pVar.i64);
// pMsg->daysToKeep2 = htonl((int32_t)p2->pVar.i64);
}
return TSDB_CODE_SUCCESS;
}
static int32_t setTimePrecision(SCreateDbReq* pMsg, const SCreateDbInfo* pCreateDbInfo, SMsgBuf* pMsgBuf) {
const char* msg = "invalid time precision";
pMsg->precision = TSDB_TIME_PRECISION_MILLI; // millisecond by default
SToken* pToken = (SToken*)&pCreateDbInfo->precision;
if (pToken->n > 0) {
pToken->n = strdequote(pToken->z);
if (strncmp(pToken->z, TSDB_TIME_PRECISION_MILLI_STR, pToken->n) == 0 &&
strlen(TSDB_TIME_PRECISION_MILLI_STR) == pToken->n) {
// time precision for this db: million second
pMsg->precision = TSDB_TIME_PRECISION_MILLI;
} else if (strncmp(pToken->z, TSDB_TIME_PRECISION_MICRO_STR, pToken->n) == 0 &&
strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
pMsg->precision = TSDB_TIME_PRECISION_MICRO;
} else if (strncmp(pToken->z, TSDB_TIME_PRECISION_NANO_STR, pToken->n) == 0 &&
strlen(TSDB_TIME_PRECISION_NANO_STR) == pToken->n) {
pMsg->precision = TSDB_TIME_PRECISION_NANO;
} else {
return buildInvalidOperationMsg(pMsgBuf, msg);
}
}
return TSDB_CODE_SUCCESS;
}
static void doSetDbOptions(SCreateDbReq* pMsg, const SCreateDbInfo* pCreateDb) {
pMsg->cacheBlockSize = pCreateDb->cacheBlockSize;
pMsg->totalBlocks = pCreateDb->numOfBlocks;
pMsg->daysPerFile = pCreateDb->daysPerFile;
pMsg->commitTime = (int32_t)pCreateDb->commitTime;
pMsg->minRows = pCreateDb->minRowsPerBlock;
pMsg->maxRows = pCreateDb->maxRowsPerBlock;
pMsg->fsyncPeriod = pCreateDb->fsyncPeriod;
pMsg->compression = (int8_t)pCreateDb->compressionLevel;
pMsg->walLevel = (char)pCreateDb->walLevel;
pMsg->replications = pCreateDb->replica;
pMsg->quorum = pCreateDb->quorum;
pMsg->ignoreExist = pCreateDb->ignoreExists;
pMsg->update = pCreateDb->update;
pMsg->cacheLastRow = pCreateDb->cachelast;
pMsg->numOfVgroups = pCreateDb->numOfVgroups;
pMsg->streamMode = pCreateDb->streamMode;
}
int32_t setDbOptions(SCreateDbReq* pCreateDbMsg, const SCreateDbInfo* pCreateDbSql, SMsgBuf* pMsgBuf) {
doSetDbOptions(pCreateDbMsg, pCreateDbSql);
if (setKeepOption(pCreateDbMsg, pCreateDbSql, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (setTimePrecision(pCreateDbMsg, pCreateDbSql, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
return TSDB_CODE_SUCCESS;
}
// can only perform the parameters based on the macro definitation
static int32_t doCheckDbOptions(SCreateDbReq* pCreate, SMsgBuf* pMsgBuf) {
char msg[512] = {0};
if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) {
snprintf(msg, tListLen(msg), "invalid db option walLevel: %d, only 1-2 allowed", pCreate->walLevel);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
if (pCreate->replications != -1 &&
(pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
int32_t blocks = pCreate->totalBlocks;
if (blocks != -1 && (blocks < TSDB_MIN_TOTAL_BLOCKS || blocks > TSDB_MAX_TOTAL_BLOCKS)) {
snprintf(msg, tListLen(msg), "invalid db option totalBlocks: %d valid range: [%d, %d]", blocks,
TSDB_MIN_TOTAL_BLOCKS, TSDB_MAX_TOTAL_BLOCKS);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
if (pCreate->quorum != -1 &&
(pCreate->quorum < TSDB_MIN_DB_QUORUM_OPTION || pCreate->quorum > TSDB_MAX_DB_QUORUM_OPTION)) {
snprintf(msg, tListLen(msg), "invalid db option quorum: %d valid range: [%d, %d]", pCreate->quorum,
TSDB_MIN_DB_QUORUM_OPTION, TSDB_MAX_DB_QUORUM_OPTION);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
int32_t val = pCreate->daysPerFile;
if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val, TSDB_MIN_DAYS_PER_FILE,
TSDB_MAX_DAYS_PER_FILE);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
val = pCreate->cacheBlockSize;
if (val != -1 && (val < TSDB_MIN_CACHE_BLOCK_SIZE || val > TSDB_MAX_CACHE_BLOCK_SIZE)) {
snprintf(msg, tListLen(msg), "invalid db option cacheBlockSize: %d valid range: [%d, %d]", val,
TSDB_MIN_CACHE_BLOCK_SIZE, TSDB_MAX_CACHE_BLOCK_SIZE);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
if (pCreate->precision != TSDB_TIME_PRECISION_MILLI && pCreate->precision != TSDB_TIME_PRECISION_MICRO &&
pCreate->precision != TSDB_TIME_PRECISION_NANO) {
snprintf(msg, tListLen(msg), "invalid db option timePrecision: %d valid value: [%d, %d, %d]", pCreate->precision,
TSDB_TIME_PRECISION_MILLI, TSDB_TIME_PRECISION_MICRO, TSDB_TIME_PRECISION_NANO);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
val = pCreate->commitTime;
if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val, TSDB_MIN_COMMIT_TIME,
TSDB_MAX_COMMIT_TIME);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
val = pCreate->fsyncPeriod;
if (val != -1 && (val < TSDB_MIN_FSYNC_PERIOD || val > TSDB_MAX_FSYNC_PERIOD)) {
snprintf(msg, tListLen(msg), "invalid db option fsyncPeriod: %d valid range: [%d, %d]", val, TSDB_MIN_FSYNC_PERIOD,
TSDB_MAX_FSYNC_PERIOD);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
if (pCreate->compression != -1 &&
(pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
return buildInvalidOperationMsg(pMsgBuf, msg);
}
val = pCreate->numOfVgroups;
if (val < TSDB_MIN_VNODES_PER_DB || val > TSDB_MAX_VNODES_PER_DB) {
snprintf(msg, tListLen(msg), "invalid number of vgroups for DB:%d valid range: [%d, %d]", val,
TSDB_MIN_VNODES_PER_DB, TSDB_MAX_VNODES_PER_DB);
}
val = pCreate->maxRows;
if (val < TSDB_MIN_MAX_ROW_FBLOCK || val > TSDB_MAX_MAX_ROW_FBLOCK) {
snprintf(msg, tListLen(msg), "invalid number of max rows in file block for DB:%d valid range: [%d, %d]", val,
TSDB_MIN_MAX_ROW_FBLOCK, TSDB_MAX_MAX_ROW_FBLOCK);
}
val = pCreate->minRows;
if (val < TSDB_MIN_MIN_ROW_FBLOCK || val > TSDB_MAX_MIN_ROW_FBLOCK) {
snprintf(msg, tListLen(msg), "invalid number of min rows in file block for DB:%d valid range: [%d, %d]", val,
TSDB_MIN_MIN_ROW_FBLOCK, TSDB_MAX_MIN_ROW_FBLOCK);
}
return TSDB_CODE_SUCCESS;
}
char* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, int32_t* outputLen, SParseContext* pCtx, SMsgBuf* pMsgBuf) {
SCreateDbReq createReq = {0};
if (setDbOptions(&createReq, pCreateDbInfo, pMsgBuf) != TSDB_CODE_SUCCESS) {
terrno = TSDB_CODE_TSC_INVALID_OPERATION;
return NULL;
}
SName name = {0};
int32_t ret = tNameSetDbName(&name, pCtx->acctId, pCreateDbInfo->dbname.z, pCreateDbInfo->dbname.n);
if (ret != TSDB_CODE_SUCCESS) {
terrno = ret;
return NULL;
}
tNameGetFullDbName(&name, createReq.db);
if (doCheckDbOptions(&createReq, pMsgBuf) != TSDB_CODE_SUCCESS) {
terrno = TSDB_CODE_TSC_INVALID_OPERATION;
return NULL;
}
int32_t tlen = tSerializeSCreateDbReq(NULL, 0, &createReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSCreateDbReq(pReq, tlen, &createReq);
*outputLen = tlen;
return pReq;
}
char* buildCreateStbReq(SCreateTableSql* pCreateTableSql, int32_t* outputLen, SParseContext* pParseCtx,
SMsgBuf* pMsgBuf) {
SMCreateStbReq createReq = {0};
createReq.igExists = pCreateTableSql->existCheck ? 1 : 0;
createReq.pColumns = pCreateTableSql->colInfo.pColumns;
createReq.pTags = pCreateTableSql->colInfo.pTagColumns;
createReq.numOfColumns = (int32_t)taosArrayGetSize(pCreateTableSql->colInfo.pColumns);
createReq.numOfTags = (int32_t)taosArrayGetSize(pCreateTableSql->colInfo.pTagColumns);
SName n = {0};
if (createSName(&n, &pCreateTableSql->name, pParseCtx, pMsgBuf) != 0) {
return NULL;
}
if (tNameExtractFullName(&n, createReq.name) != 0) {
buildInvalidOperationMsg(pMsgBuf, "invalid table name or database not specified");
return NULL;
}
int32_t tlen = tSerializeSMCreateStbReq(NULL, 0, &createReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSMCreateStbReq(pReq, tlen, &createReq);
*outputLen = tlen;
return pReq;
}
char* buildDropStableReq(SSqlInfo* pInfo, int32_t* outputLen, SParseContext* pParseCtx, SMsgBuf* pMsgBuf) {
SToken* tableName = taosArrayGet(pInfo->pMiscInfo->a, 0);
SName name = {0};
int32_t code = createSName(&name, tableName, pParseCtx, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
terrno = buildInvalidOperationMsg(pMsgBuf, "invalid table name");
return NULL;
}
SMDropStbReq dropReq = {0};
code = tNameExtractFullName(&name, dropReq.name);
assert(code == TSDB_CODE_SUCCESS && name.type == TSDB_TABLE_NAME_T);
dropReq.igNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0;
int32_t tlen = tSerializeSMDropStbReq(NULL, 0, &dropReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSMDropStbReq(pReq, tlen, &dropReq);
*outputLen = tlen;
return pReq;
}
char* buildCreateDnodeMsg(SSqlInfo* pInfo, int32_t* outputLen, SMsgBuf* pMsgBuf) {
const char* msg1 = "invalid host name (name too long, maximum length 128)";
const char* msg2 = "dnode name can not be string";
const char* msg3 = "port should be an integer that is less than 65535 and greater than 0";
const char* msg4 = "failed prepare create dnode message";
if (taosArrayGetSize(pInfo->pMiscInfo->a) != 2) {
buildInvalidOperationMsg(pMsgBuf, msg1);
return NULL;
}
SToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (id->type != TK_ID && id->type != TK_IPTOKEN) {
buildInvalidOperationMsg(pMsgBuf, msg2);
return NULL;
}
SToken* port = taosArrayGet(pInfo->pMiscInfo->a, 1);
if (port->type != TK_INTEGER) {
buildInvalidOperationMsg(pMsgBuf, msg3);
return NULL;
}
bool isSign = false;
int64_t val = 0;
toInteger(port->z, port->n, 10, &val, &isSign);
if (val >= UINT16_MAX || val <= 0) {
buildInvalidOperationMsg(pMsgBuf, msg3);
return NULL;
}
SCreateDnodeReq createReq = {0};
strncpy(createReq.fqdn, id->z, id->n);
createReq.port = val;
int32_t tlen = tSerializeSCreateDnodeReq(NULL, 0, &createReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSCreateDnodeReq(pReq, tlen, &createReq);
*outputLen = tlen;
return pReq;
}
char* buildDropDnodeMsg(SSqlInfo* pInfo, int32_t* outputLen, SMsgBuf* pMsgBuf) {
SDropDnodeReq dropReq = {0};
SToken* pzName = taosArrayGet(pInfo->pMiscInfo->a, 0);
char* end = NULL;
dropReq.dnodeId = strtoll(pzName->z, &end, 10);
if (end - pzName->z != pzName->n) {
buildInvalidOperationMsg(pMsgBuf, "invalid dnode id");
return NULL;
}
int32_t tlen = tSerializeSDropDnodeReq(NULL, 0, &dropReq);
void* pReq = malloc(tlen);
if (pReq == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
tSerializeSDropDnodeReq(pReq, tlen, &dropReq);
*outputLen = tlen;
return pReq;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,901 +0,0 @@
#include "tmsg.h"
#include "tglobal.h"
#include "parserInt.h"
#include "ttime.h"
#include "astToMsg.h"
#include "astGenerator.h"
#include "parserUtil.h"
#include "queryInfoUtil.h"
/* is contained in pFieldList or not */
static bool has(SArray* pFieldList, int32_t startIndex, const char* name) {
size_t numOfCols = taosArrayGetSize(pFieldList);
for (int32_t j = startIndex; j < numOfCols; ++j) {
TAOS_FIELD* field = taosArrayGet(pFieldList, j);
if (strncasecmp(name, field->name, sizeof(field->name) - 1) == 0) return true;
}
return false;
}
static int32_t setShowInfo(SShowInfo* pShowInfo, SParseContext* pCtx, void** output, int32_t* outputLen,
SEpSet* pEpSet, void** pExtension, SMsgBuf* pMsgBuf) {
const char* msg1 = "invalid name";
const char* msg2 = "wildcard string should be less than %d characters";
const char* msg3 = "database name too long";
const char* msg4 = "pattern is invalid";
const char* msg5 = "database name is empty";
const char* msg6 = "pattern string is empty";
const char* msg7 = "database not specified";
/*
* database prefix in pInfo->pMiscInfo->a[0]
* wildcard in like clause in pInfo->pMiscInfo->a[1]
*/
int16_t showType = pShowInfo->showType;
if (showType == TSDB_MGMT_TABLE_TABLE) {
SArray* array = NULL;
SName name = {0};
if (pCtx->db == NULL && pShowInfo->prefix.n == 0) {
return buildInvalidOperationMsg(pMsgBuf, msg7);
}
SVShowTablesReq* pShowReq = calloc(1, sizeof(SVShowTablesReq));
if (pShowInfo->prefix.n > 0) {
tNameSetDbName(&name, pCtx->acctId, pShowInfo->prefix.z, pShowInfo->prefix.n);
} else {
tNameSetDbName(&name, pCtx->acctId, pCtx->db, strlen(pCtx->db));
}
char dbFname[TSDB_DB_FNAME_LEN] = {0};
tNameGetFullDbName(&name, dbFname);
int32_t code = catalogGetDBVgInfo(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, dbFname, false, &array);
if (code != TSDB_CODE_SUCCESS) {
terrno = code;
return code;
}
SVgroupInfo* info = taosArrayGet(array, 0);
pShowReq->head.vgId = htonl(info->vgId);
*pEpSet = info->epset;
*outputLen = sizeof(SVShowTablesReq);
*output = pShowReq;
*pExtension = array;
} else {
if (showType == TSDB_MGMT_TABLE_STB || showType == TSDB_MGMT_TABLE_VGROUP) {
SToken* pDbPrefixToken = &pShowInfo->prefix;
if (pDbPrefixToken->type != 0) {
if (pDbPrefixToken->n >= TSDB_DB_NAME_LEN) { // db name is too long
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
if (pDbPrefixToken->n <= 0) {
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
if (parserValidateIdToken(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
// int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pRequest->pTsc), pDbPrefixToken);
// if (ret != TSDB_CODE_SUCCESS) {
// return buildInvalidOperationMsg(pMsgBuf, msg1);
// }
}
// show table/stable like 'xxxx', set the like pattern for show tables
SToken* pPattern = &pShowInfo->pattern;
if (pPattern->type != 0) {
if (pPattern->type == TK_ID && pPattern->z[0] == TS_ESCAPE_CHAR) {
return buildInvalidOperationMsg(pMsgBuf, msg4);
}
pPattern->n = strdequote(pPattern->z);
if (pPattern->n <= 0) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
if (pPattern->n > tsMaxWildCardsLen) {
char tmp[64] = {0};
sprintf(tmp, msg2, tsMaxWildCardsLen);
return buildInvalidOperationMsg(pMsgBuf, tmp);
}
}
} else if (showType == TSDB_MGMT_TABLE_VNODES) {
if (pShowInfo->prefix.type == 0) {
return buildInvalidOperationMsg(pMsgBuf, "No specified dnode ep");
}
if (pShowInfo->prefix.type == TK_STRING) {
pShowInfo->prefix.n = strdequote(pShowInfo->prefix.z);
}
}
*pEpSet = pCtx->mgmtEpSet;
*output = buildShowMsg(pShowInfo, outputLen, pCtx, pMsgBuf);
if (*output == NULL) {
return terrno;
}
}
return TSDB_CODE_SUCCESS;
}
static int32_t validateTableColumns(SArray* pFieldList, int32_t maxRowLength, int32_t maxColumns, SMsgBuf* pMsgBuf) {
const char* msg2 = "row length exceeds max length";
const char* msg3 = "duplicated column names";
const char* msg4 = "invalid data type";
const char* msg5 = "invalid binary/nchar column length";
const char* msg6 = "invalid column name";
const char* msg7 = "too many columns";
const char* msg8 = "illegal number of columns";
size_t numOfCols = taosArrayGetSize(pFieldList);
if (numOfCols > maxColumns) {
return buildInvalidOperationMsg(pMsgBuf, msg7);
}
int32_t rowLen = 0;
for (int32_t i = 0; i < numOfCols; ++i) {
TAOS_FIELD* pField = taosArrayGet(pFieldList, i);
if (!isValidDataType(pField->type)) {
return buildInvalidOperationMsg(pMsgBuf, msg4);
}
if (pField->bytes == 0) {
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
if ((pField->type == TSDB_DATA_TYPE_BINARY && (pField->bytes <= 0 || pField->bytes > TSDB_MAX_BINARY_LEN)) ||
(pField->type == TSDB_DATA_TYPE_NCHAR && (pField->bytes <= 0 || pField->bytes > TSDB_MAX_NCHAR_LEN))) {
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
SToken nameToken = {.z = pField->name, .n = strlen(pField->name), .type = TK_ID};
if (parserValidateNameToken(&nameToken) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
// field name must be unique
if (has(pFieldList, i + 1, pField->name) == true) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
rowLen += pField->bytes;
}
// max row length must be less than TSDB_MAX_BYTES_PER_ROW
if (rowLen > maxRowLength) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
return TSDB_CODE_SUCCESS;
}
static int32_t validateTableColumnInfo(SArray* pFieldList, SMsgBuf* pMsgBuf) {
assert(pFieldList != NULL && pMsgBuf != NULL);
const char* msg1 = "first column must be timestamp";
const char* msg2 = "illegal number of columns";
// first column must be timestamp
SField* pField = taosArrayGet(pFieldList, 0);
if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
// number of fields no less than 2
size_t numOfCols = taosArrayGetSize(pFieldList);
if (numOfCols <= 1) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
return validateTableColumns(pFieldList, TSDB_MAX_BYTES_PER_ROW, TSDB_MAX_COLUMNS, pMsgBuf);
}
static int32_t validateTagParams(SArray* pTagsList, SArray* pFieldList, SMsgBuf* pMsgBuf) {
assert(pTagsList != NULL);
const char* msg1 = "invalid number of tag columns";
const char* msg3 = "duplicated column names";
// number of fields at least 1
size_t numOfTags = taosArrayGetSize(pTagsList);
if (numOfTags < 1) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
// field name must be unique
for (int32_t i = 0; i < numOfTags; ++i) {
SField* p = taosArrayGet(pTagsList, i);
if (has(pFieldList, 0, p->name) == true) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
}
return validateTableColumns(pFieldList, TSDB_MAX_TAGS_LEN, TSDB_MAX_TAGS, pMsgBuf);
}
int32_t doCheckForCreateTable(SCreateTableSql* pCreateTable, SMsgBuf* pMsgBuf) {
const char* msg1 = "invalid table name";
SArray* pFieldList = pCreateTable->colInfo.pColumns;
SArray* pTagList = pCreateTable->colInfo.pTagColumns;
assert(pFieldList != NULL);
// if sql specifies db, use it, otherwise use default db
SToken* pNameToken = &(pCreateTable->name);
if (parserValidateIdToken(pNameToken) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
if (validateTableColumnInfo(pFieldList, pMsgBuf) != TSDB_CODE_SUCCESS ||
(pTagList != NULL && validateTagParams(pTagList, pFieldList, pMsgBuf) != TSDB_CODE_SUCCESS)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
return TSDB_CODE_SUCCESS;
}
typedef struct SVgroupTablesBatch {
SVCreateTbBatchReq req;
SVgroupInfo info;
} SVgroupTablesBatch;
static SArray* doSerializeVgroupCreateTableInfo(SHashObj* pVgroupHashmap);
static int32_t doParseSerializeTagValue(SSchema* pTagSchema, int32_t numOfInputTag, SKVRowBuilder* pKvRowBuilder,
SArray* pTagValList, int32_t tsPrecision, SMsgBuf* pMsgBuf) {
const char* msg1 = "illegal value or data overflow";
int32_t code = TSDB_CODE_SUCCESS;
for (int32_t i = 0; i < numOfInputTag; ++i) {
SSchema* pSchema = &pTagSchema[i];
char* endPtr = NULL;
char tmpTokenBuf[TSDB_MAX_TAGS_LEN] = {0};
SKvParam param = {.builder = pKvRowBuilder, .schema = pSchema};
SToken* pItem = taosArrayGet(pTagValList, i);
code = parseValueToken(&endPtr, pItem, pSchema, tsPrecision, tmpTokenBuf, KvRowAppend, &param, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
}
return code;
}
static void addCreateTbReqIntoVgroup(SHashObj* pVgroupHashmap, const SName* pTableName, SKVRow row, uint64_t suid, SVgroupInfo* pVgInfo) {
struct SVCreateTbReq req = {0};
req.type = TD_CHILD_TABLE;
req.name = strdup(tNameGetTableName(pTableName));
req.ctbCfg.suid = suid;
req.ctbCfg.pTag = row;
SVgroupTablesBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId));
if (pTableBatch == NULL) {
SVgroupTablesBatch tBatch = {0};
tBatch.info = *pVgInfo;
tBatch.req.pArray = taosArrayInit(4, sizeof(struct SVCreateTbReq));
taosArrayPush(tBatch.req.pArray, &req);
taosHashPut(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId), &tBatch, sizeof(tBatch));
} else { // add to the correct vgroup
assert(pVgInfo->vgId == pTableBatch->info.vgId);
taosArrayPush(pTableBatch->req.pArray, &req);
}
}
static void destroyCreateTbReqBatch(SVgroupTablesBatch* pTbBatch) {
size_t size = taosArrayGetSize(pTbBatch->req.pArray);
for(int32_t i = 0; i < size; ++i) {
SVCreateTbReq* pTableReq = taosArrayGet(pTbBatch->req.pArray, i);
tfree(pTableReq->name);
if (pTableReq->type == TSDB_NORMAL_TABLE) {
tfree(pTableReq->ntbCfg.pSchema);
} else if (pTableReq->type == TSDB_CHILD_TABLE) {
tfree(pTableReq->ctbCfg.pTag);
} else {
assert(0);
}
}
taosArrayDestroy(pTbBatch->req.pArray);
}
static int32_t doCheckAndBuildCreateCTableReq(SCreateTableSql* pCreateTable, SParseContext* pCtx, SMsgBuf* pMsgBuf, SArray** pBufArray) {
const char* msg1 = "invalid table name";
const char* msg2 = "tags number not matched";
const char* msg3 = "tag value too long";
const char* msg4 = "illegal value or data overflow";
int32_t code = 0;
STableMeta* pSuperTableMeta = NULL;
SHashObj* pVgroupHashmap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
// super table name, create table by using dst
size_t numOfTables = taosArrayGetSize(pCreateTable->childTableInfo);
for (int32_t j = 0; j < numOfTables; ++j) {
SCreatedTableInfo* pCreateTableInfo = taosArrayGet(pCreateTable->childTableInfo, j);
SToken* pSTableNameToken = &pCreateTableInfo->stbName;
code = parserValidateNameToken(pSTableNameToken);
if (code != TSDB_CODE_SUCCESS) {
code = buildInvalidOperationMsg(pMsgBuf, msg1);
goto _error;
}
SName name = {0};
code = createSName(&name, pSTableNameToken, pCtx, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
SKVRowBuilder kvRowBuilder = {0};
if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
goto _error;
}
SArray* pValList = pCreateTableInfo->pTagVals;
size_t numOfInputTag = taosArrayGetSize(pValList);
code = catalogGetTableMeta(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, &name, &pSuperTableMeta);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
assert(pSuperTableMeta != NULL);
// too long tag values will return invalid sql, not be truncated automatically
SSchema* pTagSchema = getTableTagSchema(pSuperTableMeta);
STableComInfo tinfo = getTableInfo(pSuperTableMeta);
SArray* pNameList = NULL;
size_t numOfBoundTags = 0;
int32_t schemaSize = getNumOfTags(pSuperTableMeta);
if (pCreateTableInfo->pTagNames) {
pNameList = pCreateTableInfo->pTagNames;
numOfBoundTags = taosArrayGetSize(pNameList);
if (numOfInputTag != numOfBoundTags || schemaSize < numOfInputTag) {
tdDestroyKVRowBuilder(&kvRowBuilder);
code = buildInvalidOperationMsg(pMsgBuf, msg2);
goto _error;
}
bool findColumnIndex = false;
for (int32_t i = 0; i < numOfBoundTags; ++i) {
SToken* sToken = taosArrayGet(pNameList, i);
char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr
strncpy(tmpTokenBuf, sToken->z, sToken->n);
sToken->z = tmpTokenBuf;
// if (TK_STRING == sToken->type) {
// tscDequoteAndTrimToken(sToken);
// }
// if (TK_ID == sToken->type) {
// tscRmEscapeAndTrimToken(sToken);
// }
SListItem* pItem = taosArrayGet(pValList, i);
findColumnIndex = false;
// todo speedup by using hash list
for (int32_t t = 0; t < schemaSize; ++t) {
if (strncmp(sToken->z, pTagSchema[t].name, sToken->n) == 0 && strlen(pTagSchema[t].name) == sToken->n) {
SSchema* pSchema = &pTagSchema[t];
char tagVal[TSDB_MAX_TAGS_LEN] = {0};
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
if (pItem->pVar.nLen > pSchema->bytes) {
tdDestroyKVRowBuilder(&kvRowBuilder);
code = buildInvalidOperationMsg(pMsgBuf, msg3);
goto _error;
}
} else if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) {
if (pItem->pVar.nType == TSDB_DATA_TYPE_BINARY) {
// code = convertTimestampStrToInt64(&(pItem->pVar), tinfo.precision);
// if (code != TSDB_CODE_SUCCESS) {
// return buildInvalidOperationMsg(pMsgBuf, msg4);
// }
} else if (pItem->pVar.nType == TSDB_DATA_TYPE_TIMESTAMP) {
pItem->pVar.i = convertTimePrecision(pItem->pVar.i, TSDB_TIME_PRECISION_NANO, tinfo.precision);
}
}
code = taosVariantDump(&(pItem->pVar), tagVal, pSchema->type, true);
// check again after the convert since it may be converted from binary to nchar.
if (IS_VAR_DATA_TYPE(pSchema->type)) {
int16_t len = varDataTLen(tagVal);
if (len > pSchema->bytes) {
tdDestroyKVRowBuilder(&kvRowBuilder);
code = buildInvalidOperationMsg(pMsgBuf, msg3);
goto _error;
}
}
if (code != TSDB_CODE_SUCCESS) {
tdDestroyKVRowBuilder(&kvRowBuilder);
code = buildInvalidOperationMsg(pMsgBuf, msg4);
goto _error;
}
tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
findColumnIndex = true;
break;
}
}
if (!findColumnIndex) {
tdDestroyKVRowBuilder(&kvRowBuilder);
// return buildInvalidOperationMsg(pMsgBuf, "invalid tag name", sToken->z);
}
}
} else {
if (schemaSize != numOfInputTag) {
tdDestroyKVRowBuilder(&kvRowBuilder);
code = buildInvalidOperationMsg(pMsgBuf, msg2);
goto _error;
}
code = doParseSerializeTagValue(pTagSchema, numOfInputTag, &kvRowBuilder, pValList, tinfo.precision, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
tdDestroyKVRowBuilder(&kvRowBuilder);
goto _error;
}
}
SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
tdDestroyKVRowBuilder(&kvRowBuilder);
if (row == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _error;
}
tdSortKVRowByColIdx(row);
SName tableName = {0};
code = createSName(&tableName, &pCreateTableInfo->name, pCtx, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
// Find a appropriate vgroup to accommodate this table , according to the table name
SVgroupInfo info = {0};
code = catalogGetTableHashVgroup(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, &tableName, &info);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
addCreateTbReqIntoVgroup(pVgroupHashmap, &tableName, row, pSuperTableMeta->uid, &info);
tfree(pSuperTableMeta);
}
*pBufArray = doSerializeVgroupCreateTableInfo(pVgroupHashmap);
if (*pBufArray == NULL) {
code = terrno;
goto _error;
}
taosHashCleanup(pVgroupHashmap);
return TSDB_CODE_SUCCESS;
_error:
taosHashCleanup(pVgroupHashmap);
tfree(pSuperTableMeta);
terrno = code;
return code;
}
static int32_t serializeVgroupTablesBatchImpl(SVgroupTablesBatch* pTbBatch, SArray* pBufArray) {
int tlen = sizeof(SMsgHead) + tSerializeSVCreateTbBatchReq(NULL, &(pTbBatch->req));
void* buf = malloc(tlen);
if (buf == NULL) {
// TODO: handle error
}
((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId);
((SMsgHead*)buf)->contLen = htonl(tlen);
void* pBuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
tSerializeSVCreateTbBatchReq(&pBuf, &(pTbBatch->req));
SVgDataBlocks* pVgData = calloc(1, sizeof(SVgDataBlocks));
pVgData->vg = pTbBatch->info;
pVgData->pData = buf;
pVgData->size = tlen;
pVgData->numOfTables = (int32_t) taosArrayGetSize(pTbBatch->req.pArray);
taosArrayPush(pBufArray, &pVgData);
}
static int32_t doBuildSingleTableBatchReq(SName* pTableName, SArray* pColumns, SVgroupInfo* pVgroupInfo, SVgroupTablesBatch* pBatch) {
struct SVCreateTbReq req = {0};
req.type = TD_NORMAL_TABLE;
req.name = strdup(tNameGetTableName(pTableName));
req.ntbCfg.nCols = taosArrayGetSize(pColumns);
int32_t num = req.ntbCfg.nCols;
req.ntbCfg.pSchema = calloc(num, sizeof(SSchema));
for(int32_t i = 0; i < num; ++i) {
SSchema* pSchema = taosArrayGet(pColumns, i);
memcpy(&req.ntbCfg.pSchema[i], pSchema, sizeof(SSchema));
}
pBatch->info = *pVgroupInfo;
pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
if (pBatch->req.pArray == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY;
}
taosArrayPush(pBatch->req.pArray, &req);
return TSDB_CODE_SUCCESS;
}
int32_t doCheckAndBuildCreateTableReq(SCreateTableSql* pCreateTable, SParseContext* pCtx, SMsgBuf* pMsgBuf, char** pOutput, int32_t* len) {
SArray* pBufArray = NULL;
int32_t code = 0;
// it is a sql statement to create a normal table
if (pCreateTable->childTableInfo == NULL) {
assert(taosArrayGetSize(pCreateTable->colInfo.pColumns) > 0 && pCreateTable->colInfo.pTagColumns == NULL);
code = doCheckForCreateTable(pCreateTable, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
SName tableName = {0};
code = createSName(&tableName, &pCreateTable->name, pCtx, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
SVgroupInfo info = {0};
catalogGetTableHashVgroup(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, &tableName, &info);
SVgroupTablesBatch tbatch = {0};
code = doBuildSingleTableBatchReq(&tableName, pCreateTable->colInfo.pColumns, &info, &tbatch);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
pBufArray = taosArrayInit(1, POINTER_BYTES);
if (pBufArray == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY;
}
serializeVgroupTablesBatchImpl(&tbatch, pBufArray);
destroyCreateTbReqBatch(&tbatch);
} else { // it is a child table, created according to a super table
code = doCheckAndBuildCreateCTableReq(pCreateTable, pCtx, pMsgBuf, &pBufArray);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
}
SVnodeModifOpStmtInfo* pStmtInfo = calloc(1, sizeof(SVnodeModifOpStmtInfo));
pStmtInfo->nodeType = TSDB_SQL_CREATE_TABLE;
pStmtInfo->pDataBlocks = pBufArray;
*pOutput = (char*) pStmtInfo;
*len = sizeof(SVnodeModifOpStmtInfo);
return TSDB_CODE_SUCCESS;
}
SArray* doSerializeVgroupCreateTableInfo(SHashObj* pVgroupHashmap) {
SArray* pBufArray = taosArrayInit(taosHashGetSize(pVgroupHashmap), sizeof(void*));
SVgroupTablesBatch* pTbBatch = NULL;
do {
pTbBatch = taosHashIterate(pVgroupHashmap, pTbBatch);
if (pTbBatch == NULL) {
break;
}
/*int32_t code = */serializeVgroupTablesBatchImpl(pTbBatch, pBufArray);
destroyCreateTbReqBatch(pTbBatch);
} while (true);
return pBufArray;
}
SDclStmtInfo* qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseContext* pCtx, char* msgBuf, int32_t msgBufLen) {
int32_t code = 0;
SDclStmtInfo* pDcl = calloc(1, sizeof(SDclStmtInfo));
SMsgBuf m = {.buf = msgBuf, .len = msgBufLen};
SMsgBuf* pMsgBuf = &m;
pDcl->epSet = pCtx->mgmtEpSet;
switch (pInfo->type) {
case TSDB_SQL_CREATE_USER:
case TSDB_SQL_ALTER_USER: {
const char* msg1 = "not support options";
const char* msg2 = "invalid user/account name";
const char* msg3 = "name too long";
const char* msg4 = "invalid user rights";
SUserInfo* pUser = &pInfo->pMiscInfo->user;
SToken* pName = &pUser->user;
SToken* pPwd = &pUser->passwd;
if (pName->n >= TSDB_USER_LEN) {
code = buildInvalidOperationMsg(pMsgBuf, msg3);
goto _error;
}
if (parserValidateIdToken(pName) != TSDB_CODE_SUCCESS) {
code = buildInvalidOperationMsg(pMsgBuf, msg2);
goto _error;
}
if (pInfo->type == TSDB_SQL_CREATE_USER) {
if (parserValidatePassword(pPwd, pMsgBuf) != TSDB_CODE_SUCCESS) {
code = TSDB_CODE_TSC_INVALID_OPERATION;
goto _error;
}
} else {
if (pUser->type == TSDB_ALTER_USER_PASSWD) {
if (parserValidatePassword(pPwd, pMsgBuf) != TSDB_CODE_SUCCESS) {
code = TSDB_CODE_TSC_INVALID_OPERATION;
goto _error;
}
} else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
assert(pPwd->type == TSDB_DATA_TYPE_NULL);
SToken* pPrivilege = &pUser->privilege;
if (strncasecmp(pPrivilege->z, "super", 5) == 0 && pPrivilege->n == 5) {
// pCmd->count = 1;
} else if (strncasecmp(pPrivilege->z, "normal", 4) == 0 && pPrivilege->n == 4) {
// pCmd->count = 2;
} else {
code = buildInvalidOperationMsg(pMsgBuf, msg4);
goto _error;
}
} else {
code = buildInvalidOperationMsg(pMsgBuf, msg1);
goto _error;
}
}
pDcl->pMsg = (char*)buildUserManipulationMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen);
pDcl->msgType = (pInfo->type == TSDB_SQL_CREATE_USER) ? TDMT_MND_CREATE_USER : TDMT_MND_ALTER_USER;
break;
}
case TSDB_SQL_CREATE_ACCT:
case TSDB_SQL_ALTER_ACCT: {
const char* msg1 = "invalid state option, available options[no, r, w, all]";
const char* msg2 = "invalid user/account name";
const char* msg3 = "name too long";
SToken* pName = &pInfo->pMiscInfo->user.user;
SToken* pPwd = &pInfo->pMiscInfo->user.passwd;
if (parserValidatePassword(pPwd, pMsgBuf) != TSDB_CODE_SUCCESS) {
code = TSDB_CODE_TSC_INVALID_OPERATION;
goto _error;
}
if (pName->n >= TSDB_USER_LEN) {
code = buildInvalidOperationMsg(pMsgBuf, msg3);
goto _error;
}
if (parserValidateNameToken(pName) != TSDB_CODE_SUCCESS) {
code = buildInvalidOperationMsg(pMsgBuf, msg2);
goto _error;
}
SCreateAcctInfo* pAcctOpt = &pInfo->pMiscInfo->acctOpt;
if (pAcctOpt->stat.n > 0) {
if (pAcctOpt->stat.z[0] == 'r' && pAcctOpt->stat.n == 1) {
} else if (pAcctOpt->stat.z[0] == 'w' && pAcctOpt->stat.n == 1) {
} else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) {
} else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) {
} else {
code = buildInvalidOperationMsg(pMsgBuf, msg1);
goto _error;
}
}
pDcl->pMsg = (char*)buildAcctManipulationMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen);
pDcl->msgType = (pInfo->type == TSDB_SQL_CREATE_ACCT) ? TDMT_MND_CREATE_ACCT : TDMT_MND_ALTER_ACCT;
break;
}
case TSDB_SQL_DROP_ACCT:
case TSDB_SQL_DROP_USER: {
pDcl->pMsg = (char*)buildDropUserMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen);
pDcl->msgType = (pInfo->type == TSDB_SQL_DROP_ACCT) ? TDMT_MND_DROP_ACCT : TDMT_MND_DROP_USER;
break;
}
case TSDB_SQL_SHOW: {
SShowInfo* pShowInfo = &pInfo->pMiscInfo->showOpt;
code = setShowInfo(pShowInfo, pCtx, (void**)&pDcl->pMsg, &pDcl->msgLen, &pDcl->epSet, &pDcl->pExtension, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
pDcl->msgType = (pShowInfo->showType == TSDB_MGMT_TABLE_TABLE) ? TDMT_VND_SHOW_TABLES : TDMT_MND_SHOW;
break;
}
case TSDB_SQL_USE_DB: {
const char* msg = "invalid db name";
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (parserValidateNameToken(pToken) != TSDB_CODE_SUCCESS) {
code = buildInvalidOperationMsg(pMsgBuf, msg);
goto _error;
}
SName n = {0};
int32_t ret = tNameSetDbName(&n, pCtx->acctId, pToken->z, pToken->n);
if (ret != TSDB_CODE_SUCCESS) {
code = buildInvalidOperationMsg(pMsgBuf, msg);
goto _error;
}
SUseDbReq usedbReq = {0};
tNameExtractFullName(&n, usedbReq.db);
int32_t bufLen = tSerializeSUseDbReq(NULL, 0, &usedbReq);
void* pBuf = malloc(bufLen);
tSerializeSUseDbReq(pBuf, bufLen, &usedbReq);
pDcl->pMsg = pBuf;
pDcl->msgLen = bufLen;
pDcl->msgType = TDMT_MND_USE_DB;
break;
}
case TSDB_SQL_ALTER_DB:
case TSDB_SQL_CREATE_DB: {
const char* msg1 = "invalid db name";
const char* msg2 = "name too long";
SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt);
if (pCreateDB->dbname.n >= TSDB_DB_NAME_LEN) {
code = buildInvalidOperationMsg(pMsgBuf, msg2);
goto _error;
}
char buf[TSDB_DB_NAME_LEN] = {0};
SToken token = taosTokenDup(&pCreateDB->dbname, buf, tListLen(buf));
if (parserValidateNameToken(&token) != TSDB_CODE_SUCCESS) {
code = buildInvalidOperationMsg(pMsgBuf, msg1);
goto _error;
}
int32_t bufLen = 0;
char* pBuf = buildCreateDbMsg(pCreateDB, &bufLen, pCtx, pMsgBuf);
pDcl->pMsg = pBuf;
pDcl->msgLen = bufLen;
pDcl->msgType = (pInfo->type == TSDB_SQL_CREATE_DB) ? TDMT_MND_CREATE_DB : TDMT_MND_ALTER_DB;
break;
}
case TSDB_SQL_DROP_DB: {
const char* msg1 = "invalid database name";
assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1);
SToken* dbName = taosArrayGet(pInfo->pMiscInfo->a, 0);
SName name = {0};
code = tNameSetDbName(&name, pCtx->acctId, dbName->z, dbName->n);
if (code != TSDB_CODE_SUCCESS) {
code = buildInvalidOperationMsg(pMsgBuf, msg1);
goto _error;
}
SDropDbReq dropdbReq = {0};
code = tNameExtractFullName(&name, dropdbReq.db);
dropdbReq.ignoreNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0;
assert(code == TSDB_CODE_SUCCESS && name.type == TSDB_DB_NAME_T);
int32_t bufLen = tSerializeSDropDbReq(NULL, 0, &dropdbReq);
void* pBuf = malloc(bufLen);
tSerializeSDropDbReq(pBuf, bufLen, &dropdbReq);
pDcl->msgType = TDMT_MND_DROP_DB;
pDcl->msgLen = bufLen;
pDcl->pMsg = pBuf;
break;
}
case TSDB_SQL_CREATE_STABLE: {
SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo;
if ((code = doCheckForCreateTable(pCreateTable, pMsgBuf)) != TSDB_CODE_SUCCESS) {
terrno = code;
goto _error;
}
pDcl->pMsg = buildCreateStbReq(pCreateTable, &pDcl->msgLen, pCtx, pMsgBuf);
pDcl->msgType = TDMT_MND_CREATE_STB;
break;
}
case TSDB_SQL_DROP_TABLE: {
pDcl->pMsg = buildDropStableReq(pInfo, &pDcl->msgLen, pCtx, pMsgBuf);
if (pDcl->pMsg == NULL) {
goto _error;
}
pDcl->msgType = TDMT_MND_DROP_STB;
break;
}
case TSDB_SQL_CREATE_DNODE: {
pDcl->pMsg = (char*)buildCreateDnodeMsg(pInfo, &pDcl->msgLen, pMsgBuf);
if (pDcl->pMsg == NULL) {
goto _error;
}
pDcl->msgType = TDMT_MND_CREATE_DNODE;
break;
}
case TSDB_SQL_DROP_DNODE: {
pDcl->pMsg = (char*)buildDropDnodeMsg(pInfo, &pDcl->msgLen, pMsgBuf);
if (pDcl->pMsg == NULL) {
goto _error;
}
pDcl->msgType = TDMT_MND_DROP_DNODE;
break;
}
default:
break;
}
return pDcl;
_error:
terrno = code;
tfree(pDcl);
return NULL;
}
SVnodeModifOpStmtInfo* qParserValidateCreateTbSqlNode(SSqlInfo* pInfo, SParseContext* pCtx, char* msgBuf, int32_t msgBufLen) {
SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo;
assert(pCreateTable->type == TSDB_SQL_CREATE_TABLE);
SMsgBuf m = {.buf = msgBuf, .len = msgBufLen};
SMsgBuf* pMsgBuf = &m;
SVnodeModifOpStmtInfo* pModifSqlStmt = NULL;
int32_t msgLen = 0;
int32_t code = doCheckAndBuildCreateTableReq(pCreateTable, pCtx, pMsgBuf, (char**) &pModifSqlStmt, &msgLen);
if (code != TSDB_CODE_SUCCESS) {
terrno = code;
tfree(pModifSqlStmt);
return NULL;
}
return pModifSqlStmt;
}

View File

@ -17,8 +17,7 @@
#include "catalog.h"
#include "parserUtil.h"
#include "queryInfoUtil.h"
#include "tmsg.h"
#include "querynodes.h"
#define IS_RAW_PAYLOAD(t) \
(((int)(t)) == PAYLOAD_TYPE_RAW) // 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert

View File

@ -16,9 +16,7 @@
#include "insertParser.h"
#include "dataBlockMgt.h"
#include "parserInt.h"
#include "parserUtil.h"
#include "queryInfoUtil.h"
#include "tglobal.h"
#include "ttime.h"
#include "ttoken.h"
@ -61,9 +59,14 @@ typedef struct SInsertParseContext {
SArray* pTableDataBlocks; // global
SArray* pVgDataBlocks; // global
int32_t totalNum;
SVnodeModifOpStmtInfo* pOutput;
SVnodeModifOpStmt* pOutput;
} SInsertParseContext;
typedef int32_t (*_row_append_fn_t)(const void *value, int32_t len, void *param);
static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE;
static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE;
static int32_t skipInsertInto(SInsertParseContext* pCxt) {
SToken sToken;
NEXT_TOKEN(pCxt->pSql, sToken);
@ -95,6 +98,66 @@ static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullD
return TSDB_CODE_SUCCESS;
}
static int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pParseCtx, SMsgBuf* pMsgBuf) {
const char* msg1 = "name too long";
const char* msg2 = "invalid database name";
const char* msg3 = "db is not specified";
int32_t code = TSDB_CODE_SUCCESS;
char* p = strnchr(pTableName->z, TS_PATH_DELIMITER[0], pTableName->n, true);
if (p != NULL) { // db has been specified in sql string so we ignore current db path
assert(*p == TS_PATH_DELIMITER[0]);
int32_t dbLen = p - pTableName->z;
char name[TSDB_DB_FNAME_LEN] = {0};
strncpy(name, pTableName->z, dbLen);
dbLen = strdequote(name);
code = tNameSetDbName(pName, pParseCtx->acctId, name, dbLen);
if (code != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
int32_t tbLen = pTableName->n - dbLen - 1;
char tbname[TSDB_TABLE_FNAME_LEN] = {0};
strncpy(tbname, p + 1, tbLen);
/*tbLen = */strdequote(tbname);
code = tNameFromString(pName, tbname, T_NAME_TABLE);
if (code != 0) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
} else { // get current DB name first, and then set it into path
if (pTableName->n >= TSDB_TABLE_NAME_LEN) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
assert(pTableName->n < TSDB_TABLE_FNAME_LEN);
char name[TSDB_TABLE_FNAME_LEN] = {0};
strncpy(name, pTableName->z, pTableName->n);
strdequote(name);
if (pParseCtx->db == NULL) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
code = tNameSetDbName(pName, pParseCtx->acctId, pParseCtx->db, strlen(pParseCtx->db));
if (code != TSDB_CODE_SUCCESS) {
code = buildInvalidOperationMsg(pMsgBuf, msg2);
return code;
}
code = tNameFromString(pName, name, T_NAME_TABLE);
if (code != 0) {
code = buildInvalidOperationMsg(pMsgBuf, msg1);
}
}
return code;
}
static int32_t getTableMeta(SInsertParseContext* pCxt, SToken* pTname) {
SName name = {0};
createSName(&name, pTname, pCxt->pComCxt, &pCxt->msg);
@ -258,6 +321,231 @@ static int parseTime(char **end, SToken *pToken, int16_t timePrec, int64_t *time
return TSDB_CODE_SUCCESS;
}
static FORCE_INLINE int32_t checkAndTrimValue(SToken* pToken, uint32_t type, char* tmpTokenBuf, SMsgBuf* pMsgBuf) {
if ((pToken->type != TK_NOW && pToken->type != TK_INTEGER && pToken->type != TK_STRING && pToken->type != TK_FLOAT && pToken->type != TK_BOOL &&
pToken->type != TK_NULL && pToken->type != TK_HEX && pToken->type != TK_OCT && pToken->type != TK_BIN) ||
(pToken->n == 0) || (pToken->type == TK_RP)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid data or symbol", pToken->z);
}
if (IS_NUMERIC_TYPE(type) && pToken->n == 0) {
return buildSyntaxErrMsg(pMsgBuf, "invalid numeric data", pToken->z);
}
// Remove quotation marks
if (TSDB_DATA_TYPE_BINARY == type) {
if (pToken->n >= TSDB_MAX_BYTES_PER_ROW) {
return buildSyntaxErrMsg(pMsgBuf, "too long string", pToken->z);
}
// delete escape character: \\, \', \"
char delim = pToken->z[0];
int32_t cnt = 0;
int32_t j = 0;
for (uint32_t k = 1; k < pToken->n - 1; ++k) {
if (pToken->z[k] == '\\' || (pToken->z[k] == delim && pToken->z[k + 1] == delim)) {
tmpTokenBuf[j] = pToken->z[k + 1];
cnt++;
j++;
k++;
continue;
}
tmpTokenBuf[j] = pToken->z[k];
j++;
}
tmpTokenBuf[j] = 0;
pToken->z = tmpTokenBuf;
pToken->n -= 2 + cnt;
}
return TSDB_CODE_SUCCESS;
}
static bool isNullStr(SToken *pToken) {
return (pToken->type == TK_NULL) || ((pToken->type == TK_STRING) && (pToken->n != 0) &&
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0));
}
static FORCE_INLINE int32_t toDouble(SToken *pToken, double *value, char **endPtr) {
errno = 0;
*value = strtold(pToken->z, endPtr);
// not a valid integer number, return error
if ((*endPtr - pToken->z) != pToken->n) {
return TK_ILLEGAL;
}
return pToken->type;
}
static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, char* tmpTokenBuf, _row_append_fn_t func, void* param, SMsgBuf* pMsgBuf) {
int64_t iv;
char *endptr = NULL;
bool isSigned = false;
int32_t code = checkAndTrimValue(pToken, pSchema->type, tmpTokenBuf, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
if (isNullStr(pToken)) {
if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) {
int64_t tmpVal = 0;
return func(&tmpVal, pSchema->bytes, param);
}
return func(getNullValue(pSchema->type), 0, param);
}
switch (pSchema->type) {
case TSDB_DATA_TYPE_BOOL: {
if ((pToken->type == TK_BOOL || pToken->type == TK_STRING) && (pToken->n != 0)) {
if (strncmp(pToken->z, "true", pToken->n) == 0) {
return func(&TRUE_VALUE, pSchema->bytes, param);
} else if (strncmp(pToken->z, "false", pToken->n) == 0) {
return func(&FALSE_VALUE, pSchema->bytes, param);
} else {
return buildSyntaxErrMsg(pMsgBuf, "invalid bool data", pToken->z);
}
} else if (pToken->type == TK_INTEGER) {
return func(((strtoll(pToken->z, NULL, 10) == 0) ? &FALSE_VALUE : &TRUE_VALUE), pSchema->bytes, param);
} else if (pToken->type == TK_FLOAT) {
return func(((strtod(pToken->z, NULL) == 0) ? &FALSE_VALUE : &TRUE_VALUE), pSchema->bytes, param);
} else {
return buildSyntaxErrMsg(pMsgBuf, "invalid bool data", pToken->z);
}
}
case TSDB_DATA_TYPE_TINYINT: {
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid tinyint data", pToken->z);
} else if (!IS_VALID_TINYINT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "tinyint data overflow", pToken->z);
}
uint8_t tmpVal = (uint8_t)iv;
return func(&tmpVal, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_UTINYINT:{
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned tinyint data", pToken->z);
} else if (!IS_VALID_UTINYINT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "unsigned tinyint data overflow", pToken->z);
}
uint8_t tmpVal = (uint8_t)iv;
return func(&tmpVal, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_SMALLINT: {
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid smallint data", pToken->z);
} else if (!IS_VALID_SMALLINT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "smallint data overflow", pToken->z);
}
int16_t tmpVal = (int16_t)iv;
return func(&tmpVal, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_USMALLINT: {
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned smallint data", pToken->z);
} else if (!IS_VALID_USMALLINT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "unsigned smallint data overflow", pToken->z);
}
uint16_t tmpVal = (uint16_t)iv;
return func(&tmpVal, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_INT: {
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid int data", pToken->z);
} else if (!IS_VALID_INT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "int data overflow", pToken->z);
}
int32_t tmpVal = (int32_t)iv;
return func(&tmpVal, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_UINT: {
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned int data", pToken->z);
} else if (!IS_VALID_UINT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "unsigned int data overflow", pToken->z);
}
uint32_t tmpVal = (uint32_t)iv;
return func(&tmpVal, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_BIGINT: {
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid bigint data", pToken->z);
} else if (!IS_VALID_BIGINT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "bigint data overflow", pToken->z);
}
return func(&iv, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_UBIGINT: {
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned bigint data", pToken->z);
} else if (!IS_VALID_UBIGINT((uint64_t)iv)) {
return buildSyntaxErrMsg(pMsgBuf, "unsigned bigint data overflow", pToken->z);
}
uint64_t tmpVal = (uint64_t)iv;
return func(&tmpVal, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_FLOAT: {
double dv;
if (TK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
}
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
}
float tmpVal = (float)dv;
return func(&tmpVal, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_DOUBLE: {
double dv;
if (TK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
}
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
}
return func(&dv, pSchema->bytes, param);
}
case TSDB_DATA_TYPE_BINARY: {
// Too long values will raise the invalid sql error message
if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) {
return buildSyntaxErrMsg(pMsgBuf, "string data overflow", pToken->z);
}
return func(pToken->z, pToken->n, param);
}
case TSDB_DATA_TYPE_NCHAR: {
return func(pToken->z, pToken->n, param);
}
case TSDB_DATA_TYPE_TIMESTAMP: {
int64_t tmpVal;
if (parseTime(end, pToken, timePrec, &tmpVal, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp", pToken->z);
}
return func(&tmpVal, pSchema->bytes, param);
}
}
return TSDB_CODE_FAILED;
}
typedef struct SMemParam {
SRowBuilder* rb;
SSchema* schema;
@ -634,7 +922,7 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
// [(field1_name, ...)]
// VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path
// [...];
int32_t parseInsertSql(SParseContext* pContext, SVnodeModifOpStmtInfo** pInfo) {
int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
SInsertParseContext context = {
.pComCxt = pContext,
.pSql = (char*) pContext->pSql,
@ -643,7 +931,7 @@ int32_t parseInsertSql(SParseContext* pContext, SVnodeModifOpStmtInfo** pInfo) {
.pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false),
.pTableBlockHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false),
.totalNum = 0,
.pOutput = calloc(1, sizeof(SVnodeModifOpStmtInfo))
.pOutput = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT)
};
if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj || NULL == context.pOutput) {
@ -651,8 +939,7 @@ int32_t parseInsertSql(SParseContext* pContext, SVnodeModifOpStmtInfo** pInfo) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
*pInfo = context.pOutput;
context.pOutput->nodeType = TSDB_SQL_INSERT;
(*pQuery)->pRoot = (SNode*)context.pOutput;
context.pOutput->payloadType = PAYLOAD_TYPE_KV;
int32_t code = skipInsertInto(&context);

View File

@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if 0
#include "astGenerator.h"
#include "parserInt.h"
#include "parserUtil.h"
@ -260,3 +261,36 @@ void qDestroyQuery(SQueryNode* pQueryNode) {
destroyQueryInfo(pQueryStmtInfo);
}
}
#else
#include "parser.h"
#include "insertParser.h"
#include "parserImpl.h"
#include "ttoken.h"
static bool isInsertSql(const char* pStr, size_t length) {
int32_t index = 0;
do {
SToken t0 = tStrGetToken((char*) pStr, &index, false);
if (t0.type != TK_LP) {
return t0.type == TK_INSERT || t0.type == TK_IMPORT;
}
} while (1);
}
int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery) {
if (isInsertSql(pCxt->pSql, pCxt->sqlLen)) {
return parseInsertSql(pCxt, pQuery);
} else {
return parseQuerySql(pCxt, pQuery);
}
}
void qDestroyQuery(SQuery* pQueryNode) {
// todo
}
#endif

View File

@ -16,9 +16,11 @@
#include "parserImpl.h"
#include "astCreateContext.h"
#include "catalog.h"
#include "functionMgt.h"
#include "parserInt.h"
#include "parserUtil.h"
#include "tglobal.h"
#include "tname.h"
#include "ttime.h"
#include "ttoken.h"
@ -174,20 +176,20 @@ static uint32_t getToken(const char* z, uint32_t* tokenId) {
return n;
}
static EStmtType getStmtType(const SNode* pRootNode) {
static bool isCmd(const SNode* pRootNode) {
if (NULL == pRootNode) {
return STMT_TYPE_CMD;
return true;
}
switch (nodeType(pRootNode)) {
case QUERY_NODE_SELECT_STMT:
return STMT_TYPE_QUERY;
return false;
default:
break;
}
return STMT_TYPE_CMD;
return true;
}
int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) {
SAstCreateContext cxt;
createAstCreateContext(pParseCxt, &cxt);
void *pParser = NewParseAlloc(malloc);
@ -236,8 +238,11 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
abort_parse:
NewParseFree(pParser, free);
destroyAstCreateContext(&cxt);
pQuery->stmtType = getStmtType(cxt.pRootNode);
pQuery->pRoot = cxt.pRootNode;
if (cxt.valid) {
*pQuery = calloc(1, sizeof(SQuery));
(*pQuery)->isCmd = isCmd(cxt.pRootNode);
(*pQuery)->pRoot = cxt.pRootNode;
}
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
}
@ -1054,16 +1059,16 @@ int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
if (TSDB_CODE_SUCCESS == code) {
code = translateQuery(&cxt, pQuery->pRoot);
}
if (TSDB_CODE_SUCCESS == code && STMT_TYPE_QUERY == pQuery->stmtType) {
if (TSDB_CODE_SUCCESS == code && !pQuery->isCmd) {
code = setReslutSchema(&cxt, pQuery);
}
return code;
}
int32_t parser(SParseContext* pParseCxt, SQuery* pQuery) {
int32_t code = doParse(pParseCxt, pQuery);
int32_t parseQuerySql(SParseContext* pCxt, SQuery** pQuery) {
int32_t code = doParse(pCxt, pQuery);
if (TSDB_CODE_SUCCESS == code) {
code = doTranslate(pParseCxt, pQuery);
code = doTranslate(pCxt, *pQuery);
}
return code;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,377 +0,0 @@
#include "os.h"
#include "queryInfoUtil.h"
#include "function.h"
#include "parser.h"
#include "parserUtil.h"
static struct SSchema _s = {
.colId = TSDB_TBNAME_COLUMN_INDEX,
.type = TSDB_DATA_TYPE_BINARY,
.bytes = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE,
.name = "tbname",
};
SSchema* getTbnameColumnSchema() {
return &_s;
}
SArray* getCurrentExprList(SQueryStmtInfo* pQueryInfo) {
assert(pQueryInfo != NULL && pQueryInfo->exprListLevelIndex >= 0 && pQueryInfo->exprListLevelIndex < 10);
return pQueryInfo->exprList[pQueryInfo->exprListLevelIndex];
}
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo) {
SArray* pExprList = getCurrentExprList(pQueryInfo);
return taosArrayGetSize(pExprList);
}
SSchema* getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex) {
assert(pTableMeta != NULL && pTableMeta->schema != NULL && colIndex >= 0 && colIndex < (getNumOfColumns(pTableMeta) + getNumOfTags(pTableMeta)));
SSchema* pSchema = (SSchema*) pTableMeta->schema;
return &pSchema[colIndex];
}
STableComInfo getTableInfo(const STableMeta* pTableMeta) {
assert(pTableMeta != NULL);
return pTableMeta->tableInfo;
}
int32_t getNumOfColumns(const STableMeta* pTableMeta) {
assert(pTableMeta != NULL);
// table created according to super table, use data from super table
return getTableInfo(pTableMeta).numOfColumns;
}
int32_t getNumOfTags(const STableMeta* pTableMeta) {
assert(pTableMeta != NULL);
return getTableInfo(pTableMeta).numOfTags;
}
SSchema *getTableColumnSchema(const STableMeta *pTableMeta) {
assert(pTableMeta != NULL);
return (SSchema*) pTableMeta->schema;
}
SSchema* getTableTagSchema(const STableMeta* pTableMeta) {
assert(pTableMeta != NULL && (pTableMeta->tableType == TSDB_SUPER_TABLE || pTableMeta->tableType == TSDB_CHILD_TABLE));
return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns);
}
static tExprNode* createFunctionExprNode(const char* funcName, struct SSourceParam *pParam) {
tExprNode** p = malloc(pParam->num * POINTER_BYTES);
if (pParam->pColumnList != NULL) {
for(int32_t i = 0; i < pParam->num; ++i) {
p[i] = calloc(1, sizeof(tExprNode));
p[i]->nodeType = TEXPR_COL_NODE;
SColumn* pSrc = taosArrayGetP(pParam->pColumnList, i);
SSchema* pSchema = calloc(1, sizeof(SSchema));
tstrncpy(pSchema->name, pSrc->name, tListLen(pSchema->name));
pSchema->type = pSrc->info.type;
pSchema->bytes = pSrc->info.bytes;
pSchema->colId = pSrc->info.colId;
p[i]->pSchema = pSchema;
}
} else {
assert(pParam->pColumnList == NULL);
for(int32_t i = 0; i < pParam->num; ++i) {
p[i] = taosArrayGetP(pParam->pExprNodeList, i);
}
}
tExprNode* pNode = calloc(1, sizeof(tExprNode));
pNode->nodeType = TEXPR_FUNCTION_NODE;
tstrncpy(pNode->_function.functionName, funcName, tListLen(pNode->_function.functionName));
pNode->_function.pChild = p;
pNode->_function.num = pParam->num;
return pNode;
}
SExprInfo* createBinaryExprInfo(tExprNode* pNode, SSchema* pResSchema) {
assert(pNode != NULL && pResSchema != NULL);
SExprInfo* pExpr = calloc(1, sizeof(SExprInfo));
if (pExpr == NULL) {
return NULL;
}
pExpr->pExpr = pNode;
memcpy(&pExpr->base.resSchema, pResSchema, sizeof(SSchema));
return pExpr;
}
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, const char* funcName, SSourceParam* pSourceParam, SSchema* pResSchema, int16_t interSize) {
SExprInfo* pExpr = calloc(1, sizeof(SExprInfo));
if (pExpr == NULL) {
return NULL;
}
uint64_t uid = 0;
if (pTableMetaInfo->pTableMeta) {
uid = pTableMetaInfo->pTableMeta->uid;
}
SSqlExpr* p = &pExpr->base;
p->pColumns = calloc(pSourceParam->num, sizeof(SColumn));
p->numOfCols = pSourceParam->num;
p->interBytes = interSize;
memcpy(&p->resSchema, pResSchema, sizeof(SSchema));
if (pSourceParam->pExprNodeList != NULL) {
pExpr->pExpr = createFunctionExprNode(funcName, pSourceParam);
return pExpr;
}
SColumn* pCol = taosArrayGetP(pSourceParam->pColumnList, 0);
if (pCol->info.colId == TSDB_TBNAME_COLUMN_INDEX) {
assert(pSourceParam->num == 1);
SSchema* s = getTbnameColumnSchema();
setColumn(p->pColumns, uid, pTableMetaInfo->aliasName, TSDB_COL_TAG, s);
pExpr->pExpr = createFunctionExprNode(funcName, pSourceParam);
} else if (TSDB_COL_IS_UD_COL(pCol->flag) || strcmp(funcName, "block_dist") == 0) {
setColumn(p->pColumns, uid, pTableMetaInfo->aliasName, TSDB_COL_UDC, pResSchema);
pExpr->pExpr = createFunctionExprNode(funcName, pSourceParam);
} else {
for(int32_t i = 0; i < pSourceParam->num; ++i) {
SColumn* c = taosArrayGetP(pSourceParam->pColumnList, i);
p->pColumns[i] = *c;
}
pExpr->pExpr = createFunctionExprNode(funcName, pSourceParam);
}
return pExpr;
}
void addExprInfo(SArray* pExprList, int32_t index, SExprInfo* pExprInfo, int32_t level) {
assert(pExprList != NULL );
int32_t num = (int32_t) taosArrayGetSize(pExprList);
if (index == num) {
taosArrayPush(pExprList, &pExprInfo);
} else {
taosArrayInsert(pExprList, index, &pExprInfo);
}
#if 0
if (pExprInfo->pExpr->nodeType == TEXPR_FUNCTION_NODE) {
printf("add function: %s, level:%d, total:%ld\n", pExprInfo->pExpr->_function.functionName, level, taosArrayGetSize(pExprList));
} else {
printf("add operator: %s, level:%d, total:%ld\n", pExprInfo->base.resSchema.name, level, taosArrayGetSize(pExprList));
}
#endif
}
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize) {
assert(pExprInfo != NULL);
SSqlExpr* pse = &pExprInfo->base;
assert(0);
pse->resSchema.type = resType;
pse->resSchema.bytes = resSize;
}
SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index) {
assert(pQueryInfo != NULL && pQueryInfo->exprList && index >= 0);
return taosArrayGetP(getCurrentExprList(pQueryInfo), index);
}
void destroyExprInfo(SExprInfo* pExprInfo) {
tExprTreeDestroy(pExprInfo->pExpr, NULL);
for(int32_t i = 0; i < pExprInfo->base.numOfParams; ++i) {
taosVariantDestroy(&pExprInfo->base.param[i]);
}
tfree(pExprInfo->base.pColumns);
tfree(pExprInfo);
}
void dropOneLevelExprInfo(SArray* pExprInfo) {
size_t size = taosArrayGetSize(pExprInfo);
for (int32_t i = 0; i < size; ++i) {
SExprInfo* pExpr = taosArrayGetP(pExprInfo, i);
destroyExprInfo(pExpr);
}
taosArrayDestroy(pExprInfo);
}
void dropAllExprInfo(SArray** pExprInfo, int32_t numOfLevel) {
for(int32_t i = 0; i < numOfLevel; ++i) {
dropOneLevelExprInfo(pExprInfo[i]);
}
}
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) {
assert (pExpr != NULL || argument != NULL || bytes != 0);
// set parameter value
// transfer to tVariant from byte data/no ascii data
taosVariantCreateFromBinary(&pExpr->param[pExpr->numOfParams], argument, bytes, type);
pExpr->numOfParams += 1;
assert(pExpr->numOfParams <= 3);
}
int32_t getExprFunctionId(SExprInfo *pExprInfo) {
assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_FUNCTION_NODE);
return 0;
}
void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
assert(dst != NULL && src != NULL);
*dst = *src;
#if 0
if (src->base.flist.numOfFilters > 0) {
dst->base.flist.filterInfo = calloc(src->base.flist.numOfFilters, sizeof(SColumnFilterInfo));
memcpy(dst->base.flist.filterInfo, src->base.flist.filterInfo, sizeof(SColumnFilterInfo) * src->base.flist.numOfFilters);
}
#endif
dst->pExpr = exprdup(src->pExpr);
dst->base.pColumns = calloc(src->base.numOfCols, sizeof(SColumn));
memcpy(dst->base.pColumns, src->base.pColumns, sizeof(SColumn) * src->base.numOfCols);
memset(dst->base.param, 0, sizeof(SVariant) * tListLen(dst->base.param));
for (int32_t j = 0; j < src->base.numOfParams; ++j) {
taosVariantAssign(&dst->base.param[j], &src->base.param[j]);
}
}
int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy) {
assert(src != NULL && dst != NULL);
size_t size = taosArrayGetSize(src);
for (int32_t i = 0; i < size; ++i) {
SExprInfo* pExpr = taosArrayGetP(src, i);
uint64_t exprUid = pExpr->base.pColumns->uid;
if (exprUid == uid) {
if (deepcopy) {
SExprInfo* p1 = calloc(1, sizeof(SExprInfo));
assignExprInfo(p1, pExpr);
taosArrayPush(dst, &p1);
} else {
taosArrayPush(dst, &pExpr);
}
}
}
return 0;
}
int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy) {
assert(src != NULL && dst != NULL);
size_t size = taosArrayGetSize(src);
for (int32_t i = 0; i < size; ++i) {
SExprInfo* pExpr = taosArrayGetP(src, i);
SExprInfo* p1 = calloc(1, sizeof(SExprInfo));
assignExprInfo(p1, pExpr);
taosArrayPush(dst, &p1);
}
return 0;
}
//void* tSqlExprDestroy(SExprInfo* pExpr) {
// if (pExpr == NULL) {
// return NULL;
// }
//
// SSqlExpr* p = &pExpr->base;
// for(int32_t i = 0; i < tListLen(p->param); ++i) {
// taosVariantDestroy(&p->param[i]);
// }
//
// if (p->flist.numOfFilters > 0) {
// tfree(p->flist.filterInfo);
// }
//
// if (pExpr->pExpr != NULL) {
// tExprTreeDestroy(pExpr->pExpr, NULL);
// }
//
// tfree(pExpr);
// return NULL;
//}
int32_t getResRowLength(SArray* pExprList) {
size_t num = taosArrayGetSize(pExprList);
if (num == 0) {
return 0;
}
int32_t size = 0;
for(int32_t i = 0; i < num; ++i) {
SExprInfo* pExpr = taosArrayGetP(pExprList, i);
size += pExpr->base.resSchema.bytes;
}
return size;
}
SArray* extractFunctionList(SArray* pExprInfoList) {
assert(pExprInfoList != NULL);
size_t len = taosArrayGetSize(pExprInfoList);
SArray* p = taosArrayInit(len, POINTER_BYTES);
for(int32_t i = 0; i < len; ++i) {
SExprInfo* pExprInfo = taosArrayGetP(pExprInfoList, i);
if (pExprInfo->pExpr->nodeType == TEXPR_FUNCTION_NODE) {
char* name = strdup(pExprInfo->pExpr->_function.functionName);
taosArrayPush(p, &name);
} else {
char* name = strdup("project");
taosArrayPush(p, &name);
}
}
return p;
}
bool tscHasColumnFilter(SQueryStmtInfo* pQueryInfo) {
// filter on primary timestamp column
if (pQueryInfo->window.skey != INT64_MIN || pQueryInfo->window.ekey != INT64_MAX) {
return true;
}
size_t size = taosArrayGetSize(pQueryInfo->colList);
for (int32_t i = 0; i < size; ++i) {
SColumn* pCol = taosArrayGetP(pQueryInfo->colList, i);
if (pCol->info.flist.numOfFilters > 0) {
return true;
}
}
return false;
}
int32_t getExprFunctionLevel(const SQueryStmtInfo* pQueryInfo) {
int32_t n = 10;
int32_t level = 0;
for(int32_t i = 0; i < n; ++i) {
SArray* pList = pQueryInfo->exprList[i];
if (taosArrayGetSize(pList) > 0) {
level += 1;
}
}
return level;
}

File diff suppressed because it is too large Load Diff

View File

@ -60,15 +60,12 @@ protected:
return code_;
}
SVnodeModifOpStmtInfo* reslut() {
return res_;
}
void dumpReslut() {
size_t num = taosArrayGetSize(res_->pDataBlocks);
cout << "schemaAttache:" << (int32_t)res_->schemaAttache << ", payloadType:" << (int32_t)res_->payloadType << ", insertType:" << res_->insertType << ", numOfVgs:" << num << endl;
SVnodeModifOpStmt* pStmt = getVnodeModifStmt(res_);
size_t num = taosArrayGetSize(pStmt->pDataBlocks);
cout << "schemaAttache:" << (int32_t)pStmt->schemaAttache << ", payloadType:" << (int32_t)pStmt->payloadType << ", insertType:" << pStmt->insertType << ", numOfVgs:" << num << endl;
for (size_t i = 0; i < num; ++i) {
SVgDataBlocks* vg = (SVgDataBlocks*)taosArrayGetP(res_->pDataBlocks, i);
SVgDataBlocks* vg = (SVgDataBlocks*)taosArrayGetP(pStmt->pDataBlocks, i);
cout << "vgId:" << vg->vg.vgId << ", numOfTables:" << vg->numOfTables << ", dataSize:" << vg->size << endl;
SSubmitReq* submit = (SSubmitReq*)vg->pData;
cout << "length:" << ntohl(submit->length) << ", numOfBlocks:" << ntohl(submit->numOfBlocks) << endl;
@ -84,13 +81,14 @@ protected:
}
void checkReslut(int32_t numOfTables, int16_t numOfRows1, int16_t numOfRows2 = -1) {
ASSERT_EQ(res_->schemaAttache, 0);
ASSERT_EQ(res_->payloadType, PAYLOAD_TYPE_KV);
ASSERT_EQ(res_->insertType, TSDB_QUERY_TYPE_INSERT);
size_t num = taosArrayGetSize(res_->pDataBlocks);
SVnodeModifOpStmt* pStmt = getVnodeModifStmt(res_);
ASSERT_EQ(pStmt->schemaAttache, 0);
ASSERT_EQ(pStmt->payloadType, PAYLOAD_TYPE_KV);
ASSERT_EQ(pStmt->insertType, TSDB_QUERY_TYPE_INSERT);
size_t num = taosArrayGetSize(pStmt->pDataBlocks);
ASSERT_GE(num, 0);
for (size_t i = 0; i < num; ++i) {
SVgDataBlocks* vg = (SVgDataBlocks*)taosArrayGetP(res_->pDataBlocks, i);
SVgDataBlocks* vg = (SVgDataBlocks*)taosArrayGetP(pStmt->pDataBlocks, i);
ASSERT_EQ(vg->numOfTables, numOfTables);
ASSERT_GE(vg->size, 0);
SSubmitReq* submit = (SSubmitReq*)vg->pData;
@ -115,7 +113,10 @@ private:
cxt_.pMsg = errMagBuf_;
cxt_.msgLen = max_err_len;
code_ = TSDB_CODE_SUCCESS;
res_ = nullptr;
}
SVnodeModifOpStmt* getVnodeModifStmt(SQuery* pQuery) {
return (SVnodeModifOpStmt*)pQuery->pRoot;
}
string acctId_;
@ -124,7 +125,7 @@ private:
char sqlBuf_[max_sql_len];
SParseContext cxt_;
int32_t code_;
SVnodeModifOpStmtInfo* res_;
SQuery* res_;
};
// INSERT INTO tb_name VALUES (field1_value, ...)

View File

@ -50,19 +50,19 @@ protected:
if (TSDB_CODE_SUCCESS != parseCode) {
return false;
}
code = doTranslate(&cxt_, &query_);
code = doTranslate(&cxt_, query_);
// cout << "doTranslate return " << code << endl;
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] code:" << code << ", " << translateCode << ", msg:" << errMagBuf_ << endl;
return (code == translateCode);
}
if (NULL != query_.pRoot && QUERY_NODE_SELECT_STMT == nodeType(query_.pRoot)) {
if (NULL != query_->pRoot && QUERY_NODE_SELECT_STMT == nodeType(query_->pRoot)) {
cout << "input sql : [" << cxt_.pSql << "]" << endl;
// string sql;
// selectToSql(query_.pRoot, sql);
// cout << "output sql : [" << sql << "]" << endl;
string str;
selectToStr(query_.pRoot, str);
selectToStr(query_->pRoot, str);
cout << "translate str : \n" << str << endl;
}
return (TSDB_CODE_SUCCESS == translateCode);
@ -507,7 +507,7 @@ private:
char errMagBuf_[max_err_len];
string sqlBuf_;
SParseContext cxt_;
SQuery query_;
SQuery* query_;
};
TEST_F(NewParserTest, selectSimple) {

View File

@ -1,787 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <function.h>
#include <gtest/gtest.h>
#include <iostream>
#include "tglobal.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#include "os.h"
#include "astGenerator.h"
#include "parserInt.h"
#include "taos.h"
#include "tdef.h"
#include "tvariant.h"
#include "parserUtil.h"
namespace {
void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_t colId) {
p->colId = colId;
p->bytes = bytes;
p->type = type;
strcpy(p->name, name);
}
void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SCatalogReq* req) {
pQueryInfo->numOfTables = 1;
pQueryInfo->pTableMetaInfo = (STableMetaInfo**)calloc(1, POINTER_BYTES);
STableMetaInfo* pTableMetaInfo = (STableMetaInfo*)calloc(1, sizeof(STableMetaInfo));
pQueryInfo->pTableMetaInfo[0] = pTableMetaInfo;
SName* name = (SName*)taosArrayGet(req->pTableName, 0);
memcpy(&pTableMetaInfo->name, taosArrayGet(req->pTableName, 0), sizeof(SName));
pTableMetaInfo->pTableMeta = (STableMeta*)calloc(1, sizeof(STableMeta) + 6 * sizeof(SSchema));
strcpy(pTableMetaInfo->aliasName, name->tname);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
pTableMeta->tableType = TSDB_NORMAL_TABLE;
pTableMeta->tableInfo.numOfColumns = 6;
pTableMeta->tableInfo.rowSize = 28;
pTableMeta->uid = 110;
pTableMetaInfo->tagColList = (SArray*)taosArrayInit(4, POINTER_BYTES);
SSchema* pSchema = pTableMetaInfo->pTableMeta->schema;
setSchema(&pSchema[0], TSDB_DATA_TYPE_TIMESTAMP, 8, "ts", 0);
setSchema(&pSchema[1], TSDB_DATA_TYPE_INT, 4, "a", 1);
setSchema(&pSchema[2], TSDB_DATA_TYPE_DOUBLE, 8, "b", 2);
setSchema(&pSchema[3], TSDB_DATA_TYPE_DOUBLE, 8, "col", 3);
setSchema(&pSchema[4], TSDB_DATA_TYPE_BINARY, 12, "c", 4);
setSchema(&pSchema[5], TSDB_DATA_TYPE_BINARY, 44, "d", 5);
}
void sqlCheck(const char* sql, bool valid) {
SSqlInfo info1 = doGenerateAST(sql);
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
if (valid) {
ASSERT_EQ(ret, 0);
} else {
ASSERT_NE(ret, 0);
}
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
} // namespace
TEST(testCase, validateAST_test) {
SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
SArray* pExprList = pQueryInfo->exprList[0];
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 0);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
ASSERT_EQ(p1->base.pColumns->info.colId, 1);
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
ASSERT_STRCASEEQ(p1->base.token, "a1111");
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
SExprInfo* p2 = (SExprInfo*)taosArrayGetP(pExprList, 1);
ASSERT_EQ(p2->base.pColumns->uid, 110);
ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
// ASSERT_EQ(p1->base.colInfo.colId, 1);
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, function_Test) {
SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
SArray* pExprList = pQueryInfo->exprList[0];
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 0);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a)");
ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
ASSERT_EQ(p1->base.pColumns->info.colId, 1);
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
ASSERT_STRCASEEQ(p1->base.token, "count(a)");
ASSERT_EQ(p1->base.interBytes, 8);
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, function_Test2) {
SSqlInfo info1 = doGenerateAST("select count(a) abc from `t.1abc`");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
SArray* pExprList = pQueryInfo->exprList[0];
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 0);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "abc");
ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
ASSERT_EQ(p1->base.pColumns->info.colId, 1);
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
ASSERT_STRCASEEQ(p1->base.token, "count(a)");
ASSERT_EQ(p1->base.interBytes, 8);
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, function_Test3) {
SSqlInfo info1 = doGenerateAST("select first(*) from `t.1abc`");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
SArray* pExprList = pQueryInfo->exprList[0];
ASSERT_EQ(taosArrayGetSize(pExprList), 6);
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 0);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_TIMESTAMP);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "first(ts)");
ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.ts");
ASSERT_EQ(p1->base.pColumns->info.colId, 0);
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
ASSERT_STRCASEEQ(p1->base.token, "first(ts)");
ASSERT_EQ(p1->base.interBytes, 24);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 6);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, function_Test4) {
SSqlInfo info1 = doGenerateAST("select block_dist() as a1 from `t.1abc`");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
SArray* pExprList = pQueryInfo->exprList[0];
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 1);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BINARY);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
// ASSERT_EQ(p1->base.colInfo.colId, 0);
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_UDC);
ASSERT_STRCASEEQ(p1->base.token, "block_dist()");
ASSERT_EQ(p1->base.interBytes, 0);
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, function_Test5) {
// todo select concat(concat(a, b), concat(b, a)) from `t.1abc`;
SSqlInfo info1 = doGenerateAST("select sum(a) + avg(b) as a1 from `t.1abc`");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_EQ(ret, 0);
SArray* pExprList = pQueryInfo->exprList[0];
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
ASSERT_EQ(p1->base.numOfCols, 2);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 1);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
ASSERT_STREQ(p1->base.pColumns->name, "sum(a)");
ASSERT_STRCASEEQ(p1->base.token, "sum(a) + avg(b)");
ASSERT_EQ(p1->base.interBytes, 0);
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, function_Test10) {
sqlCheck("select c from `t.1abc`", true);
sqlCheck("select length(c) from `t.1abc`", true);
sqlCheck("select length(sum(col)) from `t.1abc`", true);
sqlCheck("select sum(length(a+b)) from `t.1abc`", true);
sqlCheck("select sum(sum(a+b)) from `t.1abc`", false);
sqlCheck("select sum(length(a) + length(b)) from `t.1abc`", true);
sqlCheck("select length(sum(a) + sum(b)) + length(sum(a) + sum(b)) from `t.1abc`", true);
sqlCheck("select sum(length(sum(a))) from `t.1abc`", true);
sqlCheck("select cov(a, b) from `t.1abc`", true);
sqlCheck("select sum(length(a) + count(b)) from `t.1abc`", false);
sqlCheck("select concat(sum(a), count(b)) from `t.1abc`", true);
sqlCheck("select concat(concat(a,b), concat(a,b)) from `t.1abc`", true);
sqlCheck("select length(length(length(a))) from `t.1abc`", true);
sqlCheck("select count() from `t.1abc`", false);
sqlCheck("select block_dist() from `t.1abc`", true);
sqlCheck("select block_dist(a) from `t.1abc`", false);
sqlCheck("select count(*) from `t.1abc` interval(1s) group by a", false);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sqlCheck("select length119(a,b) from `t.1abc`", false);
sqlCheck("select length(a, b) from `t.1abc`", false);
sqlCheck("select block_dist() + 20 from `t.1abc`", true);
sqlCheck("select count(b), c from `t.1abc`", false);
sqlCheck("select top(a, 20), count(b) from `t.1abc`", false);
sqlCheck("select top(a, 20), b from `t.1abc`", false);
sqlCheck("select top(a, 20), a+20 from `t.1abc`", true);
// sqlCheck("select top(a, 20), bottom(a, 10) from `t.1abc`", false);
// sqlCheck("select last_row(*), count(b) from `t.1abc`", false);
// sqlCheck("select last_row(a, b) + 20 from `t.1abc`", false);
// sqlCheck("select last_row(count(*)) from `t.1abc`", false);
}
TEST(testCase, function_Test6) {
SSqlInfo info1 = doGenerateAST(
"select sum(a+b) as a1, first(b*a), count(b+b), count(1), count(42.1) from `t.1abc` interval(10s, 1s)");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_EQ(ret, 0);
SArray* pExprList = pQueryInfo->exprList[0];
if (tsCompatibleModel) {
ASSERT_EQ(taosArrayGetSize(pExprList), 6);
} else {
ASSERT_EQ(taosArrayGetSize(pExprList), 5);
}
int32_t index = tsCompatibleModel? 1:0;
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, index);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 0);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)");
ASSERT_EQ(p1->base.interBytes, 16);
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
ASSERT_STRCASEEQ(p1->pExpr->_function.functionName, "sum");
ASSERT_EQ(p1->pExpr->_function.num, 1);
tExprNode* pParam = p1->pExpr->_function.pChild[0];
ASSERT_EQ(pParam->nodeType, TEXPR_COL_NODE);
ASSERT_STREQ(pParam->pSchema->name, "t.1abc.a+b");
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
int32_t numOfResCol = tsCompatibleModel? 6:5;
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, numOfResCol);
index = tsCompatibleModel? 2:1;
SExprInfo* p2 = (SExprInfo*)taosArrayGetP(pExprList, index);
ASSERT_EQ(p2->base.pColumns->uid, 110);
ASSERT_EQ(p2->base.numOfParams, 0);
ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_STRCASEEQ(p2->base.resSchema.name, "first(b*a)");
ASSERT_EQ(p2->base.pColumns->flag, TSDB_COL_TMP);
ASSERT_STREQ(p2->base.pColumns->name, "t.1abc.b*a");
ASSERT_STRCASEEQ(p2->base.token, "first(b*a)");
ASSERT_EQ(p2->base.interBytes, 24);
ASSERT_EQ(p2->pExpr->nodeType, TEXPR_FUNCTION_NODE);
ASSERT_STRCASEEQ(p2->pExpr->_function.functionName, "first");
ASSERT_EQ(p2->pExpr->_function.num, 1);
ASSERT_EQ(p2->pExpr->_function.pChild[0]->nodeType, TEXPR_COL_NODE);
ASSERT_STREQ(p2->pExpr->_function.pChild[0]->pSchema->name, "t.1abc.b*a");
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, function_Test7) {
SSqlInfo info1 = doGenerateAST("select count(a+b),count(1) from `t.1abc` interval(10s, 1s)");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_EQ(ret, 0);
SArray* pExprList = pQueryInfo->exprList[0];
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
int32_t index = tsCompatibleModel? 1:0;
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, index);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 0);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a+b)");
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
ASSERT_STRCASEEQ(p1->base.token, "count(a+b)");
ASSERT_EQ(p1->base.interBytes, 8);
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
ASSERT_STREQ(p1->pExpr->_function.functionName, "count");
tExprNode* pParam = p1->pExpr->_function.pChild[0];
ASSERT_EQ(pParam->nodeType, TEXPR_COL_NODE);
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pQueryInfo->exprList[1], 0);
ASSERT_EQ(p2->pExpr->nodeType, TEXPR_BINARYEXPR_NODE);
ASSERT_EQ(p2->pExpr->_node.optr, OP_TYPE_ADD);
ASSERT_EQ(p2->pExpr->_node.pLeft->nodeType, TEXPR_COL_NODE);
ASSERT_EQ(p2->pExpr->_node.pRight->nodeType, TEXPR_COL_NODE);
ASSERT_EQ(pParam->pSchema->colId, p2->base.resSchema.colId);
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
int32_t numOfCols = tsCompatibleModel? 3:2;
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, numOfCols);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, function_Test8) {
SSqlInfo info1 = doGenerateAST("select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_EQ(ret, 0);
SArray* pExprList = pQueryInfo->exprList[0];
ASSERT_EQ(taosArrayGetSize(pExprList), 2);
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 1);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 1);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)");
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)");
ASSERT_EQ(p1->base.interBytes, 16);
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
ASSERT_STRCASEEQ(p1->pExpr->_function.functionName, "top");
ASSERT_TRUE(p1->pExpr->_function.num == 1);
tExprNode* pParam = p1->pExpr->_function.pChild[0];
ASSERT_EQ(pParam->nodeType, TSDB_COL_TMP);
// ASSERT_EQ(pParam->.optr, TSDB_BINARY_OP_DIVIDE);
// ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_BINARYEXPR_NODE);
// ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_VALUE_NODE);
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
info1 = doGenerateAST("select sum(length(a)+length(b)) from `t.1abc` interval(10s, 1s)");
ASSERT_EQ(info1.valid, true);
pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_EQ(ret, 0);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, invalid_sql_Test) {
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlInfo info1 = doGenerateAST("select count(k) from `t.1abc` interval(10s, 1s)");
ASSERT_EQ(info1.valid, true);
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
ctx.db = "db1";
ctx.acctId = 1;
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_NE(ret, 0);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
//===============================================================================================================
info1 = doGenerateAST("select top(a*b, ABC) from `t.1abc` interval(10s, 1s)");
ASSERT_EQ(info1.valid, true);
pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_NE(ret, 0);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, show_user_Test) {
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
char sql1[] = "show users";
SSqlInfo info1 = doGenerateAST(sql1);
ASSERT_EQ(info1.valid, true);
SParseContext ct= {.requestId = 1, .acctId = 1, .db = "abc", .pTransporter = NULL};
SDclStmtInfo* output = qParserValidateDclSqlNode(&info1, &ct, msg, buf.len);
ASSERT_NE(output, nullptr);
// convert the show command to be the select query
// select name, privilege, create_time, account from information_schema.users;
}
TEST(testCase, create_user_Test) {
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
char sql[] = {"create user abc pass 'abc'"};
SSqlInfo info1 = doGenerateAST(sql);
ASSERT_EQ(info1.valid, true);
ASSERT_EQ(isDclSqlStatement(&info1), true);
SParseContext ct= {.requestId = 1, .acctId = 1, .db = "abc"};
SDclStmtInfo* output = qParserValidateDclSqlNode(&info1, &ct, msg, buf.len);
ASSERT_NE(output, nullptr);
destroySqlInfo(&info1);
}
#pragma GCC diagnostic pop

View File

@ -1,209 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <function.h>
#include <gtest/gtest.h>
#include <tglobal.h>
#include <iostream>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#include "os.h"
#include "astGenerator.h"
#include "parserInt.h"
#include "taos.h"
#include "tdef.h"
#include "tvariant.h"
#include "planner.h"
#include "../../planner/inc/plannerInt.h"
namespace {
void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_t colId) {
p->colId = colId;
p->bytes = bytes;
p->type = type;
strcpy(p->name, name);
}
void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SCatalogReq *req) {
pQueryInfo->numOfTables = 1;
pQueryInfo->pTableMetaInfo = (STableMetaInfo**)calloc(1, POINTER_BYTES);
STableMetaInfo* pTableMetaInfo = (STableMetaInfo*)calloc(1, sizeof(STableMetaInfo));
pQueryInfo->pTableMetaInfo[0] = pTableMetaInfo;
SName* name = (SName*)taosArrayGet(req->pTableName, 0);
memcpy(&pTableMetaInfo->name, taosArrayGet(req->pTableName, 0), sizeof(SName));
pTableMetaInfo->pTableMeta = (STableMeta*)calloc(1, sizeof(STableMeta) + 4 * sizeof(SSchema));
strcpy(pTableMetaInfo->aliasName, name->tname);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
pTableMeta->tableType = TSDB_NORMAL_TABLE;
pTableMeta->tableInfo.numOfColumns = 4;
pTableMeta->tableInfo.rowSize = 28;
pTableMeta->uid = 110;
pTableMetaInfo->tagColList = (SArray*) taosArrayInit(4, POINTER_BYTES);
SSchema* pSchema = pTableMetaInfo->pTableMeta->schema;
setSchema(&pSchema[0], TSDB_DATA_TYPE_TIMESTAMP, 8, "ts", 0);
setSchema(&pSchema[1], TSDB_DATA_TYPE_INT, 4, "a", 1);
setSchema(&pSchema[2], TSDB_DATA_TYPE_DOUBLE, 8, "b", 2);
setSchema(&pSchema[3], TSDB_DATA_TYPE_DOUBLE, 8, "col", 3);
}
void generateLogicplan(const char* sql) {
SSqlInfo info1 = doGenerateAST(sql);
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_EQ(ret, 0);
struct SQueryPlanNode* n = nullptr;
code = createQueryPlan((const SQueryNode*)pQueryInfo, &n);
char* str = NULL;
queryPlanToString(n, &str);
printf("--------SQL:%s\n", sql);
printf("%s\n", str);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
}
TEST(testCase, planner_test) {
SSqlInfo info1 = doGenerateAST("select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)");
ASSERT_EQ(info1.valid, true);
char msg[128] = {0};
SMsgBuf buf;
buf.len = 128;
buf.buf = msg;
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0);
SCatalogReq req = {0};
SParseContext ctx = {0};
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128);
ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
SQueryStmtInfo* pQueryInfo = createQueryInfo();
setTableMetaInfo(pQueryInfo, &req);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ASSERT_EQ(ret, 0);
SArray* pExprList = pQueryInfo->exprList[0];
int32_t num = tsCompatibleModel? 2:1;
ASSERT_EQ(taosArrayGetSize(pExprList), num);
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 1);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 1);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)");
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)");
ASSERT_EQ(p1->base.interBytes, 16);
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
ASSERT_STREQ(p1->pExpr->_function.functionName, "top");
tExprNode* pParam = p1->pExpr->_function.pChild[0];
ASSERT_EQ(pParam->nodeType, TEXPR_COL_NODE);
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
struct SQueryPlanNode* n = nullptr;
code = createQueryPlan((const SQueryNode*)pQueryInfo, &n);
char* str = NULL;
queryPlanToString(n, &str);
printf("%s\n", str);
destroyQueryInfo(pQueryInfo);
qParserCleanupMetaRequestInfo(&req);
destroySqlInfo(&info1);
}
TEST(testCase, displayPlan) {
generateLogicplan("select count(*) from `t.1abc`");
generateLogicplan("select count(*)+ 22 from `t.1abc`");
generateLogicplan("select count(*)+ 22 from `t.1abc` interval(1h, 20s) sliding(10m) limit 20,30");
generateLogicplan("select count(*) from `t.1abc` group by a");
generateLogicplan("select count(A+B) from `t.1abc` group by a");
generateLogicplan("select count(length(a)+b) from `t.1abc` group by a");
generateLogicplan("select count(*) from `t.1abc` interval(10s, 5s) sliding(7s)");
generateLogicplan("select count(*) from `t.1abc` interval(10s, 5s) sliding(7s) order by 1 desc ");
generateLogicplan("select count(*),sum(a),avg(b),min(a+b)+99 from `t.1abc`");
generateLogicplan("select count(*), min(a) + 99 from `t.1abc`");
generateLogicplan("select count(length(count(*) + 22)) from `t.1abc`");
generateLogicplan("select concat(concat(a,b), concat(a,b)) from `t.1abc` limit 20");
generateLogicplan("select count(*), first(a), last(b) from `t.1abc` state_window(a)");
generateLogicplan("select count(*), first(a), last(b) from `t.1abc` session(ts, 20s)");
// order by + group by column + limit offset
generateLogicplan("select top(a, 20) k from `t.1abc` order by k asc limit 3 offset 1");
// fill
generateLogicplan("select min(a) from `t.1abc` where ts>now and ts<now+2h interval(1s) fill(linear)");
// union + union all
// join
// Aggregate(count(*) [count(*) #5056], sum(a) [sum(a) #5057], avg(b) [avg(b) #5058], min(a+b) [min(a+b) #5060])
// Projection(cols: [a+b #5059]) filters:(nil)
// Projection(cols: [ts #0], [a #1], [b #2]) filters:(nil)
// TableScan(t.1abc #110) time_range: -9223372036854775808 - 9223372036854775807
}
#pragma GCC diagnostic pop

View File

@ -1,3 +1,5 @@
#if 0
#include <gtest/gtest.h>
#include <iostream>
@ -723,4 +725,6 @@ TEST(testCase, extractMeta_test) {
destroySqlInfo(&info1);
}
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

View File

@ -1,137 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_PLANNER_INT_H_
#define _TD_PLANNER_INT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "common.h"
#include "tarray.h"
#include "planner.h"
#include "parser.h"
#include "tmsg.h"
#define QNODE_TAGSCAN 1
#define QNODE_TABLESCAN 2
#define QNODE_STREAMSCAN 3
#define QNODE_PROJECT 4
#define QNODE_AGGREGATE 5
#define QNODE_GROUPBY 6
#define QNODE_LIMIT 7
#define QNODE_JOIN 8
#define QNODE_DISTINCT 9
#define QNODE_SORT 10
#define QNODE_UNION 11
#define QNODE_TIMEWINDOW 12
#define QNODE_SESSIONWINDOW 13
#define QNODE_STATEWINDOW 14
#define QNODE_FILL 15
#define QNODE_MODIFY 16
typedef struct SQueryDistPlanNodeInfo {
bool stableQuery; // super table query or not
int32_t phase; // merge|partial
int32_t type; // operator type
char *name; // operator name
SEpSet *sourceEp; // data source epset
} SQueryDistPlanNodeInfo;
typedef struct SQueryTableInfo {
char *tableName; // to be deleted
uint64_t uid; // to be deleted
STableMetaInfo *pMeta;
STimeWindow window;
} SQueryTableInfo;
typedef struct SQueryPlanNode {
SQueryNodeBasicInfo info;
SSchema *pSchema; // the schema of the input SSDatablock
int32_t numOfCols; // number of input columns
SArray *pExpr; // the query functions or sql aggregations
int32_t numOfExpr; // number of result columns, which is also the number of pExprs
void *pExtInfo; // additional information
// children operator to generated result for current node to process
// in case of join, multiple prev nodes exist.
SArray *pChildren; // upstream nodes
struct SQueryPlanNode *pParent;
} SQueryPlanNode;
typedef struct SDataPayloadInfo {
int32_t msgType;
SArray *payload;
} SDataPayloadInfo;
/**
* Optimize the query execution plan, currently not implement yet.
* @param pQueryNode
* @return
*/
int32_t optimizeQueryPlan(struct SQueryPlanNode* pQueryNode);
/**
* Create the query plan according to the bound AST, which is in the form of pQueryInfo
* @param pQueryInfo
* @param pQueryNode
* @return
*/
int32_t createQueryPlan(const SQueryNode* pNode, struct SQueryPlanNode** pQueryPlan);
/**
* Convert the query plan to string, in order to display it in the shell.
* @param pQueryNode
* @return
*/
int32_t queryPlanToString(struct SQueryPlanNode* pQueryNode, char** str);
/**
* Restore the SQL statement according to the logic query plan.
* @param pQueryNode
* @param sql
* @return
*/
int32_t queryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql);
int32_t createDag(SQueryPlanNode* pQueryNode, struct SCatalog* pCatalog, SQueryDag** pDag, SArray* pNodeList, uint64_t requestId);
void setSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SDownstreamSource* pSource);
int32_t subPlanToString(const SSubplan *pPhyNode, char** str, int32_t* len);
int32_t stringToSubplan(const char* str, SSubplan** subplan);
/**
* Destroy the query plan object.
* @return
*/
void destroyQueryPlan(struct SQueryPlanNode* pQueryNode);
/**
* Destroy the physical plan.
* @param pQueryPhyNode
* @return
*/
void* destroyQueryPhyPlan(struct SPhyNode* pQueryPhyNode);
const char* opTypeToOpName(int32_t type);
int32_t opNameToOpType(const char* name);
const char* dsinkTypeToDsinkName(int32_t type);
int32_t dsinkNameToDsinkType(const char* name);
#ifdef __cplusplus
}
#endif
#endif /*_TD_PLANNER_INT_H_*/

View File

@ -1,29 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_PLANNERUTIL_H
#define TDENGINE_PLANNERUTIL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "parser.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif // TDENGINE_PLANNERUTIL_H

View File

@ -13,6 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if 0
#include <function.h>
#include "function.h"
#include "os.h"
@ -664,3 +666,5 @@ int32_t queryPlanToString(struct SQueryPlanNode* pQueryNode, char** str) {
SQueryPlanNode* queryPlanFromString() {
return NULL;
}
#endif

View File

@ -13,6 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if 0
#include "plannerInt.h"
#include "exception.h"
#include "parser.h"
@ -488,3 +490,5 @@ void qDestroySubplan(SSubplan* pSubplan) {
tfree(pSubplan);
}
#endif

View File

@ -13,6 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if 0
#include "plannerInt.h"
#include "parser.h"
#include "cJSON.h"
@ -1221,3 +1223,5 @@ SQueryDag* qStringToDag(const char* pStr) {
cJSON* pRoot = cJSON_Parse(pStr);
return qJsonToDag(pRoot);
}
#endif

View File

@ -13,90 +13,32 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "parser.h"
#include "plannerInt.h"
#include "planner.h"
static void extractResSchema(struct SQueryDag* const* pDag, SSchema** pResSchema, int32_t* numOfCols);
int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan) {
void qDestroyQueryDag(struct SQueryDag* pDag) {
if (pDag == NULL) {
return;
}
size_t size = taosArrayGetSize(pDag->pSubplans);
for(size_t i = 0; i < size; ++i) {
SArray* pa = taosArrayGetP(pDag->pSubplans, i);
size_t t = taosArrayGetSize(pa);
for(int32_t j = 0; j < t; ++j) {
SSubplan* pSubplan = taosArrayGetP(pa, j);
qDestroySubplan(pSubplan);
}
taosArrayDestroy(pa);
}
taosArrayDestroy(pDag->pSubplans);
tfree(pDag);
}
int32_t qCreateQueryDag(const struct SQueryNode* pNode, struct SQueryDag** pDag, SSchema** pResSchema, int32_t* numOfCols, SArray* pNodeList,
uint64_t requestId) {
SQueryPlanNode* pLogicPlan;
int32_t code = createQueryPlan(pNode, &pLogicPlan);
if (TSDB_CODE_SUCCESS != code) {
destroyQueryPlan(pLogicPlan);
return code;
}
if (pLogicPlan->info.type != QNODE_MODIFY) {
char* str = NULL;
queryPlanToString(pLogicPlan, &str);
qDebug("reqId:0x%"PRIx64": %s", requestId, str);
tfree(str);
}
code = optimizeQueryPlan(pLogicPlan);
if (TSDB_CODE_SUCCESS != code) {
destroyQueryPlan(pLogicPlan);
return code;
}
code = createDag(pLogicPlan, NULL, pDag, pNodeList, requestId);
if (TSDB_CODE_SUCCESS != code) {
destroyQueryPlan(pLogicPlan);
qDestroyQueryDag(*pDag);
return code;
}
extractResSchema(pDag, pResSchema, numOfCols);
destroyQueryPlan(pLogicPlan);
return TSDB_CODE_SUCCESS;
}
// extract the final result schema
void extractResSchema(struct SQueryDag* const* pDag, SSchema** pResSchema, int32_t* numOfCols) {
SArray* pTopSubplan = taosArrayGetP((*pDag)->pSubplans, 0);
SSubplan* pPlan = taosArrayGetP(pTopSubplan, 0);
SDataBlockSchema* pDataBlockSchema = &(pPlan->pDataSink->schema);
*numOfCols = pDataBlockSchema->numOfCols;
if (*numOfCols > 0) {
*pResSchema = calloc(pDataBlockSchema->numOfCols, sizeof(SSchema));
memcpy((*pResSchema), pDataBlockSchema->pSchema, pDataBlockSchema->numOfCols * sizeof(SSchema));
}
}
void qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SDownstreamSource* pSource) {
setSubplanExecutionNode(subplan, templateId, pSource);
}
int32_t qSubPlanToString(const SSubplan *subplan, char** str, int32_t* len) {
return subPlanToString(subplan, str, len);
int32_t qSubPlanToString(const SSubplan* subplan, char** str, int32_t* len) {
}
int32_t qStringToSubplan(const char* str, SSubplan** subplan) {
return stringToSubplan(str, subplan);
}
char* qQueryPlanToString(const SQueryPlan* pPlan) {
}
SQueryPlan* qStringToQueryPlan(const char* pStr) {
}
void qDestroyQueryPlan(SQueryPlan* pPlan) {
}

View File

@ -14,7 +14,9 @@
*/
#include "plannerImpl.h"
#include "functionMgt.h"
#include "query.h"
#define CHECK_ALLOC(p, res) \
do { \
@ -33,13 +35,13 @@
} \
} while (0)
typedef struct SPlanContext {
typedef struct SLogicPlanContext {
int32_t errCode;
int32_t planNodeId;
} SPlanContext;
} SLogicPlanContext;
static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt);
static SLogicNode* createLogicNodeByTable(SPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable);
static SLogicNode* createQueryLogicNode(SLogicPlanContext* pCxt, SNode* pStmt);
static SLogicNode* createLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable);
typedef struct SRewriteExprCxt {
int32_t errCode;
@ -109,7 +111,7 @@ static int32_t rewriteExpr(int32_t planNodeId, int32_t rewriteId, SNodeList* pEx
return cxt.errCode;
}
static SLogicNode* pushLogicNode(SPlanContext* pCxt, SLogicNode* pRoot, SLogicNode* pNode) {
static SLogicNode* pushLogicNode(SLogicPlanContext* pCxt, SLogicNode* pRoot, SLogicNode* pNode) {
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
goto error;
}
@ -138,7 +140,7 @@ error:
return pRoot;
}
static SLogicNode* createScanLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable) {
static SLogicNode* createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable) {
SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN);
CHECK_ALLOC(pScan, NULL);
pScan->node.id = pCxt->planNodeId++;
@ -166,7 +168,7 @@ static SLogicNode* createScanLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect,
return (SLogicNode*)pScan;
}
static SLogicNode* createSubqueryLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect, STempTableNode* pTable) {
static SLogicNode* createSubqueryLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, STempTableNode* pTable) {
SLogicNode* pRoot = createQueryLogicNode(pCxt, pTable->pSubquery);
CHECK_ALLOC(pRoot, NULL);
SNode* pNode;
@ -176,7 +178,7 @@ static SLogicNode* createSubqueryLogicNode(SPlanContext* pCxt, SSelectStmt* pSel
return pRoot;
}
static SLogicNode* createJoinLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect, SJoinTableNode* pJoinTable) {
static SLogicNode* createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SJoinTableNode* pJoinTable) {
SJoinLogicNode* pJoin = (SJoinLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_JOIN);
CHECK_ALLOC(pJoin, NULL);
pJoin->node.id = pCxt->planNodeId++;
@ -209,7 +211,7 @@ static SLogicNode* createJoinLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect,
return (SLogicNode*)pJoin;
}
static SLogicNode* createLogicNodeByTable(SPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable) {
static SLogicNode* createLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable) {
switch (nodeType(pTable)) {
case QUERY_NODE_REAL_TABLE:
return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable);
@ -255,7 +257,7 @@ static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
return DEAL_RES_CONTINUE;
}
static SNodeList* createColumnByRewriteExps(SPlanContext* pCxt, SNodeList* pExprs) {
static SNodeList* createColumnByRewriteExps(SLogicPlanContext* pCxt, SNodeList* pExprs) {
SCreateColumnCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pList = nodesMakeList() };
CHECK_ALLOC(cxt.pList, NULL);
@ -267,7 +269,7 @@ static SNodeList* createColumnByRewriteExps(SPlanContext* pCxt, SNodeList* pExpr
return cxt.pList;
}
static SLogicNode* createAggLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
static SLogicNode* createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
SNodeList* pAggFuncs = NULL;
CHECK_CODE(nodesCollectFuncs(pSelect, fmIsAggFunc, &pAggFuncs), NULL);
if (NULL == pAggFuncs && NULL == pSelect->pGroupByList) {
@ -314,7 +316,7 @@ static SLogicNode* createAggLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect)
return (SLogicNode*)pAgg;
}
static SNodeList* createColumnByProjections(SPlanContext* pCxt, SNodeList* pExprs) {
static SNodeList* createColumnByProjections(SLogicPlanContext* pCxt, SNodeList* pExprs) {
SNodeList* pList = nodesMakeList();
CHECK_ALLOC(pList, NULL);
SNode* pNode;
@ -336,7 +338,7 @@ error:
return NULL;
}
static SLogicNode* createProjectLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
static SLogicNode* createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
SProjectLogicNode* pProject = (SProjectLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PROJECT);
CHECK_ALLOC(pProject, NULL);
pProject->node.id = pCxt->planNodeId++;
@ -349,7 +351,7 @@ static SLogicNode* createProjectLogicNode(SPlanContext* pCxt, SSelectStmt* pSele
return (SLogicNode*)pProject;
}
static SLogicNode* createSelectLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
static SLogicNode* createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
SLogicNode* pRoot = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable);
if (TSDB_CODE_SUCCESS == pCxt->errCode && NULL != pSelect->pWhere) {
pRoot->pConditions = nodesCloneNode(pSelect->pWhere);
@ -364,7 +366,7 @@ static SLogicNode* createSelectLogicNode(SPlanContext* pCxt, SSelectStmt* pSelec
return pRoot;
}
static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt) {
static SLogicNode* createQueryLogicNode(SLogicPlanContext* pCxt, SNode* pStmt) {
switch (nodeType(pStmt)) {
case QUERY_NODE_SELECT_STMT:
return createSelectLogicNode(pCxt, (SSelectStmt*)pStmt);
@ -374,7 +376,7 @@ static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt) {
}
int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode) {
SPlanContext cxt = { .errCode = TSDB_CODE_SUCCESS, .planNodeId = 1 };
SLogicPlanContext cxt = { .errCode = TSDB_CODE_SUCCESS, .planNodeId = 1 };
SLogicNode* pRoot = createQueryLogicNode(&cxt, pNode);
if (TSDB_CODE_SUCCESS != cxt.errCode) {
nodesDestroyNode((SNode*)pRoot);

View File

@ -1,6 +0,0 @@
#include "tvariant.h"
#include "plannerUtil.h"

View File

@ -18,7 +18,7 @@
#include <gtest/gtest.h>
#include "plannerImpl.h"
#include "newParser.h"
#include "parser.h"
using namespace std;
using namespace testing;
@ -46,17 +46,17 @@ protected:
}
bool run(TestTarget target = TEST_PHYSICAL_PLAN) {
int32_t code = parser(&cxt_, &query_);
int32_t code = qParseQuerySql(&cxt_, &query_);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] parser code:" << code << ", strerror:" << tstrerror(code) << ", msg:" << errMagBuf_ << endl;
return false;
}
const string syntaxTreeStr = toString(query_.pRoot, false);
const string syntaxTreeStr = toString(query_->pRoot, false);
SLogicNode* pLogicPlan = nullptr;
code = createLogicPlan(query_.pRoot, &pLogicPlan);
code = createLogicPlan(query_->pRoot, &pLogicPlan);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] logic plan code:" << code << ", strerror:" << tstrerror(code) << endl;
return false;
@ -110,7 +110,7 @@ private:
char errMagBuf_[max_err_len];
string sqlBuf_;
SParseContext cxt_;
SQuery query_;
SQuery* query_;
};
TEST_F(NewPlannerTest, simple) {

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if 0
#include <gtest/gtest.h>
#include "plannerInt.h"
@ -205,3 +205,4 @@ TEST_F(PhyPlanTest, insertTest) {
SQueryDag* dag = result();
// todo check
}
#endif

View File

@ -53,7 +53,7 @@ TEST(testCase, planner_test) {
char msg[128] = {0};
const char* sql = "select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)";
SQueryStmtInfo* pQueryInfo = nullptr;
// SQueryStmtInfo* pQueryInfo = nullptr;
// int32_t code = qParseQuerySql(sql, strlen(sql), &pQueryInfo, 0, msg, sizeof(msg));
// ASSERT_EQ(code, 0);

View File

@ -8,7 +8,7 @@ target_include_directories(
)
target_link_libraries(qworker
PRIVATE os util transport planner qcom executor
PRIVATE os util transport nodes planner qcom executor
)
if(${BUILD_TEST})

View File

@ -8,7 +8,7 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
ADD_EXECUTABLE(qworkerTest ${SOURCE_LIST})
TARGET_LINK_LIBRARIES(
qworkerTest
PUBLIC os util common transport gtest qcom planner qworker executor
PUBLIC os util common transport gtest qcom nodes planner qworker executor
)
TARGET_INCLUDE_DIRECTORIES(

View File

@ -9,7 +9,7 @@ target_include_directories(
target_link_libraries(
scheduler
PUBLIC os util planner qcom common catalog transport
PUBLIC os util nodes planner qcom common catalog transport
)
if(${BUILD_TEST})

View File

@ -303,7 +303,7 @@ int32_t schRecordTaskExecNode(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *ad
}
int32_t schValidateAndBuildJob(SQueryDag *pDag, SSchJob *pJob) {
int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) {
int32_t code = 0;
pJob->queryId = pDag->queryId;
@ -1283,7 +1283,7 @@ void schDropJobAllTasks(SSchJob *pJob) {
schDropTaskInHashList(pJob, pJob->failTasks);
}
static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryDag* pDag, struct SSchJob** job, const char* sql, bool syncSchedule) {
static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan* pDag, struct SSchJob** job, const char* sql, bool syncSchedule) {
qDebug("QID:0x%"PRIx64" job started", pDag->queryId);
if (pNodeList == NULL || (pNodeList && taosArrayGetSize(pNodeList) <= 0)) {
@ -1398,7 +1398,7 @@ int32_t schedulerInit(SSchedulerCfg *cfg) {
return TSDB_CODE_SUCCESS;
}
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, struct SSchJob** pJob, const char* sql, SQueryResult *pRes) {
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan* pDag, struct SSchJob** pJob, const char* sql, SQueryResult *pRes) {
if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob || NULL == pRes) {
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
}
@ -1410,7 +1410,7 @@ int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, str
return TSDB_CODE_SUCCESS;
}
int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryDag* pDag, const char* sql, struct SSchJob** pJob) {
int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryPlan* pDag, const char* sql, struct SSchJob** pJob) {
if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob) {
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
}
@ -1419,7 +1419,7 @@ int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryDag* pDa
return TSDB_CODE_SUCCESS;
}
int32_t schedulerConvertDagToTaskList(SQueryDag* pDag, SArray **pTasks) {
int32_t schedulerConvertDagToTaskList(SQueryPlan* pDag, SArray **pTasks) {
if (NULL == pDag || pDag->numOfSubplans <= 0 || taosArrayGetSize(pDag->pSubplans) == 0) {
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
}

View File

@ -73,7 +73,7 @@ void schtInitLogFile() {
}
void schtBuildQueryDag(SQueryDag *dag) {
void schtBuildQueryDag(SQueryPlan *dag) {
uint64_t qId = schtQueryId;
dag->queryId = qId;
@ -97,7 +97,7 @@ void schtBuildQueryDag(SQueryDag *dag) {
scanPlan->pChildren = NULL;
scanPlan->level = 1;
scanPlan->pParents = taosArrayInit(1, POINTER_BYTES);
scanPlan->pNode = (SPhyNode*)calloc(1, sizeof(SPhyNode));
scanPlan->pNode = (SPhysiNode*)calloc(1, sizeof(SPhysiNode));
scanPlan->msgType = TDMT_VND_QUERY;
mergePlan->id.queryId = qId;
@ -109,7 +109,7 @@ void schtBuildQueryDag(SQueryDag *dag) {
mergePlan->pChildren = taosArrayInit(1, POINTER_BYTES);
mergePlan->pParents = NULL;
mergePlan->pNode = (SPhyNode*)calloc(1, sizeof(SPhyNode));
mergePlan->pNode = (SPhysiNode*)calloc(1, sizeof(SPhysiNode));
mergePlan->msgType = TDMT_VND_QUERY;
SSubplan *mergePointer = (SSubplan *)taosArrayPush(merge, &mergePlan);
@ -122,12 +122,12 @@ void schtBuildQueryDag(SQueryDag *dag) {
taosArrayPush(dag->pSubplans, &scan);
}
void schtFreeQueryDag(SQueryDag *dag) {
void schtFreeQueryDag(SQueryPlan *dag) {
}
void schtBuildInsertDag(SQueryDag *dag) {
void schtBuildInsertDag(SQueryPlan *dag) {
uint64_t qId = 0x0000000000000002;
dag->queryId = qId;
@ -150,7 +150,7 @@ void schtBuildInsertDag(SQueryDag *dag) {
insertPlan[0].pChildren = NULL;
insertPlan[0].pParents = NULL;
insertPlan[0].pNode = NULL;
insertPlan[0].pDataSink = (SDataSink*)calloc(1, sizeof(SDataSink));
insertPlan[0].pDataSink = (SDataSinkNode*)calloc(1, sizeof(SDataSinkNode));
insertPlan[0].msgType = TDMT_VND_SUBMIT;
insertPlan[1].id.queryId = qId;
@ -166,7 +166,7 @@ void schtBuildInsertDag(SQueryDag *dag) {
insertPlan[1].pChildren = NULL;
insertPlan[1].pParents = NULL;
insertPlan[1].pNode = NULL;
insertPlan[1].pDataSink = (SDataSink*)calloc(1, sizeof(SDataSink));
insertPlan[1].pDataSink = (SDataSinkNode*)calloc(1, sizeof(SDataSinkNode));
insertPlan[1].msgType = TDMT_VND_SUBMIT;
taosArrayPush(inserta, &insertPlan);
@ -347,7 +347,7 @@ void* schtRunJobThread(void *aa) {
char *dbname = "1.db1";
char *tablename = "table1";
SVgroupInfo vgInfo = {0};
SQueryDag dag = {0};
SQueryPlan dag = {0};
schtInitLogFile();
@ -517,7 +517,7 @@ TEST(queryTest, normalCase) {
char *tablename = "table1";
SVgroupInfo vgInfo = {0};
SSchJob *pJob = NULL;
SQueryDag dag = {0};
SQueryPlan dag = {0};
schtInitLogFile();
@ -620,7 +620,7 @@ TEST(insertTest, normalCase) {
char *dbname = "1.db1";
char *tablename = "table1";
SVgroupInfo vgInfo = {0};
SQueryDag dag = {0};
SQueryPlan dag = {0};
uint64_t numOfRows = 0;
schtInitLogFile();