parserImpl.c 19.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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/>.
 */

16 17 18
#include "parserImpl.h"

#include "astCreateContext.h"
19 20
#include "parserInt.h"
#include "ttoken.h"
21 22 23

typedef void* (*FMalloc)(size_t);
typedef void (*FFree)(void*);
24 25

extern void* NewParseAlloc(FMalloc);
26
extern void NewParse(void*, int, SToken, void*);
27
extern void NewParseFree(void*, FFree);
28
extern void NewParseTrace(FILE*, char*);
29

30
static uint32_t toNewTokenId(uint32_t tokenId) {
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
// #define                                1
// #define NEW_TK_AND                              2
// #define NEW_TK_UNION                            3
// #define NEW_TK_ALL                              4
// #define NEW_TK_MINUS                            5
// #define NEW_TK_EXCEPT                           6
// #define NEW_TK_INTERSECT                        7
// #define NEW_TK_NK_PLUS                          8
// #define NEW_TK_NK_MINUS                         9
// #define NEW_TK_NK_STAR                         10
// #define NEW_TK_NK_SLASH                        11
// #define NEW_TK_NK_REM                          12
// #define NEW_TK_SHOW                            13
// #define NEW_TK_DATABASES                       14
// #define NEW_TK_NK_INTEGER                      15
// #define NEW_TK_NK_FLOAT                        16
// #define NEW_TK_NK_STRING                       17
// #define NEW_TK_NK_BOOL                         18
// #define NEW_TK_TIMESTAMP                       19
// #define NEW_TK_NK_VARIABLE                     20
// #define NEW_TK_NK_COMMA                        21
// #define NEW_TK_NK_ID                           22
// #define NEW_TK_NK_LP                           23
// #define NEW_TK_NK_RP                           24
// #define NEW_TK_NK_DOT                          25
// #define NEW_TK_BETWEEN                         26
// #define NEW_TK_NOT                             27
// #define NEW_TK_IS                              28
// #define NEW_TK_NULL                            29
// #define NEW_TK_NK_LT                           30
// #define NEW_TK_NK_GT                           31
// #define NEW_TK_NK_LE                           32
// #define NEW_TK_NK_GE                           33
// #define NEW_TK_NK_NE                           34
// #define                            35
// #define NEW_TK_LIKE                            36
// #define NEW_TK_MATCH                           37
// #define NEW_TK_NMATCH                          38
// #define NEW_TK_IN                              39
// #define NEW_TK_FROM                            40
// #define NEW_TK_AS                              41
// #define NEW_TK_JOIN                            42
// #define NEW_TK_ON                              43
// #define NEW_TK_INNER                           44
// #define NEW_TK_SELECT                          45
// #define NEW_TK_DISTINCT                        46
// #define                            47
// #define NEW_TK_PARTITION                       48
// #define NEW_TK_BY                              49
// #define NEW_TK_SESSION                         50
// #define NEW_TK_STATE_WINDOW                    51
// #define NEW_TK_INTERVAL                        52
// #define NEW_TK_SLIDING                         53
// #define NEW_TK_FILL                            54
// #define NEW_TK_VALUE                           55
// #define NEW_TK_NONE                            56
// #define NEW_TK_PREV                            57
// #define NEW_TK_LINEAR                          58
// #define NEW_TK_NEXT                            59
// #define NEW_TK_GROUP                           60
// #define NEW_TK_HAVING                          61
// #define NEW_TK_ORDER                           62
// #define NEW_TK_SLIMIT                          63
// #define NEW_TK_SOFFSET                         64
// #define NEW_TK_LIMIT                           65
// #define NEW_TK_OFFSET                          66
// #define NEW_TK_NK_LR                           67
// #define NEW_TK_ASC                             68
// #define NEW_TK_DESC                            69
// #define NEW_TK_NULLS                           70
// #define NEW_TK_FIRST                           71
// #define NEW_TK_LAST                            72

104
  switch (tokenId) {
105 106
    case TK_OR:
      return NEW_TK_OR;
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
    case TK_UNION:
      return NEW_TK_UNION;
    case TK_ALL:
      return NEW_TK_ALL;
    case TK_MINUS:
      return NEW_TK_NK_MINUS;
    case TK_PLUS:
      return NEW_TK_NK_PLUS;
    case TK_STAR:
      return NEW_TK_NK_STAR;
    case TK_SLASH:
      return NEW_TK_NK_SLASH;
    case TK_SHOW:
      return NEW_TK_SHOW;
    case TK_DATABASES:
      return NEW_TK_DATABASES;
    case TK_ID:
      return NEW_TK_NK_ID;
    case TK_LP:
      return NEW_TK_NK_LP;
    case TK_RP:
      return NEW_TK_NK_RP;
    case TK_COMMA:
      return NEW_TK_NK_COMMA;
    case TK_DOT:
      return NEW_TK_NK_DOT;
133 134
    case TK_EQ:
      return NEW_TK_NK_EQ;
135 136 137 138
    case TK_SELECT:
      return NEW_TK_SELECT;
    case TK_DISTINCT:
      return NEW_TK_DISTINCT;
139 140
    case TK_WHERE:
      return NEW_TK_WHERE;
141 142 143 144 145 146 147 148 149 150 151 152
    case TK_AS:
      return NEW_TK_AS;
    case TK_FROM:
      return NEW_TK_FROM;
    case TK_ORDER:
      return NEW_TK_ORDER;
    case TK_BY:
      return NEW_TK_BY;
    case TK_ASC:
      return NEW_TK_ASC;
    case TK_DESC:
      return NEW_TK_DESC;
153 154 155 156
    case TK_SPACE:
      break;
    default:
      printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!tokenId = %d\n", tokenId);
157 158 159 160
  }
  return tokenId;
}

