parInitialATest.cpp 12.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "parTestUtil.h"

using namespace std;

namespace ParserTest {

X
Xiaoyu Wang 已提交
22
class ParserInitialATest : public ParserDdlTest {};
23 24 25 26

TEST_F(ParserInitialATest, alterAccount) {
  useDb("root", "test");

X
Xiaoyu Wang 已提交
27
  run("ALTER ACCOUNT ac_wxy PASS '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT, PARSER_STAGE_PARSE);
28 29 30 31 32
}

TEST_F(ParserInitialATest, alterDnode) {
  useDb("root", "test");

33
  run("ALTER DNODE 1 'resetLog'");
34

35
  run("ALTER DNODE 1 'debugFlag' '134'");
36 37 38 39 40
}

TEST_F(ParserInitialATest, alterDatabase) {
  useDb("root", "test");

41
  run("ALTER DATABASE wxy_db CACHELAST 1 FSYNC 200 WAL 1");
X
Xiaoyu Wang 已提交
42 43

  run("ALTER DATABASE wxy_db KEEP 2400");
44 45
}

46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
// todo ALTER local
// todo ALTER stable

/*
 * ALTER TABLE [db_name.]tb_name alter_table_clause
 *
 * alter_table_clause: {
 *     alter_table_options
 *   | ADD COLUMN col_name column_type
 *   | DROP COLUMN col_name
 *   | MODIFY COLUMN col_name column_type
 *   | RENAME COLUMN old_col_name new_col_name
 *   | ADD TAG tag_name tag_type
 *   | DROP TAG tag_name
 *   | MODIFY TAG tag_name tag_type
 *   | RENAME TAG old_tag_name new_tag_name
 *   | SET TAG tag_name = new_tag_value
 *   | ADD {FULLTEXT | SMA} INDEX index_name (col_name [, col_name] ...) [index_option]
 * }
 *
 * alter_table_options:
 *     alter_table_option ...
 *
 * alter_table_option: {
 *     TTL value
 *   | COMMENT 'string_value'
 * }
 */
X
Xiaoyu Wang 已提交
74
TEST_F(ParserInitialATest, alterSTable) {
75 76
  useDb("root", "test");

X
Xiaoyu Wang 已提交
77 78
  SMAlterStbReq expect = {0};

79 80 81 82 83
  auto clearAlterStbReq = [&]() {
    tFreeSMAltertbReq(&expect);
    memset(&expect, 0, sizeof(SMAlterStbReq));
  };

X
Xiaoyu Wang 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
  auto setAlterStbReqFunc = [&](const char* pTbname, int8_t alterType, int32_t numOfFields = 0,
                                const char* pField1Name = nullptr, int8_t field1Type = 0, int32_t field1Bytes = 0,
                                const char* pField2Name = nullptr, const char* pComment = nullptr,
                                int32_t ttl = TSDB_DEFAULT_TABLE_TTL) {
    int32_t len = snprintf(expect.name, sizeof(expect.name), "0.test.%s", pTbname);
    expect.name[len] = '\0';
    expect.alterType = alterType;
    expect.ttl = ttl;
    if (nullptr != pComment) {
      expect.comment = strdup(pComment);
      expect.commentLen = strlen(pComment) + 1;
    }

    expect.numOfFields = numOfFields;
    if (NULL == expect.pFields) {
      expect.pFields = taosArrayInit(2, sizeof(TAOS_FIELD));
      TAOS_FIELD field = {0};
      taosArrayPush(expect.pFields, &field);
      taosArrayPush(expect.pFields, &field);
    }

    TAOS_FIELD* pField = (TAOS_FIELD*)taosArrayGet(expect.pFields, 0);
    if (NULL != pField1Name) {
      strcpy(pField->name, pField1Name);
      pField->name[strlen(pField1Name)] = '\0';
    } else {
      memset(pField, 0, sizeof(TAOS_FIELD));
    }
    pField->type = field1Type;
    pField->bytes = field1Bytes > 0 ? field1Bytes : (field1Type > 0 ? tDataTypes[field1Type].bytes : 0);

    pField = (TAOS_FIELD*)taosArrayGet(expect.pFields, 1);
    if (NULL != pField2Name) {
      strcpy(pField->name, pField2Name);
      pField->name[strlen(pField2Name)] = '\0';
    } else {
      memset(pField, 0, sizeof(TAOS_FIELD));
    }
    pField->type = 0;
    pField->bytes = 0;
  };

  setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
    ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_TABLE_STMT);
    SMAlterStbReq req = {0};
X
Xiaoyu Wang 已提交
129
    ASSERT_EQ(tDeserializeSMAlterStbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
X
Xiaoyu Wang 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    ASSERT_EQ(std::string(req.name), std::string(expect.name));
    ASSERT_EQ(req.alterType, expect.alterType);
    ASSERT_EQ(req.numOfFields, expect.numOfFields);
    if (expect.numOfFields > 0) {
      TAOS_FIELD* pField = (TAOS_FIELD*)taosArrayGet(req.pFields, 0);
      TAOS_FIELD* pExpectField = (TAOS_FIELD*)taosArrayGet(expect.pFields, 0);
      ASSERT_EQ(std::string(pField->name), std::string(pExpectField->name));
      ASSERT_EQ(pField->type, pExpectField->type);
      ASSERT_EQ(pField->bytes, pExpectField->bytes);
    }
    if (expect.numOfFields > 1) {
      TAOS_FIELD* pField = (TAOS_FIELD*)taosArrayGet(req.pFields, 1);
      TAOS_FIELD* pExpectField = (TAOS_FIELD*)taosArrayGet(expect.pFields, 1);
      ASSERT_EQ(std::string(pField->name), std::string(pExpectField->name));
      ASSERT_EQ(pField->type, pExpectField->type);
      ASSERT_EQ(pField->bytes, pExpectField->bytes);
    }
147
    tFreeSMAltertbReq(&req);
X
Xiaoyu Wang 已提交
148 149
  });

X
Xiaoyu Wang 已提交
150 151
  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, nullptr, 10);
  run("ALTER TABLE st1 TTL 10");
