astTranslate.c 30.5 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/>.
 */

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

X
Xiaoyu Wang 已提交
18
#include "catalog.h"
19
#include "cmdnodes.h"
20
#include "functionMgt.h"
X
Xiaoyu Wang 已提交
21
#include "parserUtil.h"
22
#include "ttime.h"
23

24
static bool afterGroupBy(ESqlClause clause) {
25 26 27 28
  return clause > SQL_CLAUSE_GROUP_BY;
}

static bool beforeHaving(ESqlClause clause) {
29 30 31
  return clause < SQL_CLAUSE_HAVING;
}

32 33 34 35 36 37
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;
38
  ESqlClause currClause;
39
  SSelectStmt* pCurrStmt;
40
  SCmdMsgInfo* pCmdMsg;
41 42 43 44 45 46
} STranslateContext;

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

static char* getSyntaxErrFormat(int32_t errCode) {
  switch (errCode) {
47
    case TSDB_CODE_PAR_INVALID_COLUMN:
48
      return "Invalid column name : %s";
49
    case TSDB_CODE_PAR_TABLE_NOT_EXIST:
50
      return "Table does not exist : %s";
51
    case TSDB_CODE_PAR_AMBIGUOUS_COLUMN:
52
      return "Column ambiguously defined : %s";
53
    case TSDB_CODE_PAR_WRONG_VALUE_TYPE:
54
      return "Invalid value type : %s";
55 56
    case TSDB_CODE_PAR_INVALID_FUNTION:
      return "Invalid function name : %s";
57 58 59 60 61 62
    case TSDB_CODE_PAR_FUNTION_PARA_NUM:
      return "Invalid number of arguments : %s";
    case TSDB_CODE_PAR_FUNTION_PARA_TYPE:
      return "Inconsistent datatypes : %s";
    case TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION:
      return "There mustn't be aggregation";
63 64
    case TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT:
      return "ORDER BY item must be the number of a SELECT-list expression";
65 66
    case TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION:
      return "Not a GROUP BY expression";
67 68 69 70
    case TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION:
      return "Not SELECTed expression";
    case TSDB_CODE_PAR_NOT_SINGLE_GROUP:
      return "Not a single-group group function";
X
Xiaoyu Wang 已提交
71
    case TSDB_CODE_OUT_OF_MEMORY:
X
Xiaoyu Wang 已提交
72
      return "Out of memory";
73 74 75 76 77
    default:
      return "Unknown error";
  }
}

78 79 80 81 82
static int32_t generateSyntaxErrMsg(STranslateContext* pCxt, int32_t errCode, ...) {
  va_list vArgList;
  va_start(vArgList, errCode);
  vsnprintf(pCxt->msgBuf.buf, pCxt->msgBuf.len, getSyntaxErrFormat(errCode), vArgList);
  va_end(vArgList);
83 84 85 86 87
  pCxt->errCode = errCode;
  return errCode;
}

static int32_t addNamespace(STranslateContext* pCxt, void* pTable) {
88 89 90 91
  size_t currTotalLevel = taosArrayGetSize(pCxt->pNsLevel);
  if (currTotalLevel > pCxt->currLevel) {
    SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
    taosArrayPush(pTables, &pTable);
92
  } else {
93 94 95 96 97 98 99 100
    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);
101 102 103 104
  }
  return TSDB_CODE_SUCCESS;
}

105 106 107 108 109
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);
110 111 112 113 114 115 116 117
  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 {
118
    cmp = (QUERY_NODE_REAL_TABLE == nodeType(pTable) ? strcmp(currentDb, pTable->dbName) : 0);
119 120 121 122 123 124 125 126 127 128 129 130 131 132
  }
  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;
}

X
Xiaoyu Wang 已提交
133
static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, bool isTag, SColumnNode* pCol) {
X
Xiaoyu Wang 已提交
134 135 136
  strcpy(pCol->dbName, pTable->table.dbName);
  strcpy(pCol->tableAlias, pTable->table.tableAlias);
  strcpy(pCol->tableName, pTable->table.tableName);
137 138 139 140
  strcpy(pCol->colName, pColSchema->name);
  if ('\0' == pCol->node.aliasName[0]) {
    strcpy(pCol->node.aliasName, pColSchema->name);
  }
X
Xiaoyu Wang 已提交
141
  pCol->tableId = pTable->pMeta->uid;
142
  pCol->colId = pColSchema->colId;
X
Xiaoyu Wang 已提交
143
  pCol->colType = isTag ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN;
144
  pCol->node.resType.type = pColSchema->type;
145 146 147 148 149
  pCol->node.resType.bytes = pColSchema->bytes;
}

