From d5d73250fea8730db7558c9b467d59e7a0395d19 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 17 May 2022 14:12:06 +0800 Subject: [PATCH] fix: sql command 'alter table' --- include/util/taoserror.h | 2 + source/libs/parser/src/parTranslater.c | 184 +++++++++++++++----- source/libs/parser/src/parUtil.c | 4 + source/libs/parser/test/parInitialATest.cpp | 6 +- source/libs/scheduler/src/scheduler.c | 1 + 5 files changed, 147 insertions(+), 50 deletions(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 31b6dad2d8..f2ab9cbc6e 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -644,6 +644,8 @@ int32_t* taosGetErrno(); #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) +#define TSDB_CODE_PAR_CANNOT_DROP_PRIMARY_KEY TAOS_DEF_ERROR_CODE(0, 0x264A) +#define TSDB_CODE_PAR_INVALID_MODIFY_COL TAOS_DEF_ERROR_CODE(0, 0x264B) //planner #define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 3983b53b6e..df7d10969d 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -4254,7 +4254,135 @@ static int32_t rewriteDropTable(STranslateContext* pCxt, SQuery* pQuery) { return rewriteToVnodeModifyOpStmt(pQuery, pBufArray); } -static int32_t buildAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq) { +static SSchema* getColSchema(STableMeta* pTableMeta, const char* pTagName) { + int32_t numOfFields = getNumOfTags(pTableMeta) + getNumOfColumns(pTableMeta); + for (int32_t i = 0; i < numOfFields; ++i) { + SSchema* pTagSchema = pTableMeta->schema + i; + if (0 == strcmp(pTagName, pTagSchema->name)) { + return pTagSchema; + } + } + return NULL; +} + +static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta, + SVAlterTbReq* pReq) { + SSchema* pSchema = getColSchema(pTableMeta, pStmt->colName); + if (NULL == pSchema) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); + } + + pReq->tagName = strdup(pStmt->colName); + if (NULL == pReq->tagName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + if (DEAL_RES_ERROR == translateValueImpl(pCxt, pStmt->pVal, schemaToDataType(pSchema))) { + 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; + + return TSDB_CODE_SUCCESS; +} + +static int32_t buildAddColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta, + SVAlterTbReq* pReq) { + if (NULL != getColSchema(pTableMeta, pStmt->colName)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_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; + return TSDB_CODE_SUCCESS; +} + +static int32_t buildDropColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta, + SVAlterTbReq* pReq) { + SSchema* pSchema = getColSchema(pTableMeta, pStmt->colName); + if (NULL == pSchema) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pStmt->colName); + } else if (PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_CANNOT_DROP_PRIMARY_KEY); + } + + pReq->colName = strdup(pStmt->colName); + if (NULL == pReq->colName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t buildUpdateColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta, + SVAlterTbReq* pReq) { + pReq->colModBytes = calcTypeBytes(pStmt->dataType); + + SSchema* pSchema = getColSchema(pTableMeta, pStmt->colName); + if (NULL == pSchema) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pStmt->colName); + } else if (!IS_VAR_DATA_TYPE(pSchema->type) || pSchema->bytes >= pReq->colModBytes) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL); + } + + pReq->colName = strdup(pStmt->colName); + if (NULL == pReq->colName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t buildRenameColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta, + SVAlterTbReq* pReq) { + if (NULL == getColSchema(pTableMeta, pStmt->colName)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pStmt->colName); + } + if (NULL != getColSchema(pTableMeta, pStmt->newColName)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN); + } + + pReq->colName = strdup(pStmt->colName); + pReq->colNewName = strdup(pStmt->newColName); + if (NULL == pReq->colName || NULL == pReq->colNewName) { + return TSDB_CODE_OUT_OF_MEMORY; + } + return TSDB_CODE_SUCCESS; +} + +static int32_t buildUpdateOptionsReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq) { + int32_t code = TSDB_CODE_SUCCESS; + + if (-1 != pStmt->pOptions->ttl) { + code = checkRangeOption(pCxt, "ttl", pStmt->pOptions->ttl, TSDB_MIN_TABLE_TTL, INT32_MAX); + if (TSDB_CODE_SUCCESS == code) { + pReq->updateTTL = true; + pReq->newTTL = pStmt->pOptions->ttl; + } + } + + if (TSDB_CODE_SUCCESS == code && '\0' != pStmt->pOptions->comment[0]) { + pReq->updateComment = true; + pReq->newComment = strdup(pStmt->pOptions->comment); + if (NULL == pReq->newComment) { + code = TSDB_CODE_OUT_OF_MEMORY; + } + } + + return code; +} + +static int32_t buildAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta, + SVAlterTbReq* pReq) { pReq->tbName = strdup(pStmt->tableName); if (NULL == pReq->tbName) { return TSDB_CODE_OUT_OF_MEMORY; @@ -4268,60 +4396,22 @@ static int32_t buildAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, 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; + return buildUpdateTagValReq(pCxt, pStmt, pTableMeta, pReq); case TSDB_ALTER_TABLE_ADD_COLUMN: + return buildAddColReq(pCxt, pStmt, pTableMeta, pReq); 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; + return buildDropColReq(pCxt, pStmt, pTableMeta, pReq); 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; + return buildUpdateColReq(pCxt, pStmt, pTableMeta, pReq); 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; + return buildUpdateOptionsReq(pCxt, pStmt, pReq); 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; + return buildRenameColReq(pCxt, pStmt, pTableMeta, pReq); default: break; } - return TSDB_CODE_SUCCESS; + return TSDB_CODE_FAILED; } static int32_t serializeAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq, @@ -4394,7 +4484,7 @@ static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) { } SVAlterTbReq req = {0}; - code = buildAlterTbReq(pCxt, pStmt, &req); + code = buildAlterTbReq(pCxt, pStmt, pTableMeta, &req); SArray* pArray = NULL; if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index e7716741ed..cb2d1b7c07 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -154,6 +154,10 @@ static char* getSyntaxErrFormat(int32_t errCode) { return "Invalid password"; case TSDB_CODE_PAR_INVALID_ALTER_TABLE: return "Invalid alter table statement"; + case TSDB_CODE_PAR_CANNOT_DROP_PRIMARY_KEY: + return "Primary timestamp column cannot be dropped"; + case TSDB_CODE_PAR_INVALID_MODIFY_COL: + return "Only binary/nchar column length could be modified"; case TSDB_CODE_OUT_OF_MEMORY: return "Out of memory"; default: diff --git a/source/libs/parser/test/parInitialATest.cpp b/source/libs/parser/test/parInitialATest.cpp index e1fa8ffe8d..cc0dded570 100644 --- a/source/libs/parser/test/parInitialATest.cpp +++ b/source/libs/parser/test/parInitialATest.cpp @@ -283,13 +283,13 @@ TEST_F(ParserInitialATest, alterTable) { 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_BYTES, "c2", TSDB_DATA_TYPE_VARCHAR, 30 + VARSTR_HEADER_SIZE); + run("ALTER TABLE t1 MODIFY COLUMN c2 VARCHAR(30)"); setAlterColFunc("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, "c1", 0, 0, "cc1"); run("ALTER TABLE t1 RENAME COLUMN c1 cc1"); - int64_t val = 10; + int32_t val = 10; setAlterTagFunc("st1s1", "tag1", (const uint8_t*)&val, sizeof(val)); run("ALTER TABLE st1s1 SET TAG tag1=10"); diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index 5637539fea..4fcdb35e0d 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -1148,6 +1148,7 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch if (NULL == msg) { SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); } + SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); break; } case TDMT_VND_SUBMIT_RSP: { -- GitLab