152
  clearAlterStbReq();
X
Xiaoyu Wang 已提交
153

X
Xiaoyu Wang 已提交
154 155
  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, "test");
  run("ALTER TABLE st1 COMMENT 'test'");
156
  clearAlterStbReq();
X
Xiaoyu Wang 已提交
157

X
Xiaoyu Wang 已提交
158 159
  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_COLUMN, 1, "cc1", TSDB_DATA_TYPE_BIGINT);
  run("ALTER TABLE st1 ADD COLUMN cc1 BIGINT");
160
  clearAlterStbReq();
X
Xiaoyu Wang 已提交
161

X
Xiaoyu Wang 已提交
162 163
  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_DROP_COLUMN, 1, "c1");
  run("ALTER TABLE st1 DROP COLUMN c1");
164
  clearAlterStbReq();
X
Xiaoyu Wang 已提交
165

X
Xiaoyu Wang 已提交
166
  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, 1, "c1", TSDB_DATA_TYPE_VARCHAR,
X
Xiaoyu Wang 已提交
167
                     20 + VARSTR_HEADER_SIZE);
X
Xiaoyu Wang 已提交
168
  run("ALTER TABLE st1 MODIFY COLUMN c1 VARCHAR(20)");
169
  clearAlterStbReq();
X
Xiaoyu Wang 已提交
170

X
Xiaoyu Wang 已提交
171 172
  // setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, 2, "c1", 0, 0, "cc1");
  // run("ALTER TABLE st1 RENAME COLUMN c1 cc1");
173

X
Xiaoyu Wang 已提交
174
  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_TAG, 1, "tag11", TSDB_DATA_TYPE_BIGINT);
175
  run("ALTER TABLE st1 ADD TAG tag11 BIGINT");
176
  clearAlterStbReq();
X
Xiaoyu Wang 已提交
177 178

  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_DROP_TAG, 1, "tag1");
179
  run("ALTER TABLE st1 DROP TAG tag1");
180
  clearAlterStbReq();
X
Xiaoyu Wang 已提交
181 182 183

  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, 1, "tag1", TSDB_DATA_TYPE_VARCHAR,
                     20 + VARSTR_HEADER_SIZE);
184
  run("ALTER TABLE st1 MODIFY TAG tag1 VARCHAR(20)");
185
  clearAlterStbReq();
X
Xiaoyu Wang 已提交
186 187

  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_TAG_NAME, 2, "tag1", 0, 0, "tag11");
188
  run("ALTER TABLE st1 RENAME TAG tag1 tag11");
189
  clearAlterStbReq();
190

X
Xiaoyu Wang 已提交
191 192 193 194
  // todo
  // ADD {FULLTEXT | SMA} INDEX index_name (col_name [, col_name] ...) [index_option]
}

