parTranslater.c 280.5 KB
Newer Older
1
/*
wmmhello's avatar
wmmhello 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14
 * 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/>.
 */
15

X
Xiaoyu Wang 已提交
16
#include "parInt.h"
17

X
Xiaoyu Wang 已提交
18
#include "catalog.h"
19
#include "cmdnodes.h"
X
Xiaoyu Wang 已提交
20
#include "filter.h"
21
#include "functionMgt.h"
X
Xiaoyu Wang 已提交
22
#include "parUtil.h"
23
#include "scalar.h"
24
#include "systable.h"
X
Xiaoyu Wang 已提交
25
#include "tglobal.h"
26
#include "ttime.h"
27

X
Xiaoyu Wang 已提交
28
#define generateDealNodeErrMsg(pCxt, code, ...) \
wmmhello's avatar
wmmhello 已提交
29
  (pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, code, ##__VA_ARGS__), DEAL_RES_ERROR)
X
Xiaoyu Wang 已提交
30

X
Xiaoyu Wang 已提交
31 32
#define SYSTABLE_SHOW_TYPE_OFFSET QUERY_NODE_SHOW_DNODES_STMT

33
typedef struct STranslateContext {
wmmhello's avatar
wmmhello 已提交
34 35 36 37 38
  SParseContext*   pParseCxt;
  int32_t          errCode;
  SMsgBuf          msgBuf;
  SArray*          pNsLevel;  // element is SArray*, the element of this subarray is STableNode*
  int32_t          currLevel;
39
  int32_t          levelNo;
wmmhello's avatar
wmmhello 已提交
40
  ESqlClause       currClause;
41
  SNode*           pCurrStmt;
wmmhello's avatar
wmmhello 已提交
42 43 44
  SCmdMsgInfo*     pCmdMsg;
  SHashObj*        pDbs;
  SHashObj*        pTables;
D
dapan1121 已提交
45
  SHashObj*        pTargetTables;
wmmhello's avatar
wmmhello 已提交
46
  SExplainOptions* pExplainOpt;
47
  SParseMetaCache* pMetaCache;
X
Xiaoyu Wang 已提交
48
  bool             createStream;
49
  bool             stableQuery;
50 51
} STranslateContext;

X
Xiaoyu Wang 已提交
52
typedef struct SFullDatabaseName {
wmmhello's avatar
wmmhello 已提交
53
  char fullDbName[TSDB_DB_FNAME_LEN];
X
Xiaoyu Wang 已提交
54 55
} SFullDatabaseName;

X
Xiaoyu Wang 已提交
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
typedef struct SSysTableShowAdapter {
  ENodeType   showType;
  const char* pDbName;
  const char* pTableName;
  int32_t     numOfShowCols;
  const char* pShowCols[2];
} SSysTableShowAdapter;

// clang-format off
static const SSysTableShowAdapter sysTableShowAdapter[] = {
  {
    .showType = QUERY_NODE_SHOW_DNODES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_DNODES,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
71
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
72 73 74 75 76 77
  },
  {
    .showType = QUERY_NODE_SHOW_MNODES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_MNODES,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
78
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
79 80 81 82 83 84
  },
  {
    .showType = QUERY_NODE_SHOW_MODULES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_MODULES,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
85
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
86 87 88 89 90 91
  },
  {
    .showType = QUERY_NODE_SHOW_QNODES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_QNODES,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
92
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
93 94 95 96 97 98
  },
  {
    .showType = QUERY_NODE_SHOW_SNODES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_SNODES,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
99
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
100 101 102 103 104 105
  },
  {
    .showType = QUERY_NODE_SHOW_BNODES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_BNODES,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
106
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
107 108 109 110 111 112
  },
  {
    .showType = QUERY_NODE_SHOW_CLUSTER_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_CLUSTER,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
113
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
  },
  {
    .showType = QUERY_NODE_SHOW_DATABASES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_DATABASES,
    .numOfShowCols = 1,
    .pShowCols = {"name"}
  },
  {
    .showType = QUERY_NODE_SHOW_FUNCTIONS_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_FUNCTIONS,
    .numOfShowCols = 1,
    .pShowCols = {"name"}
  },
  {
    .showType = QUERY_NODE_SHOW_INDEXES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_INDEXES,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
134
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
135 136 137 138 139 140 141 142 143 144
  },
  {
    .showType = QUERY_NODE_SHOW_STABLES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_STABLES,
    .numOfShowCols = 1,
    .pShowCols = {"stable_name"}
  },
  {
    .showType = QUERY_NODE_SHOW_STREAMS_STMT,
145 146
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_STREAMS,
X
Xiaoyu Wang 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
    .numOfShowCols = 1,
    .pShowCols = {"stream_name"}
  },
  {
    .showType = QUERY_NODE_SHOW_TABLES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_TABLES,
    .numOfShowCols = 1,
    .pShowCols = {"table_name"}
  },
  {
    .showType = QUERY_NODE_SHOW_TAGS_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_TAGS,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_USERS_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_USERS,
    .numOfShowCols = 1,
X
Xiaoyu Wang 已提交
169
    .pShowCols = {"*"}
X
Xiaoyu Wang 已提交
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
  },
  {
    .showType = QUERY_NODE_SHOW_LICENCES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_LICENCES,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_VGROUPS_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_VGROUPS,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_TOPICS_STMT,
187 188
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_TOPICS,
X
Xiaoyu Wang 已提交
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
    .numOfShowCols = 1,
    .pShowCols = {"topic_name"}
  },
  {
    .showType = QUERY_NODE_SHOW_CONSUMERS_STMT,
    .pDbName = TSDB_PERFORMANCE_SCHEMA_DB,
    .pTableName = TSDB_PERFS_TABLE_CONSUMERS,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_CONNECTIONS_STMT,
    .pDbName = TSDB_PERFORMANCE_SCHEMA_DB,
    .pTableName = TSDB_PERFS_TABLE_CONNECTIONS,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_QUERIES_STMT,
    .pDbName = TSDB_PERFORMANCE_SCHEMA_DB,
    .pTableName = TSDB_PERFS_TABLE_QUERIES,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_APPS_STMT,
    .pDbName = TSDB_PERFORMANCE_SCHEMA_DB,
    .pTableName = TSDB_PERFS_TABLE_APPS,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_VARIABLES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_CONFIGS,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_DNODE_VARIABLES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_DNODE_VARIABLES,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_TRANSACTIONS_STMT,
    .pDbName = TSDB_PERFORMANCE_SCHEMA_DB,
    .pTableName = TSDB_PERFS_TABLE_TRANS,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
  {
    .showType = QUERY_NODE_SHOW_SUBSCRIPTIONS_STMT,
243 244
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_SUBSCRIPTIONS,
X
Xiaoyu Wang 已提交
245 246 247
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
248 249 250 251 252 253
  { .showType = QUERY_NODE_SHOW_VNODES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_VNODES,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
254 255 256 257 258 259
  { .showType = QUERY_NODE_SHOW_USER_PRIVILEGES_STMT,
    .pDbName = TSDB_INFORMATION_SCHEMA_DB,
    .pTableName = TSDB_INS_TABLE_USER_PRIVILEGES,
    .numOfShowCols = 1,
    .pShowCols = {"*"}
  },
X
Xiaoyu Wang 已提交
260 261 262
};
// clang-format on

X
Xiaoyu Wang 已提交
263 264 265
static int32_t  translateSubquery(STranslateContext* pCxt, SNode* pNode);
static int32_t  translateQuery(STranslateContext* pCxt, SNode* pNode);
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal);
266

dengyihao's avatar
dengyihao 已提交
267
static bool afterGroupBy(ESqlClause clause) { return clause > SQL_CLAUSE_GROUP_BY; }
268

dengyihao's avatar
dengyihao 已提交
269
static bool beforeHaving(ESqlClause clause) { return clause < SQL_CLAUSE_HAVING; }
270

271 272
static bool afterHaving(ESqlClause clause) { return clause > SQL_CLAUSE_HAVING; }

X
Xiaoyu Wang 已提交
273 274
static bool beforeWindow(ESqlClause clause) { return clause < SQL_CLAUSE_WINDOW; }

275 276 277 278 279 280 281 282 283 284 285 286 287 288
static bool hasSameTableAlias(SArray* pTables) {
  if (taosArrayGetSize(pTables) < 2) {
    return false;
  }
  STableNode* pTable0 = taosArrayGetP(pTables, 0);
  for (int32_t i = 1; i < taosArrayGetSize(pTables); ++i) {
    STableNode* pTable = taosArrayGetP(pTables, i);
    if (0 == strcmp(pTable0->tableAlias, pTable->tableAlias)) {
      return true;
    }
  }
  return false;
}

289
static int32_t addNamespace(STranslateContext* pCxt, void* pTable) {
wmmhello's avatar
wmmhello 已提交
290 291 292 293
  size_t currTotalLevel = taosArrayGetSize(pCxt->pNsLevel);
  if (currTotalLevel > pCxt->currLevel) {
    SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
    taosArrayPush(pTables, &pTable);
294
    if (hasSameTableAlias(pTables)) {
295 296
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_UNIQUE_TABLE_ALIAS,
                                     "Not unique table/alias: '%s'", ((STableNode*)pTable)->tableAlias);
297
    }
wmmhello's avatar
wmmhello 已提交
298 299 300
  } else {
    do {
      SArray* pTables = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
X
Xiaoyu Wang 已提交
301 302 303
      if (NULL == pTables) {
        return TSDB_CODE_OUT_OF_MEMORY;
      }
wmmhello's avatar
wmmhello 已提交
304 305
      if (pCxt->currLevel == currTotalLevel) {
        taosArrayPush(pTables, &pTable);
306
        if (hasSameTableAlias(pTables)) {
X
Xiaoyu Wang 已提交
307
          taosArrayDestroy(pTables);
308 309
          return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_UNIQUE_TABLE_ALIAS,
                                         "Not unique table/alias: '%s'", ((STableNode*)pTable)->tableAlias);
310
        }
wmmhello's avatar
wmmhello 已提交
311 312 313 314 315 316
      }
      taosArrayPush(pCxt->pNsLevel, &pTables);
      ++currTotalLevel;
    } while (currTotalLevel <= pCxt->currLevel);
  }
  return TSDB_CODE_SUCCESS;
317 318
}

D
dapan1121 已提交
319
static int32_t collectUseDatabaseImpl(const char* pFullDbName, SHashObj* pDbs) {
wmmhello's avatar
wmmhello 已提交
320
  SFullDatabaseName name = {0};
X
Xiaoyu Wang 已提交
321
  snprintf(name.fullDbName, sizeof(name.fullDbName), "%s", pFullDbName);
wmmhello's avatar
wmmhello 已提交
322
  return taosHashPut(pDbs, pFullDbName, strlen(pFullDbName), &name, sizeof(SFullDatabaseName));
X
Xiaoyu Wang 已提交
323 324
}

D
dapan1121 已提交
325
static int32_t collectUseDatabase(const SName* pName, SHashObj* pDbs) {
wmmhello's avatar
wmmhello 已提交
326 327 328
  char dbFName[TSDB_DB_FNAME_LEN] = {0};
  tNameGetFullDbName(pName, dbFName);
  return collectUseDatabaseImpl(dbFName, pDbs);
D
dapan1121 已提交
329 330
}

D
dapan1121 已提交
331
static int32_t collectUseTable(const SName* pName, SHashObj* pTable) {
wmmhello's avatar
wmmhello 已提交
332 333
  char fullName[TSDB_TABLE_FNAME_LEN];
  tNameExtractFullName(pName, fullName);
D
dapan1121 已提交
334
  return taosHashPut(pTable, fullName, strlen(fullName), pName, sizeof(SName));
X
Xiaoyu Wang 已提交
335 336 337
}

static int32_t getTableMetaImpl(STranslateContext* pCxt, const SName* pName, STableMeta** pMeta) {
wmmhello's avatar
wmmhello 已提交
338
  SParseContext* pParCxt = pCxt->pParseCxt;
D
dapan1121 已提交
339 340 341 342 343 344 345 346
  int32_t        code = collectUseDatabase(pName, pCxt->pDbs);
  if (TSDB_CODE_SUCCESS == code) {
    code = collectUseTable(pName, pCxt->pTables);
  }
  if (TSDB_CODE_SUCCESS == code) {
    if (pParCxt->async) {
      code = getTableMetaFromCache(pCxt->pMetaCache, pName, pMeta);
    } else {
X
Xiaoyu Wang 已提交
347
      SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
D
dapan1121 已提交
348 349 350 351
                               .requestId = pParCxt->requestId,
                               .requestObjRefId = pParCxt->requestRid,
                               .mgmtEps = pParCxt->mgmtEpSet};
      code = catalogGetTableMeta(pParCxt->pCatalog, &conn, pName, pMeta);
352
    }
wmmhello's avatar
wmmhello 已提交
353 354
  }
  if (TSDB_CODE_SUCCESS != code) {
355 356
    parserError("0x%" PRIx64 " catalogGetTableMeta error, code:%s, dbName:%s, tbName:%s", pCxt->pParseCxt->requestId,
                tstrerror(code), pName->dbname, pName->tname);
wmmhello's avatar
wmmhello 已提交
357 358
  }
  return code;
X
Xiaoyu Wang 已提交
359 360
}

X
Xiaoyu Wang 已提交
361
static int32_t getTableMeta(STranslateContext* pCxt, const char* pDbName, const char* pTableName, STableMeta** pMeta) {
wmmhello's avatar
wmmhello 已提交
362 363
  SName name;
  return getTableMetaImpl(pCxt, toName(pCxt->pParseCxt->acctId, pDbName, pTableName, &name), pMeta);
X
Xiaoyu Wang 已提交
364 365
}

D
dapan1121 已提交
366 367 368 369 370 371 372 373 374 375 376 377 378 379
static int32_t getTableCfg(STranslateContext* pCxt, const SName* pName, STableCfg** pCfg) {
  SParseContext* pParCxt = pCxt->pParseCxt;
  int32_t        code = collectUseDatabase(pName, pCxt->pDbs);
  if (TSDB_CODE_SUCCESS == code) {
    code = collectUseTable(pName, pCxt->pTables);
  }
  if (TSDB_CODE_SUCCESS == code) {
    if (pParCxt->async) {
      code = getTableCfgFromCache(pCxt->pMetaCache, pName, pCfg);
    } else {
      SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
                               .requestId = pParCxt->requestId,
                               .requestObjRefId = pParCxt->requestRid,
                               .mgmtEps = pParCxt->mgmtEpSet};
D
dapan1121 已提交
380
      code = catalogRefreshGetTableCfg(pParCxt->pCatalog, &conn, pName, pCfg);
D
dapan1121 已提交
381 382 383
    }
  }
  if (TSDB_CODE_SUCCESS != code) {
384 385
    parserError("0x%" PRIx64 " catalogRefreshGetTableCfg error, code:%s, dbName:%s, tbName:%s",
                pCxt->pParseCxt->requestId, tstrerror(code), pName->dbname, pName->tname);
D
dapan1121 已提交
386 387 388 389
  }
  return code;
}

390
static int32_t refreshGetTableMeta(STranslateContext* pCxt, const char* pDbName, const char* pTableName,
wmmhello's avatar
wmmhello 已提交
391 392 393 394
                                   STableMeta** pMeta) {
  SParseContext* pParCxt = pCxt->pParseCxt;
  SName          name;
  toName(pCxt->pParseCxt->acctId, pDbName, pTableName, &name);
395 396 397 398
  int32_t code = TSDB_CODE_SUCCESS;
  if (pParCxt->async) {
    code = getTableMetaFromCache(pCxt->pMetaCache, &name, pMeta);
  } else {
X
Xiaoyu Wang 已提交
399
    SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
D
dapan1121 已提交
400 401 402
                             .requestId = pParCxt->requestId,
                             .requestObjRefId = pParCxt->requestRid,
                             .mgmtEps = pParCxt->mgmtEpSet};
X
Xiaoyu Wang 已提交
403 404

    code = catalogRefreshGetTableMeta(pParCxt->pCatalog, &conn, &name, pMeta, false);
405
  }
wmmhello's avatar
wmmhello 已提交
406
  if (TSDB_CODE_SUCCESS != code) {
407 408
    parserError("0x%" PRIx64 " catalogRefreshGetTableMeta error, code:%s, dbName:%s, tbName:%s",
                pCxt->pParseCxt->requestId, tstrerror(code), pDbName, pTableName);
wmmhello's avatar
wmmhello 已提交
409 410
  }
  return code;
411 412
}

X
Xiaoyu Wang 已提交
413
static int32_t getDBVgInfoImpl(STranslateContext* pCxt, const SName* pName, SArray** pVgInfo) {
wmmhello's avatar
wmmhello 已提交
414 415 416
  SParseContext* pParCxt = pCxt->pParseCxt;
  char           fullDbName[TSDB_DB_FNAME_LEN];
  tNameGetFullDbName(pName, fullDbName);
D
dapan1121 已提交
417 418 419 420 421
  int32_t code = collectUseDatabaseImpl(fullDbName, pCxt->pDbs);
  if (TSDB_CODE_SUCCESS == code) {
    if (pParCxt->async) {
      code = getDbVgInfoFromCache(pCxt->pMetaCache, fullDbName, pVgInfo);
    } else {
X
Xiaoyu Wang 已提交
422
      SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
D
dapan1121 已提交
423 424 425
                               .requestId = pParCxt->requestId,
                               .requestObjRefId = pParCxt->requestRid,
                               .mgmtEps = pParCxt->mgmtEpSet};
426
      code = catalogGetDBVgList(pParCxt->pCatalog, &conn, fullDbName, pVgInfo);
427
    }
wmmhello's avatar
wmmhello 已提交
428 429
  }
  if (TSDB_CODE_SUCCESS != code) {
430
    parserError("0x%" PRIx64 " catalogGetDBVgList error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId,
431
                tstrerror(code), fullDbName);
wmmhello's avatar
wmmhello 已提交
432 433
  }
  return code;
X
Xiaoyu Wang 已提交
434 435
}

X
Xiaoyu Wang 已提交
436
static int32_t getDBVgInfo(STranslateContext* pCxt, const char* pDbName, SArray** pVgInfo) {
wmmhello's avatar
wmmhello 已提交
437 438 439 440 441
  SName name;
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pDbName, strlen(pDbName));
  char dbFname[TSDB_DB_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, dbFname);
  return getDBVgInfoImpl(pCxt, &name, pVgInfo);
X
Xiaoyu Wang 已提交
442 443
}

X
Xiaoyu Wang 已提交
444
static int32_t getTableHashVgroupImpl(STranslateContext* pCxt, const SName* pName, SVgroupInfo* pInfo) {
wmmhello's avatar
wmmhello 已提交
445
  SParseContext* pParCxt = pCxt->pParseCxt;
D
dapan1121 已提交
446 447 448 449 450 451 452 453
  int32_t        code = collectUseDatabase(pName, pCxt->pDbs);
  if (TSDB_CODE_SUCCESS == code) {
    code = collectUseTable(pName, pCxt->pTables);
  }
  if (TSDB_CODE_SUCCESS == code) {
    if (pParCxt->async) {
      code = getTableVgroupFromCache(pCxt->pMetaCache, pName, pInfo);
    } else {
X
Xiaoyu Wang 已提交
454
      SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
D
dapan1121 已提交
455 456 457 458
                               .requestId = pParCxt->requestId,
                               .requestObjRefId = pParCxt->requestRid,
                               .mgmtEps = pParCxt->mgmtEpSet};
      code = catalogGetTableHashVgroup(pParCxt->pCatalog, &conn, pName, pInfo);
459
    }
wmmhello's avatar
wmmhello 已提交
460 461
  }
  if (TSDB_CODE_SUCCESS != code) {
462 463
    parserError("0x%" PRIx64 " catalogGetTableHashVgroup error, code:%s, dbName:%s, tbName:%s",
                pCxt->pParseCxt->requestId, tstrerror(code), pName->dbname, pName->tname);
wmmhello's avatar
wmmhello 已提交
464 465
  }
  return code;
X
Xiaoyu Wang 已提交
466 467
}

dengyihao's avatar
dengyihao 已提交
468
static int32_t getTableHashVgroup(STranslateContext* pCxt, const char* pDbName, const char* pTableName,
wmmhello's avatar
wmmhello 已提交
469 470 471
                                  SVgroupInfo* pInfo) {
  SName name;
  return getTableHashVgroupImpl(pCxt, toName(pCxt->pParseCxt->acctId, pDbName, pTableName, &name), pInfo);
X
Xiaoyu Wang 已提交
472 473
}

dengyihao's avatar
dengyihao 已提交
474
static int32_t getDBVgVersion(STranslateContext* pCxt, const char* pDbFName, int32_t* pVersion, int64_t* pDbId,
D
dapan1121 已提交
475
                              int32_t* pTableNum, int64_t* pStateTs) {
wmmhello's avatar
wmmhello 已提交
476
  SParseContext* pParCxt = pCxt->pParseCxt;
D
dapan1121 已提交
477 478 479
  int32_t        code = collectUseDatabaseImpl(pDbFName, pCxt->pDbs);
  if (TSDB_CODE_SUCCESS == code) {
    if (pParCxt->async) {
D
dapan1121 已提交
480
      code = getDbVgVersionFromCache(pCxt->pMetaCache, pDbFName, pVersion, pDbId, pTableNum, pStateTs);
D
dapan1121 已提交
481
    } else {
D
dapan1121 已提交
482
      code = catalogGetDBVgVersion(pParCxt->pCatalog, pDbFName, pVersion, pDbId, pTableNum, pStateTs);
483
    }
wmmhello's avatar
wmmhello 已提交
484 485
  }
  if (TSDB_CODE_SUCCESS != code) {
486 487
    parserError("0x%" PRIx64 " catalogGetDBVgVersion error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId,
                tstrerror(code), pDbFName);
wmmhello's avatar
wmmhello 已提交
488 489
  }
  return code;
X
Xiaoyu Wang 已提交
490 491
}

492
static int32_t getDBCfg(STranslateContext* pCxt, const char* pDbName, SDbCfgInfo* pInfo) {
wmmhello's avatar
wmmhello 已提交
493 494 495 496 497
  SParseContext* pParCxt = pCxt->pParseCxt;
  SName          name;
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pDbName, strlen(pDbName));
  char dbFname[TSDB_DB_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, dbFname);
D
dapan1121 已提交
498 499 500 501 502
  int32_t code = collectUseDatabaseImpl(dbFname, pCxt->pDbs);
  if (TSDB_CODE_SUCCESS == code) {
    if (pParCxt->async) {
      code = getDbCfgFromCache(pCxt->pMetaCache, dbFname, pInfo);
    } else {
X
Xiaoyu Wang 已提交
503
      SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
D
dapan1121 已提交
504 505 506 507 508
                               .requestId = pParCxt->requestId,
                               .requestObjRefId = pParCxt->requestRid,
                               .mgmtEps = pParCxt->mgmtEpSet};

      code = catalogGetDBCfg(pParCxt->pCatalog, &conn, dbFname, pInfo);
509
    }
wmmhello's avatar
wmmhello 已提交
510 511
  }
  if (TSDB_CODE_SUCCESS != code) {
512 513
    parserError("0x%" PRIx64 " catalogGetDBCfg error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId, tstrerror(code),
                dbFname);
wmmhello's avatar
wmmhello 已提交
514 515
  }
  return code;
516 517
}

518 519 520 521 522 523 524
static int32_t getUdfInfo(STranslateContext* pCxt, SFunctionNode* pFunc) {
  SParseContext* pParCxt = pCxt->pParseCxt;
  SFuncInfo      funcInfo = {0};
  int32_t        code = TSDB_CODE_SUCCESS;
  if (pParCxt->async) {
    code = getUdfInfoFromCache(pCxt->pMetaCache, pFunc->functionName, &funcInfo);
  } else {
X
Xiaoyu Wang 已提交
525
    SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
D
dapan1121 已提交
526 527 528 529
                             .requestId = pParCxt->requestId,
                             .requestObjRefId = pParCxt->requestRid,
                             .mgmtEps = pParCxt->mgmtEpSet};

X
Xiaoyu Wang 已提交
530
    code = catalogGetUdfInfo(pParCxt->pCatalog, &conn, pFunc->functionName, &funcInfo);
531 532 533 534 535 536 537 538 539
  }
  if (TSDB_CODE_SUCCESS == code) {
    pFunc->funcType = FUNCTION_TYPE_UDF;
    pFunc->funcId = TSDB_FUNC_TYPE_AGGREGATE == funcInfo.funcType ? FUNC_AGGREGATE_UDF_ID : FUNC_SCALAR_UDF_ID;
    pFunc->node.resType.type = funcInfo.outputType;
    pFunc->node.resType.bytes = funcInfo.outputLen;
    pFunc->udfBufSize = funcInfo.bufSize;
    tFreeSFuncInfo(&funcInfo);
  }
540 541 542 543
  if (TSDB_CODE_SUCCESS != code) {
    parserError("0x%" PRIx64 " catalogGetUdfInfo error, code:%s, funcName:%s", pCxt->pParseCxt->requestId,
                tstrerror(code), pFunc->functionName);
  }
544 545 546
  return code;
}

X
Xiaoyu Wang 已提交
547
static int32_t getTableIndex(STranslateContext* pCxt, const SName* pName, SArray** pIndexes) {
X
Xiaoyu Wang 已提交
548
  SParseContext* pParCxt = pCxt->pParseCxt;
X
Xiaoyu Wang 已提交
549 550 551 552
  int32_t        code = collectUseDatabase(pName, pCxt->pDbs);
  if (TSDB_CODE_SUCCESS == code) {
    code = collectUseTable(pName, pCxt->pTables);
  }
X
Xiaoyu Wang 已提交
553 554 555 556 557 558 559 560
  if (TSDB_CODE_SUCCESS == code) {
    if (pParCxt->async) {
      code = getTableIndexFromCache(pCxt->pMetaCache, pName, pIndexes);
    } else {
      SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
                               .requestId = pParCxt->requestId,
                               .requestObjRefId = pParCxt->requestRid,
                               .mgmtEps = pParCxt->mgmtEpSet};
X
Xiaoyu Wang 已提交
561

X
Xiaoyu Wang 已提交
562 563
      code = catalogGetTableIndex(pParCxt->pCatalog, &conn, pName, pIndexes);
    }
X
Xiaoyu Wang 已提交
564 565
  }
  if (TSDB_CODE_SUCCESS != code) {
566 567
    parserError("0x%" PRIx64 " getTableIndex error, code:%s, dbName:%s, tbName:%s", pCxt->pParseCxt->requestId,
                tstrerror(code), pName->dbname, pName->tname);
X
Xiaoyu Wang 已提交
568 569 570 571
  }
  return code;
}

572 573 574 575 576 577 578 579 580 581 582 583 584
static int32_t getDnodeList(STranslateContext* pCxt, SArray** pDnodes) {
  SParseContext* pParCxt = pCxt->pParseCxt;
  int32_t        code = TSDB_CODE_SUCCESS;
  if (pParCxt->async) {
    code = getDnodeListFromCache(pCxt->pMetaCache, pDnodes);
  } else {
    SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter,
                             .requestId = pParCxt->requestId,
                             .requestObjRefId = pParCxt->requestRid,
                             .mgmtEps = pParCxt->mgmtEpSet};
    code = catalogGetDnodeList(pParCxt->pCatalog, &conn, pDnodes);
  }
  if (TSDB_CODE_SUCCESS != code) {
585
    parserError("0x%" PRIx64 " getDnodeList error, code:%s", pCxt->pParseCxt->requestId, tstrerror(code));
586 587 588 589
  }
  return code;
}

590
static int32_t initTranslateContext(SParseContext* pParseCxt, SParseMetaCache* pMetaCache, STranslateContext* pCxt) {
wmmhello's avatar
wmmhello 已提交
591 592 593 594 595 596
  pCxt->pParseCxt = pParseCxt;
  pCxt->errCode = TSDB_CODE_SUCCESS;
  pCxt->msgBuf.buf = pParseCxt->pMsg;
  pCxt->msgBuf.len = pParseCxt->msgLen;
  pCxt->pNsLevel = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
  pCxt->currLevel = 0;
597
  pCxt->levelNo = 0;
wmmhello's avatar
wmmhello 已提交
598
  pCxt->currClause = 0;
599
  pCxt->pMetaCache = pMetaCache;
wmmhello's avatar
wmmhello 已提交
600 601
  pCxt->pDbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
  pCxt->pTables = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
D
dapan1121 已提交
602 603
  pCxt->pTargetTables = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
  if (NULL == pCxt->pNsLevel || NULL == pCxt->pDbs || NULL == pCxt->pTables || NULL == pCxt->pTargetTables) {
wmmhello's avatar
wmmhello 已提交
604 605 606
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  return TSDB_CODE_SUCCESS;
607 608
}

X
Xiaoyu Wang 已提交
609
static int32_t resetTranslateNamespace(STranslateContext* pCxt) {
wmmhello's avatar
wmmhello 已提交
610 611 612 613 614 615 616 617 618 619 620 621
  if (NULL != pCxt->pNsLevel) {
    size_t size = taosArrayGetSize(pCxt->pNsLevel);
    for (size_t i = 0; i < size; ++i) {
      taosArrayDestroy(taosArrayGetP(pCxt->pNsLevel, i));
    }
    taosArrayDestroy(pCxt->pNsLevel);
  }
  pCxt->pNsLevel = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
  if (NULL == pCxt->pNsLevel) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
622 623
}

624
static void destroyTranslateContext(STranslateContext* pCxt) {
wmmhello's avatar
wmmhello 已提交
625 626 627 628 629 630 631
  if (NULL != pCxt->pNsLevel) {
    size_t size = taosArrayGetSize(pCxt->pNsLevel);
    for (size_t i = 0; i < size; ++i) {
      taosArrayDestroy(taosArrayGetP(pCxt->pNsLevel, i));
    }
    taosArrayDestroy(pCxt->pNsLevel);
  }
632

wmmhello's avatar
wmmhello 已提交
633 634 635 636
  if (NULL != pCxt->pCmdMsg) {
    taosMemoryFreeClear(pCxt->pCmdMsg->pMsg);
    taosMemoryFreeClear(pCxt->pCmdMsg);
  }
637

wmmhello's avatar
wmmhello 已提交
638 639
  taosHashCleanup(pCxt->pDbs);
  taosHashCleanup(pCxt->pTables);
D
dapan1121 已提交
640
  taosHashCleanup(pCxt->pTargetTables);
641 642
}

643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
static bool isSelectStmt(SNode* pCurrStmt) {
  return NULL != pCurrStmt && QUERY_NODE_SELECT_STMT == nodeType(pCurrStmt);
}

static bool isSetOperator(SNode* pCurrStmt) {
  return NULL != pCurrStmt && QUERY_NODE_SET_OPERATOR == nodeType(pCurrStmt);
}

static SNodeList* getProjectListFromCurrStmt(SNode* pCurrStmt) {
  if (isSelectStmt(pCurrStmt)) {
    return ((SSelectStmt*)pCurrStmt)->pProjectionList;
  }
  if (isSetOperator(pCurrStmt)) {
    return ((SSetOperator*)pCurrStmt)->pProjectionList;
  }
  return NULL;
}

static uint8_t getPrecisionFromCurrStmt(SNode* pCurrStmt, uint8_t defaultVal) {
  if (isSelectStmt(pCurrStmt)) {
    return ((SSelectStmt*)pCurrStmt)->precision;
  }
  if (isSetOperator(pCurrStmt)) {
    return ((SSetOperator*)pCurrStmt)->precision;
  }
  return defaultVal;
}

671
static bool isAliasColumn(const SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
672
  return (QUERY_NODE_COLUMN == nodeType(pNode) && ('\0' == ((SColumnNode*)pNode)->tableAlias[0]));
673 674 675
}

static bool isAggFunc(const SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
676
  return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId));
677 678 679
}

static bool isSelectFunc(const SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
680
  return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsSelectFunc(((SFunctionNode*)pNode)->funcId));
681 682
}

5
54liuyao 已提交
683 684 685 686
static bool isWindowPseudoColumnFunc(const SNode* pNode) {
  return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsWindowPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
}

687
static bool isTimelineFunc(const SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
688
  return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId));
689 690
}

691 692 693 694
static bool isImplicitTsFunc(const SNode* pNode) {
  return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsImplicitTsFunc(((SFunctionNode*)pNode)->funcId));
}

695
static bool isScanPseudoColumnFunc(const SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
696
  return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsScanPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
697 698
}

wmmhello's avatar
wmmhello 已提交
699 700
static bool isIndefiniteRowsFunc(const SNode* pNode) {
  return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsIndefiniteRowsFunc(((SFunctionNode*)pNode)->funcId));
701 702
}

X
Xiaoyu Wang 已提交
703 704 705 706
static bool isVectorFunc(const SNode* pNode) {
  return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsVectorFunc(((SFunctionNode*)pNode)->funcId));
}

707
static bool isDistinctOrderBy(STranslateContext* pCxt) {
708 709
  return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && isSelectStmt(pCxt->pCurrStmt) &&
          ((SSelectStmt*)pCxt->pCurrStmt)->isDistinct);
710 711
}

712
static bool belongTable(const SColumnNode* pCol, const STableNode* pTable) {
wmmhello's avatar
wmmhello 已提交
713 714 715 716 717 718 719 720
  int cmp = 0;
  if ('\0' != pCol->dbName[0]) {
    cmp = strcmp(pCol->dbName, pTable->dbName);
  }
  if (0 == cmp) {
    cmp = strcmp(pCol->tableAlias, pTable->tableAlias);
  }
  return (0 == cmp);
721 722
}

X
Xiaoyu Wang 已提交
723
static SNodeList* getProjectList(const SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
724 725 726 727 728 729
  if (QUERY_NODE_SELECT_STMT == nodeType(pNode)) {
    return ((SSelectStmt*)pNode)->pProjectionList;
  } else if (QUERY_NODE_SET_OPERATOR == nodeType(pNode)) {
    return ((SSetOperator*)pNode)->pProjectionList;
  }
  return NULL;
730 731
}

732 733 734 735 736 737 738 739
static bool isTimeLineQuery(SNode* pStmt) {
  if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
    return ((SSelectStmt*)pStmt)->isTimeLineResult;
  } else {
    return false;
  }
}

X
Xiaoyu Wang 已提交
740 741 742 743 744 745 746 747
static bool isGlobalTimeLineQuery(SNode* pStmt) {
  if (!isTimeLineQuery(pStmt)) {
    return false;
  }
  SSelectStmt* pSelect = (SSelectStmt*)pStmt;
  return NULL == pSelect->pPartitionByList || NULL != pSelect->pOrderByList;
}

748 749 750 751 752
static bool isPrimaryKeyImpl(SNode* pExpr) {
  if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
    return (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId);
  } else if (QUERY_NODE_FUNCTION == nodeType(pExpr)) {
    SFunctionNode* pFunc = (SFunctionNode*)pExpr;
753 754
    if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType || FUNCTION_TYPE_GROUP_KEY == pFunc->funcType ||
        FUNCTION_TYPE_FIRST == pFunc->funcType || FUNCTION_TYPE_LAST == pFunc->funcType) {
755
      return isPrimaryKeyImpl(nodesListGetNode(pFunc->pParameterList, 0));
756
    } else if (FUNCTION_TYPE_WSTART == pFunc->funcType || FUNCTION_TYPE_WEND == pFunc->funcType) {
757 758 759 760 761 762 763 764 765 766 767 768 769
      return true;
    }
  }
  return false;
}

static bool isPrimaryKey(STempTableNode* pTable, SNode* pExpr) {
  if (!isTimeLineQuery(pTable->pSubquery)) {
    return false;
  }
  return isPrimaryKeyImpl(pExpr);
}

X
Xiaoyu Wang 已提交
770
static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, int32_t tagFlag,
wmmhello's avatar
wmmhello 已提交
771 772 773 774 775 776 777 778
                                  SColumnNode* pCol) {
  strcpy(pCol->dbName, pTable->table.dbName);
  strcpy(pCol->tableAlias, pTable->table.tableAlias);
  strcpy(pCol->tableName, pTable->table.tableName);
  strcpy(pCol->colName, pColSchema->name);
  if ('\0' == pCol->node.aliasName[0]) {
    strcpy(pCol->node.aliasName, pColSchema->name);
  }
X
Xiaoyu Wang 已提交
779 780 781
  if ('\0' == pCol->node.userAlias[0]) {
    strcpy(pCol->node.userAlias, pColSchema->name);
  }
wmmhello's avatar
wmmhello 已提交
782 783 784
  pCol->tableId = pTable->pMeta->uid;
  pCol->tableType = pTable->pMeta->tableType;
  pCol->colId = pColSchema->colId;
X
Xiaoyu Wang 已提交
785 786
  pCol->colType = (tagFlag >= 0 ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN);
  pCol->hasIndex = (0 == tagFlag);
wmmhello's avatar
wmmhello 已提交
787 788 789 790 791
  pCol->node.resType.type = pColSchema->type;
  pCol->node.resType.bytes = pColSchema->bytes;
  if (TSDB_DATA_TYPE_TIMESTAMP == pCol->node.resType.type) {
    pCol->node.resType.precision = pTable->pMeta->tableInfo.precision;
  }
792 793
}

794
static void setColumnInfoByExpr(STempTableNode* pTable, SExprNode* pExpr, SColumnNode** pColRef) {
X
Xiaoyu Wang 已提交
795 796
  SColumnNode* pCol = *pColRef;

wmmhello's avatar
wmmhello 已提交
797 798 799
  if (NULL == pExpr->pAssociation) {
    pExpr->pAssociation = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
  }
X
Xiaoyu Wang 已提交
800
  taosArrayPush(pExpr->pAssociation, &pColRef);
801 802
  strcpy(pCol->tableAlias, pTable->table.tableAlias);
  pCol->colId = isPrimaryKey(pTable, (SNode*)pExpr) ? PRIMARYKEY_TIMESTAMP_COL_ID : 0;
wmmhello's avatar
wmmhello 已提交
803 804 805 806
  strcpy(pCol->colName, pExpr->aliasName);
  if ('\0' == pCol->node.aliasName[0]) {
    strcpy(pCol->node.aliasName, pCol->colName);
  }
X
Xiaoyu Wang 已提交
807 808 809
  if ('\0' == pCol->node.userAlias[0]) {
    strcpy(pCol->node.userAlias, pCol->colName);
  }
wmmhello's avatar
wmmhello 已提交
810
  pCol->node.resType = pExpr->resType;
811 812
}

813
static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* pTable, bool igTags, SNodeList* pList) {
wmmhello's avatar
wmmhello 已提交
814 815
  if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
    const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
816 817
    int32_t           nums = pMeta->tableInfo.numOfColumns +
                   (igTags ? 0 : ((TSDB_SUPER_TABLE == pMeta->tableType) ? pMeta->tableInfo.numOfTags : 0));
wmmhello's avatar
wmmhello 已提交
818
    for (int32_t i = 0; i < nums; ++i) {
819 820 821
      if (invisibleColumn(pCxt->pParseCxt->enableSysInfo, pMeta->tableType, pMeta->schema[i].flags)) {
        continue;
      }
wmmhello's avatar
wmmhello 已提交
822 823 824 825
      SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
      if (NULL == pCol) {
        return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
      }
X
Xiaoyu Wang 已提交
826
      setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i - pMeta->tableInfo.numOfColumns), pCol);
wmmhello's avatar
wmmhello 已提交
827 828 829
      nodesListAppend(pList, (SNode*)pCol);
    }
  } else {
830 831 832
    STempTableNode* pTempTable = (STempTableNode*)pTable;
    SNodeList*      pProjectList = getProjectList(pTempTable->pSubquery);
    SNode*          pNode;
wmmhello's avatar
wmmhello 已提交
833 834 835 836 837 838
    FOREACH(pNode, pProjectList) {
      SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
      if (NULL == pCol) {
        return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
      }
      nodesListAppend(pList, (SNode*)pCol);
X
Xiaoyu Wang 已提交
839
      SListCell* pCell = nodesListGetCell(pList, LIST_LENGTH(pList) - 1);
840
      setColumnInfoByExpr(pTempTable, (SExprNode*)pNode, (SColumnNode**)&pCell->pNode);
wmmhello's avatar
wmmhello 已提交
841 842 843
    }
  }
  return TSDB_CODE_SUCCESS;
844 845
}

X
Xiaoyu Wang 已提交
846
static bool isInternalPrimaryKey(const SColumnNode* pCol) {
847 848
  return PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId &&
         (0 == strcmp(pCol->colName, ROWTS_PSEUDO_COLUMN_NAME) || 0 == strcmp(pCol->colName, C0_PSEUDO_COLUMN_NAME));
X
Xiaoyu Wang 已提交
849 850
}

851 852
static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef, const STableNode* pTable,
                                bool* pFound) {
X
Xiaoyu Wang 已提交
853
  SColumnNode* pCol = *pColRef;
854
  *pFound = false;
wmmhello's avatar
wmmhello 已提交
855 856 857
  if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
    const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
    if (isInternalPrimaryKey(pCol)) {
X
Xiaoyu Wang 已提交
858
      setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema, -1, pCol);
859 860
      *pFound = true;
      return TSDB_CODE_SUCCESS;
wmmhello's avatar
wmmhello 已提交
861 862 863
    }
    int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
    for (int32_t i = 0; i < nums; ++i) {
864 865
      if (0 == strcmp(pCol->colName, pMeta->schema[i].name) &&
          !invisibleColumn(pCxt->pParseCxt->enableSysInfo, pMeta->tableType, pMeta->schema[i].flags)) {
X
Xiaoyu Wang 已提交
866
        setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i - pMeta->tableInfo.numOfColumns), pCol);
867
        *pFound = true;
wmmhello's avatar
wmmhello 已提交
868 869 870 871
        break;
      }
    }
  } else {
872 873 874
    STempTableNode* pTempTable = (STempTableNode*)pTable;
    SNodeList*      pProjectList = getProjectList(pTempTable->pSubquery);
    SNode*          pNode;
wmmhello's avatar
wmmhello 已提交
875 876
    FOREACH(pNode, pProjectList) {
      SExprNode* pExpr = (SExprNode*)pNode;
X
Xiaoyu Wang 已提交
877
      if (0 == strcmp(pCol->colName, pExpr->aliasName)) {
878 879 880
        if (*pFound) {
          return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AMBIGUOUS_COLUMN, pCol->colName);
        }
881
        setColumnInfoByExpr(pTempTable, pExpr, pColRef);
882
        *pFound = true;
883 884
      } else if (isPrimaryKey(pTempTable, pNode) && isInternalPrimaryKey(pCol)) {
        setColumnInfoByExpr(pTempTable, pExpr, pColRef);
X
Xiaoyu Wang 已提交
885
        *pFound = true;
wmmhello's avatar
wmmhello 已提交
886 887 888
      }
    }
  }
889
  return TSDB_CODE_SUCCESS;
890 891
}

X
Xiaoyu Wang 已提交
892
static EDealRes translateColumnWithPrefix(STranslateContext* pCxt, SColumnNode** pCol) {
wmmhello's avatar
wmmhello 已提交
893 894 895 896 897
  SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
  size_t  nums = taosArrayGetSize(pTables);
  bool    foundTable = false;
  for (size_t i = 0; i < nums; ++i) {
    STableNode* pTable = taosArrayGetP(pTables, i);
898
    if (belongTable((*pCol), pTable)) {
wmmhello's avatar
wmmhello 已提交
899
      foundTable = true;
900 901 902 903 904 905
      bool foundCol = false;
      pCxt->errCode = findAndSetColumn(pCxt, pCol, pTable, &foundCol);
      if (TSDB_CODE_SUCCESS != pCxt->errCode) {
        return DEAL_RES_ERROR;
      }
      if (foundCol) {
wmmhello's avatar
wmmhello 已提交
906 907
        break;
      }
X
Xiaoyu Wang 已提交
908
      return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, (*pCol)->colName);
wmmhello's avatar
wmmhello 已提交
909 910 911
    }
  }
  if (!foundTable) {
X
Xiaoyu Wang 已提交
912
    return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_TABLE_NOT_EXIST, (*pCol)->tableAlias);
wmmhello's avatar
wmmhello 已提交
913 914
  }
  return DEAL_RES_CONTINUE;
915
}
916

X
Xiaoyu Wang 已提交
917
static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNode** pCol) {
wmmhello's avatar
wmmhello 已提交
918 919 920
  SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
  size_t  nums = taosArrayGetSize(pTables);
  bool    found = false;
X
Xiaoyu Wang 已提交
921
  bool    isInternalPk = isInternalPrimaryKey(*pCol);
wmmhello's avatar
wmmhello 已提交
922 923
  for (size_t i = 0; i < nums; ++i) {
    STableNode* pTable = taosArrayGetP(pTables, i);
924 925 926 927 928 929
    bool        foundCol = false;
    pCxt->errCode = findAndSetColumn(pCxt, pCol, pTable, &foundCol);
    if (TSDB_CODE_SUCCESS != pCxt->errCode) {
      return DEAL_RES_ERROR;
    }
    if (foundCol) {
wmmhello's avatar
wmmhello 已提交
930
      if (found) {
X
Xiaoyu Wang 已提交
931
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_AMBIGUOUS_COLUMN, (*pCol)->colName);
wmmhello's avatar
wmmhello 已提交
932 933
      }
      found = true;
934 935 936
    }
    if (isInternalPk) {
      break;
wmmhello's avatar
wmmhello 已提交
937 938 939 940
    }
  }
  if (!found) {
    if (isInternalPk) {
941
      if (isSelectStmt(pCxt->pCurrStmt) && NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pWindow) {
wmmhello's avatar
wmmhello 已提交
942 943 944 945
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY);
      }
      return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_INTERNAL_PK);
    } else {
X
Xiaoyu Wang 已提交
946
      return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, (*pCol)->colName);
wmmhello's avatar
wmmhello 已提交
947 948 949
    }
  }
  return DEAL_RES_CONTINUE;
950 951
}

952
static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** pCol, bool* pFound) {
953
  SNodeList* pProjectionList = getProjectListFromCurrStmt(pCxt->pCurrStmt);
wmmhello's avatar
wmmhello 已提交
954 955 956
  SNode*     pNode;
  FOREACH(pNode, pProjectionList) {
    SExprNode* pExpr = (SExprNode*)pNode;
X
Xiaoyu Wang 已提交
957
    if (0 == strcmp((*pCol)->colName, pExpr->userAlias)) {
958 959 960 961 962 963 964 965 966 967
      SColumnRefNode* pColRef = (SColumnRefNode*)nodesMakeNode(QUERY_NODE_COLUMN_REF);
      if (NULL == pColRef) {
        pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
        return DEAL_RES_ERROR;
      }
      strcpy(pColRef->colName, pExpr->aliasName);
      nodesDestroyNode(*(SNode**)pCol);
      *(SNode**)pCol = (SNode*)pColRef;
      *pFound = true;
      return DEAL_RES_CONTINUE;
wmmhello's avatar
wmmhello 已提交
968 969
    }
  }
970 971
  *pFound = false;
  return DEAL_RES_CONTINUE;
972 973
}

X
Xiaoyu Wang 已提交
974
static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) {
975
  if (NULL == pCxt->pCurrStmt || isSelectStmt(pCxt->pCurrStmt) && NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) {
976 977 978
    return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, (*pCol)->colName);
  }

wmmhello's avatar
wmmhello 已提交
979
  // count(*)/first(*)/last(*) and so on
X
Xiaoyu Wang 已提交
980
  if (0 == strcmp((*pCol)->colName, "*")) {
wmmhello's avatar
wmmhello 已提交
981 982 983 984
    return DEAL_RES_CONTINUE;
  }

  EDealRes res = DEAL_RES_CONTINUE;
X
Xiaoyu Wang 已提交
985
  if ('\0' != (*pCol)->tableAlias[0]) {
wmmhello's avatar
wmmhello 已提交
986 987 988 989
    res = translateColumnWithPrefix(pCxt, pCol);
  } else {
    bool found = false;
    if (SQL_CLAUSE_ORDER_BY == pCxt->currClause) {
990 991 992
      res = translateColumnUseAlias(pCxt, pCol, &found);
    }
    if (DEAL_RES_ERROR != res && !found) {
993
      if (isSetOperator(pCxt->pCurrStmt)) {
994 995 996 997
        res = generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, (*pCol)->colName);
      } else {
        res = translateColumnWithoutPrefix(pCxt, pCol);
      }
wmmhello's avatar
wmmhello 已提交
998 999 1000
    }
  }
  return res;
1001 1002
}

X
Xiaoyu Wang 已提交
1003 1004 1005 1006 1007
static int32_t parseTimeFromValueNode(STranslateContext* pCxt, SValueNode* pVal) {
  if (IS_NUMERIC_TYPE(pVal->node.resType.type) || TSDB_DATA_TYPE_BOOL == pVal->node.resType.type) {
    if (DEAL_RES_ERROR == translateValue(pCxt, pVal)) {
      return pCxt->errCode;
    }
X
Xiaoyu Wang 已提交
1008
    int64_t value = 0;
X
Xiaoyu Wang 已提交
1009
    if (IS_UNSIGNED_NUMERIC_TYPE(pVal->node.resType.type)) {
X
Xiaoyu Wang 已提交
1010
      value = pVal->datum.u;
X
Xiaoyu Wang 已提交
1011
    } else if (IS_FLOAT_TYPE(pVal->node.resType.type)) {
X
Xiaoyu Wang 已提交
1012
      value = pVal->datum.d;
X
Xiaoyu Wang 已提交
1013
    } else if (TSDB_DATA_TYPE_BOOL == pVal->node.resType.type) {
X
Xiaoyu Wang 已提交
1014 1015 1016
      value = pVal->datum.b;
    } else {
      value = pVal->datum.i;
X
Xiaoyu Wang 已提交
1017
    }
X
Xiaoyu Wang 已提交
1018
    pVal->datum.i = value;
wmmhello's avatar
wmmhello 已提交
1019 1020 1021 1022 1023 1024 1025 1026
    return TSDB_CODE_SUCCESS;
  } else if (IS_VAR_DATA_TYPE(pVal->node.resType.type) || TSDB_DATA_TYPE_TIMESTAMP == pVal->node.resType.type) {
    if (TSDB_CODE_SUCCESS == taosParseTime(pVal->literal, &pVal->datum.i, pVal->node.resType.bytes,
                                           pVal->node.resType.precision, tsDaylight)) {
      return TSDB_CODE_SUCCESS;
    }
    char* pEnd = NULL;
    pVal->datum.i = taosStr2Int64(pVal->literal, &pEnd, 10);
X
Xiaoyu Wang 已提交
1027
    return (NULL != pEnd && '\0' == *pEnd) ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_WRONG_VALUE_TYPE;
wmmhello's avatar
wmmhello 已提交
1028
  } else {
X
Xiaoyu Wang 已提交
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
    return TSDB_CODE_PAR_WRONG_VALUE_TYPE;
  }
}

static int32_t parseBoolFromValueNode(STranslateContext* pCxt, SValueNode* pVal) {
  if (IS_VAR_DATA_TYPE(pVal->node.resType.type) || TSDB_DATA_TYPE_BOOL == pVal->node.resType.type) {
    pVal->datum.b = (0 == strcasecmp(pVal->literal, "true"));
    return TSDB_CODE_SUCCESS;
  } else if (IS_INTEGER_TYPE(pVal->node.resType.type)) {
    pVal->datum.b = (0 != taosStr2Int64(pVal->literal, NULL, 10));
    return TSDB_CODE_SUCCESS;
  } else if (IS_FLOAT_TYPE(pVal->node.resType.type)) {
    pVal->datum.b = (0 != taosStr2Double(pVal->literal, NULL));
    return TSDB_CODE_SUCCESS;
  } else {
    return TSDB_CODE_PAR_WRONG_VALUE_TYPE;
wmmhello's avatar
wmmhello 已提交
1045
  }
1046 1047
}

1048 1049 1050 1051
static EDealRes translateDurationValue(STranslateContext* pCxt, SValueNode* pVal) {
  if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit,
                          pVal->node.resType.precision) != TSDB_CODE_SUCCESS) {
    return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
1052
  }
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
  *(int64_t*)&pVal->typeData = pVal->datum.i;
  return DEAL_RES_CONTINUE;
}

static EDealRes translateNormalValue(STranslateContext* pCxt, SValueNode* pVal, SDataType targetDt, bool strict) {
  int32_t code = TSDB_CODE_SUCCESS;
  switch (targetDt.type) {
    case TSDB_DATA_TYPE_BOOL:
      if (TSDB_CODE_SUCCESS != parseBoolFromValueNode(pCxt, pVal)) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
D
dapan1121 已提交
1063
      }
1064 1065 1066 1067 1068 1069
      *(bool*)&pVal->typeData = pVal->datum.b;
      break;
    case TSDB_DATA_TYPE_TINYINT: {
      code = toInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.i);
      if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_TINYINT(pVal->datum.i))) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
D
dapan1121 已提交
1070
      }
1071 1072 1073 1074 1075 1076 1077
      *(int8_t*)&pVal->typeData = pVal->datum.i;
      break;
    }
    case TSDB_DATA_TYPE_SMALLINT: {
      code = toInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.i);
      if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_SMALLINT(pVal->datum.i))) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
D
dapan1121 已提交
1078
      }
1079 1080 1081 1082 1083 1084 1085
      *(int16_t*)&pVal->typeData = pVal->datum.i;
      break;
    }
    case TSDB_DATA_TYPE_INT: {
      code = toInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.i);
      if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_INT(pVal->datum.i))) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
D
dapan1121 已提交
1086
      }
1087 1088 1089 1090 1091
      *(int32_t*)&pVal->typeData = pVal->datum.i;
      break;
    }
    case TSDB_DATA_TYPE_BIGINT: {
      code = toInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.i);
X
Xiaoyu Wang 已提交
1092
      if (strict && TSDB_CODE_SUCCESS != code) {
1093
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
D
dapan1121 已提交
1094
      }
1095 1096 1097 1098 1099
      *(int64_t*)&pVal->typeData = pVal->datum.i;
      break;
    }
    case TSDB_DATA_TYPE_UTINYINT: {
      code = toUInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.u);
X
Xiaoyu Wang 已提交
1100
      if (strict && (TSDB_CODE_SUCCESS != code || pVal->datum.u > UINT8_MAX)) {
1101
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
D
dapan1121 已提交
1102
      }
1103 1104 1105 1106 1107
      *(uint8_t*)&pVal->typeData = pVal->datum.u;
      break;
    }
    case TSDB_DATA_TYPE_USMALLINT: {
      code = toUInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.u);
X
Xiaoyu Wang 已提交
1108
      if (strict && (TSDB_CODE_SUCCESS != code || pVal->datum.u > UINT16_MAX)) {
1109
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
1110
      }
1111 1112 1113 1114 1115
      *(uint16_t*)&pVal->typeData = pVal->datum.u;
      break;
    }
    case TSDB_DATA_TYPE_UINT: {
      code = toUInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.u);
X
Xiaoyu Wang 已提交
1116
      if (strict && (TSDB_CODE_SUCCESS != code || pVal->datum.u > UINT32_MAX)) {
1117
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
D
dapan1121 已提交
1118
      }
1119 1120 1121 1122 1123
      *(uint32_t*)&pVal->typeData = pVal->datum.u;
      break;
    }
    case TSDB_DATA_TYPE_UBIGINT: {
      code = toUInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.u);
X
Xiaoyu Wang 已提交
1124
      if (strict && TSDB_CODE_SUCCESS != code) {
1125
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
1126
      }
1127 1128 1129 1130 1131
      *(uint64_t*)&pVal->typeData = pVal->datum.u;
      break;
    }
    case TSDB_DATA_TYPE_FLOAT: {
      pVal->datum.d = taosStr2Double(pVal->literal, NULL);
X
Xiaoyu Wang 已提交
1132 1133 1134
      if (strict && !IS_VALID_FLOAT(pVal->datum.d)) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
      }
1135 1136 1137 1138 1139
      *(float*)&pVal->typeData = pVal->datum.d;
      break;
    }
    case TSDB_DATA_TYPE_DOUBLE: {
      pVal->datum.d = taosStr2Double(pVal->literal, NULL);
X
Xiaoyu Wang 已提交
1140 1141 1142 1143
      if (strict && (((pVal->datum.d == HUGE_VAL || pVal->datum.d == -HUGE_VAL) && errno == ERANGE) ||
                     isinf(pVal->datum.d) || isnan(pVal->datum.d))) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
      }
1144 1145 1146 1147 1148
      *(double*)&pVal->typeData = pVal->datum.d;
      break;
    }
    case TSDB_DATA_TYPE_VARCHAR:
    case TSDB_DATA_TYPE_VARBINARY: {
1149
      if (strict && (pVal->node.resType.bytes > targetDt.bytes - VARSTR_HEADER_SIZE)) {
1150 1151
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
      }
1152 1153 1154
      pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1);
      if (NULL == pVal->datum.p) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
1155
      }
1156 1157 1158 1159 1160 1161 1162 1163
      int32_t len = TMIN(targetDt.bytes - VARSTR_HEADER_SIZE, pVal->node.resType.bytes);
      varDataSetLen(pVal->datum.p, len);
      strncpy(varDataVal(pVal->datum.p), pVal->literal, len);
      break;
    }
    case TSDB_DATA_TYPE_TIMESTAMP: {
      if (TSDB_CODE_SUCCESS != parseTimeFromValueNode(pCxt, pVal)) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
1164
      }
1165 1166 1167 1168 1169 1170 1171
      *(int64_t*)&pVal->typeData = pVal->datum.i;
      break;
    }
    case TSDB_DATA_TYPE_NCHAR: {
      pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1);
      if (NULL == pVal->datum.p) {
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
1172
      }
1173

1174 1175 1176
      int32_t len = 0;
      if (!taosMbsToUcs4(pVal->literal, strlen(pVal->literal), (TdUcs4*)varDataVal(pVal->datum.p),
                         targetDt.bytes - VARSTR_HEADER_SIZE, &len)) {
1177
        return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
1178 1179 1180
      }
      varDataSetLen(pVal->datum.p, len);
      break;
1181
    }
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
    case TSDB_DATA_TYPE_DECIMAL:
    case TSDB_DATA_TYPE_BLOB:
      return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
    default:
      break;
  }
  return DEAL_RES_CONTINUE;
}

static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SDataType targetDt, bool strict) {
  if (pVal->placeholderNo > 0 || pVal->isNull) {
    return DEAL_RES_CONTINUE;
  }

  if (TSDB_DATA_TYPE_NULL == pVal->node.resType.type) {
    pVal->translate = true;
    pVal->isNull = true;
    return DEAL_RES_CONTINUE;
  }

  pVal->node.resType.precision = getPrecisionFromCurrStmt(pCxt->pCurrStmt, targetDt.precision);

  EDealRes res = DEAL_RES_CONTINUE;
  if (pVal->isDuration) {
    res = translateDurationValue(pCxt, pVal);
  } else {
    res = translateNormalValue(pCxt, pVal, targetDt, strict);
1209
  }
1210
  pVal->node.resType = targetDt;
D
dapan1121 已提交
1211
  pVal->node.resType.scale = pVal->unit;
1212
  pVal->translate = true;
1213 1214 1215
  if (!strict && TSDB_DATA_TYPE_UBIGINT == pVal->node.resType.type && pVal->datum.u <= INT64_MAX) {
    pVal->node.resType.type = TSDB_DATA_TYPE_BIGINT;
  }
1216
  return res;
1217
}
wmmhello's avatar
wmmhello 已提交
1218

1219 1220 1221 1222 1223 1224 1225 1226
static int32_t calcTypeBytes(SDataType dt) {
  if (TSDB_DATA_TYPE_BINARY == dt.type) {
    return dt.bytes + VARSTR_HEADER_SIZE;
  } else if (TSDB_DATA_TYPE_NCHAR == dt.type) {
    return dt.bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
  } else {
    return dt.bytes;
  }
1227 1228
}

1229
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
1230 1231
  SDataType dt = pVal->node.resType;
  dt.bytes = calcTypeBytes(dt);
1232
  return translateValueImpl(pCxt, pVal, dt, false);
1233 1234
}

1235 1236 1237 1238
static int32_t doTranslateValue(STranslateContext* pCxt, SValueNode* pVal) {
  return DEAL_RES_ERROR == translateValue(pCxt, pVal) ? pCxt->errCode : TSDB_CODE_SUCCESS;
}

1239
static bool isMultiResFunc(SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
1240 1241 1242 1243 1244 1245
  if (NULL == pNode) {
    return false;
  }
  if (QUERY_NODE_FUNCTION != nodeType(pNode) || !fmIsMultiResFunc(((SFunctionNode*)pNode)->funcId)) {
    return false;
  }
1246 1247 1248
  if (FUNCTION_TYPE_TAGS == ((SFunctionNode*)pNode)->funcType) {
    return true;
  }
wmmhello's avatar
wmmhello 已提交
1249 1250 1251 1252 1253 1254
  SNodeList* pParameterList = ((SFunctionNode*)pNode)->pParameterList;
  if (LIST_LENGTH(pParameterList) > 1) {
    return true;
  }
  SNode* pParam = nodesListGetNode(pParameterList, 0);
  return (QUERY_NODE_COLUMN == nodeType(pParam) ? 0 == strcmp(((SColumnNode*)pParam)->colName, "*") : false);
1255 1256
}

D
dapan1121 已提交
1257 1258 1259 1260
static bool dataTypeEqual(const SDataType* l, const SDataType* r) {
  return (l->type == r->type && l->bytes == r->bytes && l->precision == r->precision && l->scale == r->scale);
}

X
Xiaoyu Wang 已提交
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
// 0 means equal, 1 means the left shall prevail, -1 means the right shall prevail
static int32_t dataTypeComp(const SDataType* l, const SDataType* r) {
  if (l->type != r->type) {
    return 1;
  }

  if (l->bytes != r->bytes) {
    return l->bytes > r->bytes ? 1 : -1;
  }

  return (l->precision == r->precision && l->scale == r->scale) ? 0 : 1;
}

1274
static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
wmmhello's avatar
wmmhello 已提交
1275 1276 1277 1278 1279 1280 1281
  if (isMultiResFunc(pOp->pLeft)) {
    return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pLeft))->aliasName);
  }
  if (isMultiResFunc(pOp->pRight)) {
    return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName);
  }

1282 1283
  if (TSDB_CODE_SUCCESS != scalarGetOperatorResultType(pOp)) {
    return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pOp->node.aliasName);
wmmhello's avatar
wmmhello 已提交
1284
  }
1285

wmmhello's avatar
wmmhello 已提交
1286
  return DEAL_RES_CONTINUE;
1287 1288
}

1289
static EDealRes haveVectorFunction(SNode* pNode, void* pContext) {
5
54liuyao 已提交
1290
  if (isAggFunc(pNode) || isIndefiniteRowsFunc(pNode) || isWindowPseudoColumnFunc(pNode)) {
wmmhello's avatar
wmmhello 已提交
1291 1292 1293 1294
    *((bool*)pContext) = true;
    return DEAL_RES_END;
  }
  return DEAL_RES_CONTINUE;
X
Xiaoyu Wang 已提交
1295 1296
}

1297
static int32_t findTable(STranslateContext* pCxt, const char* pTableAlias, STableNode** pOutput) {
wmmhello's avatar
wmmhello 已提交
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307
  SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
  size_t  nums = taosArrayGetSize(pTables);
  for (size_t i = 0; i < nums; ++i) {
    STableNode* pTable = taosArrayGetP(pTables, i);
    if (NULL == pTableAlias || 0 == strcmp(pTable->tableAlias, pTableAlias)) {
      *pOutput = pTable;
      return TSDB_CODE_SUCCESS;
    }
  }
  return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TABLE_NOT_EXIST, pTableAlias);
1308 1309 1310
}

static bool isCountStar(SFunctionNode* pFunc) {
wmmhello's avatar
wmmhello 已提交
1311 1312 1313 1314 1315
  if (FUNCTION_TYPE_COUNT != pFunc->funcType || 1 != LIST_LENGTH(pFunc->pParameterList)) {
    return false;
  }
  SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
  return (QUERY_NODE_COLUMN == nodeType(pPara) && 0 == strcmp(((SColumnNode*)pPara)->colName, "*"));
1316 1317 1318 1319
}

// count(*) is rewritten as count(ts) for scannning optimization
static int32_t rewriteCountStar(STranslateContext* pCxt, SFunctionNode* pCount) {
1320
  SColumnNode* pCol = (SColumnNode*)nodesListGetNode(pCount->pParameterList, 0);
wmmhello's avatar
wmmhello 已提交
1321 1322 1323
  STableNode*  pTable = NULL;
  int32_t      code = findTable(pCxt, ('\0' == pCol->tableAlias[0] ? NULL : pCol->tableAlias), &pTable);
  if (TSDB_CODE_SUCCESS == code && QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
X
Xiaoyu Wang 已提交
1324
    setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, -1, pCol);
wmmhello's avatar
wmmhello 已提交
1325 1326
  }
  return code;
1327 1328
}

X
Xiaoyu Wang 已提交
1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358
static bool isCountTbname(SFunctionNode* pFunc) {
  if (FUNCTION_TYPE_COUNT != pFunc->funcType || 1 != LIST_LENGTH(pFunc->pParameterList)) {
    return false;
  }
  SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
  return (QUERY_NODE_FUNCTION == nodeType(pPara) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPara)->funcType);
}

// count(tbname) is rewritten as count(ts) for scannning optimization
static int32_t rewriteCountTbname(STranslateContext* pCxt, SFunctionNode* pCount) {
  SFunctionNode* pTbname = (SFunctionNode*)nodesListGetNode(pCount->pParameterList, 0);
  const char*    pTableAlias = NULL;
  if (LIST_LENGTH(pTbname->pParameterList) > 0) {
    pTableAlias = ((SValueNode*)nodesListGetNode(pTbname->pParameterList, 0))->literal;
  }
  STableNode* pTable = NULL;
  int32_t     code = findTable(pCxt, pTableAlias, &pTable);
  if (TSDB_CODE_SUCCESS == code) {
    SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
    if (NULL == pCol) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    } else {
      setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, -1, pCol);
      NODES_DESTORY_LIST(pCount->pParameterList);
      code = nodesListMakeAppend(&pCount->pParameterList, (SNode*)pCol);
    }
  }
  return code;
}

1359
static bool hasInvalidFuncNesting(SNodeList* pParameterList) {
wmmhello's avatar
wmmhello 已提交
1360
  bool hasInvalidFunc = false;
1361
  nodesWalkExprs(pParameterList, haveVectorFunction, &hasInvalidFunc);
wmmhello's avatar
wmmhello 已提交
1362 1363 1364 1365
  return hasInvalidFunc;
}

static int32_t getFuncInfo(STranslateContext* pCxt, SFunctionNode* pFunc) {
1366 1367
  // the time precision of the function execution environment
  pFunc->node.resType.precision = getPrecisionFromCurrStmt(pCxt->pCurrStmt, TSDB_TIME_PRECISION_MILLI);
1368 1369 1370 1371 1372
  int32_t code = fmGetFuncInfo(pFunc, pCxt->msgBuf.buf, pCxt->msgBuf.len);
  if (TSDB_CODE_FUNC_NOT_BUILTIN_FUNTION == code) {
    code = getUdfInfo(pCxt, pFunc);
  }
  return code;
1373 1374
}

X
Xiaoyu Wang 已提交
1375
static int32_t translateAggFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
X
Xiaoyu Wang 已提交
1376 1377 1378
  if (!fmIsAggFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
1379 1380 1381 1382 1383 1384
  if (beforeHaving(pCxt->currClause)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
  }
  if (hasInvalidFuncNesting(pFunc->pParameterList)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AGG_FUNC_NESTING);
  }
1385 1386 1387
  // The auto-generated COUNT function in the DELETE statement is legal
  if (isSelectStmt(pCxt->pCurrStmt) &&
      (((SSelectStmt*)pCxt->pCurrStmt)->hasIndefiniteRowsFunc || ((SSelectStmt*)pCxt->pCurrStmt)->hasMultiRowsFunc)) {
X
Xiaoyu Wang 已提交
1388 1389 1390 1391 1392 1393
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
  }

  if (isCountStar(pFunc)) {
    return rewriteCountStar(pCxt, pFunc);
  }
X
Xiaoyu Wang 已提交
1394 1395 1396
  if (isCountTbname(pFunc)) {
    return rewriteCountTbname(pCxt, pFunc);
  }
X
Xiaoyu Wang 已提交
1397 1398 1399 1400
  return TSDB_CODE_SUCCESS;
}

static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
X
Xiaoyu Wang 已提交
1401 1402 1403
  if (!fmIsScanPseudoColumnFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
1404
  if (0 == LIST_LENGTH(pFunc->pParameterList)) {
1405
    if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable ||
1406
        QUERY_NODE_REAL_TABLE != nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) {
X
Xiaoyu Wang 已提交
1407 1408 1409
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME);
    }
  } else {
1410
    SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 0);
X
Xiaoyu Wang 已提交
1411 1412 1413 1414 1415 1416 1417 1418 1419 1420
    STableNode* pTable = NULL;
    pCxt->errCode = findTable(pCxt, pVal->literal, &pTable);
    if (TSDB_CODE_SUCCESS == pCxt->errCode && (NULL == pTable || QUERY_NODE_REAL_TABLE != nodeType(pTable))) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME);
    }
  }
  return TSDB_CODE_SUCCESS;
}

static int32_t translateIndefiniteRowsFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
X
Xiaoyu Wang 已提交
1421 1422 1423
  if (!fmIsIndefiniteRowsFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
1424
  if (!isSelectStmt(pCxt->pCurrStmt) || SQL_CLAUSE_SELECT != pCxt->currClause) {
X
Xiaoyu Wang 已提交
1425 1426
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
  }
1427 1428
  SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
  if (pSelect->hasAggFuncs || pSelect->hasMultiRowsFunc ||
1429 1430
      (pSelect->hasIndefiniteRowsFunc &&
       (FUNC_RETURN_ROWS_INDEFINITE == pSelect->returnRows || pSelect->returnRows != fmGetFuncReturnRows(pFunc)))) {
1431 1432 1433
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
  }
  if (NULL != pSelect->pWindow || NULL != pSelect->pGroupByList) {
1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
                                   "%s function is not supported in window query or group query", pFunc->functionName);
  }
  if (hasInvalidFuncNesting(pFunc->pParameterList)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AGG_FUNC_NESTING);
  }
  return TSDB_CODE_SUCCESS;
}

static int32_t translateMultiRowsFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
  if (!fmIsMultiRowsFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
  if (!isSelectStmt(pCxt->pCurrStmt) || SQL_CLAUSE_SELECT != pCxt->currClause ||
1448 1449
      ((SSelectStmt*)pCxt->pCurrStmt)->hasIndefiniteRowsFunc || ((SSelectStmt*)pCxt->pCurrStmt)->hasAggFuncs ||
      ((SSelectStmt*)pCxt->pCurrStmt)->hasMultiRowsFunc) {
X
Xiaoyu Wang 已提交
1450 1451 1452 1453 1454 1455 1456 1457
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
  }
  if (hasInvalidFuncNesting(pFunc->pParameterList)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AGG_FUNC_NESTING);
  }
  return TSDB_CODE_SUCCESS;
}

1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487
static int32_t translateInterpFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
  if (!fmIsInterpFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
  if (!isSelectStmt(pCxt->pCurrStmt) || SQL_CLAUSE_SELECT != pCxt->currClause) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
  }
  SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
  if (pSelect->hasAggFuncs || pSelect->hasMultiRowsFunc || pSelect->hasIndefiniteRowsFunc) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
  }
  if (NULL != pSelect->pWindow || NULL != pSelect->pGroupByList) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
                                   "%s function is not supported in window query or group query", pFunc->functionName);
  }
  if (hasInvalidFuncNesting(pFunc->pParameterList)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AGG_FUNC_NESTING);
  }
  return TSDB_CODE_SUCCESS;
}

static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
  if (!fmIsTimelineFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
  if (!isSelectStmt(pCxt->pCurrStmt)) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
                                   "%s function must be used in select statements", pFunc->functionName);
  }
  SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
X
Xiaoyu Wang 已提交
1488
  if (NULL != pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
1489 1490 1491 1492 1493 1494 1495
      !isTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
                                   "%s function requires valid time series input", pFunc->functionName);
  }
  return TSDB_CODE_SUCCESS;
}

1496 1497 1498 1499 1500 1501 1502 1503 1504
static bool hasFillClause(SNode* pCurrStmt) {
  if (!isSelectStmt(pCurrStmt)) {
    return false;
  }
  SSelectStmt* pSelect = (SSelectStmt*)pCurrStmt;
  return NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow) &&
         NULL != ((SIntervalWindowNode*)pSelect->pWindow)->pFill;
}

X
Xiaoyu Wang 已提交
1505 1506 1507 1508
static int32_t translateForbidFillFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
  if (!fmIsForbidFillFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
1509
  if (hasFillClause(pCxt->pCurrStmt)) {
X
Xiaoyu Wang 已提交
1510 1511 1512 1513 1514
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC, pFunc->functionName);
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
1515 1516 1517 1518
static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
  if (!fmIsWindowPseudoColumnFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
1519
  if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pWindow) {
X
Xiaoyu Wang 已提交
1520 1521
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC);
  }
X
Xiaoyu Wang 已提交
1522
  if (beforeWindow(pCxt->currClause)) {
X
Xiaoyu Wang 已提交
1523 1524 1525
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC, "There mustn't be %s",
                                   pFunc->functionName);
  }
X
Xiaoyu Wang 已提交
1526 1527 1528
  return TSDB_CODE_SUCCESS;
}

1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
static int32_t translateForbidStreamFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
  if (!fmIsForbidStreamFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
  if (pCxt->createStream) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC, pFunc->functionName);
  }
  return TSDB_CODE_SUCCESS;
}

1539 1540 1541 1542
static int32_t translateRepeatScanFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
  if (!fmIsRepeatScanFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
1543
  if (!isSelectStmt(pCxt->pCurrStmt)) {
X
Xiaoyu Wang 已提交
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE,
                                   "%s is only supported in single table query", pFunc->functionName);
  }
  SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
  SNode*       pTable = pSelect->pFromTable;
  // select percentile() without from clause is also valid
  if ((NULL != pTable && (QUERY_NODE_REAL_TABLE != nodeType(pTable) ||
                          (TSDB_CHILD_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType &&
                           TSDB_NORMAL_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType))) ||
      NULL != pSelect->pPartitionByList) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE,
                                   "%s is only supported in single table query", pFunc->functionName);
1556
  }
X
Xiaoyu Wang 已提交
1557
  return TSDB_CODE_SUCCESS;
1558 1559
}

1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573
static bool isStar(SNode* pNode) {
  return (QUERY_NODE_COLUMN == nodeType(pNode)) && ('\0' == ((SColumnNode*)pNode)->tableAlias[0]) &&
         (0 == strcmp(((SColumnNode*)pNode)->colName, "*"));
}

static bool isTableStar(SNode* pNode) {
  return (QUERY_NODE_COLUMN == nodeType(pNode)) && ('\0' != ((SColumnNode*)pNode)->tableAlias[0]) &&
         (0 == strcmp(((SColumnNode*)pNode)->colName, "*"));
}

static int32_t translateMultiResFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
  if (!fmIsMultiResFunc(pFunc->funcId)) {
    return TSDB_CODE_SUCCESS;
  }
1574
  if (SQL_CLAUSE_SELECT != pCxt->currClause) {
1575 1576 1577 1578 1579 1580
    SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
    if (isStar(pPara) || isTableStar(pPara)) {
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
                                     "%s(*) is only supported in SELECTed list", pFunc->functionName);
    }
  }
1581
  if (tsKeepColumnName && 1 == LIST_LENGTH(pFunc->pParameterList)) {
1582 1583
    strcpy(pFunc->node.userAlias, ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->userAlias);
  }
1584 1585
  return TSDB_CODE_SUCCESS;
}
1586 1587 1588 1589 1590 1591 1592 1593

static int32_t getMultiResFuncNum(SNodeList* pParameterList) {
  if (1 == LIST_LENGTH(pParameterList)) {
    return isStar(nodesListGetNode(pParameterList, 0)) ? 2 : 1;
  }
  return LIST_LENGTH(pParameterList);
}

1594 1595 1596 1597 1598 1599 1600 1601 1602
static int32_t calcSelectFuncNum(SFunctionNode* pFunc, int32_t currSelectFuncNum) {
  if (fmIsCumulativeFunc(pFunc->funcId)) {
    return currSelectFuncNum > 0 ? currSelectFuncNum : 1;
  }
  return currSelectFuncNum + ((fmIsMultiResFunc(pFunc->funcId) && !fmIsLastRowFunc(pFunc->funcId))
                                  ? getMultiResFuncNum(pFunc->pParameterList)
                                  : 1);
}

1603 1604 1605
static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) {
  if (NULL != pCurrStmt && QUERY_NODE_SELECT_STMT == nodeType(pCurrStmt)) {
    SSelectStmt* pSelect = (SSelectStmt*)pCurrStmt;
X
Xiaoyu Wang 已提交
1606 1607
    pSelect->hasAggFuncs = pSelect->hasAggFuncs ? true : fmIsAggFunc(pFunc->funcId);
    pSelect->hasRepeatScanFuncs = pSelect->hasRepeatScanFuncs ? true : fmIsRepeatScanFunc(pFunc->funcId);
1608 1609 1610 1611
    if (fmIsIndefiniteRowsFunc(pFunc->funcId)) {
      pSelect->hasIndefiniteRowsFunc = true;
      pSelect->returnRows = fmGetFuncReturnRows(pFunc);
    }
1612
    pSelect->hasMultiRowsFunc = pSelect->hasMultiRowsFunc ? true : fmIsMultiRowsFunc(pFunc->funcId);
1613 1614
    if (fmIsSelectFunc(pFunc->funcId)) {
      pSelect->hasSelectFunc = true;
1615
      pSelect->selectFuncNum = calcSelectFuncNum(pFunc, pSelect->selectFuncNum);
1616
    } else if (fmIsVectorFunc(pFunc->funcId)) {
1617 1618
      pSelect->hasOtherVectorFunc = true;
    }
1619 1620
    pSelect->hasUniqueFunc = pSelect->hasUniqueFunc ? true : (FUNCTION_TYPE_UNIQUE == pFunc->funcType);
    pSelect->hasTailFunc = pSelect->hasTailFunc ? true : (FUNCTION_TYPE_TAIL == pFunc->funcType);
X
Xiaoyu Wang 已提交
1621
    pSelect->hasInterpFunc = pSelect->hasInterpFunc ? true : (FUNCTION_TYPE_INTERP == pFunc->funcType);
X
Xiaoyu Wang 已提交
1622
    pSelect->hasLastRowFunc = pSelect->hasLastRowFunc ? true : (FUNCTION_TYPE_LAST_ROW == pFunc->funcType);
X
Xiaoyu Wang 已提交
1623
    pSelect->hasLastFunc = pSelect->hasLastFunc ? true : (FUNCTION_TYPE_LAST == pFunc->funcType);
1624
    pSelect->hasTimeLineFunc = pSelect->hasTimeLineFunc ? true : fmIsTimelineFunc(pFunc->funcId);
X
Xiaoyu Wang 已提交
1625
    pSelect->hasUdaf = pSelect->hasUdaf ? true : fmIsUserDefinedFunc(pFunc->funcId) && fmIsAggFunc(pFunc->funcId);
1626
    pSelect->onlyHasKeepOrderFunc = pSelect->onlyHasKeepOrderFunc ? fmIsKeepOrderFunc(pFunc->funcId) : false;
X
Xiaoyu Wang 已提交
1627
  }
X
Xiaoyu Wang 已提交
1628 1629
}

1630
static int32_t rewriteFuncToValue(STranslateContext* pCxt, char* pLiteral, SNode** pNode) {
1631 1632 1633 1634 1635 1636 1637 1638 1639 1640
  SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
  if (NULL == pVal) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  strcpy(pVal->node.aliasName, ((SExprNode*)*pNode)->aliasName);
  pVal->node.resType = ((SExprNode*)*pNode)->resType;
  if (NULL == pLiteral) {
    pVal->isNull = true;
  } else {
    pVal->literal = pLiteral;
1641 1642 1643
    if (IS_VAR_DATA_TYPE(pVal->node.resType.type)) {
      pVal->node.resType.bytes = strlen(pLiteral);
    }
1644 1645
  }
  if (DEAL_RES_ERROR != translateValue(pCxt, pVal)) {
1646
    nodesDestroyNode(*pNode);
1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
    *pNode = (SNode*)pVal;
  } else {
    nodesDestroyNode((SNode*)pVal);
  }
  return pCxt->errCode;
}

static int32_t rewriteDatabaseFunc(STranslateContext* pCxt, SNode** pNode) {
  char* pCurrDb = NULL;
  if (NULL != pCxt->pParseCxt->db) {
    pCurrDb = taosMemoryStrDup((void*)pCxt->pParseCxt->db);
    if (NULL == pCurrDb) {
      return TSDB_CODE_OUT_OF_MEMORY;
wmmhello's avatar
wmmhello 已提交
1660 1661
    }
  }
1662
  return rewriteFuncToValue(pCxt, pCurrDb, pNode);
1663
}
wmmhello's avatar
wmmhello 已提交
1664

1665 1666 1667 1668
static int32_t rewriteClentVersionFunc(STranslateContext* pCxt, SNode** pNode) {
  char* pVer = taosMemoryStrDup((void*)version);
  if (NULL == pVer) {
    return TSDB_CODE_OUT_OF_MEMORY;
wmmhello's avatar
wmmhello 已提交
1669
  }
1670
  return rewriteFuncToValue(pCxt, pVer, pNode);
1671 1672 1673 1674 1675 1676
}

static int32_t rewriteServerVersionFunc(STranslateContext* pCxt, SNode** pNode) {
  char* pVer = taosMemoryStrDup((void*)pCxt->pParseCxt->svrVer);
  if (NULL == pVer) {
    return TSDB_CODE_OUT_OF_MEMORY;
wmmhello's avatar
wmmhello 已提交
1677
  }
1678
  return rewriteFuncToValue(pCxt, pVer, pNode);
1679 1680 1681 1682 1683
}

static int32_t rewriteServerStatusFunc(STranslateContext* pCxt, SNode** pNode) {
  if (pCxt->pParseCxt->nodeOffline) {
    return TSDB_CODE_RPC_NETWORK_UNAVAIL;
X
Xiaoyu Wang 已提交
1684
  }
1685
  char* pStatus = taosMemoryStrDup((void*)"1");
1686
  return rewriteFuncToValue(pCxt, pStatus, pNode);
1687 1688 1689 1690 1691 1692 1693 1694 1695
}

static int32_t rewriteUserFunc(STranslateContext* pCxt, SNode** pNode) {
  char    userConn[TSDB_USER_LEN + 1 + TSDB_FQDN_LEN] = {0};  // format 'user@host'
  int32_t len = snprintf(userConn, sizeof(userConn), "%s@", pCxt->pParseCxt->pUser);
  taosGetFqdn(userConn + len);
  char* pUserConn = taosMemoryStrDup((void*)userConn);
  if (NULL == pUserConn) {
    return TSDB_CODE_OUT_OF_MEMORY;
X
Xiaoyu Wang 已提交
1696
  }
1697
  return rewriteFuncToValue(pCxt, pUserConn, pNode);
1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
}

static int32_t rewriteSystemInfoFunc(STranslateContext* pCxt, SNode** pNode) {
  switch (((SFunctionNode*)*pNode)->funcType) {
    case FUNCTION_TYPE_DATABASE:
      return rewriteDatabaseFunc(pCxt, pNode);
    case FUNCTION_TYPE_CLIENT_VERSION:
      return rewriteClentVersionFunc(pCxt, pNode);
    case FUNCTION_TYPE_SERVER_VERSION:
      return rewriteServerVersionFunc(pCxt, pNode);
    case FUNCTION_TYPE_SERVER_STATUS:
      return rewriteServerStatusFunc(pCxt, pNode);
    case FUNCTION_TYPE_CURRENT_USER:
    case FUNCTION_TYPE_USER:
      return rewriteUserFunc(pCxt, pNode);
    default:
      break;
X
Xiaoyu Wang 已提交
1715
  }
1716 1717 1718 1719 1720 1721 1722
  return TSDB_CODE_PAR_INTERNAL_ERROR;
}

static int32_t translateNoramlFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
  int32_t code = translateAggFunc(pCxt, pFunc);
  if (TSDB_CODE_SUCCESS == code) {
    code = translateScanPseudoColumnFunc(pCxt, pFunc);
1723
  }
1724 1725
  if (TSDB_CODE_SUCCESS == code) {
    code = translateIndefiniteRowsFunc(pCxt, pFunc);
1726
  }
1727 1728 1729 1730 1731
  if (TSDB_CODE_SUCCESS == code) {
    code = translateForbidFillFunc(pCxt, pFunc);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateWindowPseudoColumnFunc(pCxt, pFunc);
1732
  }
1733 1734 1735
  if (TSDB_CODE_SUCCESS == code) {
    code = translateForbidStreamFunc(pCxt, pFunc);
  }
1736 1737 1738
  if (TSDB_CODE_SUCCESS == code) {
    code = translateRepeatScanFunc(pCxt, pFunc);
  }
1739 1740 1741
  if (TSDB_CODE_SUCCESS == code) {
    code = translateMultiResFunc(pCxt, pFunc);
  }
1742 1743 1744
  if (TSDB_CODE_SUCCESS == code) {
    code = translateMultiRowsFunc(pCxt, pFunc);
  }
1745 1746 1747 1748 1749 1750
  if (TSDB_CODE_SUCCESS == code) {
    code = translateInterpFunc(pCxt, pFunc);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateTimelineFunc(pCxt, pFunc);
  }
1751 1752 1753 1754 1755 1756
  if (TSDB_CODE_SUCCESS == code) {
    setFuncClassification(pCxt->pCurrStmt, pFunc);
  }
  return code;
}

1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803
static int32_t rewriteQueryTimeFunc(STranslateContext* pCxt, int64_t val, SNode** pNode) {
  if (INT64_MIN == val || INT64_MAX == val) {
    return rewriteFuncToValue(pCxt, NULL, pNode);
  }

  char* pStr = taosMemoryCalloc(1, 20);
  if (NULL == pStr) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  snprintf(pStr, 20, "%" PRId64 "", val);
  return rewriteFuncToValue(pCxt, pStr, pNode);
}

static int32_t rewriteQstartFunc(STranslateContext* pCxt, SNode** pNode) {
  return rewriteQueryTimeFunc(pCxt, ((SSelectStmt*)pCxt->pCurrStmt)->timeRange.skey, pNode);
}

static int32_t rewriteQendFunc(STranslateContext* pCxt, SNode** pNode) {
  return rewriteQueryTimeFunc(pCxt, ((SSelectStmt*)pCxt->pCurrStmt)->timeRange.ekey, pNode);
}

static int32_t rewriteQdurationFunc(STranslateContext* pCxt, SNode** pNode) {
  STimeWindow range = ((SSelectStmt*)pCxt->pCurrStmt)->timeRange;
  if (INT64_MIN == range.skey || INT64_MAX == range.ekey) {
    return rewriteQueryTimeFunc(pCxt, INT64_MIN, pNode);
  }
  return rewriteQueryTimeFunc(pCxt, range.ekey - range.skey + 1, pNode);
}

static int32_t rewriteClientPseudoColumnFunc(STranslateContext* pCxt, SNode** pNode) {
  if (NULL == pCxt->pCurrStmt || QUERY_NODE_SELECT_STMT != nodeType(pCxt->pCurrStmt) ||
      pCxt->currClause <= SQL_CLAUSE_WHERE) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC, "Illegal pseudo column");
  }
  switch (((SFunctionNode*)*pNode)->funcType) {
    case FUNCTION_TYPE_QSTART:
      return rewriteQstartFunc(pCxt, pNode);
    case FUNCTION_TYPE_QEND:
      return rewriteQendFunc(pCxt, pNode);
    case FUNCTION_TYPE_QDURATION:
      return rewriteQdurationFunc(pCxt, pNode);
    default:
      break;
  }
  return TSDB_CODE_PAR_INTERNAL_ERROR;
}

1804 1805 1806 1807
static int32_t translateFunctionImpl(STranslateContext* pCxt, SFunctionNode** pFunc) {
  if (fmIsSystemInfoFunc((*pFunc)->funcId)) {
    return rewriteSystemInfoFunc(pCxt, (SNode**)pFunc);
  }
1808 1809 1810
  if (fmIsClientPseudoColumnFunc((*pFunc)->funcId)) {
    return rewriteClientPseudoColumnFunc(pCxt, (SNode**)pFunc);
  }
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822
  return translateNoramlFunction(pCxt, *pFunc);
}

static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode** pFunc) {
  SNode* pParam = NULL;
  FOREACH(pParam, (*pFunc)->pParameterList) {
    if (isMultiResFunc(pParam)) {
      return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pParam)->aliasName);
    }
  }

  pCxt->errCode = getFuncInfo(pCxt, *pFunc);
X
Xiaoyu Wang 已提交
1823
  if (TSDB_CODE_SUCCESS == pCxt->errCode) {
1824
    pCxt->errCode = translateFunctionImpl(pCxt, pFunc);
wmmhello's avatar
wmmhello 已提交
1825 1826
  }
  return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
1827 1828 1829
}

static EDealRes translateExprSubquery(STranslateContext* pCxt, SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
1830
  return (TSDB_CODE_SUCCESS == translateSubquery(pCxt, pNode) ? DEAL_RES_CONTINUE : DEAL_RES_ERROR);
1831 1832
}

1833
static EDealRes translateLogicCond(STranslateContext* pCxt, SLogicConditionNode* pCond) {
wmmhello's avatar
wmmhello 已提交
1834 1835 1836
  pCond->node.resType.type = TSDB_DATA_TYPE_BOOL;
  pCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
  return DEAL_RES_CONTINUE;
1837 1838
}

X
Xiaoyu Wang 已提交
1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864
static int32_t createCastFunc(STranslateContext* pCxt, SNode* pExpr, SDataType dt, SNode** pCast) {
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
  if (NULL == pFunc) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  strcpy(pFunc->functionName, "cast");
  pFunc->node.resType = dt;
  if (TSDB_CODE_SUCCESS != nodesListMakeAppend(&pFunc->pParameterList, pExpr)) {
    nodesDestroyNode((SNode*)pFunc);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  if (TSDB_CODE_SUCCESS != getFuncInfo(pCxt, pFunc)) {
    nodesClearList(pFunc->pParameterList);
    pFunc->pParameterList = NULL;
    nodesDestroyNode((SNode*)pFunc);
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pExpr)->aliasName);
  }
  *pCast = (SNode*)pFunc;
  return TSDB_CODE_SUCCESS;
}

static EDealRes translateWhenThen(STranslateContext* pCxt, SWhenThenNode* pWhenThen) {
  pWhenThen->node.resType = ((SExprNode*)pWhenThen->pThen)->resType;
  return DEAL_RES_CONTINUE;
}

1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884
static bool isCondition(const SNode* pNode) {
  if (QUERY_NODE_OPERATOR == nodeType(pNode)) {
    return nodesIsComparisonOp((const SOperatorNode*)pNode);
  }
  return (QUERY_NODE_LOGIC_CONDITION == nodeType(pNode));
}

static int32_t rewriteIsTrue(SNode* pSrc, SNode** pIsTrue) {
  SOperatorNode* pOp = (SOperatorNode*)nodesMakeNode(QUERY_NODE_OPERATOR);
  if (NULL == pOp) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pOp->opType = OP_TYPE_IS_TRUE;
  pOp->pLeft = pSrc;
  pOp->node.resType.type = TSDB_DATA_TYPE_BOOL;
  pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
  *pIsTrue = (SNode*)pOp;
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
1885 1886
static EDealRes translateCaseWhen(STranslateContext* pCxt, SCaseWhenNode* pCaseWhen) {
  bool   first = true;
1887
  bool   allNullThen = true;
X
Xiaoyu Wang 已提交
1888 1889
  SNode* pNode = NULL;
  FOREACH(pNode, pCaseWhen->pWhenThenList) {
1890 1891 1892 1893 1894 1895 1896 1897 1898
    SWhenThenNode* pWhenThen = (SWhenThenNode*)pNode;
    if (NULL == pCaseWhen->pCase && !isCondition(pWhenThen->pWhen)) {
      SNode* pIsTrue = NULL;
      pCxt->errCode = rewriteIsTrue(pWhenThen->pWhen, &pIsTrue);
      if (TSDB_CODE_SUCCESS != pCxt->errCode) {
        return DEAL_RES_ERROR;
      }
      pWhenThen->pWhen = pIsTrue;
    }
1899 1900 1901 1902 1903 1904 1905 1906

    SExprNode* pThenExpr = (SExprNode*)pNode;
    if (TSDB_DATA_TYPE_NULL == pThenExpr->resType.type) {
      continue;
    }
    allNullThen = false;
    if (first || dataTypeComp(&pCaseWhen->node.resType, &pThenExpr->resType) < 0) {
      pCaseWhen->node.resType = pThenExpr->resType;
X
Xiaoyu Wang 已提交
1907 1908 1909 1910
    }
    first = false;
  }

1911 1912 1913 1914 1915 1916 1917 1918 1919 1920
  if (allNullThen) {
    if (NULL != pCaseWhen->pElse) {
      pCaseWhen->node.resType = ((SExprNode*)pCaseWhen->pElse)->resType;
    } else {
      pCaseWhen->node.resType.type = TSDB_DATA_TYPE_NULL;
      pCaseWhen->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
      return DEAL_RES_CONTINUE;
    }
  }

X
Xiaoyu Wang 已提交
1921 1922 1923
  FOREACH(pNode, pCaseWhen->pWhenThenList) {
    SWhenThenNode* pWhenThen = (SWhenThenNode*)pNode;
    if (!dataTypeEqual(&pCaseWhen->node.resType, &((SExprNode*)pNode)->resType)) {
1924 1925 1926 1927
      SNode* pCastFunc = NULL;
      pCxt->errCode = createCastFunc(pCxt, pWhenThen->pThen, pCaseWhen->node.resType, &pCastFunc);
      if (TSDB_CODE_SUCCESS != pCxt->errCode) {
        return DEAL_RES_ERROR;
X
Xiaoyu Wang 已提交
1928 1929 1930 1931 1932
      }
      pWhenThen->pThen = pCastFunc;
      pWhenThen->node.resType = pCaseWhen->node.resType;
    }
  }
X
Xiaoyu Wang 已提交
1933

X
Xiaoyu Wang 已提交
1934 1935
  if (NULL != pCaseWhen->pElse && !dataTypeEqual(&pCaseWhen->node.resType, &((SExprNode*)pCaseWhen->pElse)->resType)) {
    SNode* pCastFunc = NULL;
1936 1937 1938
    pCxt->errCode = createCastFunc(pCxt, pCaseWhen->pElse, pCaseWhen->node.resType, &pCastFunc);
    if (TSDB_CODE_SUCCESS != pCxt->errCode) {
      return DEAL_RES_ERROR;
X
Xiaoyu Wang 已提交
1939 1940 1941 1942 1943 1944 1945
    }
    pCaseWhen->pElse = pCastFunc;
    ((SExprNode*)pCaseWhen->pElse)->resType = pCaseWhen->node.resType;
  }
  return DEAL_RES_CONTINUE;
}

X
Xiaoyu Wang 已提交
1946
static EDealRes doTranslateExpr(SNode** pNode, void* pContext) {
wmmhello's avatar
wmmhello 已提交
1947
  STranslateContext* pCxt = (STranslateContext*)pContext;
X
Xiaoyu Wang 已提交
1948
  switch (nodeType(*pNode)) {
wmmhello's avatar
wmmhello 已提交
1949
    case QUERY_NODE_COLUMN:
X
Xiaoyu Wang 已提交
1950
      return translateColumn(pCxt, (SColumnNode**)pNode);
wmmhello's avatar
wmmhello 已提交
1951
    case QUERY_NODE_VALUE:
X
Xiaoyu Wang 已提交
1952
      return translateValue(pCxt, (SValueNode*)*pNode);
wmmhello's avatar
wmmhello 已提交
1953
    case QUERY_NODE_OPERATOR:
1954
      return translateOperator(pCxt, (SOperatorNode*)*pNode);
wmmhello's avatar
wmmhello 已提交
1955
    case QUERY_NODE_FUNCTION:
1956
      return translateFunction(pCxt, (SFunctionNode**)pNode);
wmmhello's avatar
wmmhello 已提交
1957
    case QUERY_NODE_LOGIC_CONDITION:
X
Xiaoyu Wang 已提交
1958
      return translateLogicCond(pCxt, (SLogicConditionNode*)*pNode);
wmmhello's avatar
wmmhello 已提交
1959
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
1960
      return translateExprSubquery(pCxt, ((STempTableNode*)*pNode)->pSubquery);
X
Xiaoyu Wang 已提交
1961 1962 1963 1964
    case QUERY_NODE_WHEN_THEN:
      return translateWhenThen(pCxt, (SWhenThenNode*)*pNode);
    case QUERY_NODE_CASE_WHEN:
      return translateCaseWhen(pCxt, (SCaseWhenNode*)*pNode);
wmmhello's avatar
wmmhello 已提交
1965 1966 1967 1968
    default:
      break;
  }
  return DEAL_RES_CONTINUE;
1969 1970
}

X
Xiaoyu Wang 已提交
1971 1972
static int32_t translateExpr(STranslateContext* pCxt, SNode** pNode) {
  nodesRewriteExprPostOrder(pNode, doTranslateExpr, pCxt);
wmmhello's avatar
wmmhello 已提交
1973
  return pCxt->errCode;
1974 1975 1976
}

static int32_t translateExprList(STranslateContext* pCxt, SNodeList* pList) {
X
Xiaoyu Wang 已提交
1977
  nodesRewriteExprsPostOrder(pList, doTranslateExpr, pCxt);
wmmhello's avatar
wmmhello 已提交
1978
  return pCxt->errCode;
1979 1980
}

1981
static SNodeList* getGroupByList(STranslateContext* pCxt) {
wmmhello's avatar
wmmhello 已提交
1982
  if (isDistinctOrderBy(pCxt)) {
1983
    return ((SSelectStmt*)pCxt->pCurrStmt)->pProjectionList;
wmmhello's avatar
wmmhello 已提交
1984
  }
1985
  return ((SSelectStmt*)pCxt->pCurrStmt)->pGroupByList;
1986 1987 1988
}

static SNode* getGroupByNode(SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
1989 1990 1991 1992
  if (QUERY_NODE_GROUPING_SET == nodeType(pNode)) {
    return nodesListGetNode(((SGroupingSetNode*)pNode)->pParameterList, 0);
  }
  return pNode;
1993 1994 1995
}

static int32_t getGroupByErrorCode(STranslateContext* pCxt) {
wmmhello's avatar
wmmhello 已提交
1996 1997 1998
  if (isDistinctOrderBy(pCxt)) {
    return TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION;
  }
1999 2000 2001 2002
  if (isSelectStmt(pCxt->pCurrStmt) && NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pGroupByList) {
    return TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION;
  }
  return TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN;
2003 2004
}

2005
static EDealRes rewriteColToSelectValFunc(STranslateContext* pCxt, SNode** pNode) {
2006
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
wmmhello's avatar
wmmhello 已提交
2007 2008 2009 2010 2011 2012
  if (NULL == pFunc) {
    pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
    return DEAL_RES_ERROR;
  }
  strcpy(pFunc->functionName, "_select_value");
  strcpy(pFunc->node.aliasName, ((SExprNode*)*pNode)->aliasName);
X
Xiaoyu Wang 已提交
2013
  strcpy(pFunc->node.userAlias, ((SExprNode*)*pNode)->userAlias);
wmmhello's avatar
wmmhello 已提交
2014 2015
  pCxt->errCode = nodesListMakeAppend(&pFunc->pParameterList, *pNode);
  if (TSDB_CODE_SUCCESS == pCxt->errCode) {
2016
    pCxt->errCode = getFuncInfo(pCxt, pFunc);
wmmhello's avatar
wmmhello 已提交
2017 2018 2019
  }
  if (TSDB_CODE_SUCCESS == pCxt->errCode) {
    *pNode = (SNode*)pFunc;
2020
    ((SSelectStmt*)pCxt->pCurrStmt)->hasSelectValFunc = true;
wmmhello's avatar
wmmhello 已提交
2021
  } else {
2022
    nodesDestroyNode((SNode*)pFunc);
wmmhello's avatar
wmmhello 已提交
2023 2024
  }
  return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
2025 2026
}

2027 2028 2029 2030 2031 2032 2033 2034 2035
static EDealRes rewriteExprToGroupKeyFunc(STranslateContext* pCxt, SNode** pNode) {
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
  if (NULL == pFunc) {
    pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
    return DEAL_RES_ERROR;
  }

  strcpy(pFunc->functionName, "_group_key");
  strcpy(pFunc->node.aliasName, ((SExprNode*)*pNode)->aliasName);
2036
  strcpy(pFunc->node.userAlias, ((SExprNode*)*pNode)->userAlias);
2037 2038 2039 2040 2041 2042 2043 2044 2045
  pCxt->errCode = nodesListMakeAppend(&pFunc->pParameterList, *pNode);
  if (TSDB_CODE_SUCCESS == pCxt->errCode) {
    *pNode = (SNode*)pFunc;
    pCxt->errCode = fmGetFuncInfo(pFunc, pCxt->msgBuf.buf, pCxt->msgBuf.len);
  }

  return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
}

2046
static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
2047 2048
  STranslateContext* pCxt = (STranslateContext*)pContext;
  SSelectStmt*       pSelect = (SSelectStmt*)pCxt->pCurrStmt;
wmmhello's avatar
wmmhello 已提交
2049 2050 2051
  if (!nodesIsExprNode(*pNode) || isAliasColumn(*pNode)) {
    return DEAL_RES_CONTINUE;
  }
2052
  if (isVectorFunc(*pNode) && !isDistinctOrderBy(pCxt)) {
wmmhello's avatar
wmmhello 已提交
2053 2054
    return DEAL_RES_IGNORE_CHILD;
  }
2055
  SNode* pGroupNode = NULL;
2056
  FOREACH(pGroupNode, getGroupByList(pCxt)) {
wmmhello's avatar
wmmhello 已提交
2057
    if (nodesEqualNode(getGroupByNode(pGroupNode), *pNode)) {
2058 2059 2060 2061
      return DEAL_RES_IGNORE_CHILD;
    }
  }
  SNode* pPartKey = NULL;
2062
  FOREACH(pPartKey, pSelect->pPartitionByList) {
2063
    if (nodesEqualNode(pPartKey, *pNode)) {
2064
      return rewriteExprToGroupKeyFunc(pCxt, pNode);
wmmhello's avatar
wmmhello 已提交
2065 2066
    }
  }
2067 2068 2069 2070 2071 2072
  if (NULL != pSelect->pWindow && QUERY_NODE_STATE_WINDOW == nodeType(pSelect->pWindow)) {
    if (nodesEqualNode(((SStateWindowNode*)pSelect->pWindow)->pExpr, *pNode)) {
      pSelect->hasStateKey = true;
      return rewriteExprToGroupKeyFunc(pCxt, pNode);
    }
  }
wmmhello's avatar
wmmhello 已提交
2073
  if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
2074 2075
    if (pSelect->selectFuncNum > 1 || pSelect->hasOtherVectorFunc || !pSelect->hasSelectFunc) {
      return generateDealNodeErrMsg(pCxt, getGroupByErrorCode(pCxt));
wmmhello's avatar
wmmhello 已提交
2076
    } else {
2077
      return rewriteColToSelectValFunc(pCxt, pNode);
wmmhello's avatar
wmmhello 已提交
2078 2079
    }
  }
2080 2081
  if (isVectorFunc(*pNode) && isDistinctOrderBy(pCxt)) {
    return generateDealNodeErrMsg(pCxt, getGroupByErrorCode(pCxt));
wmmhello's avatar
wmmhello 已提交
2082 2083
  }
  return DEAL_RES_CONTINUE;
2084 2085
}

2086
static int32_t checkExprForGroupBy(STranslateContext* pCxt, SNode** pNode) {
2087
  nodesRewriteExpr(pNode, doCheckExprForGroupBy, pCxt);
wmmhello's avatar
wmmhello 已提交
2088
  return pCxt->errCode;
2089 2090
}

2091 2092
static int32_t checkExprListForGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect, SNodeList* pList) {
  if (NULL == getGroupByList(pCxt) && NULL == pSelect->pWindow) {
wmmhello's avatar
wmmhello 已提交
2093 2094
    return TSDB_CODE_SUCCESS;
  }
2095
  nodesRewriteExprs(pList, doCheckExprForGroupBy, pCxt);
wmmhello's avatar
wmmhello 已提交
2096
  return pCxt->errCode;
2097 2098 2099
}

static EDealRes rewriteColsToSelectValFuncImpl(SNode** pNode, void* pContext) {
wmmhello's avatar
wmmhello 已提交
2100 2101 2102 2103 2104 2105 2106
  if (isAggFunc(*pNode) || isIndefiniteRowsFunc(*pNode)) {
    return DEAL_RES_IGNORE_CHILD;
  }
  if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
    return rewriteColToSelectValFunc((STranslateContext*)pContext, pNode);
  }
  return DEAL_RES_CONTINUE;
2107 2108 2109
}

static int32_t rewriteColsToSelectValFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
2110 2111 2112 2113 2114
  nodesRewriteExprs(pSelect->pProjectionList, rewriteColsToSelectValFuncImpl, pCxt);
  if (TSDB_CODE_SUCCESS == pCxt->errCode && !pSelect->isDistinct) {
    nodesRewriteExprs(pSelect->pOrderByList, rewriteColsToSelectValFuncImpl, pCxt);
  }
  return pCxt->errCode;
2115 2116
}

2117
typedef struct CheckAggColCoexistCxt {
wmmhello's avatar
wmmhello 已提交
2118 2119
  STranslateContext* pTranslateCxt;
  bool               existCol;
2120 2121
} CheckAggColCoexistCxt;

2122
static EDealRes doCheckAggColCoexist(SNode** pNode, void* pContext) {
wmmhello's avatar
wmmhello 已提交
2123
  CheckAggColCoexistCxt* pCxt = (CheckAggColCoexistCxt*)pContext;
2124
  if (isVectorFunc(*pNode)) {
wmmhello's avatar
wmmhello 已提交
2125 2126
    return DEAL_RES_IGNORE_CHILD;
  }
2127
  SNode* pPartKey = NULL;
2128
  FOREACH(pPartKey, ((SSelectStmt*)pCxt->pTranslateCxt->pCurrStmt)->pPartitionByList) {
2129 2130
    if (nodesEqualNode(pPartKey, *pNode)) {
      return rewriteExprToGroupKeyFunc(pCxt->pTranslateCxt, pNode);
2131 2132
    }
  }
2133
  if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
wmmhello's avatar
wmmhello 已提交
2134 2135 2136
    pCxt->existCol = true;
  }
  return DEAL_RES_CONTINUE;
2137 2138 2139
}

static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
2140
  if (NULL != pSelect->pGroupByList || NULL != pSelect->pWindow ||
2141
      (!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc && !pSelect->hasInterpFunc)) {
wmmhello's avatar
wmmhello 已提交
2142 2143
    return TSDB_CODE_SUCCESS;
  }
2144 2145 2146
  if (!pSelect->onlyHasKeepOrderFunc) {
    pSelect->isTimeLineResult = false;
  }
2147
  CheckAggColCoexistCxt cxt = {.pTranslateCxt = pCxt, .existCol = false};
2148
  nodesRewriteExprs(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
wmmhello's avatar
wmmhello 已提交
2149
  if (!pSelect->isDistinct) {
2150
    nodesRewriteExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
wmmhello's avatar
wmmhello 已提交
2151
  }
2152
  if (1 == pSelect->selectFuncNum && !pSelect->hasOtherVectorFunc) {
wmmhello's avatar
wmmhello 已提交
2153 2154
    return rewriteColsToSelectValFunc(pCxt, pSelect);
  }
2155
  if (cxt.existCol) {
wmmhello's avatar
wmmhello 已提交
2156 2157 2158
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SINGLE_GROUP);
  }
  return TSDB_CODE_SUCCESS;
2159 2160
}

2161 2162 2163 2164
static int32_t checkWindowFuncCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (NULL == pSelect->pWindow) {
    return TSDB_CODE_SUCCESS;
  }
2165
  if (NULL != pSelect->pWindow && !pSelect->hasAggFuncs && !pSelect->hasStateKey) {
2166 2167 2168 2169 2170
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN);
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
2171
static int32_t toVgroupsInfo(SArray* pVgs, SVgroupsInfo** pVgsInfo) {
wmmhello's avatar
wmmhello 已提交
2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182
  size_t vgroupNum = taosArrayGetSize(pVgs);
  *pVgsInfo = taosMemoryCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo) * vgroupNum);
  if (NULL == *pVgsInfo) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  (*pVgsInfo)->numOfVgroups = vgroupNum;
  for (int32_t i = 0; i < vgroupNum; ++i) {
    SVgroupInfo* vg = taosArrayGet(pVgs, i);
    (*pVgsInfo)->vgroups[i] = *vg;
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
2183 2184
}

2185
static int32_t addMnodeToVgroupList(const SEpSet* pEpSet, SArray** pVgroupList) {
wmmhello's avatar
wmmhello 已提交
2186 2187 2188 2189 2190 2191 2192 2193 2194 2195
  if (NULL == *pVgroupList) {
    *pVgroupList = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SVgroupInfo));
    if (NULL == *pVgroupList) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }
  SVgroupInfo vg = {.vgId = MNODE_HANDLE};
  memcpy(&vg.epSet, pEpSet, sizeof(SEpSet));
  taosArrayPush(*pVgroupList, &vg);
  return TSDB_CODE_SUCCESS;
2196 2197
}

2198 2199 2200 2201 2202
static int32_t dnodeToVgroupsInfo(SArray* pDnodes, SVgroupsInfo** pVgsInfo) {
  size_t ndnode = taosArrayGetSize(pDnodes);
  *pVgsInfo = taosMemoryCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo) * ndnode);
  if (NULL == *pVgsInfo) {
    return TSDB_CODE_OUT_OF_MEMORY;
wmmhello's avatar
wmmhello 已提交
2203
  }
2204 2205 2206 2207 2208 2209 2210 2211
  (*pVgsInfo)->numOfVgroups = ndnode;
  for (int32_t i = 0; i < ndnode; ++i) {
    memcpy(&((*pVgsInfo)->vgroups[i].epSet), taosArrayGet(pDnodes, i), sizeof(SEpSet));
  }
  return TSDB_CODE_SUCCESS;
}

static bool sysTableFromVnode(const char* pTable) {
D
dapan1121 已提交
2212
  return (0 == strcmp(pTable, TSDB_INS_TABLE_TABLES)) ||
X
Xiaoyu Wang 已提交
2213
         (0 == strcmp(pTable, TSDB_INS_TABLE_TABLE_DISTRIBUTED) || (0 == strcmp(pTable, TSDB_INS_TABLE_TAGS)));
2214 2215 2216
}

static bool sysTableFromDnode(const char* pTable) { return 0 == strcmp(pTable, TSDB_INS_TABLE_DNODE_VARIABLES); }
wmmhello's avatar
wmmhello 已提交
2217

2218 2219
static int32_t getTagsTableVgroupListImpl(STranslateContext* pCxt, SName* pTargetName, SName* pName,
                                          SArray** pVgroupList) {
2220
  if (0 == pTargetName->type) {
2221 2222 2223 2224
    return getDBVgInfoImpl(pCxt, pName, pVgroupList);
  }

  if (TSDB_DB_NAME_T == pTargetName->type) {
2225
    int32_t code = getDBVgInfoImpl(pCxt, pTargetName, pVgroupList);
2226 2227
    if (TSDB_CODE_MND_DB_NOT_EXIST == code || TSDB_CODE_MND_DB_IN_CREATING == code ||
        TSDB_CODE_MND_DB_IN_DROPPING == code) {
2228 2229 2230
      code = TSDB_CODE_SUCCESS;
    }
    return code;
2231 2232 2233 2234 2235 2236 2237 2238
  }

  SVgroupInfo vgInfo = {0};
  int32_t     code = getTableHashVgroupImpl(pCxt, pTargetName, &vgInfo);
  if (TSDB_CODE_SUCCESS == code) {
    *pVgroupList = taosArrayInit(1, sizeof(SVgroupInfo));
    if (NULL == *pVgroupList) {
      code = TSDB_CODE_OUT_OF_MEMORY;
2239 2240
    } else {
      taosArrayPush(*pVgroupList, &vgInfo);
2241
    }
2242 2243
  } else if (TSDB_CODE_MND_DB_NOT_EXIST == code || TSDB_CODE_MND_DB_IN_CREATING == code ||
             TSDB_CODE_MND_DB_IN_DROPPING == code) {
2244
    code = TSDB_CODE_SUCCESS;
2245 2246 2247 2248 2249 2250 2251 2252 2253 2254
  }
  return code;
}

static int32_t getTagsTableVgroupList(STranslateContext* pCxt, SName* pName, SArray** pVgroupList) {
  if (!isSelectStmt(pCxt->pCurrStmt)) {
    return TSDB_CODE_SUCCESS;
  }
  SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
  SName        targetName = {0};
2255
  int32_t      code = getInsTagsTableTargetName(pCxt->pParseCxt->acctId, pSelect->pWhere, &targetName);
2256 2257 2258 2259 2260 2261
  if (TSDB_CODE_SUCCESS == code) {
    code = getTagsTableVgroupListImpl(pCxt, &targetName, pName, pVgroupList);
  }
  return code;
}

2262
static int32_t setVnodeSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) {
wmmhello's avatar
wmmhello 已提交
2263 2264
  int32_t code = TSDB_CODE_SUCCESS;
  SArray* vgroupList = NULL;
2265 2266 2267
  if (0 == strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_TAGS)) {
    code = getTagsTableVgroupList(pCxt, pName, &vgroupList);
  } else if ('\0' != pRealTable->qualDbName[0]) {
wmmhello's avatar
wmmhello 已提交
2268 2269 2270 2271 2272 2273 2274
    if (0 != strcmp(pRealTable->qualDbName, TSDB_INFORMATION_SCHEMA_DB)) {
      code = getDBVgInfo(pCxt, pRealTable->qualDbName, &vgroupList);
    }
  } else {
    code = getDBVgInfoImpl(pCxt, pName, &vgroupList);
  }

2275 2276
  if (TSDB_CODE_SUCCESS == code && 0 == strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_TAGS) &&
      isSelectStmt(pCxt->pCurrStmt) && 0 == taosArrayGetSize(vgroupList)) {
2277 2278 2279
    ((SSelectStmt*)pCxt->pCurrStmt)->isEmptyResult = true;
  }

2280
  if (TSDB_CODE_SUCCESS == code && 0 == strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_TABLES)) {
wmmhello's avatar
wmmhello 已提交
2281 2282 2283 2284 2285 2286 2287 2288 2289
    code = addMnodeToVgroupList(&pCxt->pParseCxt->mgmtEpSet, &vgroupList);
  }

  if (TSDB_CODE_SUCCESS == code) {
    code = toVgroupsInfo(vgroupList, &pRealTable->pVgroupList);
  }
  taosArrayDestroy(vgroupList);

  return code;
X
Xiaoyu Wang 已提交
2290 2291
}

2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311
static int32_t setDnodeSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) {
  SArray* pDnodes = NULL;
  int32_t code = getDnodeList(pCxt, &pDnodes);
  if (TSDB_CODE_SUCCESS == code) {
    code = dnodeToVgroupsInfo(pDnodes, &pRealTable->pVgroupList);
  }
  taosArrayDestroy(pDnodes);
  return code;
}

static int32_t setSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) {
  if (sysTableFromVnode(pRealTable->table.tableName)) {
    return setVnodeSysTableVgroupList(pCxt, pName, pRealTable);
  } else if (sysTableFromDnode(pRealTable->table.tableName)) {
    return setDnodeSysTableVgroupList(pCxt, pName, pRealTable);
  } else {
    return TSDB_CODE_SUCCESS;
  }
}

X
Xiaoyu Wang 已提交
2312
static int32_t setTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) {
wmmhello's avatar
wmmhello 已提交
2313 2314 2315 2316 2317 2318 2319
  if (pCxt->pParseCxt->topicQuery) {
    return TSDB_CODE_SUCCESS;
  }

  int32_t code = TSDB_CODE_SUCCESS;
  if (TSDB_SUPER_TABLE == pRealTable->pMeta->tableType) {
    SArray* vgroupList = NULL;
2320
    code = getDBVgInfoImpl(pCxt, pName, &vgroupList);
wmmhello's avatar
wmmhello 已提交
2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335
    if (TSDB_CODE_SUCCESS == code) {
      code = toVgroupsInfo(vgroupList, &pRealTable->pVgroupList);
    }
    taosArrayDestroy(vgroupList);
  } else if (TSDB_SYSTEM_TABLE == pRealTable->pMeta->tableType) {
    code = setSysTableVgroupList(pCxt, pName, pRealTable);
  } else {
    pRealTable->pVgroupList = taosMemoryCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo));
    if (NULL == pRealTable->pVgroupList) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
    pRealTable->pVgroupList->numOfVgroups = 1;
    code = getTableHashVgroupImpl(pCxt, pName, pRealTable->pVgroupList->vgroups);
  }
  return code;
2336 2337
}

X
Xiaoyu Wang 已提交
2338
static uint8_t getStmtPrecision(SNode* pStmt) {
wmmhello's avatar
wmmhello 已提交
2339 2340
  if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
    return ((SSelectStmt*)pStmt)->precision;
X
Xiaoyu Wang 已提交
2341 2342
  } else if (QUERY_NODE_SET_OPERATOR == nodeType(pStmt)) {
    return ((SSetOperator*)pStmt)->precision;
wmmhello's avatar
wmmhello 已提交
2343 2344
  }
  return 0;
X
Xiaoyu Wang 已提交
2345 2346
}

X
Xiaoyu Wang 已提交
2347 2348
static bool stmtIsSingleTable(SNode* pStmt) {
  if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
2349 2350
    SSelectStmt* pSelect = (SSelectStmt*)pStmt;
    return NULL == pSelect->pFromTable || ((STableNode*)pSelect->pFromTable)->singleTable;
X
Xiaoyu Wang 已提交
2351 2352 2353 2354
  }
  return false;
}

X
Xiaoyu Wang 已提交
2355 2356 2357 2358
static uint8_t calcPrecision(uint8_t lp, uint8_t rp) { return (lp > rp ? rp : lp); }

static uint8_t calcJoinTablePrecision(SJoinTableNode* pJoinTable) {
  return calcPrecision(((STableNode*)pJoinTable->pLeft)->precision, ((STableNode*)pJoinTable->pRight)->precision);
X
Xiaoyu Wang 已提交
2359 2360
}

X
Xiaoyu Wang 已提交
2361 2362 2363 2364 2365 2366 2367
static bool joinTableIsSingleTable(SJoinTableNode* pJoinTable) {
  return (((STableNode*)pJoinTable->pLeft)->singleTable && ((STableNode*)pJoinTable->pRight)->singleTable);
}

static bool isSingleTable(SRealTableNode* pRealTable) {
  int8_t tableType = pRealTable->pMeta->tableType;
  if (TSDB_SYSTEM_TABLE == tableType) {
D
dapan1121 已提交
2368 2369 2370
    return 0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_TABLES) &&
           0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_TABLE_DISTRIBUTED) &&
           0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_TAGS);
X
Xiaoyu Wang 已提交
2371 2372 2373 2374
  }
  return (TSDB_CHILD_TABLE == tableType || TSDB_NORMAL_TABLE == tableType);
}

X
Xiaoyu Wang 已提交
2375
static int32_t setTableIndex(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) {
X
Xiaoyu Wang 已提交
2376
  if (pCxt->createStream || QUERY_SMA_OPTIMIZE_DISABLE == tsQuerySmaOptimize) {
X
Xiaoyu Wang 已提交
2377 2378
    return TSDB_CODE_SUCCESS;
  }
2379 2380
  if (isSelectStmt(pCxt->pCurrStmt) && NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pWindow &&
      QUERY_NODE_INTERVAL_WINDOW == nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pWindow)) {
X
Xiaoyu Wang 已提交
2381 2382 2383 2384 2385
    return getTableIndex(pCxt, pName, &pRealTable->pSmaIndexes);
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
2386
static int32_t setTableCacheLastMode(STranslateContext* pCxt, SSelectStmt* pSelect) {
2387 2388
  if ((!pSelect->hasLastRowFunc && !pSelect->hasLastFunc) || QUERY_NODE_REAL_TABLE != nodeType(pSelect->pFromTable) ||
      TSDB_SYSTEM_TABLE == ((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType) {
2389 2390 2391
    return TSDB_CODE_SUCCESS;
  }

X
Xiaoyu Wang 已提交
2392 2393 2394
  SRealTableNode* pTable = (SRealTableNode*)pSelect->pFromTable;
  SDbCfgInfo      dbCfg = {0};
  int32_t         code = getDBCfg(pCxt, pTable->table.dbName, &dbCfg);
2395
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
2396
    pTable->cacheLastMode = dbCfg.cacheLast;
2397 2398 2399 2400
  }
  return code;
}

X
Xiaoyu Wang 已提交
2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411
static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTable) {
  if ((QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pLeft) &&
       !isTimeLineQuery(((STempTableNode*)pJoinTable->pLeft)->pSubquery)) ||
      (QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pRight) &&
       !isTimeLineQuery(((STempTableNode*)pJoinTable->pRight)->pSubquery))) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
                                   "Join requires valid time series input");
  }
  return TSDB_CODE_SUCCESS;
}

2412
static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) {
wmmhello's avatar
wmmhello 已提交
2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424
  int32_t code = TSDB_CODE_SUCCESS;
  switch (nodeType(pTable)) {
    case QUERY_NODE_REAL_TABLE: {
      SRealTableNode* pRealTable = (SRealTableNode*)pTable;
      pRealTable->ratio = (NULL != pCxt->pExplainOpt ? pCxt->pExplainOpt->ratio : 1.0);
      // The SRealTableNode created through ROLLUP already has STableMeta.
      if (NULL == pRealTable->pMeta) {
        SName name;
        code = getTableMetaImpl(
            pCxt, toName(pCxt->pParseCxt->acctId, pRealTable->table.dbName, pRealTable->table.tableName, &name),
            &(pRealTable->pMeta));
        if (TSDB_CODE_SUCCESS != code) {
2425
          return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GET_META_ERROR, tstrerror(code));
wmmhello's avatar
wmmhello 已提交
2426 2427
        }
        code = setTableVgroupList(pCxt, &name, pRealTable);
X
Xiaoyu Wang 已提交
2428
        if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
2429
          code = setTableIndex(pCxt, &name, pRealTable);
X
Xiaoyu Wang 已提交
2430
        }
wmmhello's avatar
wmmhello 已提交
2431 2432
      }
      if (TSDB_CODE_SUCCESS == code) {
2433 2434 2435 2436 2437
        pRealTable->table.precision = pRealTable->pMeta->tableInfo.precision;
        pRealTable->table.singleTable = isSingleTable(pRealTable);
        if (TSDB_SUPER_TABLE == pRealTable->pMeta->tableType) {
          pCxt->stableQuery = true;
        }
X
Xiaoyu Wang 已提交
2438 2439 2440
        if (TSDB_SYSTEM_TABLE == pRealTable->pMeta->tableType && isSelectStmt(pCxt->pCurrStmt)) {
          ((SSelectStmt*)pCxt->pCurrStmt)->isTimeLineResult = false;
        }
wmmhello's avatar
wmmhello 已提交
2441 2442 2443 2444 2445 2446 2447 2448 2449
        code = addNamespace(pCxt, pRealTable);
      }
      break;
    }
    case QUERY_NODE_TEMP_TABLE: {
      STempTableNode* pTempTable = (STempTableNode*)pTable;
      code = translateSubquery(pCxt, pTempTable->pSubquery);
      if (TSDB_CODE_SUCCESS == code) {
        pTempTable->table.precision = getStmtPrecision(pTempTable->pSubquery);
X
Xiaoyu Wang 已提交
2450
        pTempTable->table.singleTable = stmtIsSingleTable(pTempTable->pSubquery);
wmmhello's avatar
wmmhello 已提交
2451 2452 2453 2454 2455 2456 2457 2458 2459 2460
        code = addNamespace(pCxt, pTempTable);
      }
      break;
    }
    case QUERY_NODE_JOIN_TABLE: {
      SJoinTableNode* pJoinTable = (SJoinTableNode*)pTable;
      code = translateTable(pCxt, pJoinTable->pLeft);
      if (TSDB_CODE_SUCCESS == code) {
        code = translateTable(pCxt, pJoinTable->pRight);
      }
X
Xiaoyu Wang 已提交
2461 2462 2463
      if (TSDB_CODE_SUCCESS == code) {
        code = checkJoinTable(pCxt, pJoinTable);
      }
wmmhello's avatar
wmmhello 已提交
2464
      if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
2465
        pJoinTable->table.precision = calcJoinTablePrecision(pJoinTable);
X
Xiaoyu Wang 已提交
2466 2467
        pJoinTable->table.singleTable = joinTableIsSingleTable(pJoinTable);
        code = translateExpr(pCxt, &pJoinTable->pOnCond);
wmmhello's avatar
wmmhello 已提交
2468 2469 2470 2471 2472 2473 2474
      }
      break;
    }
    default:
      break;
  }
  return code;
2475 2476
}

2477
static int32_t createAllColumns(STranslateContext* pCxt, bool igTags, SNodeList** pCols) {
wmmhello's avatar
wmmhello 已提交
2478 2479 2480 2481 2482 2483 2484 2485
  *pCols = nodesMakeList();
  if (NULL == *pCols) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
  }
  SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
  size_t  nums = taosArrayGetSize(pTables);
  for (size_t i = 0; i < nums; ++i) {
    STableNode* pTable = taosArrayGetP(pTables, i);
2486
    int32_t     code = createColumnsByTable(pCxt, pTable, igTags, *pCols);
wmmhello's avatar
wmmhello 已提交
2487 2488 2489 2490 2491
    if (TSDB_CODE_SUCCESS != code) {
      return code;
    }
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
2492 2493
}

2494
static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) {
2495
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
wmmhello's avatar
wmmhello 已提交
2496 2497 2498 2499 2500
  if (NULL == pFunc) {
    return NULL;
  }
  pFunc->pParameterList = nodesMakeList();
  if (NULL == pFunc->pParameterList ||
2501 2502
      TSDB_CODE_SUCCESS != nodesListStrictAppend(pFunc->pParameterList, nodesCloneNode((SNode*)pExpr))) {
    nodesDestroyNode((SNode*)pFunc);
wmmhello's avatar
wmmhello 已提交
2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514
    return NULL;
  }

  pFunc->node.resType = pExpr->resType;
  pFunc->funcId = pSrcFunc->funcId;
  pFunc->funcType = pSrcFunc->funcType;
  strcpy(pFunc->functionName, pSrcFunc->functionName);
  char    buf[TSDB_FUNC_NAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN];
  int32_t len = 0;
  if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
    SColumnNode* pCol = (SColumnNode*)pExpr;
    len = snprintf(buf, sizeof(buf), "%s(%s.%s)", pSrcFunc->functionName, pCol->tableAlias, pCol->colName);
X
Xiaoyu Wang 已提交
2515
    strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1));
2516 2517 2518 2519 2520 2521
    if (tsKeepColumnName) {
      strcpy(pFunc->node.userAlias, pCol->colName);
    } else {
      len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pCol->colName);
      strncpy(pFunc->node.userAlias, buf, TMIN(len, sizeof(pFunc->node.userAlias) - 1));
    }
wmmhello's avatar
wmmhello 已提交
2522 2523
  } else {
    len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pExpr->aliasName);
X
Xiaoyu Wang 已提交
2524 2525
    strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1));
    strncpy(pFunc->node.userAlias, buf, TMIN(len, sizeof(pFunc->node.userAlias) - 1));
wmmhello's avatar
wmmhello 已提交
2526 2527 2528
  }

  return (SNode*)pFunc;
2529 2530
}

2531
static int32_t createTableAllCols(STranslateContext* pCxt, SColumnNode* pCol, bool igTags, SNodeList** pOutput) {
wmmhello's avatar
wmmhello 已提交
2532 2533 2534 2535 2536 2537 2538 2539 2540
  STableNode* pTable = NULL;
  int32_t     code = findTable(pCxt, pCol->tableAlias, &pTable);
  if (TSDB_CODE_SUCCESS == code && NULL == *pOutput) {
    *pOutput = nodesMakeList();
    if (NULL == *pOutput) {
      code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
    }
  }
  if (TSDB_CODE_SUCCESS == code) {
2541
    code = createColumnsByTable(pCxt, pTable, igTags, *pOutput);
wmmhello's avatar
wmmhello 已提交
2542 2543
  }
  return code;
2544 2545
}

2546
static int32_t createMultiResFuncsParas(STranslateContext* pCxt, SNodeList* pSrcParas, SNodeList** pOutput) {
wmmhello's avatar
wmmhello 已提交
2547 2548 2549 2550 2551 2552
  int32_t code = TSDB_CODE_SUCCESS;

  SNodeList* pExprs = NULL;
  SNode*     pPara = NULL;
  FOREACH(pPara, pSrcParas) {
    if (isStar(pPara)) {
2553
      code = createAllColumns(pCxt, true, &pExprs);
wmmhello's avatar
wmmhello 已提交
2554
    } else if (isTableStar(pPara)) {
2555
      code = createTableAllCols(pCxt, (SColumnNode*)pPara, true, &pExprs);
wmmhello's avatar
wmmhello 已提交
2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570
    } else {
      code = nodesListMakeStrictAppend(&pExprs, nodesCloneNode(pPara));
    }
    if (TSDB_CODE_SUCCESS != code) {
      break;
    }
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pOutput = pExprs;
  } else {
    nodesDestroyList(pExprs);
  }

  return code;
2571 2572 2573
}

static int32_t createMultiResFuncs(SFunctionNode* pSrcFunc, SNodeList* pExprs, SNodeList** pOutput) {
wmmhello's avatar
wmmhello 已提交
2574 2575 2576 2577
  SNodeList* pFuncs = nodesMakeList();
  if (NULL == pFuncs) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
2578

wmmhello's avatar
wmmhello 已提交
2579 2580 2581 2582 2583 2584 2585 2586
  int32_t code = TSDB_CODE_SUCCESS;
  SNode*  pExpr = NULL;
  FOREACH(pExpr, pExprs) {
    code = nodesListStrictAppend(pFuncs, createMultiResFunc(pSrcFunc, (SExprNode*)pExpr));
    if (TSDB_CODE_SUCCESS != code) {
      break;
    }
  }
2587

wmmhello's avatar
wmmhello 已提交
2588 2589 2590 2591 2592
  if (TSDB_CODE_SUCCESS == code) {
    *pOutput = pFuncs;
  } else {
    nodesDestroyList(pFuncs);
  }
2593

wmmhello's avatar
wmmhello 已提交
2594
  return code;
2595 2596 2597
}

static int32_t createMultiResFuncsFromStar(STranslateContext* pCxt, SFunctionNode* pSrcFunc, SNodeList** pOutput) {
wmmhello's avatar
wmmhello 已提交
2598 2599 2600 2601 2602
  SNodeList* pExprs = NULL;
  int32_t    code = createMultiResFuncsParas(pCxt, pSrcFunc->pParameterList, &pExprs);
  if (TSDB_CODE_SUCCESS == code) {
    code = createMultiResFuncs(pSrcFunc, pExprs, pOutput);
  }
2603

X
Xiaoyu Wang 已提交
2604
  nodesDestroyList(pExprs);
wmmhello's avatar
wmmhello 已提交
2605
  return code;
2606 2607
}

2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635
static int32_t createTags(STranslateContext* pCxt, SNodeList** pOutput) {
  if (QUERY_NODE_REAL_TABLE != nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_PC,
                                   "The _TAGS pseudo column can only be used for subtable and supertable queries");
  }

  SRealTableNode*   pTable = (SRealTableNode*)(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable);
  const STableMeta* pMeta = pTable->pMeta;
  if (TSDB_SUPER_TABLE != pMeta->tableType && TSDB_CHILD_TABLE != pMeta->tableType) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_PC,
                                "The _TAGS pseudo column can only be used for subtable and supertable queries");
  }

  SSchema* pTagsSchema = getTableTagSchema(pMeta);
  for (int32_t i = 0; i < pMeta->tableInfo.numOfTags; ++i) {
    SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
    if (NULL == pCol) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
    }
    setColumnInfoBySchema(pTable, pTagsSchema + i, 1, pCol);
    if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(pOutput, (SNode*)pCol)) {
      NODES_DESTORY_LIST(*pOutput);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
2636
static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect) {
X
Xiaoyu Wang 已提交
2637 2638 2639 2640 2641
  SNode* pNode = NULL;
  WHERE_EACH(pNode, pSelect->pProjectionList) {
    int32_t code = TSDB_CODE_SUCCESS;
    if (isStar(pNode)) {
      SNodeList* pCols = NULL;
2642
      code = createAllColumns(pCxt, false, &pCols);
X
Xiaoyu Wang 已提交
2643 2644 2645 2646
      if (TSDB_CODE_SUCCESS == code) {
        INSERT_LIST(pSelect->pProjectionList, pCols);
        ERASE_NODE(pSelect->pProjectionList);
        continue;
wmmhello's avatar
wmmhello 已提交
2647
      }
X
Xiaoyu Wang 已提交
2648
    } else if (isMultiResFunc(pNode)) {
2649 2650 2651 2652 2653 2654
      SNodeList* pNodeList = NULL;
      if (FUNCTION_TYPE_TAGS == ((SFunctionNode*)pNode)->funcType) {
        code = createTags(pCxt, &pNodeList);
      } else {
        code = createMultiResFuncsFromStar(pCxt, (SFunctionNode*)pNode, &pNodeList);
      }
X
Xiaoyu Wang 已提交
2655
      if (TSDB_CODE_SUCCESS == code) {
2656
        INSERT_LIST(pSelect->pProjectionList, pNodeList);
X
Xiaoyu Wang 已提交
2657 2658 2659 2660 2661
        ERASE_NODE(pSelect->pProjectionList);
        continue;
      }
    } else if (isTableStar(pNode)) {
      SNodeList* pCols = NULL;
2662
      code = createTableAllCols(pCxt, (SColumnNode*)pNode, false, &pCols);
X
Xiaoyu Wang 已提交
2663 2664 2665 2666
      if (TSDB_CODE_SUCCESS == code) {
        INSERT_LIST(pSelect->pProjectionList, pCols);
        ERASE_NODE(pSelect->pProjectionList);
        continue;
wmmhello's avatar
wmmhello 已提交
2667 2668
      }
    }
X
Xiaoyu Wang 已提交
2669 2670 2671 2672
    if (TSDB_CODE_SUCCESS != code) {
      return code;
    }
    WHERE_NEXT;
wmmhello's avatar
wmmhello 已提交
2673 2674
  }
  return TSDB_CODE_SUCCESS;
2675 2676
}

2677
static int32_t getPositionValue(const SValueNode* pVal) {
wmmhello's avatar
wmmhello 已提交
2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704
  switch (pVal->node.resType.type) {
    case TSDB_DATA_TYPE_NULL:
    case TSDB_DATA_TYPE_TIMESTAMP:
    case TSDB_DATA_TYPE_NCHAR:
    case TSDB_DATA_TYPE_VARCHAR:
    case TSDB_DATA_TYPE_VARBINARY:
    case TSDB_DATA_TYPE_JSON:
      return -1;
    case TSDB_DATA_TYPE_BOOL:
      return (pVal->datum.b ? 1 : 0);
    case TSDB_DATA_TYPE_TINYINT:
    case TSDB_DATA_TYPE_SMALLINT:
    case TSDB_DATA_TYPE_INT:
    case TSDB_DATA_TYPE_BIGINT:
      return pVal->datum.i;
    case TSDB_DATA_TYPE_FLOAT:
    case TSDB_DATA_TYPE_DOUBLE:
      return pVal->datum.d;
    case TSDB_DATA_TYPE_UTINYINT:
    case TSDB_DATA_TYPE_USMALLINT:
    case TSDB_DATA_TYPE_UINT:
    case TSDB_DATA_TYPE_UBIGINT:
      return pVal->datum.u;
    default:
      break;
  }
  return -1;
2705 2706
}

dengyihao's avatar
dengyihao 已提交
2707
static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList,
wmmhello's avatar
wmmhello 已提交
2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724
                                        bool* pOther) {
  *pOther = false;
  SNode* pNode = NULL;
  WHERE_EACH(pNode, pOrderByList) {
    SNode* pExpr = ((SOrderByExprNode*)pNode)->pExpr;
    if (QUERY_NODE_VALUE == nodeType(pExpr)) {
      SValueNode* pVal = (SValueNode*)pExpr;
      if (DEAL_RES_ERROR == translateValue(pCxt, pVal)) {
        return pCxt->errCode;
      }
      int32_t pos = getPositionValue(pVal);
      if (pos < 0) {
        ERASE_NODE(pOrderByList);
        continue;
      } else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) {
        return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
      } else {
2725
        SColumnRefNode* pCol = (SColumnRefNode*)nodesMakeNode(QUERY_NODE_COLUMN_REF);
wmmhello's avatar
wmmhello 已提交
2726 2727 2728
        if (NULL == pCol) {
          return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
        }
2729
        strcpy(pCol->colName, ((SExprNode*)nodesListGetNode(pProjectionList, pos - 1))->aliasName);
wmmhello's avatar
wmmhello 已提交
2730 2731 2732 2733 2734 2735 2736 2737 2738
        ((SOrderByExprNode*)pNode)->pExpr = (SNode*)pCol;
        nodesDestroyNode(pExpr);
      }
    } else {
      *pOther = true;
    }
    WHERE_NEXT;
  }
  return TSDB_CODE_SUCCESS;
2739 2740
}

2741
static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
2742 2743 2744
  bool    other;
  int32_t code = translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other);
  if (TSDB_CODE_SUCCESS == code) {
2745 2746 2747 2748 2749
    if (!other) {
      return TSDB_CODE_SUCCESS;
    }
    pCxt->currClause = SQL_CLAUSE_ORDER_BY;
    code = translateExprList(pCxt, pSelect->pOrderByList);
2750 2751 2752
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pOrderByList);
wmmhello's avatar
wmmhello 已提交
2753 2754
  }
  return code;
2755 2756
}

X
Xiaoyu Wang 已提交
2757
static EDealRes needFillImpl(SNode* pNode, void* pContext) {
X
Xiaoyu Wang 已提交
2758
  if (isAggFunc(pNode) && FUNCTION_TYPE_GROUP_KEY != ((SFunctionNode*)pNode)->funcType) {
X
Xiaoyu Wang 已提交
2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770
    *(bool*)pContext = true;
    return DEAL_RES_END;
  }
  return DEAL_RES_CONTINUE;
}

static bool needFill(SNode* pNode) {
  bool hasFillFunc = false;
  nodesWalkExpr(pNode, needFillImpl, &hasFillFunc);
  return hasFillFunc;
}

2771 2772 2773 2774
static int32_t convertFillValue(STranslateContext* pCxt, SDataType dt, SNodeList* pValues, int32_t index) {
  SListCell* pCell = nodesListGetCell(pValues, index);
  if (dataTypeEqual(&dt, &((SExprNode*)pCell->pNode)->resType)) {
    return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
2775
  }
2776 2777 2778
  SNode*  pCaseFunc = NULL;
  int32_t code = createCastFunc(pCxt, pCell->pNode, dt, &pCaseFunc);
  if (TSDB_CODE_SUCCESS == code) {
2779
    code = scalarCalculateConstants(pCaseFunc, &pCell->pNode);
X
Xiaoyu Wang 已提交
2780
  }
2781
  return code;
X
Xiaoyu Wang 已提交
2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796
}

static int32_t checkFillValues(STranslateContext* pCxt, SFillNode* pFill, SNodeList* pProjectionList) {
  if (FILL_MODE_VALUE != pFill->mode) {
    return TSDB_CODE_SUCCESS;
  }

  int32_t        fillNo = 0;
  SNodeListNode* pFillValues = (SNodeListNode*)pFill->pValues;
  SNode*         pProject = NULL;
  FOREACH(pProject, pProjectionList) {
    if (needFill(pProject)) {
      if (fillNo >= LIST_LENGTH(pFillValues->pNodeList)) {
        return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled values number mismatch");
      }
2797 2798
      if (TSDB_CODE_SUCCESS !=
          convertFillValue(pCxt, ((SExprNode*)pProject)->resType, pFillValues->pNodeList, fillNo)) {
X
Xiaoyu Wang 已提交
2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809
        return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled data type mismatch");
      }
      ++fillNo;
    }
  }
  if (fillNo != LIST_LENGTH(pFillValues->pNodeList)) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled values number mismatch");
  }
  return TSDB_CODE_SUCCESS;
}

2810 2811 2812 2813 2814
static int32_t translateFillValues(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow) ||
      NULL == ((SIntervalWindowNode*)pSelect->pWindow)->pFill) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
2815
  return checkFillValues(pCxt, (SFillNode*)((SIntervalWindowNode*)pSelect->pWindow)->pFill, pSelect->pProjectionList);
2816 2817
}

X
Xiaoyu Wang 已提交
2818 2819 2820
static int32_t rewriteProjectAlias(SNodeList* pProjectionList) {
  int32_t no = 1;
  SNode*  pProject = NULL;
X
Xiaoyu Wang 已提交
2821 2822 2823 2824 2825 2826 2827
  FOREACH(pProject, pProjectionList) {
    SExprNode* pExpr = (SExprNode*)pProject;
    if ('\0' == pExpr->userAlias[0]) {
      strcpy(pExpr->userAlias, pExpr->aliasName);
    }
    sprintf(pExpr->aliasName, "#expr_%d", no++);
  }
X
Xiaoyu Wang 已提交
2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853
  return TSDB_CODE_SUCCESS;
}

static int32_t checkProjectAlias(STranslateContext* pCxt, SNodeList* pProjectionList) {
  SHashObj* pUserAliasSet = taosHashInit(LIST_LENGTH(pProjectionList),
                                         taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
  SNode*    pProject = NULL;
  FOREACH(pProject, pProjectionList) {
    SExprNode* pExpr = (SExprNode*)pProject;
    if (NULL != taosHashGet(pUserAliasSet, pExpr->userAlias, strlen(pExpr->userAlias))) {
      taosHashCleanup(pUserAliasSet);
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AMBIGUOUS_COLUMN, pExpr->userAlias);
    }
    taosHashPut(pUserAliasSet, pExpr->userAlias, strlen(pExpr->userAlias), &pExpr, POINTER_BYTES);
  }
  taosHashCleanup(pUserAliasSet);
  return TSDB_CODE_SUCCESS;
}

static int32_t translateProjectionList(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (pSelect->isSubquery) {
    return checkProjectAlias(pCxt, pSelect->pProjectionList);
  }
  return rewriteProjectAlias(pSelect->pProjectionList);
}

2854
static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
2855 2856 2857 2858 2859
  pCxt->currClause = SQL_CLAUSE_SELECT;
  int32_t code = translateExprList(pCxt, pSelect->pProjectionList);
  if (TSDB_CODE_SUCCESS == code) {
    code = translateStar(pCxt, pSelect);
  }
X
Xiaoyu Wang 已提交
2860 2861 2862
  if (TSDB_CODE_SUCCESS == code) {
    code = translateProjectionList(pCxt, pSelect);
  }
wmmhello's avatar
wmmhello 已提交
2863
  if (TSDB_CODE_SUCCESS == code) {
2864
    code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pProjectionList);
wmmhello's avatar
wmmhello 已提交
2865
  }
2866 2867 2868
  if (TSDB_CODE_SUCCESS == code) {
    code = translateFillValues(pCxt, pSelect);
  }
wmmhello's avatar
wmmhello 已提交
2869
  return code;
2870 2871
}

2872
static int32_t translateHaving(STranslateContext* pCxt, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
2873 2874 2875 2876
  if (NULL == pSelect->pGroupByList && NULL != pSelect->pHaving) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
  }
  pCxt->currClause = SQL_CLAUSE_HAVING;
X
Xiaoyu Wang 已提交
2877
  int32_t code = translateExpr(pCxt, &pSelect->pHaving);
wmmhello's avatar
wmmhello 已提交
2878 2879 2880 2881
  if (TSDB_CODE_SUCCESS == code) {
    code = checkExprForGroupBy(pCxt, &pSelect->pHaving);
  }
  return code;
2882 2883
}

X
Xiaoyu Wang 已提交
2884
static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
2885 2886
  if (NULL == pSelect->pGroupByList) {
    return TSDB_CODE_SUCCESS;
wmmhello's avatar
wmmhello 已提交
2887
  }
2888 2889
  if (NULL != pSelect->pWindow) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_WINDOW_COEXIST);
wmmhello's avatar
wmmhello 已提交
2890
  }
2891 2892 2893
  pCxt->currClause = SQL_CLAUSE_GROUP_BY;
  pSelect->isTimeLineResult = false;
  return translateExprList(pCxt, pSelect->pGroupByList);
2894 2895
}

X
Xiaoyu Wang 已提交
2896 2897 2898 2899 2900 2901
static int32_t getTimeRange(SNode** pPrimaryKeyCond, STimeWindow* pTimeRange, bool* pIsStrict) {
  SNode*  pNew = NULL;
  int32_t code = scalarCalculateConstants(*pPrimaryKeyCond, &pNew);
  if (TSDB_CODE_SUCCESS == code) {
    *pPrimaryKeyCond = pNew;
    code = filterGetTimeRange(*pPrimaryKeyCond, pTimeRange, pIsStrict);
wmmhello's avatar
wmmhello 已提交
2902 2903 2904
  }
  return code;
}
X
Xiaoyu Wang 已提交
2905

2906
static int32_t getQueryTimeRange(STranslateContext* pCxt, SNode* pWhere, STimeWindow* pTimeRange) {
wmmhello's avatar
wmmhello 已提交
2907 2908 2909 2910
  if (NULL == pWhere) {
    *pTimeRange = TSWINDOW_INITIALIZER;
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
2911

X
Xiaoyu Wang 已提交
2912 2913 2914
  SNode* pCond = nodesCloneNode(pWhere);
  if (NULL == pCond) {
    return TSDB_CODE_OUT_OF_MEMORY;
wmmhello's avatar
wmmhello 已提交
2915
  }
X
Xiaoyu Wang 已提交
2916

X
Xiaoyu Wang 已提交
2917
  SNode* pPrimaryKeyCond = NULL;
X
Xiaoyu Wang 已提交
2918
  filterPartitionCond(&pCond, &pPrimaryKeyCond, NULL, NULL, NULL);
X
Xiaoyu Wang 已提交
2919 2920 2921

  int32_t code = TSDB_CODE_SUCCESS;
  if (NULL != pPrimaryKeyCond) {
wmmhello's avatar
wmmhello 已提交
2922
    bool isStrict = false;
X
Xiaoyu Wang 已提交
2923
    code = getTimeRange(&pPrimaryKeyCond, pTimeRange, &isStrict);
wmmhello's avatar
wmmhello 已提交
2924 2925 2926
  } else {
    *pTimeRange = TSWINDOW_INITIALIZER;
  }
X
Xiaoyu Wang 已提交
2927 2928 2929
  nodesDestroyNode(pCond);
  nodesDestroyNode(pPrimaryKeyCond);
  return code;
X
Xiaoyu Wang 已提交
2930 2931
}

2932
static int32_t checkFill(STranslateContext* pCxt, SFillNode* pFill, SValueNode* pInterval, bool isInterpFill) {
X
Xiaoyu Wang 已提交
2933
  if (FILL_MODE_NONE == pFill->mode) {
2934 2935 2936 2937
    if (isInterpFill) {
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Unsupported fill type");
    }

X
Xiaoyu Wang 已提交
2938 2939 2940
    return TSDB_CODE_SUCCESS;
  }

X
Xiaoyu Wang 已提交
2941 2942
  if (!pCxt->createStream && (TSWINDOW_IS_EQUAL(pFill->timeRange, TSWINDOW_INITIALIZER) ||
                              TSWINDOW_IS_EQUAL(pFill->timeRange, TSWINDOW_DESC_INITIALIZER))) {
wmmhello's avatar
wmmhello 已提交
2943 2944 2945
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
  }

X
Xiaoyu Wang 已提交
2946 2947 2948 2949 2950 2951 2952 2953
  // interp FILL clause
  if (NULL == pInterval) {
    return TSDB_CODE_SUCCESS;
  }

  int64_t timeRange = TABS(pFill->timeRange.skey - pFill->timeRange.ekey);
  int64_t intervalRange = 0;
  if (TIME_IS_VAR_DURATION(pInterval->unit)) {
wmmhello's avatar
wmmhello 已提交
2954
    int64_t f = 1;
X
Xiaoyu Wang 已提交
2955
    if (pInterval->unit == 'n') {
wafwerar's avatar
wafwerar 已提交
2956
      f = 30LL * MILLISECOND_PER_DAY;
X
Xiaoyu Wang 已提交
2957
    } else if (pInterval->unit == 'y') {
wafwerar's avatar
wafwerar 已提交
2958
      f = 365LL * MILLISECOND_PER_DAY;
wmmhello's avatar
wmmhello 已提交
2959
    }
X
Xiaoyu Wang 已提交
2960
    intervalRange = pInterval->datum.i * f;
wmmhello's avatar
wmmhello 已提交
2961
  } else {
X
Xiaoyu Wang 已提交
2962
    intervalRange = pInterval->datum.i;
wmmhello's avatar
wmmhello 已提交
2963
  }
2964

wmmhello's avatar
wmmhello 已提交
2965 2966 2967 2968 2969
  if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
  }

  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
2970 2971
}

2972
static int32_t translateFill(STranslateContext* pCxt, SSelectStmt* pSelect, SIntervalWindowNode* pInterval) {
wmmhello's avatar
wmmhello 已提交
2973 2974 2975
  if (NULL == pInterval->pFill) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
2976

2977
  ((SFillNode*)pInterval->pFill)->timeRange = pSelect->timeRange;
2978
  return checkFill(pCxt, (SFillNode*)pInterval->pFill, (SValueNode*)pInterval->pInterval, false);
X
Xiaoyu Wang 已提交
2979 2980
}

X
Xiaoyu Wang 已提交
2981
static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char unit) {
wmmhello's avatar
wmmhello 已提交
2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
  int64_t days = convertTimeFromPrecisionToUnit(val, fromPrecision, 'd');
  switch (unit) {
    case 'b':
    case 'u':
    case 'a':
    case 's':
    case 'm':
    case 'h':
    case 'd':
    case 'w':
      return days / 28;
    case 'n':
      return val;
    case 'y':
      return val * 12;
    default:
      break;
  }
  return -1;
X
Xiaoyu Wang 已提交
3001 3002
}

X
Xiaoyu Wang 已提交
3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016
static const char* getPrecisionStr(uint8_t precision) {
  switch (precision) {
    case TSDB_TIME_PRECISION_MILLI:
      return TSDB_TIME_PRECISION_MILLI_STR;
    case TSDB_TIME_PRECISION_MICRO:
      return TSDB_TIME_PRECISION_MICRO_STR;
    case TSDB_TIME_PRECISION_NANO:
      return TSDB_TIME_PRECISION_NANO_STR;
    default:
      break;
  }
  return "unknown";
}

X
Xiaoyu Wang 已提交
3017
static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
wmmhello's avatar
wmmhello 已提交
3018 3019 3020 3021
  uint8_t precision = ((SColumnNode*)pInterval->pCol)->node.resType.precision;

  SValueNode* pInter = (SValueNode*)pInterval->pInterval;
  bool        valInter = TIME_IS_VAR_DURATION(pInter->unit);
X
Xiaoyu Wang 已提交
3022 3023 3024
  if (pInter->datum.i <= 0 || (!valInter && pInter->datum.i < tsMinIntervalTime)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_VALUE_TOO_SMALL, tsMinIntervalTime,
                                getPrecisionStr(precision));
wmmhello's avatar
wmmhello 已提交
3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058
  }

  if (NULL != pInterval->pOffset) {
    SValueNode* pOffset = (SValueNode*)pInterval->pOffset;
    if (pOffset->datum.i <= 0) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_OFFSET_NEGATIVE);
    }
    if (pInter->unit == 'n' && pOffset->unit == 'y') {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_OFFSET_UNIT);
    }
    bool fixed = !TIME_IS_VAR_DURATION(pOffset->unit) && !valInter;
    if ((fixed && pOffset->datum.i >= pInter->datum.i) ||
        (!fixed && getMonthsFromTimeVal(pOffset->datum.i, precision, pOffset->unit) >=
                       getMonthsFromTimeVal(pInter->datum.i, precision, pInter->unit))) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_OFFSET_TOO_BIG);
    }
  }

  if (NULL != pInterval->pSliding) {
    const static int32_t INTERVAL_SLIDING_FACTOR = 100;

    SValueNode* pSliding = (SValueNode*)pInterval->pSliding;
    if (TIME_IS_VAR_DURATION(pSliding->unit)) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SLIDING_UNIT);
    }
    if ((pSliding->datum.i < convertTimePrecision(tsMinSlidingTime, TSDB_TIME_PRECISION_MILLI, precision)) ||
        (pInter->datum.i / pSliding->datum.i > INTERVAL_SLIDING_FACTOR)) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SLIDING_TOO_SMALL);
    }
    if (pSliding->datum.i > pInter->datum.i) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SLIDING_TOO_BIG);
    }
  }

X
Xiaoyu Wang 已提交
3059 3060 3061
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
3062 3063 3064
static int32_t translateIntervalWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
  SIntervalWindowNode* pInterval = (SIntervalWindowNode*)pSelect->pWindow;
  int32_t              code = checkIntervalWindow(pCxt, pInterval);
X
Xiaoyu Wang 已提交
3065
  if (TSDB_CODE_SUCCESS == code) {
3066
    code = translateFill(pCxt, pSelect, pInterval);
X
Xiaoyu Wang 已提交
3067 3068
  }
  return code;
X
Xiaoyu Wang 已提交
3069 3070
}

X
Xiaoyu Wang 已提交
3071 3072 3073 3074 3075
static int32_t checkStateExpr(STranslateContext* pCxt, SNode* pNode) {
  int32_t type = ((SExprNode*)pNode)->resType.type;
  if (!IS_INTEGER_TYPE(type) && type != TSDB_DATA_TYPE_BOOL && !IS_VAR_DATA_TYPE(type)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STATE_WIN_TYPE);
  }
wmmhello's avatar
wmmhello 已提交
3076

X
Xiaoyu Wang 已提交
3077 3078
  if (QUERY_NODE_COLUMN == nodeType(pNode) && COLUMN_TYPE_TAG == ((SColumnNode*)pNode)->colType) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STATE_WIN_COL);
wmmhello's avatar
wmmhello 已提交
3079
  }
X
Xiaoyu Wang 已提交
3080 3081

  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3082 3083
}

3084 3085 3086 3087 3088 3089
static bool hasPartitionByTbname(SNodeList* pPartitionByList) {
  SNode* pPartKey = NULL;
  FOREACH(pPartKey, pPartitionByList) {
    if (QUERY_NODE_FUNCTION == nodeType(pPartKey) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPartKey)->funcType) {
      return true;
    }
X
Xiaoyu Wang 已提交
3090
  }
3091
  return false;
X
Xiaoyu Wang 已提交
3092 3093 3094 3095 3096 3097 3098
}

static int32_t checkStateWindowForStream(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (!pCxt->createStream) {
    return TSDB_CODE_SUCCESS;
  }
  if (TSDB_SUPER_TABLE == ((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType &&
3099
      !hasPartitionByTbname(pSelect->pPartitionByList)) {
X
Xiaoyu Wang 已提交
3100 3101 3102 3103 3104 3105
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
  }
  return TSDB_CODE_SUCCESS;
}

static int32_t translateStateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
X
Xiaoyu Wang 已提交
3106 3107 3108 3109 3110 3111
  if (QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
      !isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TIMELINE_QUERY,
                                   "STATE_WINDOW requires valid time series input");
  }

X
Xiaoyu Wang 已提交
3112
  SStateWindowNode* pState = (SStateWindowNode*)pSelect->pWindow;
X
Xiaoyu Wang 已提交
3113 3114 3115
  int32_t           code = checkStateExpr(pCxt, pState->pExpr);
  if (TSDB_CODE_SUCCESS == code) {
    code = checkStateWindowForStream(pCxt, pSelect);
X
Xiaoyu Wang 已提交
3116
  }
X
Xiaoyu Wang 已提交
3117
  return code;
X
Xiaoyu Wang 已提交
3118 3119
}

X
Xiaoyu Wang 已提交
3120 3121 3122 3123 3124 3125 3126 3127
static int32_t translateSessionWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
      !isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TIMELINE_QUERY,
                                   "SESSION requires valid time series input");
  }

  SSessionWindowNode* pSession = (SSessionWindowNode*)pSelect->pWindow;
wmmhello's avatar
wmmhello 已提交
3128 3129 3130 3131 3132 3133 3134
  if ('y' == pSession->pGap->unit || 'n' == pSession->pGap->unit || 0 == pSession->pGap->datum.i) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SESSION_GAP);
  }
  if (PRIMARYKEY_TIMESTAMP_COL_ID != pSession->pCol->colId) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SESSION_COL);
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3135 3136
}

X
Xiaoyu Wang 已提交
3137
static int32_t translateSpecificWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
3138 3139
  switch (nodeType(pSelect->pWindow)) {
    case QUERY_NODE_STATE_WINDOW:
X
Xiaoyu Wang 已提交
3140
      return translateStateWindow(pCxt, pSelect);
wmmhello's avatar
wmmhello 已提交
3141
    case QUERY_NODE_SESSION_WINDOW:
X
Xiaoyu Wang 已提交
3142
      return translateSessionWindow(pCxt, pSelect);
wmmhello's avatar
wmmhello 已提交
3143
    case QUERY_NODE_INTERVAL_WINDOW:
X
Xiaoyu Wang 已提交
3144
      return translateIntervalWindow(pCxt, pSelect);
wmmhello's avatar
wmmhello 已提交
3145 3146 3147 3148
    default:
      break;
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3149 3150
}

X
Xiaoyu Wang 已提交
3151
static int32_t translateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
3152 3153 3154 3155
  if (NULL == pSelect->pWindow) {
    return TSDB_CODE_SUCCESS;
  }
  pCxt->currClause = SQL_CLAUSE_WINDOW;
X
Xiaoyu Wang 已提交
3156
  int32_t code = translateExpr(pCxt, &pSelect->pWindow);
wmmhello's avatar
wmmhello 已提交
3157
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
3158
    code = translateSpecificWindow(pCxt, pSelect);
wmmhello's avatar
wmmhello 已提交
3159 3160
  }
  return code;
3161 3162
}

X
Xiaoyu Wang 已提交
3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176
static int32_t createDefaultFillNode(STranslateContext* pCxt, SNode** pOutput) {
  SFillNode* pFill = (SFillNode*)nodesMakeNode(QUERY_NODE_FILL);
  if (NULL == pFill) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  pFill->mode = FILL_MODE_NONE;

  SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
  if (NULL == pCol) {
    nodesDestroyNode((SNode*)pFill);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
3177
  strcpy(pCol->colName, ROWTS_PSEUDO_COLUMN_NAME);
X
Xiaoyu Wang 已提交
3178 3179 3180 3181 3182 3183
  pFill->pWStartTs = (SNode*)pCol;

  *pOutput = (SNode*)pFill;
  return TSDB_CODE_SUCCESS;
}

3184 3185 3186
static int32_t checkEvery(STranslateContext* pCxt, SValueNode* pInterval) {
  int32_t len = strlen(pInterval->literal);

3187
  char* unit = &pInterval->literal[len - 1];
3188 3189
  if (*unit == 'n' || *unit == 'y') {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE,
G
Ganlin Zhao 已提交
3190
                                   "Unsupported time unit in EVERY clause");
3191 3192 3193 3194 3195 3196 3197 3198
  }

  return TSDB_CODE_SUCCESS;
}

static int32_t translateInterpEvery(STranslateContext* pCxt, SNode** pEvery) {
  int32_t code = TSDB_CODE_SUCCESS;

3199
  code = checkEvery(pCxt, (SValueNode*)(*pEvery));
3200 3201 3202 3203
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExpr(pCxt, pEvery);
  }

3204 3205 3206 3207 3208 3209
  int64_t interval = ((SValueNode*)(*pEvery))->datum.i;
  if (interval == 0) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE,
                                   "Unsupported time unit in EVERY clause");
  }

3210 3211 3212
  return code;
}

X
Xiaoyu Wang 已提交
3213 3214 3215 3216 3217 3218 3219 3220 3221 3222
static int32_t translateInterpFill(STranslateContext* pCxt, SSelectStmt* pSelect) {
  int32_t code = TSDB_CODE_SUCCESS;

  if (NULL == pSelect->pFill) {
    code = createDefaultFillNode(pCxt, &pSelect->pFill);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExpr(pCxt, &pSelect->pFill);
  }
  if (TSDB_CODE_SUCCESS == code) {
3223
    code = getQueryTimeRange(pCxt, pSelect->pRange, &(((SFillNode*)pSelect->pFill)->timeRange));
X
Xiaoyu Wang 已提交
3224 3225
  }
  if (TSDB_CODE_SUCCESS == code) {
3226
    code = checkFill(pCxt, (SFillNode*)pSelect->pFill, (SValueNode*)pSelect->pEvery, true);
X
Xiaoyu Wang 已提交
3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239
  }

  return code;
}

static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (!pSelect->hasInterpFunc) {
    if (NULL != pSelect->pRange || NULL != pSelect->pEvery || NULL != pSelect->pFill) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_INTERP_CLAUSE);
    }
    return TSDB_CODE_SUCCESS;
  }

X
Xiaoyu Wang 已提交
3240 3241 3242 3243 3244
  if (NULL == pSelect->pRange || NULL == pSelect->pEvery || NULL == pSelect->pFill) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_INTERP_CLAUSE,
                                   "Missing RANGE clause, EVERY clause or FILL clause");
  }

X
Xiaoyu Wang 已提交
3245 3246
  int32_t code = translateExpr(pCxt, &pSelect->pRange);
  if (TSDB_CODE_SUCCESS == code) {
3247
    code = translateInterpEvery(pCxt, &pSelect->pEvery);
X
Xiaoyu Wang 已提交
3248 3249 3250 3251 3252 3253 3254
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateInterpFill(pCxt, pSelect);
  }
  return code;
}

3255 3256
static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (NULL == pSelect->pPartitionByList) {
3257 3258
    return TSDB_CODE_SUCCESS;
  }
wmmhello's avatar
wmmhello 已提交
3259
  pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
3260 3261 3262 3263 3264 3265 3266 3267
  int32_t code = translateExprList(pCxt, pSelect->pPartitionByList);
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExprList(pCxt, pSelect->pTags);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExpr(pCxt, &pSelect->pSubtable);
  }
  return code;
3268 3269
}

3270
static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
3271
  pCxt->currClause = SQL_CLAUSE_WHERE;
3272
  int32_t code = translateExpr(pCxt, &pSelect->pWhere);
3273
  if (TSDB_CODE_SUCCESS == code) {
3274 3275 3276
    code = getQueryTimeRange(pCxt, pSelect->pWhere, &pSelect->timeRange);
  }
  return code;
3277 3278
}

X
Xiaoyu Wang 已提交
3279
static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) {
wmmhello's avatar
wmmhello 已提交
3280
  pCxt->currClause = SQL_CLAUSE_FROM;
X
Xiaoyu Wang 已提交
3281
  return translateTable(pCxt, pTable);
3282 3283
}

X
Xiaoyu Wang 已提交
3284
static int32_t checkLimit(STranslateContext* pCxt, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
3285 3286 3287 3288
  if ((NULL != pSelect->pLimit && pSelect->pLimit->offset < 0) ||
      (NULL != pSelect->pSlimit && pSelect->pSlimit->offset < 0)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_OFFSET_LESS_ZERO);
  }
X
Xiaoyu Wang 已提交
3289

wmmhello's avatar
wmmhello 已提交
3290 3291 3292
  if (NULL != pSelect->pSlimit && NULL == pSelect->pPartitionByList) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SLIMIT_LEAK_PARTITION_BY);
  }
X
Xiaoyu Wang 已提交
3293

wmmhello's avatar
wmmhello 已提交
3294
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3295 3296
}

3297
static int32_t createPrimaryKeyColByTable(STranslateContext* pCxt, STableNode* pTable, SNode** pPrimaryKey) {
3298
  SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
wmmhello's avatar
wmmhello 已提交
3299 3300 3301 3302
  if (NULL == pCol) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
3303
  strcpy(pCol->colName, ROWTS_PSEUDO_COLUMN_NAME);
3304 3305 3306
  bool    found = false;
  int32_t code = findAndSetColumn(pCxt, &pCol, pTable, &found);
  if (TSDB_CODE_SUCCESS != code || !found) {
wmmhello's avatar
wmmhello 已提交
3307 3308 3309 3310
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TIMELINE_FUNC);
  }
  *pPrimaryKey = (SNode*)pCol;
  return TSDB_CODE_SUCCESS;
3311 3312 3313
}

static int32_t createPrimaryKeyCol(STranslateContext* pCxt, SNode** pPrimaryKey) {
wmmhello's avatar
wmmhello 已提交
3314 3315 3316 3317 3318 3319
  STableNode* pTable = NULL;
  int32_t     code = findTable(pCxt, NULL, &pTable);
  if (TSDB_CODE_SUCCESS == code) {
    code = createPrimaryKeyColByTable(pCxt, pTable, pPrimaryKey);
  }
  return code;
3320 3321
}

3322
static EDealRes appendTsForImplicitTsFuncImpl(SNode* pNode, void* pContext) {
wmmhello's avatar
wmmhello 已提交
3323
  STranslateContext* pCxt = pContext;
3324
  if (isImplicitTsFunc(pNode)) {
wmmhello's avatar
wmmhello 已提交
3325 3326 3327 3328 3329 3330 3331 3332 3333
    SFunctionNode* pFunc = (SFunctionNode*)pNode;
    SNode*         pPrimaryKey = NULL;
    pCxt->errCode = createPrimaryKeyCol(pCxt, &pPrimaryKey);
    if (TSDB_CODE_SUCCESS == pCxt->errCode) {
      pCxt->errCode = nodesListMakeStrictAppend(&pFunc->pParameterList, pPrimaryKey);
    }
    return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
  }
  return DEAL_RES_CONTINUE;
3334 3335
}

3336 3337
static int32_t appendTsForImplicitTsFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
  nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, appendTsForImplicitTsFuncImpl, pCxt);
wmmhello's avatar
wmmhello 已提交
3338
  return pCxt->errCode;
3339
}
X
Xiaoyu Wang 已提交
3340

3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358
typedef struct SReplaceOrderByAliasCxt {
  STranslateContext* pTranslateCxt;
  SNodeList*         pProjectionList;
} SReplaceOrderByAliasCxt;

static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
  SReplaceOrderByAliasCxt* pCxt = pContext;
  if (QUERY_NODE_COLUMN_REF == nodeType(*pNode)) {
    SNodeList* pProjectionList = pCxt->pProjectionList;
    SNode*     pProject = NULL;
    FOREACH(pProject, pProjectionList) {
      SExprNode* pExpr = (SExprNode*)pProject;
      if (0 == strcmp(((SColumnRefNode*)*pNode)->colName, pExpr->aliasName)) {
        SNode* pNew = nodesCloneNode(pProject);
        if (NULL == pNew) {
          pCxt->pTranslateCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
          return DEAL_RES_ERROR;
        }
3359
        ((SExprNode*)pNew)->orderAlias = true;
3360 3361 3362 3363 3364 3365 3366 3367 3368 3369
        nodesDestroyNode(*pNode);
        *pNode = pNew;
        return DEAL_RES_CONTINUE;
      }
    }
  }
  return DEAL_RES_CONTINUE;
}

static int32_t replaceOrderByAlias(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList) {
3370 3371 3372
  if (NULL == pOrderByList) {
    return TSDB_CODE_SUCCESS;
  }
3373 3374 3375 3376 3377
  SReplaceOrderByAliasCxt cxt = {.pTranslateCxt = pCxt, .pProjectionList = pProjectionList};
  nodesRewriteExprsPostOrder(pOrderByList, replaceOrderByAliasImpl, &cxt);
  return pCxt->errCode;
}

3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399
static void resetResultTimeline(SSelectStmt* pSelect) {
  if (NULL == pSelect->pOrderByList) {
    return;
  }
  SNode* pOrder = ((SOrderByExprNode*)nodesListGetNode(pSelect->pOrderByList, 0))->pExpr;
  if ((QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
       isPrimaryKey((STempTableNode*)pSelect->pFromTable, pOrder)) ||
      (QUERY_NODE_TEMP_TABLE != nodeType(pSelect->pFromTable) && isPrimaryKeyImpl(pOrder))) {
    pSelect->isTimeLineResult = true;
  } else {
    pSelect->isTimeLineResult = false;
  }
}

static int32_t replaceOrderByAliasForSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
  int32_t code = replaceOrderByAlias(pCxt, pSelect->pProjectionList, pSelect->pOrderByList);
  if (TSDB_CODE_SUCCESS == pCxt->errCode) {
    resetResultTimeline(pSelect);
  }
  return code;
}

3400
static int32_t translateSelectWithoutFrom(STranslateContext* pCxt, SSelectStmt* pSelect) {
3401
  pCxt->pCurrStmt = (SNode*)pSelect;
3402 3403 3404 3405 3406
  pCxt->currClause = SQL_CLAUSE_SELECT;
  return translateExprList(pCxt, pSelect->pProjectionList);
}

static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect) {
3407
  pCxt->pCurrStmt = (SNode*)pSelect;
X
Xiaoyu Wang 已提交
3408
  int32_t code = translateFrom(pCxt, pSelect->pFromTable);
wmmhello's avatar
wmmhello 已提交
3409
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
3410
    pSelect->precision = ((STableNode*)pSelect->pFromTable)->precision;
3411
    code = translateWhere(pCxt, pSelect);
wmmhello's avatar
wmmhello 已提交
3412 3413
  }
  if (TSDB_CODE_SUCCESS == code) {
3414
    code = translatePartitionBy(pCxt, pSelect);
wmmhello's avatar
wmmhello 已提交
3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateWindow(pCxt, pSelect);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateGroupBy(pCxt, pSelect);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateHaving(pCxt, pSelect);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateSelectList(pCxt, pSelect);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateOrderBy(pCxt, pSelect);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkAggColCoexist(pCxt, pSelect);
  }
3434 3435 3436
  if (TSDB_CODE_SUCCESS == code) {
    code = checkWindowFuncCoexist(pCxt, pSelect);
  }
wmmhello's avatar
wmmhello 已提交
3437 3438 3439
  if (TSDB_CODE_SUCCESS == code) {
    code = checkLimit(pCxt, pSelect);
  }
X
Xiaoyu Wang 已提交
3440 3441 3442
  if (TSDB_CODE_SUCCESS == code) {
    code = translateInterp(pCxt, pSelect);
  }
3443
  if (TSDB_CODE_SUCCESS == code) {
3444
    code = appendTsForImplicitTsFunc(pCxt, pSelect);
3445
  }
wmmhello's avatar
wmmhello 已提交
3446
  if (TSDB_CODE_SUCCESS == code) {
3447
    code = replaceOrderByAliasForSelect(pCxt, pSelect);
wmmhello's avatar
wmmhello 已提交
3448
  }
X
Xiaoyu Wang 已提交
3449 3450 3451
  if (TSDB_CODE_SUCCESS == code) {
    code = setTableCacheLastMode(pCxt, pSelect);
  }
wmmhello's avatar
wmmhello 已提交
3452
  return code;
3453 3454
}

3455 3456 3457 3458 3459 3460 3461 3462
static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (NULL == pSelect->pFromTable) {
    return translateSelectWithoutFrom(pCxt, pSelect);
  } else {
    return translateSelectFrom(pCxt, pSelect);
  }
}

3463
static SNode* createSetOperProject(const char* pTableAlias, SNode* pNode) {
3464
  SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
wmmhello's avatar
wmmhello 已提交
3465 3466 3467 3468
  if (NULL == pCol) {
    return NULL;
  }
  pCol->node.resType = ((SExprNode*)pNode)->resType;
X
Xiaoyu Wang 已提交
3469 3470 3471 3472
  snprintf(pCol->tableAlias, sizeof(pCol->tableAlias), "%s", pTableAlias);
  snprintf(pCol->colName, sizeof(pCol->colName), "%s", ((SExprNode*)pNode)->aliasName);
  snprintf(pCol->node.aliasName, sizeof(pCol->node.aliasName), "%s", pCol->colName);
  snprintf(pCol->node.userAlias, sizeof(pCol->node.userAlias), "%s", ((SExprNode*)pNode)->userAlias);
wmmhello's avatar
wmmhello 已提交
3473
  return (SNode*)pCol;
X
Xiaoyu Wang 已提交
3474 3475
}

3476
static int32_t translateSetOperProject(STranslateContext* pCxt, SSetOperator* pSetOperator) {
wmmhello's avatar
wmmhello 已提交
3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487
  SNodeList* pLeftProjections = getProjectList(pSetOperator->pLeft);
  SNodeList* pRightProjections = getProjectList(pSetOperator->pRight);
  if (LIST_LENGTH(pLeftProjections) != LIST_LENGTH(pRightProjections)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INCORRECT_NUM_OF_COL);
  }

  SNode* pLeft = NULL;
  SNode* pRight = NULL;
  FORBOTH(pLeft, pLeftProjections, pRight, pRightProjections) {
    SExprNode* pLeftExpr = (SExprNode*)pLeft;
    SExprNode* pRightExpr = (SExprNode*)pRight;
X
Xiaoyu Wang 已提交
3488 3489
    int32_t    comp = dataTypeComp(&pLeftExpr->resType, &pRightExpr->resType);
    if (comp > 0) {
wmmhello's avatar
wmmhello 已提交
3490 3491 3492 3493 3494 3495 3496
      SNode*  pRightFunc = NULL;
      int32_t code = createCastFunc(pCxt, pRight, pLeftExpr->resType, &pRightFunc);
      if (TSDB_CODE_SUCCESS != code) {
        return code;
      }
      REPLACE_LIST2_NODE(pRightFunc);
      pRightExpr = (SExprNode*)pRightFunc;
X
Xiaoyu Wang 已提交
3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510
    } else if (comp < 0) {
      SNode*  pLeftFunc = NULL;
      int32_t code = createCastFunc(pCxt, pLeft, pRightExpr->resType, &pLeftFunc);
      if (TSDB_CODE_SUCCESS != code) {
        return code;
      }
      REPLACE_LIST1_NODE(pLeftFunc);
      SExprNode* pLeftFuncExpr = (SExprNode*)pLeftFunc;
      snprintf(pLeftFuncExpr->aliasName, sizeof(pLeftFuncExpr->aliasName), "%s", pLeftExpr->aliasName);
      snprintf(pLeftFuncExpr->userAlias, sizeof(pLeftFuncExpr->userAlias), "%s", pLeftExpr->userAlias);
      pLeft = pLeftFunc;
      pLeftExpr = pLeftFuncExpr;
    }
    snprintf(pRightExpr->aliasName, sizeof(pRightExpr->aliasName), "%s", pLeftExpr->aliasName);
wmmhello's avatar
wmmhello 已提交
3511 3512 3513 3514 3515 3516
    if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pSetOperator->pProjectionList,
                                                       createSetOperProject(pSetOperator->stmtName, pLeft))) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }
  return TSDB_CODE_SUCCESS;
3517 3518
}

X
Xiaoyu Wang 已提交
3519 3520 3521 3522
static uint8_t calcSetOperatorPrecision(SSetOperator* pSetOperator) {
  return calcPrecision(getStmtPrecision(pSetOperator->pLeft), getStmtPrecision(pSetOperator->pRight));
}

3523 3524 3525 3526 3527 3528
static int32_t translateSetOperOrderBy(STranslateContext* pCxt, SSetOperator* pSetOperator) {
  bool    other;
  int32_t code = translateOrderByPosition(pCxt, pSetOperator->pProjectionList, pSetOperator->pOrderByList, &other);
  if (TSDB_CODE_SUCCESS == code) {
    if (other) {
      pCxt->currClause = SQL_CLAUSE_ORDER_BY;
3529
      pCxt->pCurrStmt = (SNode*)pSetOperator;
3530 3531 3532 3533 3534 3535 3536 3537 3538
      code = translateExprList(pCxt, pSetOperator->pOrderByList);
    }
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = replaceOrderByAlias(pCxt, pSetOperator->pProjectionList, pSetOperator->pOrderByList);
  }
  return code;
}

3539 3540 3541 3542 3543 3544 3545
static int32_t checkSetOperLimit(STranslateContext* pCxt, SLimitNode* pLimit) {
  if ((NULL != pLimit && pLimit->offset < 0)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_OFFSET_LESS_ZERO);
  }
  return TSDB_CODE_SUCCESS;
}

3546
static int32_t translateSetOperator(STranslateContext* pCxt, SSetOperator* pSetOperator) {
wmmhello's avatar
wmmhello 已提交
3547 3548 3549 3550 3551 3552 3553 3554
  int32_t code = translateQuery(pCxt, pSetOperator->pLeft);
  if (TSDB_CODE_SUCCESS == code) {
    code = resetTranslateNamespace(pCxt);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateQuery(pCxt, pSetOperator->pRight);
  }
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
3555
    pSetOperator->precision = calcSetOperatorPrecision(pSetOperator);
3556 3557 3558 3559
    code = translateSetOperProject(pCxt, pSetOperator);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateSetOperOrderBy(pCxt, pSetOperator);
wmmhello's avatar
wmmhello 已提交
3560
  }
3561 3562 3563
  if (TSDB_CODE_SUCCESS == code) {
    code = checkSetOperLimit(pCxt, (SLimitNode*)pSetOperator->pLimit);
  }
wmmhello's avatar
wmmhello 已提交
3564
  return code;
3565 3566
}

X
Xiaoyu Wang 已提交
3567 3568 3569 3570 3571 3572 3573 3574
static int32_t partitionDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelete) {
  if (NULL == pDelete->pWhere) {
    pDelete->timeRange = TSWINDOW_INITIALIZER;
    return TSDB_CODE_SUCCESS;
  }

  SNode*  pPrimaryKeyCond = NULL;
  SNode*  pOtherCond = NULL;
X
Xiaoyu Wang 已提交
3575
  int32_t code = filterPartitionCond(&pDelete->pWhere, &pPrimaryKeyCond, NULL, &pDelete->pTagCond, &pOtherCond);
X
Xiaoyu Wang 已提交
3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591
  if (TSDB_CODE_SUCCESS == code && NULL != pOtherCond) {
    code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DELETE_WHERE);
  }
  if (TSDB_CODE_SUCCESS == code) {
    bool isStrict = false;
    code = getTimeRange(&pPrimaryKeyCond, &pDelete->timeRange, &isStrict);
    if (TSDB_CODE_SUCCESS == code && !isStrict) {
      code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DELETE_WHERE);
    }
  }
  nodesDestroyNode(pPrimaryKeyCond);
  nodesDestroyNode(pOtherCond);
  return code;
}

static int32_t translateDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelete) {
3592 3593
  pCxt->currClause = SQL_CLAUSE_WHERE;
  int32_t code = translateExpr(pCxt, &pDelete->pWhere);
X
Xiaoyu Wang 已提交
3594 3595 3596 3597 3598 3599 3600
  if (TSDB_CODE_SUCCESS == code) {
    code = partitionDeleteWhere(pCxt, pDelete);
  }
  return code;
}

static int32_t translateDelete(STranslateContext* pCxt, SDeleteStmt* pDelete) {
3601
  pCxt->pCurrStmt = (SNode*)pDelete;
X
Xiaoyu Wang 已提交
3602 3603 3604 3605
  int32_t code = translateFrom(pCxt, pDelete->pFromTable);
  if (TSDB_CODE_SUCCESS == code) {
    code = translateDeleteWhere(pCxt, pDelete);
  }
3606
  pCxt->currClause = SQL_CLAUSE_SELECT;
X
Xiaoyu Wang 已提交
3607 3608 3609
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExpr(pCxt, &pDelete->pCountFunc);
  }
3610 3611 3612 3613 3614 3615
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExpr(pCxt, &pDelete->pFirstFunc);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExpr(pCxt, &pDelete->pLastFunc);
  }
X
Xiaoyu Wang 已提交
3616 3617 3618
  return code;
}

3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685
static int32_t translateInsertCols(STranslateContext* pCxt, SInsertStmt* pInsert) {
  if (NULL == pInsert->pCols) {
    return createAllColumns(pCxt, false, &pInsert->pCols);
  }
  return translateExprList(pCxt, pInsert->pCols);
}

static int32_t translateInsertQuery(STranslateContext* pCxt, SInsertStmt* pInsert) {
  int32_t code = resetTranslateNamespace(pCxt);
  if (TSDB_CODE_SUCCESS == code) {
    code = translateQuery(pCxt, pInsert->pQuery);
  }
  return code;
}

static int32_t addOrderByPrimaryKeyToQueryImpl(STranslateContext* pCxt, SNode* pPrimaryKeyExpr,
                                               SNodeList** pOrderByList) {
  SOrderByExprNode* pOrderByExpr = (SOrderByExprNode*)nodesMakeNode(QUERY_NODE_ORDER_BY_EXPR);
  if (NULL == pOrderByExpr) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pOrderByExpr->nullOrder = NULL_ORDER_FIRST;
  pOrderByExpr->order = ORDER_ASC;
  pOrderByExpr->pExpr = nodesCloneNode(pPrimaryKeyExpr);
  if (NULL == pOrderByExpr->pExpr) {
    nodesDestroyNode((SNode*)pOrderByExpr);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  ((SExprNode*)pOrderByExpr->pExpr)->orderAlias = true;
  NODES_DESTORY_LIST(*pOrderByList);
  return nodesListMakeStrictAppend(pOrderByList, (SNode*)pOrderByExpr);
}

static int32_t addOrderByPrimaryKeyToQuery(STranslateContext* pCxt, SNode* pPrimaryKeyExpr, SNode* pStmt) {
  if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
    return addOrderByPrimaryKeyToQueryImpl(pCxt, pPrimaryKeyExpr, &((SSelectStmt*)pStmt)->pOrderByList);
  }
  return addOrderByPrimaryKeyToQueryImpl(pCxt, pPrimaryKeyExpr, &((SSetOperator*)pStmt)->pOrderByList);
}

static int32_t translateInsertProject(STranslateContext* pCxt, SInsertStmt* pInsert) {
  SNodeList* pProjects = getProjectList(pInsert->pQuery);
  if (LIST_LENGTH(pInsert->pCols) != LIST_LENGTH(pProjects)) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMNS_NUM, "Illegal number of columns");
  }

  SNode* pPrimaryKeyExpr = NULL;
  SNode* pBoundCol = NULL;
  SNode* pProj = NULL;
  FORBOTH(pBoundCol, pInsert->pCols, pProj, pProjects) {
    SColumnNode* pCol = (SColumnNode*)pBoundCol;
    SExprNode*   pExpr = (SExprNode*)pProj;
    if (!dataTypeEqual(&pCol->node.resType, &pExpr->resType)) {
      SNode*  pFunc = NULL;
      int32_t code = createCastFunc(pCxt, pProj, pCol->node.resType, &pFunc);
      if (TSDB_CODE_SUCCESS != code) {
        return code;
      }
      REPLACE_LIST2_NODE(pFunc);
      pExpr = (SExprNode*)pFunc;
    }
    snprintf(pExpr->aliasName, sizeof(pExpr->aliasName), "%s", pCol->colName);
    if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) {
      pPrimaryKeyExpr = pProj;
    }
  }

X
Xiaoyu Wang 已提交
3686 3687 3688 3689 3690
  if (NULL == pPrimaryKeyExpr) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMNS_NUM,
                                   "Primary timestamp column can not be null");
  }

3691 3692 3693
  return addOrderByPrimaryKeyToQuery(pCxt, pPrimaryKeyExpr, pInsert->pQuery);
}

X
Xiaoyu Wang 已提交
3694 3695 3696 3697 3698 3699 3700 3701 3702 3703
static int32_t translateInsertTable(STranslateContext* pCxt, SNode* pTable) {
  int32_t code = translateFrom(pCxt, pTable);
  if (TSDB_CODE_SUCCESS == code && TSDB_CHILD_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType &&
      TSDB_NORMAL_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType) {
    code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR,
                                   "insert data into super table is not supported");
  }
  return code;
}

3704 3705
static int32_t translateInsert(STranslateContext* pCxt, SInsertStmt* pInsert) {
  pCxt->pCurrStmt = (SNode*)pInsert;
X
Xiaoyu Wang 已提交
3706
  int32_t code = translateInsertTable(pCxt, pInsert->pTable);
3707
  if (TSDB_CODE_SUCCESS == code) {
3708
    code = translateInsertCols(pCxt, pInsert);
3709
  }
3710
  if (TSDB_CODE_SUCCESS == code) {
3711
    code = translateInsertQuery(pCxt, pInsert);
3712
  }
3713
  if (TSDB_CODE_SUCCESS == code) {
3714
    code = translateInsertProject(pCxt, pInsert);
3715 3716 3717 3718
  }
  return code;
}

3719
static int64_t getUnitPerMinute(uint8_t precision) {
wmmhello's avatar
wmmhello 已提交
3720 3721 3722 3723
  switch (precision) {
    case TSDB_TIME_PRECISION_MILLI:
      return MILLISECOND_PER_MINUTE;
    case TSDB_TIME_PRECISION_MICRO:
wafwerar's avatar
wafwerar 已提交
3724
      return MILLISECOND_PER_MINUTE * 1000LL;
wmmhello's avatar
wmmhello 已提交
3725 3726 3727 3728 3729 3730
    case TSDB_TIME_PRECISION_NANO:
      return NANOSECOND_PER_MINUTE;
    default:
      break;
  }
  return MILLISECOND_PER_MINUTE;
3731 3732 3733
}

static int64_t getBigintFromValueNode(SValueNode* pVal) {
wmmhello's avatar
wmmhello 已提交
3734 3735 3736 3737
  if (pVal->isDuration) {
    return pVal->datum.i / getUnitPerMinute(pVal->node.resType.precision);
  }
  return pVal->datum.i;
3738 3739
}

X
Xiaoyu Wang 已提交
3740
static int32_t buildCreateDbRetentions(const SNodeList* pRetentions, SCreateDbReq* pReq) {
wmmhello's avatar
wmmhello 已提交
3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759
  if (NULL != pRetentions) {
    pReq->pRetensions = taosArrayInit(LIST_LENGTH(pRetentions), sizeof(SRetention));
    if (NULL == pReq->pRetensions) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
    SValueNode* pFreq = NULL;
    SValueNode* pKeep = NULL;
    SNode*      pNode = NULL;
    int32_t     index = 0;
    FOREACH(pNode, pRetentions) {
      pFreq = (SValueNode*)nodesListGetNode(((SNodeListNode*)pNode)->pNodeList, 0);
      pKeep = (SValueNode*)nodesListGetNode(((SNodeListNode*)pNode)->pNodeList, 1);
      SRetention retention = {
          .freq = pFreq->datum.i, .freqUnit = pFreq->unit, .keep = pKeep->datum.i, .keepUnit = pKeep->unit};
      taosArrayPush(pReq->pRetensions, &retention);
    }
    pReq->numOfRetensions = taosArrayGetSize(pReq->pRetensions);
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3760 3761 3762
}

static int32_t buildCreateDbReq(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt, SCreateDbReq* pReq) {
wmmhello's avatar
wmmhello 已提交
3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776
  SName name = {0};
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
  tNameGetFullDbName(&name, pReq->db);
  pReq->numOfVgroups = pStmt->pOptions->numOfVgroups;
  pReq->numOfStables = pStmt->pOptions->singleStable;
  pReq->buffer = pStmt->pOptions->buffer;
  pReq->pageSize = pStmt->pOptions->pagesize;
  pReq->pages = pStmt->pOptions->pages;
  pReq->daysPerFile = pStmt->pOptions->daysPerFile;
  pReq->daysToKeep0 = pStmt->pOptions->keep[0];
  pReq->daysToKeep1 = pStmt->pOptions->keep[1];
  pReq->daysToKeep2 = pStmt->pOptions->keep[2];
  pReq->minRows = pStmt->pOptions->minRowsPerBlock;
  pReq->maxRows = pStmt->pOptions->maxRowsPerBlock;
3777
  pReq->walFsyncPeriod = pStmt->pOptions->fsyncPeriod;
wmmhello's avatar
wmmhello 已提交
3778 3779 3780 3781 3782
  pReq->walLevel = pStmt->pOptions->walLevel;
  pReq->precision = pStmt->pOptions->precision;
  pReq->compression = pStmt->pOptions->compressionLevel;
  pReq->replications = pStmt->pOptions->replica;
  pReq->strict = pStmt->pOptions->strict;
3783
  pReq->cacheLast = pStmt->pOptions->cacheModel;
3784
  pReq->cacheLastSize = pStmt->pOptions->cacheLastSize;
X
Xiaoyu Wang 已提交
3785
  pReq->schemaless = pStmt->pOptions->schemaless;
X
Xiaoyu Wang 已提交
3786 3787 3788 3789
  pReq->walRetentionPeriod = pStmt->pOptions->walRetentionPeriod;
  pReq->walRetentionSize = pStmt->pOptions->walRetentionSize;
  pReq->walRollPeriod = pStmt->pOptions->walRollPeriod;
  pReq->walSegmentSize = pStmt->pOptions->walSegmentSize;
3790
  pReq->sstTrigger = pStmt->pOptions->sstTrigger;
3791 3792
  pReq->hashPrefix = pStmt->pOptions->tablePrefix;
  pReq->hashSuffix = pStmt->pOptions->tableSuffix;
3793
  pReq->tsdbPageSize = pStmt->pOptions->tsdbPageSize;
wmmhello's avatar
wmmhello 已提交
3794 3795
  pReq->ignoreExist = pStmt->ignoreExists;
  return buildCreateDbRetentions(pStmt->pOptions->pRetentions, pReq);
X
Xiaoyu Wang 已提交
3796 3797
}

3798
static int32_t checkRangeOption(STranslateContext* pCxt, int32_t code, const char* pName, int32_t val, int32_t minVal,
wmmhello's avatar
wmmhello 已提交
3799 3800
                                int32_t maxVal) {
  if (val >= 0 && (val < minVal || val > maxVal)) {
X
Xiaoyu Wang 已提交
3801 3802
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, code, "Invalid option %s: %d valid range: [%d, %d]", pName, val,
                                   minVal, maxVal);
wmmhello's avatar
wmmhello 已提交
3803 3804
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3805 3806
}

3807 3808 3809 3810 3811 3812 3813 3814 3815 3816
static int32_t checkDbRangeOption(STranslateContext* pCxt, const char* pName, int32_t val, int32_t minVal,
                                  int32_t maxVal) {
  return checkRangeOption(pCxt, TSDB_CODE_PAR_INVALID_DB_OPTION, pName, val, minVal, maxVal);
}

static int32_t checkTableRangeOption(STranslateContext* pCxt, const char* pName, int32_t val, int32_t minVal,
                                     int32_t maxVal) {
  return checkRangeOption(pCxt, TSDB_CODE_PAR_INVALID_TABLE_OPTION, pName, val, minVal, maxVal);
}

X
Xiaoyu Wang 已提交
3817
static int32_t checkDbDaysOption(STranslateContext* pCxt, SDatabaseOptions* pOptions) {
wmmhello's avatar
wmmhello 已提交
3818 3819 3820 3821 3822 3823
  if (NULL != pOptions->pDaysPerFile) {
    if (DEAL_RES_ERROR == translateValue(pCxt, pOptions->pDaysPerFile)) {
      return pCxt->errCode;
    }
    if (TIME_UNIT_MINUTE != pOptions->pDaysPerFile->unit && TIME_UNIT_HOUR != pOptions->pDaysPerFile->unit &&
        TIME_UNIT_DAY != pOptions->pDaysPerFile->unit) {
3824 3825 3826
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
                                     "Invalid option duration unit: %c, only %c, %c, %c allowed",
                                     pOptions->pDaysPerFile->unit, TIME_UNIT_MINUTE, TIME_UNIT_HOUR, TIME_UNIT_DAY);
wmmhello's avatar
wmmhello 已提交
3827 3828 3829
    }
    pOptions->daysPerFile = getBigintFromValueNode(pOptions->pDaysPerFile);
  }
3830
  return checkDbRangeOption(pCxt, "daysPerFile", pOptions->daysPerFile, TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
X
Xiaoyu Wang 已提交
3831 3832
}

X
Xiaoyu Wang 已提交
3833
static int32_t checkDbKeepOption(STranslateContext* pCxt, SDatabaseOptions* pOptions) {
wmmhello's avatar
wmmhello 已提交
3834 3835 3836 3837 3838 3839
  if (NULL == pOptions->pKeep) {
    return TSDB_CODE_SUCCESS;
  }

  int32_t numOfKeep = LIST_LENGTH(pOptions->pKeep);
  if (numOfKeep > 3 || numOfKeep < 1) {
3840
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION, "Invalid number of keep options");
wmmhello's avatar
wmmhello 已提交
3841 3842 3843 3844 3845 3846 3847 3848 3849 3850
  }

  SNode* pNode = NULL;
  FOREACH(pNode, pOptions->pKeep) {
    SValueNode* pVal = (SValueNode*)pNode;
    if (DEAL_RES_ERROR == translateValue(pCxt, pVal)) {
      return pCxt->errCode;
    }
    if (pVal->isDuration && TIME_UNIT_MINUTE != pVal->unit && TIME_UNIT_HOUR != pVal->unit &&
        TIME_UNIT_DAY != pVal->unit) {
3851 3852
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
                                     "Invalid option keep unit: %c, only m, h, d allowed", pVal->unit);
wmmhello's avatar
wmmhello 已提交
3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873
    }
    if (!pVal->isDuration) {
      pVal->datum.i = pVal->datum.i * 1440;
    }
  }

  pOptions->keep[0] = getBigintFromValueNode((SValueNode*)nodesListGetNode(pOptions->pKeep, 0));

  if (numOfKeep < 2) {
    pOptions->keep[1] = pOptions->keep[0];
  } else {
    pOptions->keep[1] = getBigintFromValueNode((SValueNode*)nodesListGetNode(pOptions->pKeep, 1));
  }
  if (numOfKeep < 3) {
    pOptions->keep[2] = pOptions->keep[1];
  } else {
    pOptions->keep[2] = getBigintFromValueNode((SValueNode*)nodesListGetNode(pOptions->pKeep, 2));
  }

  if (pOptions->keep[0] < TSDB_MIN_KEEP || pOptions->keep[1] < TSDB_MIN_KEEP || pOptions->keep[2] < TSDB_MIN_KEEP ||
      pOptions->keep[0] > TSDB_MAX_KEEP || pOptions->keep[1] > TSDB_MAX_KEEP || pOptions->keep[2] > TSDB_MAX_KEEP) {
3874 3875 3876 3877
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
                                   "Invalid option keep: %" PRId64 ", %" PRId64 ", %" PRId64 " valid range: [%dm, %dm]",
                                   pOptions->keep[0], pOptions->keep[1], pOptions->keep[2], TSDB_MIN_KEEP,
                                   TSDB_MAX_KEEP);
wmmhello's avatar
wmmhello 已提交
3878 3879 3880
  }

  if (!((pOptions->keep[0] <= pOptions->keep[1]) && (pOptions->keep[1] <= pOptions->keep[2]))) {
3881 3882
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
                                   "Invalid keep value, should be keep0 <= keep1 <= keep2");
wmmhello's avatar
wmmhello 已提交
3883 3884 3885
  }

  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3886 3887
}

3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898
static int32_t checkDbCacheModelOption(STranslateContext* pCxt, SDatabaseOptions* pOptions) {
  if ('\0' != pOptions->cacheModelStr[0]) {
    if (0 == strcasecmp(pOptions->cacheModelStr, TSDB_CACHE_MODEL_NONE_STR)) {
      pOptions->cacheModel = TSDB_CACHE_MODEL_NONE;
    } else if (0 == strcasecmp(pOptions->cacheModelStr, TSDB_CACHE_MODEL_LAST_ROW_STR)) {
      pOptions->cacheModel = TSDB_CACHE_MODEL_LAST_ROW;
    } else if (0 == strcasecmp(pOptions->cacheModelStr, TSDB_CACHE_MODEL_LAST_VALUE_STR)) {
      pOptions->cacheModel = TSDB_CACHE_MODEL_LAST_VALUE;
    } else if (0 == strcasecmp(pOptions->cacheModelStr, TSDB_CACHE_MODEL_BOTH_STR)) {
      pOptions->cacheModel = TSDB_CACHE_MODEL_BOTH;
    } else {
3899 3900
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION, "Invalid option cacheModel: %s",
                                     pOptions->cacheModelStr);
3901 3902 3903 3904 3905
    }
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
3906
static int32_t checkDbPrecisionOption(STranslateContext* pCxt, SDatabaseOptions* pOptions) {
wmmhello's avatar
wmmhello 已提交
3907
  if ('\0' != pOptions->precisionStr[0]) {
3908
    if (0 == strcasecmp(pOptions->precisionStr, TSDB_TIME_PRECISION_MILLI_STR)) {
wmmhello's avatar
wmmhello 已提交
3909
      pOptions->precision = TSDB_TIME_PRECISION_MILLI;
3910
    } else if (0 == strcasecmp(pOptions->precisionStr, TSDB_TIME_PRECISION_MICRO_STR)) {
wmmhello's avatar
wmmhello 已提交
3911
      pOptions->precision = TSDB_TIME_PRECISION_MICRO;
3912
    } else if (0 == strcasecmp(pOptions->precisionStr, TSDB_TIME_PRECISION_NANO_STR)) {
wmmhello's avatar
wmmhello 已提交
3913 3914
      pOptions->precision = TSDB_TIME_PRECISION_NANO;
    } else {
3915 3916
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION, "Invalid option precision: %s",
                                     pOptions->precisionStr);
wmmhello's avatar
wmmhello 已提交
3917 3918 3919
    }
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3920
}
X
Xiaoyu Wang 已提交
3921

3922 3923 3924 3925 3926 3927 3928
static int32_t checkDbStrictOption(STranslateContext* pCxt, SDatabaseOptions* pOptions) {
  if ('\0' != pOptions->strictStr[0]) {
    if (0 == strcasecmp(pOptions->strictStr, TSDB_DB_STRICT_OFF_STR)) {
      pOptions->strict = TSDB_DB_STRICT_OFF;
    } else if (0 == strcasecmp(pOptions->strictStr, TSDB_DB_STRICT_ON_STR)) {
      pOptions->strict = TSDB_DB_STRICT_ON;
    } else {
3929 3930
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION, "Invalid option strict: %s",
                                     pOptions->strictStr);
3931 3932 3933 3934 3935
    }
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
3936
static int32_t checkDbEnumOption(STranslateContext* pCxt, const char* pName, int32_t val, int32_t v1, int32_t v2) {
wmmhello's avatar
wmmhello 已提交
3937
  if (val >= 0 && val != v1 && val != v2) {
3938
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
X
Xiaoyu Wang 已提交
3939
                                   "Invalid option %s: %d, only %d, %d allowed", pName, val, v1, v2);
wmmhello's avatar
wmmhello 已提交
3940 3941
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3942 3943 3944
}

static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRetentions) {
wmmhello's avatar
wmmhello 已提交
3945 3946 3947
  if (NULL == pRetentions) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
3948

wmmhello's avatar
wmmhello 已提交
3949
  if (LIST_LENGTH(pRetentions) > 3) {
3950
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION, "Invalid option retentions");
wmmhello's avatar
wmmhello 已提交
3951
  }
X
Xiaoyu Wang 已提交
3952

X
Xiaoyu Wang 已提交
3953 3954 3955
  SValueNode* pPrevFreq = NULL;
  SValueNode* pPrevKeep = NULL;
  SNode*      pRetention = NULL;
wmmhello's avatar
wmmhello 已提交
3956 3957 3958 3959 3960 3961 3962 3963
  FOREACH(pRetention, pRetentions) {
    SNode* pNode = NULL;
    FOREACH(pNode, ((SNodeListNode*)pRetention)->pNodeList) {
      SValueNode* pVal = (SValueNode*)pNode;
      if (DEAL_RES_ERROR == translateValue(pCxt, pVal)) {
        return pCxt->errCode;
      }
    }
X
Xiaoyu Wang 已提交
3964 3965 3966 3967 3968 3969

    SValueNode* pFreq = (SValueNode*)nodesListGetNode(((SNodeListNode*)pRetention)->pNodeList, 0);
    SValueNode* pKeep = (SValueNode*)nodesListGetNode(((SNodeListNode*)pRetention)->pNodeList, 1);
    if (pFreq->datum.i <= 0 || 'n' == pFreq->unit || 'y' == pFreq->unit || pFreq->datum.i >= pKeep->datum.i ||
        (NULL != pPrevFreq && pPrevFreq->datum.i >= pFreq->datum.i) ||
        (NULL != pPrevKeep && pPrevKeep->datum.i > pKeep->datum.i)) {
3970
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION, "Invalid option retentions");
X
Xiaoyu Wang 已提交
3971 3972 3973
    }
    pPrevFreq = pFreq;
    pPrevKeep = pKeep;
wmmhello's avatar
wmmhello 已提交
3974
  }
X
Xiaoyu Wang 已提交
3975

wmmhello's avatar
wmmhello 已提交
3976
  return TSDB_CODE_SUCCESS;
3977 3978
}

3979
static int32_t checkOptionsDependency(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions) {
wmmhello's avatar
wmmhello 已提交
3980
  int32_t daysPerFile = pOptions->daysPerFile;
3981
  int64_t daysToKeep0 = pOptions->keep[0];
wmmhello's avatar
wmmhello 已提交
3982 3983 3984
  if (-1 == daysPerFile && -1 == daysToKeep0) {
    return TSDB_CODE_SUCCESS;
  } else if (-1 == daysPerFile || -1 == daysToKeep0) {
3985
    SDbCfgInfo dbCfg = {0};
wmmhello's avatar
wmmhello 已提交
3986 3987 3988 3989 3990 3991 3992 3993
    int32_t    code = getDBCfg(pCxt, pDbName, &dbCfg);
    if (TSDB_CODE_SUCCESS != code) {
      return code;
    }
    daysPerFile = (-1 == daysPerFile ? dbCfg.daysPerFile : daysPerFile);
    daysToKeep0 = (-1 == daysToKeep0 ? dbCfg.daysToKeep0 : daysToKeep0);
  }
  if (daysPerFile > daysToKeep0) {
X
Xiaoyu Wang 已提交
3994 3995
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
                                   "Invalid duration value, should be keep2 >= keep1 >= keep0 >= duration");
wmmhello's avatar
wmmhello 已提交
3996 3997
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
3998 3999
}

4000
static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions) {
wmmhello's avatar
wmmhello 已提交
4001
  int32_t code =
4002
      checkDbRangeOption(pCxt, "buffer", pOptions->buffer, TSDB_MIN_BUFFER_PER_VNODE, TSDB_MAX_BUFFER_PER_VNODE);
wmmhello's avatar
wmmhello 已提交
4003
  if (TSDB_CODE_SUCCESS == code) {
4004
    code = checkDbCacheModelOption(pCxt, pOptions);
wmmhello's avatar
wmmhello 已提交
4005
  }
4006
  if (TSDB_CODE_SUCCESS == code) {
4007 4008
    code =
        checkDbRangeOption(pCxt, "cacheSize", pOptions->cacheLastSize, TSDB_MIN_DB_CACHE_SIZE, TSDB_MAX_DB_CACHE_SIZE);
4009
  }
wmmhello's avatar
wmmhello 已提交
4010
  if (TSDB_CODE_SUCCESS == code) {
4011 4012
    code =
        checkDbRangeOption(pCxt, "compression", pOptions->compressionLevel, TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
wmmhello's avatar
wmmhello 已提交
4013 4014 4015 4016 4017
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbDaysOption(pCxt, pOptions);
  }
  if (TSDB_CODE_SUCCESS == code) {
4018
    code = checkDbRangeOption(pCxt, "fsyncPeriod", pOptions->fsyncPeriod, TSDB_MIN_FSYNC_PERIOD, TSDB_MAX_FSYNC_PERIOD);
wmmhello's avatar
wmmhello 已提交
4019 4020
  }
  if (TSDB_CODE_SUCCESS == code) {
4021 4022
    code = checkDbRangeOption(pCxt, "maxRowsPerBlock", pOptions->maxRowsPerBlock, TSDB_MIN_MAXROWS_FBLOCK,
                              TSDB_MAX_MAXROWS_FBLOCK);
wmmhello's avatar
wmmhello 已提交
4023 4024
  }
  if (TSDB_CODE_SUCCESS == code) {
4025 4026
    code = checkDbRangeOption(pCxt, "minRowsPerBlock", pOptions->minRowsPerBlock, TSDB_MIN_MINROWS_FBLOCK,
                              TSDB_MAX_MINROWS_FBLOCK);
wmmhello's avatar
wmmhello 已提交
4027 4028 4029 4030 4031
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbKeepOption(pCxt, pOptions);
  }
  if (TSDB_CODE_SUCCESS == code) {
4032
    code = checkDbRangeOption(pCxt, "pages", pOptions->pages, TSDB_MIN_PAGES_PER_VNODE, TSDB_MAX_PAGES_PER_VNODE);
wmmhello's avatar
wmmhello 已提交
4033 4034
  }
  if (TSDB_CODE_SUCCESS == code) {
4035 4036
    code = checkDbRangeOption(pCxt, "pagesize", pOptions->pagesize, TSDB_MIN_PAGESIZE_PER_VNODE,
                              TSDB_MAX_PAGESIZE_PER_VNODE);
wmmhello's avatar
wmmhello 已提交
4037
  }
4038 4039 4040 4041
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbRangeOption(pCxt, "tsdbPagesize", pOptions->tsdbPageSize, TSDB_MIN_TSDB_PAGESIZE,
                              TSDB_MAX_TSDB_PAGESIZE);
  }
wmmhello's avatar
wmmhello 已提交
4042 4043 4044 4045 4046 4047 4048
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbPrecisionOption(pCxt, pOptions);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbEnumOption(pCxt, "replications", pOptions->replica, TSDB_MIN_DB_REPLICA, TSDB_MAX_DB_REPLICA);
  }
  if (TSDB_CODE_SUCCESS == code) {
4049
    code = checkDbStrictOption(pCxt, pOptions);
wmmhello's avatar
wmmhello 已提交
4050 4051 4052 4053 4054
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbEnumOption(pCxt, "walLevel", pOptions->walLevel, TSDB_MIN_WAL_LEVEL, TSDB_MAX_WAL_LEVEL);
  }
  if (TSDB_CODE_SUCCESS == code) {
4055
    code = checkDbRangeOption(pCxt, "vgroups", pOptions->numOfVgroups, TSDB_MIN_VNODES_PER_DB, TSDB_MAX_VNODES_PER_DB);
wmmhello's avatar
wmmhello 已提交
4056 4057 4058 4059 4060 4061 4062 4063
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbEnumOption(pCxt, "singleStable", pOptions->singleStable, TSDB_DB_SINGLE_STABLE_ON,
                             TSDB_DB_SINGLE_STABLE_OFF);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbRetentionsOption(pCxt, pOptions->pRetentions);
  }
X
Xiaoyu Wang 已提交
4064 4065 4066
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbEnumOption(pCxt, "schemaless", pOptions->schemaless, TSDB_DB_SCHEMALESS_ON, TSDB_DB_SCHEMALESS_OFF);
  }
X
Xiaoyu Wang 已提交
4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbRangeOption(pCxt, "walRetentionPeriod", pOptions->walRetentionPeriod,
                              TSDB_DB_MIN_WAL_RETENTION_PERIOD, INT32_MAX);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbRangeOption(pCxt, "walRetentionSize", pOptions->walRetentionSize, TSDB_DB_MIN_WAL_RETENTION_SIZE,
                              INT32_MAX);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbRangeOption(pCxt, "walRollPeriod", pOptions->walRollPeriod, TSDB_DB_MIN_WAL_ROLL_PERIOD, INT32_MAX);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code =
        checkDbRangeOption(pCxt, "walSegmentSize", pOptions->walSegmentSize, TSDB_DB_MIN_WAL_SEGMENT_SIZE, INT32_MAX);
  }
4082
  if (TSDB_CODE_SUCCESS == code) {
H
Hongze Cheng 已提交
4083
    code = checkDbRangeOption(pCxt, "sstTrigger", pOptions->sstTrigger, TSDB_MIN_STT_TRIGGER, TSDB_MAX_STT_TRIGGER);
4084
  }
4085 4086 4087 4088 4089 4090
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbRangeOption(pCxt, "tablePrefix", pOptions->tablePrefix, TSDB_MIN_HASH_PREFIX, TSDB_MAX_HASH_PREFIX);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkDbRangeOption(pCxt, "tableSuffix", pOptions->tableSuffix, TSDB_MIN_HASH_SUFFIX, TSDB_MAX_HASH_SUFFIX);
  }
wmmhello's avatar
wmmhello 已提交
4091 4092 4093 4094
  if (TSDB_CODE_SUCCESS == code) {
    code = checkOptionsDependency(pCxt, pDbName, pOptions);
  }
  return code;
X
Xiaoyu Wang 已提交
4095 4096 4097
}

static int32_t checkCreateDatabase(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt) {
4098 4099 4100 4101
  if (NULL != strchr(pStmt->dbName, '.')) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME,
                                   "The database name cannot contain '.'");
  }
wmmhello's avatar
wmmhello 已提交
4102
  return checkDatabaseOptions(pCxt, pStmt->dbName, pStmt->pOptions);
X
Xiaoyu Wang 已提交
4103 4104
}

H
Hongze Cheng 已提交
4105
typedef int32_t (*FSerializeFunc)(void* pBuf, int32_t bufLen, void* pReq);
4106 4107

static int32_t buildCmdMsg(STranslateContext* pCxt, int16_t msgType, FSerializeFunc func, void* pReq) {
wmmhello's avatar
wmmhello 已提交
4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121
  pCxt->pCmdMsg = taosMemoryMalloc(sizeof(SCmdMsgInfo));
  if (NULL == pCxt->pCmdMsg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
  pCxt->pCmdMsg->msgType = msgType;
  pCxt->pCmdMsg->msgLen = func(NULL, 0, pReq);
  pCxt->pCmdMsg->pMsg = taosMemoryMalloc(pCxt->pCmdMsg->msgLen);
  if (NULL == pCxt->pCmdMsg->pMsg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  func(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, pReq);

  return TSDB_CODE_SUCCESS;
4122 4123
}

4124
static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
4125
  SCreateDbReq createReq = {0};
4126
  int32_t      code = checkCreateDatabase(pCxt, pStmt);
wmmhello's avatar
wmmhello 已提交
4127 4128 4129 4130 4131 4132
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCreateDbReq(pCxt, pStmt, &createReq);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCmdMsg(pCxt, TDMT_MND_CREATE_DB, (FSerializeFunc)tSerializeSCreateDbReq, &createReq);
  }
4133
  tFreeSCreateDbReq(&createReq);
wmmhello's avatar
wmmhello 已提交
4134
  return code;
4135 4136
}

4137
static int32_t translateDropDatabase(STranslateContext* pCxt, SDropDatabaseStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
4138 4139 4140 4141 4142
  SDropDbReq dropReq = {0};
  SName      name = {0};
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
  tNameGetFullDbName(&name, dropReq.db);
  dropReq.ignoreNotExists = pStmt->ignoreNotExists;
4143

wmmhello's avatar
wmmhello 已提交
4144
  return buildCmdMsg(pCxt, TDMT_MND_DROP_DB, (FSerializeFunc)tSerializeSDropDbReq, &dropReq);
4145 4146
}

4147
static void buildAlterDbReq(STranslateContext* pCxt, SAlterDatabaseStmt* pStmt, SAlterDbReq* pReq) {
wmmhello's avatar
wmmhello 已提交
4148 4149 4150 4151 4152 4153 4154 4155 4156 4157
  SName name = {0};
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
  tNameGetFullDbName(&name, pReq->db);
  pReq->buffer = pStmt->pOptions->buffer;
  pReq->pageSize = -1;
  pReq->pages = pStmt->pOptions->pages;
  pReq->daysPerFile = -1;
  pReq->daysToKeep0 = pStmt->pOptions->keep[0];
  pReq->daysToKeep1 = pStmt->pOptions->keep[1];
  pReq->daysToKeep2 = pStmt->pOptions->keep[2];
4158
  pReq->walFsyncPeriod = pStmt->pOptions->fsyncPeriod;
wmmhello's avatar
wmmhello 已提交
4159 4160
  pReq->walLevel = pStmt->pOptions->walLevel;
  pReq->strict = pStmt->pOptions->strict;
4161
  pReq->cacheLast = pStmt->pOptions->cacheModel;
4162
  pReq->cacheLastSize = pStmt->pOptions->cacheLastSize;
wmmhello's avatar
wmmhello 已提交
4163
  pReq->replications = pStmt->pOptions->replica;
4164
  pReq->sstTrigger = pStmt->pOptions->sstTrigger;
wmmhello's avatar
wmmhello 已提交
4165
  return;
4166 4167 4168
}

static int32_t translateAlterDatabase(STranslateContext* pCxt, SAlterDatabaseStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
4169 4170 4171 4172
  int32_t code = checkDatabaseOptions(pCxt, pStmt->dbName, pStmt->pOptions);
  if (TSDB_CODE_SUCCESS != code) {
    return code;
  }
X
Xiaoyu Wang 已提交
4173

wmmhello's avatar
wmmhello 已提交
4174 4175
  SAlterDbReq alterReq = {0};
  buildAlterDbReq(pCxt, pStmt, &alterReq);
4176

wmmhello's avatar
wmmhello 已提交
4177
  return buildCmdMsg(pCxt, TDMT_MND_ALTER_DB, (FSerializeFunc)tSerializeSAlterDbReq, &alterReq);
4178 4179
}

X
Xiaoyu Wang 已提交
4180
static int32_t translateTrimDatabase(STranslateContext* pCxt, STrimDatabaseStmt* pStmt) {
4181
  STrimDbReq req = {.maxSpeed = pStmt->maxSpeed};
X
Xiaoyu Wang 已提交
4182 4183 4184 4185 4186 4187
  SName      name = {0};
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
  tNameGetFullDbName(&name, req.db);
  return buildCmdMsg(pCxt, TDMT_MND_TRIM_DB, (FSerializeFunc)tSerializeSTrimDbReq, &req);
}

X
Xiaoyu Wang 已提交
4188
static int32_t columnDefNodeToField(SNodeList* pList, SArray** pArray) {
wmmhello's avatar
wmmhello 已提交
4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200
  *pArray = taosArrayInit(LIST_LENGTH(pList), sizeof(SField));
  SNode* pNode;
  FOREACH(pNode, pList) {
    SColumnDefNode* pCol = (SColumnDefNode*)pNode;
    SField          field = {.type = pCol->dataType.type, .bytes = calcTypeBytes(pCol->dataType)};
    strcpy(field.name, pCol->colName);
    if (pCol->sma) {
      field.flags |= COL_SMA_ON;
    }
    taosArrayPush(*pArray, &field);
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
4201 4202
}

4203
static SColumnDefNode* findColDef(SNodeList* pCols, const SColumnNode* pCol) {
wmmhello's avatar
wmmhello 已提交
4204 4205 4206 4207 4208 4209 4210
  SNode* pColDef = NULL;
  FOREACH(pColDef, pCols) {
    if (0 == strcmp(pCol->colName, ((SColumnDefNode*)pColDef)->colName)) {
      return (SColumnDefNode*)pColDef;
    }
  }
  return NULL;
X
Xiaoyu Wang 已提交
4211 4212
}

X
Xiaoyu Wang 已提交
4213
static int32_t checkTableSmaOption(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227
  if (NULL != pStmt->pOptions->pSma) {
    SNode* pNode = NULL;
    FOREACH(pNode, pStmt->pCols) { ((SColumnDefNode*)pNode)->sma = false; }
    FOREACH(pNode, pStmt->pOptions->pSma) {
      SColumnNode*    pSmaCol = (SColumnNode*)pNode;
      SColumnDefNode* pColDef = findColDef(pStmt->pCols, pSmaCol);
      if (NULL == pColDef) {
        return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pSmaCol->colName);
      }
      pSmaCol->node.resType = pColDef->dataType;
      pColDef->sma = true;
    }
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
4228 4229
}

X
Xiaoyu Wang 已提交
4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240
static bool validRollupFunc(const char* pFunc) {
  static const char*   rollupFuncs[] = {"avg", "sum", "min", "max", "last", "first"};
  static const int32_t numOfRollupFuncs = (sizeof(rollupFuncs) / sizeof(char*));
  for (int i = 0; i < numOfRollupFuncs; ++i) {
    if (0 == strcmp(rollupFuncs[i], pFunc)) {
      return true;
    }
  }
  return false;
}

4241 4242
static int32_t checkTableRollupOption(STranslateContext* pCxt, SNodeList* pFuncs, bool createStable,
                                      SDbCfgInfo* pDbCfg) {
wmmhello's avatar
wmmhello 已提交
4243
  if (NULL == pFuncs) {
4244 4245
    if (NULL != pDbCfg->pRetensions) {
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION,
4246
                                     "To create a super table in databases configured with the 'RETENTIONS' option, "
4247 4248
                                     "the 'ROLLUP' option must be present");
    }
wmmhello's avatar
wmmhello 已提交
4249 4250
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
4251

4252 4253 4254 4255 4256 4257
  if (!createStable || NULL == pDbCfg->pRetensions) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION,
                                   "Invalid option rollup: Only supported for create super table in databases "
                                   "configured with the 'RETENTIONS' option");
  }
  if (1 != LIST_LENGTH(pFuncs)) {
4258
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION,
4259 4260 4261 4262
                                   "Invalid option rollup: only one function is allowed");
  }
  const char* pFunc = ((SFunctionNode*)nodesListGetNode(pFuncs, 0))->functionName;
  if (!validRollupFunc(pFunc)) {
4263
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION,
4264
                                   "Invalid option rollup: %s function is not supported", pFunc);
wmmhello's avatar
wmmhello 已提交
4265 4266
  }
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
4267 4268
}

4269
static int32_t checkTableTagsSchema(STranslateContext* pCxt, SHashObj* pHash, SNodeList* pTags) {
wmmhello's avatar
wmmhello 已提交
4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289
  int32_t ntags = LIST_LENGTH(pTags);
  if (0 == ntags) {
    return TSDB_CODE_SUCCESS;
  } else if (ntags > TSDB_MAX_TAGS) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_NUM);
  }

  int32_t code = TSDB_CODE_SUCCESS;
  int32_t tagsSize = 0;
  SNode*  pNode = NULL;
  FOREACH(pNode, pTags) {
    SColumnDefNode* pTag = (SColumnDefNode*)pNode;
    int32_t         len = strlen(pTag->colName);
    if (NULL != taosHashGet(pHash, pTag->colName, len)) {
      code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
    }
    if (TSDB_CODE_SUCCESS == code && pTag->dataType.type == TSDB_DATA_TYPE_JSON && ntags > 1) {
      code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
    }
    if (TSDB_CODE_SUCCESS == code) {
4290 4291
      if ((TSDB_DATA_TYPE_VARCHAR == pTag->dataType.type && calcTypeBytes(pTag->dataType) > TSDB_MAX_BINARY_LEN) ||
          (TSDB_DATA_TYPE_NCHAR == pTag->dataType.type && calcTypeBytes(pTag->dataType) > TSDB_MAX_NCHAR_LEN)) {
4292
        code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
wmmhello's avatar
wmmhello 已提交
4293 4294 4295 4296 4297 4298
      }
    }
    if (TSDB_CODE_SUCCESS == code) {
      code = taosHashPut(pHash, pTag->colName, len, &pTag, POINTER_BYTES);
    }
    if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
4299
      tagsSize += calcTypeBytes(pTag->dataType);
wmmhello's avatar
wmmhello 已提交
4300 4301 4302 4303 4304 4305 4306 4307 4308 4309
    } else {
      break;
    }
  }

  if (TSDB_CODE_SUCCESS == code && tagsSize > TSDB_MAX_TAGS_LEN) {
    code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_LENGTH, TSDB_MAX_TAGS_LEN);
  }

  return code;
4310 4311
}

4312
static int32_t checkTableColsSchema(STranslateContext* pCxt, SHashObj* pHash, int32_t ntags, SNodeList* pCols) {
wmmhello's avatar
wmmhello 已提交
4313 4314 4315
  int32_t ncols = LIST_LENGTH(pCols);
  if (ncols < TSDB_MIN_COLUMNS) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
4316
  } else if (ncols + ntags > TSDB_MAX_COLUMNS) {
wmmhello's avatar
wmmhello 已提交
4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
  }

  int32_t code = TSDB_CODE_SUCCESS;

  bool    first = true;
  int32_t rowSize = 0;
  SNode*  pNode = NULL;
  FOREACH(pNode, pCols) {
    SColumnDefNode* pCol = (SColumnDefNode*)pNode;
    if (first) {
      first = false;
      if (TSDB_DATA_TYPE_TIMESTAMP != pCol->dataType.type) {
        code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FIRST_COLUMN);
      }
    }
    if (TSDB_CODE_SUCCESS == code && pCol->dataType.type == TSDB_DATA_TYPE_JSON) {
      code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON);
    }
    int32_t len = strlen(pCol->colName);
    if (TSDB_CODE_SUCCESS == code && NULL != taosHashGet(pHash, pCol->colName, len)) {
      code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
    }
    if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
4341 4342
      if ((TSDB_DATA_TYPE_VARCHAR == pCol->dataType.type && calcTypeBytes(pCol->dataType) > TSDB_MAX_BINARY_LEN) ||
          (TSDB_DATA_TYPE_NCHAR == pCol->dataType.type && calcTypeBytes(pCol->dataType) > TSDB_MAX_NCHAR_LEN)) {
wmmhello's avatar
wmmhello 已提交
4343 4344 4345 4346 4347 4348 4349
        code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
      }
    }
    if (TSDB_CODE_SUCCESS == code) {
      code = taosHashPut(pHash, pCol->colName, len, &pCol, POINTER_BYTES);
    }
    if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
4350
      rowSize += calcTypeBytes(pCol->dataType);
wmmhello's avatar
wmmhello 已提交
4351 4352 4353 4354 4355 4356 4357 4358 4359 4360
    } else {
      break;
    }
  }

  if (TSDB_CODE_SUCCESS == code && rowSize > TSDB_MAX_BYTES_PER_ROW) {
    code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW);
  }

  return code;
4361 4362 4363
}

static int32_t checkTableSchema(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
4364 4365 4366 4367 4368
  SHashObj* pHash = taosHashInit(LIST_LENGTH(pStmt->pTags) + LIST_LENGTH(pStmt->pCols),
                                 taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
  if (NULL == pHash) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
4369

wmmhello's avatar
wmmhello 已提交
4370 4371
  int32_t code = checkTableTagsSchema(pCxt, pHash, pStmt->pTags);
  if (TSDB_CODE_SUCCESS == code) {
4372
    code = checkTableColsSchema(pCxt, pHash, LIST_LENGTH(pStmt->pTags), pStmt->pCols);
wmmhello's avatar
wmmhello 已提交
4373
  }
4374

wmmhello's avatar
wmmhello 已提交
4375 4376
  taosHashCleanup(pHash);
  return code;
4377 4378
}

X
Xiaoyu Wang 已提交
4379 4380 4381 4382 4383
static int32_t getTableDelayOrWatermarkOption(STranslateContext* pCxt, const char* pName, int64_t minVal,
                                              int64_t maxVal, SValueNode* pVal, int64_t* pMaxDelay) {
  int32_t code = (DEAL_RES_ERROR == translateValue(pCxt, pVal) ? pCxt->errCode : TSDB_CODE_SUCCESS);
  if (TSDB_CODE_SUCCESS == code && TIME_UNIT_MILLISECOND != pVal->unit && TIME_UNIT_SECOND != pVal->unit &&
      TIME_UNIT_MINUTE != pVal->unit) {
4384 4385 4386
    code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION,
                                   "Invalid option %s unit: %c, only %c, %c, %c allowed", pName, pVal->unit,
                                   TIME_UNIT_MILLISECOND, TIME_UNIT_SECOND, TIME_UNIT_MINUTE);
X
Xiaoyu Wang 已提交
4387 4388
  }
  if (TSDB_CODE_SUCCESS == code) {
4389
    code = checkTableRangeOption(pCxt, pName, pVal->datum.i, minVal, maxVal);
X
Xiaoyu Wang 已提交
4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401
  }
  if (TSDB_CODE_SUCCESS == code) {
    *pMaxDelay = pVal->datum.i;
  }
  return code;
}

static int32_t getTableMaxDelayOption(STranslateContext* pCxt, SValueNode* pVal, int64_t* pMaxDelay) {
  return getTableDelayOrWatermarkOption(pCxt, "maxDelay", TSDB_MIN_ROLLUP_MAX_DELAY, TSDB_MAX_ROLLUP_MAX_DELAY, pVal,
                                        pMaxDelay);
}

4402 4403
static int32_t checkTableMaxDelayOption(STranslateContext* pCxt, STableOptions* pOptions, bool createStable,
                                        SDbCfgInfo* pDbCfg) {
X
Xiaoyu Wang 已提交
4404 4405 4406 4407
  if (NULL == pOptions->pMaxDelay) {
    return TSDB_CODE_SUCCESS;
  }

4408 4409 4410 4411 4412 4413
  if (!createStable || NULL == pDbCfg->pRetensions) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION,
                                   "Invalid option maxdelay: Only supported for create super table in databases "
                                   "configured with the 'RETENTIONS' option");
  }

X
Xiaoyu Wang 已提交
4414
  if (LIST_LENGTH(pOptions->pMaxDelay) > 2) {
4415
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION, "Invalid option maxdelay");
X
Xiaoyu Wang 已提交
4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431
  }

  int32_t code =
      getTableMaxDelayOption(pCxt, (SValueNode*)nodesListGetNode(pOptions->pMaxDelay, 0), &pOptions->maxDelay1);
  if (TSDB_CODE_SUCCESS == code && 2 == LIST_LENGTH(pOptions->pMaxDelay)) {
    code = getTableMaxDelayOption(pCxt, (SValueNode*)nodesListGetNode(pOptions->pMaxDelay, 1), &pOptions->maxDelay2);
  }

  return code;
}

static int32_t getTableWatermarkOption(STranslateContext* pCxt, SValueNode* pVal, int64_t* pMaxDelay) {
  return getTableDelayOrWatermarkOption(pCxt, "watermark", TSDB_MIN_ROLLUP_WATERMARK, TSDB_MAX_ROLLUP_WATERMARK, pVal,
                                        pMaxDelay);
}

4432 4433
static int32_t checkTableWatermarkOption(STranslateContext* pCxt, STableOptions* pOptions, bool createStable,
                                         SDbCfgInfo* pDbCfg) {
X
Xiaoyu Wang 已提交
4434 4435 4436 4437
  if (NULL == pOptions->pWatermark) {
    return TSDB_CODE_SUCCESS;
  }

4438 4439 4440 4441 4442 4443
  if (!createStable || NULL == pDbCfg->pRetensions) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION,
                                   "Invalid option watermark: Only supported for create super table in databases "
                                   "configured with the 'RETENTIONS' option");
  }

X
Xiaoyu Wang 已提交
4444
  if (LIST_LENGTH(pOptions->pWatermark) > 2) {
4445
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION, "Invalid option watermark");
X
Xiaoyu Wang 已提交
4446
  }
X
Xiaoyu Wang 已提交
4447 4448 4449 4450 4451 4452 4453 4454

  int32_t code =
      getTableWatermarkOption(pCxt, (SValueNode*)nodesListGetNode(pOptions->pWatermark, 0), &pOptions->watermark1);
  if (TSDB_CODE_SUCCESS == code && 2 == LIST_LENGTH(pOptions->pWatermark)) {
    code = getTableWatermarkOption(pCxt, (SValueNode*)nodesListGetNode(pOptions->pWatermark, 1), &pOptions->watermark2);
  }

  return code;
X
Xiaoyu Wang 已提交
4455 4456
}

4457
static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt, bool createStable) {
X
Xiaoyu Wang 已提交
4458 4459 4460 4461 4462
  if (NULL != strchr(pStmt->tableName, '.')) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME,
                                   "The table name cannot contain '.'");
  }

4463
  SDbCfgInfo dbCfg = {0};
4464 4465 4466 4467 4468
  int32_t    code = getDBCfg(pCxt, pStmt->dbName, &dbCfg);
  if (TSDB_CODE_SUCCESS == code && !createStable && NULL != dbCfg.pRetensions) {
    code = generateSyntaxErrMsgExt(
        &pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION,
        "Only super table creation is supported in databases configured with the 'RETENTIONS' option");
4469 4470 4471 4472
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkTableMaxDelayOption(pCxt, pStmt->pOptions, createStable, &dbCfg);
  }
X
Xiaoyu Wang 已提交
4473
  if (TSDB_CODE_SUCCESS == code) {
4474
    code = checkTableWatermarkOption(pCxt, pStmt->pOptions, createStable, &dbCfg);
X
Xiaoyu Wang 已提交
4475
  }
wmmhello's avatar
wmmhello 已提交
4476
  if (TSDB_CODE_SUCCESS == code) {
4477
    code = checkTableRollupOption(pCxt, pStmt->pOptions->pRollupFuncs, createStable, &dbCfg);
wmmhello's avatar
wmmhello 已提交
4478 4479 4480 4481 4482 4483 4484 4485
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkTableSmaOption(pCxt, pStmt);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkTableSchema(pCxt, pStmt);
  }
  return code;
X
Xiaoyu Wang 已提交
4486 4487
}

4488
static void toSchema(const SColumnDefNode* pCol, col_id_t colId, SSchema* pSchema) {
wmmhello's avatar
wmmhello 已提交
4489 4490 4491 4492 4493 4494 4495 4496 4497
  int8_t flags = 0;
  if (pCol->sma) {
    flags |= COL_SMA_ON;
  }
  pSchema->colId = colId;
  pSchema->type = pCol->dataType.type;
  pSchema->bytes = calcTypeBytes(pCol->dataType);
  pSchema->flags = flags;
  strcpy(pSchema->name, pCol->colName);
4498 4499 4500
}

typedef struct SSampleAstInfo {
wmmhello's avatar
wmmhello 已提交
4501 4502 4503 4504 4505 4506
  const char* pDbName;
  const char* pTableName;
  SNodeList*  pFuncs;
  SNode*      pInterval;
  SNode*      pOffset;
  SNode*      pSliding;
4507
  SNodeList*  pPartitionByList;
wmmhello's avatar
wmmhello 已提交
4508
  STableMeta* pRollupTableMeta;
4509 4510
} SSampleAstInfo;

X
Xiaoyu Wang 已提交
4511 4512
static int32_t buildSampleAst(STranslateContext* pCxt, SSampleAstInfo* pInfo, char** pAst, int32_t* pLen, char** pExpr,
                              int32_t* pExprLen) {
4513
  SSelectStmt* pSelect = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT);
wmmhello's avatar
wmmhello 已提交
4514 4515 4516 4517 4518
  if (NULL == pSelect) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  sprintf(pSelect->stmtName, "%p", pSelect);

4519
  SRealTableNode* pTable = (SRealTableNode*)nodesMakeNode(QUERY_NODE_REAL_TABLE);
wmmhello's avatar
wmmhello 已提交
4520
  if (NULL == pTable) {
4521
    nodesDestroyNode((SNode*)pSelect);
wmmhello's avatar
wmmhello 已提交
4522 4523
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
4524 4525
  snprintf(pTable->table.dbName, sizeof(pTable->table.dbName), "%s", pInfo->pDbName);
  snprintf(pTable->table.tableName, sizeof(pTable->table.tableName), "%s", pInfo->pTableName);
wmmhello's avatar
wmmhello 已提交
4526 4527 4528 4529
  TSWAP(pTable->pMeta, pInfo->pRollupTableMeta);
  pSelect->pFromTable = (SNode*)pTable;

  TSWAP(pSelect->pProjectionList, pInfo->pFuncs);
4530
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
wmmhello's avatar
wmmhello 已提交
4531
  if (NULL == pSelect->pProjectionList || NULL == pFunc) {
4532
    nodesDestroyNode((SNode*)pSelect);
wmmhello's avatar
wmmhello 已提交
4533 4534
    return TSDB_CODE_OUT_OF_MEMORY;
  }
4535
  strcpy(pFunc->functionName, "_wstart");
4536
  nodesListPushFront(pSelect->pProjectionList, (SNode*)pFunc);
wmmhello's avatar
wmmhello 已提交
4537 4538 4539
  SNode* pProject = NULL;
  FOREACH(pProject, pSelect->pProjectionList) { sprintf(((SExprNode*)pProject)->aliasName, "#%p", pProject); }

4540 4541
  TSWAP(pSelect->pPartitionByList, pInfo->pPartitionByList);

4542
  SIntervalWindowNode* pInterval = (SIntervalWindowNode*)nodesMakeNode(QUERY_NODE_INTERVAL_WINDOW);
wmmhello's avatar
wmmhello 已提交
4543
  if (NULL == pInterval) {
4544
    nodesDestroyNode((SNode*)pSelect);
wmmhello's avatar
wmmhello 已提交
4545 4546 4547 4548 4549 4550 4551 4552
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pSelect->pWindow = (SNode*)pInterval;
  TSWAP(pInterval->pInterval, pInfo->pInterval);
  TSWAP(pInterval->pOffset, pInfo->pOffset);
  TSWAP(pInterval->pSliding, pInfo->pSliding);
  pInterval->pCol = nodesMakeNode(QUERY_NODE_COLUMN);
  if (NULL == pInterval->pCol) {
4553
    nodesDestroyNode((SNode*)pSelect);
wmmhello's avatar
wmmhello 已提交
4554 4555 4556
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  ((SColumnNode*)pInterval->pCol)->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
4557
  strcpy(((SColumnNode*)pInterval->pCol)->colName, ROWTS_PSEUDO_COLUMN_NAME);
wmmhello's avatar
wmmhello 已提交
4558

X
Xiaoyu Wang 已提交
4559
  pCxt->createStream = true;
wmmhello's avatar
wmmhello 已提交
4560 4561
  int32_t code = translateQuery(pCxt, (SNode*)pSelect);
  if (TSDB_CODE_SUCCESS == code) {
4562
    code = nodesNodeToString((SNode*)pSelect, false, pAst, pLen);
wmmhello's avatar
wmmhello 已提交
4563
  }
X
Xiaoyu Wang 已提交
4564 4565 4566
  if (TSDB_CODE_SUCCESS == code && NULL != pExpr) {
    code = nodesListToString(pSelect->pProjectionList, false, pExpr, pExprLen);
  }
4567
  nodesDestroyNode((SNode*)pSelect);
wmmhello's avatar
wmmhello 已提交
4568
  return code;
4569 4570 4571
}

static void clearSampleAstInfo(SSampleAstInfo* pInfo) {
wmmhello's avatar
wmmhello 已提交
4572 4573 4574 4575
  nodesDestroyList(pInfo->pFuncs);
  nodesDestroyNode(pInfo->pInterval);
  nodesDestroyNode(pInfo->pOffset);
  nodesDestroyNode(pInfo->pSliding);
4576 4577 4578
}

static SNode* makeIntervalVal(SRetention* pRetension, int8_t precision) {
4579
  SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
wmmhello's avatar
wmmhello 已提交
4580 4581 4582 4583 4584 4585 4586 4587
  if (NULL == pVal) {
    return NULL;
  }
  int64_t timeVal = convertTimeFromPrecisionToUnit(pRetension->freq, precision, pRetension->freqUnit);
  char    buf[20] = {0};
  int32_t len = snprintf(buf, sizeof(buf), "%" PRId64 "%c", timeVal, pRetension->freqUnit);
  pVal->literal = strndup(buf, len);
  if (NULL == pVal->literal) {
4588
    nodesDestroyNode((SNode*)pVal);
wmmhello's avatar
wmmhello 已提交
4589 4590 4591 4592 4593 4594 4595
    return NULL;
  }
  pVal->isDuration = true;
  pVal->node.resType.type = TSDB_DATA_TYPE_BIGINT;
  pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
  pVal->node.resType.precision = precision;
  return (SNode*)pVal;
4596 4597 4598
}

static SNode* createColumnFromDef(SColumnDefNode* pDef) {
4599
  SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
wmmhello's avatar
wmmhello 已提交
4600 4601 4602 4603 4604
  if (NULL == pCol) {
    return NULL;
  }
  strcpy(pCol->colName, pDef->colName);
  return (SNode*)pCol;
4605 4606 4607
}

static SNode* createRollupFunc(SNode* pSrcFunc, SColumnDefNode* pColDef) {
4608
  SFunctionNode* pFunc = (SFunctionNode*)nodesCloneNode(pSrcFunc);
wmmhello's avatar
wmmhello 已提交
4609 4610 4611 4612
  if (NULL == pFunc) {
    return NULL;
  }
  if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pFunc->pParameterList, createColumnFromDef(pColDef))) {
4613
    nodesDestroyNode((SNode*)pFunc);
wmmhello's avatar
wmmhello 已提交
4614 4615 4616
    return NULL;
  }
  return (SNode*)pFunc;
4617 4618 4619
}

static SNodeList* createRollupFuncs(SCreateTableStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641
  SNodeList* pFuncs = nodesMakeList();
  if (NULL == pFuncs) {
    return NULL;
  }

  SNode* pFunc = NULL;
  FOREACH(pFunc, pStmt->pOptions->pRollupFuncs) {
    SNode* pCol = NULL;
    bool   primaryKey = true;
    FOREACH(pCol, pStmt->pCols) {
      if (primaryKey) {
        primaryKey = false;
        continue;
      }
      if (TSDB_CODE_SUCCESS != nodesListStrictAppend(pFuncs, createRollupFunc(pFunc, (SColumnDefNode*)pCol))) {
        nodesDestroyList(pFuncs);
        return NULL;
      }
    }
  }

  return pFuncs;
4642 4643 4644
}

static STableMeta* createRollupTableMeta(SCreateTableStmt* pStmt, int8_t precision) {
wmmhello's avatar
wmmhello 已提交
4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667
  int32_t     numOfField = LIST_LENGTH(pStmt->pCols) + LIST_LENGTH(pStmt->pTags);
  STableMeta* pMeta = taosMemoryCalloc(1, sizeof(STableMeta) + numOfField * sizeof(SSchema));
  if (NULL == pMeta) {
    return NULL;
  }
  pMeta->tableType = TSDB_SUPER_TABLE;
  pMeta->tableInfo.numOfTags = LIST_LENGTH(pStmt->pTags);
  pMeta->tableInfo.precision = precision;
  pMeta->tableInfo.numOfColumns = LIST_LENGTH(pStmt->pCols);

  int32_t index = 0;
  SNode*  pCol = NULL;
  FOREACH(pCol, pStmt->pCols) {
    toSchema((SColumnDefNode*)pCol, index + 1, pMeta->schema + index);
    ++index;
  }
  SNode* pTag = NULL;
  FOREACH(pTag, pStmt->pTags) {
    toSchema((SColumnDefNode*)pTag, index + 1, pMeta->schema + index);
    ++index;
  }

  return pMeta;
4668 4669
}

4670 4671 4672 4673 4674 4675
static SNode* createTbnameFunction() {
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
  if (NULL == pFunc) {
    return NULL;
  }
  strcpy(pFunc->functionName, "tbname");
4676 4677
  strcpy(pFunc->node.aliasName, "tbname");
  strcpy(pFunc->node.userAlias, "tbname");
4678 4679 4680
  return (SNode*)pFunc;
}

L
Liu Jicong 已提交
4681
static int32_t buildSampleAstInfoByTable(STranslateContext* pCxt, SCreateTableStmt* pStmt, SRetention* pRetension,
wmmhello's avatar
wmmhello 已提交
4682 4683 4684 4685 4686 4687 4688 4689 4690
                                         int8_t precision, SSampleAstInfo* pInfo) {
  pInfo->pDbName = pStmt->dbName;
  pInfo->pTableName = pStmt->tableName;
  pInfo->pFuncs = createRollupFuncs(pStmt);
  pInfo->pInterval = makeIntervalVal(pRetension, precision);
  pInfo->pRollupTableMeta = createRollupTableMeta(pStmt, precision);
  if (NULL == pInfo->pFuncs || NULL == pInfo->pInterval || NULL == pInfo->pRollupTableMeta) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
4691
  return nodesListMakeStrictAppend(&pInfo->pPartitionByList, createTbnameFunction());
4692 4693
}

L
Liu Jicong 已提交
4694
static int32_t getRollupAst(STranslateContext* pCxt, SCreateTableStmt* pStmt, SRetention* pRetension, int8_t precision,
wmmhello's avatar
wmmhello 已提交
4695 4696 4697 4698
                            char** pAst, int32_t* pLen) {
  SSampleAstInfo info = {0};
  int32_t        code = buildSampleAstInfoByTable(pCxt, pStmt, pRetension, precision, &info);
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
4699
    code = buildSampleAst(pCxt, &info, pAst, pLen, NULL, NULL);
wmmhello's avatar
wmmhello 已提交
4700 4701 4702
  }
  clearSampleAstInfo(&info);
  return code;
4703 4704 4705
}

static int32_t buildRollupAst(STranslateContext* pCxt, SCreateTableStmt* pStmt, SMCreateStbReq* pReq) {
wmmhello's avatar
wmmhello 已提交
4706 4707 4708 4709 4710 4711 4712 4713 4714
  SDbCfgInfo dbCfg = {0};
  int32_t    code = getDBCfg(pCxt, pStmt->dbName, &dbCfg);
  int32_t    num = taosArrayGetSize(dbCfg.pRetensions);
  if (TSDB_CODE_SUCCESS != code || num < 2) {
    return code;
  }
  for (int32_t i = 1; i < num; ++i) {
    SRetention*       pRetension = taosArrayGet(dbCfg.pRetensions, i);
    STranslateContext cxt = {0};
4715
    initTranslateContext(pCxt->pParseCxt, pCxt->pMetaCache, &cxt);
wmmhello's avatar
wmmhello 已提交
4716 4717 4718 4719 4720 4721 4722
    code = getRollupAst(&cxt, pStmt, pRetension, dbCfg.precision, 1 == i ? &pReq->pAst1 : &pReq->pAst2,
                        1 == i ? &pReq->ast1Len : &pReq->ast2Len);
    destroyTranslateContext(&cxt);
    if (TSDB_CODE_SUCCESS != code) {
      break;
    }
  }
D
dapan1121 已提交
4723

wmmhello's avatar
wmmhello 已提交
4724
  return code;
4725
}
X
Xiaoyu Wang 已提交
4726

D
dapan1121 已提交
4727 4728 4729 4730 4731 4732
static int32_t buildRollupFuncs(SNodeList* pFuncs, SArray** pArray) {
  if (NULL == pFuncs) {
    return TSDB_CODE_SUCCESS;
  }
  *pArray = taosArrayInit(LIST_LENGTH(pFuncs), TSDB_FUNC_NAME_LEN);
  SNode* pNode;
4733
  FOREACH(pNode, pFuncs) { taosArrayPush(*pArray, ((SFunctionNode*)pNode)->functionName); }
D
dapan1121 已提交
4734 4735 4736
  return TSDB_CODE_SUCCESS;
}

4737
static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStmt, SMCreateStbReq* pReq) {
wmmhello's avatar
wmmhello 已提交
4738
  pReq->igExists = pStmt->ignoreExists;
X
Xiaoyu Wang 已提交
4739 4740 4741 4742
  pReq->delay1 = pStmt->pOptions->maxDelay1;
  pReq->delay2 = pStmt->pOptions->maxDelay2;
  pReq->watermark1 = pStmt->pOptions->watermark1;
  pReq->watermark2 = pStmt->pOptions->watermark2;
4743 4744 4745
  pReq->colVer = 1;
  pReq->tagVer = 1;
  pReq->source = TD_REQ_FROM_APP;
wmmhello's avatar
wmmhello 已提交
4746 4747 4748 4749
  columnDefNodeToField(pStmt->pCols, &pReq->pColumns);
  columnDefNodeToField(pStmt->pTags, &pReq->pTags);
  pReq->numOfColumns = LIST_LENGTH(pStmt->pCols);
  pReq->numOfTags = LIST_LENGTH(pStmt->pTags);
X
Xiaoyu Wang 已提交
4750
  if (pStmt->pOptions->commentNull == false) {
S
Shengliang Guan 已提交
4751 4752
    pReq->pComment = strdup(pStmt->pOptions->comment);
    if (NULL == pReq->pComment) {
wmmhello's avatar
wmmhello 已提交
4753 4754
      return TSDB_CODE_OUT_OF_MEMORY;
    }
wmmhello's avatar
wmmhello 已提交
4755
    pReq->commentLen = strlen(pStmt->pOptions->comment);
X
Xiaoyu Wang 已提交
4756
  } else {
wmmhello's avatar
wmmhello 已提交
4757
    pReq->commentLen = -1;
wmmhello's avatar
wmmhello 已提交
4758
  }
D
dapan1121 已提交
4759
  buildRollupFuncs(pStmt->pOptions->pRollupFuncs, &pReq->pFuncs);
S
Shengliang Guan 已提交
4760
  pReq->numOfFuncs = taosArrayGetSize(pReq->pFuncs);
wmmhello's avatar
wmmhello 已提交
4761 4762 4763 4764

  SName tableName;
  tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &tableName), pReq->name);
  int32_t code = collectUseTable(&tableName, pCxt->pTables);
D
dapan1121 已提交
4765 4766 4767
  if (TSDB_CODE_SUCCESS == code) {
    code = collectUseTable(&tableName, pCxt->pTargetTables);
  }
wmmhello's avatar
wmmhello 已提交
4768 4769 4770 4771
  if (TSDB_CODE_SUCCESS == code) {
    code = buildRollupAst(pCxt, pStmt, pReq);
  }
  return code;
4772
}
4773

4774
static int32_t translateCreateSuperTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
4775
  SMCreateStbReq createReq = {0};
4776
  int32_t        code = checkCreateTable(pCxt, pStmt, true);
wmmhello's avatar
wmmhello 已提交
4777 4778 4779 4780 4781 4782 4783 4784
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCreateStbReq(pCxt, pStmt, &createReq);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCmdMsg(pCxt, TDMT_MND_CREATE_STB, (FSerializeFunc)tSerializeSMCreateStbReq, &createReq);
  }
  tFreeSMCreateStbReq(&createReq);
  return code;
4785 4786
}

4787
static int32_t doTranslateDropSuperTable(STranslateContext* pCxt, const SName* pTableName, bool ignoreNotExists) {
D
dapan1121 已提交
4788 4789 4790 4791 4792 4793 4794 4795
  int32_t code = collectUseTable(pTableName, pCxt->pTargetTables);
  if (TSDB_CODE_SUCCESS == code) {
    SMDropStbReq dropReq = {0};
    tNameExtractFullName(pTableName, dropReq.name);
    dropReq.igNotExists = ignoreNotExists;
    code = buildCmdMsg(pCxt, TDMT_MND_DROP_STB, (FSerializeFunc)tSerializeSMDropStbReq, &dropReq);
  }
  return code;
4796 4797 4798
}

static int32_t translateDropTable(STranslateContext* pCxt, SDropTableStmt* pStmt) {
4799
  SDropTableClause* pClause = (SDropTableClause*)nodesListGetNode(pStmt->pTables, 0);
X
Xiaoyu Wang 已提交
4800 4801 4802
  SName             tableName;
  return doTranslateDropSuperTable(
      pCxt, toName(pCxt->pParseCxt->acctId, pClause->dbName, pClause->tableName, &tableName), pClause->ignoreNotExists);
4803 4804 4805
}

static int32_t translateDropSuperTable(STranslateContext* pCxt, SDropSuperTableStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
4806 4807 4808
  SName tableName;
  return doTranslateDropSuperTable(pCxt, toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &tableName),
                                   pStmt->ignoreNotExists);
4809 4810
}

X
Xiaoyu Wang 已提交
4811 4812 4813 4814 4815
static int32_t buildAlterSuperTableReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, SMAlterStbReq* pAlterReq) {
  SName tableName;
  tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &tableName), pAlterReq->name);
  pAlterReq->alterType = pStmt->alterType;

wmmhello's avatar
wmmhello 已提交
4816
  if (TSDB_ALTER_TABLE_UPDATE_OPTIONS == pStmt->alterType) {
X
Xiaoyu Wang 已提交
4817
    //    pAlterReq->ttl = pStmt->pOptions->ttl;
wmmhello's avatar
wmmhello 已提交
4818
    if (pStmt->pOptions->commentNull == false) {
wmmhello's avatar
wmmhello 已提交
4819 4820 4821 4822
      pAlterReq->comment = strdup(pStmt->pOptions->comment);
      if (NULL == pAlterReq->comment) {
        return TSDB_CODE_OUT_OF_MEMORY;
      }
wmmhello's avatar
wmmhello 已提交
4823
      pAlterReq->commentLen = strlen(pStmt->pOptions->comment);
X
Xiaoyu Wang 已提交
4824
    } else {
wmmhello's avatar
wmmhello 已提交
4825
      pAlterReq->commentLen = -1;
wmmhello's avatar
wmmhello 已提交
4826
    }
wmmhello's avatar
wmmhello 已提交
4827

wmmhello's avatar
wmmhello 已提交
4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863
    return TSDB_CODE_SUCCESS;
  }

  pAlterReq->pFields = taosArrayInit(2, sizeof(TAOS_FIELD));
  if (NULL == pAlterReq->pFields) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  switch (pStmt->alterType) {
    case TSDB_ALTER_TABLE_ADD_TAG:
    case TSDB_ALTER_TABLE_DROP_TAG:
    case TSDB_ALTER_TABLE_ADD_COLUMN:
    case TSDB_ALTER_TABLE_DROP_COLUMN:
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
    case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES: {
      TAOS_FIELD field = {.type = pStmt->dataType.type, .bytes = calcTypeBytes(pStmt->dataType)};
      strcpy(field.name, pStmt->colName);
      taosArrayPush(pAlterReq->pFields, &field);
      break;
    }
    case TSDB_ALTER_TABLE_UPDATE_TAG_NAME:
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: {
      TAOS_FIELD oldField = {0};
      strcpy(oldField.name, pStmt->colName);
      taosArrayPush(pAlterReq->pFields, &oldField);
      TAOS_FIELD newField = {0};
      strcpy(newField.name, pStmt->newColName);
      taosArrayPush(pAlterReq->pFields, &newField);
      break;
    }
    default:
      break;
  }

  pAlterReq->numOfFields = taosArrayGetSize(pAlterReq->pFields);
  return TSDB_CODE_SUCCESS;
4864 4865
}

4866
static SSchema* getColSchema(STableMeta* pTableMeta, const char* pColName) {
X
Xiaoyu Wang 已提交
4867 4868
  int32_t numOfFields = getNumOfTags(pTableMeta) + getNumOfColumns(pTableMeta);
  for (int32_t i = 0; i < numOfFields; ++i) {
4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883
    SSchema* pSchema = pTableMeta->schema + i;
    if (0 == strcmp(pColName, pSchema->name)) {
      return pSchema;
    }
  }
  return NULL;
}

static SSchema* getTagSchema(STableMeta* pTableMeta, const char* pTagName) {
  int32_t  numOfTags = getNumOfTags(pTableMeta);
  SSchema* pTagsSchema = getTableTagSchema(pTableMeta);
  for (int32_t i = 0; i < numOfTags; ++i) {
    SSchema* pSchema = pTagsSchema + i;
    if (0 == strcmp(pTagName, pSchema->name)) {
      return pSchema;
X
Xiaoyu Wang 已提交
4884 4885 4886 4887 4888
    }
  }
  return NULL;
}

4889
static int32_t checkAlterSuperTableBySchema(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta) {
4890 4891 4892 4893 4894 4895 4896
  SSchema* pTagsSchema = getTableTagSchema(pTableMeta);
  if (getNumOfTags(pTableMeta) == 1 && pTagsSchema->type == TSDB_DATA_TYPE_JSON &&
      (pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG || pStmt->alterType == TSDB_ALTER_TABLE_DROP_TAG ||
       pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_TAG_BYTES)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
  }

X
Xiaoyu Wang 已提交
4897 4898 4899 4900 4901
  int32_t tagsLen = 0;
  for (int32_t i = 0; i < pTableMeta->tableInfo.numOfTags; ++i) {
    tagsLen += pTagsSchema[i].bytes;
  }

X
Xiaoyu Wang 已提交
4902 4903
  if (TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES == pStmt->alterType ||
      TSDB_ALTER_TABLE_UPDATE_TAG_BYTES == pStmt->alterType) {
4904 4905 4906
    if (TSDB_SUPER_TABLE != pTableMeta->tableType) {
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE, "Table is not super table");
    }
4907

4908 4909 4910 4911 4912 4913
    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->type != pStmt->dataType.type ||
               pSchema->bytes >= calcTypeBytes(pStmt->dataType)) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL);
X
Xiaoyu Wang 已提交
4914
    }
X
Xiaoyu Wang 已提交
4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944

    if (TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES == pStmt->alterType &&
        pTableMeta->tableInfo.rowSize + calcTypeBytes(pStmt->dataType) - pSchema->bytes > TSDB_MAX_BYTES_PER_ROW) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW);
    }

    if (TSDB_ALTER_TABLE_UPDATE_TAG_BYTES == pStmt->alterType &&
        tagsLen + calcTypeBytes(pStmt->dataType) - pSchema->bytes > TSDB_MAX_TAGS_LEN) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_LENGTH, TSDB_MAX_TAGS_LEN);
    }
  }

  if (TSDB_ALTER_TABLE_ADD_COLUMN == pStmt->alterType) {
    if (TSDB_MAX_COLUMNS == pTableMeta->tableInfo.numOfColumns) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
    }

    if (pTableMeta->tableInfo.rowSize + calcTypeBytes(pStmt->dataType) > TSDB_MAX_BYTES_PER_ROW) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW);
    }
  }

  if (TSDB_ALTER_TABLE_ADD_TAG == pStmt->alterType) {
    if (TSDB_MAX_TAGS == pTableMeta->tableInfo.numOfTags) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_NUM);
    }

    if (tagsLen + calcTypeBytes(pStmt->dataType) > TSDB_MAX_TAGS_LEN) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_LENGTH, TSDB_MAX_TAGS_LEN);
    }
X
Xiaoyu Wang 已提交
4945
  }
X
Xiaoyu Wang 已提交
4946

X
Xiaoyu Wang 已提交
4947 4948 4949
  return TSDB_CODE_SUCCESS;
}

4950
static int32_t checkAlterSuperTable(STranslateContext* pCxt, SAlterTableStmt* pStmt) {
4951
  if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == pStmt->alterType) {
4952 4953 4954 4955
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE,
                                   "Set tag value only available for child table");
  }

4956 4957 4958 4959 4960
  if (TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME == pStmt->alterType) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE,
                                   "Rename column only available for normal table");
  }

4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972
  if (pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_OPTIONS && -1 != pStmt->pOptions->ttl) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE);
  }

  if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
  }

  if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON);
  }

4973 4974 4975 4976 4977 4978 4979 4980 4981
  SDbCfgInfo dbCfg = {0};
  int32_t    code = getDBCfg(pCxt, pStmt->dbName, &dbCfg);
  if (TSDB_CODE_SUCCESS == code && NULL != dbCfg.pRetensions &&
      (TSDB_ALTER_TABLE_ADD_COLUMN == pStmt->alterType || TSDB_ALTER_TABLE_DROP_COLUMN == pStmt->alterType ||
       TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES == pStmt->alterType)) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE,
                                   "Modifying the table schema is not supported in databases "
                                   "configured with the 'RETENTIONS' option");
  }
4982 4983
  STableMeta* pTableMeta = NULL;
  if (TSDB_CODE_SUCCESS == code) {
4984 4985 4986 4987
    code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = checkAlterSuperTableBySchema(pCxt, pStmt, pTableMeta);
4988 4989 4990 4991 4992
  }
  taosMemoryFree(pTableMeta);
  return code;
}

X
Xiaoyu Wang 已提交
4993 4994 4995 4996 4997 4998
static int32_t translateAlterSuperTable(STranslateContext* pCxt, SAlterTableStmt* pStmt) {
  SMAlterStbReq alterReq = {0};
  int32_t       code = checkAlterSuperTable(pCxt, pStmt);
  if (TSDB_CODE_SUCCESS == code) {
    code = buildAlterSuperTableReq(pCxt, pStmt, &alterReq);
  }
X
Xiaoyu Wang 已提交
4999 5000 5001
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCmdMsg(pCxt, TDMT_MND_ALTER_STB, (FSerializeFunc)tSerializeSMAlterStbReq, &alterReq);
  }
5002
  tFreeSMAltertbReq(&alterReq);
X
Xiaoyu Wang 已提交
5003
  return code;
5004 5005
}

5006
static int32_t translateUseDatabase(STranslateContext* pCxt, SUseDatabaseStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5007 5008 5009 5010
  SUseDbReq usedbReq = {0};
  SName     name = {0};
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
  tNameExtractFullName(&name, usedbReq.db);
X
Xiaoyu Wang 已提交
5011 5012
  int32_t code =
      getDBVgVersion(pCxt, usedbReq.db, &usedbReq.vgVersion, &usedbReq.dbId, &usedbReq.numOfTable, &usedbReq.stateTs);
wmmhello's avatar
wmmhello 已提交
5013 5014 5015 5016
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCmdMsg(pCxt, TDMT_MND_USE_DB, (FSerializeFunc)tSerializeSUseDbReq, &usedbReq);
  }
  return code;
5017 5018
}

5019
static int32_t translateCreateUser(STranslateContext* pCxt, SCreateUserStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5020 5021 5022 5023
  SCreateUserReq createReq = {0};
  strcpy(createReq.user, pStmt->useName);
  createReq.createType = 0;
  createReq.superUser = 0;
X
Xiaoyu Wang 已提交
5024
  createReq.sysInfo = pStmt->sysinfo;
5025
  createReq.enable = 1;
wmmhello's avatar
wmmhello 已提交
5026
  strcpy(createReq.pass, pStmt->password);
5027

wmmhello's avatar
wmmhello 已提交
5028
  return buildCmdMsg(pCxt, TDMT_MND_CREATE_USER, (FSerializeFunc)tSerializeSCreateUserReq, &createReq);
5029 5030 5031
}

static int32_t translateAlterUser(STranslateContext* pCxt, SAlterUserStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5032 5033 5034 5035
  SAlterUserReq alterReq = {0};
  strcpy(alterReq.user, pStmt->useName);
  alterReq.alterType = pStmt->alterType;
  alterReq.superUser = 0;
X
Xiaoyu Wang 已提交
5036 5037
  alterReq.enable = pStmt->enable;
  alterReq.sysInfo = pStmt->sysinfo;
X
Xiaoyu Wang 已提交
5038
  snprintf(alterReq.pass, sizeof(alterReq.pass), "%s", pStmt->password);
wmmhello's avatar
wmmhello 已提交
5039
  if (NULL != pCxt->pParseCxt->db) {
5040
    snprintf(alterReq.objname, sizeof(alterReq.objname), "%s", pCxt->pParseCxt->db);
wmmhello's avatar
wmmhello 已提交
5041
  }
5042

wmmhello's avatar
wmmhello 已提交
5043
  return buildCmdMsg(pCxt, TDMT_MND_ALTER_USER, (FSerializeFunc)tSerializeSAlterUserReq, &alterReq);
5044 5045 5046
}

static int32_t translateDropUser(STranslateContext* pCxt, SDropUserStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5047 5048
  SDropUserReq dropReq = {0};
  strcpy(dropReq.user, pStmt->useName);
5049

wmmhello's avatar
wmmhello 已提交
5050
  return buildCmdMsg(pCxt, TDMT_MND_DROP_USER, (FSerializeFunc)tSerializeSDropUserReq, &dropReq);
5051 5052 5053
}

static int32_t translateCreateDnode(STranslateContext* pCxt, SCreateDnodeStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5054 5055 5056
  SCreateDnodeReq createReq = {0};
  strcpy(createReq.fqdn, pStmt->fqdn);
  createReq.port = pStmt->port;
5057

wmmhello's avatar
wmmhello 已提交
5058
  return buildCmdMsg(pCxt, TDMT_MND_CREATE_DNODE, (FSerializeFunc)tSerializeSCreateDnodeReq, &createReq);
5059 5060 5061
}

static int32_t translateDropDnode(STranslateContext* pCxt, SDropDnodeStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5062 5063 5064 5065
  SDropDnodeReq dropReq = {0};
  dropReq.dnodeId = pStmt->dnodeId;
  strcpy(dropReq.fqdn, pStmt->fqdn);
  dropReq.port = pStmt->port;
5066
  dropReq.force = pStmt->force;
5067

wmmhello's avatar
wmmhello 已提交
5068
  return buildCmdMsg(pCxt, TDMT_MND_DROP_DNODE, (FSerializeFunc)tSerializeSDropDnodeReq, &dropReq);
5069 5070
}

5071
static int32_t translateAlterDnode(STranslateContext* pCxt, SAlterDnodeStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5072 5073 5074 5075
  SMCfgDnodeReq cfgReq = {0};
  cfgReq.dnodeId = pStmt->dnodeId;
  strcpy(cfgReq.config, pStmt->config);
  strcpy(cfgReq.value, pStmt->value);
5076

wmmhello's avatar
wmmhello 已提交
5077
  return buildCmdMsg(pCxt, TDMT_MND_CONFIG_DNODE, (FSerializeFunc)tSerializeSMCfgDnodeReq, &cfgReq);
5078 5079
}

X
Xiaoyu Wang 已提交
5080 5081
static int32_t getSmaIndexDstVgId(STranslateContext* pCxt, const char* pDbName, const char* pTableName,
                                  int32_t* pVgId) {
wmmhello's avatar
wmmhello 已提交
5082
  SVgroupInfo vg = {0};
X
Xiaoyu Wang 已提交
5083
  int32_t     code = getTableHashVgroup(pCxt, pDbName, pTableName, &vg);
wmmhello's avatar
wmmhello 已提交
5084 5085 5086 5087
  if (TSDB_CODE_SUCCESS == code) {
    *pVgId = vg.vgId;
  }
  return code;
X
Xiaoyu Wang 已提交
5088
}
X
Xiaoyu Wang 已提交
5089

X
Xiaoyu Wang 已提交
5090
static int32_t getSmaIndexSql(STranslateContext* pCxt, char** pSql, int32_t* pLen) {
wmmhello's avatar
wmmhello 已提交
5091 5092 5093 5094 5095 5096
  *pSql = strdup(pCxt->pParseCxt->pSql);
  if (NULL == *pSql) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  *pLen = pCxt->pParseCxt->sqlLen + 1;
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
5097 5098
}

5099
static int32_t buildSampleAstInfoByIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt, SSampleAstInfo* pInfo) {
X
Xiaoyu Wang 已提交
5100
  pInfo->pDbName = pStmt->dbName;
wmmhello's avatar
wmmhello 已提交
5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111
  pInfo->pTableName = pStmt->tableName;
  pInfo->pFuncs = nodesCloneList(pStmt->pOptions->pFuncs);
  pInfo->pInterval = nodesCloneNode(pStmt->pOptions->pInterval);
  pInfo->pOffset = nodesCloneNode(pStmt->pOptions->pOffset);
  pInfo->pSliding = nodesCloneNode(pStmt->pOptions->pSliding);
  if (NULL == pInfo->pFuncs || NULL == pInfo->pInterval ||
      (NULL != pStmt->pOptions->pOffset && NULL == pInfo->pOffset) ||
      (NULL != pStmt->pOptions->pSliding && NULL == pInfo->pSliding)) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  return TSDB_CODE_SUCCESS;
5112
}
X
Xiaoyu Wang 已提交
5113

X
Xiaoyu Wang 已提交
5114 5115
static int32_t getSmaIndexAst(STranslateContext* pCxt, SCreateIndexStmt* pStmt, char** pAst, int32_t* pLen,
                              char** pExpr, int32_t* pExprLen) {
wmmhello's avatar
wmmhello 已提交
5116 5117 5118
  SSampleAstInfo info = {0};
  int32_t        code = buildSampleAstInfoByIndex(pCxt, pStmt, &info);
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
5119
    code = buildSampleAst(pCxt, &info, pAst, pLen, pExpr, pExprLen);
wmmhello's avatar
wmmhello 已提交
5120 5121 5122
  }
  clearSampleAstInfo(&info);
  return code;
X
Xiaoyu Wang 已提交
5123 5124 5125
}

static int32_t buildCreateSmaReq(STranslateContext* pCxt, SCreateIndexStmt* pStmt, SMCreateSmaReq* pReq) {
wmmhello's avatar
wmmhello 已提交
5126
  SName name;
X
Xiaoyu Wang 已提交
5127
  tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->indexDbName, pStmt->indexName, &name), pReq->name);
5128 5129
  memset(&name, 0, sizeof(SName));
  tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &name), pReq->stb);
wmmhello's avatar
wmmhello 已提交
5130 5131 5132 5133 5134 5135 5136 5137
  pReq->igExists = pStmt->ignoreExists;
  pReq->interval = ((SValueNode*)pStmt->pOptions->pInterval)->datum.i;
  pReq->intervalUnit = ((SValueNode*)pStmt->pOptions->pInterval)->unit;
  pReq->offset = (NULL != pStmt->pOptions->pOffset ? ((SValueNode*)pStmt->pOptions->pOffset)->datum.i : 0);
  pReq->sliding =
      (NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->datum.i : pReq->interval);
  pReq->slidingUnit =
      (NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->unit : pReq->intervalUnit);
5138 5139
  if (NULL != pStmt->pOptions->pStreamOptions) {
    SStreamOptions* pStreamOpt = (SStreamOptions*)pStmt->pOptions->pStreamOptions;
C
Cary Xu 已提交
5140 5141 5142 5143 5144 5145 5146 5147 5148
    pReq->maxDelay = (NULL != pStreamOpt->pDelay ? ((SValueNode*)pStreamOpt->pDelay)->datum.i : -1);
    pReq->watermark = (NULL != pStreamOpt->pWatermark ? ((SValueNode*)pStreamOpt->pWatermark)->datum.i
                                                      : TSDB_DEFAULT_ROLLUP_WATERMARK);
    if (pReq->watermark < TSDB_MIN_ROLLUP_WATERMARK) {
      pReq->watermark = TSDB_MIN_ROLLUP_WATERMARK;
    }
    if (pReq->watermark > TSDB_MAX_ROLLUP_WATERMARK) {
      pReq->watermark = TSDB_MAX_ROLLUP_WATERMARK;
    }
5149
  }
wmmhello's avatar
wmmhello 已提交
5150

X
Xiaoyu Wang 已提交
5151
  int32_t code = getSmaIndexDstVgId(pCxt, pStmt->dbName, pStmt->tableName, &pReq->dstVgId);
wmmhello's avatar
wmmhello 已提交
5152 5153 5154 5155
  if (TSDB_CODE_SUCCESS == code) {
    code = getSmaIndexSql(pCxt, &pReq->sql, &pReq->sqlLen);
  }
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
5156
    code = getSmaIndexAst(pCxt, pStmt, &pReq->ast, &pReq->astLen, &pReq->expr, &pReq->exprLen);
wmmhello's avatar
wmmhello 已提交
5157 5158 5159
  }

  return code;
X
Xiaoyu Wang 已提交
5160 5161
}

5162 5163
static int32_t checkCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) {
  SDbCfgInfo dbCfg = {0};
X
Xiaoyu Wang 已提交
5164
  int32_t    code = getDBCfg(pCxt, pStmt->dbName, &dbCfg);
5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176
  if (TSDB_CODE_SUCCESS == code && NULL != dbCfg.pRetensions) {
    code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_SMA_INDEX,
                                   "Tables configured with the 'ROLLUP' option do not support creating sma index");
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = doTranslateValue(pCxt, (SValueNode*)pStmt->pOptions->pInterval);
  }
  if (TSDB_CODE_SUCCESS == code && NULL != pStmt->pOptions->pOffset) {
    code = doTranslateValue(pCxt, (SValueNode*)pStmt->pOptions->pOffset);
  }
  if (TSDB_CODE_SUCCESS == code && NULL != pStmt->pOptions->pSliding) {
    code = doTranslateValue(pCxt, (SValueNode*)pStmt->pOptions->pSliding);
wmmhello's avatar
wmmhello 已提交
5177 5178
  }

5179
  if (TSDB_CODE_SUCCESS == code && NULL != pStmt->pOptions->pStreamOptions) {
5180
    SStreamOptions* pStreamOpt = (SStreamOptions*)pStmt->pOptions->pStreamOptions;
5181 5182
    if (NULL != pStreamOpt->pWatermark) {
      code = doTranslateValue(pCxt, (SValueNode*)pStreamOpt->pWatermark);
5183
    }
5184 5185
    if (TSDB_CODE_SUCCESS == code && NULL != pStreamOpt->pDelay) {
      code = doTranslateValue(pCxt, (SValueNode*)pStreamOpt->pDelay);
5186 5187 5188
    }
  }

5189 5190 5191 5192
  return code;
}

static int32_t translateCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5193
  SMCreateSmaReq createSmaReq = {0};
5194 5195 5196 5197
  int32_t        code = checkCreateSmaIndex(pCxt, pStmt);
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCreateSmaReq(pCxt, pStmt, &createSmaReq);
  }
wmmhello's avatar
wmmhello 已提交
5198 5199 5200 5201 5202
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCmdMsg(pCxt, TDMT_MND_CREATE_SMA, (FSerializeFunc)tSerializeSMCreateSmaReq, &createSmaReq);
  }
  tFreeSMCreateSmaReq(&createSmaReq);
  return code;
X
Xiaoyu Wang 已提交
5203
}
5204

dengyihao's avatar
dengyihao 已提交
5205
static int32_t buildCreateFullTextReq(STranslateContext* pCxt, SCreateIndexStmt* pStmt, SMCreateFullTextReq* pReq) {
wmmhello's avatar
wmmhello 已提交
5206
  // impl later
5207
  return TSDB_CODE_SUCCESS;
dengyihao's avatar
dengyihao 已提交
5208
}
5209

dengyihao's avatar
dengyihao 已提交
5210
static int32_t translateCreateFullTextIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5211 5212 5213 5214 5215 5216 5217
  SMCreateFullTextReq createFTReq = {0};
  int32_t             code = buildCreateFullTextReq(pCxt, pStmt, &createFTReq);
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCmdMsg(pCxt, TDMT_MND_CREATE_INDEX, (FSerializeFunc)tSerializeSMCreateFullTextReq, &createFTReq);
  }
  tFreeSMCreateFullTextReq(&createFTReq);
  return code;
dengyihao's avatar
dengyihao 已提交
5218
}
X
Xiaoyu Wang 已提交
5219 5220

static int32_t translateCreateIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) {
5221
  if (INDEX_TYPE_FULLTEXT == pStmt->indexType) {
wmmhello's avatar
wmmhello 已提交
5222 5223
    return translateCreateFullTextIndex(pCxt, pStmt);
  }
5224
  return translateCreateSmaIndex(pCxt, pStmt);
X
Xiaoyu Wang 已提交
5225 5226
}

5227
static int32_t translateDropIndex(STranslateContext* pCxt, SDropIndexStmt* pStmt) {
X
Xiaoyu Wang 已提交
5228 5229
  SMDropSmaReq dropSmaReq = {0};
  SName        name;
X
Xiaoyu Wang 已提交
5230
  tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->indexDbName, pStmt->indexName, &name), dropSmaReq.name);
X
Xiaoyu Wang 已提交
5231 5232
  dropSmaReq.igNotExists = pStmt->ignoreNotExists;
  return buildCmdMsg(pCxt, TDMT_MND_DROP_SMA, (FSerializeFunc)tSerializeSMDropSmaReq, &dropSmaReq);
wmmhello's avatar
wmmhello 已提交
5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249
}

static int16_t getCreateComponentNodeMsgType(ENodeType type) {
  switch (type) {
    case QUERY_NODE_CREATE_QNODE_STMT:
      return TDMT_MND_CREATE_QNODE;
    case QUERY_NODE_CREATE_BNODE_STMT:
      return TDMT_MND_CREATE_BNODE;
    case QUERY_NODE_CREATE_SNODE_STMT:
      return TDMT_MND_CREATE_SNODE;
    case QUERY_NODE_CREATE_MNODE_STMT:
      return TDMT_MND_CREATE_MNODE;
    default:
      break;
  }
  return -1;
}
5250 5251

static int32_t translateCreateComponentNode(STranslateContext* pCxt, SCreateComponentNodeStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5252 5253
  SMCreateQnodeReq createReq = {.dnodeId = pStmt->dnodeId};
  return buildCmdMsg(pCxt, getCreateComponentNodeMsgType(nodeType(pStmt)),
S
Shengliang Guan 已提交
5254
                     (FSerializeFunc)tSerializeSCreateDropMQSNodeReq, &createReq);
X
Xiaoyu Wang 已提交
5255 5256
}

5257
static int16_t getDropComponentNodeMsgType(ENodeType type) {
wmmhello's avatar
wmmhello 已提交
5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270
  switch (type) {
    case QUERY_NODE_DROP_QNODE_STMT:
      return TDMT_MND_DROP_QNODE;
    case QUERY_NODE_DROP_BNODE_STMT:
      return TDMT_MND_DROP_BNODE;
    case QUERY_NODE_DROP_SNODE_STMT:
      return TDMT_MND_DROP_SNODE;
    case QUERY_NODE_DROP_MNODE_STMT:
      return TDMT_MND_DROP_MNODE;
    default:
      break;
  }
  return -1;
5271 5272 5273
}

static int32_t translateDropComponentNode(STranslateContext* pCxt, SDropComponentNodeStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5274 5275
  SDDropQnodeReq dropReq = {.dnodeId = pStmt->dnodeId};
  return buildCmdMsg(pCxt, getDropComponentNodeMsgType(nodeType(pStmt)),
S
Shengliang Guan 已提交
5276
                     (FSerializeFunc)tSerializeSCreateDropMQSNodeReq, &dropReq);
5277 5278
}

X
Xiaoyu Wang 已提交
5279 5280 5281 5282 5283 5284 5285
static int32_t checkTopicQuery(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (pSelect->hasAggFuncs || pSelect->hasInterpFunc || pSelect->hasIndefiniteRowsFunc) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TOPIC_QUERY);
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
5286
static int32_t buildCreateTopicReq(STranslateContext* pCxt, SCreateTopicStmt* pStmt, SCMCreateTopicReq* pReq) {
X
Xiaoyu Wang 已提交
5287
  snprintf(pReq->name, sizeof(pReq->name), "%d.%s", pCxt->pParseCxt->acctId, pStmt->topicName);
wmmhello's avatar
wmmhello 已提交
5288
  pReq->igExists = pStmt->ignoreExists;
X
Xiaoyu Wang 已提交
5289
  pReq->withMeta = pStmt->withMeta;
wmmhello's avatar
wmmhello 已提交
5290 5291 5292 5293 5294 5295 5296

  pReq->sql = strdup(pCxt->pParseCxt->pSql);
  if (NULL == pReq->sql) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  int32_t code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
5297
  SName   name;
5298 5299 5300
  if ('\0' != pStmt->subSTbName[0]) {
    pReq->subType = TOPIC_SUB_TYPE__TABLE;
    toName(pCxt->pParseCxt->acctId, pStmt->subDbName, pStmt->subSTbName, &name);
L
Liu Jicong 已提交
5301
    tNameGetFullDbName(&name, pReq->subDbName);
5302 5303 5304 5305 5306 5307 5308
    tNameExtractFullName(&name, pReq->subStbName);
  } else if ('\0' != pStmt->subDbName[0]) {
    pReq->subType = TOPIC_SUB_TYPE__DB;
    tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->subDbName, strlen(pStmt->subDbName));
    tNameGetFullDbName(&name, pReq->subDbName);
  } else {
    pReq->subType = TOPIC_SUB_TYPE__COLUMN;
L
Liu Jicong 已提交
5309 5310
    char* dbName = ((SRealTableNode*)(((SSelectStmt*)pStmt->pQuery)->pFromTable))->table.dbName;
    tNameSetDbName(&name, pCxt->pParseCxt->acctId, dbName, strlen(dbName));
L
Liu Jicong 已提交
5311
    tNameGetFullDbName(&name, pReq->subDbName);
wmmhello's avatar
wmmhello 已提交
5312 5313
    pCxt->pParseCxt->topicQuery = true;
    code = translateQuery(pCxt, pStmt->pQuery);
X
Xiaoyu Wang 已提交
5314 5315 5316
    if (TSDB_CODE_SUCCESS == code) {
      code = checkTopicQuery(pCxt, (SSelectStmt*)pStmt->pQuery);
    }
wmmhello's avatar
wmmhello 已提交
5317 5318 5319 5320 5321 5322
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL);
    }
  }

  return code;
X
Xiaoyu Wang 已提交
5323 5324 5325
}

static int32_t checkCreateTopic(STranslateContext* pCxt, SCreateTopicStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5326 5327 5328
  if (NULL == pStmt->pQuery) {
    return TSDB_CODE_SUCCESS;
  }
5329

wmmhello's avatar
wmmhello 已提交
5330 5331 5332 5333 5334 5335 5336 5337
  if (QUERY_NODE_SELECT_STMT == nodeType(pStmt->pQuery)) {
    SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
    if (!pSelect->isDistinct && QUERY_NODE_REAL_TABLE == nodeType(pSelect->pFromTable) &&
        NULL == pSelect->pGroupByList && NULL == pSelect->pLimit && NULL == pSelect->pSlimit &&
        NULL == pSelect->pOrderByList && NULL == pSelect->pPartitionByList) {
      return TSDB_CODE_SUCCESS;
    }
  }
X
Xiaoyu Wang 已提交
5338

wmmhello's avatar
wmmhello 已提交
5339
  return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TOPIC_QUERY);
X
Xiaoyu Wang 已提交
5340 5341 5342
}

static int32_t translateCreateTopic(STranslateContext* pCxt, SCreateTopicStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5343 5344 5345 5346 5347 5348
  SCMCreateTopicReq createReq = {0};
  int32_t           code = checkCreateTopic(pCxt, pStmt);
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCreateTopicReq(pCxt, pStmt, &createReq);
  }
  if (TSDB_CODE_SUCCESS == code) {
L
Liu Jicong 已提交
5349
    code = buildCmdMsg(pCxt, TDMT_MND_TMQ_CREATE_TOPIC, (FSerializeFunc)tSerializeSCMCreateTopicReq, &createReq);
wmmhello's avatar
wmmhello 已提交
5350 5351 5352
  }
  tFreeSCMCreateTopicReq(&createReq);
  return code;
5353 5354 5355
}

static int32_t translateDropTopic(STranslateContext* pCxt, SDropTopicStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5356
  SMDropTopicReq dropReq = {0};
5357

wmmhello's avatar
wmmhello 已提交
5358 5359 5360 5361
  SName name;
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->topicName, strlen(pStmt->topicName));
  tNameGetFullDbName(&name, dropReq.name);
  dropReq.igNotExists = pStmt->ignoreNotExists;
5362

L
Liu Jicong 已提交
5363
  return buildCmdMsg(pCxt, TDMT_MND_TMQ_DROP_TOPIC, (FSerializeFunc)tSerializeSMDropTopicReq, &dropReq);
5364 5365
}

X
Xiaoyu Wang 已提交
5366 5367 5368 5369 5370 5371 5372 5373 5374
static int32_t translateDropCGroup(STranslateContext* pCxt, SDropCGroupStmt* pStmt) {
  SMDropCgroupReq dropReq = {0};

  SName name;
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->topicName, strlen(pStmt->topicName));
  tNameGetFullDbName(&name, dropReq.topic);
  dropReq.igNotExists = pStmt->ignoreNotExists;
  strcpy(dropReq.cgroup, pStmt->cgroup);

L
Liu Jicong 已提交
5375
  return buildCmdMsg(pCxt, TDMT_MND_TMQ_DROP_CGROUP, (FSerializeFunc)tSerializeSMDropCgroupReq, &dropReq);
X
Xiaoyu Wang 已提交
5376 5377
}

5378
static int32_t translateAlterLocal(STranslateContext* pCxt, SAlterLocalStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5379 5380
  // todo
  return TSDB_CODE_SUCCESS;
5381 5382
}

5383
static int32_t translateExplain(STranslateContext* pCxt, SExplainStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5384 5385 5386 5387
  if (pStmt->analyze) {
    pCxt->pExplainOpt = pStmt->pOptions;
  }
  return translateQuery(pCxt, pStmt->pQuery);
5388 5389
}

5390
static int32_t translateDescribe(STranslateContext* pCxt, SDescribeStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5391
  return refreshGetTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pStmt->pMeta);
5392 5393
}

5394
static int32_t translateKillConnection(STranslateContext* pCxt, SKillStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5395 5396
  SKillConnReq killReq = {0};
  killReq.connId = pStmt->targetId;
D
dapan1121 已提交
5397
  return buildCmdMsg(pCxt, TDMT_MND_KILL_CONN, (FSerializeFunc)tSerializeSKillConnReq, &killReq);
5398 5399
}

X
Xiaoyu Wang 已提交
5400
static int32_t translateKillQuery(STranslateContext* pCxt, SKillQueryStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5401
  SKillQueryReq killReq = {0};
X
Xiaoyu Wang 已提交
5402
  strcpy(killReq.queryStrId, pStmt->queryId);
wmmhello's avatar
wmmhello 已提交
5403
  return buildCmdMsg(pCxt, TDMT_MND_KILL_QUERY, (FSerializeFunc)tSerializeSKillQueryReq, &killReq);
5404 5405
}

5406
static int32_t translateKillTransaction(STranslateContext* pCxt, SKillStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5407 5408 5409
  SKillTransReq killReq = {0};
  killReq.transId = pStmt->targetId;
  return buildCmdMsg(pCxt, TDMT_MND_KILL_TRANS, (FSerializeFunc)tSerializeSKillTransReq, &killReq);
5410 5411
}

X
Xiaoyu Wang 已提交
5412 5413 5414
static bool crossTableWithoutAggOper(SSelectStmt* pSelect) {
  return NULL == pSelect->pWindow && !pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc &&
         !pSelect->hasInterpFunc && TSDB_SUPER_TABLE == ((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType &&
5415
         !hasPartitionByTbname(pSelect->pPartitionByList);
X
Xiaoyu Wang 已提交
5416 5417
}

X
Xiaoyu Wang 已提交
5418 5419
static bool crossTableWithUdaf(SSelectStmt* pSelect) {
  return pSelect->hasUdaf && TSDB_SUPER_TABLE == ((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType &&
5420
         !hasPartitionByTbname(pSelect->pPartitionByList);
X
Xiaoyu Wang 已提交
5421 5422
}

X
Xiaoyu Wang 已提交
5423
static int32_t checkCreateStream(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
5424 5425 5426 5427 5428 5429 5430 5431 5432 5433
  if (NULL != pStmt->pOptions->pWatermark &&
      (DEAL_RES_ERROR == translateValue(pCxt, (SValueNode*)pStmt->pOptions->pWatermark))) {
    return pCxt->errCode;
  }

  if (NULL != pStmt->pOptions->pDelay &&
      (DEAL_RES_ERROR == translateValue(pCxt, (SValueNode*)pStmt->pOptions->pDelay))) {
    return pCxt->errCode;
  }

wmmhello's avatar
wmmhello 已提交
5434 5435 5436
  if (NULL == pStmt->pQuery) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
5437

5438
  if (QUERY_NODE_SELECT_STMT != nodeType(pStmt->pQuery) || NULL == ((SSelectStmt*)pStmt->pQuery)->pFromTable ||
X
Xiaoyu Wang 已提交
5439
      QUERY_NODE_REAL_TABLE != nodeType(((SSelectStmt*)pStmt->pQuery)->pFromTable)) {
X
Xiaoyu Wang 已提交
5440
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
wmmhello's avatar
wmmhello 已提交
5441
  }
5442

X
Xiaoyu Wang 已提交
5443
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
5444 5445 5446
}

static void getSourceDatabase(SNode* pStmt, int32_t acctId, char* pDbFName) {
wmmhello's avatar
wmmhello 已提交
5447 5448 5449
  SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId};
  strcpy(name.dbname, ((SRealTableNode*)(((SSelectStmt*)pStmt)->pFromTable))->table.dbName);
  tNameGetFullDbName(&name, pDbFName);
X
Xiaoyu Wang 已提交
5450 5451
}

5452 5453 5454
static int32_t addWstartTsToCreateStreamQuery(SNode* pStmt) {
  SSelectStmt* pSelect = (SSelectStmt*)pStmt;
  SNode*       pProj = nodesListGetNode(pSelect->pProjectionList, 0);
5455
  if (NULL == pSelect->pWindow ||
5456
      (QUERY_NODE_FUNCTION == nodeType(pProj) && 0 == strcmp("_wstart", ((SFunctionNode*)pProj)->functionName))) {
5457 5458 5459 5460 5461 5462
    return TSDB_CODE_SUCCESS;
  }
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
  if (NULL == pFunc) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
5463
  strcpy(pFunc->functionName, "_wstart");
5464 5465 5466 5467 5468 5469 5470 5471
  strcpy(pFunc->node.aliasName, pFunc->functionName);
  int32_t code = nodesListPushFront(pSelect->pProjectionList, (SNode*)pFunc);
  if (TSDB_CODE_SUCCESS != code) {
    nodesDestroyNode((SNode*)pFunc);
  }
  return code;
}

5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518
static int32_t addTagsToCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt, SSelectStmt* pSelect) {
  if (NULL == pStmt->pTags) {
    return TSDB_CODE_SUCCESS;
  }

  SNode* pTag = NULL;
  FOREACH(pTag, pStmt->pTags) {
    bool   found = false;
    SNode* pPart = NULL;
    FOREACH(pPart, pSelect->pPartitionByList) {
      if (0 == strcmp(((SColumnDefNode*)pTag)->colName, ((SExprNode*)pPart)->userAlias)) {
        if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pSelect->pTags, nodesCloneNode(pPart))) {
          return TSDB_CODE_OUT_OF_MEMORY;
        }
        found = true;
        break;
      }
    }
    if (!found) {
      return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, ((SColumnDefNode*)pTag)->colName);
    }
  }
  return TSDB_CODE_SUCCESS;
}

typedef struct SRewriteSubtableCxt {
  STranslateContext* pCxt;
  SNodeList*         pPartitionList;
} SRewriteSubtableCxt;

static EDealRes rewriteSubtable(SNode** pNode, void* pContext) {
  if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
    SRewriteSubtableCxt* pCxt = pContext;
    bool                 found = false;
    SNode*               pPart = NULL;
    FOREACH(pPart, pCxt->pPartitionList) {
      if (0 == strcmp(((SColumnNode*)*pNode)->colName, ((SExprNode*)pPart)->userAlias)) {
        SNode* pNew = nodesCloneNode(pPart);
        if (NULL == pNew) {
          pCxt->pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
          return DEAL_RES_ERROR;
        }
        nodesDestroyNode(*pNode);
        *pNode = pNew;
        found = true;
        break;
      }
5519 5520 5521
    }
    if (!found) {
      return generateDealNodeErrMsg(pCxt->pCxt, TSDB_CODE_PAR_INVALID_COLUMN, ((SColumnNode*)*pNode)->colName);
5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558
    }
    return DEAL_RES_IGNORE_CHILD;
  }
  return DEAL_RES_CONTINUE;
}

static int32_t addSubtableNameToCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt,
                                                  SSelectStmt* pSelect) {
  if (NULL == pStmt->pSubtable) {
    return TSDB_CODE_SUCCESS;
  }
  pSelect->pSubtable = nodesCloneNode(pStmt->pSubtable);
  if (NULL == pSelect->pSubtable) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  SRewriteSubtableCxt cxt = {.pCxt = pCxt, .pPartitionList = pSelect->pPartitionByList};
  nodesRewriteExpr(&pSelect->pSubtable, rewriteSubtable, &cxt);
  return pCxt->errCode;
}

static int32_t addSubtableInfoToCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
  SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
  if (NULL == pSelect->pPartitionByList) {
    if (NULL != pStmt->pTags || NULL != pStmt->pSubtable) {
      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
    }
    return TSDB_CODE_SUCCESS;
  }

  int32_t code = addTagsToCreateStreamQuery(pCxt, pStmt, pSelect);
  if (TSDB_CODE_SUCCESS == code) {
    code = addSubtableNameToCreateStreamQuery(pCxt, pStmt, pSelect);
  }

  return code;
}

X
Xiaoyu Wang 已提交
5559 5560
static int32_t checkStreamQuery(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (TSDB_DATA_TYPE_TIMESTAMP != ((SExprNode*)nodesListGetNode(pSelect->pProjectionList, 0))->resType.type ||
X
Xiaoyu Wang 已提交
5561 5562
      !pSelect->isTimeLineResult || crossTableWithoutAggOper(pSelect) || NULL != pSelect->pOrderByList ||
      crossTableWithUdaf(pSelect)) {
X
Xiaoyu Wang 已提交
5563 5564
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
  }
X
Xiaoyu Wang 已提交
5565 5566 5567 5568
  if (NULL != pSelect->pSubtable && TSDB_DATA_TYPE_VARCHAR != ((SExprNode*)pSelect->pSubtable)->resType.type) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
                                   "SUBTABLE expression must be of VARCHAR type");
  }
X
Xiaoyu Wang 已提交
5569 5570 5571
  return TSDB_CODE_SUCCESS;
}

5572
static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt, SCMCreateStreamReq* pReq) {
5573
  pCxt->createStream = true;
5574
  int32_t code = addWstartTsToCreateStreamQuery(pStmt->pQuery);
5575
  if (TSDB_CODE_SUCCESS == code) {
5576 5577 5578 5579
    code = addSubtableInfoToCreateStreamQuery(pCxt, pStmt);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateQuery(pCxt, pStmt->pQuery);
5580
  }
X
Xiaoyu Wang 已提交
5581
  if (TSDB_CODE_SUCCESS == code) {
5582
    code = checkStreamQuery(pCxt, (SSelectStmt*)pStmt->pQuery);
X
Xiaoyu Wang 已提交
5583
  }
5584
  if (TSDB_CODE_SUCCESS == code) {
5585 5586
    getSourceDatabase(pStmt->pQuery, pCxt->pParseCxt->acctId, pReq->sourceDB);
    code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL);
5587 5588 5589 5590
  }
  return code;
}

X
Xiaoyu Wang 已提交
5591
static int32_t buildCreateStreamReq(STranslateContext* pCxt, SCreateStreamStmt* pStmt, SCMCreateStreamReq* pReq) {
wmmhello's avatar
wmmhello 已提交
5592 5593 5594
  pReq->igExists = pStmt->ignoreExists;

  SName name;
L
Liu Jicong 已提交
5595 5596
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->streamName, strlen(pStmt->streamName));
  tNameGetFullDbName(&name, pReq->name);
wmmhello's avatar
wmmhello 已提交
5597 5598 5599 5600 5601 5602 5603

  if ('\0' != pStmt->targetTabName[0]) {
    strcpy(name.dbname, pStmt->targetDbName);
    strcpy(name.tname, pStmt->targetTabName);
    tNameExtractFullName(&name, pReq->targetStbFullName);
  }

5604
  int32_t code = buildCreateStreamQuery(pCxt, pStmt, pReq);
wmmhello's avatar
wmmhello 已提交
5605 5606 5607 5608 5609 5610 5611 5612 5613
  if (TSDB_CODE_SUCCESS == code) {
    pReq->sql = strdup(pCxt->pParseCxt->pSql);
    if (NULL == pReq->sql) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  if (TSDB_CODE_SUCCESS == code) {
    pReq->triggerType = pStmt->pOptions->triggerType;
5614
    pReq->maxDelay = (NULL != pStmt->pOptions->pDelay ? ((SValueNode*)pStmt->pOptions->pDelay)->datum.i : 0);
wmmhello's avatar
wmmhello 已提交
5615
    pReq->watermark = (NULL != pStmt->pOptions->pWatermark ? ((SValueNode*)pStmt->pOptions->pWatermark)->datum.i : 0);
5616
    pReq->fillHistory = pStmt->pOptions->fillHistory;
5617
    pReq->igExpired = pStmt->pOptions->ignoreExpired;
5618 5619
    columnDefNodeToField(pStmt->pTags, &pReq->pTags);
    pReq->numOfTags = LIST_LENGTH(pStmt->pTags);
wmmhello's avatar
wmmhello 已提交
5620 5621 5622
  }

  return code;
X
Xiaoyu Wang 已提交
5623 5624 5625
}

static int32_t translateCreateStream(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5626
  SCMCreateStreamReq createReq = {0};
X
Xiaoyu Wang 已提交
5627

wmmhello's avatar
wmmhello 已提交
5628 5629 5630 5631 5632 5633 5634
  int32_t code = checkCreateStream(pCxt, pStmt);
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCreateStreamReq(pCxt, pStmt, &createReq);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCmdMsg(pCxt, TDMT_MND_CREATE_STREAM, (FSerializeFunc)tSerializeSCMCreateStreamReq, &createReq);
  }
5635

wmmhello's avatar
wmmhello 已提交
5636 5637
  tFreeSCMCreateStreamReq(&createReq);
  return code;
5638 5639 5640
}

static int32_t translateDropStream(STranslateContext* pCxt, SDropStreamStmt* pStmt) {
X
Xiaoyu Wang 已提交
5641 5642 5643 5644 5645 5646
  SMDropStreamReq dropReq = {0};
  SName           name;
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->streamName, strlen(pStmt->streamName));
  tNameGetFullDbName(&name, dropReq.name);
  dropReq.igNotExists = pStmt->ignoreNotExists;
  return buildCmdMsg(pCxt, TDMT_MND_DROP_STREAM, (FSerializeFunc)tSerializeSMDropStreamReq, &dropReq);
5647
}
5648

L
Liu Jicong 已提交
5649
static int32_t readFromFile(char* pName, int32_t* len, char** buf) {
wmmhello's avatar
wmmhello 已提交
5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679
  int64_t filesize = 0;
  if (taosStatFile(pName, &filesize, NULL) < 0) {
    return TAOS_SYSTEM_ERROR(errno);
  }

  *len = filesize;

  if (*len <= 0) {
    return TSDB_CODE_TSC_FILE_EMPTY;
  }

  *buf = taosMemoryCalloc(1, *len);
  if (*buf == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  TdFilePtr tfile = taosOpenFile(pName, O_RDONLY | O_BINARY);
  if (NULL == tfile) {
    taosMemoryFreeClear(*buf);
    return TAOS_SYSTEM_ERROR(errno);
  }

  int64_t s = taosReadFile(tfile, *buf, *len);
  if (s != *len) {
    taosCloseFile(&tfile);
    taosMemoryFreeClear(*buf);
    return TSDB_CODE_TSC_APP_ERROR;
  }
  taosCloseFile(&tfile);
  return TSDB_CODE_SUCCESS;
5680 5681 5682
}

static int32_t translateCreateFunction(STranslateContext* pCxt, SCreateFunctionStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697
  if (fmIsBuiltinFunc(pStmt->funcName)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FUNCTION_NAME);
  }
  SCreateFuncReq req = {0};
  strcpy(req.name, pStmt->funcName);
  req.igExists = pStmt->ignoreExists;
  req.funcType = pStmt->isAgg ? TSDB_FUNC_TYPE_AGGREGATE : TSDB_FUNC_TYPE_SCALAR;
  req.scriptType = TSDB_FUNC_SCRIPT_BIN_LIB;
  req.outputType = pStmt->outputDt.type;
  req.outputLen = pStmt->outputDt.bytes;
  req.bufSize = pStmt->bufSize;
  int32_t code = readFromFile(pStmt->libraryPath, &req.codeLen, &req.pCode);
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCmdMsg(pCxt, TDMT_MND_CREATE_FUNC, (FSerializeFunc)tSerializeSCreateFuncReq, &req);
  }
X
Xiaoyu Wang 已提交
5698
  tFreeSCreateFuncReq(&req);
wmmhello's avatar
wmmhello 已提交
5699
  return code;
5700 5701
}

S
slzhou 已提交
5702
static int32_t translateDropFunction(STranslateContext* pCxt, SDropFunctionStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5703 5704 5705 5706
  SDropFuncReq req = {0};
  strcpy(req.name, pStmt->funcName);
  req.igNotExists = pStmt->ignoreNotExists;
  return buildCmdMsg(pCxt, TDMT_MND_DROP_FUNC, (FSerializeFunc)tSerializeSDropFuncReq, &req);
S
slzhou 已提交
5707 5708
}

5709
static int32_t translateGrant(STranslateContext* pCxt, SGrantStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5710 5711 5712 5713 5714 5715 5716 5717 5718
  SAlterUserReq req = {0};
  if (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_ALL) ||
      (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_READ) &&
       PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_WRITE))) {
    req.alterType = TSDB_ALTER_USER_ADD_ALL_DB;
  } else if (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_READ)) {
    req.alterType = TSDB_ALTER_USER_ADD_READ_DB;
  } else if (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_WRITE)) {
    req.alterType = TSDB_ALTER_USER_ADD_WRITE_DB;
5719 5720
  } else if (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_SUBSCRIBE)) {
    req.alterType = TSDB_ALTER_USER_ADD_SUBSCRIBE_TOPIC;
wmmhello's avatar
wmmhello 已提交
5721 5722
  }
  strcpy(req.user, pStmt->userName);
5723
  sprintf(req.objname, "%d.%s", pCxt->pParseCxt->acctId, pStmt->objName);
wmmhello's avatar
wmmhello 已提交
5724
  return buildCmdMsg(pCxt, TDMT_MND_ALTER_USER, (FSerializeFunc)tSerializeSAlterUserReq, &req);
5725 5726 5727
}

static int32_t translateRevoke(STranslateContext* pCxt, SRevokeStmt* pStmt) {
wmmhello's avatar
wmmhello 已提交
5728 5729 5730 5731 5732 5733 5734 5735 5736
  SAlterUserReq req = {0};
  if (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_ALL) ||
      (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_READ) &&
       PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_WRITE))) {
    req.alterType = TSDB_ALTER_USER_REMOVE_ALL_DB;
  } else if (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_READ)) {
    req.alterType = TSDB_ALTER_USER_REMOVE_READ_DB;
  } else if (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_WRITE)) {
    req.alterType = TSDB_ALTER_USER_REMOVE_WRITE_DB;
5737 5738
  } else if (PRIVILEGE_TYPE_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_SUBSCRIBE)) {
    req.alterType = TSDB_ALTER_USER_REMOVE_SUBSCRIBE_TOPIC;
wmmhello's avatar
wmmhello 已提交
5739 5740
  }
  strcpy(req.user, pStmt->userName);
5741
  sprintf(req.objname, "%d.%s", pCxt->pParseCxt->acctId, pStmt->objName);
wmmhello's avatar
wmmhello 已提交
5742
  return buildCmdMsg(pCxt, TDMT_MND_ALTER_USER, (FSerializeFunc)tSerializeSAlterUserReq, &req);
5743 5744
}

X
Xiaoyu Wang 已提交
5745 5746 5747 5748 5749 5750 5751 5752 5753 5754
static int32_t translateBalanceVgroup(STranslateContext* pCxt, SBalanceVgroupStmt* pStmt) {
  SBalanceVgroupReq req = {0};
  return buildCmdMsg(pCxt, TDMT_MND_BALANCE_VGROUP, (FSerializeFunc)tSerializeSBalanceVgroupReq, &req);
}

static int32_t translateMergeVgroup(STranslateContext* pCxt, SMergeVgroupStmt* pStmt) {
  SMergeVgroupReq req = {.vgId1 = pStmt->vgId1, .vgId2 = pStmt->vgId2};
  return buildCmdMsg(pCxt, TDMT_MND_MERGE_VGROUP, (FSerializeFunc)tSerializeSMergeVgroupReq, &req);
}

X
Xiaoyu Wang 已提交
5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781
static int32_t checkDnodeIds(STranslateContext* pCxt, SRedistributeVgroupStmt* pStmt) {
  int32_t numOfDnodes = LIST_LENGTH(pStmt->pDnodes);
  if (numOfDnodes > 3 || numOfDnodes < 1) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_REDISTRIBUTE_VG);
  }

  SNode* pNode = NULL;
  FOREACH(pNode, pStmt->pDnodes) {
    SValueNode* pVal = (SValueNode*)pNode;
    if (DEAL_RES_ERROR == translateValue(pCxt, pVal)) {
      return pCxt->errCode;
    }
  }

  pStmt->dnodeId1 = getBigintFromValueNode((SValueNode*)nodesListGetNode(pStmt->pDnodes, 0));
  pStmt->dnodeId2 = -1;
  pStmt->dnodeId3 = -1;
  if (numOfDnodes > 1) {
    pStmt->dnodeId2 = getBigintFromValueNode((SValueNode*)nodesListGetNode(pStmt->pDnodes, 1));
  }
  if (numOfDnodes > 2) {
    pStmt->dnodeId3 = getBigintFromValueNode((SValueNode*)nodesListGetNode(pStmt->pDnodes, 2));
  }

  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
5782 5783
static int32_t translateRedistributeVgroup(STranslateContext* pCxt, SRedistributeVgroupStmt* pStmt) {
  SRedistributeVgroupReq req = {.vgId = pStmt->vgId};
X
Xiaoyu Wang 已提交
5784 5785 5786 5787 5788 5789 5790 5791
  int32_t                code = checkDnodeIds(pCxt, pStmt);
  if (TSDB_CODE_SUCCESS == code) {
    req.dnodeId1 = pStmt->dnodeId1;
    req.dnodeId2 = pStmt->dnodeId2;
    req.dnodeId3 = pStmt->dnodeId3;
    code = buildCmdMsg(pCxt, TDMT_MND_REDISTRIBUTE_VGROUP, (FSerializeFunc)tSerializeSRedistributeVgroupReq, &req);
  }
  return code;
X
Xiaoyu Wang 已提交
5792 5793
}

5794 5795 5796 5797 5798
static int32_t translateSplitVgroup(STranslateContext* pCxt, SSplitVgroupStmt* pStmt) {
  SSplitVgroupReq req = {.vgId = pStmt->vgId};
  return buildCmdMsg(pCxt, TDMT_MND_SPLIT_VGROUP, (FSerializeFunc)tSerializeSSplitVgroupReq, &req);
}

X
Xiaoyu Wang 已提交
5799 5800 5801 5802 5803
static int32_t translateShowVariables(STranslateContext* pCxt, SShowStmt* pStmt) {
  SShowVariablesReq req = {0};
  return buildCmdMsg(pCxt, TDMT_MND_SHOW_VARIABLES, (FSerializeFunc)tSerializeSShowVariablesReq, &req);
}

5804 5805 5806 5807 5808 5809 5810 5811 5812
static int32_t translateShowCreateDatabase(STranslateContext* pCxt, SShowCreateDatabaseStmt* pStmt) {
  pStmt->pCfg = taosMemoryCalloc(1, sizeof(SDbCfgInfo));
  if (NULL == pStmt->pCfg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  return getDBCfg(pCxt, pStmt->dbName, (SDbCfgInfo*)pStmt->pCfg);
}

static int32_t translateShowCreateTable(STranslateContext* pCxt, SShowCreateTableStmt* pStmt) {
X
Xiaoyu Wang 已提交
5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823
  pStmt->pDbCfg = taosMemoryCalloc(1, sizeof(SDbCfgInfo));
  if (NULL == pStmt->pDbCfg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  int32_t code = getDBCfg(pCxt, pStmt->dbName, (SDbCfgInfo*)pStmt->pDbCfg);
  if (TSDB_CODE_SUCCESS == code) {
    SName name;
    toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &name);
    code = getTableCfg(pCxt, &name, (STableCfg**)&pStmt->pTableCfg);
  }
  return code;
5824 5825
}

5826
static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
wmmhello's avatar
wmmhello 已提交
5827 5828 5829 5830 5831 5832 5833 5834
  int32_t code = TSDB_CODE_SUCCESS;
  switch (nodeType(pNode)) {
    case QUERY_NODE_SELECT_STMT:
      code = translateSelect(pCxt, (SSelectStmt*)pNode);
      break;
    case QUERY_NODE_SET_OPERATOR:
      code = translateSetOperator(pCxt, (SSetOperator*)pNode);
      break;
X
Xiaoyu Wang 已提交
5835 5836 5837
    case QUERY_NODE_DELETE_STMT:
      code = translateDelete(pCxt, (SDeleteStmt*)pNode);
      break;
5838 5839 5840
    case QUERY_NODE_INSERT_STMT:
      code = translateInsert(pCxt, (SInsertStmt*)pNode);
      break;
wmmhello's avatar
wmmhello 已提交
5841 5842 5843 5844 5845 5846 5847 5848 5849
    case QUERY_NODE_CREATE_DATABASE_STMT:
      code = translateCreateDatabase(pCxt, (SCreateDatabaseStmt*)pNode);
      break;
    case QUERY_NODE_DROP_DATABASE_STMT:
      code = translateDropDatabase(pCxt, (SDropDatabaseStmt*)pNode);
      break;
    case QUERY_NODE_ALTER_DATABASE_STMT:
      code = translateAlterDatabase(pCxt, (SAlterDatabaseStmt*)pNode);
      break;
X
Xiaoyu Wang 已提交
5850 5851 5852
    case QUERY_NODE_TRIM_DATABASE_STMT:
      code = translateTrimDatabase(pCxt, (STrimDatabaseStmt*)pNode);
      break;
wmmhello's avatar
wmmhello 已提交
5853 5854 5855 5856 5857 5858 5859 5860 5861 5862
    case QUERY_NODE_CREATE_TABLE_STMT:
      code = translateCreateSuperTable(pCxt, (SCreateTableStmt*)pNode);
      break;
    case QUERY_NODE_DROP_TABLE_STMT:
      code = translateDropTable(pCxt, (SDropTableStmt*)pNode);
      break;
    case QUERY_NODE_DROP_SUPER_TABLE_STMT:
      code = translateDropSuperTable(pCxt, (SDropSuperTableStmt*)pNode);
      break;
    case QUERY_NODE_ALTER_TABLE_STMT:
5863
    case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
X
Xiaoyu Wang 已提交
5864
      code = translateAlterSuperTable(pCxt, (SAlterTableStmt*)pNode);
wmmhello's avatar
wmmhello 已提交
5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910
      break;
    case QUERY_NODE_CREATE_USER_STMT:
      code = translateCreateUser(pCxt, (SCreateUserStmt*)pNode);
      break;
    case QUERY_NODE_ALTER_USER_STMT:
      code = translateAlterUser(pCxt, (SAlterUserStmt*)pNode);
      break;
    case QUERY_NODE_DROP_USER_STMT:
      code = translateDropUser(pCxt, (SDropUserStmt*)pNode);
      break;
    case QUERY_NODE_USE_DATABASE_STMT:
      code = translateUseDatabase(pCxt, (SUseDatabaseStmt*)pNode);
      break;
    case QUERY_NODE_CREATE_DNODE_STMT:
      code = translateCreateDnode(pCxt, (SCreateDnodeStmt*)pNode);
      break;
    case QUERY_NODE_DROP_DNODE_STMT:
      code = translateDropDnode(pCxt, (SDropDnodeStmt*)pNode);
      break;
    case QUERY_NODE_ALTER_DNODE_STMT:
      code = translateAlterDnode(pCxt, (SAlterDnodeStmt*)pNode);
      break;
    case QUERY_NODE_CREATE_INDEX_STMT:
      code = translateCreateIndex(pCxt, (SCreateIndexStmt*)pNode);
      break;
    case QUERY_NODE_DROP_INDEX_STMT:
      code = translateDropIndex(pCxt, (SDropIndexStmt*)pNode);
      break;
    case QUERY_NODE_CREATE_QNODE_STMT:
    case QUERY_NODE_CREATE_BNODE_STMT:
    case QUERY_NODE_CREATE_SNODE_STMT:
    case QUERY_NODE_CREATE_MNODE_STMT:
      code = translateCreateComponentNode(pCxt, (SCreateComponentNodeStmt*)pNode);
      break;
    case QUERY_NODE_DROP_QNODE_STMT:
    case QUERY_NODE_DROP_BNODE_STMT:
    case QUERY_NODE_DROP_SNODE_STMT:
    case QUERY_NODE_DROP_MNODE_STMT:
      code = translateDropComponentNode(pCxt, (SDropComponentNodeStmt*)pNode);
      break;
    case QUERY_NODE_CREATE_TOPIC_STMT:
      code = translateCreateTopic(pCxt, (SCreateTopicStmt*)pNode);
      break;
    case QUERY_NODE_DROP_TOPIC_STMT:
      code = translateDropTopic(pCxt, (SDropTopicStmt*)pNode);
      break;
X
Xiaoyu Wang 已提交
5911 5912 5913
    case QUERY_NODE_DROP_CGROUP_STMT:
      code = translateDropCGroup(pCxt, (SDropCGroupStmt*)pNode);
      break;
wmmhello's avatar
wmmhello 已提交
5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926
    case QUERY_NODE_ALTER_LOCAL_STMT:
      code = translateAlterLocal(pCxt, (SAlterLocalStmt*)pNode);
      break;
    case QUERY_NODE_EXPLAIN_STMT:
      code = translateExplain(pCxt, (SExplainStmt*)pNode);
      break;
    case QUERY_NODE_DESCRIBE_STMT:
      code = translateDescribe(pCxt, (SDescribeStmt*)pNode);
      break;
    case QUERY_NODE_KILL_CONNECTION_STMT:
      code = translateKillConnection(pCxt, (SKillStmt*)pNode);
      break;
    case QUERY_NODE_KILL_QUERY_STMT:
X
Xiaoyu Wang 已提交
5927
      code = translateKillQuery(pCxt, (SKillQueryStmt*)pNode);
wmmhello's avatar
wmmhello 已提交
5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949
      break;
    case QUERY_NODE_KILL_TRANSACTION_STMT:
      code = translateKillTransaction(pCxt, (SKillStmt*)pNode);
      break;
    case QUERY_NODE_CREATE_STREAM_STMT:
      code = translateCreateStream(pCxt, (SCreateStreamStmt*)pNode);
      break;
    case QUERY_NODE_DROP_STREAM_STMT:
      code = translateDropStream(pCxt, (SDropStreamStmt*)pNode);
      break;
    case QUERY_NODE_CREATE_FUNCTION_STMT:
      code = translateCreateFunction(pCxt, (SCreateFunctionStmt*)pNode);
      break;
    case QUERY_NODE_DROP_FUNCTION_STMT:
      code = translateDropFunction(pCxt, (SDropFunctionStmt*)pNode);
      break;
    case QUERY_NODE_GRANT_STMT:
      code = translateGrant(pCxt, (SGrantStmt*)pNode);
      break;
    case QUERY_NODE_REVOKE_STMT:
      code = translateRevoke(pCxt, (SRevokeStmt*)pNode);
      break;
X
Xiaoyu Wang 已提交
5950 5951 5952 5953 5954 5955 5956 5957 5958
    case QUERY_NODE_BALANCE_VGROUP_STMT:
      code = translateBalanceVgroup(pCxt, (SBalanceVgroupStmt*)pNode);
      break;
    case QUERY_NODE_MERGE_VGROUP_STMT:
      code = translateMergeVgroup(pCxt, (SMergeVgroupStmt*)pNode);
      break;
    case QUERY_NODE_REDISTRIBUTE_VGROUP_STMT:
      code = translateRedistributeVgroup(pCxt, (SRedistributeVgroupStmt*)pNode);
      break;
5959 5960 5961
    case QUERY_NODE_SPLIT_VGROUP_STMT:
      code = translateSplitVgroup(pCxt, (SSplitVgroupStmt*)pNode);
      break;
X
Xiaoyu Wang 已提交
5962 5963 5964
    case QUERY_NODE_SHOW_VARIABLES_STMT:
      code = translateShowVariables(pCxt, (SShowStmt*)pNode);
      break;
5965 5966 5967 5968 5969 5970 5971
    case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
      code = translateShowCreateDatabase(pCxt, (SShowCreateDatabaseStmt*)pNode);
      break;
    case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
    case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
      code = translateShowCreateTable(pCxt, (SShowCreateTableStmt*)pNode);
      break;
wmmhello's avatar
wmmhello 已提交
5972 5973 5974 5975
    default:
      break;
  }
  return code;
5976 5977 5978
}

static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) {
5979 5980
  ESqlClause currClause = pCxt->currClause;
  SNode*     pCurrStmt = pCxt->pCurrStmt;
5981 5982
  int32_t    currLevel = pCxt->currLevel;
  pCxt->currLevel = ++(pCxt->levelNo);
X
Xiaoyu Wang 已提交
5983
  int32_t code = translateQuery(pCxt, pNode);
wmmhello's avatar
wmmhello 已提交
5984
  pCxt->currClause = currClause;
5985
  pCxt->pCurrStmt = pCurrStmt;
5986
  pCxt->currLevel = currLevel;
wmmhello's avatar
wmmhello 已提交
5987
  return code;
5988 5989
}

X
Xiaoyu Wang 已提交
5990
static int32_t extractQueryResultSchema(const SNodeList* pProjections, int32_t* numOfCols, SSchema** pSchema) {
wmmhello's avatar
wmmhello 已提交
5991 5992 5993 5994 5995 5996 5997 5998 5999 6000
  *numOfCols = LIST_LENGTH(pProjections);
  *pSchema = taosMemoryCalloc((*numOfCols), sizeof(SSchema));
  if (NULL == (*pSchema)) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  SNode*  pNode;
  int32_t index = 0;
  FOREACH(pNode, pProjections) {
    SExprNode* pExpr = (SExprNode*)pNode;
6001 6002 6003 6004 6005 6006 6007
    if (TSDB_DATA_TYPE_NULL == pExpr->resType.type) {
      (*pSchema)[index].type = TSDB_DATA_TYPE_VARCHAR;
      (*pSchema)[index].bytes = 0;
    } else {
      (*pSchema)[index].type = pExpr->resType.type;
      (*pSchema)[index].bytes = pExpr->resType.bytes;
    }
wmmhello's avatar
wmmhello 已提交
6008 6009 6010 6011 6012 6013 6014 6015 6016 6017
    (*pSchema)[index].colId = index + 1;
    if ('\0' != pExpr->userAlias[0]) {
      strcpy((*pSchema)[index].name, pExpr->userAlias);
    } else {
      strcpy((*pSchema)[index].name, pExpr->aliasName);
    }
    index += 1;
  }

  return TSDB_CODE_SUCCESS;
6018 6019
}

H
Hongze Cheng 已提交
6020
static int8_t extractResultTsPrecision(const SSelectStmt* pSelect) { return pSelect->precision; }
6021

6022
static int32_t extractExplainResultSchema(int32_t* numOfCols, SSchema** pSchema) {
wmmhello's avatar
wmmhello 已提交
6023 6024 6025 6026 6027 6028 6029 6030 6031
  *numOfCols = 1;
  *pSchema = taosMemoryCalloc((*numOfCols), sizeof(SSchema));
  if (NULL == (*pSchema)) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  (*pSchema)[0].type = TSDB_DATA_TYPE_BINARY;
  (*pSchema)[0].bytes = TSDB_EXPLAIN_RESULT_ROW_SIZE;
  strcpy((*pSchema)[0].name, TSDB_EXPLAIN_RESULT_COLUMN_NAME);
  return TSDB_CODE_SUCCESS;
6032 6033 6034
}

static int32_t extractDescribeResultSchema(int32_t* numOfCols, SSchema** pSchema) {
wmmhello's avatar
wmmhello 已提交
6035 6036 6037 6038 6039
  *numOfCols = DESCRIBE_RESULT_COLS;
  *pSchema = taosMemoryCalloc((*numOfCols), sizeof(SSchema));
  if (NULL == (*pSchema)) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
6040

wmmhello's avatar
wmmhello 已提交
6041 6042 6043
  (*pSchema)[0].type = TSDB_DATA_TYPE_BINARY;
  (*pSchema)[0].bytes = DESCRIBE_RESULT_FIELD_LEN;
  strcpy((*pSchema)[0].name, "field");
6044

wmmhello's avatar
wmmhello 已提交
6045 6046 6047
  (*pSchema)[1].type = TSDB_DATA_TYPE_BINARY;
  (*pSchema)[1].bytes = DESCRIBE_RESULT_TYPE_LEN;
  strcpy((*pSchema)[1].name, "type");
6048

wmmhello's avatar
wmmhello 已提交
6049 6050 6051
  (*pSchema)[2].type = TSDB_DATA_TYPE_INT;
  (*pSchema)[2].bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
  strcpy((*pSchema)[2].name, "length");
6052

wmmhello's avatar
wmmhello 已提交
6053 6054 6055
  (*pSchema)[3].type = TSDB_DATA_TYPE_BINARY;
  (*pSchema)[3].bytes = DESCRIBE_RESULT_NOTE_LEN;
  strcpy((*pSchema)[3].name, "note");
6056

wmmhello's avatar
wmmhello 已提交
6057
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
6058 6059
}

6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085
static int32_t extractShowCreateDatabaseResultSchema(int32_t* numOfCols, SSchema** pSchema) {
  *numOfCols = 2;
  *pSchema = taosMemoryCalloc((*numOfCols), sizeof(SSchema));
  if (NULL == (*pSchema)) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  (*pSchema)[0].type = TSDB_DATA_TYPE_BINARY;
  (*pSchema)[0].bytes = TSDB_DB_NAME_LEN;
  strcpy((*pSchema)[0].name, "Database");

  (*pSchema)[1].type = TSDB_DATA_TYPE_BINARY;
  (*pSchema)[1].bytes = TSDB_MAX_BINARY_LEN;
  strcpy((*pSchema)[1].name, "Create Database");

  return TSDB_CODE_SUCCESS;
}

static int32_t extractShowCreateTableResultSchema(int32_t* numOfCols, SSchema** pSchema) {
  *numOfCols = 2;
  *pSchema = taosMemoryCalloc((*numOfCols), sizeof(SSchema));
  if (NULL == (*pSchema)) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  (*pSchema)[0].type = TSDB_DATA_TYPE_BINARY;
6086
  (*pSchema)[0].bytes = SHOW_CREATE_TB_RESULT_FIELD1_LEN;
6087 6088 6089
  strcpy((*pSchema)[0].name, "Table");

  (*pSchema)[1].type = TSDB_DATA_TYPE_BINARY;
6090
  (*pSchema)[1].bytes = SHOW_CREATE_TB_RESULT_FIELD2_LEN;
6091 6092 6093 6094 6095
  strcpy((*pSchema)[1].name, "Create Table");

  return TSDB_CODE_SUCCESS;
}

D
dapan1121 已提交
6096
static int32_t extractShowVariablesResultSchema(int32_t* numOfCols, SSchema** pSchema) {
D
dapan1121 已提交
6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113
  *numOfCols = 2;
  *pSchema = taosMemoryCalloc((*numOfCols), sizeof(SSchema));
  if (NULL == (*pSchema)) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  (*pSchema)[0].type = TSDB_DATA_TYPE_BINARY;
  (*pSchema)[0].bytes = TSDB_CONFIG_OPTION_LEN;
  strcpy((*pSchema)[0].name, "name");

  (*pSchema)[1].type = TSDB_DATA_TYPE_BINARY;
  (*pSchema)[1].bytes = TSDB_CONFIG_VALUE_LEN;
  strcpy((*pSchema)[1].name, "value");

  return TSDB_CODE_SUCCESS;
}

6114
int32_t extractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema) {
wmmhello's avatar
wmmhello 已提交
6115 6116 6117
  if (NULL == pRoot) {
    return TSDB_CODE_SUCCESS;
  }
6118

wmmhello's avatar
wmmhello 已提交
6119 6120 6121 6122 6123 6124 6125 6126
  switch (nodeType(pRoot)) {
    case QUERY_NODE_SELECT_STMT:
    case QUERY_NODE_SET_OPERATOR:
      return extractQueryResultSchema(getProjectList(pRoot), numOfCols, pSchema);
    case QUERY_NODE_EXPLAIN_STMT:
      return extractExplainResultSchema(numOfCols, pSchema);
    case QUERY_NODE_DESCRIBE_STMT:
      return extractDescribeResultSchema(numOfCols, pSchema);
6127 6128 6129 6130 6131
    case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
      return extractShowCreateDatabaseResultSchema(numOfCols, pSchema);
    case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
    case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
      return extractShowCreateTableResultSchema(numOfCols, pSchema);
D
dapan1121 已提交
6132
    case QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT:
D
dapan1121 已提交
6133 6134
    case QUERY_NODE_SHOW_VARIABLES_STMT:
      return extractShowVariablesResultSchema(numOfCols, pSchema);
wmmhello's avatar
wmmhello 已提交
6135 6136 6137
    default:
      break;
  }
6138

wmmhello's avatar
wmmhello 已提交
6139
  return TSDB_CODE_FAILED;
6140 6141
}

X
Xiaoyu Wang 已提交
6142 6143 6144 6145
static SNode* createStarCol() {
  SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
  if (NULL == pCol) {
    return NULL;
wmmhello's avatar
wmmhello 已提交
6146
  }
X
Xiaoyu Wang 已提交
6147 6148
  strcpy(pCol->colName, "*");
  return (SNode*)pCol;
X
Xiaoyu Wang 已提交
6149 6150
}

X
Xiaoyu Wang 已提交
6151
static SNode* createProjectCol(const char* pProjCol) {
6152 6153 6154 6155
  SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
  if (NULL == pCol) {
    return NULL;
  }
X
Xiaoyu Wang 已提交
6156
  snprintf(pCol->colName, sizeof(pCol->colName), "%s", pProjCol);
6157 6158 6159
  return (SNode*)pCol;
}

X
Xiaoyu Wang 已提交
6160 6161
static SNodeList* createProjectCols(int32_t ncols, const char* const pCols[]) {
  SNodeList* pProjections = NULL;
6162
  if (0 == ncols) {
X
Xiaoyu Wang 已提交
6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177
    nodesListMakeStrictAppend(&pProjections, createStarCol());
    return pProjections;
  }
  for (int32_t i = 0; i < ncols; ++i) {
    int32_t code = nodesListMakeStrictAppend(&pProjections, createProjectCol(pCols[i]));
    if (TSDB_CODE_SUCCESS != code) {
      nodesDestroyList(pProjections);
      return NULL;
    }
  }
  return pProjections;
}

static int32_t createSimpleSelectStmt(const char* pDb, const char* pTable, int32_t numOfProjs,
                                      const char* const pProjCol[], SSelectStmt** pStmt) {
6178
  SSelectStmt* pSelect = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT);
wmmhello's avatar
wmmhello 已提交
6179 6180 6181 6182
  if (NULL == pSelect) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  sprintf(pSelect->stmtName, "%p", pSelect);
X
Xiaoyu Wang 已提交
6183

6184 6185
  SRealTableNode* pRealTable = (SRealTableNode*)nodesMakeNode(QUERY_NODE_REAL_TABLE);
  if (NULL == pRealTable) {
6186
    nodesDestroyNode((SNode*)pSelect);
wmmhello's avatar
wmmhello 已提交
6187 6188
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
6189 6190 6191
  snprintf(pRealTable->table.dbName, sizeof(pRealTable->table.dbName), "%s", pDb);
  snprintf(pRealTable->table.tableName, sizeof(pRealTable->table.tableName), "%s", pTable);
  snprintf(pRealTable->table.tableAlias, sizeof(pRealTable->table.tableAlias), "%s", pTable);
6192
  pSelect->pFromTable = (SNode*)pRealTable;
X
Xiaoyu Wang 已提交
6193

6194 6195 6196 6197 6198 6199
  if (numOfProjs >= 0) {
    pSelect->pProjectionList = createProjectCols(numOfProjs, pProjCol);
    if (NULL == pSelect->pProjectionList) {
      nodesDestroyNode((SNode*)pSelect);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
6200 6201
  }

wmmhello's avatar
wmmhello 已提交
6202
  *pStmt = pSelect;
X
Xiaoyu Wang 已提交
6203

wmmhello's avatar
wmmhello 已提交
6204
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
6205 6206
}

6207
static int32_t createSelectStmtForShow(ENodeType showType, SSelectStmt** pStmt) {
X
Xiaoyu Wang 已提交
6208 6209
  const SSysTableShowAdapter* pShow = &sysTableShowAdapter[showType - SYSTABLE_SHOW_TYPE_OFFSET];
  return createSimpleSelectStmt(pShow->pDbName, pShow->pTableName, pShow->numOfShowCols, pShow->pShowCols, pStmt);
6210 6211 6212
}

static int32_t createSelectStmtForShowTableDist(SShowTableDistributedStmt* pStmt, SSelectStmt** pOutput) {
X
Xiaoyu Wang 已提交
6213
  return createSimpleSelectStmt(pStmt->dbName, pStmt->tableName, 0, NULL, pOutput);
6214 6215
}

X
Xiaoyu Wang 已提交
6216
static int32_t createOperatorNode(EOperatorType opType, const char* pColName, SNode* pRight, SNode** pOp) {
wmmhello's avatar
wmmhello 已提交
6217 6218 6219
  if (NULL == pRight) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
6220

6221
  SOperatorNode* pOper = (SOperatorNode*)nodesMakeNode(QUERY_NODE_OPERATOR);
wmmhello's avatar
wmmhello 已提交
6222 6223 6224
  if (NULL == pOper) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
6225

wmmhello's avatar
wmmhello 已提交
6226 6227 6228 6229
  pOper->opType = opType;
  pOper->pLeft = nodesMakeNode(QUERY_NODE_COLUMN);
  pOper->pRight = nodesCloneNode(pRight);
  if (NULL == pOper->pLeft || NULL == pOper->pRight) {
6230
    nodesDestroyNode((SNode*)pOper);
wmmhello's avatar
wmmhello 已提交
6231 6232 6233
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  strcpy(((SColumnNode*)pOper->pLeft)->colName, pColName);
X
Xiaoyu Wang 已提交
6234

wmmhello's avatar
wmmhello 已提交
6235 6236
  *pOp = (SNode*)pOper;
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
6237 6238 6239
}

static const char* getTbNameColName(ENodeType type) {
wmmhello's avatar
wmmhello 已提交
6240
  return (QUERY_NODE_SHOW_STABLES_STMT == type ? "stable_name" : "table_name");
X
Xiaoyu Wang 已提交
6241 6242 6243
}

static int32_t createLogicCondNode(SNode* pCond1, SNode* pCond2, SNode** pCond) {
6244
  SLogicConditionNode* pCondition = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
wmmhello's avatar
wmmhello 已提交
6245 6246 6247 6248 6249 6250
  if (NULL == pCondition) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pCondition->condType = LOGIC_COND_TYPE_AND;
  pCondition->pParameterList = nodesMakeList();
  if (NULL == pCondition->pParameterList) {
6251
    nodesDestroyNode((SNode*)pCondition);
wmmhello's avatar
wmmhello 已提交
6252 6253 6254 6255
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  if (TSDB_CODE_SUCCESS != nodesListAppend(pCondition->pParameterList, pCond1) ||
      TSDB_CODE_SUCCESS != nodesListAppend(pCondition->pParameterList, pCond2)) {
6256
    nodesDestroyNode((SNode*)pCondition);
wmmhello's avatar
wmmhello 已提交
6257 6258 6259 6260 6261
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  *pCond = (SNode*)pCondition;
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
6262 6263 6264
}

static int32_t createShowCondition(const SShowStmt* pShow, SSelectStmt* pSelect) {
wmmhello's avatar
wmmhello 已提交
6265 6266 6267 6268
  SNode* pDbCond = NULL;
  SNode* pTbCond = NULL;
  if (TSDB_CODE_SUCCESS != createOperatorNode(OP_TYPE_EQUAL, "db_name", pShow->pDbName, &pDbCond) ||
      TSDB_CODE_SUCCESS !=
6269
          createOperatorNode(pShow->tableCondType, getTbNameColName(nodeType(pShow)), pShow->pTbName, &pTbCond)) {
wmmhello's avatar
wmmhello 已提交
6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289
    nodesDestroyNode(pDbCond);
    nodesDestroyNode(pTbCond);
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  if (NULL != pDbCond && NULL != pTbCond) {
    if (TSDB_CODE_SUCCESS != createLogicCondNode(pDbCond, pTbCond, &pSelect->pWhere)) {
      nodesDestroyNode(pDbCond);
      nodesDestroyNode(pTbCond);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  } else {
    pSelect->pWhere = (NULL == pDbCond ? pTbCond : pDbCond);
  }

  if (NULL != pShow->pDbName) {
    strcpy(((SRealTableNode*)pSelect->pFromTable)->qualDbName, ((SValueNode*)pShow->pDbName)->literal);
  }

  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
6290 6291 6292
}

static int32_t rewriteShow(STranslateContext* pCxt, SQuery* pQuery) {
wmmhello's avatar
wmmhello 已提交
6293 6294 6295 6296 6297 6298 6299 6300 6301
  SSelectStmt* pStmt = NULL;
  int32_t      code = createSelectStmtForShow(nodeType(pQuery->pRoot), &pStmt);
  if (TSDB_CODE_SUCCESS == code) {
    code = createShowCondition((SShowStmt*)pQuery->pRoot, pStmt);
  }
  if (TSDB_CODE_SUCCESS == code) {
    pQuery->showRewrite = true;
    nodesDestroyNode(pQuery->pRoot);
    pQuery->pRoot = (SNode*)pStmt;
6302 6303 6304 6305 6306 6307
  } else {
    nodesDestroyNode((SNode*)pStmt);
  }
  return code;
}

X
Xiaoyu Wang 已提交
6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321
static int32_t checkShowVgroups(STranslateContext* pCxt, SShowStmt* pShow) {
  // just to verify whether the database exists
  SDbCfgInfo dbCfg = {0};
  return getDBCfg(pCxt, ((SValueNode*)pShow->pDbName)->literal, &dbCfg);
}

static int32_t rewriteShowVgroups(STranslateContext* pCxt, SQuery* pQuery) {
  int32_t code = checkShowVgroups(pCxt, (SShowStmt*)pQuery->pRoot);
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteShow(pCxt, pQuery);
  }
  return code;
}

6322 6323 6324 6325 6326 6327 6328 6329 6330
static SNode* createTagsFunction() {
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
  if (NULL == pFunc) {
    return NULL;
  }
  strcpy(pFunc->functionName, "_tags");
  return (SNode*)pFunc;
}

6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342
static int32_t createShowTableTagsProjections(SNodeList** pProjections, SNodeList** pTags) {
  if (NULL != *pTags) {
    TSWAP(*pProjections, *pTags);
    return TSDB_CODE_SUCCESS;
  }
  int32_t code = nodesListMakeStrictAppend(pProjections, createTbnameFunction());
  if (TSDB_CODE_SUCCESS == code) {
    code = nodesListStrictAppend(*pProjections, createTagsFunction());
  }
  return code;
}

6343
static int32_t rewriteShowStableTags(STranslateContext* pCxt, SQuery* pQuery) {
6344 6345
  SShowTableTagsStmt* pShow = (SShowTableTagsStmt*)pQuery->pRoot;
  SSelectStmt*        pSelect = NULL;
6346 6347 6348
  int32_t code = createSimpleSelectStmt(((SValueNode*)pShow->pDbName)->literal, ((SValueNode*)pShow->pTbName)->literal,
                                        -1, NULL, &pSelect);
  if (TSDB_CODE_SUCCESS == code) {
6349
    code = createShowTableTagsProjections(&pSelect->pProjectionList, &pShow->pTags);
6350 6351 6352
  }
  if (TSDB_CODE_SUCCESS == code) {
    pQuery->showRewrite = true;
6353
    pSelect->tagScan = true;
6354 6355 6356 6357
    nodesDestroyNode(pQuery->pRoot);
    pQuery->pRoot = (SNode*)pSelect;
  } else {
    nodesDestroyNode((SNode*)pSelect);
wmmhello's avatar
wmmhello 已提交
6358 6359
  }
  return code;
6360 6361
}

6362
static int32_t rewriteShowDnodeVariables(STranslateContext* pCxt, SQuery* pQuery) {
6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373
  SShowDnodeVariablesStmt* pStmt = (SShowDnodeVariablesStmt*)pQuery->pRoot;
  SNode*                   pDnodeCond = NULL;
  SNode*                   pLikeCond = NULL;
  SSelectStmt*             pSelect = NULL;
  int32_t                  code = createSelectStmtForShow(nodeType(pQuery->pRoot), &pSelect);
  if (TSDB_CODE_SUCCESS == code) {
    code = createOperatorNode(OP_TYPE_EQUAL, "dnode_id", pStmt->pDnodeId, &pDnodeCond);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = createOperatorNode(OP_TYPE_LIKE, "name", pStmt->pLikePattern, &pLikeCond);
  }
6374
  if (TSDB_CODE_SUCCESS == code) {
6375 6376 6377 6378 6379
    if (NULL != pLikeCond) {
      code = createLogicCondNode(pDnodeCond, pLikeCond, &pSelect->pWhere);
    } else {
      pSelect->pWhere = pDnodeCond;
    }
6380 6381 6382 6383
  }
  if (TSDB_CODE_SUCCESS == code) {
    pQuery->showRewrite = true;
    nodesDestroyNode(pQuery->pRoot);
6384
    pQuery->pRoot = (SNode*)pSelect;
6385 6386 6387 6388
  }
  return code;
}

6389 6390 6391 6392 6393 6394 6395 6396
static int32_t rewriteShowVnodes(STranslateContext* pCxt, SQuery* pQuery) {
  SShowVnodesStmt* pShow = (SShowVnodesStmt*)(pQuery->pRoot);
  SSelectStmt*     pStmt = NULL;
  int32_t          code = createSelectStmtForShow(QUERY_NODE_SHOW_VNODES_STMT, &pStmt);
  if (TSDB_CODE_SUCCESS == code) {
    if (NULL != pShow->pDnodeId) {
      code = createOperatorNode(OP_TYPE_EQUAL, "dnode_id", pShow->pDnodeId, &pStmt->pWhere);
    } else {
6397
      code = createOperatorNode(OP_TYPE_EQUAL, "dnode_ep", pShow->pDnodeEndpoint, &pStmt->pWhere);
6398 6399 6400 6401 6402 6403 6404 6405 6406 6407
    }
  }
  if (TSDB_CODE_SUCCESS == code) {
    pQuery->showRewrite = true;
    nodesDestroyNode(pQuery->pRoot);
    pQuery->pRoot = (SNode*)pStmt;
  }
  return code;
}

6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437
static SNode* createBlockDistInfoFunc() {
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
  if (NULL == pFunc) {
    return NULL;
  }

  strcpy(pFunc->functionName, "_block_dist_info");
  strcpy(pFunc->node.aliasName, "_block_dist_info");
  return (SNode*)pFunc;
}

static SNode* createBlockDistFunc() {
  SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
  if (NULL == pFunc) {
    return NULL;
  }

  strcpy(pFunc->functionName, "_block_dist");
  strcpy(pFunc->node.aliasName, "_block_dist");
  if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pFunc->pParameterList, createBlockDistInfoFunc())) {
    nodesDestroyNode((SNode*)pFunc);
    return NULL;
  }
  return (SNode*)pFunc;
}

static int32_t rewriteShowTableDist(STranslateContext* pCxt, SQuery* pQuery) {
  SSelectStmt* pStmt = NULL;
  int32_t      code = createSelectStmtForShowTableDist((SShowTableDistributedStmt*)pQuery->pRoot, &pStmt);
  if (TSDB_CODE_SUCCESS == code) {
6438
    NODES_DESTORY_LIST(pStmt->pProjectionList);
6439 6440 6441 6442 6443 6444 6445 6446 6447 6448
    code = nodesListMakeStrictAppend(&pStmt->pProjectionList, createBlockDistFunc());
  }
  if (TSDB_CODE_SUCCESS == code) {
    pQuery->showRewrite = true;
    nodesDestroyNode(pQuery->pRoot);
    pQuery->pRoot = (SNode*)pStmt;
  }
  return code;
}

X
Xiaoyu Wang 已提交
6449
typedef struct SVgroupCreateTableBatch {
wmmhello's avatar
wmmhello 已提交
6450 6451 6452
  SVCreateTbBatchReq req;
  SVgroupInfo        info;
  char               dbName[TSDB_DB_NAME_LEN];
X
Xiaoyu Wang 已提交
6453
} SVgroupCreateTableBatch;
6454

dengyihao's avatar
dengyihao 已提交
6455
static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt* pStmt, const SVgroupInfo* pVgroupInfo,
wmmhello's avatar
wmmhello 已提交
6456 6457 6458 6459 6460 6461 6462 6463 6464
                                        SVgroupCreateTableBatch* pBatch) {
  char  dbFName[TSDB_DB_FNAME_LEN] = {0};
  SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId};
  strcpy(name.dbname, pStmt->dbName);
  tNameGetFullDbName(&name, dbFName);

  SVCreateTbReq req = {0};
  req.type = TD_NORMAL_TABLE;
  req.name = strdup(pStmt->tableName);
wmmhello's avatar
wmmhello 已提交
6465
  req.ttl = pStmt->pOptions->ttl;
wmmhello's avatar
wmmhello 已提交
6466
  if (pStmt->pOptions->commentNull == false) {
wmmhello's avatar
wmmhello 已提交
6467 6468
    req.comment = strdup(pStmt->pOptions->comment);
    if (NULL == req.comment) {
6469
      tdDestroySVCreateTbReq(&req);
wmmhello's avatar
wmmhello 已提交
6470 6471
      return TSDB_CODE_OUT_OF_MEMORY;
    }
wmmhello's avatar
wmmhello 已提交
6472
    req.commentLen = strlen(pStmt->pOptions->comment);
X
Xiaoyu Wang 已提交
6473
  } else {
wmmhello's avatar
wmmhello 已提交
6474
    req.commentLen = -1;
wmmhello's avatar
wmmhello 已提交
6475
  }
6476 6477 6478 6479
  req.ntb.schemaRow.nCols = LIST_LENGTH(pStmt->pCols);
  req.ntb.schemaRow.version = 1;
  req.ntb.schemaRow.pSchema = taosMemoryCalloc(req.ntb.schemaRow.nCols, sizeof(SSchema));
  if (NULL == req.name || NULL == req.ntb.schemaRow.pSchema) {
6480
    tdDestroySVCreateTbReq(&req);
wmmhello's avatar
wmmhello 已提交
6481 6482 6483 6484 6485 6486 6487 6488
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  if (pStmt->ignoreExists) {
    req.flags |= TD_CREATE_IF_NOT_EXISTS;
  }
  SNode*   pCol;
  col_id_t index = 0;
  FOREACH(pCol, pStmt->pCols) {
6489
    toSchema((SColumnDefNode*)pCol, index + 1, req.ntb.schemaRow.pSchema + index);
wmmhello's avatar
wmmhello 已提交
6490 6491 6492 6493 6494 6495
    ++index;
  }
  pBatch->info = *pVgroupInfo;
  strcpy(pBatch->dbName, pStmt->dbName);
  pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
  if (NULL == pBatch->req.pArray) {
6496
    tdDestroySVCreateTbReq(&req);
wmmhello's avatar
wmmhello 已提交
6497 6498 6499 6500 6501
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  taosArrayPush(pBatch->req.pArray, &req);

  return TSDB_CODE_SUCCESS;
6502 6503
}

X
Xiaoyu Wang 已提交
6504
static int32_t serializeVgroupCreateTableBatch(SVgroupCreateTableBatch* pTbBatch, SArray* pBufArray) {
wmmhello's avatar
wmmhello 已提交
6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533
  int      tlen;
  SEncoder coder = {0};

  int32_t ret = 0;
  tEncodeSize(tEncodeSVCreateTbBatchReq, &pTbBatch->req, tlen, ret);
  tlen += sizeof(SMsgHead);
  void* buf = taosMemoryMalloc(tlen);
  if (NULL == buf) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  ((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId);
  ((SMsgHead*)buf)->contLen = htonl(tlen);
  void* pBuf = POINTER_SHIFT(buf, sizeof(SMsgHead));

  tEncoderInit(&coder, pBuf, tlen - sizeof(SMsgHead));
  tEncodeSVCreateTbBatchReq(&coder, &pTbBatch->req);
  tEncoderClear(&coder);

  SVgDataBlocks* pVgData = taosMemoryCalloc(1, sizeof(SVgDataBlocks));
  if (NULL == pVgData) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pVgData->vg = pTbBatch->info;
  pVgData->pData = buf;
  pVgData->size = tlen;
  pVgData->numOfTables = (int32_t)taosArrayGetSize(pTbBatch->req.pArray);
  taosArrayPush(pBufArray, &pVgData);

  return TSDB_CODE_SUCCESS;
6534 6535
}

wmmhello's avatar
wmmhello 已提交
6536
static void destroyCreateTbReqBatch(void* data) {
6537 6538
  SVgroupCreateTableBatch* pTbBatch = (SVgroupCreateTableBatch*)data;
  size_t                   size = taosArrayGetSize(pTbBatch->req.pArray);
wmmhello's avatar
wmmhello 已提交
6539 6540
  for (int32_t i = 0; i < size; ++i) {
    SVCreateTbReq* pTableReq = taosArrayGet(pTbBatch->req.pArray, i);
6541
    tdDestroySVCreateTbReq(pTableReq);
wmmhello's avatar
wmmhello 已提交
6542
  }
6543

wmmhello's avatar
wmmhello 已提交
6544
  taosArrayDestroy(pTbBatch->req.pArray);
6545 6546
}

wmmhello's avatar
wmmhello 已提交
6547
int32_t rewriteToVnodeModifyOpStmt(SQuery* pQuery, SArray* pBufArray) {
6548
  SVnodeModifOpStmt* pNewStmt = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT);
wmmhello's avatar
wmmhello 已提交
6549 6550 6551 6552 6553 6554 6555 6556
  if (pNewStmt == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pNewStmt->sqlNodeType = nodeType(pQuery->pRoot);
  pNewStmt->pDataBlocks = pBufArray;
  nodesDestroyNode(pQuery->pRoot);
  pQuery->pRoot = (SNode*)pNewStmt;
  return TSDB_CODE_SUCCESS;
6557 6558
}

X
Xiaoyu Wang 已提交
6559
static void destroyCreateTbReqArray(SArray* pArray) {
wmmhello's avatar
wmmhello 已提交
6560 6561 6562 6563 6564 6565 6566
  size_t size = taosArrayGetSize(pArray);
  for (size_t i = 0; i < size; ++i) {
    SVgDataBlocks* pVg = taosArrayGetP(pArray, i);
    taosMemoryFreeClear(pVg->pData);
    taosMemoryFreeClear(pVg);
  }
  taosArrayDestroy(pArray);
X
Xiaoyu Wang 已提交
6567 6568
}

dengyihao's avatar
dengyihao 已提交
6569
static int32_t buildCreateTableDataBlock(int32_t acctId, const SCreateTableStmt* pStmt, const SVgroupInfo* pInfo,
wmmhello's avatar
wmmhello 已提交
6570 6571 6572 6573 6574
                                         SArray** pBufArray) {
  *pBufArray = taosArrayInit(1, POINTER_BYTES);
  if (NULL == *pBufArray) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
6575

wmmhello's avatar
wmmhello 已提交
6576 6577 6578 6579 6580
  SVgroupCreateTableBatch tbatch = {0};
  int32_t                 code = buildNormalTableBatchReq(acctId, pStmt, pInfo, &tbatch);
  if (TSDB_CODE_SUCCESS == code) {
    code = serializeVgroupCreateTableBatch(&tbatch, *pBufArray);
  }
X
Xiaoyu Wang 已提交
6581

wmmhello's avatar
wmmhello 已提交
6582 6583 6584 6585 6586
  destroyCreateTbReqBatch(&tbatch);
  if (TSDB_CODE_SUCCESS != code) {
    destroyCreateTbReqArray(*pBufArray);
  }
  return code;
6587 6588 6589
}

static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) {
wmmhello's avatar
wmmhello 已提交
6590 6591
  SCreateTableStmt* pStmt = (SCreateTableStmt*)pQuery->pRoot;

6592
  int32_t     code = checkCreateTable(pCxt, pStmt, false);
wmmhello's avatar
wmmhello 已提交
6593
  SVgroupInfo info = {0};
6594
  SName       name;
D
dapan1121 已提交
6595
  toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &name);
wmmhello's avatar
wmmhello 已提交
6596
  if (TSDB_CODE_SUCCESS == code) {
D
dapan1121 已提交
6597 6598 6599 6600
    code = getTableHashVgroupImpl(pCxt, &name, &info);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = collectUseTable(&name, pCxt->pTargetTables);
wmmhello's avatar
wmmhello 已提交
6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613
  }
  SArray* pBufArray = NULL;
  if (TSDB_CODE_SUCCESS == code) {
    code = buildCreateTableDataBlock(pCxt->pParseCxt->acctId, pStmt, &info, &pBufArray);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteToVnodeModifyOpStmt(pQuery, pBufArray);
    if (TSDB_CODE_SUCCESS != code) {
      destroyCreateTbReqArray(pBufArray);
    }
  }

  return code;
6614 6615
}

C
Cary Xu 已提交
6616
static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, SCreateSubTableClause* pStmt,
6617
                                     const STag* pTag, uint64_t suid, const char* sTableNmae, SVgroupInfo* pVgInfo,
6618
                                     SArray* tagName, uint8_t tagNum) {
6619 6620 6621 6622
  //  char  dbFName[TSDB_DB_FNAME_LEN] = {0};
  //  SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId};
  //  strcpy(name.dbname, pStmt->dbName);
  //  tNameGetFullDbName(&name, dbFName);
wmmhello's avatar
wmmhello 已提交
6623 6624 6625 6626

  struct SVCreateTbReq req = {0};
  req.type = TD_CHILD_TABLE;
  req.name = strdup(pStmt->tableName);
X
Xiaoyu Wang 已提交
6627
  req.ttl = pStmt->pOptions->ttl;
wmmhello's avatar
wmmhello 已提交
6628
  if (pStmt->pOptions->commentNull == false) {
wmmhello's avatar
wmmhello 已提交
6629
    req.comment = strdup(pStmt->pOptions->comment);
wmmhello's avatar
wmmhello 已提交
6630
    req.commentLen = strlen(pStmt->pOptions->comment);
X
Xiaoyu Wang 已提交
6631
  } else {
wmmhello's avatar
wmmhello 已提交
6632
    req.commentLen = -1;
wmmhello's avatar
wmmhello 已提交
6633
  }
wmmhello's avatar
wmmhello 已提交
6634
  req.ctb.suid = suid;
6635
  req.ctb.tagNum = tagNum;
6636
  req.ctb.stbName = strdup(sTableNmae);
C
Cary Xu 已提交
6637
  req.ctb.pTag = (uint8_t*)pTag;
H
Haojun Liao 已提交
6638
  req.ctb.tagName = taosArrayDup(tagName, NULL);
wmmhello's avatar
wmmhello 已提交
6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655
  if (pStmt->ignoreExists) {
    req.flags |= TD_CREATE_IF_NOT_EXISTS;
  }

  SVgroupCreateTableBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId));
  if (pTableBatch == NULL) {
    SVgroupCreateTableBatch tBatch = {0};
    tBatch.info = *pVgInfo;
    strcpy(tBatch.dbName, pStmt->dbName);

    tBatch.req.pArray = taosArrayInit(4, sizeof(struct SVCreateTbReq));
    taosArrayPush(tBatch.req.pArray, &req);

    taosHashPut(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId), &tBatch, sizeof(tBatch));
  } else {  // add to the correct vgroup
    taosArrayPush(pTableBatch->req.pArray, &req);
  }
6656 6657
}

X
Xiaoyu Wang 已提交
6658 6659
static SDataType schemaToDataType(uint8_t precision, SSchema* pSchema) {
  SDataType dt = {.type = pSchema->type, .bytes = pSchema->bytes, .precision = precision, .scale = 0};
6660 6661 6662
  return dt;
}

6663 6664 6665 6666 6667
static int32_t createCastFuncForTag(STranslateContext* pCxt, SNode* pNode, SDataType dt, SNode** pCast) {
  SNode* pExpr = nodesCloneNode(pNode);
  if (NULL == pExpr) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
6668 6669 6670 6671
  int32_t code = translateExpr(pCxt, &pExpr);
  if (TSDB_CODE_SUCCESS == code) {
    code = createCastFunc(pCxt, pExpr, dt, pCast);
  }
6672 6673 6674 6675 6676 6677
  if (TSDB_CODE_SUCCESS != code) {
    nodesDestroyNode(pExpr);
  }
  return code;
}

6678
static int32_t createTagValFromExpr(STranslateContext* pCxt, SDataType targetDt, SNode* pNode, SValueNode** pVal) {
6679
  SNode*  pCast = NULL;
6680
  int32_t code = createCastFuncForTag(pCxt, pNode, targetDt, &pCast);
6681
  SNode*  pNew = NULL;
6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693
  if (TSDB_CODE_SUCCESS == code) {
    code = scalarCalculateConstants(pCast, &pNew);
  }
  if (TSDB_CODE_SUCCESS == code) {
    pCast = pNew;
    if (QUERY_NODE_VALUE != nodeType(pCast)) {
      code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pNode)->aliasName);
    }
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pVal = (SValueNode*)pCast;
wmmhello's avatar
wmmhello 已提交
6694
  } else {
6695
    nodesDestroyNode(pCast);
X
Xiaoyu Wang 已提交
6696
  }
6697
  return code;
X
Xiaoyu Wang 已提交
6698 6699
}

6700
static int32_t createTagValFromVal(STranslateContext* pCxt, SDataType targetDt, SNode* pNode, SValueNode** pVal) {
6701 6702
  SValueNode* pTempVal = (SValueNode*)nodesCloneNode(pNode);
  if (NULL == pTempVal) {
6703 6704
    return TSDB_CODE_OUT_OF_MEMORY;
  }
6705 6706 6707 6708 6709 6710
  if (DEAL_RES_ERROR == translateValueImpl(pCxt, pTempVal, targetDt, true)) {
    nodesDestroyNode((SNode*)pTempVal);
    return pCxt->errCode;
  }
  *pVal = pTempVal;
  return TSDB_CODE_SUCCESS;
6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721
}

static int32_t createTagVal(STranslateContext* pCxt, uint8_t precision, SSchema* pSchema, SNode* pNode,
                            SValueNode** pVal) {
  if (QUERY_NODE_VALUE == nodeType(pNode)) {
    return createTagValFromVal(pCxt, schemaToDataType(precision, pSchema), pNode, pVal);
  } else {
    return createTagValFromExpr(pCxt, schemaToDataType(precision, pSchema), pNode, pVal);
  }
}

X
Xiaoyu Wang 已提交
6722 6723 6724 6725
static int32_t buildJsonTagVal(STranslateContext* pCxt, SSchema* pTagSchema, SValueNode* pVal, SArray* pTagArray,
                               STag** ppTag) {
  if (pVal->literal && strlen(pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
    return buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pVal->literal);
wmmhello's avatar
wmmhello 已提交
6726
  }
X
Xiaoyu Wang 已提交
6727

wmmhello's avatar
wmmhello 已提交
6728
  return parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf);
X
Xiaoyu Wang 已提交
6729 6730 6731 6732 6733 6734
}

static int32_t buildNormalTagVal(STranslateContext* pCxt, SSchema* pTagSchema, SValueNode* pVal, SArray* pTagArray) {
  if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) {
    void*   nodeVal = nodesGetValueFromNode(pVal);
    STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
6735
    //    strcpy(val.colName, pTagSchema->name);
X
Xiaoyu Wang 已提交
6736 6737 6738 6739 6740 6741 6742 6743 6744
    if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
      val.pData = varDataVal(nodeVal);
      val.nData = varDataLen(nodeVal);
    } else {
      memcpy(&val.i64, nodeVal, pTagSchema->bytes);
    }
    taosArrayPush(pTagArray, &val);
  }
  return TSDB_CODE_SUCCESS;
6745 6746
}

dengyihao's avatar
dengyihao 已提交
6747
static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableClause* pStmt, STableMeta* pSuperTableMeta,
wmmhello's avatar
wmmhello 已提交
6748
                                     STag** ppTag, SArray* tagName) {
wmmhello's avatar
wmmhello 已提交
6749 6750 6751 6752 6753 6754
  int32_t numOfTags = getNumOfTags(pSuperTableMeta);
  if (LIST_LENGTH(pStmt->pValsOfTags) != LIST_LENGTH(pStmt->pSpecificTags) ||
      numOfTags < LIST_LENGTH(pStmt->pValsOfTags)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TAGS_NOT_MATCHED);
  }

C
Cary Xu 已提交
6755
  SArray* pTagArray = taosArrayInit(LIST_LENGTH(pStmt->pValsOfTags), sizeof(STagVal));
X
Xiaoyu Wang 已提交
6756 6757
  if (NULL == pTagArray) {
    return TSDB_CODE_OUT_OF_MEMORY;
C
Cary Xu 已提交
6758
  }
6759 6760 6761 6762 6763 6764

  int32_t code = TSDB_CODE_SUCCESS;

  bool       isJson = false;
  SNodeList* pVals = NULL;
  SNode *    pTag = NULL, *pNode = NULL;
wmmhello's avatar
wmmhello 已提交
6765 6766
  FORBOTH(pTag, pStmt->pSpecificTags, pNode, pStmt->pValsOfTags) {
    SColumnNode* pCol = (SColumnNode*)pTag;
6767
    SSchema*     pSchema = getTagSchema(pSuperTableMeta, pCol->colName);
wmmhello's avatar
wmmhello 已提交
6768
    if (NULL == pSchema) {
wmmhello's avatar
wmmhello 已提交
6769
      code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAG_NAME, pCol->colName);
wmmhello's avatar
wmmhello 已提交
6770 6771
    }
    SValueNode* pVal = NULL;
6772 6773
    if (TSDB_CODE_SUCCESS == code) {
      code = createTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pSchema, pNode, &pVal);
wmmhello's avatar
wmmhello 已提交
6774
    }
6775 6776 6777 6778
    if (TSDB_CODE_SUCCESS == code) {
      if (pSchema->type == TSDB_DATA_TYPE_JSON) {
        isJson = true;
        code = buildJsonTagVal(pCxt, pSchema, pVal, pTagArray, ppTag);
wmmhello's avatar
wmmhello 已提交
6779
        taosArrayPush(tagName, pCol->colName);
6780 6781
      } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) {
        code = buildNormalTagVal(pCxt, pSchema, pVal, pTagArray);
wmmhello's avatar
wmmhello 已提交
6782
        taosArrayPush(tagName, pCol->colName);
6783
      }
wmmhello's avatar
wmmhello 已提交
6784
    }
6785 6786 6787 6788 6789
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListMakeAppend(&pVals, (SNode*)pVal);
    }
    if (TSDB_CODE_SUCCESS != code) {
      break;
wmmhello's avatar
wmmhello 已提交
6790 6791 6792
    }
  }

6793 6794
  if (TSDB_CODE_SUCCESS == code && !isJson) {
    code = tTagNew(pTagArray, 1, false, ppTag);
wmmhello's avatar
wmmhello 已提交
6795
  }
6796 6797

  nodesDestroyList(pVals);
C
Cary Xu 已提交
6798
  taosArrayDestroy(pTagArray);
6799
  return code;
6800
}
6801

dengyihao's avatar
dengyihao 已提交
6802
static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClause* pStmt, STableMeta* pSuperTableMeta,
wmmhello's avatar
wmmhello 已提交
6803
                                    STag** ppTag, SArray* tagName) {
wmmhello's avatar
wmmhello 已提交
6804 6805 6806 6807
  if (getNumOfTags(pSuperTableMeta) != LIST_LENGTH(pStmt->pValsOfTags)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TAGS_NOT_MATCHED);
  }

6808 6809 6810
  SArray* pTagArray = taosArrayInit(LIST_LENGTH(pStmt->pValsOfTags), sizeof(STagVal));
  if (NULL == pTagArray) {
    return TSDB_CODE_OUT_OF_MEMORY;
C
Cary Xu 已提交
6811 6812
  }

6813 6814 6815 6816 6817 6818 6819
  int32_t code = TSDB_CODE_SUCCESS;

  bool       isJson = false;
  int32_t    index = 0;
  SSchema*   pTagSchemas = getTableTagSchema(pSuperTableMeta);
  SNodeList* pVals = NULL;
  SNode*     pNode;
wmmhello's avatar
wmmhello 已提交
6820 6821
  FOREACH(pNode, pStmt->pValsOfTags) {
    SValueNode* pVal = NULL;
C
Cary Xu 已提交
6822
    SSchema*    pTagSchema = pTagSchemas + index;
6823 6824 6825 6826 6827
    code = createTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pTagSchema, pNode, &pVal);
    if (TSDB_CODE_SUCCESS == code) {
      if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
        isJson = true;
        code = buildJsonTagVal(pCxt, pTagSchema, pVal, pTagArray, ppTag);
wmmhello's avatar
wmmhello 已提交
6828
        taosArrayPush(tagName, pTagSchema->name);
6829 6830 6831
      } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL && !pVal->isNull) {
        char*   tmpVal = nodesGetValueFromNode(pVal);
        STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
6832
        //        strcpy(val.colName, pTagSchema->name);
6833 6834 6835 6836 6837 6838 6839
        if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
          val.pData = varDataVal(tmpVal);
          val.nData = varDataLen(tmpVal);
        } else {
          memcpy(&val.i64, tmpVal, pTagSchema->bytes);
        }
        taosArrayPush(pTagArray, &val);
wmmhello's avatar
wmmhello 已提交
6840
        taosArrayPush(tagName, pTagSchema->name);
6841
      }
wmmhello's avatar
wmmhello 已提交
6842
    }
6843 6844
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListMakeAppend(&pVals, (SNode*)pVal);
wmmhello's avatar
wmmhello 已提交
6845
    }
6846 6847
    if (TSDB_CODE_SUCCESS != code) {
      break;
wmmhello's avatar
wmmhello 已提交
6848
    }
wmmhello's avatar
wmmhello 已提交
6849
    ++index;
wmmhello's avatar
wmmhello 已提交
6850
  }
wmmhello's avatar
wmmhello 已提交
6851

6852 6853
  if (TSDB_CODE_SUCCESS == code && !isJson) {
    code = tTagNew(pTagArray, 1, false, ppTag);
wmmhello's avatar
wmmhello 已提交
6854 6855
  }

6856
  nodesDestroyList(pVals);
C
Cary Xu 已提交
6857
  taosArrayDestroy(pTagArray);
wmmhello's avatar
wmmhello 已提交
6858
  return code;
6859 6860
}

X
Xiaoyu Wang 已提交
6861
static int32_t checkCreateSubTable(STranslateContext* pCxt, SCreateSubTableClause* pStmt) {
wmmhello's avatar
wmmhello 已提交
6862 6863 6864
  if (0 != strcmp(pStmt->dbName, pStmt->useDbName)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_CORRESPONDING_STABLE_ERR);
  }
X
Xiaoyu Wang 已提交
6865 6866 6867 6868
  if (NULL != strchr(pStmt->tableName, '.')) {
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME,
                                   "The table name cannot contain '.'");
  }
wmmhello's avatar
wmmhello 已提交
6869
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
6870
}
6871
static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableClause* pStmt, SHashObj* pVgroupHashmap) {
wmmhello's avatar
wmmhello 已提交
6872 6873 6874 6875 6876 6877
  int32_t code = checkCreateSubTable(pCxt, pStmt);

  STableMeta* pSuperTableMeta = NULL;
  if (TSDB_CODE_SUCCESS == code) {
    code = getTableMeta(pCxt, pStmt->useDbName, pStmt->useTableName, &pSuperTableMeta);
  }
D
dapan1121 已提交
6878 6879 6880 6881 6882
  if (TSDB_CODE_SUCCESS == code) {
    SName name;
    toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &name);
    code = collectUseTable(&name, pCxt->pTargetTables);
  }
wmmhello's avatar
wmmhello 已提交
6883

6884
  STag*   pTag = NULL;
wmmhello's avatar
wmmhello 已提交
6885
  SArray* tagName = taosArrayInit(8, TSDB_COL_NAME_LEN);
wmmhello's avatar
wmmhello 已提交
6886 6887 6888

  if (TSDB_CODE_SUCCESS == code) {
    if (NULL != pStmt->pSpecificTags) {
wmmhello's avatar
wmmhello 已提交
6889
      code = buildKVRowForBindTags(pCxt, pStmt, pSuperTableMeta, &pTag, tagName);
wmmhello's avatar
wmmhello 已提交
6890
    } else {
wmmhello's avatar
wmmhello 已提交
6891
      code = buildKVRowForAllTags(pCxt, pStmt, pSuperTableMeta, &pTag, tagName);
wmmhello's avatar
wmmhello 已提交
6892 6893 6894 6895 6896 6897 6898 6899
    }
  }

  SVgroupInfo info = {0};
  if (TSDB_CODE_SUCCESS == code) {
    code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &info);
  }
  if (TSDB_CODE_SUCCESS == code) {
6900
    addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt, pTag, pSuperTableMeta->uid,
6901
                             pStmt->useTableName, &info, tagName, pSuperTableMeta->tableInfo.numOfTags);
6902 6903
  } else {
    taosMemoryFree(pTag);
wmmhello's avatar
wmmhello 已提交
6904 6905
  }

wmmhello's avatar
wmmhello 已提交
6906
  taosArrayDestroy(tagName);
wmmhello's avatar
wmmhello 已提交
6907 6908
  taosMemoryFreeClear(pSuperTableMeta);
  return code;
6909 6910
}

wmmhello's avatar
wmmhello 已提交
6911
SArray* serializeVgroupsCreateTableBatch(SHashObj* pVgroupHashmap) {
wmmhello's avatar
wmmhello 已提交
6912 6913 6914 6915
  SArray* pBufArray = taosArrayInit(taosHashGetSize(pVgroupHashmap), sizeof(void*));
  if (NULL == pBufArray) {
    return NULL;
  }
6916

wmmhello's avatar
wmmhello 已提交
6917 6918 6919 6920 6921 6922 6923
  int32_t                  code = TSDB_CODE_SUCCESS;
  SVgroupCreateTableBatch* pTbBatch = NULL;
  do {
    pTbBatch = taosHashIterate(pVgroupHashmap, pTbBatch);
    if (pTbBatch == NULL) {
      break;
    }
6924

wmmhello's avatar
wmmhello 已提交
6925 6926
    serializeVgroupCreateTableBatch(pTbBatch, pBufArray);
  } while (true);
6927

wmmhello's avatar
wmmhello 已提交
6928
  return pBufArray;
6929 6930 6931
}

static int32_t rewriteCreateMultiTable(STranslateContext* pCxt, SQuery* pQuery) {
wmmhello's avatar
wmmhello 已提交
6932
  SCreateMultiTableStmt* pStmt = (SCreateMultiTableStmt*)pQuery->pRoot;
6933

wmmhello's avatar
wmmhello 已提交
6934 6935 6936 6937
  SHashObj* pVgroupHashmap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
  if (NULL == pVgroupHashmap) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
6938

wmmhello's avatar
wmmhello 已提交
6939
  taosHashSetFreeFp(pVgroupHashmap, destroyCreateTbReqBatch);
wmmhello's avatar
wmmhello 已提交
6940 6941 6942
  int32_t code = TSDB_CODE_SUCCESS;
  SNode*  pNode;
  FOREACH(pNode, pStmt->pSubTables) {
X
Xiaoyu Wang 已提交
6943
    SCreateSubTableClause* pClause = (SCreateSubTableClause*)pNode;
X
Xiaoyu Wang 已提交
6944
    code = rewriteCreateSubTable(pCxt, pClause, pVgroupHashmap);
wmmhello's avatar
wmmhello 已提交
6945 6946 6947 6948 6949
    if (TSDB_CODE_SUCCESS != code) {
      taosHashCleanup(pVgroupHashmap);
      return code;
    }
  }
6950

wmmhello's avatar
wmmhello 已提交
6951
  SArray* pBufArray = serializeVgroupsCreateTableBatch(pVgroupHashmap);
wmmhello's avatar
wmmhello 已提交
6952 6953 6954 6955
  taosHashCleanup(pVgroupHashmap);
  if (NULL == pBufArray) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
6956

wmmhello's avatar
wmmhello 已提交
6957
  return rewriteToVnodeModifyOpStmt(pQuery, pBufArray);
X
Xiaoyu Wang 已提交
6958 6959 6960
}

typedef struct SVgroupDropTableBatch {
wmmhello's avatar
wmmhello 已提交
6961 6962 6963
  SVDropTbBatchReq req;
  SVgroupInfo      info;
  char             dbName[TSDB_DB_NAME_LEN];
X
Xiaoyu Wang 已提交
6964 6965
} SVgroupDropTableBatch;

6966 6967
static void addDropTbReqIntoVgroup(SHashObj* pVgroupHashmap, SDropTableClause* pClause, SVgroupInfo* pVgInfo,
                                   uint64_t suid) {
6968
  SVDropTbReq            req = {.name = pClause->tableName, .suid = suid, .igNotExists = pClause->ignoreNotExists};
wmmhello's avatar
wmmhello 已提交
6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979
  SVgroupDropTableBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId));
  if (NULL == pTableBatch) {
    SVgroupDropTableBatch tBatch = {0};
    tBatch.info = *pVgInfo;
    tBatch.req.pArray = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SVDropTbReq));
    taosArrayPush(tBatch.req.pArray, &req);

    taosHashPut(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId), &tBatch, sizeof(tBatch));
  } else {  // add to the correct vgroup
    taosArrayPush(pTableBatch->req.pArray, &req);
  }
X
Xiaoyu Wang 已提交
6980 6981 6982
}

static int32_t buildDropTableVgroupHashmap(STranslateContext* pCxt, SDropTableClause* pClause, bool* pIsSuperTable,
wmmhello's avatar
wmmhello 已提交
6983
                                           SHashObj* pVgroupHashmap) {
D
dapan1121 已提交
6984 6985
  SName name;
  toName(pCxt->pParseCxt->acctId, pClause->dbName, pClause->tableName, &name);
wmmhello's avatar
wmmhello 已提交
6986
  STableMeta* pTableMeta = NULL;
D
dapan1121 已提交
6987 6988 6989 6990
  int32_t     code = getTableMetaImpl(pCxt, &name, &pTableMeta);
  if (TSDB_CODE_SUCCESS == code) {
    code = collectUseTable(&name, pCxt->pTargetTables);
  }
X
Xiaoyu Wang 已提交
6991

wmmhello's avatar
wmmhello 已提交
6992 6993 6994 6995
  if (TSDB_CODE_SUCCESS == code && TSDB_SUPER_TABLE == pTableMeta->tableType) {
    *pIsSuperTable = true;
    goto over;
  }
X
Xiaoyu Wang 已提交
6996

wmmhello's avatar
wmmhello 已提交
6997 6998
  if (TSDB_CODE_PAR_TABLE_NOT_EXIST == code && pClause->ignoreNotExists) {
    code = TSDB_CODE_SUCCESS;
6999
    goto over;
wmmhello's avatar
wmmhello 已提交
7000
  }
7001

wmmhello's avatar
wmmhello 已提交
7002
  *pIsSuperTable = false;
X
Xiaoyu Wang 已提交
7003

wmmhello's avatar
wmmhello 已提交
7004 7005 7006 7007 7008
  SVgroupInfo info = {0};
  if (TSDB_CODE_SUCCESS == code) {
    code = getTableHashVgroup(pCxt, pClause->dbName, pClause->tableName, &info);
  }
  if (TSDB_CODE_SUCCESS == code) {
7009
    addDropTbReqIntoVgroup(pVgroupHashmap, pClause, &info, pTableMeta->suid);
wmmhello's avatar
wmmhello 已提交
7010
  }
X
Xiaoyu Wang 已提交
7011 7012

over:
wmmhello's avatar
wmmhello 已提交
7013 7014
  taosMemoryFreeClear(pTableMeta);
  return code;
X
Xiaoyu Wang 已提交
7015 7016
}

wmmhello's avatar
wmmhello 已提交
7017 7018 7019 7020
static void destroyDropTbReqBatch(void* data) {
  SVgroupDropTableBatch* pTbBatch = (SVgroupDropTableBatch*)data;
  taosArrayDestroy(pTbBatch->req.pArray);
}
X
Xiaoyu Wang 已提交
7021 7022

static int32_t serializeVgroupDropTableBatch(SVgroupDropTableBatch* pTbBatch, SArray* pBufArray) {
wmmhello's avatar
wmmhello 已提交
7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051
  int      tlen;
  SEncoder coder = {0};

  int32_t ret = 0;
  tEncodeSize(tEncodeSVDropTbBatchReq, &pTbBatch->req, tlen, ret);
  tlen += sizeof(SMsgHead);
  void* buf = taosMemoryMalloc(tlen);
  if (NULL == buf) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  ((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId);
  ((SMsgHead*)buf)->contLen = htonl(tlen);
  void* pBuf = POINTER_SHIFT(buf, sizeof(SMsgHead));

  tEncoderInit(&coder, pBuf, tlen - sizeof(SMsgHead));
  tEncodeSVDropTbBatchReq(&coder, &pTbBatch->req);
  tEncoderClear(&coder);

  SVgDataBlocks* pVgData = taosMemoryCalloc(1, sizeof(SVgDataBlocks));
  if (NULL == pVgData) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pVgData->vg = pTbBatch->info;
  pVgData->pData = buf;
  pVgData->size = tlen;
  pVgData->numOfTables = (int32_t)taosArrayGetSize(pTbBatch->req.pArray);
  taosArrayPush(pBufArray, &pVgData);

  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
7052 7053
}

wmmhello's avatar
wmmhello 已提交
7054
SArray* serializeVgroupsDropTableBatch(SHashObj* pVgroupHashmap) {
wmmhello's avatar
wmmhello 已提交
7055 7056 7057 7058
  SArray* pBufArray = taosArrayInit(taosHashGetSize(pVgroupHashmap), sizeof(void*));
  if (NULL == pBufArray) {
    return NULL;
  }
X
Xiaoyu Wang 已提交
7059

wmmhello's avatar
wmmhello 已提交
7060 7061 7062 7063 7064 7065 7066
  int32_t                code = TSDB_CODE_SUCCESS;
  SVgroupDropTableBatch* pTbBatch = NULL;
  do {
    pTbBatch = taosHashIterate(pVgroupHashmap, pTbBatch);
    if (pTbBatch == NULL) {
      break;
    }
X
Xiaoyu Wang 已提交
7067

wmmhello's avatar
wmmhello 已提交
7068 7069
    serializeVgroupDropTableBatch(pTbBatch, pBufArray);
  } while (true);
X
Xiaoyu Wang 已提交
7070

wmmhello's avatar
wmmhello 已提交
7071
  return pBufArray;
X
Xiaoyu Wang 已提交
7072 7073 7074
}

static int32_t rewriteDropTable(STranslateContext* pCxt, SQuery* pQuery) {
wmmhello's avatar
wmmhello 已提交
7075 7076 7077 7078 7079 7080 7081
  SDropTableStmt* pStmt = (SDropTableStmt*)pQuery->pRoot;

  SHashObj* pVgroupHashmap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
  if (NULL == pVgroupHashmap) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

wmmhello's avatar
wmmhello 已提交
7082
  taosHashSetFreeFp(pVgroupHashmap, destroyDropTbReqBatch);
wmmhello's avatar
wmmhello 已提交
7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095
  bool   isSuperTable = false;
  SNode* pNode;
  FOREACH(pNode, pStmt->pTables) {
    int32_t code = buildDropTableVgroupHashmap(pCxt, (SDropTableClause*)pNode, &isSuperTable, pVgroupHashmap);
    if (TSDB_CODE_SUCCESS != code) {
      taosHashCleanup(pVgroupHashmap);
      return code;
    }
    if (isSuperTable && LIST_LENGTH(pStmt->pTables) > 1) {
      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DROP_STABLE);
    }
  }

7096
  if (isSuperTable || 0 == taosHashGetSize(pVgroupHashmap)) {
wmmhello's avatar
wmmhello 已提交
7097 7098 7099 7100
    taosHashCleanup(pVgroupHashmap);
    return TSDB_CODE_SUCCESS;
  }

wmmhello's avatar
wmmhello 已提交
7101
  SArray* pBufArray = serializeVgroupsDropTableBatch(pVgroupHashmap);
wmmhello's avatar
wmmhello 已提交
7102 7103 7104 7105 7106 7107
  taosHashCleanup(pVgroupHashmap);
  if (NULL == pBufArray) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  return rewriteToVnodeModifyOpStmt(pQuery, pBufArray);
X
Xiaoyu Wang 已提交
7108 7109
}

X
Xiaoyu Wang 已提交
7110
static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta,
wmmhello's avatar
wmmhello 已提交
7111
                                    SVAlterTbReq* pReq) {
X
Xiaoyu Wang 已提交
7112
  SSchema* pSchema = getTagSchema(pTableMeta, pStmt->colName);
wmmhello's avatar
wmmhello 已提交
7113
  if (NULL == pSchema) {
X
Xiaoyu Wang 已提交
7114 7115
    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE, "Invalid tag name: %s",
                                   pStmt->colName);
wmmhello's avatar
wmmhello 已提交
7116 7117 7118 7119 7120 7121
  }

  pReq->tagName = strdup(pStmt->colName);
  if (NULL == pReq->tagName) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
7122
  pReq->colId = pSchema->colId;
wmmhello's avatar
wmmhello 已提交
7123

D
dapan1121 已提交
7124
  SDataType targetDt = schemaToDataType(pTableMeta->tableInfo.precision, pSchema);
wmmhello's avatar
wmmhello 已提交
7125

D
dapan1121 已提交
7126
  if (QUERY_NODE_VALUE != pStmt->pVal->node.type) {
H
Hongze Cheng 已提交
7127
    SValueNode* pVal = NULL;
D
dapan1121 已提交
7128
    pCxt->errCode = createTagValFromExpr(pCxt, targetDt, (SNode*)pStmt->pVal, &pVal);
D
dapan1121 已提交
7129 7130 7131
    if (pCxt->errCode) {
      return pCxt->errCode;
    }
D
dapan1121 已提交
7132 7133 7134

    nodesDestroyNode((SNode*)pStmt->pVal);
    pStmt->pVal = pVal;
D
dapan1121 已提交
7135 7136 7137 7138
  } else if (DEAL_RES_ERROR == translateValueImpl(pCxt, pStmt->pVal, targetDt, true)) {
    return pCxt->errCode;
  }

wmmhello's avatar
wmmhello 已提交
7139
  pReq->tagType = targetDt.type;
D
dapan1121 已提交
7140
  if (targetDt.type == TSDB_DATA_TYPE_JSON) {
7141 7142
    if (pStmt->pVal->literal &&
        strlen(pStmt->pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
wmmhello's avatar
wmmhello 已提交
7143 7144
      return buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pStmt->pVal->literal);
    }
X
Xiaoyu Wang 已提交
7145
    SArray* pTagVals = taosArrayInit(1, sizeof(STagVal));
wmmhello's avatar
wmmhello 已提交
7146
    int32_t code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
7147 7148
    STag*   pTag = NULL;
    do {
wmmhello's avatar
wmmhello 已提交
7149
      code = parseJsontoTagData(pStmt->pVal->literal, pTagVals, &pTag, &pCxt->msgBuf);
wmmhello's avatar
wmmhello 已提交
7150 7151 7152
      if (TSDB_CODE_SUCCESS != code) {
        break;
      }
X
Xiaoyu Wang 已提交
7153
    } while (0);
7154

wmmhello's avatar
wmmhello 已提交
7155
    taosArrayDestroy(pTagVals);
X
Xiaoyu Wang 已提交
7156
    if (code != TSDB_CODE_SUCCESS) {
wmmhello's avatar
wmmhello 已提交
7157
      return code;
wmmhello's avatar
wmmhello 已提交
7158
    }
wmmhello's avatar
wmmhello 已提交
7159
    pReq->nTagVal = pTag->len;
X
Xiaoyu Wang 已提交
7160
    pReq->pTagVal = (uint8_t*)pTag;
wmmhello's avatar
wmmhello 已提交
7161
    pStmt->pVal->datum.p = (char*)pTag;  // for free
7162
  } else {
7163
    pReq->isNull = pStmt->pVal->isNull;
wmmhello's avatar
wmmhello 已提交
7164 7165
    pReq->nTagVal = pStmt->pVal->node.resType.bytes;
    pReq->pTagVal = nodesGetValueFromNode(pStmt->pVal);
wmmhello's avatar
wmmhello 已提交
7166 7167 7168 7169 7170 7171

    // data and length are seperated for new tag format STagVal
    if (IS_VAR_DATA_TYPE(pStmt->pVal->node.resType.type)) {
      pReq->nTagVal = varDataLen(pReq->pTagVal);
      pReq->pTagVal = varDataVal(pReq->pTagVal);
    }
wmmhello's avatar
wmmhello 已提交
7172 7173 7174
  }

  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
7175 7176 7177
}

static int32_t buildAddColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta,
wmmhello's avatar
wmmhello 已提交
7178 7179 7180 7181
                              SVAlterTbReq* pReq) {
  if (NULL != getColSchema(pTableMeta, pStmt->colName)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
  }
X
Xiaoyu Wang 已提交
7182

X
Xiaoyu Wang 已提交
7183 7184 7185 7186 7187 7188 7189 7190
  if (TSDB_MAX_COLUMNS == pTableMeta->tableInfo.numOfColumns) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
  }

  if (pTableMeta->tableInfo.rowSize + calcTypeBytes(pStmt->dataType) > TSDB_MAX_BYTES_PER_ROW) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW);
  }

wmmhello's avatar
wmmhello 已提交
7191 7192 7193 7194
  pReq->colName = strdup(pStmt->colName);
  if (NULL == pReq->colName) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
7195

wmmhello's avatar
wmmhello 已提交
7196 7197
  pReq->type = pStmt->dataType.type;
  pReq->flags = COL_SMA_ON;
7198
  pReq->bytes = calcTypeBytes(pStmt->dataType);
wmmhello's avatar
wmmhello 已提交
7199
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
7200 7201 7202
}

static int32_t buildDropColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta,
wmmhello's avatar
wmmhello 已提交
7203 7204 7205 7206 7207 7208 7209 7210 7211 7212
                               SVAlterTbReq* pReq) {
  if (2 == getNumOfColumns(pTableMeta)) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DROP_COL);
  }
  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);
  }
X
Xiaoyu Wang 已提交
7213

wmmhello's avatar
wmmhello 已提交
7214 7215 7216 7217
  pReq->colName = strdup(pStmt->colName);
  if (NULL == pReq->colName) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
7218
  pReq->colId = pSchema->colId;
X
Xiaoyu Wang 已提交
7219

wmmhello's avatar
wmmhello 已提交
7220
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
7221 7222 7223
}

static int32_t buildUpdateColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta,
wmmhello's avatar
wmmhello 已提交
7224 7225
                                 SVAlterTbReq* pReq) {
  pReq->colModBytes = calcTypeBytes(pStmt->dataType);
wmmhello's avatar
wmmhello 已提交
7226
  pReq->colModType = pStmt->dataType.type;
wmmhello's avatar
wmmhello 已提交
7227 7228 7229 7230 7231 7232 7233
  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->type != pStmt->dataType.type ||
             pSchema->bytes >= pReq->colModBytes) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL);
  }
X
Xiaoyu Wang 已提交
7234

X
Xiaoyu Wang 已提交
7235 7236 7237 7238
  if (pTableMeta->tableInfo.rowSize + pReq->colModBytes - pSchema->bytes > TSDB_MAX_BYTES_PER_ROW) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW);
  }

wmmhello's avatar
wmmhello 已提交
7239 7240 7241 7242
  pReq->colName = strdup(pStmt->colName);
  if (NULL == pReq->colName) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
7243
  pReq->colId = pSchema->colId;
X
Xiaoyu Wang 已提交
7244

wmmhello's avatar
wmmhello 已提交
7245
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
7246 7247 7248
}

static int32_t buildRenameColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta,
wmmhello's avatar
wmmhello 已提交
7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262
                                 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;
X
Xiaoyu Wang 已提交
7263 7264 7265
}

static int32_t buildUpdateOptionsReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq) {
wmmhello's avatar
wmmhello 已提交
7266
  int32_t code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
7267

wmmhello's avatar
wmmhello 已提交
7268
  if (-1 != pStmt->pOptions->ttl) {
7269 7270
    pReq->updateTTL = true;
    pReq->newTTL = pStmt->pOptions->ttl;
wmmhello's avatar
wmmhello 已提交
7271
  }
X
Xiaoyu Wang 已提交
7272

X
Xiaoyu Wang 已提交
7273 7274
  if (TSDB_CODE_SUCCESS == code) {
    if (pStmt->pOptions->commentNull == false) {
wmmhello's avatar
wmmhello 已提交
7275 7276 7277
      pReq->newComment = strdup(pStmt->pOptions->comment);
      if (NULL == pReq->newComment) {
        code = TSDB_CODE_OUT_OF_MEMORY;
X
Xiaoyu Wang 已提交
7278 7279
      } else {
        pReq->newCommentLen = strlen(pReq->newComment);
wmmhello's avatar
wmmhello 已提交
7280
      }
X
Xiaoyu Wang 已提交
7281
    } else {
wmmhello's avatar
wmmhello 已提交
7282
      pReq->newCommentLen = -1;
wmmhello's avatar
wmmhello 已提交
7283 7284
    }
  }
X
Xiaoyu Wang 已提交
7285

wmmhello's avatar
wmmhello 已提交
7286
  return code;
X
Xiaoyu Wang 已提交
7287 7288 7289
}

static int32_t buildAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta,
wmmhello's avatar
wmmhello 已提交
7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313
                               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:
      return buildUpdateTagValReq(pCxt, pStmt, pTableMeta, pReq);
    case TSDB_ALTER_TABLE_ADD_COLUMN:
      return buildAddColReq(pCxt, pStmt, pTableMeta, pReq);
    case TSDB_ALTER_TABLE_DROP_COLUMN:
      return buildDropColReq(pCxt, pStmt, pTableMeta, pReq);
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
      return buildUpdateColReq(pCxt, pStmt, pTableMeta, pReq);
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
      return buildUpdateOptionsReq(pCxt, pStmt, pReq);
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
X
Xiaoyu Wang 已提交
7314 7315 7316 7317 7318
      if (TSDB_CHILD_TABLE == pTableMeta->tableType) {
        return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE);
      } else {
        return buildRenameColReq(pCxt, pStmt, pTableMeta, pReq);
      }
wmmhello's avatar
wmmhello 已提交
7319 7320 7321 7322 7323
    default:
      break;
  }

  return TSDB_CODE_FAILED;
X
Xiaoyu Wang 已提交
7324 7325 7326
}

static int32_t serializeAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq,
wmmhello's avatar
wmmhello 已提交
7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360
                                   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;
X
Xiaoyu Wang 已提交
7361 7362 7363
}

static int32_t buildModifyVnodeArray(STranslateContext* pCxt, SAlterTableStmt* pStmt, SVAlterTbReq* pReq,
wmmhello's avatar
wmmhello 已提交
7364 7365 7366 7367 7368
                                     SArray** pArray) {
  SArray* pTmpArray = taosArrayInit(1, sizeof(void*));
  if (NULL == pTmpArray) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
7369

wmmhello's avatar
wmmhello 已提交
7370 7371 7372 7373 7374 7375
  int32_t code = serializeAlterTbReq(pCxt, pStmt, pReq, pTmpArray);
  if (TSDB_CODE_SUCCESS == code) {
    *pArray = pTmpArray;
  } else {
    taosArrayDestroy(pTmpArray);
  }
X
Xiaoyu Wang 已提交
7376

wmmhello's avatar
wmmhello 已提交
7377
  return code;
7378 7379
}

7380 7381 7382 7383 7384 7385 7386 7387
static void destoryAlterTbReq(SVAlterTbReq* pReq) {
  taosMemoryFree(pReq->tbName);
  taosMemoryFree(pReq->colName);
  taosMemoryFree(pReq->colNewName);
  taosMemoryFree(pReq->tagName);
  taosMemoryFree(pReq->newComment);
}

7388 7389
static int32_t rewriteAlterTableImpl(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta,
                                     SQuery* pQuery) {
7390
  if (getNumOfTags(pTableMeta) == 1 && pStmt->alterType == TSDB_ALTER_TABLE_DROP_TAG) {
7391
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE);
wmmhello's avatar
wmmhello 已提交
7392
  }
wmmhello's avatar
wmmhello 已提交
7393

wmmhello's avatar
wmmhello 已提交
7394 7395 7396 7397 7398
  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);
  }
X
Xiaoyu Wang 已提交
7399

wmmhello's avatar
wmmhello 已提交
7400
  SVAlterTbReq req = {0};
7401
  int32_t      code = buildAlterTbReq(pCxt, pStmt, pTableMeta, &req);
X
Xiaoyu Wang 已提交
7402

wmmhello's avatar
wmmhello 已提交
7403 7404 7405 7406 7407 7408 7409
  SArray* pArray = NULL;
  if (TSDB_CODE_SUCCESS == code) {
    code = buildModifyVnodeArray(pCxt, pStmt, &req, &pArray);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteToVnodeModifyOpStmt(pQuery, pArray);
  }
7410
  destoryAlterTbReq(&req);
wmmhello's avatar
wmmhello 已提交
7411
  return code;
7412 7413
}

7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429
static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) {
  SAlterTableStmt* pStmt = (SAlterTableStmt*)pQuery->pRoot;

  if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN) {
    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON);
  }

  STableMeta* pTableMeta = NULL;
  int32_t     code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta);
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteAlterTableImpl(pCxt, pStmt, pTableMeta, pQuery);
  }
  taosMemoryFree(pTableMeta);
  return code;
}

X
Xiaoyu Wang 已提交
7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490
static int32_t serializeFlushVgroup(SVgroupInfo* pVg, SArray* pBufArray) {
  int32_t len = sizeof(SMsgHead);
  void*   buf = taosMemoryMalloc(len);
  if (NULL == buf) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  ((SMsgHead*)buf)->vgId = htonl(pVg->vgId);
  ((SMsgHead*)buf)->contLen = htonl(len);

  SVgDataBlocks* pVgData = taosMemoryCalloc(1, sizeof(SVgDataBlocks));
  if (NULL == pVgData) {
    taosMemoryFree(buf);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pVgData->vg = *pVg;
  pVgData->pData = buf;
  pVgData->size = len;
  taosArrayPush(pBufArray, &pVgData);

  return TSDB_CODE_SUCCESS;
}

static int32_t serializeFlushDb(SArray* pVgs, SArray** pOutput) {
  int32_t numOfVgs = taosArrayGetSize(pVgs);

  SArray* pBufArray = taosArrayInit(numOfVgs, sizeof(void*));
  if (NULL == pBufArray) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  for (int32_t i = 0; i < numOfVgs; ++i) {
    int32_t code = serializeFlushVgroup((SVgroupInfo*)taosArrayGet(pVgs, i), pBufArray);
    if (TSDB_CODE_SUCCESS != code) {
      taosArrayDestroy(pBufArray);
      return code;
    }
  }

  *pOutput = pBufArray;
  return TSDB_CODE_SUCCESS;
}

static int32_t rewriteFlushDatabase(STranslateContext* pCxt, SQuery* pQuery) {
  SFlushDatabaseStmt* pStmt = (SFlushDatabaseStmt*)pQuery->pRoot;

  SArray* pBufArray = NULL;
  SArray* pVgs = NULL;
  int32_t code = getDBVgInfo(pCxt, pStmt->dbName, &pVgs);
  if (TSDB_CODE_SUCCESS == code) {
    code = serializeFlushDb(pVgs, &pBufArray);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteToVnodeModifyOpStmt(pQuery, pBufArray);
  }
  if (TSDB_CODE_SUCCESS != code) {
    taosArrayDestroy(pBufArray);
  }
  taosArrayDestroy(pVgs);
  return code;
}

7491
static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
wmmhello's avatar
wmmhello 已提交
7492 7493
  int32_t code = TSDB_CODE_SUCCESS;
  switch (nodeType(pQuery->pRoot)) {
X
Xiaoyu Wang 已提交
7494
    case QUERY_NODE_SHOW_LICENCES_STMT:
wmmhello's avatar
wmmhello 已提交
7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512
    case QUERY_NODE_SHOW_DATABASES_STMT:
    case QUERY_NODE_SHOW_TABLES_STMT:
    case QUERY_NODE_SHOW_STABLES_STMT:
    case QUERY_NODE_SHOW_USERS_STMT:
    case QUERY_NODE_SHOW_DNODES_STMT:
    case QUERY_NODE_SHOW_MNODES_STMT:
    case QUERY_NODE_SHOW_MODULES_STMT:
    case QUERY_NODE_SHOW_QNODES_STMT:
    case QUERY_NODE_SHOW_FUNCTIONS_STMT:
    case QUERY_NODE_SHOW_INDEXES_STMT:
    case QUERY_NODE_SHOW_STREAMS_STMT:
    case QUERY_NODE_SHOW_BNODES_STMT:
    case QUERY_NODE_SHOW_SNODES_STMT:
    case QUERY_NODE_SHOW_CONNECTIONS_STMT:
    case QUERY_NODE_SHOW_QUERIES_STMT:
    case QUERY_NODE_SHOW_CLUSTER_STMT:
    case QUERY_NODE_SHOW_TOPICS_STMT:
    case QUERY_NODE_SHOW_TRANSACTIONS_STMT:
D
dapan1121 已提交
7513
    case QUERY_NODE_SHOW_APPS_STMT:
7514 7515
    case QUERY_NODE_SHOW_CONSUMERS_STMT:
    case QUERY_NODE_SHOW_SUBSCRIPTIONS_STMT:
7516
    case QUERY_NODE_SHOW_TAGS_STMT:
7517
    case QUERY_NODE_SHOW_USER_PRIVILEGES_STMT:
wmmhello's avatar
wmmhello 已提交
7518 7519
      code = rewriteShow(pCxt, pQuery);
      break;
X
Xiaoyu Wang 已提交
7520 7521 7522
    case QUERY_NODE_SHOW_VGROUPS_STMT:
      code = rewriteShowVgroups(pCxt, pQuery);
      break;
7523 7524 7525
    case QUERY_NODE_SHOW_TABLE_TAGS_STMT:
      code = rewriteShowStableTags(pCxt, pQuery);
      break;
7526 7527 7528
    case QUERY_NODE_SHOW_DNODE_VARIABLES_STMT:
      code = rewriteShowDnodeVariables(pCxt, pQuery);
      break;
7529 7530 7531
    case QUERY_NODE_SHOW_VNODES_STMT:
      code = rewriteShowVnodes(pCxt, pQuery);
      break;
7532 7533 7534
    case QUERY_NODE_SHOW_TABLE_DISTRIBUTED_STMT:
      code = rewriteShowTableDist(pCxt, pQuery);
      break;
wmmhello's avatar
wmmhello 已提交
7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548
    case QUERY_NODE_CREATE_TABLE_STMT:
      if (NULL == ((SCreateTableStmt*)pQuery->pRoot)->pTags) {
        code = rewriteCreateTable(pCxt, pQuery);
      }
      break;
    case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
      code = rewriteCreateMultiTable(pCxt, pQuery);
      break;
    case QUERY_NODE_DROP_TABLE_STMT:
      code = rewriteDropTable(pCxt, pQuery);
      break;
    case QUERY_NODE_ALTER_TABLE_STMT:
      code = rewriteAlterTable(pCxt, pQuery);
      break;
X
Xiaoyu Wang 已提交
7549 7550 7551
    case QUERY_NODE_FLUSH_DATABASE_STMT:
      code = rewriteFlushDatabase(pCxt, pQuery);
      break;
wmmhello's avatar
wmmhello 已提交
7552 7553 7554 7555
    default:
      break;
  }
  return code;
7556 7557
}

D
dapan1121 已提交
7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573
static int32_t toMsgType(ENodeType type) {
  switch (type) {
    case QUERY_NODE_CREATE_TABLE_STMT:
      return TDMT_VND_CREATE_TABLE;
    case QUERY_NODE_ALTER_TABLE_STMT:
      return TDMT_VND_ALTER_TABLE;
    case QUERY_NODE_DROP_TABLE_STMT:
      return TDMT_VND_DROP_TABLE;
    default:
      break;
  }
  return TDMT_VND_CREATE_TABLE;
}

static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery) {
  if (NULL != pCxt->pDbs) {
7574
    taosArrayDestroy(pQuery->pDbList);
D
dapan1121 已提交
7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586
    pQuery->pDbList = taosArrayInit(taosHashGetSize(pCxt->pDbs), TSDB_DB_FNAME_LEN);
    if (NULL == pQuery->pDbList) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
    SFullDatabaseName* pDb = taosHashIterate(pCxt->pDbs, NULL);
    while (NULL != pDb) {
      taosArrayPush(pQuery->pDbList, pDb->fullDbName);
      pDb = taosHashIterate(pCxt->pDbs, pDb);
    }
  }

  if (NULL != pCxt->pTables) {
7587
    taosArrayDestroy(pQuery->pTableList);
D
dapan1121 已提交
7588 7589 7590 7591 7592 7593 7594 7595 7596 7597
    pQuery->pTableList = taosArrayInit(taosHashGetSize(pCxt->pTables), sizeof(SName));
    if (NULL == pQuery->pTableList) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
    SName* pTable = taosHashIterate(pCxt->pTables, NULL);
    while (NULL != pTable) {
      taosArrayPush(pQuery->pTableList, pTable);
      pTable = taosHashIterate(pCxt->pTables, pTable);
    }
  }
D
dapan1121 已提交
7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611

  if (NULL != pCxt->pTargetTables) {
    taosArrayDestroy(pQuery->pTargetTableList);
    pQuery->pTargetTableList = taosArrayInit(taosHashGetSize(pCxt->pTargetTables), sizeof(SName));
    if (NULL == pQuery->pTargetTableList) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
    SName* pTable = taosHashIterate(pCxt->pTargetTables, NULL);
    while (NULL != pTable) {
      taosArrayPush(pQuery->pTargetTableList, pTable);
      pTable = taosHashIterate(pCxt->pTargetTables, pTable);
    }
  }

D
dapan1121 已提交
7612 7613 7614
  return TSDB_CODE_SUCCESS;
}

7615
static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
wmmhello's avatar
wmmhello 已提交
7616 7617
  switch (nodeType(pQuery->pRoot)) {
    case QUERY_NODE_SELECT_STMT:
7618 7619 7620 7621 7622
      if (NULL == ((SSelectStmt*)pQuery->pRoot)->pFromTable) {
        pQuery->execMode = QUERY_EXEC_MODE_LOCAL;
        pQuery->haveResultSet = true;
        break;
      }
wmmhello's avatar
wmmhello 已提交
7623 7624 7625 7626
    case QUERY_NODE_SET_OPERATOR:
    case QUERY_NODE_EXPLAIN_STMT:
      pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE;
      pQuery->haveResultSet = true;
D
dapan1121 已提交
7627
      pQuery->msgType = TDMT_SCH_QUERY;
wmmhello's avatar
wmmhello 已提交
7628
      break;
D
dapan1121 已提交
7629 7630 7631 7632
    case QUERY_NODE_DELETE_STMT:
      pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE;
      pQuery->msgType = TDMT_VND_DELETE;
      break;
7633 7634 7635 7636
    case QUERY_NODE_INSERT_STMT:
      pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE;
      pQuery->msgType = TDMT_VND_SUBMIT;
      break;
wmmhello's avatar
wmmhello 已提交
7637 7638
    case QUERY_NODE_VNODE_MODIF_STMT:
      pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE;
D
dapan1121 已提交
7639
      pQuery->msgType = toMsgType(((SVnodeModifOpStmt*)pQuery->pRoot)->sqlNodeType);
wmmhello's avatar
wmmhello 已提交
7640 7641
      break;
    case QUERY_NODE_DESCRIBE_STMT:
7642 7643 7644
    case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
    case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
    case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
D
dapan1121 已提交
7645
    case QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT:
wmmhello's avatar
wmmhello 已提交
7646 7647 7648 7649
      pQuery->execMode = QUERY_EXEC_MODE_LOCAL;
      pQuery->haveResultSet = true;
      break;
    case QUERY_NODE_RESET_QUERY_CACHE_STMT:
7650
    case QUERY_NODE_ALTER_LOCAL_STMT:
wmmhello's avatar
wmmhello 已提交
7651 7652
      pQuery->execMode = QUERY_EXEC_MODE_LOCAL;
      break;
D
dapan1121 已提交
7653 7654 7655 7656 7657 7658 7659
    case QUERY_NODE_SHOW_VARIABLES_STMT:
      pQuery->haveResultSet = true;
      pQuery->execMode = QUERY_EXEC_MODE_RPC;
      if (NULL != pCxt->pCmdMsg) {
        TSWAP(pQuery->pCmdMsg, pCxt->pCmdMsg);
        pQuery->msgType = pQuery->pCmdMsg->msgType;
      }
7660
      break;
wmmhello's avatar
wmmhello 已提交
7661 7662 7663 7664 7665 7666 7667 7668 7669
    default:
      pQuery->execMode = QUERY_EXEC_MODE_RPC;
      if (NULL != pCxt->pCmdMsg) {
        TSWAP(pQuery->pCmdMsg, pCxt->pCmdMsg);
        pQuery->msgType = pQuery->pCmdMsg->msgType;
      }
      break;
  }

7670 7671
  pQuery->stableQuery = pCxt->stableQuery;

wmmhello's avatar
wmmhello 已提交
7672
  if (pQuery->haveResultSet) {
7673
    taosMemoryFreeClear(pQuery->pResSchema);
wmmhello's avatar
wmmhello 已提交
7674 7675 7676 7677 7678 7679 7680 7681 7682 7683
    if (TSDB_CODE_SUCCESS != extractResultSchema(pQuery->pRoot, &pQuery->numOfResCols, &pQuery->pResSchema)) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }

    if (nodeType(pQuery->pRoot) == QUERY_NODE_SELECT_STMT) {
      pQuery->precision = extractResultTsPrecision((SSelectStmt*)pQuery->pRoot);
    }
  }

  return TSDB_CODE_SUCCESS;
7684 7685
}

7686
int32_t translate(SParseContext* pParseCxt, SQuery* pQuery, SParseMetaCache* pMetaCache) {
wmmhello's avatar
wmmhello 已提交
7687 7688
  STranslateContext cxt = {0};

7689
  int32_t code = initTranslateContext(pParseCxt, pMetaCache, &cxt);
wmmhello's avatar
wmmhello 已提交
7690 7691 7692 7693 7694 7695 7696 7697 7698
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteQuery(&cxt, pQuery);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateQuery(&cxt, pQuery->pRoot);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = setQuery(&cxt, pQuery);
  }
D
dapan1121 已提交
7699
  setRefreshMate(&cxt, pQuery);
wmmhello's avatar
wmmhello 已提交
7700 7701 7702
  destroyTranslateContext(&cxt);
  return code;
}