static void setColumnInfoByExpr(const STableNode* pTable, SExprNode* pExpr, SColumnNode* pCol) {
  pCol->pProjectRef = (SNode*)pExpr;
X
Xiaoyu Wang 已提交
150
  nodesListAppend(pExpr->pAssociationList, (SNode*)pCol);
151 152 153
  if (NULL != pTable) {
    strcpy(pCol->tableAlias, pTable->tableAlias);
  }
154 155 156 157
  strcpy(pCol->colName, pExpr->aliasName);
  pCol->node.resType = pExpr->resType;
}

X
Xiaoyu Wang 已提交
158
static int32_t createColumnNodeByTable(STranslateContext* pCxt, const STableNode* pTable, SNodeList* pList) {
159 160 161 162 163
  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);
X
Xiaoyu Wang 已提交
164
      if (NULL == pCol) {
X
Xiaoyu Wang 已提交
165
        return generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
X
Xiaoyu Wang 已提交
166
      }
X
Xiaoyu Wang 已提交
167
      setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i < pMeta->tableInfo.numOfTags), pCol);
168 169 170 171 172 173 174
      nodesListAppend(pList, (SNode*)pCol);
    }
  } else {
    SNodeList* pProjectList = getProjectList(((STempTableNode*)pTable)->pSubquery);
    SNode* pNode;
    FOREACH(pNode, pProjectList) {
      SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
X
Xiaoyu Wang 已提交
175
      if (NULL == pCol) {
X
Xiaoyu Wang 已提交
176
        return generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
X
Xiaoyu Wang 已提交
177
      }
178
      setColumnInfoByExpr(pTable, (SExprNode*)pNode, pCol);
179 180 181
      nodesListAppend(pList, (SNode*)pCol);
    }
  }
X
Xiaoyu Wang 已提交
182
  return TSDB_CODE_SUCCESS;
183 184 185 186 187 188 189 190 191
}

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)) {
X
Xiaoyu Wang 已提交
192
        setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i < pMeta->tableInfo.numOfTags), pCol);
193 194 195 196 197 198 199 200 201 202
        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)) {
203
        setColumnInfoByExpr(pTable, pExpr, pCol);
204 205 206 207 208 209 210 211
        found = true;
        break;
      }
    }
  }
  return found;
}

212
static EDealRes translateColumnWithPrefix(STranslateContext* pCxt, SColumnNode* pCol) {
213 214
  SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
  size_t nums = taosArrayGetSize(pTables);
215
  bool foundTable = false;
216 217 218
  for (size_t i = 0; i < nums; ++i) {
    STableNode* pTable = taosArrayGetP(pTables, i);
    if (belongTable(pCxt->pParseCxt->db, pCol, pTable)) {
219
      foundTable = true;
220 221
      if (findAndSetColumn(pCol, pTable)) {
        break;
222
      }
223
      generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, pCol->colName);
224
      return DEAL_RES_ERROR;
225
    }
226
  }
227 228 229 230
  if (!foundTable) {
    generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_TABLE_NOT_EXIST, pCol->tableAlias);
    return DEAL_RES_ERROR;
  }
231
  return DEAL_RES_CONTINUE;
232
}
233

234
static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNode* pCol) {
235 236 237 238 239 240 241
  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) {
242
        generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_AMBIGUOUS_COLUMN, pCol->colName);
243
        return DEAL_RES_ERROR;
244 245
      }
      found = true;
246
    }
247 248
  }
  if (!found) {
249
    generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, pCol->colName);
250
    return DEAL_RES_ERROR;
251
  }
252
  return DEAL_RES_CONTINUE;
253 254
}