161
static uint32_t getToken(const char* z, uint32_t* tokenId) {
162 163 164 165 166 167
  uint32_t n = tGetToken(z, tokenId);
  *tokenId = toNewTokenId(*tokenId);
  return n;
}

int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
168 169
  SAstCreateContext cxt;
  createAstCreateContext(pParseCxt, &cxt);
170
  void *pParser = NewParseAlloc(malloc);
171 172 173
  int32_t i = 0;
  while (1) {
    SToken t0 = {0};
174
    // printf("===========================\n");
175
    if (cxt.pQueryCxt->pSql[i] == 0) {
176
      NewParse(pParser, 0, t0, &cxt);
177 178
      goto abort_parse;
    }
179
    // printf("input: [%s]\n", cxt.pQueryCxt->pSql + i);
180
    t0.n = getToken((char *)&cxt.pQueryCxt->pSql[i], &t0.type);
181
    t0.z = (char *)(cxt.pQueryCxt->pSql + i);
182
    // printf("token : %d %d [%s]\n", t0.type, t0.n, t0.z);
183 184 185 186 187 188 189 190
    i += t0.n;

    switch (t0.type) {
      case TK_SPACE:
      case TK_COMMENT: {
        break;
      }
      case TK_SEMI: {
191
        NewParse(pParser, 0, t0, &cxt);
192 193 194 195 196 197
        goto abort_parse;
      }

      case TK_QUESTION:
      case TK_ILLEGAL: {
        snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z);
198
        cxt.valid = false;
199 200 201 202 203 204 205
        goto abort_parse;
      }

      case TK_HEX:
      case TK_OCT:
      case TK_BIN: {
        snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unsupported token: \"%s\"", t0.z);
206
        cxt.valid = false;
207 208 209 210
        goto abort_parse;
      }

      default:
211
        NewParse(pParser, t0.type, t0, &cxt);
212
        // NewParseTrace(stdout, "");
213 214 215 216 217 218 219
        if (!cxt.valid) {
          goto abort_parse;
        }
    }
  }

abort_parse:
220
  // printf("doParse completed.\n");
221
  NewParseFree(pParser, free);
222
  destroyAstCreateContext(&cxt);
223 224
  pQuery->pRoot = cxt.pRootNode;
  return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
225
}
226 227 228 229 230 231 232 233 234

// typedef struct SNamespace {
//   int16_t level; // todo for correlated subquery
//   char dbName[TSDB_DB_NAME_LEN];
//   char tableAlias[TSDB_TABLE_NAME_LEN];
//   SHashObj* pColHash; // key is colname, value is index of STableMeta.schema
//   STableMeta* pMeta;
// } SNamespace;

235 236 237 238 239
typedef enum ESqlClause {
  SQL_CLAUSE_FROM = 1,
  SQL_CLAUSE_WHERE
} ESqlClause;

