parInitialATest.cpp 12.6 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 167 168
  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, 1, "c2", TSDB_DATA_TYPE_VARCHAR,
                     30 + VARSTR_HEADER_SIZE);
  run("ALTER TABLE st1 MODIFY COLUMN c2 VARCHAR(30)");
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

X
Xiaoyu Wang 已提交
182 183 184
  setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, 1, "tag2", TSDB_DATA_TYPE_VARCHAR,
                     30 + VARSTR_HEADER_SIZE);
  run("ALTER TABLE st1 MODIFY TAG tag2 VARCHAR(30)");
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
TEST_F(ParserInitialATest, alterSTableSemanticCheck) {
  useDb("root", "test");

  run("ALTER TABLE st1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE);
X
Xiaoyu Wang 已提交
199 200 201 202

  run("ALTER TABLE st1 MODIFY COLUMN c2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL);

  run("ALTER TABLE st1 MODIFY TAG tag2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL);
X
Xiaoyu Wang 已提交
203 204
}

X
Xiaoyu Wang 已提交
205 206 207 208 209
TEST_F(ParserInitialATest, alterTable) {
  useDb("root", "test");

  SVAlterTbReq expect = {0};

210 211 212 213 214 215
  auto clearAlterTbReq = [&]() {
    free(expect.tbName);
    free(expect.colName);
    free(expect.colNewName);
    free(expect.tagName);
    memset(&expect, 0, sizeof(SVAlterTbReq));
216 217
  };

X
Xiaoyu Wang 已提交
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
  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 已提交
241
  auto setAlterTagFunc = [&](const char* pTbname, const char* pTagName, uint8_t* pNewVal, uint32_t bytes) {
X
Xiaoyu Wang 已提交
242 243 244 245 246 247 248 249 250
    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 已提交
251
  auto setAlterOptionsFunc = [&](const char* pTbname, int32_t ttl, char* pComment = nullptr) {
X
Xiaoyu Wang 已提交
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
    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 已提交
275
    tDecoderInit(&coder, (uint8_t*)pBuf, pVgData->size);
X
Xiaoyu Wang 已提交
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 304 305 306 307
    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");
308
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
309

H
Hongze Cheng 已提交
310
  setAlterOptionsFunc("t1", -1, (char*)"test");
X
Xiaoyu Wang 已提交
311
  run("ALTER TABLE t1 COMMENT 'test'");
312
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
313 314 315

  setAlterColFunc("t1", TSDB_ALTER_TABLE_ADD_COLUMN, "cc1", TSDB_DATA_TYPE_BIGINT);
  run("ALTER TABLE t1 ADD COLUMN cc1 BIGINT");
316
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
317 318 319

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

X
Xiaoyu Wang 已提交
322 323
  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)");
324
  clearAlterTbReq();
X
Xiaoyu Wang 已提交
325 326 327

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

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

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

X
Xiaoyu Wang 已提交
339 340 341 342
TEST_F(ParserInitialATest, alterTableSemanticCheck) {
  useDb("root", "test");

  run("ALTER TABLE st1s1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE);
X
Xiaoyu Wang 已提交
343 344

  run("ALTER TABLE st1s1 SET TAG tag2 =  '123456789012345678901'", TSDB_CODE_PAR_WRONG_VALUE_TYPE);
X
Xiaoyu Wang 已提交
345 346
}

347 348 349
TEST_F(ParserInitialATest, alterUser) {
  useDb("root", "test");

350
  run("ALTER user wxy PASS '123456'");
351

352
  run("ALTER user wxy privilege 'write'");
353 354
}

X
Xiaoyu Wang 已提交
355 356 357 358 359 360 361 362 363 364 365 366 367
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");
}

368 369 370
TEST_F(ParserInitialATest, bug001) {
  useDb("root", "test");

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

374
}  // namespace ParserTest