255
static bool translateColumnUseAlias(STranslateContext* pCxt, SColumnNode* pCol) {
256
  SNodeList* pProjectionList = pCxt->pCurrStmt->pProjectionList;
257 258 259 260 261 262 263 264 265 266 267
  SNode* pNode;
  FOREACH(pNode, pProjectionList) {
    SExprNode* pExpr = (SExprNode*)pNode;
    if (0 == strcmp(pCol->colName, pExpr->aliasName)) {
        setColumnInfoByExpr(NULL, pExpr, pCol);
        return true;
    }
  }
  return false;
}

268
static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
269 270
  // count(*)/first(*)/last(*)
  if (0 == strcmp(pCol->colName, "*")) {
271
    return DEAL_RES_CONTINUE;
272
  }
273 274 275
  if ('\0' != pCol->tableAlias[0]) {
    return translateColumnWithPrefix(pCxt, pCol);
  }
276 277 278 279
  bool found = false;
  if (SQL_CLAUSE_ORDER_BY == pCxt->currClause) {
    found = translateColumnUseAlias(pCxt, pCol);
  }
280
  return found ? DEAL_RES_CONTINUE : translateColumnWithoutPrefix(pCxt, pCol);
281 282
}

283 284 285 286 287 288
static int32_t trimStringCopy(const char* src, int32_t len, bool format, char* dst) {
  char* dstVal = dst;
  if (format) {
    varDataSetLen(dst, len);
    dstVal = varDataVal(dst);
  }
289 290 291 292 293 294
  // delete escape character: \\, \', \"
  char delim = src[0];
  int32_t cnt = 0;
  int32_t j = 0;
  for (uint32_t k = 1; k < len - 1; ++k) {
    if (src[k] == '\\' || (src[k] == delim && src[k + 1] == delim)) {
X
Xiaoyu Wang 已提交
295
      dstVal[j] = src[k + 1];
296 297 298 299 300
      cnt++;
      j++;
      k++;
      continue;
    }
X
Xiaoyu Wang 已提交
301
    dstVal[j] = src[k];
302 303
    j++;
  }
X
Xiaoyu Wang 已提交
304
  dstVal[j] = '\0';
305 306 307
  return j;
}

308
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
309 310 311 312
  if (pVal->isDuration) {
    char unit = 0;
    if (parseAbsoluteDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &unit, pVal->node.resType.precision) != TSDB_CODE_SUCCESS) {
      generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
313
      return DEAL_RES_ERROR;
314 315 316 317 318 319 320 321
    }
  } else {
    switch (pVal->node.resType.type) {
      case TSDB_DATA_TYPE_NULL:
        break;
      case TSDB_DATA_TYPE_BOOL:
        pVal->datum.b = (0 == strcasecmp(pVal->literal, "true"));
        break;
322 323 324
      case TSDB_DATA_TYPE_TINYINT:
      case TSDB_DATA_TYPE_SMALLINT:
      case TSDB_DATA_TYPE_INT:
325 326
      case TSDB_DATA_TYPE_BIGINT: {
        char* endPtr = NULL;
327
        pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
328 329
        break;
      }
330 331 332
      case TSDB_DATA_TYPE_UTINYINT:
      case TSDB_DATA_TYPE_USMALLINT:
      case TSDB_DATA_TYPE_UINT:
X
Xiaoyu Wang 已提交
333
      case TSDB_DATA_TYPE_UBIGINT: {
334 335 336 337 338
        char* endPtr = NULL;
        pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
        break;
      }
      case TSDB_DATA_TYPE_FLOAT:
339 340 341 342 343
      case TSDB_DATA_TYPE_DOUBLE: {
        char* endPtr = NULL;
        pVal->datum.d = strtold(pVal->literal, &endPtr);
        break;
      }
344 345 346 347
      case TSDB_DATA_TYPE_BINARY:
      case TSDB_DATA_TYPE_NCHAR:
      case TSDB_DATA_TYPE_VARCHAR:
      case TSDB_DATA_TYPE_VARBINARY: {
348
        int32_t n = strlen(pVal->literal);
X
Xiaoyu Wang 已提交
349
        pVal->datum.p = calloc(1, n + VARSTR_HEADER_SIZE);
X
Xiaoyu Wang 已提交
350
        if (NULL == pVal->datum.p) {
X
Xiaoyu Wang 已提交
351
          generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
X
Xiaoyu Wang 已提交
352 353
          return DEAL_RES_ERROR;
        }
354
        trimStringCopy(pVal->literal, n, true, pVal->datum.p);
355 356 357 358 359
        break;
      }
      case TSDB_DATA_TYPE_TIMESTAMP: {
        int32_t n = strlen(pVal->literal);
        char* tmp = calloc(1, n);
X
Xiaoyu Wang 已提交
360
        if (NULL == tmp) {
X
Xiaoyu Wang 已提交
361
          generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
X
Xiaoyu Wang 已提交
362 363
          return DEAL_RES_ERROR;
        }
364
        int32_t len = trimStringCopy(pVal->literal, n, false, tmp);
S
os env  
Shengliang Guan 已提交
365
        if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
366 367
          tfree(tmp);
          generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
368
          return DEAL_RES_ERROR;
369 370 371 372
        }
        tfree(tmp);
        break;
      }
373 374 375 376
      case TSDB_DATA_TYPE_JSON:
      case TSDB_DATA_TYPE_DECIMAL:
      case TSDB_DATA_TYPE_BLOB:
        // todo
377 378 379 380
      default:
        break;
    }
  }
