diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 32bda084ed5ab1ddac400354264f18545d88e001..cc10348d24fea98aa852bab008886e36a92fb258 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -642,6 +642,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_INVALID_INTERNAL_PK TAOS_DEF_ERROR_CODE(0, 0x2646) #define TSDB_CODE_PAR_INVALID_TIMELINE_FUNC TAOS_DEF_ERROR_CODE(0, 0x2647) #define TSDB_CODE_PAR_INVALID_PASSWD TAOS_DEF_ERROR_CODE(0, 0x2648) +#define TSDB_CODE_PAR_INVALID_ALTER_TABLE TAOS_DEF_ERROR_CODE(0, 0x2649) //planner #define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700) diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 52edd79f3bacefe10cd02e0b139d87a95fabc827..d180c2ff6e17a9cce4a2da730f256f629f2c0986 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -4217,7 +4217,6 @@ int32_t tDecodeSVAlterTbReq(SDecoder *pDecoder, SVAlterTbReq *pReq) { if (tDecodeCStr(pDecoder, &pReq->tbName) < 0) return -1; if (tDecodeI8(pDecoder, &pReq->action) < 0) return -1; - if (tDecodeCStr(pDecoder, &pReq->colName) < 0) return -1; switch (pReq->action) { case TSDB_ALTER_TABLE_ADD_COLUMN: if (tDecodeCStr(pDecoder, &pReq->colName) < 0) return -1; diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 9c83b600d27a62c81505cb50e28fabd34324319e..836e97c4dbf3b562a4a72a3ee51ea1916af0d5fc 100644 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -241,7 +241,7 @@ alter_table_clause(A) ::= alter_table_clause(A) ::= full_table_name(B) RENAME TAG column_name(C) column_name(D). { A = createAlterTableRenameCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &C, &D); } alter_table_clause(A) ::= - full_table_name(B) SET TAG column_name(C) NK_EQ literal(D). { A = createAlterTableSetTag(pCxt, B, &C, D); } + full_table_name(B) SET TAG column_name(C) NK_EQ literal(D). { A = createAlterTableSetTag(pCxt, B, &C, releaseRawExprNode(pCxt, D)); } %type multi_create_clause { SNodeList* } %destructor multi_create_clause { nodesDestroyList($$); } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 9773b69ee75992b2405cb17d09ce34f727d4b7ce..3983b53b6e001cefaf13cce940989268abeb90c5 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -2949,8 +2949,8 @@ static int32_t translateCreateIndex(STranslateContext* pCxt, SCreateIndexStmt* p } static int32_t translateDropIndex(STranslateContext* pCxt, SDropIndexStmt* pStmt) { - SEncoder encoder = {0}; - int32_t contLen = 0; + SEncoder encoder = {0}; + int32_t contLen = 0; SVDropTSmaReq dropSmaReq = {0}; strcpy(dropSmaReq.indexName, pStmt->indexName); @@ -2958,7 +2958,7 @@ static int32_t translateDropIndex(STranslateContext* pCxt, SDropIndexStmt* pStmt if (NULL == pCxt->pCmdMsg) { return TSDB_CODE_OUT_OF_MEMORY; } - + int32_t ret = 0; tEncodeSize(tEncodeSVDropTSmaReq, &dropSmaReq, contLen, ret); if (ret < 0) { @@ -3800,7 +3800,7 @@ static void destroyCreateTbReqBatch(SVgroupCreateTableBatch* pTbBatch) { taosArrayDestroy(pTbBatch->req.pArray); } -static int32_t rewriteToVnodeModifOpStmt(SQuery* pQuery, SArray* pBufArray) { +static int32_t rewriteToVnodeModifyOpStmt(SQuery* pQuery, SArray* pBufArray) { SVnodeModifOpStmt* pNewStmt = nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT); if (pNewStmt == NULL) { return TSDB_CODE_OUT_OF_MEMORY; @@ -3855,7 +3855,7 @@ static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) { code = buildCreateTableDataBlock(pCxt->pParseCxt->acctId, pStmt, &info, &pBufArray); } if (TSDB_CODE_SUCCESS == code) { - code = rewriteToVnodeModifOpStmt(pQuery, pBufArray); + code = rewriteToVnodeModifyOpStmt(pQuery, pBufArray); if (TSDB_CODE_SUCCESS != code) { destroyCreateTbReqArray(pBufArray); } @@ -4111,7 +4111,7 @@ static int32_t rewriteCreateMultiTable(STranslateContext* pCxt, SQuery* pQuery) return TSDB_CODE_OUT_OF_MEMORY; } - return rewriteToVnodeModifOpStmt(pQuery, pBufArray); + return rewriteToVnodeModifyOpStmt(pQuery, pBufArray); } typedef struct SVgroupDropTableBatch { @@ -4251,14 +4251,162 @@ static int32_t rewriteDropTable(STranslateContext* pCxt, SQuery* pQuery) { return TSDB_CODE_OUT_OF_MEMORY; } - return rewriteToVnodeModifOpStmt(pQuery, pBufArray); + return rewriteToVnodeModifyOpStmt(pQuery, pBufArray); } -static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) { - // todo +static int32_t buildAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq) { + pReq->tbName = strdup(pStmt->tableName); + if (NULL == pReq->tbName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pReq->action = pStmt->alterType; + + switch (pStmt->alterType) { + case TSDB_ALTER_TABLE_ADD_TAG: + case TSDB_ALTER_TABLE_DROP_TAG: + case TSDB_ALTER_TABLE_UPDATE_TAG_NAME: + case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES: + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); + case TSDB_ALTER_TABLE_UPDATE_TAG_VAL: + pReq->tagName = strdup(pStmt->colName); + if (NULL == pReq->tagName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + if (DEAL_RES_ERROR == translateValue(pCxt, pStmt->pVal)) { + return pCxt->errCode; + } + pReq->isNull = (TSDB_DATA_TYPE_NULL == pStmt->pVal->node.resType.type); + pReq->nTagVal = pStmt->pVal->node.resType.bytes; + char* pVal = nodesGetValueFromNode(pStmt->pVal); + pReq->pTagVal = IS_VAR_DATA_TYPE(pStmt->pVal->node.resType.type) ? pVal + VARSTR_HEADER_SIZE : pVal; + break; + case TSDB_ALTER_TABLE_ADD_COLUMN: + case TSDB_ALTER_TABLE_DROP_COLUMN: + pReq->colName = strdup(pStmt->colName); + if (NULL == pReq->colName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pReq->type = pStmt->dataType.type; + pReq->flags = COL_SMA_ON; + pReq->bytes = pStmt->dataType.bytes; + break; + case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES: + pReq->colName = strdup(pStmt->colName); + if (NULL == pReq->colName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pReq->colModBytes = calcTypeBytes(pStmt->dataType); + break; + case TSDB_ALTER_TABLE_UPDATE_OPTIONS: + if (-1 != pStmt->pOptions->ttl) { + pReq->updateTTL = true; + pReq->newTTL = pStmt->pOptions->ttl; + } + if ('\0' != pStmt->pOptions->comment[0]) { + pReq->updateComment = true; + pReq->newComment = strdup(pStmt->pOptions->comment); + if (NULL == pReq->newComment) { + return TSDB_CODE_OUT_OF_MEMORY; + } + } + break; + case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: + pReq->colName = strdup(pStmt->colName); + pReq->colNewName = strdup(pStmt->newColName); + if (NULL == pReq->colName || NULL == pReq->colNewName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + break; + default: + break; + } + return TSDB_CODE_SUCCESS; } +static int32_t serializeAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq, + SArray* pArray) { + SVgroupInfo vg = {0}; + int32_t code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &vg); + int tlen = 0; + if (TSDB_CODE_SUCCESS == code) { + tEncodeSize(tEncodeSVAlterTbReq, pReq, tlen, code); + } + if (TSDB_CODE_SUCCESS == code) { + tlen += sizeof(SMsgHead); + void* pMsg = taosMemoryMalloc(tlen); + if (NULL == pMsg) { + return TSDB_CODE_OUT_OF_MEMORY; + } + ((SMsgHead*)pMsg)->vgId = htonl(vg.vgId); + ((SMsgHead*)pMsg)->contLen = htonl(tlen); + void* pBuf = POINTER_SHIFT(pMsg, sizeof(SMsgHead)); + SEncoder coder = {0}; + tEncoderInit(&coder, pBuf, tlen - sizeof(SMsgHead)); + tEncodeSVAlterTbReq(&coder, pReq); + tEncoderClear(&coder); + + SVgDataBlocks* pVgData = taosMemoryCalloc(1, sizeof(SVgDataBlocks)); + if (NULL == pVgData) { + taosMemoryFree(pMsg); + return TSDB_CODE_OUT_OF_MEMORY; + } + pVgData->vg = vg; + pVgData->pData = pMsg; + pVgData->size = tlen; + pVgData->numOfTables = 1; + taosArrayPush(pArray, &pVgData); + } + + return code; +} + +static int32_t buildModifyVnodeArray(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq, + SArray** pArray) { + SArray* pTmpArray = taosArrayInit(1, sizeof(void*)); + if (NULL == pTmpArray) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + int32_t code = serializeAlterTbReq(pCxt, pStmt, pReq, pTmpArray); + if (TSDB_CODE_SUCCESS == code) { + *pArray = pTmpArray; + } else { + taosArrayDestroy(pTmpArray); + } + + return code; +} + +static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) { + SAlterTableStmt* pStmt = (SAlterTableStmt*)pQuery->pRoot; + + STableMeta* pTableMeta = NULL; + int32_t code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + + if (TSDB_SUPER_TABLE == pTableMeta->tableType) { + return TSDB_CODE_SUCCESS; + } else if (TSDB_CHILD_TABLE != pTableMeta->tableType && TSDB_NORMAL_TABLE != pTableMeta->tableType) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); + } + + SVAlterTbReq req = {0}; + code = buildAlterTbReq(pCxt, pStmt, &req); + + SArray* pArray = NULL; + if (TSDB_CODE_SUCCESS == code) { + code = buildModifyVnodeArray(pCxt, pStmt, &req, &pArray); + } + if (TSDB_CODE_SUCCESS == code) { + code = rewriteToVnodeModifyOpStmt(pQuery, pArray); + } + + return code; +} + static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { int32_t code = TSDB_CODE_SUCCESS; switch (nodeType(pQuery->pRoot)) { @@ -4296,9 +4444,7 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { code = rewriteDropTable(pCxt, pQuery); break; case QUERY_NODE_ALTER_TABLE_STMT: - if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == ((SAlterTableStmt*)pQuery->pRoot)->alterType) { - code = rewriteAlterTable(pCxt, pQuery); - } + code = rewriteAlterTable(pCxt, pQuery); break; default: break; diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 0c703c9dfc40abd39a59673883c44806463a5e2b..e7716741ed5b7cd07fd01ca70c6fe0b59061d690 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -152,6 +152,8 @@ static char* getSyntaxErrFormat(int32_t errCode) { return "Invalid timeline function"; case TSDB_CODE_PAR_INVALID_PASSWD: return "Invalid password"; + case TSDB_CODE_PAR_INVALID_ALTER_TABLE: + return "Invalid alter table statement"; case TSDB_CODE_OUT_OF_MEMORY: return "Out of memory"; default: diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index 42931313382a5d4b0d4fec438970ad52f6b7ff88..ed812405e05ad96ef4390507a0ab5490e3b9f709 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -3500,7 +3500,7 @@ static YYACTIONTYPE yy_reduce( yymsp[-4].minor.yy172 = yylhsminor.yy172; break; case 121: /* alter_table_clause ::= full_table_name SET TAG column_name NK_EQ literal */ -{ yylhsminor.yy172 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy172, &yymsp[-2].minor.yy105, yymsp[0].minor.yy172); } +{ yylhsminor.yy172 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy172, &yymsp[-2].minor.yy105, releaseRawExprNode(pCxt, yymsp[0].minor.yy172)); } yymsp[-5].minor.yy172 = yylhsminor.yy172; break; case 123: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ diff --git a/source/libs/parser/test/parInitialATest.cpp b/source/libs/parser/test/parInitialATest.cpp index 4ddb7736b2cf545f0f05981d43ef0574a77154b6..e1fa8ffe8dd6a3cdd38b35edf3f0e231e3d929e9 100644 --- a/source/libs/parser/test/parInitialATest.cpp +++ b/source/libs/parser/test/parInitialATest.cpp @@ -69,7 +69,7 @@ TEST_F(ParserInitialATest, alterDatabase) { * | COMMENT 'string_value' * } */ -TEST_F(ParserInitialATest, alterTable) { +TEST_F(ParserInitialATest, alterSTable) { useDb("root", "test"); SMAlterStbReq expect = {0}; @@ -119,7 +119,7 @@ TEST_F(ParserInitialATest, alterTable) { setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) { ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_TABLE_STMT); SMAlterStbReq req = {0}; - ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSMAlterStbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req)); + ASSERT_EQ(tDeserializeSMAlterStbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS); ASSERT_EQ(std::string(req.name), std::string(expect.name)); ASSERT_EQ(req.alterType, expect.alterType); ASSERT_EQ(req.numOfFields, expect.numOfFields); @@ -139,24 +139,24 @@ TEST_F(ParserInitialATest, alterTable) { } }); - setAlterStbReqFunc("t1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, nullptr, 10); - run("ALTER TABLE t1 TTL 10"); + setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, nullptr, 10); + run("ALTER TABLE st1 TTL 10"); - setAlterStbReqFunc("t1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, "test"); - run("ALTER TABLE t1 COMMENT 'test'"); + setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, "test"); + run("ALTER TABLE st1 COMMENT 'test'"); - setAlterStbReqFunc("t1", TSDB_ALTER_TABLE_ADD_COLUMN, 1, "cc1", TSDB_DATA_TYPE_BIGINT); - run("ALTER TABLE t1 ADD COLUMN cc1 BIGINT"); + setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_COLUMN, 1, "cc1", TSDB_DATA_TYPE_BIGINT); + run("ALTER TABLE st1 ADD COLUMN cc1 BIGINT"); - setAlterStbReqFunc("t1", TSDB_ALTER_TABLE_DROP_COLUMN, 1, "c1"); - run("ALTER TABLE t1 DROP COLUMN c1"); + setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_DROP_COLUMN, 1, "c1"); + run("ALTER TABLE st1 DROP COLUMN c1"); - setAlterStbReqFunc("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, 1, "c1", TSDB_DATA_TYPE_VARCHAR, + setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, 1, "c1", TSDB_DATA_TYPE_VARCHAR, 20 + VARSTR_HEADER_SIZE); - run("ALTER TABLE t1 MODIFY COLUMN c1 VARCHAR(20)"); + run("ALTER TABLE st1 MODIFY COLUMN c1 VARCHAR(20)"); - setAlterStbReqFunc("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, 2, "c1", 0, 0, "cc1"); - run("ALTER TABLE t1 RENAME COLUMN c1 cc1"); + setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, 2, "c1", 0, 0, "cc1"); + run("ALTER TABLE st1 RENAME COLUMN c1 cc1"); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_TAG, 1, "tag11", TSDB_DATA_TYPE_BIGINT); run("ALTER TABLE st1 ADD TAG tag11 BIGINT"); @@ -171,7 +171,127 @@ TEST_F(ParserInitialATest, alterTable) { setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_TAG_NAME, 2, "tag1", 0, 0, "tag11"); run("ALTER TABLE st1 RENAME TAG tag1 tag11"); - // run("ALTER TABLE st1s1 SET TAG tag1=10"); + // todo + // ADD {FULLTEXT | SMA} INDEX index_name (col_name [, col_name] ...) [index_option] +} + +TEST_F(ParserInitialATest, alterTable) { + useDb("root", "test"); + + SVAlterTbReq expect = {0}; + + auto setAlterColFunc = [&](const char* pTbname, int8_t alterType, const char* pColName, int8_t dataType = 0, + int32_t dataBytes = 0, const char* pNewColName = nullptr) { + memset(&expect, 0, sizeof(SVAlterTbReq)); + expect.tbName = strdup(pTbname); + expect.action = alterType; + expect.colName = strdup(pColName); + + switch (alterType) { + case TSDB_ALTER_TABLE_ADD_COLUMN: + expect.type = dataType; + expect.flags = COL_SMA_ON; + expect.bytes = dataBytes > 0 ? dataBytes : (dataType > 0 ? tDataTypes[dataType].bytes : 0); + break; + case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES: + expect.colModBytes = dataBytes; + break; + case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: + expect.colNewName = strdup(pNewColName); + break; + default: + break; + } + }; + + auto setAlterTagFunc = [&](const char* pTbname, const char* pTagName, const uint8_t* pNewVal, uint32_t bytes) { + memset(&expect, 0, sizeof(SVAlterTbReq)); + expect.tbName = strdup(pTbname); + expect.action = TSDB_ALTER_TABLE_UPDATE_TAG_VAL; + expect.tagName = strdup(pTagName); + + expect.isNull = (nullptr == pNewVal); + expect.nTagVal = bytes; + expect.pTagVal = pNewVal; + }; + + auto setAlterOptionsFunc = [&](const char* pTbname, int32_t ttl, const char* pComment = nullptr) { + memset(&expect, 0, sizeof(SVAlterTbReq)); + expect.tbName = strdup(pTbname); + expect.action = TSDB_ALTER_TABLE_UPDATE_OPTIONS; + if (-1 != ttl) { + expect.updateTTL = true; + expect.newTTL = ttl; + } + if (nullptr != pComment) { + expect.updateComment = true; + expect.newComment = pComment; + } + }; + + setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) { + ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_VNODE_MODIF_STMT); + SVnodeModifOpStmt* pStmt = (SVnodeModifOpStmt*)pQuery->pRoot; + + ASSERT_EQ(pStmt->sqlNodeType, QUERY_NODE_ALTER_TABLE_STMT); + ASSERT_NE(pStmt->pDataBlocks, nullptr); + ASSERT_EQ(taosArrayGetSize(pStmt->pDataBlocks), 1); + SVgDataBlocks* pVgData = (SVgDataBlocks*)taosArrayGetP(pStmt->pDataBlocks, 0); + void* pBuf = POINTER_SHIFT(pVgData->pData, sizeof(SMsgHead)); + SVAlterTbReq req = {0}; + SDecoder coder = {0}; + tDecoderInit(&coder, (const uint8_t*)pBuf, pVgData->size); + ASSERT_EQ(tDecodeSVAlterTbReq(&coder, &req), TSDB_CODE_SUCCESS); + + ASSERT_EQ(std::string(req.tbName), std::string(expect.tbName)); + ASSERT_EQ(req.action, expect.action); + if (nullptr != expect.colName) { + ASSERT_EQ(std::string(req.colName), std::string(expect.colName)); + } + ASSERT_EQ(req.type, expect.type); + ASSERT_EQ(req.flags, expect.flags); + ASSERT_EQ(req.bytes, expect.bytes); + ASSERT_EQ(req.colModBytes, expect.colModBytes); + if (nullptr != expect.colNewName) { + ASSERT_EQ(std::string(req.colNewName), std::string(expect.colNewName)); + } + if (nullptr != expect.tagName) { + ASSERT_EQ(std::string(req.tagName), std::string(expect.tagName)); + } + ASSERT_EQ(req.isNull, expect.isNull); + ASSERT_EQ(req.nTagVal, expect.nTagVal); + ASSERT_EQ(memcmp(req.pTagVal, expect.pTagVal, expect.nTagVal), 0); + ASSERT_EQ(req.updateTTL, expect.updateTTL); + ASSERT_EQ(req.newTTL, expect.newTTL); + ASSERT_EQ(req.updateComment, expect.updateComment); + if (nullptr != expect.newComment) { + ASSERT_EQ(std::string(req.newComment), std::string(expect.newComment)); + } + + tDecoderClear(&coder); + }); + + setAlterOptionsFunc("t1", 10, nullptr); + run("ALTER TABLE t1 TTL 10"); + + setAlterOptionsFunc("t1", -1, "test"); + run("ALTER TABLE t1 COMMENT 'test'"); + + setAlterColFunc("t1", TSDB_ALTER_TABLE_ADD_COLUMN, "cc1", TSDB_DATA_TYPE_BIGINT); + run("ALTER TABLE t1 ADD COLUMN cc1 BIGINT"); + + setAlterColFunc("t1", TSDB_ALTER_TABLE_DROP_COLUMN, "c1"); + run("ALTER TABLE t1 DROP COLUMN c1"); + + setAlterColFunc("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, "c1", TSDB_DATA_TYPE_VARCHAR, 20 + VARSTR_HEADER_SIZE); + run("ALTER TABLE t1 MODIFY COLUMN c1 VARCHAR(20)"); + + setAlterColFunc("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, "c1", 0, 0, "cc1"); + run("ALTER TABLE t1 RENAME COLUMN c1 cc1"); + + int64_t val = 10; + setAlterTagFunc("st1s1", "tag1", (const uint8_t*)&val, sizeof(val)); + run("ALTER TABLE st1s1 SET TAG tag1=10"); // todo // ADD {FULLTEXT | SMA} INDEX index_name (col_name [, col_name] ...) [index_option] diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index d4b9f5b2922c01d833244ed99ba9903f23e2615a..c2434e60f3dff0857bc5b92efbc4d27e583caf45 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -985,6 +985,8 @@ static int32_t getMsgType(ENodeType sqlType) { return TDMT_VND_CREATE_TABLE; case QUERY_NODE_DROP_TABLE_STMT: return TDMT_VND_DROP_TABLE; + case QUERY_NODE_ALTER_TABLE_STMT: + return TDMT_VND_ALTER_TABLE; default: break; } diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index 2710e54f9533ce9ed34552bfa0745d5854c7ad34..5637539feab58969af070ae812b589797800ce76 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -256,6 +256,7 @@ int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t m return TSDB_CODE_SUCCESS; case TDMT_VND_CREATE_TABLE_RSP: case TDMT_VND_DROP_TABLE_RSP: + case TDMT_VND_ALTER_TABLE_RSP: case TDMT_VND_SUBMIT_RSP: break; default: @@ -1131,6 +1132,24 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); break; } + case TDMT_VND_ALTER_TABLE_RSP: { + SVAlterTbRsp rsp = {0}; + if (msg) { + SDecoder coder = {0}; + tDecoderInit(&coder, msg, msgSize); + code = tDecodeSVAlterTbRsp(&coder, &rsp); + tDecoderClear(&coder); + SCH_ERR_JRET(code); + SCH_ERR_JRET(rsp.code); + } + + SCH_ERR_JRET(rspCode); + + if (NULL == msg) { + SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); + } + break; + } case TDMT_VND_SUBMIT_RSP: { SCH_ERR_JRET(rspCode); @@ -1391,6 +1410,10 @@ int32_t schHandleDropTableCallback(void *param, const SDataBuf *pMsg, int32_t co return schHandleCallback(param, pMsg, TDMT_VND_DROP_TABLE_RSP, code); } +int32_t schHandleAlterTableCallback(void *param, const SDataBuf *pMsg, int32_t code) { + return schHandleCallback(param, pMsg, TDMT_VND_ALTER_TABLE_RSP, code); +} + int32_t schHandleQueryCallback(void *param, const SDataBuf *pMsg, int32_t code) { return schHandleCallback(param, pMsg, TDMT_VND_QUERY_RSP, code); } @@ -1490,6 +1513,9 @@ int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) { case TDMT_VND_DROP_TABLE: *fp = schHandleDropTableCallback; break; + case TDMT_VND_ALTER_TABLE: + *fp = schHandleAlterTableCallback; + break; case TDMT_VND_SUBMIT: *fp = schHandleSubmitCallback; break; @@ -2010,6 +2036,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, switch (msgType) { case TDMT_VND_CREATE_TABLE: case TDMT_VND_DROP_TABLE: + case TDMT_VND_ALTER_TABLE: case TDMT_VND_SUBMIT: { msgSize = pTask->msgLen; msg = taosMemoryCalloc(1, msgSize);