diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 7630c5f5e5..9ee1aeca86 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -100,7 +100,7 @@ typedef enum _mgmt_table { TSDB_MGMT_TABLE_CLUSTER, TSDB_MGMT_TABLE_STREAMTABLES, TSDB_MGMT_TABLE_TP, - TSDB_MGMT_TABLE_FUNCTION, + TSDB_MGMT_TABLE_FUNC, TSDB_MGMT_TABLE_MAX, } EShowType; @@ -526,20 +526,21 @@ typedef struct { typedef struct { char name[TSDB_FUNC_NAME_LEN]; + int8_t igExists; int8_t funcType; int8_t scriptType; - int8_t align; int8_t outputType; int32_t outputLen; int32_t bufSize; - int64_t sigature; + int64_t signature; int32_t commentSize; int32_t codeSize; char pCont[]; } SCreateFuncReq; typedef struct { - char name[TSDB_FUNC_NAME_LEN]; + char name[TSDB_FUNC_NAME_LEN]; + int8_t igNotExists; } SDropFuncReq; typedef struct { @@ -549,13 +550,13 @@ typedef struct { typedef struct { char name[TSDB_FUNC_NAME_LEN]; + int8_t align; int8_t funcType; int8_t scriptType; - int8_t align; int8_t outputType; int32_t outputLen; int32_t bufSize; - int64_t sigature; + int64_t signature; int32_t commentSize; int32_t codeSize; char pCont[]; diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 2ff4d58e0b..26d8bc81eb 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -119,9 +119,9 @@ enum { TD_DEF_MSG_TYPE(TDMT_MND_ALTER_DB, "mnode-alter-db", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_SYNC_DB, "mnode-sync-db", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_COMPACT_DB, "mnode-compact-db", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_MND_CREATE_FUNCTION, "mnode-create-function", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_MND_RETRIEVE_FUNCTION, "mnode-retrieve-function", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_MND_DROP_FUNCTION, "mnode-drop-function", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_CREATE_FUNC, "mnode-create-func", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_RETRIEVE_FUNC, "mnode-retrieve-func", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_DROP_FUNC, "mnode-drop-func", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_CREATE_STB, "mnode-create-stb", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_ALTER_STB, "mnode-alter-stb", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_DROP_STB, "mnode-drop-stb", NULL, NULL) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 8c048690c0..69bf085491 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -239,6 +239,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MND_INVALID_FUNC_COMMENT TAOS_DEF_ERROR_CODE(0, 0x03C4) #define TSDB_CODE_MND_INVALID_FUNC_CODE TAOS_DEF_ERROR_CODE(0, 0x03C5) #define TSDB_CODE_MND_INVALID_FUNC_BUFSIZE TAOS_DEF_ERROR_CODE(0, 0x03C6) +#define TSDB_CODE_MND_INVALID_FUNC_RETRIEVE TAOS_DEF_ERROR_CODE(0, 0x03C7) // mnode-trans #define TSDB_CODE_MND_TRANS_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x03D0) diff --git a/include/util/tdef.h b/include/util/tdef.h index 4c29d9963d..4d3ef06bd6 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -173,6 +173,7 @@ do { \ #define TSDB_FUNC_BUF_SIZE 512 #define TSDB_FUNC_TYPE_SCALAR 1 #define TSDB_FUNC_TYPE_AGGREGATE 2 +#define TSDB_FUNC_MAX_RETRIEVE 1024 #define TSDB_TYPE_STR_MAX_LEN 32 #define TSDB_TABLE_FNAME_LEN (TSDB_DB_FNAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_NAME_DELIMITER_LEN) diff --git a/source/dnode/mgmt/impl/src/dndTransport.c b/source/dnode/mgmt/impl/src/dndTransport.c index 17aa9fa327..6052e055ad 100644 --- a/source/dnode/mgmt/impl/src/dndTransport.c +++ b/source/dnode/mgmt/impl/src/dndTransport.c @@ -90,9 +90,9 @@ static void dndInitMsgFp(STransMgmt *pMgmt) { pMgmt->msgFp[TMSG_INDEX(TDMT_MND_ALTER_DB)] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_SYNC_DB)] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_COMPACT_DB)] = dndProcessMnodeWriteMsg; - pMgmt->msgFp[TMSG_INDEX(TDMT_MND_CREATE_FUNCTION)] = dndProcessMnodeWriteMsg; - pMgmt->msgFp[TMSG_INDEX(TDMT_MND_RETRIEVE_FUNCTION)] = dndProcessMnodeWriteMsg; - pMgmt->msgFp[TMSG_INDEX(TDMT_MND_DROP_FUNCTION)] = dndProcessMnodeWriteMsg; + pMgmt->msgFp[TMSG_INDEX(TDMT_MND_CREATE_FUNC)] = dndProcessMnodeWriteMsg; + pMgmt->msgFp[TMSG_INDEX(TDMT_MND_RETRIEVE_FUNC)] = dndProcessMnodeWriteMsg; + pMgmt->msgFp[TMSG_INDEX(TDMT_MND_DROP_FUNC)] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_CREATE_STB)] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_ALTER_STB)] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_DROP_STB)] = dndProcessMnodeWriteMsg; diff --git a/source/dnode/mgmt/impl/test/sut/inc/sut.h b/source/dnode/mgmt/impl/test/sut/inc/sut.h index 9f724faeb9..955f62610a 100644 --- a/source/dnode/mgmt/impl/test/sut/inc/sut.h +++ b/source/dnode/mgmt/impl/test/sut/inc/sut.h @@ -96,6 +96,15 @@ class Testbase { #define CheckBinary(val, len) \ { EXPECT_STREQ(test.GetShowBinary(len), val); } +#define CheckBinaryByte(b, len) \ + { \ + char* bytes = (char*)calloc(1, len); \ + for (int32_t i = 0; i < len - 1; ++i) { \ + bytes[i] = b; \ + } \ + EXPECT_STREQ(test.GetShowBinary(len), bytes); \ + } + #define CheckInt8(val) \ { EXPECT_EQ(test.GetShowInt8(), val); } diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 78f371133c..e1103e7bb4 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -314,7 +314,7 @@ typedef struct { int8_t outputType; int32_t outputLen; int32_t bufSize; - int64_t sigature; + int64_t signature; int32_t commentSize; int32_t codeSize; char* pComment; diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index d406247bc1..f9dde7bc75 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -25,14 +25,14 @@ static SSdbRaw *mndFuncActionEncode(SFuncObj *pFunc); static SSdbRow *mndFuncActionDecode(SSdbRaw *pRaw); static int32_t mndFuncActionInsert(SSdb *pSdb, SFuncObj *pFunc); static int32_t mndFuncActionDelete(SSdb *pSdb, SFuncObj *pFunc); -static int32_t mndFuncActionUpdate(SSdb *pSdb, SFuncObj *pOldFunc, SFuncObj *pNewFunc); -static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pMsg, SCreateFuncReq *pCreate); -static int32_t mndDropFunc(SMnode *pMnode, SMnodeMsg *pMsg, SFuncObj *pFunc); -static int32_t mndProcessCreateFuncMsg(SMnodeMsg *pMsg); -static int32_t mndProcessDropFuncMsg(SMnodeMsg *pMsg); -static int32_t mndProcessRetrieveFuncMsg(SMnodeMsg *pMsg); -static int32_t mndGetFuncMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta); -static int32_t mndRetrieveFuncs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndFuncActionUpdate(SSdb *pSdb, SFuncObj *pOld, SFuncObj *pNew); +static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pReq, SCreateFuncReq *pCreate); +static int32_t mndDropFunc(SMnode *pMnode, SMnodeMsg *pReq, SFuncObj *pFunc); +static int32_t mndProcessCreateFuncReq(SMnodeMsg *pReq); +static int32_t mndProcessDropFuncReq(SMnodeMsg *pReq); +static int32_t mndProcessRetrieveFuncReq(SMnodeMsg *pReq); +static int32_t mndGetFuncMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveFuncs(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextFunc(SMnode *pMnode, void *pIter); int32_t mndInitFunc(SMnode *pMnode) { @@ -44,13 +44,13 @@ int32_t mndInitFunc(SMnode *pMnode) { .updateFp = (SdbUpdateFp)mndFuncActionUpdate, .deleteFp = (SdbDeleteFp)mndFuncActionDelete}; - mndSetMsgHandle(pMnode, TDMT_MND_CREATE_FUNCTION, mndProcessCreateFuncMsg); - mndSetMsgHandle(pMnode, TDMT_MND_DROP_FUNCTION, mndProcessDropFuncMsg); - mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_FUNCTION, mndProcessRetrieveFuncMsg); + mndSetMsgHandle(pMnode, TDMT_MND_CREATE_FUNC, mndProcessCreateFuncReq); + mndSetMsgHandle(pMnode, TDMT_MND_DROP_FUNC, mndProcessDropFuncReq); + mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_FUNC, mndProcessRetrieveFuncReq); - mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_FUNCTION, mndGetFuncMeta); - mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_FUNCTION, mndRetrieveFuncs); - mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_FUNCTION, mndCancelGetNextFunc); + mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_FUNC, mndGetFuncMeta); + mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_FUNC, mndRetrieveFuncs); + mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_FUNC, mndCancelGetNextFunc); return sdbSetTable(pMnode->pSdb, table); } @@ -73,7 +73,7 @@ static SSdbRaw *mndFuncActionEncode(SFuncObj *pFunc) { SDB_SET_INT8(pRaw, dataPos, pFunc->outputType, FUNC_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, pFunc->outputLen, FUNC_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, pFunc->bufSize, FUNC_ENCODE_OVER) - SDB_SET_INT64(pRaw, dataPos, pFunc->sigature, FUNC_ENCODE_OVER) + SDB_SET_INT64(pRaw, dataPos, pFunc->signature, FUNC_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, pFunc->commentSize, FUNC_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, pFunc->codeSize, FUNC_ENCODE_OVER) SDB_SET_BINARY(pRaw, dataPos, pFunc->pComment, pFunc->commentSize, FUNC_ENCODE_OVER) @@ -104,13 +104,11 @@ static SSdbRow *mndFuncActionDecode(SSdbRaw *pRaw) { goto FUNC_DECODE_OVER; } - int32_t size = sizeof(SFuncObj) + TSDB_FUNC_COMMENT_LEN + TSDB_FUNC_CODE_LEN; - SSdbRow *pRow = sdbAllocRow(size); + SSdbRow *pRow = sdbAllocRow(sizeof(SFuncObj)); if (pRow == NULL) goto FUNC_DECODE_OVER; SFuncObj *pFunc = sdbGetRowObj(pRow); if (pFunc == NULL) goto FUNC_DECODE_OVER; - char *tmp = (char *)pFunc + sizeof(SFuncObj); int32_t dataPos = 0; SDB_GET_BINARY(pRaw, dataPos, pFunc->name, TSDB_FUNC_NAME_LEN, FUNC_DECODE_OVER) @@ -121,12 +119,18 @@ static SSdbRow *mndFuncActionDecode(SSdbRaw *pRaw) { SDB_GET_INT8(pRaw, dataPos, &pFunc->outputType, FUNC_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &pFunc->outputLen, FUNC_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &pFunc->bufSize, FUNC_DECODE_OVER) - SDB_GET_INT64(pRaw, dataPos, &pFunc->sigature, FUNC_DECODE_OVER) + SDB_GET_INT64(pRaw, dataPos, &pFunc->signature, FUNC_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &pFunc->commentSize, FUNC_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &pFunc->codeSize, FUNC_DECODE_OVER) - SDB_GET_BINARY(pRaw, dataPos, pFunc->pData, pFunc->commentSize + pFunc->codeSize, FUNC_DECODE_OVER) - pFunc->pComment = pFunc->pData; - pFunc->pCode = (pFunc->pData + pFunc->commentSize); + + pFunc->pComment = calloc(1, pFunc->commentSize); + pFunc->pCode = calloc(1, pFunc->codeSize); + if (pFunc->pComment == NULL || pFunc->pCode == NULL) { + goto FUNC_DECODE_OVER; + } + + SDB_GET_BINARY(pRaw, dataPos, pFunc->pComment, pFunc->commentSize, FUNC_DECODE_OVER) + SDB_GET_BINARY(pRaw, dataPos, pFunc->pCode, pFunc->codeSize, FUNC_DECODE_OVER) terrno = 0; @@ -148,136 +152,136 @@ static int32_t mndFuncActionInsert(SSdb *pSdb, SFuncObj *pFunc) { static int32_t mndFuncActionDelete(SSdb *pSdb, SFuncObj *pFunc) { mTrace("func:%s, perform delete action, row:%p", pFunc->name, pFunc); + tfree(pFunc->pCode); + tfree(pFunc->pComment); return 0; } -static int32_t mndFuncActionUpdate(SSdb *pSdb, SFuncObj *pOldFunc, SFuncObj *pNewFunc) { - mTrace("func:%s, perform update action, old row:%p new row:%p", pOldFunc->name, pOldFunc, pNewFunc); +static int32_t mndFuncActionUpdate(SSdb *pSdb, SFuncObj *pOld, SFuncObj *pNew) { + mTrace("func:%s, perform update action, old row:%p new row:%p", pOld->name, pOld, pNew); return 0; } -static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pMsg, SCreateFuncReq *pCreate) { - SFuncObj *pFunc = calloc(1, sizeof(SFuncObj) + pCreate->commentSize + pCreate->codeSize); - pFunc->createdTime = taosGetTimestampMs(); - pFunc->funcType = pCreate->funcType; - pFunc->scriptType = pCreate->scriptType; - pFunc->outputType = pCreate->outputType; - pFunc->outputLen = pCreate->outputLen; - pFunc->bufSize = pCreate->bufSize; - pFunc->sigature = pCreate->sigature; - pFunc->commentSize = pCreate->commentSize; - pFunc->codeSize = pCreate->codeSize; - pFunc->pComment = pFunc->pData; - memcpy(pFunc->pComment, pCreate->pCont, pCreate->commentSize); - pFunc->pCode = pFunc->pData + pCreate->commentSize; - memcpy(pFunc->pCode, pCreate->pCont + pCreate->commentSize, pFunc->codeSize); - - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg); - if (pTrans == NULL) { - free(pFunc); - mError("func:%s, failed to create since %s", pCreate->name, terrstr()); - return -1; +static SFuncObj *mndAcquireFunc(SMnode *pMnode, char *funcName) { + SSdb *pSdb = pMnode->pSdb; + SFuncObj *pFunc = sdbAcquire(pSdb, SDB_FUNC, funcName); + if (pFunc == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) { + terrno = TSDB_CODE_MND_FUNC_NOT_EXIST; } + return pFunc; +} + +static void mndReleaseFunc(SMnode *pMnode, SFuncObj *pFunc) { + SSdb *pSdb = pMnode->pSdb; + sdbRelease(pSdb, pFunc); +} + +static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pReq, SCreateFuncReq *pCreate) { + int32_t code = -1; + STrans *pTrans = NULL; + + SFuncObj func = {0}; + memcpy(func.name, pCreate->name, TSDB_FUNC_NAME_LEN); + func.createdTime = taosGetTimestampMs(); + func.funcType = pCreate->funcType; + func.scriptType = pCreate->scriptType; + func.outputType = pCreate->outputType; + func.outputLen = pCreate->outputLen; + func.bufSize = pCreate->bufSize; + func.signature = pCreate->signature; + func.commentSize = pCreate->commentSize; + func.codeSize = pCreate->codeSize; + func.pComment = malloc(func.commentSize); + func.pCode = malloc(func.codeSize); + if (func.pCode == NULL || func.pCode == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto CREATE_FUNC_OVER; + } + + memcpy(func.pComment, pCreate->pCont, pCreate->commentSize); + memcpy(func.pCode, pCreate->pCont + pCreate->commentSize, func.codeSize); + + pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); + if (pTrans == NULL) goto CREATE_FUNC_OVER; mDebug("trans:%d, used to create func:%s", pTrans->id, pCreate->name); - SSdbRaw *pRedoRaw = mndFuncActionEncode(pFunc); - if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { - mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); - free(pFunc); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING); + SSdbRaw *pRedoRaw = mndFuncActionEncode(&func); + if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) goto CREATE_FUNC_OVER; + if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING) != 0) goto CREATE_FUNC_OVER; - SSdbRaw *pUndoRaw = mndFuncActionEncode(pFunc); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - free(pFunc); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED); + SSdbRaw *pUndoRaw = mndFuncActionEncode(&func); + if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) goto CREATE_FUNC_OVER; + if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) goto CREATE_FUNC_OVER; - SSdbRaw *pCommitRaw = mndFuncActionEncode(pFunc); - if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { - mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); - free(pFunc); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); + SSdbRaw *pCommitRaw = mndFuncActionEncode(&func); + if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) goto CREATE_FUNC_OVER; + if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) goto CREATE_FUNC_OVER; - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } + if (mndTransPrepare(pMnode, pTrans) != 0) goto CREATE_FUNC_OVER; - free(pFunc); + code = 0; + +CREATE_FUNC_OVER: + free(func.pCode); + free(func.pComment); mndTransDrop(pTrans); - return 0; + return code; } -static int32_t mndDropFunc(SMnode *pMnode, SMnodeMsg *pMsg, SFuncObj *pFunc) { - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("func:%s, failed to drop since %s", pFunc->name, terrstr()); - return -1; - } +static int32_t mndDropFunc(SMnode *pMnode, SMnodeMsg *pReq, SFuncObj *pFunc) { + int32_t code = -1; + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); + if (pTrans == NULL) goto DROP_FUNC_OVER; + mDebug("trans:%d, used to drop user:%s", pTrans->id, pFunc->name); SSdbRaw *pRedoRaw = mndFuncActionEncode(pFunc); - if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { - mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } + if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) goto DROP_FUNC_OVER; sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING); SSdbRaw *pUndoRaw = mndFuncActionEncode(pFunc); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } + if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) goto DROP_FUNC_OVER; sdbSetRawStatus(pUndoRaw, SDB_STATUS_READY); SSdbRaw *pCommitRaw = mndFuncActionEncode(pFunc); - if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { - mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } + if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) goto DROP_FUNC_OVER; sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } + if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_FUNC_OVER; + code = 0; + +DROP_FUNC_OVER: mndTransDrop(pTrans); - return 0; + return code; } -static int32_t mndProcessCreateFuncMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndProcessCreateFuncReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; - SCreateFuncReq *pCreate = pMsg->rpcMsg.pCont; + SCreateFuncReq *pCreate = pReq->rpcMsg.pCont; pCreate->outputLen = htonl(pCreate->outputLen); pCreate->bufSize = htonl(pCreate->bufSize); - pCreate->sigature = htobe64(pCreate->sigature); + pCreate->signature = htobe64(pCreate->signature); pCreate->commentSize = htonl(pCreate->commentSize); pCreate->codeSize = htonl(pCreate->codeSize); mDebug("func:%s, start to create", pCreate->name); - SFuncObj *pFunc = sdbAcquire(pMnode->pSdb, SDB_FUNC, pCreate->name); + SFuncObj *pFunc = mndAcquireFunc(pMnode, pCreate->name); if (pFunc != NULL) { - sdbRelease(pMnode->pSdb, pFunc); - terrno = TSDB_CODE_MND_FUNC_ALREADY_EXIST; - mError("func:%s, failed to create since %s", pCreate->name, terrstr()); + mndReleaseFunc(pMnode, pFunc); + if (pCreate->igExists) { + mDebug("stb:%s, already exist, ignore exist is set", pCreate->name); + return 0; + } else { + terrno = TSDB_CODE_MND_FUNC_ALREADY_EXIST; + mError("func:%s, failed to create since %s", pCreate->name, terrstr()); + return -1; + } + } else if (terrno == TSDB_CODE_MND_FUNC_ALREADY_EXIST) { + mError("stb:%s, failed to create since %s", pCreate->name, terrstr()); return -1; } @@ -305,14 +309,13 @@ static int32_t mndProcessCreateFuncMsg(SMnodeMsg *pMsg) { return -1; } - if (pCreate->bufSize < 0 || pCreate->bufSize > TSDB_FUNC_BUF_SIZE) { + if (pCreate->bufSize <= 0 || pCreate->bufSize > TSDB_FUNC_BUF_SIZE) { terrno = TSDB_CODE_MND_INVALID_FUNC_BUFSIZE; mError("func:%s, failed to create since %s", pCreate->name, terrstr()); return -1; } - int32_t code = mndCreateFunc(pMnode, pMsg, pCreate); - + int32_t code = mndCreateFunc(pMnode, pReq, pCreate); if (code != 0) { mError("func:%s, failed to create since %s", pCreate->name, terrstr()); return -1; @@ -321,9 +324,9 @@ static int32_t mndProcessCreateFuncMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessDropFuncMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SDropFuncReq *pDrop = pMsg->rpcMsg.pCont; +static int32_t mndProcessDropFuncReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SDropFuncReq *pDrop = pReq->rpcMsg.pCont; mDebug("func:%s, start to drop", pDrop->name); @@ -333,14 +336,20 @@ static int32_t mndProcessDropFuncMsg(SMnodeMsg *pMsg) { return -1; } - SFuncObj *pFunc = sdbAcquire(pMnode->pSdb, SDB_FUNC, pDrop->name); + SFuncObj *pFunc = mndAcquireFunc(pMnode, pDrop->name); if (pFunc == NULL) { - terrno = TSDB_CODE_MND_FUNC_NOT_EXIST; - mError("func:%s, failed to drop since %s", pDrop->name, terrstr()); - return -1; + if (pDrop->igNotExists) { + mDebug("func:%s, not exist, ignore not exist is set", pDrop->name); + return 0; + } else { + terrno = TSDB_CODE_MND_FUNC_NOT_EXIST; + mError("func:%s, failed to drop since %s", pDrop->name, terrstr()); + return -1; + } } - int32_t code = mndDropFunc(pMnode, pMsg, pFunc); + int32_t code = mndDropFunc(pMnode, pReq, pFunc); + mndReleaseFunc(pMnode, pFunc); if (code != 0) { mError("func:%s, failed to drop since %s", pDrop->name, terrstr()); @@ -350,15 +359,26 @@ static int32_t mndProcessDropFuncMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessRetrieveFuncMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndProcessRetrieveFuncReq(SMnodeMsg *pReq) { + int32_t code = -1; + SMnode *pMnode = pReq->pMnode; - SRetrieveFuncReq *pRetrieve = pMsg->rpcMsg.pCont; + SRetrieveFuncReq *pRetrieve = pReq->rpcMsg.pCont; pRetrieve->numOfFuncs = htonl(pRetrieve->numOfFuncs); + if (pRetrieve->numOfFuncs <= 0 || pRetrieve->numOfFuncs > TSDB_FUNC_MAX_RETRIEVE) { + terrno = TSDB_CODE_MND_INVALID_FUNC_RETRIEVE; + return -1; + } - int32_t size = sizeof(SRetrieveFuncRsp) + (sizeof(SFuncInfo) + TSDB_FUNC_CODE_LEN) * pRetrieve->numOfFuncs + 16384; + int32_t fsize = sizeof(SFuncInfo) + TSDB_FUNC_CODE_LEN + TSDB_FUNC_COMMENT_LEN; + int32_t size = sizeof(SRetrieveFuncRsp) + fsize * pRetrieve->numOfFuncs; SRetrieveFuncRsp *pRetrieveRsp = rpcMallocCont(size); + if (pRetrieveRsp == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto FUNC_RETRIEVE_OVER; + } + pRetrieveRsp->numOfFuncs = htonl(pRetrieve->numOfFuncs); char *pOutput = pRetrieveRsp->pFuncInfos; @@ -366,37 +386,42 @@ static int32_t mndProcessRetrieveFuncMsg(SMnodeMsg *pMsg) { char funcName[TSDB_FUNC_NAME_LEN] = {0}; memcpy(funcName, pRetrieve->pFuncNames + i * TSDB_FUNC_NAME_LEN, TSDB_FUNC_NAME_LEN); - SFuncObj *pFunc = sdbAcquire(pMnode->pSdb, SDB_FUNC, funcName); + SFuncObj *pFunc = mndAcquireFunc(pMnode, funcName); if (pFunc == NULL) { terrno = TSDB_CODE_MND_INVALID_FUNC; mError("func:%s, failed to retrieve since %s", funcName, terrstr()); - return -1; + goto FUNC_RETRIEVE_OVER; } SFuncInfo *pFuncInfo = (SFuncInfo *)pOutput; - - strncpy(pFuncInfo->name, pFunc->name, TSDB_FUNC_NAME_LEN); + memcpy(pFuncInfo->name, pFunc->name, TSDB_FUNC_NAME_LEN); pFuncInfo->funcType = pFunc->funcType; pFuncInfo->scriptType = pFunc->scriptType; pFuncInfo->outputType = pFunc->outputType; pFuncInfo->outputLen = htonl(pFunc->outputLen); pFuncInfo->bufSize = htonl(pFunc->bufSize); - pFuncInfo->sigature = htobe64(pFunc->sigature); + pFuncInfo->signature = htobe64(pFunc->signature); pFuncInfo->commentSize = htonl(pFunc->commentSize); pFuncInfo->codeSize = htonl(pFunc->codeSize); - memcpy(pFuncInfo->pCont, pFunc->pCode, pFunc->commentSize + pFunc->codeSize); - - pOutput += sizeof(SFuncInfo) + pFunc->commentSize + pFunc->codeSize; + memcpy(pFuncInfo->pCont, pFunc->pComment, pFunc->commentSize); + memcpy(pFuncInfo->pCont + pFunc->commentSize, pFunc->pCode, pFunc->codeSize); + pOutput += (sizeof(SFuncInfo) + pFunc->commentSize + pFunc->codeSize); + mndReleaseFunc(pMnode, pFunc); } - pMsg->pCont = pRetrieveRsp; - pMsg->contLen = (int32_t)(pOutput - (char *)pRetrieveRsp); + pReq->pCont = pRetrieveRsp; + pReq->contLen = (int32_t)(pOutput - (char *)pRetrieveRsp); - return 0; + code = 0; + +FUNC_RETRIEVE_OVER: + if (code != 0) rpcFreeCont(pRetrieveRsp); + + return code; } -static int32_t mndGetFuncMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetFuncMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -454,7 +479,7 @@ static int32_t mndGetFuncMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *p pShow->numOfRows = sdbGetSize(pSdb, SDB_FUNC); pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; - strcpy(pMeta->tbFname, "show funcs"); + strcpy(pMeta->tbFname, mndShowStr(pShow->type)); return 0; } @@ -477,8 +502,8 @@ static void *mnodeGenTypeStr(char *buf, int32_t buflen, uint8_t type, int16_t le return tDataTypes[type].name; } -static int32_t mndRetrieveFuncs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveFuncs(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; SFuncObj *pFunc = NULL; diff --git a/source/dnode/mnode/impl/src/mndShow.c b/source/dnode/mnode/impl/src/mndShow.c index 28fe0551c2..e2ddcee0e9 100644 --- a/source/dnode/mnode/impl/src/mndShow.c +++ b/source/dnode/mnode/impl/src/mndShow.c @@ -296,7 +296,7 @@ char *mndShowStr(int32_t showType) { return "show streamtables"; case TSDB_MGMT_TABLE_TP: return "show topics"; - case TSDB_MGMT_TABLE_FUNCTION: + case TSDB_MGMT_TABLE_FUNC: return "show functions"; default: return "undefined"; diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 5ed801e3ea..45b8428663 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -123,8 +123,7 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) { goto STB_DECODE_OVER; } - int32_t size = sizeof(SStbObj) + TSDB_MAX_COLUMNS * sizeof(SSchema); - SSdbRow *pRow = sdbAllocRow(size); + SSdbRow *pRow = sdbAllocRow(sizeof(SStbObj)); if (pRow == NULL) goto STB_DECODE_OVER; SStbObj *pStb = sdbGetRowObj(pRow); @@ -143,6 +142,9 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) { int32_t totalCols = pStb->numOfColumns + pStb->numOfTags; pStb->pSchema = calloc(totalCols, sizeof(SSchema)); + if (pStb->pSchema == NULL) { + goto STB_DECODE_OVER; + } for (int32_t i = 0; i < totalCols; ++i) { SSchema *pSchema = &pStb->pSchema[i]; @@ -448,7 +450,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pReq, SMCreateStbReq *pCr stbObj.pSchema[i].colId = i + 1; } - int32_t code = 0; + int32_t code = -1; STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); if (pTrans == NULL) goto CREATE_STB_OVER; @@ -481,7 +483,7 @@ static int32_t mndProcessMCreateStbReq(SMnodeMsg *pReq) { SStbObj *pStb = mndAcquireStb(pMnode, pCreate->name); if (pStb != NULL) { - sdbRelease(pMnode->pSdb, pStb); + mndReleaseStb(pMnode, pStb); if (pCreate->igExists) { mDebug("stb:%s, already exist, ignore exist is set", pCreate->name); return 0; @@ -492,6 +494,7 @@ static int32_t mndProcessMCreateStbReq(SMnodeMsg *pReq) { } } else if (terrno != TSDB_CODE_MND_STB_NOT_EXIST) { mError("stb:%s, failed to create since %s", pCreate->name, terrstr()); + return -1; } // topic should have different name with stb @@ -640,7 +643,7 @@ static int32_t mndDropStb(SMnode *pMnode, SMnodeMsg *pReq, SStbObj *pStb) { DROP_STB_OVER: mndTransDrop(pTrans); - return 0; + return code; } static int32_t mndProcessMDropStbReq(SMnodeMsg *pReq) { @@ -665,7 +668,6 @@ static int32_t mndProcessMDropStbReq(SMnodeMsg *pReq) { mndReleaseStb(pMnode, pStb); if (code != 0) { - terrno = code; mError("stb:%s, failed to drop since %s", pDrop->name, terrstr()); return -1; } diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index 2301df65d7..03226c7400 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -390,9 +390,11 @@ static void mndTransDropActions(SArray *pArray) { } void mndTransDrop(STrans *pTrans) { - mndTransDropData(pTrans); - mDebug("trans:%d, is dropped, data:%p", pTrans->id, pTrans); - tfree(pTrans); + if (pTrans != NULL) { + mndTransDropData(pTrans); + mDebug("trans:%d, is dropped, data:%p", pTrans->id, pTrans); + tfree(pTrans); + } } static int32_t mndTransAppendLog(SArray *pArray, SSdbRaw *pRaw) { diff --git a/source/dnode/mnode/impl/test/CMakeLists.txt b/source/dnode/mnode/impl/test/CMakeLists.txt index 3ca35d58a7..5f6f2f3b4f 100644 --- a/source/dnode/mnode/impl/test/CMakeLists.txt +++ b/source/dnode/mnode/impl/test/CMakeLists.txt @@ -12,3 +12,4 @@ add_subdirectory(dnode) add_subdirectory(mnode) add_subdirectory(db) add_subdirectory(stb) +add_subdirectory(func) diff --git a/source/dnode/mnode/impl/test/func/CMakeLists.txt b/source/dnode/mnode/impl/test/func/CMakeLists.txt new file mode 100644 index 0000000000..26b0a60968 --- /dev/null +++ b/source/dnode/mnode/impl/test/func/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. FUNC_SRC) +add_executable(mnode_test_func ${FUNC_SRC}) +target_link_libraries( + mnode_test_func + PUBLIC sut +) + +add_test( + NAME mnode_test_func + COMMAND mnode_test_func +) diff --git a/source/dnode/mnode/impl/test/func/func.cpp b/source/dnode/mnode/impl/test/func/func.cpp new file mode 100644 index 0000000000..9d31ec7314 --- /dev/null +++ b/source/dnode/mnode/impl/test/func/func.cpp @@ -0,0 +1,521 @@ +/** + * @file func.cpp + * @author slguan (slguan@taosdata.com) + * @brief MNODE module func tests + * @version 1.0 + * @date 2022-01-24 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class MndTestFunc : public ::testing::Test { + protected: + static void SetUpTestSuite() { test.Init("/tmp/mnode_test_func", 9038); } + static void TearDownTestSuite() { test.Cleanup(); } + + static Testbase test; + + public: + void SetUp() override {} + void TearDown() override {} +}; + +Testbase MndTestFunc::test; + +TEST_F(MndTestFunc, 01_Show_Func) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_FUNC, ""); + CHECK_META("show functions", 7); + + CHECK_SCHEMA(0, TSDB_DATA_TYPE_BINARY, TSDB_FUNC_NAME_LEN + VARSTR_HEADER_SIZE, "name"); + CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, PATH_MAX + VARSTR_HEADER_SIZE, "comment"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_INT, 4, "aggregate"); + CHECK_SCHEMA(3, TSDB_DATA_TYPE_BINARY, TSDB_TYPE_STR_MAX_LEN + VARSTR_HEADER_SIZE, "outputtype"); + CHECK_SCHEMA(4, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); + CHECK_SCHEMA(5, TSDB_DATA_TYPE_INT, 4, "code_len"); + CHECK_SCHEMA(6, TSDB_DATA_TYPE_INT, 4, "bufsize"); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 0); +} + +TEST_F(MndTestFunc, 02_Create_Func) { + { + int32_t contLen = sizeof(SCreateFuncReq); + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, ""); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_NAME); + } + + { + int32_t contLen = sizeof(SCreateFuncReq); + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_COMMENT); + } + + { + int32_t contLen = sizeof(SCreateFuncReq); + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + pReq->commentSize = htonl(TSDB_FUNC_COMMENT_LEN + 1); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_COMMENT); + } + + { + int32_t contLen = sizeof(SCreateFuncReq); + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + pReq->commentSize = htonl(TSDB_FUNC_COMMENT_LEN); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_CODE); + } + + { + int32_t contLen = sizeof(SCreateFuncReq); + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + pReq->commentSize = htonl(TSDB_FUNC_COMMENT_LEN); + pReq->codeSize = htonl(TSDB_FUNC_CODE_LEN - 1); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_CODE); + } + + { + int32_t contLen = sizeof(SCreateFuncReq) + 24; + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + pReq->commentSize = htonl(TSDB_FUNC_COMMENT_LEN); + pReq->codeSize = htonl(TSDB_FUNC_CODE_LEN); + pReq->pCont[0] = 0; + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_CODE); + } + + { + int32_t contLen = sizeof(SCreateFuncReq) + 24; + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + pReq->commentSize = htonl(TSDB_FUNC_COMMENT_LEN); + pReq->codeSize = htonl(TSDB_FUNC_CODE_LEN); + pReq->pCont[0] = 'a'; + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_BUFSIZE); + } + + { + int32_t contLen = sizeof(SCreateFuncReq) + 24; + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + pReq->commentSize = htonl(TSDB_FUNC_COMMENT_LEN); + pReq->codeSize = htonl(TSDB_FUNC_CODE_LEN); + pReq->pCont[0] = 'a'; + pReq->bufSize = htonl(TSDB_FUNC_BUF_SIZE + 1); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_BUFSIZE); + } + + for (int32_t i = 0; i < 3; ++i) { + int32_t contLen = sizeof(SCreateFuncReq); + int32_t commentSize = TSDB_FUNC_COMMENT_LEN; + int32_t codeSize = TSDB_FUNC_CODE_LEN; + contLen = (contLen + codeSize + commentSize); + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + pReq->igExists = 0; + if (i == 2) pReq->igExists = 1; + pReq->funcType = 1; + pReq->scriptType = 2; + pReq->outputType = TSDB_DATA_TYPE_SMALLINT; + pReq->outputLen = htonl(12); + pReq->bufSize = htonl(4); + pReq->signature = htobe64(5); + pReq->commentSize = htonl(commentSize); + pReq->codeSize = htonl(codeSize); + for (int32_t i = 0; i < commentSize - 1; ++i) { + pReq->pCont[i] = 'm'; + } + for (int32_t i = commentSize; i < commentSize + codeSize - 1; ++i) { + pReq->pCont[i] = 'd'; + } + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (i == 0 || i == 2) { + ASSERT_EQ(pRsp->code, 0); + } else { + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_FUNC_ALREADY_EXIST); + } + } + + test.SendShowMetaReq(TSDB_MGMT_TABLE_FUNC, ""); + CHECK_META("show functions", 7); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckBinary("f1", TSDB_FUNC_NAME_LEN); + CheckBinaryByte('m', TSDB_FUNC_COMMENT_LEN); + CheckInt32(0); + CheckBinary("SMALLINT", TSDB_TYPE_STR_MAX_LEN); + CheckTimestamp(); + CheckInt32(TSDB_FUNC_CODE_LEN); + CheckInt32(4); +} + +TEST_F(MndTestFunc, 03_Retrieve_Func) { + { + int32_t contLen = sizeof(SRetrieveFuncReq); + int32_t numOfFuncs = 1; + contLen = (contLen + numOfFuncs * TSDB_FUNC_NAME_LEN); + + SRetrieveFuncReq* pReq = (SRetrieveFuncReq*)rpcMallocCont(contLen); + pReq->numOfFuncs = htonl(1); + strcpy(pReq->pFuncNames, "f1"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_RETRIEVE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + SRetrieveFuncRsp* pRetrieveRsp = (SRetrieveFuncRsp*)pRsp->pCont; + pRetrieveRsp->numOfFuncs = htonl(pRetrieveRsp->numOfFuncs); + + SFuncInfo* pFuncInfo = (SFuncInfo*)(pRetrieveRsp->pFuncInfos); + pFuncInfo->outputLen = htonl(pFuncInfo->outputLen); + pFuncInfo->bufSize = htonl(pFuncInfo->bufSize); + pFuncInfo->signature = htobe64(pFuncInfo->signature); + pFuncInfo->commentSize = htonl(pFuncInfo->commentSize); + pFuncInfo->codeSize = htonl(pFuncInfo->codeSize); + + EXPECT_STREQ(pFuncInfo->name, "f1"); + EXPECT_EQ(pFuncInfo->funcType, 1); + EXPECT_EQ(pFuncInfo->scriptType, 2); + EXPECT_EQ(pFuncInfo->outputType, TSDB_DATA_TYPE_SMALLINT); + EXPECT_EQ(pFuncInfo->outputLen, 12); + EXPECT_EQ(pFuncInfo->bufSize, 4); + EXPECT_EQ(pFuncInfo->signature, 5); + EXPECT_EQ(pFuncInfo->commentSize, TSDB_FUNC_COMMENT_LEN); + EXPECT_EQ(pFuncInfo->codeSize, TSDB_FUNC_CODE_LEN); + + char* pComment = pFuncInfo->pCont; + char* pCode = pFuncInfo->pCont + pFuncInfo->commentSize; + char comments[TSDB_FUNC_COMMENT_LEN] = {0}; + for (int32_t i = 0; i < TSDB_FUNC_COMMENT_LEN - 1; ++i) { + comments[i] = 'm'; + } + char codes[TSDB_FUNC_CODE_LEN] = {0}; + for (int32_t i = 0; i < TSDB_FUNC_CODE_LEN - 1; ++i) { + codes[i] = 'd'; + } + EXPECT_STREQ(pComment, comments); + EXPECT_STREQ(pCode, codes); + } + + { + int32_t contLen = sizeof(SRetrieveFuncReq); + int32_t numOfFuncs = 0; + contLen = (contLen + numOfFuncs * TSDB_FUNC_NAME_LEN); + + SRetrieveFuncReq* pReq = (SRetrieveFuncReq*)rpcMallocCont(contLen); + pReq->numOfFuncs = htonl(numOfFuncs); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_RETRIEVE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_RETRIEVE); + } + + { + int32_t contLen = sizeof(SRetrieveFuncReq); + int32_t numOfFuncs = TSDB_FUNC_MAX_RETRIEVE + 1; + contLen = (contLen + numOfFuncs * TSDB_FUNC_NAME_LEN); + + SRetrieveFuncReq* pReq = (SRetrieveFuncReq*)rpcMallocCont(contLen); + pReq->numOfFuncs = htonl(numOfFuncs); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_RETRIEVE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_RETRIEVE); + } + + { + int32_t contLen = sizeof(SRetrieveFuncReq); + int32_t numOfFuncs = 1; + contLen = (contLen + numOfFuncs * TSDB_FUNC_NAME_LEN); + + SRetrieveFuncReq* pReq = (SRetrieveFuncReq*)rpcMallocCont(contLen); + pReq->numOfFuncs = htonl(numOfFuncs); + strcpy(pReq->pFuncNames, "f2"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_RETRIEVE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC); + } + + { + int32_t contLen = sizeof(SCreateFuncReq); + int32_t commentSize = 1024; + int32_t codeSize = 9527; + contLen = (contLen + codeSize + commentSize); + + SCreateFuncReq* pReq = (SCreateFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f2"); + pReq->igExists = 1; + pReq->funcType = 2; + pReq->scriptType = 3; + pReq->outputType = TSDB_DATA_TYPE_BINARY; + pReq->outputLen = htonl(24); + pReq->bufSize = htonl(6); + pReq->signature = htobe64(18); + pReq->commentSize = htonl(commentSize); + pReq->codeSize = htonl(codeSize); + for (int32_t i = 0; i < commentSize - 1; ++i) { + pReq->pCont[i] = 'p'; + } + for (int32_t i = commentSize; i < commentSize + codeSize - 1; ++i) { + pReq->pCont[i] = 'q'; + } + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_FUNC, ""); + CHECK_META("show functions", 7); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + } + + { + int32_t contLen = sizeof(SRetrieveFuncReq); + int32_t numOfFuncs = 1; + contLen = (contLen + numOfFuncs * TSDB_FUNC_NAME_LEN); + + SRetrieveFuncReq* pReq = (SRetrieveFuncReq*)rpcMallocCont(contLen); + pReq->numOfFuncs = htonl(1); + strcpy(pReq->pFuncNames, "f2"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_RETRIEVE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + SRetrieveFuncRsp* pRetrieveRsp = (SRetrieveFuncRsp*)pRsp->pCont; + pRetrieveRsp->numOfFuncs = htonl(pRetrieveRsp->numOfFuncs); + + SFuncInfo* pFuncInfo = (SFuncInfo*)(pRetrieveRsp->pFuncInfos); + pFuncInfo->outputLen = htonl(pFuncInfo->outputLen); + pFuncInfo->bufSize = htonl(pFuncInfo->bufSize); + pFuncInfo->signature = htobe64(pFuncInfo->signature); + pFuncInfo->commentSize = htonl(pFuncInfo->commentSize); + pFuncInfo->codeSize = htonl(pFuncInfo->codeSize); + + EXPECT_STREQ(pFuncInfo->name, "f2"); + EXPECT_EQ(pFuncInfo->funcType, 2); + EXPECT_EQ(pFuncInfo->scriptType, 3); + EXPECT_EQ(pFuncInfo->outputType, TSDB_DATA_TYPE_BINARY); + EXPECT_EQ(pFuncInfo->outputLen, 24); + EXPECT_EQ(pFuncInfo->bufSize, 6); + EXPECT_EQ(pFuncInfo->signature, 18); + EXPECT_EQ(pFuncInfo->commentSize, 1024); + EXPECT_EQ(pFuncInfo->codeSize, 9527); + + char* pComment = pFuncInfo->pCont; + char* pCode = pFuncInfo->pCont + pFuncInfo->commentSize; + char* comments = (char*)calloc(1, 1024); + for (int32_t i = 0; i < 1024 - 1; ++i) { + comments[i] = 'p'; + } + char* codes = (char*)calloc(1, 9527); + for (int32_t i = 0; i < 9527 - 1; ++i) { + codes[i] = 'q'; + } + EXPECT_STREQ(pComment, comments); + EXPECT_STREQ(pCode, codes); + free(comments); + free(codes); + } + + { + int32_t contLen = sizeof(SRetrieveFuncReq); + int32_t numOfFuncs = 2; + contLen = (contLen + numOfFuncs * TSDB_FUNC_NAME_LEN); + + SRetrieveFuncReq* pReq = (SRetrieveFuncReq*)rpcMallocCont(contLen); + pReq->numOfFuncs = htonl(numOfFuncs); + strcpy(pReq->pFuncNames, "f2"); + strcpy((char*)pReq->pFuncNames + TSDB_FUNC_NAME_LEN, "f1"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_RETRIEVE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + SRetrieveFuncRsp* pRetrieveRsp = (SRetrieveFuncRsp*)pRsp->pCont; + pRetrieveRsp->numOfFuncs = htonl(pRetrieveRsp->numOfFuncs); + + { + SFuncInfo* pFuncInfo = (SFuncInfo*)(pRetrieveRsp->pFuncInfos); + pFuncInfo->outputLen = htonl(pFuncInfo->outputLen); + pFuncInfo->bufSize = htonl(pFuncInfo->bufSize); + pFuncInfo->signature = htobe64(pFuncInfo->signature); + pFuncInfo->commentSize = htonl(pFuncInfo->commentSize); + pFuncInfo->codeSize = htonl(pFuncInfo->codeSize); + + EXPECT_STREQ(pFuncInfo->name, "f2"); + EXPECT_EQ(pFuncInfo->funcType, 2); + EXPECT_EQ(pFuncInfo->scriptType, 3); + EXPECT_EQ(pFuncInfo->outputType, TSDB_DATA_TYPE_BINARY); + EXPECT_EQ(pFuncInfo->outputLen, 24); + EXPECT_EQ(pFuncInfo->bufSize, 6); + EXPECT_EQ(pFuncInfo->signature, 18); + EXPECT_EQ(pFuncInfo->commentSize, 1024); + EXPECT_EQ(pFuncInfo->codeSize, 9527); + + char* pComment = pFuncInfo->pCont; + char* pCode = pFuncInfo->pCont + pFuncInfo->commentSize; + char* comments = (char*)calloc(1, 1024); + for (int32_t i = 0; i < 1024 - 1; ++i) { + comments[i] = 'p'; + } + char* codes = (char*)calloc(1, 9527); + for (int32_t i = 0; i < 9527 - 1; ++i) { + codes[i] = 'q'; + } + EXPECT_STREQ(pComment, comments); + EXPECT_STREQ(pCode, codes); + free(comments); + free(codes); + } + + { + SFuncInfo* pFuncInfo = (SFuncInfo*)(pRetrieveRsp->pFuncInfos + sizeof(SFuncInfo) + 1024 + 9527); + pFuncInfo->outputLen = htonl(pFuncInfo->outputLen); + pFuncInfo->bufSize = htonl(pFuncInfo->bufSize); + pFuncInfo->signature = htobe64(pFuncInfo->signature); + pFuncInfo->commentSize = htonl(pFuncInfo->commentSize); + pFuncInfo->codeSize = htonl(pFuncInfo->codeSize); + EXPECT_STREQ(pFuncInfo->name, "f1"); + EXPECT_EQ(pFuncInfo->funcType, 1); + EXPECT_EQ(pFuncInfo->scriptType, 2); + EXPECT_EQ(pFuncInfo->outputType, TSDB_DATA_TYPE_SMALLINT); + EXPECT_EQ(pFuncInfo->outputLen, 12); + EXPECT_EQ(pFuncInfo->bufSize, 4); + EXPECT_EQ(pFuncInfo->signature, 5); + EXPECT_EQ(pFuncInfo->commentSize, TSDB_FUNC_COMMENT_LEN); + EXPECT_EQ(pFuncInfo->codeSize, TSDB_FUNC_CODE_LEN); + + char* pComment = pFuncInfo->pCont; + char* pCode = pFuncInfo->pCont + pFuncInfo->commentSize; + char comments[TSDB_FUNC_COMMENT_LEN] = {0}; + for (int32_t i = 0; i < TSDB_FUNC_COMMENT_LEN - 1; ++i) { + comments[i] = 'm'; + } + char codes[TSDB_FUNC_CODE_LEN] = {0}; + for (int32_t i = 0; i < TSDB_FUNC_CODE_LEN - 1; ++i) { + codes[i] = 'd'; + } + EXPECT_STREQ(pComment, comments); + EXPECT_STREQ(pCode, codes); + } + } + + { + int32_t contLen = sizeof(SRetrieveFuncReq); + int32_t numOfFuncs = 2; + contLen = (contLen + numOfFuncs * TSDB_FUNC_NAME_LEN); + + SRetrieveFuncReq* pReq = (SRetrieveFuncReq*)rpcMallocCont(contLen); + pReq->numOfFuncs = htonl(numOfFuncs); + strcpy(pReq->pFuncNames, "f2"); + strcpy((char*)pReq->pFuncNames + TSDB_FUNC_NAME_LEN, "f3"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_RETRIEVE_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC); + } +} + +TEST_F(MndTestFunc, 04_Drop_Func) { + { + int32_t contLen = sizeof(SDropFuncReq); + + SDropFuncReq* pReq = (SDropFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, ""); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_FUNC_NAME); + } + + { + int32_t contLen = sizeof(SDropFuncReq); + + SDropFuncReq* pReq = (SDropFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f3"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_FUNC_NOT_EXIST); + } + + { + int32_t contLen = sizeof(SDropFuncReq); + + SDropFuncReq* pReq = (SDropFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f3"); + pReq->igNotExists = 1; + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDropFuncReq); + + SDropFuncReq* pReq = (SDropFuncReq*)rpcMallocCont(contLen); + strcpy(pReq->name, "f1"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_FUNC, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + test.SendShowMetaReq(TSDB_MGMT_TABLE_FUNC, ""); + CHECK_META("show functions", 7); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + // restart + test.Restart(); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_FUNC, ""); + CHECK_META("show functions", 7); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckBinary("f2", TSDB_FUNC_NAME_LEN); +} diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 6e91ad997c..410e4fb187 100644 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -65,7 +65,7 @@ program ::= cmd. {} //////////////////////////////////THE SHOW STATEMENT/////////////////////////////////////////// cmd ::= SHOW DATABASES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_DB, 0, 0);} cmd ::= SHOW TOPICS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_TP, 0, 0);} -cmd ::= SHOW FUNCTIONS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_FUNCTION, 0, 0);} +cmd ::= SHOW FUNCTIONS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_FUNC, 0, 0);} cmd ::= SHOW MNODES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_MNODE, 0, 0);} cmd ::= SHOW DNODES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_DNODE, 0, 0);} cmd ::= SHOW ACCOUNTS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_ACCT, 0, 0);} diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index a6537998f7..6f63feb3c4 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -2232,7 +2232,7 @@ static void yy_reduce( { setShowOptions(pInfo, TSDB_MGMT_TABLE_TP, 0, 0);} break; case 3: /* cmd ::= SHOW FUNCTIONS */ -{ setShowOptions(pInfo, TSDB_MGMT_TABLE_FUNCTION, 0, 0);} +{ setShowOptions(pInfo, TSDB_MGMT_TABLE_FUNC, 0, 0);} break; case 4: /* cmd ::= SHOW MNODES */ { setShowOptions(pInfo, TSDB_MGMT_TABLE_MNODE, 0, 0);} diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 3a67b6515b..56919ff99e 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -248,6 +248,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_NAME, "Invalid func name") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_COMMENT, "Invalid func comment") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_CODE, "Invalid func code") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_BUFSIZE, "Invalid func bufSize") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_RETRIEVE, "Invalid func retrieve msg") // mnode-trans TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_ALREADY_EXIST, "Transaction already exists")