381
  return DEAL_RES_CONTINUE;
382 383
}

384
static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
385 386 387 388 389
  SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType;
  SDataType rdt = ((SExprNode*)(pOp->pRight))->resType;
  if (nodesIsArithmeticOp(pOp)) {
    if (TSDB_DATA_TYPE_JSON == ldt.type || TSDB_DATA_TYPE_BLOB == ldt.type ||
        TSDB_DATA_TYPE_JSON == rdt.type || TSDB_DATA_TYPE_BLOB == rdt.type) {
390
      generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName);
391
      return DEAL_RES_ERROR;
392 393 394 395 396 397
    }
    pOp->node.resType.type = TSDB_DATA_TYPE_DOUBLE;
    pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
  } else if (nodesIsComparisonOp(pOp)) {
    if (TSDB_DATA_TYPE_JSON == ldt.type || TSDB_DATA_TYPE_BLOB == ldt.type ||
        TSDB_DATA_TYPE_JSON == rdt.type || TSDB_DATA_TYPE_BLOB == rdt.type) {
398
      generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName);
399
      return DEAL_RES_ERROR;
400 401 402 403 404 405
    }
    pOp->node.resType.type = TSDB_DATA_TYPE_BOOL;
    pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
  } else {
    // todo json operator
  }
406
  return DEAL_RES_CONTINUE;
407 408
}

409
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
X
Xiaoyu Wang 已提交
410
  if (TSDB_CODE_SUCCESS != fmGetFuncInfo(pFunc->functionName, &pFunc->funcId, &pFunc->funcType)) {
411
    generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_INVALID_FUNTION, pFunc->functionName);
412
    return DEAL_RES_ERROR;
413 414
  }
  int32_t code = fmGetFuncResultType(pFunc);
415 416
  if (TSDB_CODE_SUCCESS != code) {
    generateSyntaxErrMsg(pCxt, code, pFunc->functionName);
417
    return DEAL_RES_ERROR;
418
  }
419
  if (fmIsAggFunc(pFunc->funcId) && beforeHaving(pCxt->currClause)) {
420
    generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
421
    return DEAL_RES_ERROR;
422
  }
423 424 425 426 427
  return DEAL_RES_CONTINUE;
}

static EDealRes translateExprSubquery(STranslateContext* pCxt, SNode* pNode) {
  return (TSDB_CODE_SUCCESS == translateSubquery(pCxt, pNode) ? DEAL_RES_CONTINUE : DEAL_RES_ERROR);
428 429
}

430 431 432 433 434 435
static EDealRes translateLogicCond(STranslateContext* pCxt, SLogicConditionNode* pCond) {
  pCond->node.resType.type = TSDB_DATA_TYPE_BOOL;
  pCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
  return DEAL_RES_CONTINUE;
}

436
static EDealRes doTranslateExpr(SNode* pNode, void* pContext) {
437 438 439 440 441 442 443 444
  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);
445
    case QUERY_NODE_FUNCTION:
446
      return translateFunction(pCxt, (SFunctionNode*)pNode);
447 448
    case QUERY_NODE_LOGIC_CONDITION:
      return translateLogicCond(pCxt, (SLogicConditionNode*)pNode);
449
    case QUERY_NODE_TEMP_TABLE:
450
      return translateExprSubquery(pCxt, ((STempTableNode*)pNode)->pSubquery);
451 452 453
    default:
      break;
  }
454
  return DEAL_RES_CONTINUE;
455 456 457 458 459 460 461 462 463 464 465 466
}

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;
}

467 468 469 470
static bool isAliasColumn(SColumnNode* pCol) {
  return ('\0' == pCol->tableAlias[0]);
}

471 472 473 474
static bool isDistinctOrderBy(STranslateContext* pCxt) {
  return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct);
}

475
static SNodeList* getGroupByList(STranslateContext* pCxt) {
476
  if (isDistinctOrderBy(pCxt)) {
477 478 479 480 481 482 483 484 485 486 487 488 489
    return pCxt->pCurrStmt->pProjectionList;
  }
  return pCxt->pCurrStmt->pGroupByList;
}

static SNode* getGroupByNode(SNode* pNode) {
  if (QUERY_NODE_GROUPING_SET == nodeType(pNode)) {
    return nodesListGetNode(((SGroupingSetNode*)pNode)->pParameterList, 0);
  }
  return pNode;
}

static int32_t getGroupByErrorCode(STranslateContext* pCxt) {
490
  if (isDistinctOrderBy(pCxt)) {
491 492 493 494 495 496
    return TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION;
  }
  return TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION;
}

static EDealRes doCheckExprForGroupBy(SNode* pNode, void* pContext) {
497 498 499 500
  STranslateContext* pCxt = (STranslateContext*)pContext;
  if (!nodesIsExprNode(pNode) || (QUERY_NODE_COLUMN == nodeType(pNode) && isAliasColumn((SColumnNode*)pNode))) {
    return DEAL_RES_CONTINUE;
  }
501
  if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId) && !isDistinctOrderBy(pCxt)) {
502 503 504
    return DEAL_RES_IGNORE_CHILD;
  }
  SNode* pGroupNode;
505 506
  FOREACH(pGroupNode, getGroupByList(pCxt)) {
    if (nodesEqualNode(getGroupByNode(pGroupNode), pNode)) {
507 508 509
      return DEAL_RES_IGNORE_CHILD;
    }
  }
510 511
  if (QUERY_NODE_COLUMN == nodeType(pNode) ||
      (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId) && isDistinctOrderBy(pCxt))) {
512
    generateSyntaxErrMsg(pCxt, getGroupByErrorCode(pCxt));
513 514 515 516 517 518
    return DEAL_RES_ERROR;
  }
  return DEAL_RES_CONTINUE;
}

static int32_t checkExprForGroupBy(STranslateContext* pCxt, SNode* pNode) {
519
  nodesWalkNode(pNode, doCheckExprForGroupBy, pCxt);
520 521 522 523
  return pCxt->errCode;
}

static int32_t checkExprListForGroupBy(STranslateContext* pCxt, SNodeList* pList) {
524 525 526 527
  if (NULL == getGroupByList(pCxt)) {
    return TSDB_CODE_SUCCESS;
  }
  nodesWalkList(pList, doCheckExprForGroupBy, pCxt);
528 529 530
  return pCxt->errCode;
}

531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
typedef struct CheckAggColCoexistCxt {
  STranslateContext* pTranslateCxt;
  bool existAggFunc;
  bool existCol;
} CheckAggColCoexistCxt;

static EDealRes doCheckAggColCoexist(SNode* pNode, void* pContext) {
  CheckAggColCoexistCxt* pCxt = (CheckAggColCoexistCxt*)pContext;
  if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId)) {
    pCxt->existAggFunc = true;
    return DEAL_RES_IGNORE_CHILD;
  }
  if (QUERY_NODE_COLUMN == nodeType(pNode)) {
    pCxt->existCol = true;
  }
  return DEAL_RES_CONTINUE;
}