X
Xiaoyu Wang 已提交
195 196 197 198 199 200
TEST_F(ParserInitialATest, alterSTableSemanticCheck) {
  useDb("root", "test");

  run("ALTER TABLE st1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE);
}

X
Xiaoyu Wang 已提交
201 202 203 204 205
TEST_F(ParserInitialATest, alterTable) {
  useDb("root", "test");

  SVAlterTbReq expect = {0};

206 207 208 209 210 211
  auto clearAlterTbReq = [&]() {
    free(expect.tbName);
    free(expect.colName);
    free(expect.colNewName);
    free(expect.tagName);
    memset(&expect, 0, sizeof(SVAlterTbReq));
212 213
  };

X
Xiaoyu Wang 已提交
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
  auto setAlterColFunc = [&](const char* pTbname, int8_t alterType, const char* pColName, int8_t dataType = 0,
                             int32_t dataBytes = 0, const char* pNewColName = nullptr) {
    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;
    }
  };

H
Hongze Cheng 已提交
237
  auto setAlterTagFunc = [&](const char* pTbname, const char* pTagName, uint8_t* pNewVal, uint32_t bytes) {
X
Xiaoyu Wang 已提交
238 239 240 241 242 243 244 245 246
    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;
  };

H
Hongze Cheng 已提交
247
  auto setAlterOptionsFunc = [&](const char* pTbname, int32_t ttl, char* pComment = nullptr) {
X
Xiaoyu Wang 已提交
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
    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};
H
Hongze Cheng 已提交
271
    tDecoderInit(&coder, (uint8_t*)pBuf, pVgData->size);
X
Xiaoyu Wang 已提交
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
    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");
304
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
305

H
Hongze Cheng 已提交
306
  setAlterOptionsFunc("t1", -1, (char*)"test");
X
Xiaoyu Wang 已提交
307
  run("ALTER TABLE t1 COMMENT 'test'");
308
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
309 310 311

  setAlterColFunc("t1", TSDB_ALTER_TABLE_ADD_COLUMN, "cc1", TSDB_DATA_TYPE_BIGINT);
  run("ALTER TABLE t1 ADD COLUMN cc1 BIGINT");
312
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
313 314 315

  setAlterColFunc("t1", TSDB_ALTER_TABLE_DROP_COLUMN, "c1");
  run("ALTER TABLE t1 DROP COLUMN c1");
316
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
317

X
Xiaoyu Wang 已提交
318 319
  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)");
320
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
321 322 323

  setAlterColFunc("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, "c1", 0, 0, "cc1");
  run("ALTER TABLE t1 RENAME COLUMN c1 cc1");
324
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
325

X
Xiaoyu Wang 已提交
326
  int32_t val = 10;
H
Hongze Cheng 已提交
327
  setAlterTagFunc("st1s1", "tag1", (uint8_t*)&val, sizeof(val));
X
Xiaoyu Wang 已提交
328
  run("ALTER TABLE st1s1 SET TAG tag1=10");
329
  clearAlterTbReq();
330 331 332 333

  // todo
  // ADD {FULLTEXT | SMA} INDEX index_name (col_name [, col_name] ...) [index_option]
}
334

X
Xiaoyu Wang 已提交
335 336 337 338 339 340
TEST_F(ParserInitialATest, alterTableSemanticCheck) {
  useDb("root", "test");

  run("ALTER TABLE st1s1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE);
}

341 342 343
TEST_F(ParserInitialATest, alterUser) {
  useDb("root", "test");

344
  run("ALTER user wxy PASS '123456'");
345

346
  run("ALTER user wxy privilege 'write'");
347 348
}

X
Xiaoyu Wang 已提交
349 350 351 352 353 354 355 356 357 358 359 360 361
TEST_F(ParserInitialATest, balanceVgroup) {
  useDb("root", "test");

  setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
    ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_BALANCE_VGROUP_STMT);
    ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_BALANCE_VGROUP);
    SBalanceVgroupReq req = {0};
    ASSERT_EQ(tDeserializeSBalanceVgroupReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
  });

  run("BALANCE VGROUP");
}

362 363 364
TEST_F(ParserInitialATest, bug001) {
  useDb("root", "test");

X
Xiaoyu Wang 已提交
365
  run("ALTER DATABASE db WAL 0     # td-14436", TSDB_CODE_PAR_SYNTAX_ERROR, PARSER_STAGE_PARSE);
366 367
}

368
}  // namespace ParserTest