240 241 242 243 244 245
typedef struct STranslateContext {
  SParseContext* pParseCxt;
  int32_t errCode;
  SMsgBuf msgBuf;
  SArray* pNsLevel; // element is SArray*, the element of this subarray is STableNode*
  int32_t currLevel;
246
  ESqlClause currClause;
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
} STranslateContext;

static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode);

static char* getSyntaxErrFormat(int32_t errCode) {
  switch (errCode) {
    case TSDB_CODE_PARSER_INVALID_COLUMN:
      return "Invalid column name : %s";
    case TSDB_CODE_PARSER_TABLE_NOT_EXIST:
      return "Table does not exist : %s";
    case TSDB_CODE_PARSER_AMBIGUOUS_COLUMN:
      return "Column ambiguously defined : %s";
    default:
      return "Unknown error";
  }
}

static int32_t generateSyntaxErrMsg(STranslateContext* pCxt, int32_t errCode, const char* additionalInfo) {
  snprintf(pCxt->msgBuf.buf, pCxt->msgBuf.len, getSyntaxErrFormat(errCode), additionalInfo);
  pCxt->errCode = errCode;
  return errCode;
}

static int32_t addNamespace(STranslateContext* pCxt, void* pTable) {
271 272 273 274
  size_t currTotalLevel = taosArrayGetSize(pCxt->pNsLevel);
  if (currTotalLevel > pCxt->currLevel) {
    SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
    taosArrayPush(pTables, &pTable);
275
  } else {
276 277 278 279 280 281 282 283
    do {
      SArray* pTables = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
      if (pCxt->currLevel == currTotalLevel) {
        taosArrayPush(pTables, &pTable);
      }
      taosArrayPush(pCxt->pNsLevel, &pTables);
      ++currTotalLevel;
    } while (currTotalLevel <= pCxt->currLevel);
284 285 286 287
  }
  return TSDB_CODE_SUCCESS;
}

288 289 290 291 292
static SName* toName(int32_t acctId, const SRealTableNode* pRealTable, SName* pName) {
  pName->type = TSDB_TABLE_NAME_T;
  pName->acctId = acctId;
  strcpy(pName->dbname, pRealTable->table.dbName);
  strcpy(pName->tname, pRealTable->table.tableName);
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
  return pName;
}

static bool belongTable(const char* currentDb, const SColumnNode* pCol, const STableNode* pTable) {
  int cmp = 0;
  if ('\0' != pCol->dbName[0]) {
    cmp = strcmp(pCol->dbName, pTable->dbName);
  } else {
    cmp = strcmp(currentDb, pTable->dbName);
  }
  if (0 == cmp) {
    cmp = strcmp(pCol->tableAlias, pTable->tableAlias);
  }
  return (0 == cmp);
}

static SNodeList* getProjectList(SNode* pNode) {
  if (QUERY_NODE_SELECT_STMT == nodeType(pNode)) {
    return ((SSelectStmt*)pNode)->pProjectionList;
  }
  return NULL;
}

316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
static void setColumnInfoBySchema(const STableNode* pTable, const SSchema* pColSchema, SColumnNode* pCol) {
  strcpy(pCol->dbName, pTable->dbName);
  strcpy(pCol->tableAlias, pTable->tableAlias);
  strcpy(pCol->tableName, pTable->tableName);
  strcpy(pCol->colName, pColSchema->name);
  if ('\0' == pCol->node.aliasName[0]) {
    strcpy(pCol->node.aliasName, pColSchema->name);
  }
  pCol->colId = pColSchema->colId;
  pCol->colType = pColSchema->type;
  pCol->node.resType.bytes = pColSchema->bytes;
}

static void setColumnInfoByExpr(const STableNode* pTable, SExprNode* pExpr, SColumnNode* pCol) {
  pCol->pProjectRef = (SNode*)pExpr;
  pExpr->pAssociationList = nodesListAppend(pExpr->pAssociationList, (SNode*)pCol);
  strcpy(pCol->tableAlias, pTable->tableAlias);
  strcpy(pCol->colName, pExpr->aliasName);
  pCol->node.resType = pExpr->resType;
}