static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (NULL != pSelect->pGroupByList) {
    return TSDB_CODE_SUCCESS;
  }
  CheckAggColCoexistCxt cxt = { .pTranslateCxt = pCxt, .existAggFunc = false, .existCol = false };
  nodesWalkList(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
  if (!pSelect->isDistinct) {
    nodesWalkList(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
  }
  if (cxt.existAggFunc && cxt.existCol) {
    return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_NOT_SINGLE_GROUP);
  }
  return TSDB_CODE_SUCCESS;
}

564 565 566 567 568 569
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;
570 571
      code = catalogGetTableMeta(pCxt->pParseCxt->pCatalog, pCxt->pParseCxt->pTransporter, &(pCxt->pParseCxt->mgmtEpSet),
          toName(pCxt->pParseCxt->acctId, pRealTable, &name), &(pRealTable->pMeta));
572
      if (TSDB_CODE_SUCCESS != code) {
573
        return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_TABLE_NOT_EXIST, pRealTable->table.tableName);
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
      }
      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;
}

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);
607
    pSelect->pProjectionList = nodesMakeList();
X
Xiaoyu Wang 已提交
608
    if (NULL == pSelect->pProjectionList) {
X
Xiaoyu Wang 已提交
609
      return generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
X
Xiaoyu Wang 已提交
610
    }
611 612
    for (size_t i = 0; i < nums; ++i) {
      STableNode* pTable = taosArrayGetP(pTables, i);
X
Xiaoyu Wang 已提交
613 614 615 616
      int32_t code = createColumnNodeByTable(pCxt, pTable, pSelect->pProjectionList);
      if (TSDB_CODE_SUCCESS != code) {
        return code;
      }
617 618 619 620 621
    }
    *pIsSelectStar = true;
  } else {

  }
622
  return TSDB_CODE_SUCCESS;
623 624
}

625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
static int32_t getPositionValue(const SValueNode* pVal) {
  switch (pVal->node.resType.type) {
    case TSDB_DATA_TYPE_NULL:
    case TSDB_DATA_TYPE_BINARY:
    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;
}

X
Xiaoyu Wang 已提交
656
static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList, bool* pOther) {
657 658 659
  *pOther = false;
  SNode* pNode;
  FOREACH(pNode, pOrderByList) {
660 661 662 663
    SNode* pExpr = ((SOrderByExprNode*)pNode)->pExpr;
    if (QUERY_NODE_VALUE == nodeType(pExpr)) {
      SValueNode* pVal = (SValueNode*)pExpr;
      if (!translateValue(pCxt, pVal)) {
X
Xiaoyu Wang 已提交
664
        return pCxt->errCode;
665
      }
X
Xiaoyu Wang 已提交
666
      int32_t pos = getPositionValue(pVal);
667 668 669 670
      if (pos < 0) {
        ERASE_NODE(pOrderByList);
        continue;
      } else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) {
X
Xiaoyu Wang 已提交
671
        return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
672 673
      } else {
        SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
X
Xiaoyu Wang 已提交
674
        if (NULL == pCol) {
X
Xiaoyu Wang 已提交
675
          return generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
X
Xiaoyu Wang 已提交
676
        }
677 678 679
        setColumnInfoByExpr(NULL, (SExprNode*)nodesListGetNode(pProjectionList, pos - 1), pCol);
        ((SOrderByExprNode*)pNode)->pExpr = (SNode*)pCol;
        nodesDestroyNode(pExpr);
680 681 682 683 684
      }
    } else {
      *pOther = true;
    }
  }
X
Xiaoyu Wang 已提交
685
  return TSDB_CODE_SUCCESS;
686 687
}

688
static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
689
  bool other;
X
Xiaoyu Wang 已提交
690 691 692
  int32_t code = translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other);
  if (TSDB_CODE_SUCCESS != code) {
    return code;
693 694 695 696 697
  }
  if (!other) {
    return TSDB_CODE_SUCCESS;
  }
  pCxt->currClause = SQL_CLAUSE_ORDER_BY;
X
Xiaoyu Wang 已提交
698
  code = translateExprList(pCxt, pSelect->pOrderByList);
699
  if (TSDB_CODE_SUCCESS == code) {
700 701 702
    code = checkExprListForGroupBy(pCxt, pSelect->pOrderByList);
  }
  return code;
