From a67b0c99fc638644ede67049d7fa59e94f637511 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Thu, 21 Sep 2023 19:28:07 +0800 Subject: [PATCH] feat: support create/drop view --- include/common/tmsg.h | 8 ++-- include/common/tmsgdef.h | 3 +- include/common/ttokendef.h | 1 + include/libs/nodes/cmdnodes.h | 1 + include/libs/parser/parser.h | 2 +- source/client/inc/clientInt.h | 1 + source/client/src/clientImpl.c | 15 +++++- source/client/src/clientMain.c | 2 +- source/common/src/tmsg.c | 52 +++++++++++++++++++-- source/dnode/mgmt/mgmt_mnode/src/mmHandle.c | 1 + source/dnode/mnode/impl/CMakeLists.txt | 1 + source/dnode/mnode/impl/inc/mndView.h | 17 +++++++ source/dnode/mnode/impl/src/mndMain.c | 2 + source/dnode/mnode/impl/src/mndView.c | 21 +++++---- source/dnode/mnode/sdb/src/sdbHash.c | 2 + source/libs/parser/inc/parAst.h | 2 + source/libs/parser/inc/parInt.h | 1 + source/libs/parser/inc/parUtil.h | 2 + source/libs/parser/inc/sql.y | 4 +- source/libs/parser/src/parAstCreater.c | 2 + source/libs/parser/src/parAstParser.c | 26 +++++++---- source/libs/parser/src/parTokenizer.c | 1 + source/libs/parser/src/parTranslater.c | 33 +++++++++---- source/libs/parser/src/sql.c | 4 +- source/util/src/terror.c | 5 ++ 25 files changed, 165 insertions(+), 44 deletions(-) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index a1e273cc46..60d53b8311 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -3903,6 +3903,7 @@ typedef struct { } SPackedData; typedef struct { + char fullname[TSDB_VIEW_FNAME_LEN]; char name[TSDB_VIEW_NAME_LEN]; char dbFName[TSDB_DB_FNAME_LEN]; char* querySql; @@ -3914,17 +3915,14 @@ typedef struct { SRWLatch lock; } SCMCreateViewReq; -typedef struct { - int64_t streamId; -} SCMCreateViewRsp; - int32_t tSerializeSCMCreateViewReq(void* buf, int32_t bufLen, const SCMCreateViewReq* pReq); int32_t tDeserializeSCMCreateViewReq(void* buf, int32_t bufLen, SCMCreateViewReq* pReq); void tFreeSCMCreateViewReq(SCMCreateViewReq* pReq); typedef struct { + char fullname[TSDB_VIEW_FNAME_LEN]; + char name[TSDB_VIEW_NAME_LEN]; char dbFName[TSDB_DB_FNAME_LEN]; - char viewName[TSDB_VIEW_NAME_LEN]; char* sql; int8_t igNotExists; } SCMDropViewReq; diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 144efc9945..2bdc998c95 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -189,7 +189,8 @@ enum { // WARN: new msg should be appended to segment tail TD_DEF_MSG_TYPE(TDMT_MND_STREAM_BEGIN_CHECKPOINT, "stream-begin-checkpoint", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_STREAM_NODECHANGE_CHECK, "stream-nodechange-check", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_TRIM_DB_TIMER, "trim-db-tmr", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_MND_CREATE_VIEW, "create-view", SCMCreateViewReq, SCMCreateViewRsp) + TD_DEF_MSG_TYPE(TDMT_MND_CREATE_VIEW, "create-view", SCMCreateViewReq, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_DROP_VIEW, "drop-view", SCMDropViewReq, NULL) TD_NEW_MSG_SEG(TDMT_VND_MSG) TD_DEF_MSG_TYPE(TDMT_VND_SUBMIT, "submit", SSubmitReq, SSubmitRsp) diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h index 7f60353fb7..3ef8a5f1d2 100644 --- a/include/common/ttokendef.h +++ b/include/common/ttokendef.h @@ -359,6 +359,7 @@ + #define TK_NK_SPACE 600 #define TK_NK_COMMENT 601 #define TK_NK_ILLEGAL 602 diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index c81835f3b2..e210f10e90 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -496,6 +496,7 @@ typedef struct SCreateViewStmt { ENodeType type; char dbName[TSDB_DB_NAME_LEN]; char viewName[TSDB_VIEW_NAME_LEN]; + char* pQuerySql; bool orReplace; SNodeList* pCols; SNode* pQuery; diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 66fdd6f66c..50d77c03fa 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -33,7 +33,7 @@ typedef struct SStmtCallback { int32_t (*getExecInfoFn)(TAOS_STMT*, SHashObj**, SHashObj**); } SStmtCallback; -typedef int32_t (*validateSqlFn)(void* param, SQuery* pQuery, const char* sql, SQueryResInfo* pRes); +typedef int32_t (*validateSqlFn)(void* param, SQuery* pQuery, const char* sql, SCMCreateViewReq* pRes); typedef struct SParseCsvCxt { TdFilePtr fp; // last parsed file diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 9448634c5b..56ee7e41d4 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -300,6 +300,7 @@ void taosAsyncQueryImpl(uint64_t connId, const char* sql, __taos_async_fn_t fp, void taosAsyncQueryImplWithReqid(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly, int64_t reqid); void taosAsyncFetchImpl(SRequestObj *pRequest, __taos_async_fn_t fp, void *param); +int32_t clientValidateSql(void* param, SQuery* pQuery, const char* sql, SCMCreateViewReq* pReq); int32_t getVersion1BlockMetaSize(const char* p, int32_t numOfCols); diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index db219c5c17..4ffd34b167 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -2592,6 +2592,12 @@ void taosAsyncFetchImpl(SRequestObj* pRequest, __taos_async_fn_t fp, void* param schedulerFetchRows(pRequest->body.queryJob, &req); } +int32_t asyncValidateSql(void* param) { + doAsyncQuery((SRequestObj*)param, false); + return TSDB_CODE_SUCCESS; +} + + int32_t clientValidateSql(void* param, SQuery* pQuery, const char* sql, SCMCreateViewReq* pReq) { SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param; SSyncQueryParam* syncParam = taosMemoryCalloc(1, sizeof(SSyncQueryParam)); @@ -2605,9 +2611,14 @@ int32_t clientValidateSql(void* param, SQuery* pQuery, const char* sql, SCMCreat return code; } - pNewRequest->pQuery = pQuery; + //pNewRequest->pQuery = pQuery; pNewRequest->body.queryFp = syncQueryFn; - doAsyncQuery(pNewRequest, false); + + code = taosAsyncExec(asyncValidateSql, pNewRequest, NULL); + if (TSDB_CODE_SUCCESS != code) { + tscError("failed to sched async validate sql"); + return code; + } tsem_wait(&syncParam->sem); diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 09d39122b9..69be3f805f 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -32,7 +32,7 @@ #define TSC_VAR_RELEASED 0 static int32_t sentinel = TSC_VAR_NOT_RELEASE; -static int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt); +static int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper); int taos_options(TSDB_OPTION option, const void *arg, ...) { static int32_t lock = 0; diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 0cddccac46..14f82b988a 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -8431,8 +8431,10 @@ int32_t tSerializeSCMCreateViewReq(void *buf, int32_t bufLen, const SCMCreateVie tEncoderInit(&encoder, buf, bufLen); if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->fullname) < 0) return -1; if (tEncodeCStr(&encoder, pReq->name) < 0) return -1; if (tEncodeCStr(&encoder, pReq->dbFName) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->querySql) < 0) return -1; if (tEncodeCStr(&encoder, pReq->sql) < 0) return -1; if (tEncodeI8(&encoder, pReq->orReplace) < 0) return -1; if (tEncodeI8(&encoder, pReq->precision) < 0) return -1; @@ -8454,8 +8456,10 @@ int32_t tDeserializeSCMCreateViewReq(void *buf, int32_t bufLen, SCMCreateViewReq tDecoderInit(&decoder, buf, bufLen); if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->fullname) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->name) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->dbFName) < 0) return -1; + if (tDecodeCStrAlloc(&decoder, &pReq->querySql) < 0) return -1; if (tDecodeCStrAlloc(&decoder, &pReq->sql) < 0) return -1; if (tDecodeI8(&decoder, &pReq->orReplace) < 0) return -1; if (tDecodeI8(&decoder, &pReq->precision) < 0) return -1; @@ -8484,13 +8488,53 @@ void tFreeSCMCreateViewReq(SCMCreateViewReq* pReq) { if (NULL == pReq) { return; } - + + taosMemoryFree(pReq->querySql); + taosMemoryFree(pReq->sql); taosMemoryFree(pReq->pSchema); } -int32_t tSerializeSCMDropViewReq(void* buf, int32_t bufLen, const SCMDropViewReq* pReq); -int32_t tDeserializeSCMDropViewReq(void* buf, int32_t bufLen, SCMDropViewReq* pReq); -void tFreeSCMDropViewReq(SCMDropViewReq* pReq); +int32_t tSerializeSCMDropViewReq(void* buf, int32_t bufLen, const SCMDropViewReq* pReq) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->fullname) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->name) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->dbFName) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->sql) < 0) return -1; + if (tEncodeI8(&encoder, pReq->igNotExists) < 0) return -1; + + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSCMDropViewReq(void* buf, int32_t bufLen, SCMDropViewReq* pReq) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->fullname) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->name) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->dbFName) < 0) return -1; + if (tDecodeCStrAlloc(&decoder, &pReq->sql) < 0) return -1; + if (tDecodeI8(&decoder, &pReq->igNotExists) < 0) return -1; + + tEndDecode(&decoder); + + tDecoderClear(&decoder); + return 0; +} +void tFreeSCMDropViewReq(SCMDropViewReq* pReq) { + if (NULL == pReq) { + return; + } + + taosMemoryFree(pReq->sql); +} diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c index 3679535390..4501a92754 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c @@ -186,6 +186,7 @@ SArray *mmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_INDEX, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_RESTORE_DNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_VIEW, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_VIEW, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SCH_QUERY, mmPutMsgToQueryQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SCH_MERGE_QUERY, mmPutMsgToQueryQueue, 1) == NULL) goto _OVER; diff --git a/source/dnode/mnode/impl/CMakeLists.txt b/source/dnode/mnode/impl/CMakeLists.txt index 48dc71a12b..e613fc2588 100644 --- a/source/dnode/mnode/impl/CMakeLists.txt +++ b/source/dnode/mnode/impl/CMakeLists.txt @@ -7,6 +7,7 @@ IF (TD_ENTERPRISE) LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/mnode/src/mndDb.c) LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/mnode/src/mndVgroup.c) LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/mnode/src/mndDnode.c) + LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/view/src/mndView.c) ENDIF () add_library(mnode STATIC ${MNODE_SRC}) diff --git a/source/dnode/mnode/impl/inc/mndView.h b/source/dnode/mnode/impl/inc/mndView.h index 7c6e102207..bd21d85806 100755 --- a/source/dnode/mnode/impl/inc/mndView.h +++ b/source/dnode/mnode/impl/inc/mndView.h @@ -25,11 +25,28 @@ extern "C" { int32_t mndInitView(SMnode *pMnode); void mndCleanupView(SMnode *pMnode); +int32_t mndProcessCreateViewReq(SRpcMsg *pReq); +int32_t mndProcessDropViewReq(SRpcMsg *pReq); + +#ifdef TD_ENTERPRISE SViewObj *mndAcquireView(SMnode *pMnode, char *viewName); void mndReleaseView(SMnode *pMnode, SViewObj *pView); SSdbRaw *mndViewActionEncode(SViewObj *pView); SSdbRow *mndViewActionDecode(SSdbRaw *pRaw); +int32_t mndViewActionInsert(SSdb *pSdb, SViewObj *pView); +int32_t mndViewActionDelete(SSdb *pSdb, SViewObj *pView); +int32_t mndViewActionUpdate(SSdb *pSdb, SViewObj *pOldView, SViewObj *pNewView); + +int32_t mndProcessCreateViewReqImpl(SCMCreateViewReq* pCreateView, SRpcMsg *pReq); +int32_t mndProcessDropViewReqImpl(SCMDropViewReq* pDropView, SRpcMsg *pReq); + +#endif + +int32_t mndRetrieveView(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); +void mndCancelGetNextView(SMnode *pMnode, void *pIter); + + #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c index 1c87cde78a..817abb1558 100644 --- a/source/dnode/mnode/impl/src/mndMain.c +++ b/source/dnode/mnode/impl/src/mndMain.c @@ -41,6 +41,7 @@ #include "mndTrans.h" #include "mndUser.h" #include "mndVgroup.h" +#include "mndView.h" static inline int32_t mndAcquireRpc(SMnode *pMnode) { int32_t code = 0; @@ -447,6 +448,7 @@ static int32_t mndInitSteps(SMnode *pMnode) { if (mndAllocStep(pMnode, "mnode-perfs", mndInitPerfs, mndCleanupPerfs) != 0) return -1; if (mndAllocStep(pMnode, "mnode-db", mndInitDb, mndCleanupDb) != 0) return -1; if (mndAllocStep(pMnode, "mnode-func", mndInitFunc, mndCleanupFunc) != 0) return -1; + if (mndAllocStep(pMnode, "mnode-view", mndInitView, mndCleanupView) != 0) return -1; if (mndAllocStep(pMnode, "mnode-sdb", mndOpenSdb, NULL) != 0) return -1; if (mndAllocStep(pMnode, "mnode-profile", mndInitProfile, mndCleanupProfile) != 0) return -1; if (mndAllocStep(pMnode, "mnode-show", mndInitShow, mndCleanupShow) != 0) return -1; diff --git a/source/dnode/mnode/impl/src/mndView.c b/source/dnode/mnode/impl/src/mndView.c index 417f03897e..14d6630d78 100755 --- a/source/dnode/mnode/impl/src/mndView.c +++ b/source/dnode/mnode/impl/src/mndView.c @@ -14,11 +14,11 @@ */ #include "mndView.h" +#include "mndShow.h" int32_t mndInitView(SMnode *pMnode) { mndSetMsgHandle(pMnode, TDMT_MND_CREATE_VIEW, mndProcessCreateViewReq); mndSetMsgHandle(pMnode, TDMT_MND_DROP_VIEW, mndProcessDropViewReq); - mndSetMsgHandle(pMnode, TDMT_MND_NODECHECK_TIMER, mndProcessNodeCheck); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_VIEWS, mndRetrieveView); mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_VIEWS, mndCancelGetNextView); @@ -41,13 +41,10 @@ int32_t mndInitView(SMnode *pMnode) { } void mndCleanupView(SMnode *pMnode) { - taosArrayDestroy(execNodeList.pTaskList); - taosHashCleanup(execNodeList.pTaskMap); - taosThreadMutexDestroy(&execNodeList.lock); mDebug("mnd view cleanup"); } -static int32_t mndProcessCreateViewReq(SRpcMsg *pReq) { +int32_t mndProcessCreateViewReq(SRpcMsg *pReq) { #ifndef TD_ENTERPRISE return TSDB_CODE_OPS_NOT_SUPPORT; #else @@ -57,13 +54,13 @@ static int32_t mndProcessCreateViewReq(SRpcMsg *pReq) { return -1; } - mInfo("start to create view:%s, sql:%s", createViewReq.name, createViewReq.sql); + mInfo("start to create view:%s, sql:%s", createViewReq.fullname, createViewReq.sql); return mndProcessCreateViewReqImpl(&createViewReq, pReq); #endif } -static int32_t mndProcessDropViewReq(SRpcMsg *pReq) { +int32_t mndProcessDropViewReq(SRpcMsg *pReq) { #ifndef TD_ENTERPRISE return TSDB_CODE_OPS_NOT_SUPPORT; #else @@ -73,13 +70,14 @@ static int32_t mndProcessDropViewReq(SRpcMsg *pReq) { return -1; } - mInfo("start to drop view:%s, sql:%s", dropViewReq.viewName, dropViewReq.sql); + mInfo("start to drop view:%s, sql:%s", dropViewReq.name, dropViewReq.sql); return mndProcessDropViewReqImpl(&dropViewReq, pReq); #endif } -static int32_t mndRetrieveView(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) { +int32_t mndRetrieveView(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) { +#if 0 SMnode *pMnode = pReq->info.node; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; @@ -149,9 +147,12 @@ static int32_t mndRetrieveView(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo pShow->numOfRows += numOfRows; return numOfRows; +#else + return 0; +#endif } -static void mndCancelGetNextView(SMnode *pMnode, void *pIter) { +void mndCancelGetNextView(SMnode *pMnode, void *pIter) { SSdb *pSdb = pMnode->pSdb; sdbCancelFetch(pSdb, pIter); } diff --git a/source/dnode/mnode/sdb/src/sdbHash.c b/source/dnode/mnode/sdb/src/sdbHash.c index 09743d549a..df5c399da8 100644 --- a/source/dnode/mnode/sdb/src/sdbHash.c +++ b/source/dnode/mnode/sdb/src/sdbHash.c @@ -62,6 +62,8 @@ const char *sdbTableName(ESdbType type) { return "func"; case SDB_IDX: return "idx"; + case SDB_VIEW: + return "view"; default: return "undefine"; } diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index 7ebdc496fd..1ced53bd59 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -248,6 +248,8 @@ SNode* createRevokeStmt(SAstCreateContext* pCxt, int64_t privileges, STokenPair* SNode* pTagCond); SNode* createDeleteStmt(SAstCreateContext* pCxt, SNode* pTable, SNode* pWhere); SNode* createInsertStmt(SAstCreateContext* pCxt, SNode* pTable, SNodeList* pCols, SNode* pQuery); +SNode* createCreateViewStmt(SAstCreateContext* pCxt, bool orReplace, SNode* pView, SNodeList* pCols, const SToken* pAs, SNode* pQuery); +SNode* createDropViewStmt(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pView); #ifdef __cplusplus } diff --git a/source/libs/parser/inc/parInt.h b/source/libs/parser/inc/parInt.h index 69253e62e2..7064fb0b20 100644 --- a/source/libs/parser/inc/parInt.h +++ b/source/libs/parser/inc/parInt.h @@ -36,6 +36,7 @@ int32_t extractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pS int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery); int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow); int32_t translatePostCreateSmaIndex(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow); +int32_t buildQueryAfterParse(SQuery** pQuery, SNode* pRootNode, int16_t placeholderNo, SArray* pPlaceholderValues); #ifdef __cplusplus } diff --git a/source/libs/parser/inc/parUtil.h b/source/libs/parser/inc/parUtil.h index c963984f85..6750fe9ef1 100644 --- a/source/libs/parser/inc/parUtil.h +++ b/source/libs/parser/inc/parUtil.h @@ -103,6 +103,8 @@ int32_t reserveDbVgVersionInCache(int32_t acctId, const char* pDb, SParseMetaCac int32_t reserveDbCfgInCache(int32_t acctId, const char* pDb, SParseMetaCache* pMetaCache); int32_t reserveUserAuthInCache(int32_t acctId, const char* pUser, const char* pDb, const char* pTable, AUTH_TYPE type, SParseMetaCache* pMetaCache); +int32_t reserveViewUserAuthInCache(int32_t acctId, const char* pUser, const char* pDb, const char* pTable, AUTH_TYPE type, + SParseMetaCache* pMetaCache); int32_t reserveUdfInCache(const char* pFunc, SParseMetaCache* pMetaCache); int32_t reserveTableIndexInCache(int32_t acctId, const char* pDb, const char* pTable, SParseMetaCache* pMetaCache); int32_t reserveTableCfgInCache(int32_t acctId, const char* pDb, const char* pTable, SParseMetaCache* pMetaCache); diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 34231e9593..eae362cc02 100755 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -627,8 +627,8 @@ cmd ::= CREATE or_replace_opt(A) VIEW full_view_name(B) col_list_opt(C) AS(D) qu { pCxt->pRootNode = createCreateViewStmt(pCxt, A, B, C, &D, E); } cmd ::= DROP VIEW exists_opt(A) full_view_name(B). { pCxt->pRootNode = createDropViewStmt(pCxt, A, B); } -full_view_name(A) ::= view_name(B). { A = createViewNode(pCxt, NULL, &B, NULL); } -full_view_name(A) ::= db_name(B) NK_DOT view_name(C). { A = createViewNode(pCxt, &B, &C, NULL); } +full_view_name(A) ::= view_name(B). { A = createViewNode(pCxt, NULL, &B); } +full_view_name(A) ::= db_name(B) NK_DOT view_name(C). { A = createViewNode(pCxt, &B, &C); } /************************************************ create/drop stream **************************************************/ cmd ::= CREATE STREAM not_exists_opt(E) stream_name(A) stream_options(B) INTO diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index 99e1d370cd..1ac337f4b7 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -2166,6 +2166,8 @@ SNode* createCreateViewStmt(SAstCreateContext* pCxt, bool orReplace, SNode* pVie CHECK_PARSER_STATUS(pCxt); SCreateViewStmt* pStmt = (SCreateViewStmt*)nodesMakeNode(QUERY_NODE_CREATE_VIEW_STMT); CHECK_OUT_OF_MEM(pStmt); + pStmt->pQuerySql = strdup(pAs->z + pAs->n); + CHECK_OUT_OF_MEM(pStmt->pQuerySql); strcpy(pStmt->dbName, ((SViewNode*)pView)->table.dbName); strcpy(pStmt->viewName, ((SViewNode*)pView)->table.tableName); nodesDestroyNode(pView); diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index c6cd9c7d12..bf6ff87c55 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -29,6 +29,20 @@ extern void Parse(void*, int, SToken, void*); extern void ParseFree(void*, FFree); extern void ParseTrace(FILE*, char*); +int32_t buildQueryAfterParse(SQuery** pQuery, SNode* pRootNode, int16_t placeholderNo, SArray* pPlaceholderValues) { + *pQuery = (SQuery*)nodesMakeNode(QUERY_NODE_QUERY); + if (NULL == *pQuery) { + return TSDB_CODE_OUT_OF_MEMORY; + } + (*pQuery)->pRoot = pRootNode; + (*pQuery)->placeholderNum = placeholderNo; + (*pQuery)->pPlaceholderValues = pPlaceholderValues; + (*pQuery)->execStage = QUERY_EXEC_STAGE_ANALYSE; + + return TSDB_CODE_SUCCESS; +} + + int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) { SAstCreateContext cxt; initAstCreateContext(pParseCxt, &cxt); @@ -77,14 +91,10 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) { abort_parse: ParseFree(pParser, (FFree)taosMemoryFree); if (TSDB_CODE_SUCCESS == cxt.errCode) { - *pQuery = (SQuery*)nodesMakeNode(QUERY_NODE_QUERY); - if (NULL == *pQuery) { - return TSDB_CODE_OUT_OF_MEMORY; + int32_t code = buildQueryAfterParse(pQuery, cxt.pRootNode, cxt.placeholderNo, cxt.pPlaceholderValues); + if (TSDB_CODE_SUCCESS != code) { + return code; } - (*pQuery)->pRoot = cxt.pRootNode; - (*pQuery)->placeholderNum = cxt.placeholderNo; - TSWAP((*pQuery)->pPlaceholderValues, cxt.pPlaceholderValues); - (*pQuery)->execStage = QUERY_EXEC_STAGE_ANALYSE; } taosArrayDestroy(cxt.pPlaceholderValues); return cxt.errCode; @@ -782,7 +792,7 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { return collectMetaKeyFromShowSubscriptions(pCxt, (SShowStmt*)pStmt); case QUERY_NODE_CREATE_VIEW_STMT: return collectMetaKeyFromCreateViewStmt(pCxt, (SCreateViewStmt*)pStmt); - case QUERY_NODE_CREATE_VIEW_STMT: + case QUERY_NODE_DROP_VIEW_STMT: return collectMetaKeyFromDropViewStmt(pCxt, (SDropViewStmt*)pStmt); default: break; diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c index cbb3b1952b..9181ecc896 100644 --- a/source/libs/parser/src/parTokenizer.c +++ b/source/libs/parser/src/parTokenizer.c @@ -263,6 +263,7 @@ static SKeyword keywordTable[] = { {"VERBOSE", TK_VERBOSE}, {"VGROUP", TK_VGROUP}, {"VGROUPS", TK_VGROUPS}, + {"VIEW", TK_VIEW}, {"VNODE", TK_VNODE}, {"VNODES", TK_VNODES}, {"WAL_FSYNC_PERIOD", TK_WAL_FSYNC_PERIOD}, diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 3c3ed31a1f..6b816f755c 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -7272,29 +7272,46 @@ static int32_t validateCreateView(STranslateContext* pCxt, SCreateViewStmt* pStm static int32_t translateCreateView(STranslateContext* pCxt, SCreateViewStmt* pStmt) { int32_t code = validateCreateView(pCxt, pStmt); - if (TSDB_CODE_SUCCESS == code) { - code = (*pCxt->pParseCxt->validateSqlFp)(pCxt->pParseCxt->validateSqlParam, pStmt->pQuery, pCxt->pParseCxt->pSql, &pStmt->createReq); + if (TSDB_CODE_SUCCESS == code) { + SQuery* pQuery = NULL; + code = buildQueryAfterParse(&pQuery, pStmt->pQuery, 0, NULL); + if (TSDB_CODE_SUCCESS == code) { + code = (*pCxt->pParseCxt->validateSqlFp)(pCxt->pParseCxt->validateSqlParam, pQuery, pStmt->pQuerySql, &pStmt->createReq); + } } if (TSDB_CODE_SUCCESS == code) { strncpy(pStmt->createReq.name, pStmt->viewName, sizeof(pStmt->createReq.name) - 1); snprintf(pStmt->createReq.dbFName, sizeof(pStmt->createReq.dbFName) - 1, "%d.%s", pCxt->pParseCxt->acctId, pStmt->dbName); + snprintf(pStmt->createReq.fullname, sizeof(pStmt->createReq.fullname) - 1, "%s.%s", pStmt->createReq.dbFName, pStmt->viewName); + TSWAP(pStmt->createReq.querySql, pStmt->pQuerySql); pStmt->createReq.orReplace = pStmt->orReplace; - + pStmt->createReq.sql = strdup(pCxt->pParseCxt->pSql); + if (NULL == pStmt->createReq.sql) { + code = TSDB_CODE_OUT_OF_MEMORY; + } + } + if (TSDB_CODE_SUCCESS == code) { code = buildCmdMsg(pCxt, TDMT_MND_CREATE_VIEW, (FSerializeFunc)tSerializeSCMCreateViewReq, &pStmt->createReq); } - + tFreeSCMCreateViewReq(&pStmt->createReq); return code; } static int32_t translateDropView(STranslateContext* pCxt, SDropViewStmt* pStmt) { - SMDropViewReq dropReq = {0}; + SCMDropViewReq dropReq = {0}; SName name; tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName)); tNameGetFullDbName(&name, dropReq.dbFName); + strncpy(dropReq.name, pStmt->viewName, sizeof(dropReq.name) - 1); + snprintf(dropReq.fullname, sizeof(dropReq.fullname) - 1, "%s.%s", dropReq.dbFName, dropReq.name); + dropReq.sql = strdup(pCxt->pParseCxt->pSql); + if (NULL == dropReq.sql) { + return TSDB_CODE_OUT_OF_MEMORY; + } dropReq.igNotExists = pStmt->ignoreNotExists; - return buildCmdMsg(pCxt, TDMT_MND_DROP_VIEW, (FSerializeFunc)tSerializeSMDropViewReq, &dropReq); + return buildCmdMsg(pCxt, TDMT_MND_DROP_VIEW, (FSerializeFunc)tSerializeSCMDropViewReq, &dropReq); } @@ -7730,10 +7747,10 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) { code = translateRestoreDnode(pCxt, (SRestoreComponentNodeStmt*)pNode); break; case QUERY_NODE_CREATE_VIEW_STMT: - code = translateCreateView(pCxt, (SCreateStreamStmt*)pNode); + code = translateCreateView(pCxt, (SCreateViewStmt*)pNode); break; case QUERY_NODE_DROP_VIEW_STMT: - code = translateDropView(pCxt, (SCreateStreamStmt*)pNode); + code = translateDropView(pCxt, (SDropViewStmt*)pNode); break; default: diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index 35aa454ee6..b95dbe841a 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -5676,11 +5676,11 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createDropViewStmt(pCxt, yymsp[-1].minor.yy953, yymsp[0].minor.yy168); } break; case 345: /* full_view_name ::= view_name */ -{ yylhsminor.yy168 = createViewNode(pCxt, NULL, &yymsp[0].minor.yy737, NULL); } +{ yylhsminor.yy168 = createViewNode(pCxt, NULL, &yymsp[0].minor.yy737); } yymsp[0].minor.yy168 = yylhsminor.yy168; break; case 346: /* full_view_name ::= db_name NK_DOT view_name */ -{ yylhsminor.yy168 = createViewNode(pCxt, &yymsp[-2].minor.yy737, &yymsp[0].minor.yy737, NULL); } +{ yylhsminor.yy168 = createViewNode(pCxt, &yymsp[-2].minor.yy737, &yymsp[0].minor.yy737); } yymsp[-2].minor.yy168 = yylhsminor.yy168; break; case 347: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ diff --git a/source/util/src/terror.c b/source/util/src/terror.c index d847436669..0b9e10b740 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -316,6 +316,11 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_SMA_ALREADY_EXIST, "index already exists TAOS_DEFINE_ERROR(TSDB_CODE_MND_SMA_NOT_EXIST, "index not exist") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SMA_OPTION, "Invalid sma index option") +// mnode-view +TAOS_DEFINE_ERROR(TSDB_CODE_MND_VIEW_ALREADY_EXIST, "view already exists in db") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_VIEW_NOT_EXIST, "view not exists in db") + + // dnode TAOS_DEFINE_ERROR(TSDB_CODE_DNODE_OFFLINE, "Dnode is offline") TAOS_DEFINE_ERROR(TSDB_CODE_MNODE_NOT_FOUND, "Mnode not found")