diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 1b0d4bffee2832b4cfcd84b5881343e1616e1972..544af9b6eed46cde117815a66e0f99e1e60c0322 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -1764,18 +1764,15 @@ int32_t tDecodeSVDropTbBatchRsp(SDecoder* pCoder, SVDropTbBatchRsp* pRsp); typedef struct { const char* tbName; int8_t action; + const char* colName; // TSDB_ALTER_TABLE_ADD_COLUMN - int8_t type; - int8_t flags; - int32_t bytes; - const char* colAddName; + int8_t type; + int8_t flags; + int32_t bytes; // TSDB_ALTER_TABLE_DROP_COLUMN - const char* colDropName; // TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES - const char* colModName; - int32_t colModBytes; + int32_t colModBytes; // TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME - const char* colOldName; const char* colNewName; // TSDB_ALTER_TABLE_UPDATE_TAG_VAL const char* tagName; diff --git a/include/util/taoserror.h b/include/util/taoserror.h index b8f6e44c2db32356525543bdfff0053be458b11c..32bda084ed5ab1ddac400354264f18545d88e001 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -324,7 +324,8 @@ int32_t* taosGetErrno(); #define TSDB_CODE_VND_HASH_MISMATCH TAOS_DEF_ERROR_CODE(0, 0x0517) #define TSDB_CODE_VND_TABLE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0518) #define TSDB_CODE_VND_INVALID_TABLE_ACTION TAOS_DEF_ERROR_CODE(0, 0x0519) -#define TSDB_CODE_VND_COL_ALREADY_EXISTS TAOS_DEF_ERROR_CODE(0, 0x051a) +#define TSDB_CODE_VND_COL_ALREADY_EXISTS TAOS_DEF_ERROR_CODE(0, 0x051a) +#define TSDB_CODE_VND_TABLE_COL_NOT_EXISTS TAOS_DEF_ERROR_CODE(0, 0x051b) // tsdb #define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index bcb2bae22f62196b7220a86dcb3895e992e116a5..ce038a6df1029b3c4be452fd5e5f5d46e3a31ab3 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -4169,22 +4169,19 @@ int32_t tEncodeSVAlterTbReq(SEncoder *pEncoder, const SVAlterTbReq *pReq) { if (tEncodeCStr(pEncoder, pReq->tbName) < 0) return -1; if (tEncodeI8(pEncoder, pReq->action) < 0) return -1; + if (tEncodeCStr(pEncoder, pReq->colName) < 0) return -1; switch (pReq->action) { case TSDB_ALTER_TABLE_ADD_COLUMN: if (tEncodeI8(pEncoder, pReq->type) < 0) return -1; if (tEncodeI8(pEncoder, pReq->flags) < 0) return -1; if (tEncodeI32v(pEncoder, pReq->bytes) < 0) return -1; - if (tEncodeCStr(pEncoder, pReq->colAddName) < 0) return -1; break; case TSDB_ALTER_TABLE_DROP_COLUMN: - if (tEncodeCStr(pEncoder, pReq->colDropName) < 0) return -1; break; case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES: - if (tEncodeCStr(pEncoder, pReq->colModName) < 0) return -1; if (tEncodeI32v(pEncoder, pReq->colModBytes) < 0) return -1; break; case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: - if (tEncodeCStr(pEncoder, pReq->colOldName) < 0) return -1; if (tEncodeCStr(pEncoder, pReq->colNewName) < 0) return -1; break; case TSDB_ALTER_TABLE_UPDATE_TAG_VAL: @@ -4217,22 +4214,19 @@ 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 (tDecodeI8(pDecoder, &pReq->type) < 0) return -1; if (tDecodeI8(pDecoder, &pReq->flags) < 0) return -1; if (tDecodeI32v(pDecoder, &pReq->bytes) < 0) return -1; - if (tDecodeCStr(pDecoder, &pReq->colAddName) < 0) return -1; break; case TSDB_ALTER_TABLE_DROP_COLUMN: - if (tDecodeCStr(pDecoder, &pReq->colDropName) < 0) return -1; break; case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES: - if (tDecodeCStr(pDecoder, &pReq->colModName) < 0) return -1; if (tDecodeI32v(pDecoder, &pReq->colModBytes) < 0) return -1; break; case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: - if (tDecodeCStr(pDecoder, &pReq->colOldName) < 0) return -1; if (tDecodeCStr(pDecoder, &pReq->colNewName) < 0) return -1; break; case TSDB_ALTER_TABLE_UPDATE_TAG_VAL: diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index f00e59f3d533fec25ed17400307481eb4e85cdd6..46c22da95237ba3af7b06f6049f405e0561a34fa 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -376,8 +376,138 @@ int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq) { } static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) { - // TODO + void *pVal = NULL; + int nVal = 0; + const void *pData = NULL; + int nData = 0; + int ret = 0; + tb_uid_t uid; + int64_t oversion; + SSchema *pColumn = NULL; + SMetaEntry entry = {0}; + SSchemaWrapper *pSchema; + int c; + + // search name index + ret = tdbDbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal); + if (ret < 0) { + terrno = TSDB_CODE_VND_TABLE_NOT_EXIST; + return -1; + } + + uid = *(tb_uid_t *)pVal; + tdbFree(pVal); + pVal = NULL; + + // search uid index + TDBC *pUidIdxc = NULL; + + tdbDbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn); + tdbDbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c); + ASSERT(c == 0); + + tdbDbcGet(pUidIdxc, NULL, NULL, &pData, &nData); + oversion = *(int64_t *)pData; + + // search table.db + TDBC *pTbDbc = NULL; + + tdbDbcOpen(pMeta->pTbDb, &pTbDbc, &pMeta->txn); + tdbDbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c); + ASSERT(c == 0); + tdbDbcGet(pTbDbc, NULL, NULL, &pData, &nData); + + // get table entry + SDecoder dc = {0}; + tDecoderInit(&dc, pData, nData); + metaDecodeEntry(&dc, &entry); + + if (entry.type != TSDB_NORMAL_TABLE) { + terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION; + goto _err; + } + + // search the column to add/drop/update + pSchema = &entry.ntbEntry.schema; + int32_t iCol = 0; + for (;;) { + pColumn = NULL; + + if (iCol >= pSchema->nCols) break; + pColumn = &pSchema->pSchema[iCol]; + + if (strcmp(pColumn->name, pAlterTbReq->colName) == 0) break; + iCol++; + } + + entry.version = version; + int tlen; + switch (pAlterTbReq->action) { + case TSDB_ALTER_TABLE_ADD_COLUMN: + if (pColumn) { + terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS; + goto _err; + } + pSchema->sver++; + pSchema->nCols++; + pSchema->pSchema = + taosMemoryRealloc(entry.ntbEntry.schema.pSchema, sizeof(SSchema) * entry.ntbEntry.schema.nCols); + pSchema->pSchema[entry.ntbEntry.schema.nCols - 1].bytes = pAlterTbReq->bytes; + pSchema->pSchema[entry.ntbEntry.schema.nCols - 1].type = pAlterTbReq->type; + pSchema->pSchema[entry.ntbEntry.schema.nCols - 1].flags = pAlterTbReq->flags; + pSchema->pSchema[entry.ntbEntry.schema.nCols - 1].colId = entry.ntbEntry.ncid++; + strcpy(pSchema->pSchema[entry.ntbEntry.schema.nCols - 1].name, pAlterTbReq->colName); + break; + case TSDB_ALTER_TABLE_DROP_COLUMN: + if (pColumn == NULL) { + terrno = TSDB_CODE_VND_TABLE_COL_NOT_EXISTS; + goto _err; + } + if (pColumn->colId == 0) { + terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION; + goto _err; + } + pSchema->sver++; + pSchema->nCols--; + tlen = (pSchema->nCols - iCol - 1) * sizeof(SSchema); + if (tlen) { + memmove(pColumn, pColumn + 1, tlen); + } + break; + case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES: + if (pColumn == NULL) { + terrno = TSDB_CODE_VND_TABLE_COL_NOT_EXISTS; + goto _err; + } + if (!IS_VAR_DATA_TYPE(pColumn->type) || pColumn->bytes <= pAlterTbReq->bytes) { + terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION; + goto _err; + } + pSchema->sver++; + pColumn->bytes = pAlterTbReq->bytes; + break; + case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: + if (pColumn == NULL) { + terrno = TSDB_CODE_VND_TABLE_COL_NOT_EXISTS; + goto _err; + } + pSchema->sver++; + strcpy(pColumn->name, pAlterTbReq->colNewName); + break; + } + + entry.version = version; + + tDecoderClear(&dc); + tdbDbcClose(pTbDbc); + tdbDbcClose(pUidIdxc); return 0; + +_err: + tDecoderClear(&dc); + tdbDbcClose(pTbDbc); + tdbDbcClose(pUidIdxc); + return -1; } static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) { diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 8857427af75867e18c3726e3df03cf5ec74ce577..b5e64242e4e50179352debf1989a97f70108eef5 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -324,6 +324,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_HASH_MISMATCH, "Hash value mismatch") TAOS_DEFINE_ERROR(TSDB_CODE_VND_TABLE_NOT_EXIST, "Table does not exists") TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_TABLE_ACTION, "Invalid table action") TAOS_DEFINE_ERROR(TSDB_CODE_VND_COL_ALREADY_EXISTS, "Table column already exists") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_TABLE_COL_NOT_EXISTS, "Table column not exists") + // tsdb TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INVALID_TABLE_ID, "Invalid table ID")