703 704 705 706 707 708 709 710 711
}

static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) {
  bool isSelectStar = false;
  int32_t code = translateStar(pCxt, pSelect, &isSelectStar);
  if (TSDB_CODE_SUCCESS == code && !isSelectStar) {
    pCxt->currClause = SQL_CLAUSE_SELECT;
    code = translateExprList(pCxt, pSelect->pProjectionList);
  }
712
  if (TSDB_CODE_SUCCESS == code) {
713 714
    code = checkExprListForGroupBy(pCxt, pSelect->pProjectionList);
  }
715 716 717
  return code;
}

718 719 720 721
static int32_t translateHaving(STranslateContext* pCxt, SSelectStmt* pSelect) {
  if (NULL == pSelect->pGroupByList && NULL != pSelect->pHaving) {
    return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
  }
722
  pCxt->currClause = SQL_CLAUSE_HAVING;
723 724 725 726 727
  int32_t code = translateExpr(pCxt, pSelect->pHaving);
  if (TSDB_CODE_SUCCESS == code) {
    code = checkExprForGroupBy(pCxt, pSelect->pHaving);
  }
  return code;
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
}

static int32_t translateGroupBy(STranslateContext* pCxt, SNodeList* pGroupByList) {
  pCxt->currClause = SQL_CLAUSE_GROUP_BY;
  return translateExprList(pCxt, pGroupByList);
}

static int32_t translateWindow(STranslateContext* pCxt, SNode* pWindow) {
  pCxt->currClause = SQL_CLAUSE_WINDOW;
  return translateExpr(pCxt, pWindow);
}

static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartitionByList) {
  pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
  return translateExprList(pCxt, pPartitionByList);
}

static int32_t translateWhere(STranslateContext* pCxt, SNode* pWhere) {
  pCxt->currClause = SQL_CLAUSE_WHERE;
  return translateExpr(pCxt, pWhere);
}

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

755
static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
756 757
  pCxt->pCurrStmt = pSelect;
  int32_t code = translateFrom(pCxt, pSelect->pFromTable);
758
  if (TSDB_CODE_SUCCESS == code) {
759
    code = translateWhere(pCxt, pSelect->pWhere);
760
  }
761
  if (TSDB_CODE_SUCCESS == code) {
762
    code = translatePartitionBy(pCxt, pSelect->pPartitionByList);
763
  }
764
  if (TSDB_CODE_SUCCESS == code) {
765
    code = translateWindow(pCxt, pSelect->pWindow);
766
  }
767 768 769 770
  if (TSDB_CODE_SUCCESS == code) {
    code = translateGroupBy(pCxt, pSelect->pGroupByList);
  }
  if (TSDB_CODE_SUCCESS == code) {
771
    code = translateHaving(pCxt, pSelect);
772 773 774 775 776
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = translateSelectList(pCxt, pSelect);
  }
  if (TSDB_CODE_SUCCESS == code) {
777
    code = translateOrderBy(pCxt, pSelect);
778
  }
779 780 781
  if (TSDB_CODE_SUCCESS == code) {
    code = checkAggColCoexist(pCxt, pSelect);
  }
782 783 784
  return code;
}

785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
static void buildCreateDbReq(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt, SCreateDbReq* pReq) {
  SName name = {0};
  tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
  tNameGetFullDbName(&name, pReq->db);
  pReq->numOfVgroups = pStmt->options.numOfVgroups;
  pReq->cacheBlockSize = pStmt->options.cacheBlockSize;
  pReq->totalBlocks = pStmt->options.numOfBlocks;
  pReq->daysPerFile = pStmt->options.daysPerFile;
  pReq->daysToKeep0 = pStmt->options.keep;
  pReq->daysToKeep1 = -1;
  pReq->daysToKeep2 = -1;
  pReq->minRows = pStmt->options.minRowsPerBlock;
  pReq->maxRows = pStmt->options.maxRowsPerBlock;
  pReq->commitTime = -1;
  pReq->fsyncPeriod = pStmt->options.fsyncPeriod;
  pReq->walLevel = pStmt->options.walLevel;
  pReq->precision = pStmt->options.precision;
  pReq->compression = pStmt->options.compressionLevel;
  pReq->replications = pStmt->options.replica;
  pReq->quorum = pStmt->options.quorum;
  pReq->update = -1;
  pReq->cacheLastRow = pStmt->options.cachelast;
  pReq->ignoreExist = pStmt->ignoreExists;
  pReq->streamMode = pStmt->options.streamMode;
  return;
}