337 338 339 340 341 342
static int32_t createColumnNodeByTable(const STableNode* pTable, SNodeList* pList) {
  if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
    const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
    int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
    for (int32_t i = 0; i < nums; ++i) {
      SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
343
      setColumnInfoBySchema(pTable, pMeta->schema + i, pCol);
344 345 346 347 348 349 350
      nodesListAppend(pList, (SNode*)pCol);
    }
  } else {
    SNodeList* pProjectList = getProjectList(((STempTableNode*)pTable)->pSubquery);
    SNode* pNode;
    FOREACH(pNode, pProjectList) {
      SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
351
      setColumnInfoByExpr(pTable, (SExprNode*)pNode, pCol);
352 353 354 355 356 357 358 359 360 361 362 363
      nodesListAppend(pList, (SNode*)pCol);
    }
  }
}

static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
  bool found = false;
  if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
    const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
    int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
    for (int32_t i = 0; i < nums; ++i) {
      if (0 == strcmp(pCol->colName, pMeta->schema[i].name)) {
364
        setColumnInfoBySchema(pTable, pMeta->schema + i, pCol);
365 366 367 368 369 370 371 372 373 374
        found = true;
        break;
      }
    }
  } else {
    SNodeList* pProjectList = getProjectList(((STempTableNode*)pTable)->pSubquery);
    SNode* pNode;
    FOREACH(pNode, pProjectList) {
      SExprNode* pExpr = (SExprNode*)pNode;
      if (0 == strcmp(pCol->colName, pExpr->aliasName)) {
375
        setColumnInfoByExpr(pTable, pExpr, pCol);
376 377 378 379 380 381 382 383
        found = true;
        break;
      }
    }
  }
  return found;
}

384 385 386 387 388 389 390 391
static bool translateColumnWithPrefix(STranslateContext* pCxt, SColumnNode* pCol) {
  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 (belongTable(pCxt->pParseCxt->db, pCol, pTable)) {
      if (findAndSetColumn(pCol, pTable)) {
        break;
392
      }
393 394
      generateSyntaxErrMsg(pCxt, TSDB_CODE_PARSER_INVALID_COLUMN, pCol->colName);
      return false;
395
    }
396 397 398
  }
  return true;
}
399

400 401 402 403 404 405 406 407 408 409 410 411
static bool translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNode* pCol) {
  SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
  size_t nums = taosArrayGetSize(pTables);
  bool found = false;
  for (size_t i = 0; i < nums; ++i) {
    STableNode* pTable = taosArrayGetP(pTables, i);
    if (findAndSetColumn(pCol, pTable)) {
      if (found) {
        generateSyntaxErrMsg(pCxt, TSDB_CODE_PARSER_AMBIGUOUS_COLUMN, pCol->colName);
        return false;
      }
      found = true;
412
    }
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
  }
  if (!found) {
    generateSyntaxErrMsg(pCxt, TSDB_CODE_PARSER_INVALID_COLUMN, pCol->colName);
    return false;
  }
  return true;
}

static bool translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
  if ('\0' != pCol->tableAlias[0]) {
    return translateColumnWithPrefix(pCxt, pCol);
  }
  return translateColumnWithoutPrefix(pCxt, pCol);
}

// check literal format
static bool translateValue(STranslateContext* pCxt, SValueNode* pVal) {
  return true;
}

static bool translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
  return true;
}

static bool translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
  return true;
}

static bool doTranslateExpr(SNode* pNode, void* pContext) {
  STranslateContext* pCxt = (STranslateContext*)pContext;
  switch (nodeType(pNode)) {
    case QUERY_NODE_COLUMN:
      return translateColumn(pCxt, (SColumnNode*)pNode);
    case QUERY_NODE_VALUE:
      return translateValue(pCxt, (SValueNode*)pNode);
    case QUERY_NODE_OPERATOR:
      return translateOperator(pCxt, (SOperatorNode*)pNode);
450
    case QUERY_NODE_FUNCTION:
451
      return translateFunction(pCxt, (SFunctionNode*)pNode);
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
    case QUERY_NODE_TEMP_TABLE:
      return translateSubquery(pCxt, ((STempTableNode*)pNode)->pSubquery);
    default:
      break;
  }
  return true;
}

static int32_t translateExpr(STranslateContext* pCxt, SNode* pNode) {
  nodesWalkNodePostOrder(pNode, doTranslateExpr, pCxt);
  return pCxt->errCode;
}