static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt) {
  SCreateDbReq createReq = {0};
  buildCreateDbReq(pCxt, pStmt, &createReq);

  pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
  if (NULL== pCxt->pCmdMsg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
  pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_DB;
  pCxt->pCmdMsg->msgLen = tSerializeSCreateDbReq(NULL, 0, &createReq);
  pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
  if (NULL== pCxt->pCmdMsg->pMsg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  tSerializeSCreateDbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq);

  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
832 833 834 835
static int32_t translateCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
  return TSDB_CODE_SUCCESS;
}

836 837 838 839 840 841
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;
842 843 844
    case QUERY_NODE_CREATE_DATABASE_STMT:
      code = translateCreateDatabase(pCxt, (SCreateDatabaseStmt*)pNode);
      break;
X
Xiaoyu Wang 已提交
845 846 847
    case QUERY_NODE_CREATE_TABLE_STMT:
      code = translateCreateTable(pCxt, (SCreateTableStmt*)pNode);
      break;
848 849 850 851 852 853 854 855
    default:
      break;
  }
  return code;
}

static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) {
  ++(pCxt->currLevel);
856
  ESqlClause currClause = pCxt->currClause;
857
  SSelectStmt* pCurrStmt = pCxt->pCurrStmt;
858 859
  int32_t code = translateQuery(pCxt, pNode);
  --(pCxt->currLevel);
860
  pCxt->currClause = currClause;
861
  pCxt->pCurrStmt = pCurrStmt;
862 863 864
  return code;
}

X
Xiaoyu Wang 已提交
865 866 867 868 869 870
int32_t setReslutSchema(STranslateContext* pCxt, SQuery* pQuery) {
  if (QUERY_NODE_SELECT_STMT == nodeType(pQuery->pRoot)) {
    SSelectStmt* pSelect = (SSelectStmt*)pQuery->pRoot;
    pQuery->numOfResCols = LIST_LENGTH(pSelect->pProjectionList);
    pQuery->pResSchema = calloc(pQuery->numOfResCols, sizeof(SSchema));
    if (NULL == pQuery->pResSchema) {
X
Xiaoyu Wang 已提交
871
      return generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
X
Xiaoyu Wang 已提交
872 873 874 875 876 877 878 879 880 881 882 883 884
    }
    SNode* pNode;
    int32_t index = 0;
    FOREACH(pNode, pSelect->pProjectionList) {
      SExprNode* pExpr = (SExprNode*)pNode;
      pQuery->pResSchema[index].type = pExpr->resType.type;
      pQuery->pResSchema[index].bytes = pExpr->resType.bytes;
      strcpy(pQuery->pResSchema[index].name, pExpr->aliasName);
    }
  }
  return TSDB_CODE_SUCCESS;
}

885 886 887 888 889 890 891 892
void destroyTranslateContext(STranslateContext* pCxt) {
  taosArrayDestroy(pCxt->pNsLevel);
  if (NULL != pCxt->pCmdMsg) {
    tfree(pCxt->pCmdMsg->pMsg);
    tfree(pCxt->pCmdMsg);
  }
}

893
int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
894 895 896 897 898 899 900 901
  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
  };
902
  int32_t code = fmFuncMgtInit();
X
Xiaoyu Wang 已提交
903 904
  if (TSDB_CODE_SUCCESS == code) {
    code = translateQuery(&cxt, pQuery->pRoot);
905
  }
906 907 908 909 910 911 912
  if (TSDB_CODE_SUCCESS == code) {
    if (pQuery->isCmd) {
      pQuery->pCmdMsg = cxt.pCmdMsg;
      cxt.pCmdMsg = NULL;
    } else {
      code = setReslutSchema(&cxt, pQuery);
    }
913
  }
914
  destroyTranslateContext(&cxt);
X
Xiaoyu Wang 已提交
915
  return code;
916
}