static int32_t translateExprList(STranslateContext* pCxt, SNodeList* pList) {
  nodesWalkListPostOrder(pList, doTranslateExpr, pCxt);
  return pCxt->errCode;
}

static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) {
  int32_t code = TSDB_CODE_SUCCESS;
  switch (nodeType(pTable)) {
    case QUERY_NODE_REAL_TABLE: {
      SRealTableNode* pRealTable = (SRealTableNode*)pTable;
      SName name;
476 477
      code = catalogGetTableMeta(pCxt->pParseCxt->pCatalog, pCxt->pParseCxt->pTransporter, &(pCxt->pParseCxt->mgmtEpSet),
          toName(pCxt->pParseCxt->acctId, pRealTable, &name), &(pRealTable->pMeta));
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
      if (TSDB_CODE_SUCCESS != code) {
        return generateSyntaxErrMsg(pCxt, TSDB_CODE_PARSER_TABLE_NOT_EXIST, pRealTable->table.tableName);
      }
      code = addNamespace(pCxt, pRealTable);
      break;
    }
    case QUERY_NODE_TEMP_TABLE: {
      STempTableNode* pTempTable = (STempTableNode*)pTable;
      code = translateSubquery(pCxt, pTempTable->pSubquery);
      if (TSDB_CODE_SUCCESS == code) {
        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);
      }
      if (TSDB_CODE_SUCCESS == code) {
        code = translateExpr(pCxt, pJoinTable->pOnCond);
      }
      break;
    }
    default:
      break;
  }
  return code;
}

509 510 511 512 513
static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) {
  pCxt->currClause = SQL_CLAUSE_FROM;
  return translateTable(pCxt, pTable);
}

514 515 516 517
static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect, bool* pIsSelectStar) {
  if (NULL == pSelect->pProjectionList) { // select * ...
    SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
    size_t nums = taosArrayGetSize(pTables);
518
    pSelect->pProjectionList = nodesMakeList();
519 520 521 522 523 524 525 526
    for (size_t i = 0; i < nums; ++i) {
      STableNode* pTable = taosArrayGetP(pTables, i);
      createColumnNodeByTable(pTable, pSelect->pProjectionList);
    }
    *pIsSelectStar = true;
  } else {

  }
527
  return TSDB_CODE_SUCCESS;
528 529 530 531
}

static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
  int32_t code = TSDB_CODE_SUCCESS;
532
  code = translateFrom(pCxt, pSelect->pFromTable);
533 534 535
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExpr(pCxt, pSelect->pWhere);
  }
536 537 538
  if (TSDB_CODE_SUCCESS == code) {
    code = translateExprList(pCxt, pSelect->pGroupByList);
  }
539 540 541 542 543 544 545
  bool isSelectStar = false;
  if (TSDB_CODE_SUCCESS == code) {
    code = translateStar(pCxt, pSelect, &isSelectStar);
  }
  if (TSDB_CODE_SUCCESS == code && !isSelectStar) {
    code = translateExprList(pCxt, pSelect->pProjectionList);
  }
546
  // printf("%s:%d code = %d\n", __FUNCTION__, __LINE__, code);
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
  return code;
}

static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
  int32_t code = TSDB_CODE_SUCCESS;
  switch (nodeType(pNode)) {
    case QUERY_NODE_SELECT_STMT:
      code = translateSelect(pCxt, (SSelectStmt*)pNode);
      break;
    default:
      break;
  }
  return code;
}

static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) {
  ++(pCxt->currLevel);
564
  ESqlClause currClause = pCxt->currClause;
565 566
  int32_t code = translateQuery(pCxt, pNode);
  --(pCxt->currLevel);
567
  pCxt->currClause = currClause;
568 569 570 571
  return code;
}

int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
572 573 574 575 576 577 578 579
  STranslateContext cxt = {
    .pParseCxt = pParseCxt,
    .errCode = TSDB_CODE_SUCCESS,
    .msgBuf = { .buf = pParseCxt->pMsg, .len = pParseCxt->msgLen },
    .pNsLevel = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES),
    .currLevel = 0,
    .currClause = 0
  };
580 581
  return translateQuery(&cxt, pQuery->pRoot);
}