tscSQLParser.c 199.4 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * 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/>.
 */

#define _XOPEN_SOURCE
S
slguan 已提交
17
#define _DEFAULT_SOURCE
H
hzcheng 已提交
18

S
slguan 已提交
19
#include "os.h"
H
hjxilinx 已提交
20
#include "qast.h"
H
hzcheng 已提交
21
#include "taos.h"
S
slguan 已提交
22
#include "taosmsg.h"
H
hzcheng 已提交
23
#include "tstoken.h"
H
hjxilinx 已提交
24
#include "tstrbuild.h"
H
hjxilinx 已提交
25
#include "ttime.h"
H
hzcheng 已提交
26 27 28 29

#include "tscUtil.h"
#include "tschemautil.h"
#include "tsclient.h"
30
#include "ttokendef.h"
H
hjxilinx 已提交
31

H
hjxilinx 已提交
32 33
#include "name.h"

S
slguan 已提交
34 35 36 37 38 39 40 41
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"

// -1 is tbname column index, so here use the -2 as the initial value
#define COLUMN_INDEX_INITIAL_VAL (-2)
#define COLUMN_INDEX_INITIALIZER \
  { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL }
#define COLUMN_INDEX_VALIDE(index) (((index).tableIndex >= 0) && ((index).columnIndex >= TSDB_TBNAME_COLUMN_INDEX))
#define TBNAME_LIST_SEP ","
H
hzcheng 已提交
42 43

typedef struct SColumnList {
S
slguan 已提交
44 45
  int32_t      num;
  SColumnIndex ids[TSDB_MAX_COLUMNS];
H
hzcheng 已提交
46 47
} SColumnList;

48
static SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIdx, int32_t tableIndex);
H
hzcheng 已提交
49 50

static int32_t setShowInfo(SSqlObj* pSql, SSqlInfo* pInfo);
H
hjxilinx 已提交
51
static char*   getAccountId(SSqlObj* pSql);
H
hzcheng 已提交
52

H
hjxilinx 已提交
53
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name);
H
hzcheng 已提交
54 55 56 57 58
static void getCurrentDBName(SSqlObj* pSql, SSQLToken* pDBToken);
static bool hasSpecifyDB(SSQLToken* pTableName);
static bool validateTableColumnInfo(tFieldList* pFieldList, SSqlCmd* pCmd);
static bool validateTagParams(tFieldList* pTagsList, tFieldList* pFieldList, SSqlCmd* pCmd);

59
static int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQLToken* tableName, int32_t* len);
H
hzcheng 已提交
60

H
hjxilinx 已提交
61
static void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength);
H
hzcheng 已提交
62 63
static void getRevisedName(char* resultFieldName, int32_t functionId, int32_t maxLen, char* columnName);

64
static int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem, bool finalResult);
65
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
H
hjxilinx 已提交
66
                                 int8_t type, char* fieldName, SSqlExpr* pSqlExpr);
S
slguan 已提交
67
static int32_t changeFunctionID(int32_t optr, int16_t* functionId);
H
hjxilinx 已提交
68
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable);
H
hzcheng 已提交
69

70
static bool validateIpAddress(const char* ip, size_t size);
71
static bool hasUnsupportFunctionsForSTableQuery(SQueryInfo* pQueryInfo);
72 73
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo);
static void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo);
H
hzcheng 已提交
74

75
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd);
H
hzcheng 已提交
76

77
static int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
H
hjxilinx 已提交
78
static int32_t parseSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
H
hzcheng 已提交
79

80
static int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pItem);
H
hzcheng 已提交
81

82
static int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql);
83
static int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL);
S
slguan 已提交
84
static int32_t parseOrderbyClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema);
H
hzcheng 已提交
85

86
static int32_t tsRewriteFieldNameIfNecessary(SQueryInfo* pQueryInfo);
H
hzcheng 已提交
87
static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
88
static int32_t validateSqlFunctionInStreamSql(SQueryInfo* pQueryInfo);
S
slguan 已提交
89
static int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString);
90
static int32_t validateFunctionsInIntervalOrGroupbyQuery(SQueryInfo* pQueryInfo);
H
hjxilinx 已提交
91
static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
H
hzcheng 已提交
92
static int32_t validateDNodeConfig(tDCLSQL* pOptions);
S
slguan 已提交
93
static int32_t validateLocalConfig(tDCLSQL* pOptions);
H
hzcheng 已提交
94 95
static int32_t validateColumnName(char* name);
static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
S
slguan 已提交
96

H
hjxilinx 已提交
97
static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField);
98
static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo);
H
hjxilinx 已提交
99

100
static void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex);
S
slguan 已提交
101

102
static int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t index, SQuerySQL* pQuerySql, SSqlObj* pSql);
H
hjxilinx 已提交
103
static int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql);
104
static int32_t getColumnIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
105
static int32_t getTableIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
S
slguan 已提交
106 107
static int32_t optrToString(tSQLExpr* pExpr, char** exprString);

108 109
static int32_t getMeterIndex(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
static int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
110
static int32_t doLocalQueryProcess(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
111
static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate);
H
hjxilinx 已提交
112

S
slguan 已提交
113
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex);
H
hjxilinx 已提交
114

115
static int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo);
116 117 118 119
static int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo);
static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo);
static int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index);

H
hjxilinx 已提交
120 121 122
static int32_t tSQLBinaryExprCreateFromSqlExpr(tSQLSyntaxNode **pExpr, tSQLExpr* pAst, int32_t* num,
    SColIndexEx** pColIndex, SSqlExprInfo* pExprInfo);

H
hjxilinx 已提交
123 124 125 126
/*
 * Used during parsing query sql. Since the query sql usually small in length, error position
 * is not needed in the final error message.
 */
127 128
static int32_t invalidSqlErrMsg(char* dstBuffer, const char* errMsg) {
  return tscInvalidSQLErrMsg(dstBuffer, errMsg, NULL);
H
hjxilinx 已提交
129 130
}

131
static int32_t tscQueryOnlyMetricTags(SQueryInfo* pQueryInfo, bool* queryOnMetricTags) {
132
  assert(QUERY_IS_STABLE_QUERY(pQueryInfo->type));
H
hzcheng 已提交
133 134

  *queryOnMetricTags = true;
H
hjxilinx 已提交
135
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
136
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hzcheng 已提交
137

S
slguan 已提交
138 139
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ &&
        !(pExpr->functionId == TSDB_FUNC_COUNT && pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX)) {
H
hzcheng 已提交
140 141 142 143 144 145 146 147
      *queryOnMetricTags = false;
      break;
    }
  }

  return TSDB_CODE_SUCCESS;
}

148
static int setColumnFilterInfoForTimestamp(SQueryInfo* pQueryInfo, tVariant* pVar) {
S
slguan 已提交
149 150 151 152 153
  int64_t     time = 0;
  const char* msg = "invalid timestamp";

  strdequote(pVar->pz);
  char*           seg = strnchr(pVar->pz, '-', pVar->nLen, false);
H
hjxilinx 已提交
154
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
155

H
hjxilinx 已提交
156
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
157
  
S
slguan 已提交
158
  if (seg != NULL) {
H
hjxilinx 已提交
159
    if (taosParseTime(pVar->pz, &time, pVar->nLen, tinfo.precision) != TSDB_CODE_SUCCESS) {
160
      return invalidSqlErrMsg(pQueryInfo->msg, msg);
S
slguan 已提交
161 162 163
    }
  } else {
    if (tVariantDump(pVar, (char*)&time, TSDB_DATA_TYPE_BIGINT)) {
164
      return invalidSqlErrMsg(pQueryInfo->msg, msg);
S
slguan 已提交
165 166 167 168 169 170 171 172 173
    }
  }

  tVariantDestroy(pVar);
  tVariantCreateFromBinary(pVar, (char*)&time, 0, TSDB_DATA_TYPE_BIGINT);

  return TSDB_CODE_SUCCESS;
}

174 175 176 177 178 179
static int32_t handlePassword(SSqlCmd* pCmd, SSQLToken* pPwd) {
  const char* msg1 = "password can not be empty";
  const char* msg2 = "name or password too long";
  const char* msg3 = "password needs single quote marks enclosed";

  if (pPwd->type != TK_STRING) {
180
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
181 182 183 184 185 186 187
  }

  strdequote(pPwd->z);
  strtrim(pPwd->z);  // trim space before and after passwords
  pPwd->n = strlen(pPwd->z);

  if (pPwd->n <= 0) {
188
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
189 190 191
  }

  if (pPwd->n > TSDB_PASSWORD_LEN) {
192
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
193 194 195 196 197
  }

  return TSDB_CODE_SUCCESS;
}

H
hzcheng 已提交
198 199 200 201 202 203
// todo handle memory leak in error handle function
int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
  if (pInfo == NULL || pSql == NULL || pSql->signature != pSql) {
    return TSDB_CODE_APP_ERROR;
  }

204
  SSqlCmd*    pCmd = &(pSql->cmd);
205
  SQueryInfo* pQueryInfo = NULL;
H
hzcheng 已提交
206

207
  if (!pInfo->valid) {
208
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), pInfo->pzErrMsg);
H
hzcheng 已提交
209 210
  }

211
  int32_t code = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex, &pQueryInfo);
H
hjxilinx 已提交
212
//  assert(pQueryInfo->numOfTables == 0);
H
hjxilinx 已提交
213

H
hjxilinx 已提交
214 215 216 217 218 219
  STableMetaInfo* pTableMetaInfo = NULL;
  if (pQueryInfo->numOfTables == 0) {
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
  } else {
    pTableMetaInfo = &pQueryInfo->pTableMetaInfo[0];
  }
220

221 222 223 224 225 226 227 228
  pCmd->command = pInfo->type;

  switch (pInfo->type) {
    case TSDB_SQL_DROP_TABLE:
    case TSDB_SQL_DROP_USER:
    case TSDB_SQL_DROP_ACCT:
    case TSDB_SQL_DROP_DNODE:
    case TSDB_SQL_DROP_DB: {
229 230
      const char* msg1 = "invalid ip address";
      const char* msg2 = "invalid name";
231
      const char* msg3 = "param name too long";
H
hzcheng 已提交
232 233

      SSQLToken* pzName = &pInfo->pDCLInfo->a[0];
234
      if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (tscValidateName(pzName) != TSDB_CODE_SUCCESS)) {
235
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
236 237
      }

238 239
      if (pInfo->type == TSDB_SQL_DROP_DB) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
240

H
hjxilinx 已提交
241
        code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pzName, NULL, NULL);
H
hzcheng 已提交
242
        if (code != TSDB_CODE_SUCCESS) {
243
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
244 245
        }

246 247
      } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
248

H
hjxilinx 已提交
249
        if (setMeterID(pTableMetaInfo, pzName, pSql) != TSDB_CODE_SUCCESS) {
250
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
251
        }
252 253
      } else if (pInfo->type == TSDB_SQL_DROP_DNODE) {
        if (!validateIpAddress(pzName->z, pzName->n)) {
254
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
255 256
        }

H
hjxilinx 已提交
257
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
258 259
      } else {  // drop user
        if (pzName->n > TSDB_USER_LEN) {
260
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
261 262
        }

H
hjxilinx 已提交
263
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
264 265
      }

266 267
      break;
    }
H
hzcheng 已提交
268

269 270 271
    case TSDB_SQL_USE_DB: {
      const char* msg = "invalid db name";
      SSQLToken*  pToken = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
272 273

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
274
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
275 276
      }

H
hjxilinx 已提交
277
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pToken, NULL, NULL);
H
hzcheng 已提交
278
      if (ret != TSDB_CODE_SUCCESS) {
279
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
280 281 282 283 284
      }

      break;
    }

285 286
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
287 288
    }

289 290 291
    case TSDB_SQL_SHOW: {
      if (setShowInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
292 293
      }

294 295 296 297 298 299 300 301
      break;
    }

    case TSDB_SQL_ALTER_DB:
    case TSDB_SQL_CREATE_DB: {
      const char* msg1 = "invalid db name";
      const char* msg2 = "name too long";

302
      SCreateDBInfo* pCreateDB = &(pInfo->pDCLInfo->dbOpt);
H
hzcheng 已提交
303
      if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) {
304
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
305 306
      }

H
hjxilinx 已提交
307
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname), NULL, NULL);
H
hzcheng 已提交
308
      if (ret != TSDB_CODE_SUCCESS) {
309
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
310 311
      }

H
hjxilinx 已提交
312
      if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
313
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
314 315 316 317 318
      }

      break;
    }

319
    case TSDB_SQL_CREATE_DNODE: {  // todo parse hostname
S
slguan 已提交
320 321
      const char* msg = "invalid ip address";

322
      if (pInfo->pDCLInfo->nTokens > 1) {
323
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
324 325
      }

326 327
      SSQLToken* pIpAddr = &pInfo->pDCLInfo->a[0];
      if (!validateIpAddress(pIpAddr->z, pIpAddr->n)) {
328
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
329 330 331 332 333
      }

      break;
    }

334 335 336 337 338
    case TSDB_SQL_CREATE_ACCT:
    case TSDB_SQL_ALTER_ACCT: {
      const char* msg1 = "invalid state option, available options[no, r, w, all]";
      const char* msg2 = "invalid user/account name";
      const char* msg3 = "name too long";
H
hzcheng 已提交
339

340 341
      SSQLToken* pName = &pInfo->pDCLInfo->user.user;
      SSQLToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
342

343 344
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
345 346
      }

347
      if (pName->n > TSDB_USER_LEN) {
348
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
349 350
      }

351
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
352
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
353 354 355
      }

      SCreateAcctSQL* pAcctOpt = &pInfo->pDCLInfo->acctOpt;
356
      if (pAcctOpt->stat.n > 0) {
H
hzcheng 已提交
357 358 359 360 361
        if (pAcctOpt->stat.z[0] == 'r' && pAcctOpt->stat.n == 1) {
        } else if (pAcctOpt->stat.z[0] == 'w' && pAcctOpt->stat.n == 1) {
        } else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) {
        } else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) {
        } else {
362
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
363 364
        }
      }
365

H
hzcheng 已提交
366 367 368
      break;
    }

369
    case TSDB_SQL_DESCRIBE_TABLE: {
S
slguan 已提交
370
      SSQLToken*  pToken = &pInfo->pDCLInfo->a[0];
371
      const char* msg2 = "table name is too long";
H
hjxilinx 已提交
372
      const char* msg1 = "invalid table name";
H
hzcheng 已提交
373

S
slguan 已提交
374
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
375
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
376
      }
S
slguan 已提交
377

S
slguan 已提交
378
      if (pToken->n > TSDB_TABLE_NAME_LEN) {
379
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
380 381
      }

H
hjxilinx 已提交
382
      if (setMeterID(pTableMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
383
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
384 385
      }

H
hjxilinx 已提交
386
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
387 388
    }

389
    case TSDB_SQL_CFG_DNODE: {
390 391
      const char* msg1 = "invalid ip address";
      const char* msg2 = "invalid configure options or values";
H
hzcheng 已提交
392

393 394 395
      /* validate the ip address */
      tDCLSQL* pDCL = pInfo->pDCLInfo;
      if (!validateIpAddress(pDCL->a[0].z, pDCL->a[0].n)) {
396
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
397 398
      }

399 400
      /* validate the parameter names and options */
      if (validateDNodeConfig(pDCL) != TSDB_CODE_SUCCESS) {
401
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
402 403
      }

404 405
      char* pMsg = pCmd->payload + tsRpcHeadSize;
      pMsg += sizeof(SMgmtHead);
H
hzcheng 已提交
406

S
slguan 已提交
407
      SCMCfgDnodeMsg* pCfg = (SCMCfgDnodeMsg*)pMsg;
408
      strncpy(pCfg->ip, pDCL->a[0].z, pDCL->a[0].n);
H
hzcheng 已提交
409

410
      strncpy(pCfg->config, pDCL->a[1].z, pDCL->a[1].n);
H
hzcheng 已提交
411

412 413 414 415
      if (pDCL->nTokens == 3) {
        pCfg->config[pDCL->a[1].n] = ' ';  // add sep
        strncpy(&pCfg->config[pDCL->a[1].n + 1], pDCL->a[2].z, pDCL->a[2].n);
      }
H
hzcheng 已提交
416

417 418
      break;
    }
H
hzcheng 已提交
419

420 421 422 423 424 425
    case TSDB_SQL_CREATE_USER:
    case TSDB_SQL_ALTER_USER: {
      const char* msg5 = "invalid user rights";
      const char* msg7 = "not support options";
      const char* msg2 = "invalid user/account name";
      const char* msg3 = "name too long";
H
hzcheng 已提交
426

427
      pCmd->command = pInfo->type;
H
hjxilinx 已提交
428
      // tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
429

430 431 432
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
      SSQLToken* pName = &pUser->user;
      SSQLToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
433

434
      if (pName->n > TSDB_USER_LEN) {
435
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
436
      }
H
hzcheng 已提交
437

438
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
439
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
440
      }
H
hzcheng 已提交
441

442 443 444 445 446 447 448 449
      if (pCmd->command == TSDB_SQL_CREATE_USER) {
        if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
          return TSDB_CODE_INVALID_SQL;
        }
      } else {
        if (pUser->type == TSDB_ALTER_USER_PASSWD) {
          if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
            return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
450
          }
451
        } else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
L
lihui 已提交
452 453 454
          assert(pPwd->type == TSDB_DATA_TYPE_NULL);

          SSQLToken* pPrivilege = &pUser->privilege;
H
hzcheng 已提交
455

L
lihui 已提交
456
          if (strncasecmp(pPrivilege->z, "super", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
457
            pCmd->count = 1;
L
lihui 已提交
458
          } else if (strncasecmp(pPrivilege->z, "read", 4) == 0 && pPrivilege->n == 4) {
H
hzcheng 已提交
459
            pCmd->count = 2;
L
lihui 已提交
460
          } else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
461 462
            pCmd->count = 3;
          } else {
463
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
464 465
          }
        } else {
466
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
467 468
        }
      }
469

H
hzcheng 已提交
470 471
      break;
    }
472 473

    case TSDB_SQL_CFG_LOCAL: {
S
slguan 已提交
474 475 476 477 478
      tDCLSQL*    pDCL = pInfo->pDCLInfo;
      const char* msg = "invalid configure options or values";

      // validate the parameter names and options
      if (validateLocalConfig(pDCL) != TSDB_CODE_SUCCESS) {
479
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
480 481 482 483 484 485 486
      }

      strncpy(pCmd->payload, pDCL->a[0].z, pDCL->a[0].n);
      if (pDCL->nTokens == 2) {
        pCmd->payload[pDCL->a[0].n] = ' ';  // add sep
        strncpy(&pCmd->payload[pDCL->a[0].n + 1], pDCL->a[1].z, pDCL->a[1].n);
      }
H
hzcheng 已提交
487 488 489 490

      break;
    }

491 492
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
493

494
      if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
495
        if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
496
          return code;
H
hzcheng 已提交
497 498
        }

499 500 501
      } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) {
        if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
502 503
        }

504 505 506
      } else if (pCreateTable->type == TSQL_CREATE_STREAM) {
        if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
S
slguan 已提交
507
        }
H
hzcheng 已提交
508 509 510 511 512
      }

      break;
    }

513
    case TSDB_SQL_SELECT: {
514
      assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
515
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
516

517
      for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) {
518 519 520 521
        SQueryInfo* pqi = NULL;
        if ((code = tscGetQueryInfoDetailSafely(pCmd, i, &pqi)) != TSDB_CODE_SUCCESS) {
          return code;
        }
522 523 524 525
      }

      assert(pCmd->numOfClause == pInfo->subclauseInfo.numOfClause);
      for (int32_t i = 0; i < pInfo->subclauseInfo.numOfClause; ++i) {
526
        SQuerySQL* pQuerySql = pInfo->subclauseInfo.pClause[i];
527

528 529
        if ((code = doCheckForQuery(pSql, pQuerySql, i)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
530
        }
H
hjxilinx 已提交
531

H
hjxilinx 已提交
532
        tscPrintSelectClause(pSql, i);
H
hzcheng 已提交
533
      }
H
hjxilinx 已提交
534

H
hjxilinx 已提交
535
      // set the command/global limit parameters from the first subclause to the sqlcmd object
536 537
      SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
      pCmd->command = pQueryInfo1->command;
H
hjxilinx 已提交
538

539
      // if there is only one element, the limit of clause is the limit of global result.
H
hjxilinx 已提交
540
      for (int32_t i = 1; i < pCmd->numOfClause; ++i) {
541
        SQueryInfo* pQueryInfo2 = tscGetQueryInfoDetail(pCmd, i);
H
hjxilinx 已提交
542

543 544 545
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
546
        }
547
      }
548 549

      return TSDB_CODE_SUCCESS;  // do not build query message here
550
    }
H
hzcheng 已提交
551

552 553 554
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
555 556 557 558 559
      }

      break;
    }

560 561 562 563
    case TSDB_SQL_KILL_QUERY:
    case TSDB_SQL_KILL_STREAM:
    case TSDB_SQL_KILL_CONNECTION: {
      if ((code = setKillInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
564 565 566 567 568 569 570
        return code;
      }

      break;
    }

    default:
571
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
572 573
  }

574
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
575 576
}

S
slguan 已提交
577 578 579 580
/*
 * if the top/bottom exists, only tags columns, tbname column, and primary timestamp column
 * are available.
 */
581
static bool isTopBottomQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
582
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
583
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
584 585 586 587

    if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) {
      return true;
    }
H
hzcheng 已提交
588 589
  }

S
slguan 已提交
590
  return false;
H
hzcheng 已提交
591 592
}

593
int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
S
slguan 已提交
594 595
  const char* msg1 = "invalid query expression";
  const char* msg2 = "interval cannot be less than 10 ms";
596

H
hjxilinx 已提交
597
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
598
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
599
  
H
hjxilinx 已提交
600
  if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
H
hzcheng 已提交
601 602 603 604 605
    return TSDB_CODE_SUCCESS;
  }

  // interval is not null
  SSQLToken* t = &pQuerySql->interval;
606
  if (getTimestampInUsFromStr(t->z, t->n, &pQueryInfo->intervalTime) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
607 608 609
    return TSDB_CODE_INVALID_SQL;
  }

H
hjxilinx 已提交
610
  // if the unit of time window value is millisecond, change the value from microsecond
H
hjxilinx 已提交
611
  if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
612
    pQueryInfo->intervalTime = pQueryInfo->intervalTime / 1000;
H
hzcheng 已提交
613 614 615
  }

  /* parser has filter the illegal type, no need to check here */
H
hjxilinx 已提交
616
  pQueryInfo->slidingTimeUnit = pQuerySql->interval.z[pQuerySql->interval.n - 1];
H
hzcheng 已提交
617 618

  // interval cannot be less than 10 milliseconds
619
  if (pQueryInfo->intervalTime < tsMinIntervalTime) {
620
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
621 622 623
  }

  // for top/bottom + interval query, we do not add additional timestamp column in the front
624
  if (isTopBottomQuery(pQueryInfo)) {
H
hjxilinx 已提交
625 626 627
    if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_INVALID_SQL;
    }
H
hjxilinx 已提交
628

H
hzcheng 已提交
629 630 631
    return TSDB_CODE_SUCCESS;
  }

H
hjxilinx 已提交
632 633 634
  /*
   * check invalid SQL:
   * select count(tbname)/count(tag1)/count(tag2) from super_table_name interval(1d);
H
hjxilinx 已提交
635
   */
H
hjxilinx 已提交
636
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
637
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
638
    if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
639
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
640 641
    }
  }
H
hjxilinx 已提交
642

H
hjxilinx 已提交
643 644 645
  /*
   * check invalid SQL:
   * select tbname, tags_fields from super_table_name interval(1s)
H
hjxilinx 已提交
646
   */
H
hjxilinx 已提交
647
  if (tscQueryTags(pQueryInfo) && pQueryInfo->intervalTime > 0) {
H
hjxilinx 已提交
648 649
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
  }
S
slguan 已提交
650 651

  // need to add timestamp column in result set, if interval is existed
652
  uint64_t uid = tscSqlExprGet(pQueryInfo, 0)->uid;
S
slguan 已提交
653 654

  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
655
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
656
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
hjxilinx 已提交
657
    if (pTableMetaInfo->pTableMeta->uid == uid) {
S
slguan 已提交
658 659 660 661 662 663 664 665 666 667
      tableIndex = i;
      break;
    }
  }

  if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
    return TSDB_CODE_INVALID_SQL;
  }

  SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
H
hjxilinx 已提交
668
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE);
H
hzcheng 已提交
669

S
slguan 已提交
670
  SColumnList ids = getColumnList(1, 0, PRIMARYKEY_TIMESTAMP_COL_INDEX);
671

H
hjxilinx 已提交
672 673
  int32_t ret =
      insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hjxilinx 已提交
674 675 676
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }
H
hjxilinx 已提交
677

H
hjxilinx 已提交
678
  if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
679 680
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
681

H
hjxilinx 已提交
682
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
683 684
}

H
hjxilinx 已提交
685
int32_t parseSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
686 687
  const char* msg0 = "sliding value too small";
  const char* msg1 = "sliding value no larger than the interval value";
H
hzcheng 已提交
688

H
hjxilinx 已提交
689
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
690
  SSQLToken*      pSliding = &pQuerySql->sliding;
H
hjxilinx 已提交
691
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
692 693

  if (pSliding->n != 0) {
H
hjxilinx 已提交
694
    getTimestampInUsFromStr(pSliding->z, pSliding->n, &pQueryInfo->slidingTime);
H
hjxilinx 已提交
695
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
696
      pQueryInfo->slidingTime /= 1000;
H
hzcheng 已提交
697 698
    }

H
hjxilinx 已提交
699
    if (pQueryInfo->slidingTime < tsMinSlidingTime) {
700
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
701 702
    }

H
hjxilinx 已提交
703
    if (pQueryInfo->slidingTime > pQueryInfo->intervalTime) {
704
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
705
    }
H
hjxilinx 已提交
706
  } else {
H
hjxilinx 已提交
707
    pQueryInfo->slidingTime = pQueryInfo->intervalTime;
H
hzcheng 已提交
708 709 710 711 712
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
713
int32_t setMeterID(STableMetaInfo* pTableMetaInfo, SSQLToken* pzTableName, SSqlObj* pSql) {
714
  const char* msg = "name too long";
H
hzcheng 已提交
715

716 717
  SSqlCmd* pCmd = &pSql->cmd;
  int32_t  code = TSDB_CODE_SUCCESS;
S
slguan 已提交
718

H
hjxilinx 已提交
719 720
  // backup the old name in pTableMetaInfo
  size_t size = strlen(pTableMetaInfo->name);
H
hjxilinx 已提交
721
  char*  oldName = NULL;
722
  if (size > 0) {
H
hjxilinx 已提交
723
    oldName = strdup(pTableMetaInfo->name);
724
  }
H
hjxilinx 已提交
725

H
hzcheng 已提交
726
  if (hasSpecifyDB(pzTableName)) {
727
    // db has been specified in sql string so we ignore current db path
H
hjxilinx 已提交
728
    code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), NULL, pzTableName, NULL);
S
slguan 已提交
729
  } else {  // get current DB name first, then set it into path
H
hzcheng 已提交
730 731 732
    SSQLToken t = {0};
    getCurrentDBName(pSql, &t);

H
hjxilinx 已提交
733
    code = setObjFullName(pTableMetaInfo->name, NULL, &t, pzTableName, NULL);
H
hzcheng 已提交
734 735
  }

S
slguan 已提交
736
  if (code != TSDB_CODE_SUCCESS) {
737
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
738 739
  }

740 741 742 743
  if (code != TSDB_CODE_SUCCESS) {
    free(oldName);
    return code;
  }
H
hjxilinx 已提交
744

745 746 747 748 749
  /*
   * the old name exists and is not equalled to the new name. Release the metermeta/metricmeta
   * that are corresponding to the old name for the new table name.
   */
  if (size > 0) {
H
hjxilinx 已提交
750 751
    if (strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
      tscClearMeterMetaInfo(pTableMetaInfo, false);
752 753
    }
  } else {
H
hjxilinx 已提交
754
    assert(pTableMetaInfo->pTableMeta == NULL);
755
  }
H
hjxilinx 已提交
756

757 758
  tfree(oldName);
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
759 760 761 762 763
}

static bool validateTableColumnInfo(tFieldList* pFieldList, SSqlCmd* pCmd) {
  assert(pFieldList != NULL);

764 765 766 767 768 769 770
  const char* msg = "illegal number of columns";
  const char* msg1 = "first column must be timestamp";
  const char* msg2 = "row length exceeds max length";
  const char* msg3 = "duplicated column names";
  const char* msg4 = "invalid data types";
  const char* msg5 = "invalid binary/nchar column length";
  const char* msg6 = "invalid column name";
H
hzcheng 已提交
771 772 773

  // number of fields no less than 2
  if (pFieldList->nField <= 1 || pFieldList->nField > TSDB_MAX_COLUMNS) {
774
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
775 776 777 778 779
    return false;
  }

  // first column must be timestamp
  if (pFieldList->p[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
780
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
781 782 783 784 785 786 787 788 789 790
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
    nLen += pFieldList->p[i].bytes;
  }

  // max row length must be less than TSDB_MAX_BYTES_PER_ROW
  if (nLen > TSDB_MAX_BYTES_PER_ROW) {
791
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
792 793 794 795 796 797 798
    return false;
  }

  // field name must be unique
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
    TAOS_FIELD* pField = &pFieldList->p[i];
    if (pField->type < TSDB_DATA_TYPE_BOOL || pField->type > TSDB_DATA_TYPE_NCHAR) {
799
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
800 801 802 803 804
      return false;
    }

    if ((pField->type == TSDB_DATA_TYPE_BINARY && (pField->bytes <= 0 || pField->bytes > TSDB_MAX_BINARY_LEN)) ||
        (pField->type == TSDB_DATA_TYPE_NCHAR && (pField->bytes <= 0 || pField->bytes > TSDB_MAX_NCHAR_LEN))) {
805
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
806 807 808 809
      return false;
    }

    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
810
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
811 812 813 814
      return false;
    }

    if (has(pFieldList, i + 1, pFieldList->p[i].name) == true) {
815
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
816 817 818 819 820 821 822 823 824 825
      return false;
    }
  }

  return true;
}

static bool validateTagParams(tFieldList* pTagsList, tFieldList* pFieldList, SSqlCmd* pCmd) {
  assert(pTagsList != NULL);

826 827 828 829 830 831 832
  const char* msg1 = "invalid number of tag columns";
  const char* msg2 = "tag length too long";
  const char* msg3 = "duplicated column names";
  const char* msg4 = "timestamp not allowed in tags";
  const char* msg5 = "invalid data type in tags";
  const char* msg6 = "invalid tag name";
  const char* msg7 = "invalid binary/nchar tag length";
H
hzcheng 已提交
833 834 835

  // number of fields at least 1
  if (pTagsList->nField < 1 || pTagsList->nField > TSDB_MAX_TAGS) {
836
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
837 838 839 840 841 842 843 844 845 846
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
    nLen += pTagsList->p[i].bytes;
  }

  // max tag row length must be less than TSDB_MAX_TAGS_LEN
  if (nLen > TSDB_MAX_TAGS_LEN) {
847
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
848 849 850 851 852 853
    return false;
  }

  // field name must be unique
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
    if (has(pFieldList, 0, pTagsList->p[i].name) == true) {
854
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
855 856 857 858 859 860 861
      return false;
    }
  }

  /* timestamp in tag is not allowed */
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
    if (pTagsList->p[i].type == TSDB_DATA_TYPE_TIMESTAMP) {
862
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
863 864 865 866
      return false;
    }

    if (pTagsList->p[i].type < TSDB_DATA_TYPE_BOOL || pTagsList->p[i].type > TSDB_DATA_TYPE_NCHAR) {
867
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
868 869 870 871 872
      return false;
    }

    if ((pTagsList->p[i].type == TSDB_DATA_TYPE_BINARY && pTagsList->p[i].bytes <= 0) ||
        (pTagsList->p[i].type == TSDB_DATA_TYPE_NCHAR && pTagsList->p[i].bytes <= 0)) {
873
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
874 875 876 877
      return false;
    }

    if (validateColumnName(pTagsList->p[i].name) != TSDB_CODE_SUCCESS) {
878
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
879 880 881 882
      return false;
    }

    if (has(pTagsList, i + 1, pTagsList->p[i].name) == true) {
883
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
884 885 886 887 888 889 890 891 892 893 894
      return false;
    }
  }

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
895 896 897 898 899 900
  const char* msg1 = "timestamp not allowed in tags";
  const char* msg2 = "duplicated column names";
  const char* msg3 = "tag length too long";
  const char* msg4 = "invalid tag name";
  const char* msg5 = "invalid binary/nchar tag length";
  const char* msg6 = "invalid data type in tags";
H
hzcheng 已提交
901

902
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
903

904
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
905
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
906

H
hjxilinx 已提交
907 908 909
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
910
  // no more than 6 tags
H
hjxilinx 已提交
911
  if (numOfTags == TSDB_MAX_TAGS) {
H
hzcheng 已提交
912 913 914
    char msg[128] = {0};
    sprintf(msg, "tags no more than %d", TSDB_MAX_TAGS);

915
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
916 917 918 919 920
    return false;
  }

  // no timestamp allowable
  if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) {
921
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
922 923 924
    return false;
  }

L
[#1236]  
lihui 已提交
925
  if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_NCHAR)) {
926
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
927 928 929
    return false;
  }

H
hjxilinx 已提交
930
  SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
931 932
  int32_t  nLen = 0;

H
hjxilinx 已提交
933
  for (int32_t i = 0; i < numOfTags; ++i) {
H
hzcheng 已提交
934 935 936 937 938
    nLen += pTagSchema[i].bytes;
  }

  // length less than TSDB_MAX_TASG_LEN
  if (nLen + pTagField->bytes > TSDB_MAX_TAGS_LEN) {
939
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
940 941 942 943 944
    return false;
  }

  // tags name can not be a keyword
  if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) {
945
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
946 947 948 949 950
    return false;
  }

  // binary(val), val can not be equalled to or less than 0
  if ((pTagField->type == TSDB_DATA_TYPE_BINARY || pTagField->type == TSDB_DATA_TYPE_NCHAR) && pTagField->bytes <= 0) {
951
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
952 953 954 955
    return false;
  }

  // field name must be unique
H
hjxilinx 已提交
956
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
957

H
hjxilinx 已提交
958
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
H
hzcheng 已提交
959
    if (strncasecmp(pTagField->name, pSchema[i].name, TSDB_COL_NAME_LEN) == 0) {
960
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
961 962 963 964 965 966 967 968
      return false;
    }
  }

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
969 970 971 972 973 974
  const char* msg1 = "too many columns";
  const char* msg2 = "duplicated column names";
  const char* msg3 = "column length too long";
  const char* msg4 = "invalid data types";
  const char* msg5 = "invalid column name";
  const char* msg6 = "invalid column length";
H
hzcheng 已提交
975

976
  assert(pCmd->numOfClause == 1);
977
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
978 979 980 981 982
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
983
  // no more max columns
H
hjxilinx 已提交
984
  if (numOfCols >= TSDB_MAX_COLUMNS || numOfTags + numOfCols >= TSDB_MAX_COLUMNS) {
985
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
986 987 988 989
    return false;
  }

  if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_NCHAR) {
990
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
991 992 993 994
    return false;
  }

  if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) {
995
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
996 997 998
    return false;
  }

H
hjxilinx 已提交
999
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
1000 1001
  int32_t  nLen = 0;

H
hjxilinx 已提交
1002
  for (int32_t i = 0; i < numOfCols; ++i) {
H
hzcheng 已提交
1003 1004 1005 1006
    nLen += pSchema[i].bytes;
  }

  if (pColField->bytes <= 0) {
1007
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1008 1009 1010 1011 1012
    return false;
  }

  // length less than TSDB_MAX_BYTES_PER_ROW
  if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) {
1013
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1014 1015 1016 1017
    return false;
  }

  // field name must be unique
H
hjxilinx 已提交
1018
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
H
hzcheng 已提交
1019
    if (strncasecmp(pColField->name, pSchema[i].name, TSDB_COL_NAME_LEN) == 0) {
1020
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1021 1022 1023 1024 1025 1026 1027 1028
      return false;
    }
  }

  return true;
}

/* is contained in pFieldList or not */
H
hjxilinx 已提交
1029
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name) {
H
hzcheng 已提交
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
  for (int32_t j = startIdx; j < pFieldList->nField; ++j) {
    if (strncasecmp(name, pFieldList->p[j].name, TSDB_COL_NAME_LEN) == 0) return true;
  }

  return false;
}

static char* getAccountId(SSqlObj* pSql) { return pSql->pTscObj->acctId; }

static void getCurrentDBName(SSqlObj* pSql, SSQLToken* pDBToken) {
  pDBToken->z = pSql->pTscObj->db;
  pDBToken->n = strlen(pSql->pTscObj->db);
}

/* length limitation, strstr cannot be applied */
static bool hasSpecifyDB(SSQLToken* pTableName) {
  for (int32_t i = 0; i < pTableName->n; ++i) {
    if (pTableName->z[i] == TS_PATH_DELIMITER[0]) {
      return true;
    }
  }

  return false;
}

1055
int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQLToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
  int32_t totalLen = 0;

  if (account != NULL) {
    int32_t len = strlen(account);
    strcpy(fullName, account);
    fullName[len] = TS_PATH_DELIMITER[0];
    totalLen += (len + 1);
  }

  /* db name is not specified, the tableName dose not include db name */
  if (pDB != NULL) {
    if (pDB->n > TSDB_DB_NAME_LEN) {
      return TSDB_CODE_INVALID_SQL;
    }

    memcpy(&fullName[totalLen], pDB->z, pDB->n);
    totalLen += pDB->n;
  }

  if (tableName != NULL) {
    if (pDB != NULL) {
      fullName[totalLen] = TS_PATH_DELIMITER[0];
      totalLen += 1;

      /* here we only check the table name length limitation */
S
slguan 已提交
1081
      if (tableName->n > TSDB_TABLE_NAME_LEN) {
H
hzcheng 已提交
1082 1083 1084 1085
        return TSDB_CODE_INVALID_SQL;
      }
    } else {  // pDB == NULL, the db prefix name is specified in tableName
      /* the length limitation includes tablename + dbname + sep */
S
slguan 已提交
1086
      if (tableName->n > TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN + tListLen(TS_PATH_DELIMITER)) {
H
hzcheng 已提交
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
        return TSDB_CODE_INVALID_SQL;
      }
    }

    memcpy(&fullName[totalLen], tableName->z, tableName->n);
    totalLen += tableName->n;
  }

  if (xlen != NULL) {
    *xlen = totalLen;
  }
S
slguan 已提交
1098

S
slguan 已提交
1099
  if (totalLen < TSDB_TABLE_ID_LEN) {
S
slguan 已提交
1100 1101 1102
    fullName[totalLen] = 0;
  }

S
slguan 已提交
1103
  return (totalLen <= TSDB_TABLE_ID_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1104 1105
}

S
slguan 已提交
1106
static void extractColumnNameFromString(tSQLExprItem* pItem) {
H
hzcheng 已提交
1107
  if (pItem->pNode->nSQLOptr == TK_STRING) {
S
slguan 已提交
1108
    pItem->pNode->val.nLen = strdequote(pItem->pNode->val.pz);
H
hzcheng 已提交
1109 1110 1111 1112
    pItem->pNode->nSQLOptr = TK_ID;

    SSQLToken* pIdToken = &pItem->pNode->colInfo;
    pIdToken->type = TK_ID;
S
slguan 已提交
1113 1114
    pIdToken->z = pItem->pNode->val.pz;
    pIdToken->n = pItem->pNode->val.nLen;
H
hzcheng 已提交
1115 1116 1117
  }
}

1118
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) {
H
hzcheng 已提交
1119 1120
  assert(pSelection != NULL && pCmd != NULL);

1121
  const char* msg1 = "invalid column name, or illegal column type";
1122 1123
  const char* msg2 = "functions can not be mixed up";
  const char* msg3 = "not support query expression";
1124
  const char* msg4 = "columns from different table mixed up in arithmetic expression";
H
hjxilinx 已提交
1125
  const char* msg5 = "invalid function name";
H
hjxilinx 已提交
1126

1127
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
1128

H
hzcheng 已提交
1129
  for (int32_t i = 0; i < pSelection->nExpr; ++i) {
H
hjxilinx 已提交
1130
    int32_t outputIndex = pQueryInfo->exprsInfo.numOfExprs;
H
hzcheng 已提交
1131 1132
    tSQLExprItem* pItem = &pSelection->a[i];

S
slguan 已提交
1133 1134 1135
    // project on all fields
    if (pItem->pNode->nSQLOptr == TK_ALL || pItem->pNode->nSQLOptr == TK_ID || pItem->pNode->nSQLOptr == TK_STRING) {
      // it is actually a function, but the function name is invalid
H
hzcheng 已提交
1136
      if (pItem->pNode->nSQLOptr == TK_ID && (pItem->pNode->colInfo.z == NULL && pItem->pNode->colInfo.n == 0)) {
H
hjxilinx 已提交
1137
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1138 1139
      }

S
slguan 已提交
1140 1141
      // if the name of column is quoted, remove it and set the right information for later process
      extractColumnNameFromString(pItem);
1142
      pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
S
slguan 已提交
1143 1144

      // select table_name1.field_name1, table_name2.field_name2  from table_name1, table_name2
1145
      if (addProjectionExprAndResultField(pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
1146
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1147
      }
L
lihui 已提交
1148
    } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_AVG_IRATE) {
S
slguan 已提交
1149
      // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
H
hjxilinx 已提交
1150
      if (addExprAndResultField(pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
1151 1152 1153 1154
        return TSDB_CODE_INVALID_SQL;
      }

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
H
hjxilinx 已提交
1155
      // arithmetic function in select clause
1156
      SColumnList columnList = {0};
H
hjxilinx 已提交
1157 1158 1159
      int32_t     arithmeticType = NON_ARITHMEIC_EXPR;

      if (validateArithmeticSQLExpr(pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
1160
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1161
      }
1162 1163
      
      int32_t tableIndex = columnList.ids[0].tableIndex;
H
hzcheng 已提交
1164 1165
      char  arithmeticExprStr[1024] = {0};
      char* p = arithmeticExprStr;
H
hjxilinx 已提交
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
      
      if (arithmeticType == NORMAL_ARITHMETIC) {
        pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
  
        // all columns in arithmetic expression must belong to the same table
        for (int32_t f = 1; f < columnList.num; ++f) {
          if (columnList.ids[f].tableIndex != tableIndex) {
            return invalidSqlErrMsg(pQueryInfo->msg, msg4);
          }
        }
  
        if (buildArithmeticExprString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
          return TSDB_CODE_INVALID_SQL;
        }
  
        // expr string is set as the parameter of function
        SColumnIndex index = {.tableIndex = tableIndex};
        SSqlExpr*    pExpr = tscSqlExprInsert(pQueryInfo, outputIndex, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE,
                                              sizeof(double), sizeof(double));
        addExprParams(pExpr, arithmeticExprStr, TSDB_DATA_TYPE_BINARY, strlen(arithmeticExprStr), index.tableIndex);
  
        /* todo alias name should use the original sql string */
        char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
        strncpy(pExpr->aliasName, name, TSDB_COL_NAME_LEN);
  
        insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
H
hzcheng 已提交
1192
      } else {
H
hjxilinx 已提交
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
        columnList.num = 0;
        columnList.ids[0] = (SColumnIndex) {0, 0};
        
        insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, "abc", NULL);
        
        int32_t slot = tscNumOfFields(pQueryInfo) - 1;
        
        if (pQueryInfo->fieldsInfo.pExpr[slot] == NULL) {
          SSqlFunctionExpr* pFuncExpr = calloc(1, sizeof(SSqlFunctionExpr));
          tscFieldInfoSetBinExpr(&pQueryInfo->fieldsInfo, slot, pFuncExpr);
          
          // arithmetic expression always return result in the format of double float
          pFuncExpr->resBytes = sizeof(double);
          pFuncExpr->interResBytes = sizeof(double);
          pFuncExpr->resType = TSDB_DATA_TYPE_DOUBLE;

1209
          SSqlBinaryExprInfo* pBinExprInfo = &pFuncExpr->binExprInfo;
H
hjxilinx 已提交
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
          
          tSQLSyntaxNode* pNode = NULL;
          SColIndexEx* pColIndex = NULL;
          
          int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pNode, pItem->pNode, &pBinExprInfo->numOfCols, &pColIndex, &pQueryInfo->exprsInfo);
          if (ret != TSDB_CODE_SUCCESS) {
            tSQLBinaryExprDestroy(&pNode->pExpr, NULL);
            return invalidSqlErrMsg(pQueryInfo->msg, "invalid expression in select clause");
          }
          
          pBinExprInfo->pBinExpr = pNode->pExpr;
          pBinExprInfo->pReqColumns = pColIndex;
          
          for(int32_t k = 0; k < pBinExprInfo->numOfCols; ++k) {
            SColIndexEx* pCol = &pBinExprInfo->pReqColumns[k];
            for(int32_t f = 0; f < pQueryInfo->exprsInfo.numOfExprs; ++f) {
              SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, f);
              if (strcmp(pExpr->aliasName, pCol->name) == 0) {
                pCol->colIdxInBuf = f;
                break;
              }
            }
            
            assert(pCol->colIdxInBuf >= 0 && pCol->colIdxInBuf < pQueryInfo->exprsInfo.numOfExprs);
            tfree(pNode);
          }
        }
H
hzcheng 已提交
1237 1238 1239 1240 1241 1242
      }
    } else {
      /*
       * not support such expression
       * e.g., select 12+5 from table_name
       */
1243
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1244 1245
    }

1246
    if (pQueryInfo->fieldsInfo.numOfOutputCols > TSDB_MAX_COLUMNS) {
H
hzcheng 已提交
1247 1248 1249 1250
      return TSDB_CODE_INVALID_SQL;
    }
  }

1251 1252
  if (!functionCompatibleCheck(pQueryInfo)) {
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1253 1254
  }

1255 1256
  if (isSTable) {
    pQueryInfo->type |= TSDB_QUERY_TYPE_STABLE_QUERY;
H
hjxilinx 已提交
1257
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
1258 1259
    int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
    
H
hjxilinx 已提交
1260
    if (tscQueryTags(pQueryInfo)) {                      // local handle the metric tag query
H
hjxilinx 已提交
1261
      pCmd->count = numOfCols;  // the number of meter schema, tricky.
1262
      pQueryInfo->command = TSDB_SQL_RETRIEVE_TAGS;
H
hzcheng 已提交
1263 1264 1265 1266 1267 1268
    }

    /*
     * transfer sql functions that need secondary merge into another format
     * in dealing with metric queries such as: count/first/last
     */
1269
    tscTansformSQLFunctionForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1270

1271
    if (hasUnsupportFunctionsForSTableQuery(pQueryInfo)) {
H
hzcheng 已提交
1272 1273 1274 1275 1276 1277 1278
      return TSDB_CODE_INVALID_SQL;
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1279 1280
int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
    int8_t type, char* fieldName, SSqlExpr* pSqlExpr) {
S
slguan 已提交
1281
  for (int32_t i = 0; i < pIdList->num; ++i) {
1282
    tscColumnBaseInfoInsert(pQueryInfo, &(pIdList->ids[i]));
H
hzcheng 已提交
1283 1284
  }

1285
  tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, outputIndex, type, fieldName, bytes);
H
hjxilinx 已提交
1286 1287
  tscFieldInfoSetExpr(&pQueryInfo->fieldsInfo, outputIndex, pSqlExpr);
  
H
hzcheng 已提交
1288 1289 1290
  return TSDB_CODE_SUCCESS;
}

1291
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIdx, int32_t tableIndex) {
H
hjxilinx 已提交
1292
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1293 1294 1295 1296
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIdx);
H
hzcheng 已提交
1297

S
slguan 已提交
1298
  int16_t functionId = (int16_t)((colIdx >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
H
hzcheng 已提交
1299

S
slguan 已提交
1300
  if (functionId == TSDB_FUNC_TAGPRJ) {
H
hjxilinx 已提交
1301
//    addRequiredTagColumn(pQueryInfo, colIdx - numOfCols, tableIndex);
1302
    pQueryInfo->type = TSDB_QUERY_TYPE_STABLE_QUERY;
S
slguan 已提交
1303
  } else {
1304
    pQueryInfo->type = TSDB_QUERY_TYPE_PROJECTION_QUERY;
H
hzcheng 已提交
1305 1306
  }

S
slguan 已提交
1307 1308
  SColumnIndex index = {tableIndex, colIdx};
  SSqlExpr*    pExpr =
1309
      tscSqlExprInsert(pQueryInfo, outputIndex, functionId, &index, pSchema->type, pSchema->bytes, pSchema->bytes);
S
slguan 已提交
1310 1311

  return pExpr;
H
hzcheng 已提交
1312 1313
}

1314
void addRequiredTagColumn(SQueryInfo* pQueryInfo, int32_t tagColIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1315
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
S
slguan 已提交
1316

H
hjxilinx 已提交
1317 1318
  if (pTableMetaInfo->numOfTags == 0 || pTableMetaInfo->tagColumnIndex[pTableMetaInfo->numOfTags - 1] < tagColIndex) {
    pTableMetaInfo->tagColumnIndex[pTableMetaInfo->numOfTags++] = tagColIndex;
H
hzcheng 已提交
1319
  } else {  // find the appropriate position
H
hjxilinx 已提交
1320 1321
    for (int32_t i = 0; i < pTableMetaInfo->numOfTags; ++i) {
      if (tagColIndex > pTableMetaInfo->tagColumnIndex[i]) {
H
hzcheng 已提交
1322
        continue;
H
hjxilinx 已提交
1323
      } else if (tagColIndex == pTableMetaInfo->tagColumnIndex[i]) {
H
hzcheng 已提交
1324 1325
        break;
      } else {
H
hjxilinx 已提交
1326 1327
        memmove(&pTableMetaInfo->tagColumnIndex[i + 1], &pTableMetaInfo->tagColumnIndex[i],
                sizeof(pTableMetaInfo->tagColumnIndex[0]) * (pTableMetaInfo->numOfTags - i));
H
hzcheng 已提交
1328

H
hjxilinx 已提交
1329
        pTableMetaInfo->tagColumnIndex[i] = tagColIndex;
S
slguan 已提交
1330

H
hjxilinx 已提交
1331
        pTableMetaInfo->numOfTags++;
H
hzcheng 已提交
1332 1333 1334 1335 1336 1337
        break;
      }
    }
  }

  // plus one means tbname
H
hjxilinx 已提交
1338
  assert(tagColIndex >= -1 && tagColIndex < TSDB_MAX_TAGS && pTableMetaInfo->numOfTags <= TSDB_MAX_TAGS + 1);
H
hzcheng 已提交
1339 1340
}

1341 1342
static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSQLExprItem* pItem) {
  SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos, pIndex->columnIndex, pIndex->tableIndex);
H
hzcheng 已提交
1343

H
hjxilinx 已提交
1344
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
H
hjxilinx 已提交
1345 1346 1347
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
1348

S
slguan 已提交
1349
  char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName;
H
hjxilinx 已提交
1350 1351
  strncpy(pExpr->aliasName, colName, tListLen(pExpr->aliasName));
  
S
slguan 已提交
1352 1353 1354
  SColumnList ids = {0};
  ids.num = 1;
  ids.ids[0] = *pIndex;
H
hzcheng 已提交
1355

H
hjxilinx 已提交
1356
  if (pIndex->columnIndex >= tscGetNumOfColumns(pTableMeta) || pIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1357 1358
    ids.num = 0;
  }
H
hzcheng 已提交
1359

H
hjxilinx 已提交
1360
  insertResultField(pQueryInfo, startPos, &ids, pExpr->resBytes, pExpr->resType, pExpr->aliasName, pExpr);
S
slguan 已提交
1361
}
H
hzcheng 已提交
1362

1363
void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1364
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
1365 1366
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
                                     pColSchema->bytes, pColSchema->bytes);
H
hzcheng 已提交
1367

S
slguan 已提交
1368 1369 1370 1371
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1372

H
hjxilinx 已提交
1373
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1374 1375 1376

  pExpr->colInfo.flag = flag;
  if (TSDB_COL_IS_TAG(flag)) {
1377
    addRequiredTagColumn(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex);
S
slguan 已提交
1378 1379 1380
  }
}

1381
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1382
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1383 1384

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1385 1386
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1387

H
hjxilinx 已提交
1388
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1389
  
H
hjxilinx 已提交
1390
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1391
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1392
  } else {
H
hjxilinx 已提交
1393
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1394 1395 1396
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
hjxilinx 已提交
1397
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex);
H
hjxilinx 已提交
1398
    strncpy(pExpr->aliasName, pSchema[j].name, tListLen(pExpr->aliasName));
S
slguan 已提交
1399 1400 1401 1402 1403

    pIndex->columnIndex = j;
    SColumnList ids = {0};
    ids.ids[0] = *pIndex;

H
hjxilinx 已提交
1404
    ids.num = 1;
S
slguan 已提交
1405

H
hjxilinx 已提交
1406
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1407 1408 1409 1410 1411
  }

  return numOfTotalColumns;
}

1412
int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pItem) {
S
slguan 已提交
1413 1414 1415
  const char* msg0 = "invalid column name";
  const char* msg1 = "tag for table query is not allowed";

H
hjxilinx 已提交
1416
  int32_t startPos = pQueryInfo->exprsInfo.numOfExprs;
S
slguan 已提交
1417 1418 1419

  if (pItem->pNode->nSQLOptr == TK_ALL) {  // project on all fields
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1420
    if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1421
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
1422 1423 1424 1425
    }

    // all meters columns are required
    if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) {  // all table columns are required.
1426
      for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
S
slguan 已提交
1427
        index.tableIndex = i;
1428
        int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1429
        startPos += inc;
H
hzcheng 已提交
1430 1431
      }
    } else {
1432
      doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1433 1434 1435 1436
    }
  } else if (pItem->pNode->nSQLOptr == TK_ID) {  // simple column projection query
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;

1437
    if (getColumnIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1438
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
1439
    }
H
hzcheng 已提交
1440

S
slguan 已提交
1441
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1442
      SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = TSDB_TABLE_NAME_LEN};
S
slguan 已提交
1443
      strcpy(colSchema.name, TSQL_TBNAME_L);
1444

1445 1446
      pQueryInfo->type = TSDB_QUERY_TYPE_STABLE_QUERY;
      tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, true);
S
slguan 已提交
1447
    } else {
H
hjxilinx 已提交
1448
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1449
      STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
1450

H
hjxilinx 已提交
1451
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
1452
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1453 1454
      }

1455
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
hzcheng 已提交
1456 1457 1458 1459 1460 1461 1462 1463
    }
  } else {
    return TSDB_CODE_INVALID_SQL;
  }

  return TSDB_CODE_SUCCESS;
}

S
slguan 已提交
1464
static int32_t setExprInfoForFunctions(SQueryInfo* pQueryInfo, SSchema* pSchema, int32_t functionID, char* aliasName,
S
slguan 已提交
1465
                                       int32_t resColIdx, SColumnIndex* pColIndex) {
H
hzcheng 已提交
1466 1467 1468
  int16_t type = 0;
  int16_t bytes = 0;

S
slguan 已提交
1469
  char        columnName[TSDB_COL_NAME_LEN] = {0};
1470
  const char* msg1 = "not support column types";
H
hzcheng 已提交
1471 1472

  if (functionID == TSDB_FUNC_SPREAD) {
S
slguan 已提交
1473 1474 1475
    if (pSchema[pColIndex->columnIndex].type == TSDB_DATA_TYPE_BINARY ||
        pSchema[pColIndex->columnIndex].type == TSDB_DATA_TYPE_NCHAR ||
        pSchema[pColIndex->columnIndex].type == TSDB_DATA_TYPE_BOOL) {
1476
      invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1477 1478 1479 1480 1481 1482
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
S
slguan 已提交
1483 1484
    type = pSchema[pColIndex->columnIndex].type;
    bytes = pSchema[pColIndex->columnIndex].bytes;
H
hzcheng 已提交
1485 1486 1487 1488 1489
  }

  if (aliasName != NULL) {
    strcpy(columnName, aliasName);
  } else {
S
slguan 已提交
1490
    getRevisedName(columnName, functionID, TSDB_COL_NAME_LEN, pSchema[pColIndex->columnIndex].name);
H
hzcheng 已提交
1491
  }
H
hjxilinx 已提交
1492 1493
  
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, resColIdx, functionID, pColIndex, type, bytes, bytes);
H
hjxilinx 已提交
1494 1495
  strncpy(pExpr->aliasName, columnName, tListLen(pExpr->aliasName));
  
1496
  // for all querie, the timestamp column meeds to be loaded
S
slguan 已提交
1497
  SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1498
  tscColumnBaseInfoInsert(pQueryInfo, &index);
H
hzcheng 已提交
1499

S
slguan 已提交
1500
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
H
hjxilinx 已提交
1501
  insertResultField(pQueryInfo, resColIdx, &ids, bytes, type, columnName, pExpr);
H
hzcheng 已提交
1502 1503 1504 1505

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1506
int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem, bool finalResult) {
H
hjxilinx 已提交
1507
  STableMetaInfo* pTableMetaInfo = NULL;
S
slguan 已提交
1508 1509
  int32_t         optr = pItem->pNode->nSQLOptr;

1510
  const char* msg1 = "not support column types";
S
slguan 已提交
1511
  const char* msg2 = "invalid parameters";
1512
  const char* msg3 = "illegal column name";
S
slguan 已提交
1513
  const char* msg4 = "invalid table name";
1514
  const char* msg5 = "parameter is out of range [0, 100]";
S
slguan 已提交
1515
  const char* msg6 = "function applied to tags not allowed";
H
hzcheng 已提交
1516 1517 1518 1519 1520

  switch (optr) {
    case TK_COUNT: {
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
        /* more than one parameter for count() function */
1521
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1522 1523 1524 1525
      }

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
1526
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1527 1528
      }

H
hjxilinx 已提交
1529
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1530
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1531 1532 1533 1534

      if (pItem->pNode->pParam != NULL) {
        SSQLToken* pToken = &pItem->pNode->pParam->a[0].pNode->colInfo;
        if (pToken->z == NULL || pToken->n == 0) {
1535
          return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1536 1537
        }

S
slguan 已提交
1538 1539 1540 1541 1542 1543
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
        if (pParamElem->pNode->nSQLOptr == TK_ALL) {
          // select table.*
          // check if the table name is valid or not
          SSQLToken tmpToken = pParamElem->pNode->colInfo;

1544 1545
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
1546 1547 1548 1549
          }

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
hjxilinx 已提交
1550
          pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
H
hzcheng 已提交
1551
        } else {
S
slguan 已提交
1552
          // count the number of meters created according to the metric
1553
          if (getColumnIndexByName(pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1554
            return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
1555 1556
          }

H
hjxilinx 已提交
1557
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1558 1559

          // count tag is equalled to count(tbname)
H
hjxilinx 已提交
1560
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
S
slguan 已提交
1561
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
hzcheng 已提交
1562 1563
          }

S
slguan 已提交
1564
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
hjxilinx 已提交
1565
          pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
H
hzcheng 已提交
1566
        }
S
slguan 已提交
1567 1568 1569 1570
      } else {  // count(*) is equalled to count(primary_timestamp_key)
        index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};

        int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
hjxilinx 已提交
1571
        pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
H
hzcheng 已提交
1572
      }
H
hjxilinx 已提交
1573 1574 1575 1576
      
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
      getColumnName(pItem, pExpr->aliasName, TSDB_COL_NAME_LEN);
      
S
slguan 已提交
1577
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1578 1579 1580 1581 1582 1583 1584 1585
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
        insertResultField(pQueryInfo, numOfOutput, &ids, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->aliasName, pExpr);
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
          tscColumnBaseInfoInsert(pQueryInfo, &(ids.ids[i]));
        }
      }
1586 1587 1588 1589
  
      SColumnIndex tsCol = {.tableIndex = index.tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
      tscColumnBaseInfoInsert(pQueryInfo, &tsCol);
  
S
slguan 已提交
1590
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1591 1592 1593
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1594 1595 1596 1597 1598 1599
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1600
    case TK_TWA:
H
hzcheng 已提交
1601 1602 1603 1604 1605 1606 1607 1608 1609
    case TK_MIN:
    case TK_MAX:
    case TK_DIFF:
    case TK_STDDEV:
    case TK_LEASTSQUARES: {
      // 1. valid the number of parameters
      if (pItem->pNode->pParam == NULL || (optr != TK_LEASTSQUARES && pItem->pNode->pParam->nExpr != 1) ||
          (optr == TK_LEASTSQUARES && pItem->pNode->pParam->nExpr != 3)) {
        /* no parameters or more than one parameter for function */
1610
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1611 1612 1613 1614
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ALL && pParamElem->pNode->nSQLOptr != TK_ID) {
1615
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1616 1617
      }

S
slguan 已提交
1618
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1619
      if ((getColumnIndexByName(&pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) ||
1620
          index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
1621
        return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1622 1623 1624
      }

      // 2. check if sql function can be applied on this column data type
H
hjxilinx 已提交
1625
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1626
      SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
S
slguan 已提交
1627 1628
      int16_t  colType = pSchema->type;

H
hjxilinx 已提交
1629
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1630
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1631 1632 1633 1634
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
S
slguan 已提交
1635
      int16_t intermediateResSize = 0;
H
hzcheng 已提交
1636 1637 1638

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
1639
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1640 1641
      }

S
slguan 已提交
1642 1643 1644 1645
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
        return TSDB_CODE_INVALID_SQL;
      }
H
hzcheng 已提交
1646

S
slguan 已提交
1647
      // set the first column ts for diff query
H
hzcheng 已提交
1648 1649
      if (optr == TK_DIFF) {
        colIdx += 1;
S
slguan 已提交
1650
        SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
H
hjxilinx 已提交
1651
        SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
1652
                         TSDB_KEYSIZE);
H
hzcheng 已提交
1653

S
slguan 已提交
1654
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1655
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1656 1657
      }

S
slguan 已提交
1658
      // functions can not be applied to tags
H
hjxilinx 已提交
1659
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1660
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
S
slguan 已提交
1661 1662
      }

1663
      SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, resultType, resultSize, resultSize);
H
hzcheng 已提交
1664 1665 1666 1667 1668 1669 1670 1671

      if (optr == TK_LEASTSQUARES) {
        /* set the leastsquares parameters */
        char val[8] = {0};
        if (tVariantDump(&pParamElem[1].pNode->val, val, TSDB_DATA_TYPE_DOUBLE) < 0) {
          return TSDB_CODE_INVALID_SQL;
        }

S
slguan 已提交
1672
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1673 1674 1675 1676 1677 1678

        memset(val, 0, tListLen(val));
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE) < 0) {
          return TSDB_CODE_INVALID_SQL;
        }

S
slguan 已提交
1679
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1680 1681
      }

S
slguan 已提交
1682 1683 1684
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
      getColumnName(pItem, pExpr->aliasName, TSDB_COL_NAME_LEN);
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, pExpr->resType, pExpr->aliasName, pExpr);
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
          tscColumnBaseInfoInsert(pQueryInfo, &(ids.ids[i]));
        }
      }
1697 1698 1699 1700
  
      SColumnIndex tsCol = {.tableIndex = index.tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
      tscColumnBaseInfoInsert(pQueryInfo, &tsCol);
      
S
slguan 已提交
1701
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
    }
    case TK_FIRST:
    case TK_LAST:
    case TK_SPREAD:
    case TK_LAST_ROW:
    case TK_INTERP: {
      bool requireAllFields = (pItem->pNode->pParam == NULL);

      int16_t functionID = 0;
      changeFunctionID(optr, &functionID);

      if (!requireAllFields) {
        if (pItem->pNode->pParam->nExpr < 1) {
1715
          return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1716 1717 1718 1719 1720 1721
        }

        /* in first/last function, multiple columns can be add to resultset */
        for (int32_t i = 0; i < pItem->pNode->pParam->nExpr; ++i) {
          tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[i]);
          if (pParamElem->pNode->nSQLOptr != TK_ALL && pParamElem->pNode->nSQLOptr != TK_ID) {
1722
            return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1723 1724
          }

S
slguan 已提交
1725 1726 1727 1728 1729 1730
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

          if (pParamElem->pNode->nSQLOptr == TK_ALL) {
            // select table.*
            SSQLToken tmpToken = pParamElem->pNode->colInfo;

1731 1732
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
1733 1734
            }

H
hjxilinx 已提交
1735
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1736
            SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1737

H
hjxilinx 已提交
1738
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
1739
              index.columnIndex = j;
1740
              if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIdx++, &index) != 0) {
S
slguan 已提交
1741 1742 1743
                return TSDB_CODE_INVALID_SQL;
              }
            }
H
hzcheng 已提交
1744

S
slguan 已提交
1745
          } else {
1746
            if (getColumnIndexByName(&pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1747
              return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
1748 1749
            }

H
hjxilinx 已提交
1750
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1751
            SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1752 1753

            // functions can not be applied to tags
H
hjxilinx 已提交
1754
            if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
1755
              return invalidSqlErrMsg(pQueryInfo->msg, msg6);
S
slguan 已提交
1756 1757
            }

1758
            if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIdx + i, &index) != 0) {
S
slguan 已提交
1759 1760
              return TSDB_CODE_INVALID_SQL;
            }
H
hzcheng 已提交
1761 1762
          }
        }
1763
        
S
slguan 已提交
1764 1765 1766 1767
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

1768
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
1769
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
1770
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1771

H
hjxilinx 已提交
1772
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
1773
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
1774 1775
            if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIdx + i + j, &index) !=
                0) {
S
slguan 已提交
1776 1777
              return TSDB_CODE_INVALID_SQL;
            }
H
hzcheng 已提交
1778
          }
S
slguan 已提交
1779

H
hjxilinx 已提交
1780
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1781 1782
        }

1783
        
S
slguan 已提交
1784
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1785 1786 1787 1788 1789 1790 1791 1792 1793
      }
    }
    case TK_TOP:
    case TK_BOTTOM:
    case TK_PERCENTILE:
    case TK_APERCENTILE: {
      // 1. valid the number of parameters
      if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 2) {
        /* no parameters or more than one parameter for function */
1794
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1795 1796 1797 1798
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
1799
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1800
      }
H
hjxilinx 已提交
1801
      
S
slguan 已提交
1802
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1803
      if (getColumnIndexByName(&pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1804
        return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
1805 1806
      }

H
hjxilinx 已提交
1807
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1808
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1809 1810

      // functions can not be applied to tags
H
hjxilinx 已提交
1811
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1812
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
H
hzcheng 已提交
1813 1814 1815
      }

      // 2. valid the column type
S
slguan 已提交
1816
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
1817
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1818
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1819 1820 1821 1822
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
1823
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1824 1825 1826 1827
      }

      tVariant* pVariant = &pParamElem[1].pNode->val;

S
slguan 已提交
1828 1829
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1830

H
hjxilinx 已提交
1831
      char    val[8] = {0};
H
hjxilinx 已提交
1832 1833
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
1834 1835 1836
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE);

L
lihui 已提交
1837
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
1838
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
1839
          return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851
        }

        resultSize = sizeof(double);
        resultType = TSDB_DATA_TYPE_DOUBLE;

        /*
         * sql function transformation
         * for dp = 0, it is actually min,
         * for dp = 100, it is max,
         */
        int16_t functionId = 0;
        if (changeFunctionID(optr, &functionId) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
1852
          return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1853 1854
        }

H
hjxilinx 已提交
1855
        pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize);
S
slguan 已提交
1856
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1857 1858 1859 1860 1861
      } else {
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT);

        int64_t nTop = *((int32_t*)val);
        if (nTop <= 0 || nTop > 100) {  // todo use macro
1862
          return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
1863 1864 1865 1866
        }

        int16_t functionId = 0;
        if (changeFunctionID(optr, &functionId) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
1867
          return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1868
        }
S
slguan 已提交
1869

H
hzcheng 已提交
1870
        // set the first column ts for top/bottom query
S
slguan 已提交
1871
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
H
hjxilinx 已提交
1872
        pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE);
S
slguan 已提交
1873 1874 1875

        const int32_t TS_COLUMN_INDEX = 0;
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
1876
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
1877
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
1878 1879 1880

        colIdx += 1;  // the first column is ts

H
hjxilinx 已提交
1881
        pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize);
S
slguan 已提交
1882
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
1883
      }
H
hjxilinx 已提交
1884 1885 1886 1887
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
      getColumnName(pItem, pExpr->aliasName, TSDB_COL_NAME_LEN);
  
S
slguan 已提交
1888
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
1889 1890 1891 1892 1893 1894 1895
      if (finalResult) {
        insertResultField(pQueryInfo, colIdx, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
          tscColumnBaseInfoInsert(pQueryInfo, &(ids.ids[i]));
        }
      }
S
slguan 已提交
1896 1897

      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1898 1899
    }
    default:
S
slguan 已提交
1900
      return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1901
  }
1902 1903
  
  
H
hzcheng 已提交
1904 1905
}

S
slguan 已提交
1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
  assert(num == 1 && columnIndex >= -1 && tableIndex >= 0);

  SColumnList columnList = {0};
  columnList.num = num;

  int32_t index = num - 1;
  columnList.ids[index].tableIndex = tableIndex;
  columnList.ids[index].columnIndex = columnIndex;

  return columnList;
}

H
hzcheng 已提交
1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
    int32_t len = (pItem->pNode->operand.n < nameLength) ? pItem->pNode->operand.n : nameLength;
    strncpy(resultFieldName, pItem->pNode->operand.z, len);
  }
}

void getRevisedName(char* resultFieldName, int32_t functionId, int32_t maxLen, char* columnName) {
  snprintf(resultFieldName, maxLen, "%s(%s)", aAggs[functionId].aName, columnName);
}

S
slguan 已提交
1933 1934 1935 1936 1937 1938 1939 1940 1941
static bool isTablenameToken(SSQLToken* token) {
  SSQLToken tmpToken = *token;
  SSQLToken tableToken = {0};

  extractTableNameFromToken(&tmpToken, &tableToken);

  return (strncasecmp(TSQL_TBNAME_L, tmpToken.z, tmpToken.n) == 0 && tmpToken.n == strlen(TSQL_TBNAME_L));
}

1942
static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SSQLToken* pToken) {
H
hjxilinx 已提交
1943
  STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index)->pTableMeta;
S
slguan 已提交
1944

H
hjxilinx 已提交
1945 1946
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962

  int16_t columnIndex = COLUMN_INDEX_INITIAL_VAL;

  for (int16_t i = 0; i < numOfCols; ++i) {
    if (pToken->n != strlen(pSchema[i].name)) {
      continue;
    }

    if (strncasecmp(pSchema[i].name, pToken->z, pToken->n) == 0) {
      columnIndex = i;
    }
  }

  return columnIndex;
}

1963
int32_t doGetColumnIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
1964 1965 1966 1967 1968 1969 1970 1971 1972 1973
  const char* msg0 = "ambiguous column name";
  const char* msg1 = "invalid column name";

  if (isTablenameToken(pToken)) {
    pIndex->columnIndex = TSDB_TBNAME_COLUMN_INDEX;
  } else if (strncasecmp(pToken->z, DEFAULT_PRIMARY_TIMESTAMP_COL_NAME, pToken->n) == 0) {
    pIndex->columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX;
  } else {
    // not specify the table name, try to locate the table index by column name
    if (pIndex->tableIndex == COLUMN_INDEX_INITIAL_VAL) {
1974 1975
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
1976 1977 1978

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
1979
            return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
1980 1981 1982 1983 1984 1985 1986
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
1987
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
1988 1989 1990 1991 1992 1993
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
1994
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
    return TSDB_CODE_INVALID_SQL;
  }
}

2005
int32_t getMeterIndex(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2006
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2007
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2008 2009 2010 2011 2012 2013 2014
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
S
slguan 已提交
2015
  char tableName[TSDB_TABLE_ID_LEN + 1] = {0};
S
slguan 已提交
2016

2017
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2018
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
hjxilinx 已提交
2019
    extractTableName(pTableMetaInfo->name, tableName);
S
slguan 已提交
2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033

    if (strncasecmp(tableName, pTableToken->z, pTableToken->n) == 0 && strlen(tableName) == pTableToken->n) {
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
    return TSDB_CODE_INVALID_SQL;
  }

  return TSDB_CODE_SUCCESS;
}

2034
int32_t getTableIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2035 2036 2037
  SSQLToken tableToken = {0};
  extractTableNameFromToken(pToken, &tableToken);

2038
  if (getMeterIndex(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2039
    return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
2040 2041
  }

S
slguan 已提交
2042 2043
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2044

2045
int32_t getColumnIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2046
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
S
slguan 已提交
2047
    return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
2048 2049
  }

S
slguan 已提交
2050 2051
  SSQLToken tmpToken = *pToken;

2052
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2053
    return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
2054 2055
  }

2056
  return doGetColumnIndexByName(&tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069
}

int32_t changeFunctionID(int32_t optr, int16_t* functionId) {
  switch (optr) {
    case TK_COUNT:
      *functionId = TSDB_FUNC_COUNT;
      break;
    case TK_SUM:
      *functionId = TSDB_FUNC_SUM;
      break;
    case TK_AVG:
      *functionId = TSDB_FUNC_AVG;
      break;
L
lihui 已提交
2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087
    case TK_RATE:
      *functionId = TSDB_FUNC_RATE;
      break;
    case TK_IRATE:
      *functionId = TSDB_FUNC_IRATE;
      break;
    case TK_SUM_RATE:
      *functionId = TSDB_FUNC_SUM_RATE;
      break;
    case TK_SUM_IRATE:
      *functionId = TSDB_FUNC_SUM_IRATE;
      break;
    case TK_AVG_RATE:
      *functionId = TSDB_FUNC_AVG_RATE;
      break;
    case TK_AVG_IRATE:
      *functionId = TSDB_FUNC_AVG_IRATE;
      break;
H
hzcheng 已提交
2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123
    case TK_MIN:
      *functionId = TSDB_FUNC_MIN;
      break;
    case TK_MAX:
      *functionId = TSDB_FUNC_MAX;
      break;
    case TK_STDDEV:
      *functionId = TSDB_FUNC_STDDEV;
      break;
    case TK_PERCENTILE:
      *functionId = TSDB_FUNC_PERCT;
      break;
    case TK_APERCENTILE:
      *functionId = TSDB_FUNC_APERCT;
      break;
    case TK_FIRST:
      *functionId = TSDB_FUNC_FIRST;
      break;
    case TK_LAST:
      *functionId = TSDB_FUNC_LAST;
      break;
    case TK_LEASTSQUARES:
      *functionId = TSDB_FUNC_LEASTSQR;
      break;
    case TK_TOP:
      *functionId = TSDB_FUNC_TOP;
      break;
    case TK_BOTTOM:
      *functionId = TSDB_FUNC_BOTTOM;
      break;
    case TK_DIFF:
      *functionId = TSDB_FUNC_DIFF;
      break;
    case TK_SPREAD:
      *functionId = TSDB_FUNC_SPREAD;
      break;
S
slguan 已提交
2124 2125
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140
      break;
    case TK_INTERP:
      *functionId = TSDB_FUNC_INTERP;
      break;
    case TK_LAST_ROW:
      *functionId = TSDB_FUNC_LAST_ROW;
      break;
    default:
      return -1;
  }

  return TSDB_CODE_SUCCESS;
}

int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
S
slguan 已提交
2141
  SSqlCmd*        pCmd = &pSql->cmd;
2142
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2143
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2144

H
hzcheng 已提交
2145 2146
  pCmd->command = TSDB_SQL_SHOW;

2147
  const char* msg1 = "invalid name";
2148
  const char* msg2 = "pattern filter string too long";
2149 2150 2151 2152
  const char* msg3 = "database name too long";
  const char* msg4 = "invalid ip address";
  const char* msg5 = "database name is empty";
  const char* msg6 = "pattern string is empty";
H
hzcheng 已提交
2153 2154 2155 2156 2157

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2158 2159 2160
  SShowInfo* pShowInfo = &pInfo->pDCLInfo->showOpt;
  int16_t    showType = pShowInfo->showType;
  if (showType == TSDB_MGMT_TABLE_TABLE || showType == TSDB_MGMT_TABLE_METRIC || showType == TSDB_MGMT_TABLE_VGROUP) {
H
hzcheng 已提交
2161
    // db prefix in tagCond, show table conds in payload
2162 2163 2164
    SSQLToken* pDbPrefixToken = &pShowInfo->prefix;
    if (pDbPrefixToken->type != 0) {
      assert(pDbPrefixToken->n >= 0);
H
hzcheng 已提交
2165 2166

      if (pDbPrefixToken->n > TSDB_DB_NAME_LEN) {  // db name is too long
2167
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
2168 2169
      }

2170
      if (pDbPrefixToken->n <= 0) {
2171
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2172 2173
      }

2174
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2175
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2176 2177
      }

H
hjxilinx 已提交
2178
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2179
      if (ret != TSDB_CODE_SUCCESS) {
2180
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2181
      }
2182
    }
H
hzcheng 已提交
2183

2184 2185 2186 2187
    // show table/stable like 'xxxx', set the like pattern for show tables
    SSQLToken* pPattern = &pShowInfo->pattern;
    if (pPattern->type != 0) {
      pPattern->n = strdequote(pPattern->z);
S
slguan 已提交
2188

2189
      if (pPattern->n <= 0) {
2190
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2191
      }
H
hzcheng 已提交
2192

S
slguan 已提交
2193
      if (pCmd->payloadLen > TSDB_TABLE_NAME_LEN) {
2194
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2195 2196
      }
    }
2197 2198
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2199
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2200 2201
    }

L
lihui 已提交
2202
    // show vnodes may be ip addr of dnode in payload
2203 2204
    SSQLToken* pDnodeIp = &pShowInfo->prefix;
    if (pDnodeIp->n > TSDB_IPv4ADDR_LEN) {  // ip addr is too long
2205
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2206
    }
L
lihui 已提交
2207

2208
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2209
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2210
    }
H
hzcheng 已提交
2211 2212 2213 2214 2215 2216
  }

  return TSDB_CODE_SUCCESS;
}

int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
2217 2218
  const char* msg1 = "invalid ip address";
  const char* msg2 = "invalid port";
H
hzcheng 已提交
2219

2220 2221
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
H
hzcheng 已提交
2222

2223 2224
  SSQLToken* ip = &(pInfo->pDCLInfo->ip);
  if (ip->n > TSDB_KILL_MSG_LEN) {
H
hzcheng 已提交
2225 2226 2227
    return TSDB_CODE_INVALID_SQL;
  }

2228
  strncpy(pCmd->payload, ip->z, ip->n);
H
hzcheng 已提交
2229 2230 2231

  const char delim = ':';

2232 2233 2234 2235
  char* ipStr = strtok(ip->z, &delim);
  char* portStr = strtok(NULL, &delim);

  if (!validateIpAddress(ipStr, strlen(ipStr))) {
H
hzcheng 已提交
2236 2237
    memset(pCmd->payload, 0, tListLen(pCmd->payload));

2238
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2239 2240
  }

L
lihui 已提交
2241
  uint16_t port = (uint16_t)strtol(portStr, NULL, 10);
H
hzcheng 已提交
2242 2243
  if (port <= 0 || port > 65535) {
    memset(pCmd->payload, 0, tListLen(pCmd->payload));
2244
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2245 2246 2247 2248 2249
  }

  return TSDB_CODE_SUCCESS;
}

2250 2251 2252 2253 2254 2255 2256 2257 2258
bool validateIpAddress(const char* ip, size_t size) {
  char tmp[128] = {0};  // buffer to build null-terminated string
  assert(size < 128);

  strncpy(tmp, ip, size);

  in_addr_t ipAddr = inet_addr(tmp);

  return ipAddr != INADDR_NONE;
H
hzcheng 已提交
2259 2260
}

2261
int32_t tscTansformSQLFunctionForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2262
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2263

H
hjxilinx 已提交
2264
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
S
slguan 已提交
2265
    return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
2266 2267
  }

H
hjxilinx 已提交
2268
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2269 2270 2271

  int16_t bytes = 0;
  int16_t type = 0;
S
slguan 已提交
2272
  int16_t intermediateBytes = 0;
H
hzcheng 已提交
2273

H
hjxilinx 已提交
2274
  for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) {
2275
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2276 2277
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

H
hjxilinx 已提交
2278
    int32_t colIndex = pExpr->colInfo.colIdx;
H
hjxilinx 已提交
2279
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2280
    
S
slguan 已提交
2281
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2282 2283
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
H
hjxilinx 已提交
2284
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, pExpr->param[0].i64Key, &type, &bytes,
S
slguan 已提交
2285 2286 2287
                            &intermediateBytes, 0, true) != TSDB_CODE_SUCCESS) {
        return TSDB_CODE_INVALID_SQL;
      }
H
hzcheng 已提交
2288

2289
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIdx, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2290 2291
      // todo refactor
      pExpr->interResBytes = intermediateBytes;
H
hzcheng 已提交
2292 2293 2294
    }
  }

2295
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2296
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2297 2298 2299
}

/* transfer the field-info back to original input format */
2300
void tscRestoreSQLFunctionForMetricQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2301
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
2302
  if (!UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2303 2304 2305
    return;
  }

H
hjxilinx 已提交
2306
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
2307
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
2308
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIdx);
H
hjxilinx 已提交
2309
    
H
hjxilinx 已提交
2310 2311 2312
//    if (/*(pExpr->functionId >= TSDB_FUNC_FIRST_DST && pExpr->functionId <= TSDB_FUNC_LAST_DST) ||
//        (pExpr->functionId >= TSDB_FUNC_SUM && pExpr->functionId <= TSDB_FUNC_MAX) ||
//        pExpr->functionId == TSDB_FUNC_LAST_ROW*/) {
H
hjxilinx 已提交
2313 2314 2315
      // the final result size and type in the same as query on single table.
      // so here, set the flag to be false;
      int16_t inter = 0;
H
hjxilinx 已提交
2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328
      
      int32_t functionId = pExpr->functionId;
      if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) {
        continue;
      }
      
      if (functionId == TSDB_FUNC_FIRST_DST) {
        functionId = TSDB_FUNC_FIRST;
      } else if (functionId == TSDB_FUNC_LAST_DST) {
        functionId = TSDB_FUNC_LAST;
      }
      
      getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->resType, &pExpr->resBytes,
H
hjxilinx 已提交
2329
                        &inter, 0, false);
H
hjxilinx 已提交
2330
//    }
H
hzcheng 已提交
2331 2332 2333
  }
}

2334
bool hasUnsupportFunctionsForSTableQuery(SQueryInfo* pQueryInfo) {
S
slguan 已提交
2335
  const char* msg1 = "TWA not allowed to apply to super table directly";
H
hjxilinx 已提交
2336
  const char* msg2 = "TWA only support group by tbname for super table query";
2337
  const char* msg3 = "function not support for super table query";
H
hjxilinx 已提交
2338

S
slguan 已提交
2339
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2340
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
2341
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
2342
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_METRIC) == 0) {
2343
      invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
2344
      return true;
H
hzcheng 已提交
2345 2346 2347
    }
  }

2348 2349 2350
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
      invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
2351 2352
      return true;
    }
H
hzcheng 已提交
2353

2354 2355 2356
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1 ||
        pQueryInfo->groupbyExpr.columnInfo[0].colIdx != TSDB_TBNAME_COLUMN_INDEX) {
      invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
2357 2358 2359
      return true;
    }
  }
S
slguan 已提交
2360

H
hzcheng 已提交
2361 2362 2363
  return false;
}

2364
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
2365
  int32_t startIdx = 0;
2366
  int32_t functionID = tscSqlExprGet(pQueryInfo, startIdx)->functionId;
S
slguan 已提交
2367 2368

  // ts function can be simultaneously used with any other functions.
H
hzcheng 已提交
2369
  if (functionID == TSDB_FUNC_TS || functionID == TSDB_FUNC_TS_DUMMY) {
S
slguan 已提交
2370
    startIdx++;
H
hzcheng 已提交
2371 2372
  }

2373
  int32_t factor = funcCompatDefList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2374 2375 2376

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2377
  for (int32_t i = startIdx + 1; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
2378
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
2379 2380 2381 2382 2383 2384 2385

    int16_t functionId = pExpr->functionId;
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

    if (functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
2386 2387 2388 2389
      continue;
    }

    if (funcCompatDefList[functionId] != factor) {
H
hzcheng 已提交
2390 2391 2392 2393 2394 2395 2396
      return false;
    }
  }

  return true;
}

2397
void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex) {
H
hjxilinx 已提交
2398
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
S
slguan 已提交
2399

H
hjxilinx 已提交
2400 2401 2402 2403
  /*
   * update tags column index for group by tags
   * group by columns belong to this table
   */
2404 2405 2406
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 && pQueryInfo->groupbyExpr.tableIndex == tableIndex) {
    for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
      int32_t index = pQueryInfo->groupbyExpr.columnInfo[i].colIdx;
H
hjxilinx 已提交
2407

H
hjxilinx 已提交
2408 2409
      for (int32_t j = 0; j < pTableMetaInfo->numOfTags; ++j) {
        int32_t tagColIndex = pTableMetaInfo->tagColumnIndex[j];
H
hjxilinx 已提交
2410
        if (tagColIndex == index) {
2411
          pQueryInfo->groupbyExpr.columnInfo[i].colIdx = j;
H
hjxilinx 已提交
2412 2413
          break;
        }
H
hzcheng 已提交
2414 2415 2416 2417 2418
      }
    }
  }

  // update tags column index for expression
2419 2420
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
2421

S
slguan 已提交
2422
    if (!TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {  // not tags, continue
H
hzcheng 已提交
2423 2424
      continue;
    }
H
hjxilinx 已提交
2425

H
hjxilinx 已提交
2426
    // not belongs to this table
H
hjxilinx 已提交
2427
    if (pExpr->uid != pTableMetaInfo->pTableMeta->uid) {
H
hjxilinx 已提交
2428 2429
      continue;
    }
H
hzcheng 已提交
2430

H
hjxilinx 已提交
2431 2432
    for (int32_t j = 0; j < pTableMetaInfo->numOfTags; ++j) {
      if (pExpr->colInfo.colIdx == pTableMetaInfo->tagColumnIndex[j]) {
H
hzcheng 已提交
2433 2434 2435 2436 2437
        pExpr->colInfo.colIdx = j;
        break;
      }
    }
  }
H
hjxilinx 已提交
2438

H
hjxilinx 已提交
2439
  // update join condition tag column index
2440
  SJoinInfo* pJoinInfo = &pQueryInfo->tagCond.joinInfo;
H
hjxilinx 已提交
2441 2442 2443
  if (!pJoinInfo->hasJoin) {  // not join query
    return;
  }
H
hjxilinx 已提交
2444

H
hjxilinx 已提交
2445
  assert(pJoinInfo->left.uid != pJoinInfo->right.uid);
H
hjxilinx 已提交
2446

H
hjxilinx 已提交
2447
  // the join condition expression node belongs to this table(super table)
H
hjxilinx 已提交
2448 2449 2450
  if (pTableMetaInfo->pTableMeta->uid == pJoinInfo->left.uid) {
    for (int32_t i = 0; i < pTableMetaInfo->numOfTags; ++i) {
      if (pJoinInfo->left.tagCol == pTableMetaInfo->tagColumnIndex[i]) {
H
hjxilinx 已提交
2451 2452 2453 2454
        pJoinInfo->left.tagCol = i;
      }
    }
  }
H
hjxilinx 已提交
2455

H
hjxilinx 已提交
2456 2457 2458
  if (pTableMetaInfo->pTableMeta->uid == pJoinInfo->right.uid) {
    for (int32_t i = 0; i < pTableMetaInfo->numOfTags; ++i) {
      if (pJoinInfo->right.tagCol == pTableMetaInfo->tagColumnIndex[i]) {
H
hjxilinx 已提交
2459 2460 2461 2462
        pJoinInfo->right.tagCol = i;
      }
    }
  }
H
hzcheng 已提交
2463 2464
}

2465
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2466 2467
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
H
hjxilinx 已提交
2468
  const char* msg3 = "group by columns must belong to one table";
S
slguan 已提交
2469 2470 2471
  const char* msg7 = "not support group by expression";
  const char* msg8 = "not allowed column type for group by";
  const char* msg9 = "tags not allowed for table query";
H
hzcheng 已提交
2472

S
slguan 已提交
2473
  // todo : handle two meter situation
H
hjxilinx 已提交
2474
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2475 2476 2477 2478 2479

  if (pList == NULL) {
    return TSDB_CODE_SUCCESS;
  }

2480
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2481
  if (pList->nExpr > TSDB_MAX_TAGS) {
2482
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
2483 2484
  }

H
hjxilinx 已提交
2485
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2486
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2487
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2488

S
slguan 已提交
2489
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
H
hzcheng 已提交
2490 2491 2492 2493 2494

  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tVariant* pVar = &pList->a[i].pVar;
    SSQLToken token = {pVar->nLen, pVar->nType, pVar->pz};

S
slguan 已提交
2495
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
2496

2497
    if (getColumnIndexByName(&token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
2498
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
2499
    }
H
hzcheng 已提交
2500

S
slguan 已提交
2501
    if (tableIndex != index.tableIndex && tableIndex >= 0) {
2502
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
2503 2504
    }

S
slguan 已提交
2505
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2506

H
hjxilinx 已提交
2507
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2508
    pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
2509

S
slguan 已提交
2510 2511 2512
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2513
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2514
    }
H
hzcheng 已提交
2515

S
slguan 已提交
2516
    bool groupTag = false;
H
hjxilinx 已提交
2517
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= tscGetNumOfColumns(pTableMeta)) {
S
slguan 已提交
2518
      groupTag = true;
H
hzcheng 已提交
2519 2520
    }

S
slguan 已提交
2521
    if (groupTag) {
H
hjxilinx 已提交
2522
      if (!UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
2523
        return invalidSqlErrMsg(pQueryInfo->msg, msg9);
S
slguan 已提交
2524 2525 2526 2527
      }

      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
H
hjxilinx 已提交
2528
        relIndex -= tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2529 2530
      }

2531
      pQueryInfo->groupbyExpr.columnInfo[i] =
S
slguan 已提交
2532
          (SColIndexEx){.colIdx = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId};  // relIndex;
2533
      addRequiredTagColumn(pQueryInfo, pQueryInfo->groupbyExpr.columnInfo[i].colIdx, index.tableIndex);
S
slguan 已提交
2534 2535
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
2536
      if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
2537
        return invalidSqlErrMsg(pQueryInfo->msg, msg8);
S
slguan 已提交
2538 2539
      }

2540 2541
      tscColumnBaseInfoInsert(pQueryInfo, &index);
      pQueryInfo->groupbyExpr.columnInfo[i] =
S
slguan 已提交
2542
          (SColIndexEx){.colIdx = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId};  // relIndex;
2543
      pQueryInfo->groupbyExpr.orderType = TSQL_SO_ASC;
S
slguan 已提交
2544 2545

      if (i == 0 && pList->nExpr > 1) {
2546
        return invalidSqlErrMsg(pQueryInfo->msg, msg7);
S
slguan 已提交
2547
      }
H
hzcheng 已提交
2548 2549 2550
    }
  }

2551
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
S
slguan 已提交
2552

H
hzcheng 已提交
2553 2554 2555
  return TSDB_CODE_SUCCESS;
}

2556 2557
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2558
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2559
  } else {
2560
    tscFieldInfoCalOffset(pQueryInfo);
H
hzcheng 已提交
2561 2562 2563
  }
}

S
slguan 已提交
2564 2565 2566 2567
static SColumnFilterInfo* addColumnFilterInfo(SColumnBase* pColumn) {
  if (pColumn == NULL) {
    return NULL;
  }
2568

S
slguan 已提交
2569
  int32_t size = pColumn->numOfFilters + 1;
L
lihui 已提交
2570
  char*   tmp = (char*)realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2571 2572
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2573 2574
  }

S
slguan 已提交
2575
  pColumn->numOfFilters++;
2576

S
slguan 已提交
2577 2578 2579 2580
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2581 2582
}

2583 2584
static int32_t doExtractColumnFilterInfo(SQueryInfo* pQueryInfo, SColumnFilterInfo* pColumnFilter,
                                         SColumnIndex* columnIndex, tSQLExpr* pExpr) {
S
slguan 已提交
2585
  const char* msg = "not supported filter condition";
H
hzcheng 已提交
2586

S
slguan 已提交
2587
  tSQLExpr*       pRight = pExpr->pRight;
H
hjxilinx 已提交
2588
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, columnIndex->tableIndex);
H
hzcheng 已提交
2589

H
hjxilinx 已提交
2590
  SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex->columnIndex);
H
hzcheng 已提交
2591

S
slguan 已提交
2592
  int16_t colType = pSchema->type;
2593
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2594 2595 2596
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2597
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2598
    int retVal = setColumnFilterInfoForTimestamp(pQueryInfo, &pRight->val);
2599 2600 2601
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2602 2603 2604
  }

  if (pExpr->nSQLOptr == TK_LE || pExpr->nSQLOptr == TK_LT) {
S
slguan 已提交
2605 2606
    tVariantDump(&pRight->val, (char*)&pColumnFilter->upperBndd, colType);
  } else {  // TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
H
hzcheng 已提交
2607
    if (colType == TSDB_DATA_TYPE_BINARY) {
S
slguan 已提交
2608 2609
      pColumnFilter->pz = (int64_t)calloc(1, pRight->val.nLen + 1);
      pColumnFilter->len = pRight->val.nLen;
H
hzcheng 已提交
2610

S
slguan 已提交
2611 2612 2613 2614 2615 2616 2617 2618 2619
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType);
    } else if (colType == TSDB_DATA_TYPE_NCHAR) {
      // pRight->val.nLen + 1 is larger than the actual nchar string length
      pColumnFilter->pz = (int64_t)calloc(1, (pRight->val.nLen + 1) * TSDB_NCHAR_SIZE);

      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType);

      size_t len = wcslen((wchar_t*)pColumnFilter->pz);
      pColumnFilter->len = len * TSDB_NCHAR_SIZE;
H
hzcheng 已提交
2620
    } else {
S
slguan 已提交
2621
      tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType);
H
hzcheng 已提交
2622 2623 2624 2625 2626
    }
  }

  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
2627
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
2628 2629
      break;
    case TK_LT:
S
slguan 已提交
2630
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
2631 2632
      break;
    case TK_GT:
S
slguan 已提交
2633
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LARGE;
H
hzcheng 已提交
2634 2635
      break;
    case TK_GE:
S
slguan 已提交
2636
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LARGE_EQUAL;
H
hzcheng 已提交
2637 2638
      break;
    case TK_EQ:
S
slguan 已提交
2639
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
2640 2641
      break;
    case TK_NE:
S
slguan 已提交
2642
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
2643 2644
      break;
    case TK_LIKE:
S
slguan 已提交
2645
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
2646
      break;
S
slguan 已提交
2647
    default:
2648
      return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
2649
  }
S
slguan 已提交
2650

2651
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2652 2653
}

S
slguan 已提交
2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667
typedef struct SCondExpr {
  tSQLExpr* pTagCond;
  tSQLExpr* pTimewindow;

  tSQLExpr* pColumnCond;

  tSQLExpr* pTableCond;
  int16_t   relType;  // relation between table name in expression and other tag
                      // filter condition expression, TK_AND or TK_OR
  int16_t tableCondIndex;

  tSQLExpr* pJoinExpr;  // join condition
  bool      tsJoin;
} SCondExpr;
H
hzcheng 已提交
2668

S
slguan 已提交
2669 2670 2671
static int32_t getTimeRange(int64_t* stime, int64_t* etime, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2672
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2673 2674
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2675 2676

  } else if (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_STRING) {  // value
S
slguan 已提交
2677 2678
    *str += tVariantToString(&pExpr->val, *str);

H
hjxilinx 已提交
2679 2680 2681 2682 2683 2684 2685
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    /*
     * arithmetic expression of aggregation, such as count(ts) + count(ts) *2
     */
    strncpy(*str, pExpr->operand.z, pExpr->operand.n);
    *str += pExpr->operand.n;
  } else {  // not supported operation
S
slguan 已提交
2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704
    assert(false);
  }

  return TSDB_CODE_SUCCESS;
}

static bool isExprLeafNode(tSQLExpr* pExpr) {
  return (pExpr->pRight == NULL && pExpr->pLeft == NULL) &&
         (pExpr->nSQLOptr == TK_ID || (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_NCHAR) ||
          pExpr->nSQLOptr == TK_SET);
}

static bool isExprDirectParentOfLeaftNode(tSQLExpr* pExpr) {
  return (pExpr->pLeft != NULL && pExpr->pRight != NULL) &&
         (isExprLeafNode(pExpr->pLeft) && isExprLeafNode(pExpr->pRight));
}

static int32_t tSQLExprLeafToString(tSQLExpr* pExpr, bool addParentheses, char** output) {
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
H
hzcheng 已提交
2705 2706 2707
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

  if (addParentheses) {
    *(*output) = '(';
    *output += 1;
  }

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_INVALID_SQL;
  }

  tSQLExprNodeToString(pRight, output);

  if (addParentheses) {
    *(*output) = ')';
    *output += 1;
  }

H
hzcheng 已提交
2728 2729 2730 2731
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
2732 2733 2734 2735
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791

  switch (pExpr->nSQLOptr) {
    case TK_LE: {
      *(int16_t*)(*exprString) = *(int16_t*)le;
      *exprString += 1;
      break;
    }
    case TK_GE: {
      *(int16_t*)(*exprString) = *(int16_t*)ge;
      *exprString += 1;
      break;
    }
    case TK_NE: {
      *(int16_t*)(*exprString) = *(int16_t*)ne;
      *exprString += 1;
      break;
    }

    case TK_LT:
      *(*exprString) = '<';
      break;
    case TK_GT:
      *(*exprString) = '>';
      break;
    case TK_EQ:
      *(*exprString) = '=';
      break;
    case TK_PLUS:
      *(*exprString) = '+';
      break;
    case TK_MINUS:
      *(*exprString) = '-';
      break;
    case TK_STAR:
      *(*exprString) = '*';
      break;
    case TK_DIVIDE:
      *(*exprString) = '/';
      break;
    case TK_REM:
      *(*exprString) = '%';
      break;
    case TK_LIKE: {
      int32_t len = sprintf(*exprString, " %s ", likeOptr);
      *exprString += (len - 1);
      break;
    }
    default:
      return TSDB_CODE_INVALID_SQL;
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2792
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
2793 2794 2795 2796 2797
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
2798
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2799
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2800 2801
  }

H
hzcheng 已提交
2802 2803
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
2804
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
2805 2806

    if (i < pList->nExpr - 1) {
H
hjxilinx 已提交
2807
      taosStringBuilderAppendString(sb, TBNAME_LIST_SEP);
S
slguan 已提交
2808
    }
H
hzcheng 已提交
2809

S
slguan 已提交
2810
    if (pSub->val.nLen <= 0 || pSub->val.nLen > TSDB_TABLE_NAME_LEN) {
H
hzcheng 已提交
2811 2812 2813 2814 2815 2816 2817
      return TSDB_CODE_INVALID_SQL;
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2818
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
2819 2820
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2821 2822

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2823 2824
}

S
slguan 已提交
2825 2826 2827 2828 2829 2830
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2831

2832
static int32_t extractColumnFilterInfo(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, tSQLExpr* pExpr, int32_t sqlOptr) {
H
hjxilinx 已提交
2833
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
2834

H
hjxilinx 已提交
2835 2836
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2837

S
slguan 已提交
2838 2839 2840
  const char* msg1 = "non binary column not support like operator";
  const char* msg2 = "binary column not support this operator";

2841
  SColumnBase*       pColumn = tscColumnBaseInfoInsert(pQueryInfo, pIndex);
S
slguan 已提交
2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866
  SColumnFilterInfo* pColFilter = NULL;

  /*
   * in case of TK_AND filter condition, we first find the corresponding column and build the query condition together
   * the already existed condition.
   */
  if (sqlOptr == TK_AND) {
    // this is a new filter condition on this column
    if (pColumn->numOfFilters == 0) {
      pColFilter = addColumnFilterInfo(pColumn);
    } else {  // update the existed column filter information, find the filter info here
      pColFilter = &pColumn->filterInfo[0];
    }
  } else if (sqlOptr == TK_OR) {
    // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
    pColFilter = addColumnFilterInfo(pColumn);
  } else {  // error;
    return TSDB_CODE_INVALID_SQL;
  }

  pColFilter->filterOnBinary =
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

  if (pColFilter->filterOnBinary) {
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
2867
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
2868
    }
S
slguan 已提交
2869 2870
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
2871
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
2872
    }
S
slguan 已提交
2873 2874 2875
  }

  pColumn->colIndex = *pIndex;
2876
  return doExtractColumnFilterInfo(pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
2877 2878
}

2879
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2880 2881 2882 2883 2884
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

  const char* or = "OR";
  const char*and = "AND";

2885
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
2886 2887 2888 2889 2890 2891 2892 2893 2894
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

2895
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2896 2897 2898 2899 2900 2901 2902
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    *(*str) = '(';
    *str += 1;
H
hzcheng 已提交
2903

2904
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
2905
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2906
      return ret;
H
hzcheng 已提交
2907
    }
S
slguan 已提交
2908

2909
    relToString(pExpr, str);
S
slguan 已提交
2910

2911
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
2912 2913 2914 2915

    *(*str) = ')';
    *str += 1;

H
hzcheng 已提交
2916 2917 2918
    return ret;
  }

S
slguan 已提交
2919 2920 2921
  return tSQLExprLeafToString(pExpr, true, str);
}

2922
static int32_t getTablenameCond(SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
2923 2924 2925 2926
  const char* msg0 = "invalid table name list";

  if (pTableCond == NULL) {
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2927 2928
  }

S
slguan 已提交
2929 2930
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
2931

S
slguan 已提交
2932
  if (!isTablenameToken(&pLeft->colInfo)) {
H
hzcheng 已提交
2933 2934 2935
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
2936
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2937

S
slguan 已提交
2938
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
2939
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
2940
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
2941
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
2942
  }
H
hzcheng 已提交
2943

S
slguan 已提交
2944
  if (ret != TSDB_CODE_SUCCESS) {
2945
    invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
2946
  }
H
hzcheng 已提交
2947

S
slguan 已提交
2948 2949 2950
  return ret;
}

2951
static int32_t getColumnQueryCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
2952 2953 2954 2955 2956
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
2957
    int32_t ret = getColumnQueryCondInfo(pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
2958 2959 2960 2961
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

2962
    return getColumnQueryCondInfo(pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
2963 2964
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2965
    if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
2966 2967
      return TSDB_CODE_INVALID_SQL;
    }
S
slguan 已提交
2968

2969
    return extractColumnFilterInfo(pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
2970
  }
S
slguan 已提交
2971
}
H
hzcheng 已提交
2972

2973
static int32_t getJoinCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
2974
  const char* msg = "invalid join query condition";
H
hzcheng 已提交
2975

S
slguan 已提交
2976 2977 2978
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
2979

S
slguan 已提交
2980
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
2981
    return invalidSqlErrMsg(pQueryInfo->msg, msg);
S
slguan 已提交
2982 2983
  }

2984
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
2985 2986 2987 2988
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2989
  if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2990 2991 2992
    return TSDB_CODE_INVALID_SQL;
  }

H
hjxilinx 已提交
2993
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2994
  int16_t         tagColIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
S
slguan 已提交
2995

H
hjxilinx 已提交
2996
  pLeft->uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
2997
  pLeft->tagCol = tagColIndex;
H
hjxilinx 已提交
2998
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
2999 3000

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3001
  if (getColumnIndexByName(&pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3002 3003 3004
    return TSDB_CODE_INVALID_SQL;
  }

H
hjxilinx 已提交
3005
  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3006
  tagColIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3007

H
hjxilinx 已提交
3008
  pRight->uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
3009
  pRight->tagCol = tagColIndex;
H
hjxilinx 已提交
3010
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3011 3012

  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3013 3014 3015 3016
  return TSDB_CODE_SUCCESS;
}

// todo error handle / such as and /or mixed with +/-/*/
S
slguan 已提交
3017
int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
H
hzcheng 已提交
3018 3019 3020
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3021
  *(*exprString)++ = '(';
H
hzcheng 已提交
3022 3023

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
S
slguan 已提交
3024
    buildArithmeticExprString(pLeft, exprString);
H
hzcheng 已提交
3025
  } else {
S
slguan 已提交
3026
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3027 3028 3029 3030 3031 3032 3033 3034
    if (ret != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_INVALID_SQL;
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
S
slguan 已提交
3035
    buildArithmeticExprString(pRight, exprString);
H
hzcheng 已提交
3036
  } else {
S
slguan 已提交
3037
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3038 3039 3040 3041 3042
    if (ret != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_INVALID_SQL;
    }
  }

H
hjxilinx 已提交
3043
  *(*exprString)++ = ')';
H
hzcheng 已提交
3044 3045 3046 3047

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3048
static int32_t validateSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3049
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3050 3051 3052 3053 3054
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
      return TSDB_CODE_INVALID_SQL;
    }
L
lihui 已提交
3055

H
hjxilinx 已提交
3056 3057 3058 3059 3060 3061
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
    if (getColumnIndexByName(&pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_INVALID_SQL;
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3062
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3063 3064
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3065 3066 3067 3068 3069 3070
    if ((pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || (pSchema->type == TSDB_DATA_TYPE_BOOL) ||
        (pSchema->type == TSDB_DATA_TYPE_BINARY) || (pSchema->type == TSDB_DATA_TYPE_NCHAR)) {
      return TSDB_CODE_INVALID_SQL;
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3071 3072
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
    return TSDB_CODE_INVALID_SQL;
H
hjxilinx 已提交
3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
      return TSDB_CODE_INVALID_SQL;
    }

    int32_t      outputIndex = pQueryInfo->exprsInfo.numOfExprs;
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
    // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
    if (addExprAndResultField(pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_INVALID_SQL;
    }
H
hzcheng 已提交
3087 3088 3089 3090 3091
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3092
static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3093 3094 3095 3096 3097 3098
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
H
hjxilinx 已提交
3099
    int32_t ret = validateArithmeticSQLExpr(pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3100 3101 3102 3103
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
H
hjxilinx 已提交
3104
    int32_t ret = validateSQLExpr(pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3105 3106 3107 3108 3109 3110 3111
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
H
hjxilinx 已提交
3112
    int32_t ret = validateArithmeticSQLExpr(pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3113 3114 3115 3116
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
H
hjxilinx 已提交
3117
    int32_t ret = validateSQLExpr(pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  return TSDB_CODE_SUCCESS;
}

static bool isValidExpr(tSQLExpr* pLeft, tSQLExpr* pRight, int32_t optr) {
  if (pLeft == NULL || (pRight == NULL && optr != TK_IN)) {
    return false;
  }

  /*
   * filter illegal expression in where clause:
S
slguan 已提交
3133 3134 3135
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3136 3137 3138
   *
   * However, columnA < 4+12 is valid
   */
L
lihui 已提交
3139 3140
  if ((pLeft->nSQLOptr >= TK_COUNT && pLeft->nSQLOptr <= TK_AVG_IRATE) ||
      (pRight->nSQLOptr >= TK_COUNT && pRight->nSQLOptr <= TK_AVG_IRATE) ||
H
hzcheng 已提交
3141 3142 3143 3144 3145 3146 3147 3148
      (pLeft->nSQLOptr >= TK_BOOL && pLeft->nSQLOptr <= TK_BINARY && pRight->nSQLOptr >= TK_BOOL &&
       pRight->nSQLOptr <= TK_BINARY)) {
    return false;
  }

  return true;
}

S
slguan 已提交
3149 3150 3151
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3152

S
slguan 已提交
3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177
  if (pRight->nSQLOptr == TK_ID && (pLeft->nSQLOptr == TK_INTEGER || pLeft->nSQLOptr == TK_FLOAT ||
                                    pLeft->nSQLOptr == TK_STRING || pLeft->nSQLOptr == TK_BOOL)) {
    /*
     * exchange value of the left handside and the value of the right-handside
     * to make sure that the value of filter expression always locates in
     * right-handside and
     * the column-id is at the left handside.
     */
    uint32_t optr = 0;
    switch (pExpr->nSQLOptr) {
      case TK_LE:
        optr = TK_GE;
        break;
      case TK_LT:
        optr = TK_GT;
        break;
      case TK_GT:
        optr = TK_LT;
        break;
      case TK_GE:
        optr = TK_LE;
        break;
      default:
        optr = pExpr->nSQLOptr;
    }
H
hzcheng 已提交
3178

S
slguan 已提交
3179 3180 3181 3182 3183
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3184
static bool validateJoinExprNode(SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198
  const char* msg1 = "illegal column name";
  const char* msg2 = "= is expected in join expression";
  const char* msg3 = "join column must have same type";
  const char* msg4 = "self join is not allowed";
  const char* msg5 = "join table must be the same type(table to table, super table to super table)";
  const char* msg6 = "tags in join condition not support binary/nchar types";

  tSQLExpr* pRight = pExpr->pRight;

  if (pRight->nSQLOptr != TK_ID) {
    return true;
  }

  if (pExpr->nSQLOptr != TK_EQ) {
3199
    invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
3200 3201 3202 3203 3204
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3205
  if (getColumnIndexByName(&pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
3206
    invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3207
    return false;
H
hzcheng 已提交
3208 3209
  }

S
slguan 已提交
3210
  // todo extract function
H
hjxilinx 已提交
3211
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3212
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3213 3214
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3215
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3216
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3217 3218 3219
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3220
    invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
3221 3222
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3223
    invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
3224 3225
    return false;
  } else if (leftType == TSDB_DATA_TYPE_BINARY || leftType == TSDB_DATA_TYPE_NCHAR) {
3226
    invalidSqlErrMsg(pQueryInfo->msg, msg6);
S
slguan 已提交
3227
    return false;
H
hzcheng 已提交
3228 3229
  }

S
slguan 已提交
3230
  // table to table/ super table to super table are allowed
H
hjxilinx 已提交
3231
  if (UTIL_TABLE_IS_SUPERTABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPERTABLE(pRightMeterMeta)) {
3232
    invalidSqlErrMsg(pQueryInfo->msg, msg5);
S
slguan 已提交
3233 3234
    return false;
  }
H
hzcheng 已提交
3235

S
slguan 已提交
3236 3237
  return true;
}
H
hzcheng 已提交
3238

S
slguan 已提交
3239 3240 3241 3242 3243 3244
static bool validTableNameOptr(tSQLExpr* pExpr) {
  const char nameFilterOptr[] = {TK_IN, TK_LIKE};

  for (int32_t i = 0; i < tListLen(nameFilterOptr); ++i) {
    if (pExpr->nSQLOptr == nameFilterOptr[i]) {
      return true;
H
hzcheng 已提交
3245 3246 3247
    }
  }

S
slguan 已提交
3248
  return false;
H
hzcheng 已提交
3249 3250
}

3251
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3252 3253
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3254
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3255
    }
H
hzcheng 已提交
3256

S
slguan 已提交
3257 3258 3259 3260
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3261

S
slguan 已提交
3262 3263
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3264

3265
static int32_t handleExprInQueryCond(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr, int32_t* type,
S
slguan 已提交
3266 3267 3268 3269 3270
                                     int32_t parentOptr) {
  const char* msg1 = "meter query cannot use tags filter";
  const char* msg2 = "illegal column name";
  const char* msg3 = "only one query time range allowed";
  const char* msg4 = "only one join condition allowed";
H
hjxilinx 已提交
3271 3272 3273
  const char* msg5 = "not support ordinary column join";
  const char* msg6 = "only one query condition on tbname allowed";
  const char* msg7 = "only in/like allowed in filter table name";
H
hzcheng 已提交
3274

S
slguan 已提交
3275 3276
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3277

S
slguan 已提交
3278 3279 3280
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3281
  if (getColumnIndexByName(&pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3282
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
3283 3284
  }

S
slguan 已提交
3285 3286
  assert(isExprDirectParentOfLeaftNode(*pExpr));

H
hjxilinx 已提交
3287
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3288
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3289 3290

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3291
    if (!validateJoinExprNode(pQueryInfo, *pExpr, &index)) {
H
hzcheng 已提交
3292 3293
      return TSDB_CODE_INVALID_SQL;
    }
S
slguan 已提交
3294 3295 3296

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
3297
      pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
S
slguan 已提交
3298 3299 3300 3301 3302 3303 3304 3305
      pCondExpr->tsJoin = true;

      /*
       * to release expression, e.g., m1.ts = m2.ts,
       * since this expression is used to set the join query type
       */
      tSQLExprDestroy(*pExpr);
    } else {
3306
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3307 3308 3309 3310
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
H
hjxilinx 已提交
3311
  } else if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) ||
S
slguan 已提交
3312 3313
             index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {  // query on tags
    // check for tag query condition
H
hjxilinx 已提交
3314
    if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
3315
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3316 3317 3318 3319 3320 3321 3322 3323
    }

    // check for like expression
    if ((*pExpr)->nSQLOptr == TK_LIKE) {
      if (pRight->val.nLen > TSDB_PATTERN_STRING_MAX_LEN) {
        return TSDB_CODE_INVALID_SQL;
      }

H
hjxilinx 已提交
3324
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3325 3326 3327

      if ((!isTablenameToken(&pLeft->colInfo)) && pSchema[index.columnIndex].type != TSDB_DATA_TYPE_BINARY &&
          pSchema[index.columnIndex].type != TSDB_DATA_TYPE_NCHAR) {
3328
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
3329 3330 3331 3332 3333 3334
      }
    }

    // in case of in operator, keep it in a seperate attribute
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3335
        return invalidSqlErrMsg(pQueryInfo->msg, msg7);
S
slguan 已提交
3336 3337 3338 3339 3340 3341 3342
      }

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3343
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
S
slguan 已提交
3344 3345 3346 3347 3348 3349
      }

      *type = TSQL_EXPR_TBNAME;
      *pExpr = NULL;
    } else {
      if (pRight->nSQLOptr == TK_ID) {  // join on tag columns for stable query
3350
        if (!validateJoinExprNode(pQueryInfo, *pExpr, &index)) {
S
slguan 已提交
3351 3352 3353 3354
          return TSDB_CODE_INVALID_SQL;
        }

        if (pCondExpr->pJoinExpr != NULL) {
3355
          return invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
3356 3357
        }

3358 3359
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373
        *pExpr = NULL;
      } else {
        // do nothing
        //                ret = setExprToCond(pCmd, &pCondExpr->pTagCond,
        //                *pExpr, NULL, parentOptr);
      }

      *type = TSQL_EXPR_TAG;
    }

  } else {  // query on other columns
    *type = TSQL_EXPR_COLUMN;

    if (pRight->nSQLOptr == TK_ID) {  // other column cannot be served as the join column
3374
      return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
3375 3376
    }

3377
    ret = setExprToCond(&pCondExpr->pColumnCond, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3378 3379
    *pExpr = NULL;  // remove it from expr tree
  }
H
hzcheng 已提交
3380

S
slguan 已提交
3381
  return ret;
H
hzcheng 已提交
3382 3383
}

3384 3385
int32_t getQueryCondExpr(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr, int32_t* type,
                         int32_t parentOptr) {
H
hzcheng 已提交
3386 3387 3388 3389
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
3390
  const char* msg1 = "query condition between different columns must use 'AND'";
H
hzcheng 已提交
3391

S
slguan 已提交
3392 3393 3394 3395
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
H
hzcheng 已提交
3396 3397 3398
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
3399 3400
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3401

S
slguan 已提交
3402
  if (!isExprDirectParentOfLeaftNode(*pExpr)) {
3403
    int32_t ret = getQueryCondExpr(pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3404 3405 3406 3407
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3408
    ret = getQueryCondExpr(pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3409 3410 3411
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3412

S
slguan 已提交
3413 3414 3415 3416 3417 3418
    /*
     *  if left child and right child do not belong to the same group, the sub
     *  expression is not valid for parent node, it must be TK_AND operator.
     */
    if (leftType != rightType) {
      if ((*pExpr)->nSQLOptr == TK_OR && (leftType + rightType != TSQL_EXPR_TBNAME + TSQL_EXPR_TAG)) {
3419
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3420
      }
H
hzcheng 已提交
3421 3422
    }

S
slguan 已提交
3423 3424 3425
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3426

S
slguan 已提交
3427
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3428

3429
  return handleExprInQueryCond(pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3430
}
H
hzcheng 已提交
3431

S
slguan 已提交
3432 3433 3434 3435
static void doCompactQueryExpr(tSQLExpr** pExpr) {
  if (*pExpr == NULL || isExprDirectParentOfLeaftNode(*pExpr)) {
    return;
  }
H
hzcheng 已提交
3436

S
slguan 已提交
3437 3438 3439
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3440

S
slguan 已提交
3441 3442 3443
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3444

S
slguan 已提交
3445 3446 3447 3448
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3449

S
slguan 已提交
3450 3451 3452
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3453

S
slguan 已提交
3454 3455 3456 3457
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3458

S
slguan 已提交
3459
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3460
  }
S
slguan 已提交
3461
}
H
hzcheng 已提交
3462

3463
static void doExtractExprForSTable(tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
S
slguan 已提交
3464 3465 3466 3467
  if (isExprDirectParentOfLeaftNode(*pExpr)) {
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3468
    if (getColumnIndexByName(&pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3469
      return;
H
hzcheng 已提交
3470 3471
    }

S
slguan 已提交
3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484
    if (index.tableIndex != tableIndex) {
      return;
    }

    SSQLToken t = {0};
    extractTableNameFromToken(&pLeft->colInfo, &t);

    *pOut = *pExpr;
    (*pExpr) = NULL;

  } else {
    *pOut = tSQLExprCreate(NULL, NULL, (*pExpr)->nSQLOptr);

3485 3486
    doExtractExprForSTable(&(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(&(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3487 3488 3489
  }
}

3490
static tSQLExpr* extractExprForSTable(tSQLExpr** pExpr, SQueryInfo* pQueryInfo, int32_t tableIndex) {
S
slguan 已提交
3491
  tSQLExpr* pResExpr = NULL;
H
hzcheng 已提交
3492

S
slguan 已提交
3493
  if (*pExpr != NULL) {
3494
    doExtractExprForSTable(pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3495
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3496 3497
  }

S
slguan 已提交
3498
  return pResExpr;
H
hzcheng 已提交
3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513
}

int tableNameCompar(const void* lhs, const void* rhs) {
  char* left = *(char**)lhs;
  char* right = *(char**)rhs;

  int32_t ret = strcmp(left, right);

  if (ret == 0) {
    return 0;
  }

  return ret > 0 ? 1 : -1;
}

3514
static int32_t setTableCondForSTableQuery(SQueryInfo* pQueryInfo, const char* account, tSQLExpr* pExpr,
3515
                                          int16_t tableCondIndex, SStringBuilder* sb) {
3516
  const char* msg = "table name too long";
H
hzcheng 已提交
3517

S
slguan 已提交
3518 3519 3520 3521
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

H
hjxilinx 已提交
3522
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableCondIndex);
S
slguan 已提交
3523

3524
  STagCond* pTagCond = &pQueryInfo->tagCond;
H
hjxilinx 已提交
3525
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
3526 3527 3528 3529

  assert(pExpr->nSQLOptr == TK_LIKE || pExpr->nSQLOptr == TK_IN);

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3530
    char* str = taosStringBuilderGetResult(sb, NULL);
3531
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3532 3533 3534
    return TSDB_CODE_SUCCESS;
  }

H
hjxilinx 已提交
3535 3536
  SStringBuilder sb1 = {0};
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3537

S
slguan 已提交
3538
  char db[TSDB_TABLE_ID_LEN] = {0};
H
hzcheng 已提交
3539

S
slguan 已提交
3540
  // remove the duplicated input table names
H
hzcheng 已提交
3541
  int32_t num = 0;
H
hjxilinx 已提交
3542 3543 3544
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3545
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3546 3547 3548 3549 3550 3551 3552 3553 3554

  int32_t j = 1;
  for (int32_t i = 1; i < num; ++i) {
    if (strcmp(segments[i], segments[i - 1]) != 0) {
      segments[j++] = segments[i];
    }
  }
  num = j;

H
hjxilinx 已提交
3555 3556 3557
  char* name = extractDBName(pTableMetaInfo->name, db);
  SSQLToken dbToken = {.type = TK_STRING, .z = name, .n = strlen(name)};
  
H
hzcheng 已提交
3558 3559
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3560
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3561
    }
H
hjxilinx 已提交
3562

S
slguan 已提交
3563
    char      idBuf[TSDB_TABLE_ID_LEN + 1] = {0};
S
slguan 已提交
3564
    int32_t   xlen = strlen(segments[i]);
H
hzcheng 已提交
3565 3566
    SSQLToken t = {.z = segments[i], .n = xlen, .type = TK_STRING};

3567
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3568
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3569
      taosStringBuilderDestroy(&sb1);
H
hzcheng 已提交
3570
      tfree(segments);
H
hjxilinx 已提交
3571

3572
      invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
3573 3574
      return ret;
    }
H
hjxilinx 已提交
3575

H
hjxilinx 已提交
3576
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3577
  }
H
hjxilinx 已提交
3578

H
hjxilinx 已提交
3579
  char* str = taosStringBuilderGetResult(&sb1, NULL);
3580
  pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
H
hjxilinx 已提交
3581

H
hjxilinx 已提交
3582
  taosStringBuilderDestroy(&sb1);
H
hzcheng 已提交
3583 3584 3585 3586
  tfree(segments);
  return TSDB_CODE_SUCCESS;
}

3587 3588 3589
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
  for (int32_t i = 0; i < pQueryInfo->colList.numOfCols; ++i) {
    SColumnBase* pColBase = &pQueryInfo->colList.pColList[i];
3590

S
slguan 已提交
3591 3592 3593 3594
    for (int32_t j = 0; j < pColBase->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pColBase->filterInfo[j];
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610

      if ((lowerOptr == TSDB_RELATION_LARGE_EQUAL || lowerOptr == TSDB_RELATION_LARGE) &&
          (upperOptr == TSDB_RELATION_LESS_EQUAL || upperOptr == TSDB_RELATION_LESS)) {
        continue;
      }

      // there must be at least two range, not support yet.
      if (lowerOptr * upperOptr != TSDB_RELATION_INVALID) {
        return false;
      }
    }
  }

  return true;
}

3611
static int32_t getTimeRangeFromExpr(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
3612 3613
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
3614 3615 3616 3617 3618

  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
3619 3620
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    if (pExpr->nSQLOptr == TK_OR) {
3621
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3622
    }
H
hzcheng 已提交
3623

3624
    getTimeRangeFromExpr(pQueryInfo, pExpr->pLeft);
S
slguan 已提交
3625

3626
    return getTimeRangeFromExpr(pQueryInfo, pExpr->pRight);
S
slguan 已提交
3627 3628
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3629
    if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3630 3631 3632
      return TSDB_CODE_INVALID_SQL;
    }

H
hjxilinx 已提交
3633
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3634
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3635
    
S
slguan 已提交
3636 3637 3638 3639 3640
    tSQLExpr* pRight = pExpr->pRight;

    TSKEY stime = 0;
    TSKEY etime = INT64_MAX;

H
hjxilinx 已提交
3641
    if (getTimeRange(&stime, &etime, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
3642
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
3643 3644 3645
    }

    // update the timestamp query range
3646 3647
    if (pQueryInfo->stime < stime) {
      pQueryInfo->stime = stime;
S
slguan 已提交
3648 3649
    }

3650 3651
    if (pQueryInfo->etime > etime) {
      pQueryInfo->etime = etime;
S
slguan 已提交
3652 3653 3654 3655 3656 3657
    }
  }

  return TSDB_CODE_SUCCESS;
}

3658
static int32_t validateJoinExpr(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
3659 3660 3661 3662
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

3663 3664
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
3665 3666
      return TSDB_CODE_SUCCESS;
    } else {
3667
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
3668 3669 3670
    }
  }

H
hjxilinx 已提交
3671
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
3672
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {  // for stable join, tag columns
3673
                                                   // must be present for join
S
slguan 已提交
3674
    if (pCondExpr->pJoinExpr == NULL) {
3675
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3676 3677 3678 3679
    }
  }

  if (!pCondExpr->tsJoin) {
3680
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
3681 3682
  }

S
slguan 已提交
3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707
  return TSDB_CODE_SUCCESS;
}

static void cleanQueryExpr(SCondExpr* pCondExpr) {
  if (pCondExpr->pTableCond) {
    tSQLExprDestroy(pCondExpr->pTableCond);
  }

  if (pCondExpr->pTagCond) {
    tSQLExprDestroy(pCondExpr->pTagCond);
  }

  if (pCondExpr->pColumnCond) {
    tSQLExprDestroy(pCondExpr->pColumnCond);
  }

  if (pCondExpr->pTimewindow) {
    tSQLExprDestroy(pCondExpr->pTimewindow);
  }

  if (pCondExpr->pJoinExpr) {
    tSQLExprDestroy(pCondExpr->pJoinExpr);
  }
}

3708
static void doAddJoinTagsColumnsIntoTagList(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
H
hjxilinx 已提交
3709
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
3710
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
S
slguan 已提交
3711
    SColumnIndex index = {0};
H
hjxilinx 已提交
3712

3713
    getColumnIndexByName(&pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index);
H
hjxilinx 已提交
3714
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3715

H
hjxilinx 已提交
3716
    int32_t columnInfo = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
3717
    addRequiredTagColumn(pQueryInfo, columnInfo, index.tableIndex);
H
hjxilinx 已提交
3718

3719
    getColumnIndexByName(&pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index);
H
hjxilinx 已提交
3720
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3721

H
hjxilinx 已提交
3722
    columnInfo = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
3723
    addRequiredTagColumn(pQueryInfo, columnInfo, index.tableIndex);
S
slguan 已提交
3724
  }
H
hjxilinx 已提交
3725
}
S
slguan 已提交
3726

3727
static int32_t getTagQueryCondExpr(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSQLExpr** pExpr) {
H
hjxilinx 已提交
3728
  int32_t ret = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
3729

H
hjxilinx 已提交
3730
  if (pCondExpr->pTagCond != NULL) {
3731 3732
    for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
      tSQLExpr* p1 = extractExprForSTable(pExpr, pQueryInfo, i);
H
hjxilinx 已提交
3733

H
hjxilinx 已提交
3734
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
hjxilinx 已提交
3735

H
hjxilinx 已提交
3736 3737
      char  c[TSDB_MAX_TAGS_LEN] = {0};
      char* str = c;
H
hjxilinx 已提交
3738

3739
      if ((ret = getTagCondString(p1, &str)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3740 3741
        return ret;
      }
H
hjxilinx 已提交
3742

3743
      tsSetSTableQueryCond(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid, c);
H
hjxilinx 已提交
3744

H
hjxilinx 已提交
3745 3746 3747
      doCompactQueryExpr(pExpr);
      tSQLExprDestroy(p1);
    }
H
hjxilinx 已提交
3748

H
hjxilinx 已提交
3749 3750
    pCondExpr->pTagCond = NULL;
  }
H
hjxilinx 已提交
3751

S
slguan 已提交
3752 3753
  return ret;
}
3754
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
3755 3756 3757
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
3758

H
hjxilinx 已提交
3759
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
3760
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
3761

H
hjxilinx 已提交
3762
  int32_t ret = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
3763

3764 3765
  pQueryInfo->stime = 0;
  pQueryInfo->etime = INT64_MAX;
S
slguan 已提交
3766

H
hjxilinx 已提交
3767
  // tags query condition may be larger than 512bytes, therefore, we need to prepare enough large space
H
hjxilinx 已提交
3768
  SStringBuilder sb = {0};
H
hjxilinx 已提交
3769
  SCondExpr      condExpr = {0};
S
slguan 已提交
3770

H
hjxilinx 已提交
3771
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
3772
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3773 3774
  }

H
hjxilinx 已提交
3775
  int32_t type = 0;
3776
  if ((ret = getQueryCondExpr(pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3777 3778
    return ret;
  }
H
hjxilinx 已提交
3779

S
slguan 已提交
3780
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
3781

S
slguan 已提交
3782
  // after expression compact, the expression tree is only include tag query condition
H
hjxilinx 已提交
3783
  condExpr.pTagCond = (*pExpr);
H
hjxilinx 已提交
3784

S
slguan 已提交
3785
  // 1. check if it is a join query
3786
  if ((ret = validateJoinExpr(pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3787 3788
    return ret;
  }
H
hjxilinx 已提交
3789

S
slguan 已提交
3790
  // 2. get the query time range
3791
  if ((ret = getTimeRangeFromExpr(pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3792 3793
    return ret;
  }
H
hjxilinx 已提交
3794

S
slguan 已提交
3795
  // 3. get the tag query condition
3796
  if ((ret = getTagQueryCondExpr(pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3797
    return ret;
S
slguan 已提交
3798
  }
H
hjxilinx 已提交
3799

S
slguan 已提交
3800
  // 4. get the table name query condition
3801
  if ((ret = getTablenameCond(pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3802 3803
    return ret;
  }
H
hjxilinx 已提交
3804

S
slguan 已提交
3805
  // 5. other column query condition
3806
  if ((ret = getColumnQueryCondInfo(pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3807 3808
    return ret;
  }
H
hjxilinx 已提交
3809

S
slguan 已提交
3810
  // 6. join condition
3811
  if ((ret = getJoinCondInfo(pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3812
    return ret;
H
hzcheng 已提交
3813
  }
H
hjxilinx 已提交
3814

S
slguan 已提交
3815
  // 7. query condition for table name
3816
  pQueryInfo->tagCond.relType = (condExpr.relType == TK_AND) ? TSDB_RELATION_AND : TSDB_RELATION_OR;
H
hjxilinx 已提交
3817

3818
  ret = setTableCondForSTableQuery(pQueryInfo, getAccountId(pSql), condExpr.pTableCond, condExpr.tableCondIndex, &sb);
H
hjxilinx 已提交
3819
  taosStringBuilderDestroy(&sb);
H
hjxilinx 已提交
3820

3821
  if (!validateFilterExpr(pQueryInfo)) {
H
hjxilinx 已提交
3822
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
3823
  }
H
hjxilinx 已提交
3824

3825
  doAddJoinTagsColumnsIntoTagList(pQueryInfo, &condExpr);
H
hjxilinx 已提交
3826

H
hjxilinx 已提交
3827
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
3828 3829 3830 3831
  return ret;
}

int32_t getTimeRange(int64_t* stime, int64_t* etime, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
3832 3833 3834 3835 3836
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
3837 3838
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
3839
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
3840 3841 3842 3843
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
    return TSDB_CODE_INVALID_SQL;
  }
H
hzcheng 已提交
3844 3845 3846 3847

  int64_t val = 0;
  bool    parsed = false;
  if (pRight->val.nType == TSDB_DATA_TYPE_BINARY) {
S
slguan 已提交
3848 3849
    pRight->val.nLen = strdequote(pRight->val.pz);

S
slguan 已提交
3850
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
3851 3852 3853 3854 3855 3856
    if (seg != NULL) {
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO) == TSDB_CODE_SUCCESS) {
        parsed = true;
      } else {
        return TSDB_CODE_INVALID_SQL;
      }
S
slguan 已提交
3857 3858 3859 3860 3861 3862 3863
    } else {
      SSQLToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
        return TSDB_CODE_INVALID_SQL;
      }
H
hzcheng 已提交
3864 3865 3866 3867
    }
  } else if (pRight->nSQLOptr == TK_INTEGER && timePrecision == TSDB_TIME_PRECISION_MILLI) {
    /*
     * if the pRight->nSQLOptr == TK_INTEGER/TK_FLOAT, the value is adaptive, we
S
slguan 已提交
3868
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919
     *
     * Additional check to avoid data overflow
     */
    if (pRight->val.i64Key <= INT64_MAX / 1000) {
      pRight->val.i64Key *= 1000;
    }
  } else if (pRight->nSQLOptr == TK_FLOAT && timePrecision == TSDB_TIME_PRECISION_MILLI) {
    pRight->val.dKey *= 1000;
  }

  if (!parsed) {
    /*
     * failed to parse timestamp in regular formation, try next
     * it may be a epoch time in string format
     */
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT);

    /*
     * transfer it into MICROSECOND format if it is a string, since for
     * TK_INTEGER/TK_FLOAT the value has been transferred
     *
     * additional check to avoid data overflow
     */
    if (pRight->nSQLOptr == TK_STRING && timePrecision == TSDB_TIME_PRECISION_MILLI) {
      if (val <= INT64_MAX / 1000) {
        val *= 1000;
      }
    }
  }

  int32_t delta = 1;
  /* for millisecond, delta is 1ms=1000us */
  if (timePrecision == TSDB_TIME_PRECISION_MILLI) {
    delta *= 1000;
  }

  if (optr == TK_LE) {
    *etime = val;
  } else if (optr == TK_LT) {
    *etime = val - delta;
  } else if (optr == TK_GT) {
    *stime = val + delta;
  } else if (optr == TK_GE) {
    *stime = val;
  } else if (optr == TK_EQ) {
    *stime = val;
    *etime = *stime;
  }
  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3920
// todo error !!!!
3921
int32_t tsRewriteFieldNameIfNecessary(SQueryInfo* pQueryInfo) {
S
slguan 已提交
3922 3923
  const char rep[] = {'(', ')', '*', ',', '.', '/', '\\', '+', '-', '%', ' '};

3924 3925
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
    char* fieldName = tscFieldInfoGetField(pQueryInfo, i)->name;
H
hzcheng 已提交
3926
    for (int32_t j = 0; j < TSDB_COL_NAME_LEN && fieldName[j] != 0; ++j) {
S
slguan 已提交
3927 3928 3929 3930 3931
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
3932 3933
      }
    }
S
slguan 已提交
3934

H
hzcheng 已提交
3935 3936 3937 3938
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
3939 3940 3941 3942
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
    char* fieldName = tscFieldInfoGetField(pQueryInfo, i)->name;
    for (int32_t j = i + 1; j < pQueryInfo->fieldsInfo.numOfOutputCols; ++j) {
      if (strncasecmp(fieldName, tscFieldInfoGetField(pQueryInfo, j)->name, TSDB_COL_NAME_LEN) == 0) {
3943
        const char* msg = "duplicated column name in new table";
3944
        return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
3945 3946 3947 3948 3949 3950 3951
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

3952
int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
3953 3954 3955 3956
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
3957 3958 3959 3960

  const char* msg = "illegal value or data overflow";
  const char* msg1 = "value is expected";
  const char* msg2 = "invalid fill option";
H
hzcheng 已提交
3961 3962

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
3963
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
3964 3965
  }

3966
  if (pQueryInfo->defaultVal == NULL) {
H
hjxilinx 已提交
3967
    pQueryInfo->defaultVal = calloc(pQueryInfo->exprsInfo.numOfExprs, sizeof(int64_t));
3968 3969 3970 3971 3972
    if (pQueryInfo->defaultVal == NULL) {
      return TSDB_CODE_CLI_OUT_OF_MEMORY;
    }
  }

H
hzcheng 已提交
3973
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
3974
    pQueryInfo->interpoType = TSDB_INTERPO_NONE;
H
hzcheng 已提交
3975
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
3976
    pQueryInfo->interpoType = TSDB_INTERPO_NULL;
H
hjxilinx 已提交
3977
    for (int32_t i = START_INTERPO_COL_IDX; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
3978 3979
      TAOS_FIELD* pFields = tscFieldInfoGetField(pQueryInfo, i);
      setNull((char*)&pQueryInfo->defaultVal[i], pFields->type, pFields->bytes);
H
hzcheng 已提交
3980 3981
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
3982
    pQueryInfo->interpoType = TSDB_INTERPO_PREV;
H
hzcheng 已提交
3983
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
3984
    pQueryInfo->interpoType = TSDB_INTERPO_LINEAR;
H
hzcheng 已提交
3985
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
3986
    pQueryInfo->interpoType = TSDB_INTERPO_SET_VALUE;
H
hzcheng 已提交
3987 3988

    if (pFillToken->nExpr == 1) {
3989
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
3990 3991 3992 3993 3994 3995
    }

    int32_t startPos = 1;
    int32_t numOfFillVal = pFillToken->nExpr - 1;

    /* for point interpolation query, we do not have the timestamp column */
3996
    if (tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
3997 3998
      startPos = 0;

H
hjxilinx 已提交
3999 4000
      if (numOfFillVal > pQueryInfo->exprsInfo.numOfExprs) {
        numOfFillVal = pQueryInfo->exprsInfo.numOfExprs;
H
hzcheng 已提交
4001 4002
      }
    } else {
H
hjxilinx 已提交
4003 4004
      numOfFillVal = (pFillToken->nExpr > pQueryInfo->exprsInfo.numOfExprs)
                         ? pQueryInfo->exprsInfo.numOfExprs
4005
                         : pFillToken->nExpr;
H
hzcheng 已提交
4006 4007 4008 4009 4010
    }

    int32_t j = 1;

    for (int32_t i = startPos; i < numOfFillVal; ++i, ++j) {
4011
      TAOS_FIELD* pFields = tscFieldInfoGetField(pQueryInfo, i);
H
hjxilinx 已提交
4012

4013 4014 4015 4016
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
        setNull((char*)(&pQueryInfo->defaultVal[i]), pFields->type, pFields->bytes);
        continue;
      }
H
hjxilinx 已提交
4017

4018
      int32_t ret = tVariantDump(&pFillToken->a[j].pVar, (char*)&pQueryInfo->defaultVal[i], pFields->type);
H
hzcheng 已提交
4019
      if (ret != TSDB_CODE_SUCCESS) {
4020
        return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
4021 4022 4023
      }
    }

H
hjxilinx 已提交
4024 4025
    if ((pFillToken->nExpr < pQueryInfo->exprsInfo.numOfExprs) ||
        ((pFillToken->nExpr - 1 < pQueryInfo->exprsInfo.numOfExprs) && (tscIsPointInterpQuery(pQueryInfo)))) {
H
hzcheng 已提交
4026 4027
      tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1];

H
hjxilinx 已提交
4028
      for (int32_t i = numOfFillVal; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4029
        TAOS_FIELD* pFields = tscFieldInfoGetField(pQueryInfo, i);
H
hzcheng 已提交
4030 4031

        if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4032
          setNull((char*)(&pQueryInfo->defaultVal[i]), pFields->type, pFields->bytes);
H
hjxilinx 已提交
4033 4034
        } else {
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->defaultVal[i], pFields->type);
H
hzcheng 已提交
4035 4036 4037 4038
        }
      }
    }
  } else {
4039
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4040 4041 4042 4043 4044
  }

  return TSDB_CODE_SUCCESS;
}

4045
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4046
  /* set default timestamp order information for all queries */
4047
  pQueryInfo->order.order = TSQL_SO_ASC;
H
hjxilinx 已提交
4048
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4049

4050 4051 4052
  if (isTopBottomQuery(pQueryInfo)) {
    pQueryInfo->order.order = TSQL_SO_ASC;
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4053
  } else {
4054
    pQueryInfo->order.orderColId = -1;
H
hzcheng 已提交
4055 4056 4057
  }

  /* for metric query, set default ascending order for group output */
H
hjxilinx 已提交
4058
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
4059
    pQueryInfo->groupbyExpr.orderType = TSQL_SO_ASC;
H
hzcheng 已提交
4060 4061 4062
  }
}

S
slguan 已提交
4063
int32_t parseOrderbyClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4064 4065 4066 4067
  const char* msg0 = "only support order by primary timestamp";
  const char* msg1 = "invalid column name";
  const char* msg2 = "only support order by primary timestamp and queried column";
  const char* msg3 = "only support order by primary timestamp and first tag in groupby clause";
H
hzcheng 已提交
4068

4069
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4070
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4071 4072 4073 4074 4075 4076

  if (pQuerySql->pSortOrder == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4077 4078 4079 4080 4081 4082 4083

  /*
   * for table query, there is only one or none order option is allowed, which is the
   * ts or values(top/bottom) order is supported.
   *
   * for super table query, the order option must be less than 3.
   */
H
hjxilinx 已提交
4084
  if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4085
    if (pSortorder->nExpr > 1) {
4086
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
4087 4088 4089
    }
  } else {
    if (pSortorder->nExpr > 2) {
4090
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101
    }
  }

  // handle the first part of order by
  tVariant* pVar = &pSortorder->a[0].pVar;

  // e.g., order by 1 asc, return directly with out further check.
  if (pVar->nType >= TSDB_DATA_TYPE_TINYINT && pVar->nType <= TSDB_DATA_TYPE_BIGINT) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
4102 4103 4104
  SSQLToken    columnName = {pVar->nLen, pVar->nType, pVar->pz};
  SColumnIndex index = {0};

H
hjxilinx 已提交
4105
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {  // metric query
4106
    if (getColumnIndexByName(&columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4107
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
4108 4109 4110 4111
    }

    bool orderByTags = false;
    bool orderByTS = false;
H
hzcheng 已提交
4112

H
hjxilinx 已提交
4113 4114
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4115
      if (relTagIndex == pQueryInfo->groupbyExpr.columnInfo[0].colIdx) {
H
hzcheng 已提交
4116 4117
        orderByTags = true;
      }
S
slguan 已提交
4118 4119
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4120 4121
    }

S
slguan 已提交
4122
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4123 4124 4125
      orderByTS = true;
    }

4126 4127
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4128 4129 4130 4131 4132 4133
    } else {
      assert(!(orderByTags && orderByTS));
    }

    if (pSortorder->nExpr == 1) {
      if (orderByTags) {
H
hjxilinx 已提交
4134
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4135 4136
        pQueryInfo->groupbyExpr.orderType = pQuerySql->pSortOrder->a[0].sortOrder;
      } else if (isTopBottomQuery(pQueryInfo)) {
S
slguan 已提交
4137
        /* order of top/bottom query in interval is not valid  */
4138
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4139 4140
        assert(pExpr->functionId == TSDB_FUNC_TS);

4141
        pExpr = tscSqlExprGet(pQueryInfo, 1);
S
slguan 已提交
4142
        if (pExpr->colInfo.colIdx != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4143
          return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
4144
        }
4145

4146 4147
        pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4148
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4149
      } else {
4150 4151
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4152 4153 4154 4155
      }
    }

    if (pSortorder->nExpr == 2) {
S
slguan 已提交
4156
      if (orderByTags) {
H
hjxilinx 已提交
4157
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4158
        pQueryInfo->groupbyExpr.orderType = pQuerySql->pSortOrder->a[0].sortOrder;
S
slguan 已提交
4159
      } else {
4160 4161
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4162 4163
      }

H
hzcheng 已提交
4164 4165
      tVariant* pVar2 = &pSortorder->a[1].pVar;
      SSQLToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4166
      if (getColumnIndexByName(&cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4167
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
4168 4169 4170
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4171
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4172
      } else {
4173 4174
        pQueryInfo->order.order = pSortorder->a[1].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4175 4176 4177 4178
      }
    }

  } else {  // meter query
4179
    if (getColumnIndexByName(&columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4180
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4181 4182
    }

4183 4184
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4185 4186
    }

4187
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4188
      /* order of top/bottom query in interval is not valid  */
4189
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4190
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4191

4192
      pExpr = tscSqlExprGet(pQueryInfo, 1);
S
slguan 已提交
4193
      if (pExpr->colInfo.colIdx != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4194
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4195
      }
4196

4197 4198
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4199 4200
      return TSDB_CODE_SUCCESS;
    }
4201

4202
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4203 4204 4205 4206 4207 4208
  }

  return TSDB_CODE_SUCCESS;
}

int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
S
slguan 已提交
4209
  const int32_t DEFAULT_TABLE_INDEX = 0;
4210

4211 4212 4213 4214 4215 4216
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";
  const char* msg3 = "manipulation of tag available for super table";
  const char* msg4 = "set tag value only available for table";
  const char* msg5 = "only support add one tag";
  const char* msg6 = "column can only be modified by super table";
S
slguan 已提交
4217 4218

  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4219
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4220 4221
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

H
hjxilinx 已提交
4222
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, DEFAULT_TABLE_INDEX);
H
hzcheng 已提交
4223

4224
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4225
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
4226
  }
P
plum-lihui 已提交
4227

H
hjxilinx 已提交
4228
  if (setMeterID(pTableMetaInfo, &(pAlterSQL->name), pSql) != TSDB_CODE_SUCCESS) {
4229
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4230 4231
  }

H
hjxilinx 已提交
4232
  int32_t ret = tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
4233 4234 4235 4236
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

H
hjxilinx 已提交
4237
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4238

4239 4240
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN ||
      pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
hjxilinx 已提交
4241
    if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
4242
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4243
    }
H
hjxilinx 已提交
4244
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo))) {
4245
    return invalidSqlErrMsg(pQueryInfo->msg, msg4);
4246
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4247
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4248
    return invalidSqlErrMsg(pQueryInfo->msg, msg6);
H
hzcheng 已提交
4249 4250
  }

4251
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
hzcheng 已提交
4252 4253
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4254
      return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
4255 4256 4257 4258 4259 4260
    }

    if (!validateOneTags(pCmd, &pFieldList->p[0])) {
      return TSDB_CODE_INVALID_SQL;
    }

4261
    tscFieldInfoSetValFromField(&pQueryInfo->fieldsInfo, 0, &pFieldList->p[0]);
4262
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
4263 4264 4265 4266 4267
    const char* msg1 = "no tags can be dropped";
    const char* msg2 = "only support one tag";
    const char* msg3 = "tag name too long";
    const char* msg4 = "illegal tag name";
    const char* msg5 = "primary tag cannot be dropped";
H
hzcheng 已提交
4268

H
hjxilinx 已提交
4269
    if (tscGetNumOfTags(pTableMeta) == 1) {
4270
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4271 4272 4273 4274
    }

    // numOfTags == 1
    if (pAlterSQL->varList->nExpr > 1) {
4275
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4276 4277 4278 4279
    }

    tVariantListItem* pItem = &pAlterSQL->varList->a[0];
    if (pItem->pVar.nLen > TSDB_COL_NAME_LEN) {
4280
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4281
    }
4282

4283
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
4284 4285
    SSQLToken    name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen, .type = TK_STRING};

4286
    if (getColumnIndexByName(&name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4287
      return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
4288 4289
    }

H
hjxilinx 已提交
4290
    if (index.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4291
      return invalidSqlErrMsg(pQueryInfo->msg, msg4);
4292
    } else if (index.columnIndex == 0) {
4293
      return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
4294 4295
    }

4296 4297
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
4298 4299
    tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 0, TSDB_DATA_TYPE_INT, name1,
                         tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
4300
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
4301 4302
    const char* msg1 = "tag name too long";
    const char* msg2 = "invalid tag name";
4303

H
hzcheng 已提交
4304 4305 4306 4307 4308
    tVariantList* pVarList = pAlterSQL->varList;
    if (pVarList->nExpr > 2) {
      return TSDB_CODE_INVALID_SQL;
    }

4309 4310 4311 4312
    tVariantListItem* pSrcItem = &pAlterSQL->varList->a[0];
    tVariantListItem* pDstItem = &pAlterSQL->varList->a[1];

    if (pSrcItem->pVar.nLen >= TSDB_COL_NAME_LEN || pDstItem->pVar.nLen >= TSDB_COL_NAME_LEN) {
4313
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4314 4315
    }

4316
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4317
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
4318
    }
H
hzcheng 已提交
4319

S
slguan 已提交
4320 4321
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4322

S
slguan 已提交
4323
    SSQLToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4324
    if (getColumnIndexByName(&srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4325
      return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
4326 4327
    }

S
slguan 已提交
4328
    SSQLToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4329
    if (getColumnIndexByName(&destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4330 4331 4332 4333 4334
      return TSDB_CODE_INVALID_SQL;
    }

    char name[128] = {0};
    strncpy(name, pVarList->a[0].pVar.pz, pVarList->a[0].pVar.nLen);
4335
    tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 0, TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
H
hzcheng 已提交
4336 4337 4338

    memset(name, 0, tListLen(name));
    strncpy(name, pVarList->a[1].pVar.pz, pVarList->a[1].pVar.nLen);
4339
    tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 1, TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
4340
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
S
slguan 已提交
4341
    const char* msg1 = "invalid tag value";
4342
    const char* msg2 = "update normal column not supported";
S
slguan 已提交
4343 4344
    const char* msg3 = "tag value too long";

4345 4346
    // Note: update can only be applied to table not super table.
    // the following is handle display tags value for meters created according to super table
H
hzcheng 已提交
4347 4348 4349
    tVariantList* pVarList = pAlterSQL->varList;
    tVariant*     pTagName = &pVarList->a[0].pVar;

4350 4351
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
    SSQLToken    name = {.type = TK_STRING, .z = pTagName->pz, .n = pTagName->nLen};
4352
    if (getColumnIndexByName(&name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4353
      return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
4354 4355
    }

H
hjxilinx 已提交
4356
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4357
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
4358 4359
    }

H
hjxilinx 已提交
4360
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
4361 4362 4363
    if (tVariantDump(&pVarList->a[1].pVar, pAlterSQL->tagData.data /*pCmd->payload*/, pTagsSchema->type) !=
        TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4364 4365 4366
    }

    // validate the length of binary
4367 4368
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
        pVarList->a[1].pVar.nLen > pTagsSchema->bytes) {
4369
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4370 4371
    }

4372 4373
    char name1[128] = {0};
    strncpy(name1, pTagName->pz, pTagName->nLen);
4374 4375
    tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 0, TSDB_DATA_TYPE_INT, name1,
                         tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
H
hzcheng 已提交
4376

4377
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
hzcheng 已提交
4378 4379
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4380
      const char* msg = "only support add one column";
4381
      return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
4382 4383 4384 4385 4386 4387
    }

    if (!validateOneColumn(pCmd, &pFieldList->p[0])) {
      return TSDB_CODE_INVALID_SQL;
    }

4388
    tscFieldInfoSetValFromField(&pQueryInfo->fieldsInfo, 0, &pFieldList->p[0]);
4389
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
4390 4391 4392
    const char* msg1 = "no columns can be dropped";
    const char* msg2 = "only support one column";
    const char* msg4 = "illegal column name";
4393
    const char* msg3 = "primary timestamp column cannot be dropped";
H
hzcheng 已提交
4394

H
hjxilinx 已提交
4395
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
4396
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4397 4398 4399
    }

    if (pAlterSQL->varList->nExpr > 1) {
4400
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4401 4402 4403 4404
    }

    tVariantListItem* pItem = &pAlterSQL->varList->a[0];

4405 4406
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
    SSQLToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4407
    if (getColumnIndexByName(&name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4408
      return invalidSqlErrMsg(pQueryInfo->msg, msg4);
H
hzcheng 已提交
4409 4410
    }

4411
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4412
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
4413
    }
H
hzcheng 已提交
4414

4415 4416
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
4417 4418
    tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 0, TSDB_DATA_TYPE_INT, name1,
                         tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
H
hzcheng 已提交
4419 4420 4421 4422 4423
  }

  return TSDB_CODE_SUCCESS;
}

4424
int32_t validateSqlFunctionInStreamSql(SQueryInfo* pQueryInfo) {
4425 4426
  const char* msg0 = "sample interval can not be less than 10ms.";
  const char* msg1 = "functions not allowed in select clause";
H
hzcheng 已提交
4427

4428
  if (pQueryInfo->intervalTime != 0 && pQueryInfo->intervalTime < 10) {
4429
    return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
4430 4431
  }

H
hjxilinx 已提交
4432
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4433
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
4434
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
4435
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4436 4437 4438 4439 4440 4441
    }
  }

  return TSDB_CODE_SUCCESS;
}

4442
int32_t validateFunctionsInIntervalOrGroupbyQuery(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4443
  bool        isProjectionFunction = false;
4444
  const char* msg1 = "column projection is not compatible with interval";
H
hjxilinx 已提交
4445

H
hzcheng 已提交
4446
  // multi-output set/ todo refactor
H
hjxilinx 已提交
4447
  for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) {
4448
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
4449

4450 4451 4452
    // projection query on primary timestamp, the selectivity function needs to be present.
    if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
      bool hasSelectivity = false;
H
hjxilinx 已提交
4453
      for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) {
4454
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
4455 4456 4457 4458 4459
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
4460

4461 4462 4463 4464
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4465

S
slguan 已提交
4466
    if (pExpr->functionId == TSDB_FUNC_PRJ || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4467
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4468 4469 4470
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4471 4472

  if (isProjectionFunction) {
4473
    invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4474 4475 4476 4477 4478 4479
  }

  return isProjectionFunction == true ? TSDB_CODE_INVALID_SQL : TSDB_CODE_SUCCESS;
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4480 4481
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4482 4483 4484 4485 4486 4487 4488
} SDNodeDynConfOption;

int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
    return TSDB_CODE_INVALID_SQL;
  }

H
hjxilinx 已提交
4489
  const SDNodeDynConfOption DNODE_DYNAMIC_CFG_OPTIONS[14] = {
S
slguan 已提交
4490
      {"resetLog", 8},      {"resetQueryCache", 15}, {"dDebugFlag", 10},       {"rpcDebugFlag", 12},
H
hzcheng 已提交
4491 4492
      {"tmrDebugFlag", 12}, {"cDebugFlag", 10},      {"uDebugFlag", 10},       {"mDebugFlag", 10},
      {"sdbDebugFlag", 12}, {"httpDebugFlag", 13},   {"monitorDebugFlag", 16}, {"qDebugflag", 10},
S
slguan 已提交
4493
      {"debugFlag", 9},     {"monitor", 7}};
H
hzcheng 已提交
4494 4495 4496 4497 4498 4499

  SSQLToken* pOptionToken = &pOptions->a[1];

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
    for (int32_t i = 0; i < 2; ++i) {
H
hjxilinx 已提交
4500
      const SDNodeDynConfOption* pOption = &DNODE_DYNAMIC_CFG_OPTIONS[i];
H
hzcheng 已提交
4501 4502 4503 4504
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
S
slguan 已提交
4505 4506 4507 4508 4509 4510 4511 4512
  } else if ((strncasecmp(DNODE_DYNAMIC_CFG_OPTIONS[13].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (DNODE_DYNAMIC_CFG_OPTIONS[13].len == pOptionToken->n)) {
    SSQLToken* pValToken = &pOptions->a[2];
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
      return TSDB_CODE_INVALID_SQL;  // options value is invalid
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4513 4514 4515 4516 4517 4518 4519 4520 4521
  } else {
    SSQLToken* pValToken = &pOptions->a[2];

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      /* options value is out of valid range */
      return TSDB_CODE_INVALID_SQL;
    }

S
slguan 已提交
4522
    for (int32_t i = 2; i < tListLen(DNODE_DYNAMIC_CFG_OPTIONS) - 1; ++i) {
H
hjxilinx 已提交
4523
      const SDNodeDynConfOption* pOption = &DNODE_DYNAMIC_CFG_OPTIONS[i];
H
hzcheng 已提交
4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534

      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        /* options is valid */
        return TSDB_CODE_SUCCESS;
      }
    }
  }

  return TSDB_CODE_INVALID_SQL;
}

S
slguan 已提交
4535 4536 4537 4538 4539
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
    return TSDB_CODE_INVALID_SQL;
  }

H
hjxilinx 已提交
4540 4541
  SDNodeDynConfOption LOCAL_DYNAMIC_CFG_OPTIONS[6] = {{"resetLog", 8},    {"rpcDebugFlag", 12}, {"tmrDebugFlag", 12},
                                                      {"cDebugFlag", 10}, {"uDebugFlag", 10},   {"debugFlag", 9}};
S
slguan 已提交
4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572

  SSQLToken* pOptionToken = &pOptions->a[0];

  if (pOptions->nTokens == 1) {
    // reset log does not need value
    for (int32_t i = 0; i < 1; ++i) {
      SDNodeDynConfOption* pOption = &LOCAL_DYNAMIC_CFG_OPTIONS[i];
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
  } else {
    SSQLToken* pValToken = &pOptions->a[1];

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
      return TSDB_CODE_INVALID_SQL;
    }

    for (int32_t i = 1; i < tListLen(LOCAL_DYNAMIC_CFG_OPTIONS); ++i) {
      SDNodeDynConfOption* pOption = &LOCAL_DYNAMIC_CFG_OPTIONS[i];
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        // options is valid
        return TSDB_CODE_SUCCESS;
      }
    }
  }
  return TSDB_CODE_INVALID_SQL;
}

H
hzcheng 已提交
4573 4574 4575 4576 4577 4578
int32_t validateColumnName(char* name) {
  bool ret = isKeyWord(name, strlen(name));
  if (ret) {
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
4579
  SSQLToken token = {.z = name};
H
hzcheng 已提交
4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
    return TSDB_CODE_INVALID_SQL;
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
    strtrim(token.z);
    token.n = (uint32_t)strlen(token.z);

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
      return TSDB_CODE_INVALID_SQL;
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
      return TSDB_CODE_INVALID_SQL;
    }
  }

  return TSDB_CODE_SUCCESS;
}

4606 4607
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
4608 4609 4610
    return true;
  }

4611
  return (pQueryInfo->stime == pQueryInfo->etime) && (pQueryInfo->stime != 0);
H
hzcheng 已提交
4612 4613
}

4614
int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* pQuerySql, SSqlObj* pSql) {
H
hjxilinx 已提交
4615
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4616

S
slguan 已提交
4617 4618 4619 4620
  const char* msg0 = "soffset/offset can not be less than 0";
  const char* msg1 = "slimit/soffset only available for STable query";
  const char* msg2 = "function not supported on table";
  const char* msg3 = "slimit/soffset can not apply to projection query";
H
hjxilinx 已提交
4621

H
hzcheng 已提交
4622
  // handle the limit offset value, validate the limit
4623
  pQueryInfo->limit = pQuerySql->limit;
4624
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4625
  pQueryInfo->slimit = pQuerySql->slimit;
4626 4627 4628 4629
  
  tscTrace("%p limit:%d, offset:%" PRId64 " slimit:%d, soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
4630
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
4631
    return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
4632 4633
  }

4634
  if (pQueryInfo->limit.limit == 0) {
S
slguan 已提交
4635
    tscTrace("%p limit 0, no output result", pSql);
4636
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4637
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
4638 4639
  }

H
hjxilinx 已提交
4640
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
4641
    bool queryOnTags = false;
4642
    if (tscQueryOnlyMetricTags(pQueryInfo, &queryOnTags) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4643 4644 4645 4646
      return TSDB_CODE_INVALID_SQL;
    }

    if (queryOnTags == true) {  // local handle the metric tag query
4647
      pQueryInfo->command = TSDB_SQL_RETRIEVE_TAGS;
S
slguan 已提交
4648
    } else {
4649
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
4650 4651 4652
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
          return invalidSqlErrMsg(pQueryInfo->msg, msg3);
        }
H
hjxilinx 已提交
4653

4654
        // for projection query on super table, all queries are subqueries
4655
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
4656
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
4657
        }
S
slguan 已提交
4658
      }
H
hzcheng 已提交
4659 4660
    }

4661
    if (pQueryInfo->slimit.limit == 0) {
4662
      tscTrace("%p slimit 0, no output result", pSql);
4663
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4664 4665 4666 4667
      return TSDB_CODE_SUCCESS;
    }

    /*
4668 4669 4670 4671
     * Get the distribution of all tables among all available virtual nodes that are qualified for the query condition
     * and created according to this super table from management node.
     * And then launching multiple async-queries against all qualified virtual nodes, during the first-stage
     * query operation.
H
hzcheng 已提交
4672
     */
H
hjxilinx 已提交
4673
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
4674 4675 4676 4677
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
4678
    // No tables included. No results generated. Query results are empty.
H
hjxilinx 已提交
4679
    if (pTableMetaInfo->pTableMeta == NULL) {
H
hzcheng 已提交
4680
      tscTrace("%p no table in metricmeta, no output result", pSql);
4681
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4682 4683 4684
    }

    // keep original limitation value in globalLimit
4685
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4686
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
4687

4688 4689 4690 4691 4692 4693 4694 4695 4696
    if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
      /*
       * the limitation/offset value should be removed during retrieve data from virtual node,
       * since the global order are done in client side, so the limitation should also
       * be done at the client side.
       */
      if (pQueryInfo->limit.limit > 0) {
        pQueryInfo->limit.limit = -1;
      }
H
hjxilinx 已提交
4697

4698 4699
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
4700
  } else {
4701 4702
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4703 4704
    }

S
slguan 已提交
4705
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
4706
    for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4707
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4708
      if (pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX) {
4709
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4710 4711 4712 4713 4714 4715
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}
4716

4717
static int32_t setKeepOption(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
hjxilinx 已提交
4718
  const char* msg = "invalid number of options";
H
hjxilinx 已提交
4719

4720 4721 4722
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
4723

H
hjxilinx 已提交
4724 4725 4726
  tVariantList* pKeep = pCreateDb->keep;
  if (pKeep != NULL) {
    switch (pKeep->nExpr) {
S
slguan 已提交
4727
      case 1:
H
hjxilinx 已提交
4728
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
4729 4730
        break;
      case 2: {
H
hjxilinx 已提交
4731 4732
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl(pKeep->a[1].pVar.i64Key);
4733 4734 4735
        break;
      }
      case 3: {
H
hjxilinx 已提交
4736 4737 4738
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl(pKeep->a[1].pVar.i64Key);
        pMsg->daysToKeep2 = htonl(pKeep->a[2].pVar.i64Key);
4739 4740
        break;
      }
4741
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
4742 4743
    }
  }
H
hjxilinx 已提交
4744

H
hjxilinx 已提交
4745 4746
  return TSDB_CODE_SUCCESS;
}
4747

4748
static int32_t setTimePrecisionOption(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDbInfo) {
H
hjxilinx 已提交
4749
  const char* msg = "invalid time precision";
H
hjxilinx 已提交
4750

H
hjxilinx 已提交
4751
  pMsg->precision = TSDB_TIME_PRECISION_MILLI;  // millisecond by default
H
hjxilinx 已提交
4752

H
hjxilinx 已提交
4753
  SSQLToken* pToken = &pCreateDbInfo->precision;
4754 4755
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
4756

4757 4758 4759 4760 4761
    if (strncmp(pToken->z, TSDB_TIME_PRECISION_MILLI_STR, pToken->n) == 0 &&
        strlen(TSDB_TIME_PRECISION_MILLI_STR) == pToken->n) {
      // time precision for this db: million second
      pMsg->precision = TSDB_TIME_PRECISION_MILLI;
    } else if (strncmp(pToken->z, TSDB_TIME_PRECISION_MICRO_STR, pToken->n) == 0 &&
H
hjxilinx 已提交
4762
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
4763 4764
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
4765
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
4766 4767
    }
  }
H
hjxilinx 已提交
4768

H
hjxilinx 已提交
4769 4770
  return TSDB_CODE_SUCCESS;
}
4771

4772
static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
S
slguan 已提交
4773
  pMsg->blocksPerTable = htons(pCreateDb->numOfBlocksPerTable);
H
hjxilinx 已提交
4774 4775
  pMsg->compression = pCreateDb->compressionLevel;

H
hjxilinx 已提交
4776
  pMsg->commitLog = (char)pCreateDb->commitLog;
H
hjxilinx 已提交
4777 4778 4779 4780 4781 4782 4783 4784 4785 4786
  pMsg->commitTime = htonl(pCreateDb->commitTime);
  pMsg->maxSessions = htonl(pCreateDb->tablesPerVnode);
  pMsg->cacheNumOfBlocks.fraction = pCreateDb->numOfAvgCacheBlocks;
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
  pMsg->rowsInFileBlock = htonl(pCreateDb->rowPerFileBlock);
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
  pMsg->replications = pCreateDb->replica;
}

int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) {
4787
  SCMCreateDbMsg* pMsg = (SCMCreateDbMsg*)(pCmd->payload);
H
hjxilinx 已提交
4788
  setCreateDBOption(pMsg, pCreateDbSql);
H
hjxilinx 已提交
4789

H
hjxilinx 已提交
4790 4791 4792
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
4793

H
hjxilinx 已提交
4794 4795 4796
  if (setTimePrecisionOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
4797

H
hjxilinx 已提交
4798 4799 4800
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
4801

4802
  return TSDB_CODE_SUCCESS;
H
huili 已提交
4803
}
S
slguan 已提交
4804

4805
void tscAddTimestampColumn(SQueryInfo* pQueryInfo, int16_t functionId, int16_t tableIndex) {
S
slguan 已提交
4806 4807
  // the first column not timestamp column, add it
  SSqlExpr* pExpr = NULL;
4808 4809
  if (pQueryInfo->exprsInfo.numOfExprs > 0) {
    pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4810 4811 4812 4813 4814
  }

  if (pExpr == NULL || pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX || pExpr->functionId != functionId) {
    SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};

4815
    pExpr = tscSqlExprInsert(pQueryInfo, 0, functionId, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE);
S
slguan 已提交
4816 4817 4818 4819 4820
    pExpr->colInfo.flag = TSDB_COL_NORMAL;

    // NOTE: tag column does not add to source column list
    SColumnList ids = getColumnList(1, tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX);

H
hjxilinx 已提交
4821
    insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, "ts", pExpr);
S
slguan 已提交
4822 4823 4824
  }
}

4825 4826
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
4827

4828 4829
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
4830 4831
    int32_t     num = pQueryInfo->exprsInfo.numOfExprs;

4832
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, num - 1);
4833

S
slguan 已提交
4834
    if (pExpr->functionId != TSDB_FUNC_TAG) {
H
hjxilinx 已提交
4835
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
4836
      int16_t         columnInfo = tscGetJoinTagColIndexByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid);
4837
      SColumnIndex    index = {.tableIndex = 0, .columnIndex = columnInfo};
H
hjxilinx 已提交
4838
      SSchema*        pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
4839 4840 4841 4842 4843

      int16_t type = pSchema[index.columnIndex].type;
      int16_t bytes = pSchema[index.columnIndex].bytes;
      char*   name = pSchema[index.columnIndex].name;

H
hjxilinx 已提交
4844
      pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_TAG, &index, type, bytes,
4845
                               bytes);
S
slguan 已提交
4846 4847 4848 4849
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
      SColumnList ids = {0};
H
hjxilinx 已提交
4850
      insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, &ids, bytes, type, name, pExpr);
S
slguan 已提交
4851 4852 4853 4854

      int32_t relIndex = index.columnIndex;

      pExpr->colInfo.colIdx = relIndex;
4855
      pQueryInfo->groupbyExpr.columnInfo[0].colIdx = relIndex;
S
slguan 已提交
4856

4857
      addRequiredTagColumn(pQueryInfo, pQueryInfo->groupbyExpr.columnInfo[0].colIdx, 0);
S
slguan 已提交
4858 4859 4860 4861
    }
  }
}

H
hjxilinx 已提交
4862 4863 4864
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
4865
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
4866 4867 4868
  pExpr->numOfParams = 1;
}

4869 4870
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
  int32_t index = pQueryInfo->groupbyExpr.columnInfo[tagIndex].colIdx;
S
slguan 已提交
4871

H
hjxilinx 已提交
4872
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
4873

H
hjxilinx 已提交
4874
  SSchema*     pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index);
S
slguan 已提交
4875 4876
  SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = index};

H
hjxilinx 已提交
4877
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_PRJ, &colIndex,
4878
                                     pSchema->type, pSchema->bytes, pSchema->bytes);
S
slguan 已提交
4879 4880

  pExpr->colInfo.flag = TSDB_COL_NORMAL;
H
hjxilinx 已提交
4881
  doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
4882

S
slguan 已提交
4883 4884 4885 4886 4887
  // NOTE: tag column does not add to source column list
  SColumnList list = {0};
  list.num = 1;
  list.ids[0] = colIndex;

H
hjxilinx 已提交
4888
  insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs - 1, &list, pSchema->bytes, pSchema->type,
H
hjxilinx 已提交
4889
                    pSchema->name, pExpr);
H
hjxilinx 已提交
4890
  tscFieldInfoUpdateVisible(&pQueryInfo->fieldsInfo, pQueryInfo->exprsInfo.numOfExprs - 1, false);
S
slguan 已提交
4891 4892
}

4893
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4894
  int32_t tagLength = 0;
H
hjxilinx 已提交
4895
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4896
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4897 4898 4899 4900 4901 4902 4903 4904 4905
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ || pExpr->functionId == TSDB_FUNC_TAG) {
      pExpr->functionId = TSDB_FUNC_TAG_DUMMY;
      tagLength += pExpr->resBytes;
    } else if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
      pExpr->functionId = TSDB_FUNC_TS_DUMMY;
      tagLength += pExpr->resBytes;
    }
  }

H
hjxilinx 已提交
4906
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
4907
  SSchema*        pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
4908

H
hjxilinx 已提交
4909
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4910
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4911
    if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) {
S
slguan 已提交
4912
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIdx];
S
slguan 已提交
4913 4914 4915 4916 4917 4918
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, pExpr->param[0].i64Key, &pExpr->resType,
                        &pExpr->resBytes, &pExpr->interResBytes, tagLength, true);
    }
  }
}

4919
static void doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
4920
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4921
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
4922 4923
    if (pExpr->functionId == TSDB_FUNC_PRJ) {
      bool qualifiedCol = false;
4924 4925
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
        if (pExpr->colInfo.colId == pQueryInfo->groupbyExpr.columnInfo[j].colId) {
H
hjxilinx 已提交
4926
          qualifiedCol = true;
H
hjxilinx 已提交
4927
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
4928 4929 4930 4931
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
4932

H
hjxilinx 已提交
4933 4934 4935 4936 4937
      assert(qualifiedCol);
    }
  }
}

S
slguan 已提交
4938 4939 4940 4941 4942 4943 4944 4945 4946 4947
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
    if (columnId == pGroupbyExpr->columnInfo[j].colId && pGroupbyExpr->columnInfo[j].flag == TSDB_COL_TAG) {
      return true;
    }
  }

  return false;
}

4948
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4949 4950 4951
  bool hasTagPrj = false;
  bool hasColumnPrj = false;

H
hjxilinx 已提交
4952
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4953
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964
    if (pExpr->functionId == TSDB_FUNC_PRJ) {
      hasColumnPrj = true;
    } else if (pExpr->functionId == TSDB_FUNC_TAGPRJ) {
      hasTagPrj = true;
    }
  }

  return (hasTagPrj) && (hasColumnPrj == false);
}

// check if all the tags prj columns belongs to the group by columns
4965
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4966 4967
  bool allInGroupby = true;

H
hjxilinx 已提交
4968
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4969
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4970 4971 4972 4973
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

4974
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
4975 4976 4977 4978 4979 4980 4981 4982 4983
      allInGroupby = false;
      break;
    }
  }

  // all selected tag columns belong to the group by columns set, always correct
  return allInGroupby;
}

4984
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
4985
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4986
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ) {
      pExpr->functionId = TSDB_FUNC_TAG;
    }
  }
}

/*
 * check for selectivity function + tags column function both exist.
 * 1. tagprj functions are not compatible with aggregated function when missing "group by" clause
 * 2. if selectivity function and tagprj function both exist, there should be only
 *    one selectivity function exists.
 */
4999
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5000
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5001
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5002

S
slguan 已提交
5003 5004 5005 5006
  bool    tagColExists = false;
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5007
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
5008
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5009 5010 5011 5012 5013 5014
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
      tagColExists = true;
      break;
    }
  }
H
hjxilinx 已提交
5015

H
hjxilinx 已提交
5016
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
5017
    int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
5018
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5019
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5020
      continue;
S
slguan 已提交
5021
    }
H
hjxilinx 已提交
5022

H
hjxilinx 已提交
5023 5024 5025 5026 5027 5028
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5029

H
hjxilinx 已提交
5030
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5031 5032
    // When the tag projection function on tag column that is not in the group by clause, aggregation function and
    // selectivity function exist in select clause is not allowed.
5033
    if (numOfAggregation > 0) {
5034
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5035 5036 5037 5038 5039 5040
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5041 5042
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5043 5044 5045 5046 5047
    } else if (numOfSelectivity > 1) {
      /*
       * If more than one selectivity functions exist, all the selectivity functions must be last_row.
       * Otherwise, return with error code.
       */
H
hjxilinx 已提交
5048
      for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
5049
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5050 5051 5052 5053 5054
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5055
          return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5056 5057 5058
        }
      }

5059 5060
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5061 5062
    }
  } else {
5063 5064 5065
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) == TSDB_QUERY_TYPE_PROJECTION_QUERY) {
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
        return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hjxilinx 已提交
5066
      }
H
hjxilinx 已提交
5067

H
hjxilinx 已提交
5068 5069
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5070 5071
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5072
      }
S
slguan 已提交
5073 5074 5075 5076 5077 5078
    }
  }

  return TSDB_CODE_SUCCESS;
}

5079
static int32_t doAddGroupbyColumnsOnDemand(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5080 5081
  const char* msg2 = "interval not allowed in group by normal column";

H
hjxilinx 已提交
5082
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
5083

H
hjxilinx 已提交
5084
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5085 5086 5087 5088
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5089 5090
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
    SColIndexEx* pColIndex = &pQueryInfo->groupbyExpr.columnInfo[i];
S
slguan 已提交
5091 5092 5093 5094

    int16_t colIndex = pColIndex->colIdx;
    if (pColIndex->colIdx == TSDB_TBNAME_COLUMN_INDEX) {
      type = TSDB_DATA_TYPE_BINARY;
S
slguan 已提交
5095
      bytes = TSDB_TABLE_NAME_LEN;
S
slguan 已提交
5096 5097
      name = TSQL_TBNAME_L;
    } else {
H
hjxilinx 已提交
5098
      colIndex = (TSDB_COL_IS_TAG(pColIndex->flag)) ? tscGetNumOfColumns(pTableMetaInfo->pTableMeta) + pColIndex->colIdx
S
slguan 已提交
5099 5100 5101 5102 5103 5104 5105 5106
                                                    : pColIndex->colIdx;

      type = pSchema[colIndex].type;
      bytes = pSchema[colIndex].bytes;
      name = pSchema[colIndex].name;
    }

    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5107
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
S
slguan 已提交
5108

H
hjxilinx 已提交
5109
      SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_TAG, &index,
5110
                                         type, bytes, bytes);
S
slguan 已提交
5111 5112 5113 5114 5115

      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
      SColumnList ids = {0};
H
hjxilinx 已提交
5116
      insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs-1, &ids, bytes, type, name, pExpr);
S
slguan 已提交
5117 5118
    } else {
      // if this query is "group by" normal column, interval is not allowed
5119
      if (pQueryInfo->intervalTime > 0) {
5120
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
5121 5122 5123
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5124
      for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) {
5125
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5126 5127 5128 5129 5130 5131 5132 5133 5134 5135
        if (pExpr->colInfo.colId == pColIndex->colId) {
          break;
        }
      }

      /*
       * if the group by column does not required by user, add this column into the final result set
       * but invisible to user
       */
      if (!hasGroupColumn) {
5136
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5137 5138 5139 5140 5141 5142 5143
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5144
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5145
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5146
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5147
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5148
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5149 5150 5151

  // only retrieve tags, group by is not supportted
  if (pCmd->command == TSDB_SQL_RETRIEVE_TAGS) {
5152
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5153
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5154 5155 5156 5157 5158
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5159
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5160
    // check if all the tags prj columns belongs to the group by columns
5161 5162 5163
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
      return doAddGroupbyColumnsOnDemand(pQueryInfo);
S
slguan 已提交
5164 5165 5166
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5167
    for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
5168
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5169 5170 5171 5172 5173 5174
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5175
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5176
        bool qualified = false;
5177 5178
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
          SColIndexEx* pColIndex = &pQueryInfo->groupbyExpr.columnInfo[j];
S
slguan 已提交
5179 5180 5181 5182 5183 5184 5185
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5186
          return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
5187 5188 5189 5190
        }
      }

      if (IS_MULTIOUTPUT(aAggs[functId].nStatus) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM &&
H
hjxilinx 已提交
5191
          functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) {
5192
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5193 5194 5195
      }

      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX) {
5196
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5197 5198 5199
      }
    }

5200
    if (checkUpdateTagPrjFunctions(pQueryInfo) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
5201 5202 5203 5204 5205 5206 5207
      return TSDB_CODE_INVALID_SQL;
    }

    /*
     * group by tag function must be not changed the function name, otherwise, the group operation may fail to
     * divide the subset of final result.
     */
5208
    if (doAddGroupbyColumnsOnDemand(pQueryInfo) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
5209 5210 5211 5212
      return TSDB_CODE_INVALID_SQL;
    }

    // projection query on metric does not compatible with "group by" syntax
5213
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5214
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5215
    }
H
hjxilinx 已提交
5216

H
hjxilinx 已提交
5217
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5218
  } else {
5219
    return checkUpdateTagPrjFunctions(pQueryInfo);
S
slguan 已提交
5220 5221
  }
}
H
hjxilinx 已提交
5222

5223
int32_t doLocalQueryProcess(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5224 5225 5226
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5227

H
hjxilinx 已提交
5228 5229
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5230
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hjxilinx 已提交
5231
  }
H
hjxilinx 已提交
5232

H
hjxilinx 已提交
5233 5234
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5235
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hjxilinx 已提交
5236
  }
H
hjxilinx 已提交
5237

H
hjxilinx 已提交
5238
  // TODO redefine the function
H
hjxilinx 已提交
5239 5240 5241 5242 5243 5244
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5245
  int32_t index = -1;
H
hjxilinx 已提交
5246
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5247
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5248
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5249 5250 5251 5252
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5253

5254
  SSqlExpr* pExpr1 = tscSqlExprInsertEmpty(pQueryInfo, 0, TSDB_FUNC_TAG_DUMMY);
H
hjxilinx 已提交
5255 5256
  const char* name = (pExprList->a[0].aliasName != NULL)? pExprList->a[0].aliasName:functionsInfo[index].name;
  strncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
hjxilinx 已提交
5257 5258 5259

  switch (index) {
    case 0:
5260
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;
H
hjxilinx 已提交
5261 5262
      return TSDB_CODE_SUCCESS;
    case 1:
5263
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;
H
hjxilinx 已提交
5264 5265
      return TSDB_CODE_SUCCESS;
    case 2:
5266
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;
H
hjxilinx 已提交
5267 5268
      return TSDB_CODE_SUCCESS;
    case 3:
5269
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;
H
hjxilinx 已提交
5270 5271
      return TSDB_CODE_SUCCESS;
    case 4:
5272
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;
H
hjxilinx 已提交
5273
      return TSDB_CODE_SUCCESS;
5274
    default: { return invalidSqlErrMsg(pQueryInfo->msg, msg3); }
H
hjxilinx 已提交
5275 5276
  }
}
H
hjxilinx 已提交
5277 5278

// can only perform the parameters based on the macro definitation
5279
int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate) {
H
hjxilinx 已提交
5280
  char msg[512] = {0};
H
hjxilinx 已提交
5281

H
hjxilinx 已提交
5282 5283
  if (pCreate->commitLog != -1 && (pCreate->commitLog < 0 || pCreate->commitLog > 1)) {
    snprintf(msg, tListLen(msg), "invalid db option commitLog: %d, only 0 or 1 allowed", pCreate->commitLog);
5284
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5285
  }
H
hjxilinx 已提交
5286

H
hjxilinx 已提交
5287 5288
  if (pCreate->replications != -1 &&
      (pCreate->replications < TSDB_REPLICA_MIN_NUM || pCreate->replications > TSDB_REPLICA_MAX_NUM)) {
H
hjxilinx 已提交
5289 5290
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
             TSDB_REPLICA_MIN_NUM, TSDB_REPLICA_MAX_NUM);
5291
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5292
  }
H
hjxilinx 已提交
5293

H
hjxilinx 已提交
5294 5295 5296 5297
  int32_t val = htonl(pCreate->daysPerFile);
  if (val != -1 && (val < TSDB_FILE_MIN_PARTITION_RANGE || val > TSDB_FILE_MAX_PARTITION_RANGE)) {
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
             TSDB_FILE_MIN_PARTITION_RANGE, TSDB_FILE_MAX_PARTITION_RANGE);
5298
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5299
  }
H
hjxilinx 已提交
5300

H
hjxilinx 已提交
5301 5302 5303 5304
  val = htonl(pCreate->rowsInFileBlock);
  if (val != -1 && (val < TSDB_MIN_ROWS_IN_FILEBLOCK || val > TSDB_MAX_ROWS_IN_FILEBLOCK)) {
    snprintf(msg, tListLen(msg), "invalid db option rowsInFileBlock: %d valid range: [%d, %d]", val,
             TSDB_MIN_ROWS_IN_FILEBLOCK, TSDB_MAX_ROWS_IN_FILEBLOCK);
5305
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5306
  }
H
hjxilinx 已提交
5307

H
hjxilinx 已提交
5308 5309 5310 5311
  val = htonl(pCreate->cacheBlockSize);
  if (val != -1 && (val < TSDB_MIN_CACHE_BLOCK_SIZE || val > TSDB_MAX_CACHE_BLOCK_SIZE)) {
    snprintf(msg, tListLen(msg), "invalid db option cacheBlockSize: %d valid range: [%d, %d]", val,
             TSDB_MIN_CACHE_BLOCK_SIZE, TSDB_MAX_CACHE_BLOCK_SIZE);
5312
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5313
  }
H
hjxilinx 已提交
5314

H
hjxilinx 已提交
5315 5316
  val = htonl(pCreate->maxSessions);
  if (val != -1 && (val < TSDB_MIN_TABLES_PER_VNODE || val > TSDB_MAX_TABLES_PER_VNODE)) {
H
hjxilinx 已提交
5317 5318
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
             TSDB_MIN_TABLES_PER_VNODE, TSDB_MAX_TABLES_PER_VNODE);
5319
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5320
  }
H
hjxilinx 已提交
5321 5322 5323 5324

  if (pCreate->precision != TSDB_TIME_PRECISION_MILLI && pCreate->precision != TSDB_TIME_PRECISION_MICRO) {
    snprintf(msg, tListLen(msg), "invalid db option timePrecision: %d valid value: [%d, %d]", pCreate->precision,
             TSDB_TIME_PRECISION_MILLI, TSDB_TIME_PRECISION_MICRO);
5325
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5326
  }
H
hjxilinx 已提交
5327

H
hjxilinx 已提交
5328
  if (pCreate->cacheNumOfBlocks.fraction != -1 && (pCreate->cacheNumOfBlocks.fraction < TSDB_MIN_AVG_BLOCKS ||
H
hjxilinx 已提交
5329 5330 5331
                                                   pCreate->cacheNumOfBlocks.fraction > TSDB_MAX_AVG_BLOCKS)) {
    snprintf(msg, tListLen(msg), "invalid db option ablocks: %f valid value: [%d, %d]",
             pCreate->cacheNumOfBlocks.fraction, TSDB_MIN_AVG_BLOCKS, TSDB_MAX_AVG_BLOCKS);
5332
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5333
  }
H
hjxilinx 已提交
5334

H
hjxilinx 已提交
5335 5336 5337 5338
  val = htonl(pCreate->commitTime);
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME_INTERVAL || val > TSDB_MAX_COMMIT_TIME_INTERVAL)) {
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
             TSDB_MIN_COMMIT_TIME_INTERVAL, TSDB_MAX_COMMIT_TIME_INTERVAL);
5339
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5340
  }
H
hjxilinx 已提交
5341

H
hjxilinx 已提交
5342 5343
  if (pCreate->compression != -1 &&
      (pCreate->compression < TSDB_MIN_COMPRESSION_LEVEL || pCreate->compression > TSDB_MAX_COMPRESSION_LEVEL)) {
H
hjxilinx 已提交
5344 5345
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
             TSDB_MIN_COMPRESSION_LEVEL, TSDB_MAX_COMPRESSION_LEVEL);
5346
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5347
  }
H
hjxilinx 已提交
5348

H
hjxilinx 已提交
5349 5350
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5351 5352

// for debug purpose
H
hjxilinx 已提交
5353 5354
void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) {
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
5355

H
hjxilinx 已提交
5356
  if (pQueryInfo->exprsInfo.numOfExprs == 0) {
H
hjxilinx 已提交
5357 5358
    return;
  }
H
hjxilinx 已提交
5359

H
hjxilinx 已提交
5360
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5361 5362

  char    str[1024] = {0};
H
hjxilinx 已提交
5363
  int32_t offset = 0;
H
hjxilinx 已提交
5364

H
hjxilinx 已提交
5365
  offset += sprintf(str, "num:%d [", pQueryInfo->exprsInfo.numOfExprs);
5366 5367
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5368

L
lihui 已提交
5369
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5370 5371 5372
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5373 5374 5375
    if (tmpLen + offset > totalBufSize) break;

    offset += sprintf(str + offset, "%s", tmpBuf);
H
hjxilinx 已提交
5376

5377
    if (i < pQueryInfo->exprsInfo.numOfExprs - 1) {
H
hjxilinx 已提交
5378 5379 5380
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5381

H
hjxilinx 已提交
5382
  str[offset] = ']';
H
hjxilinx 已提交
5383
  tscTrace("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5384
}
5385

5386
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5387 5388 5389
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5390 5391
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5392
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;

  tFieldList* pFieldList = pCreateTable->colInfo.pColumns;
  tFieldList* pTagList = pCreateTable->colInfo.pTagColumns;

  assert(pFieldList != NULL);

  // if sql specifies db, use it, otherwise use default db
  SSQLToken* pzTableName = &(pCreateTable->name);

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5405
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5406 5407
  }

H
hjxilinx 已提交
5408
  if (setMeterID(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5409
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5410 5411 5412 5413 5414 5415 5416 5417 5418
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
    return TSDB_CODE_INVALID_SQL;
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
5419
    tscFieldInfoSetValFromField(&pQueryInfo->fieldsInfo, col, &pFieldList->p[col]);
5420 5421 5422 5423 5424 5425
  }

  pCmd->numOfCols = (int16_t)pFieldList->nField;

  if (pTagList != NULL) {  // create metric[optional]
    for (int32_t i = 0; i < pTagList->nField; ++i) {
5426
      tscFieldInfoSetValFromField(&pQueryInfo->fieldsInfo, col++, &pTagList->p[i]);
5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443
    }

    pCmd->count = pTagList->nField;
  }

  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
  const char* msg1 = "invalid table name";
  const char* msg3 = "tag value too long";
  const char* msg4 = "illegal value or data overflow";
  const char* msg5 = "tags number not matched";

  SSqlCmd* pCmd = &pSql->cmd;

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
5444 5445 5446
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
5447 5448 5449
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
5450 5451 5452 5453

  const int32_t TABLE_INDEX = 0;
  const int32_t STABLE_INDEX = 1;

H
hjxilinx 已提交
5454
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5455 5456 5457 5458 5459

  // super table name, create table by using dst
  SSQLToken* pToken = &(pCreateTable->usingInfo.stableName);

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5460
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5461 5462
  }

5463
  if (setMeterID(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5464
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5465 5466 5467
  }

  // get meter meta from mnode
S
slguan 已提交
5468
  strncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, TSDB_TABLE_ID_LEN);
5469 5470
  tVariantList* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;

H
hjxilinx 已提交
5471
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5472 5473 5474 5475
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5476
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5477
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5478 5479 5480
  }

  // too long tag values will return invalid sql, not be truncated automatically
H
hjxilinx 已提交
5481
  SSchema* pTagSchema = tscGetTableTagSchema(pStableMeterMetaInfo->pTableMeta);
5482 5483 5484 5485 5486

  char* tagVal = pCreateTable->usingInfo.tagdata.data;
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    int32_t ret = tVariantDump(&(pList->a[i].pVar), tagVal, pTagSchema[i].type);
    if (ret != TSDB_CODE_SUCCESS) {
5487
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5488 5489 5490 5491 5492
    }

    // validate the length of binary
    if ((pTagSchema[i].type == TSDB_DATA_TYPE_BINARY || pTagSchema[i].type == TSDB_DATA_TYPE_NCHAR) &&
        pList->a[i].pVar.nLen > pTagSchema[i].bytes) {
5493
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
5494 5495 5496 5497 5498 5499 5500
    }

    tagVal += pTagSchema[i].bytes;
  }

  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5501
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5502 5503
  }

H
hjxilinx 已提交
5504
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
5505
  int32_t         ret = setMeterID(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";
  const char* msg3 = "fill only available for interval query";
  const char* msg4 = "fill option not supported in stream computing";
  const char* msg5 = "sql too long";  // todo ADD support

5520
  SSqlCmd*    pCmd = &pSql->cmd;
5521
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5522 5523
  assert(pQueryInfo->numOfTables == 1);

5524
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5525
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5526 5527 5528 5529 5530 5531

  // if sql specifies db, use it, otherwise use default db
  SSQLToken* pzTableName = &(pCreateTable->name);
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5532
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5533 5534 5535 5536 5537 5538 5539
  }

  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
  tVariant*     pVar = &pSrcMeterName->a[0].pVar;

  SSQLToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
5540
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
5541 5542
  }

H
hjxilinx 已提交
5543
  if (setMeterID(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5544
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
5545 5546
  }

H
hjxilinx 已提交
5547
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5548 5549 5550 5551
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5552
  bool isSTable = UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo);
5553
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5554 5555 5556 5557
    return TSDB_CODE_INVALID_SQL;
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5558
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5559 5560 5561 5562 5563
      return TSDB_CODE_INVALID_SQL;
    }
  }

  // set interval value
5564
  if (parseIntervalClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5565 5566
    return TSDB_CODE_INVALID_SQL;
  } else {
5567
    if ((pQueryInfo->intervalTime > 0) &&
5568
        (validateFunctionsInIntervalOrGroupbyQuery(pQueryInfo) != TSDB_CODE_SUCCESS)) {
5569 5570 5571 5572 5573
      return TSDB_CODE_INVALID_SQL;
    }
  }

  // set the created table[stream] name
H
hjxilinx 已提交
5574
  if (setMeterID(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5575
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
5576 5577 5578
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5579
    return invalidSqlErrMsg(pQueryInfo->msg, msg5);
5580 5581
  }

5582
  if (tsRewriteFieldNameIfNecessary(pQueryInfo) != TSDB_CODE_SUCCESS) {
5583 5584 5585
    return TSDB_CODE_INVALID_SQL;
  }

5586
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutputCols;
5587

5588
  if (validateSqlFunctionInStreamSql(pQueryInfo) != TSDB_CODE_SUCCESS) {
5589 5590 5591 5592 5593 5594 5595 5596
    return TSDB_CODE_INVALID_SQL;
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
5597
    if (pQueryInfo->intervalTime == 0) {
5598
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
5599 5600 5601 5602 5603 5604
    }

    tVariantListItem* pItem = &pQuerySql->fillType->a[0];
    if (pItem->pVar.nType == TSDB_DATA_TYPE_BINARY) {
      if (!((strncmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) ||
            (strncmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4))) {
5605
        return invalidSqlErrMsg(pQueryInfo->msg, msg4);
5606 5607 5608 5609 5610
      }
    }
  }

  // set the number of stream table columns
5611
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutputCols;
5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
  assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0));

  const char* msg0 = "invalid table name";
  const char* msg1 = "table name too long";
  const char* msg2 = "point interpolation query needs timestamp";
  const char* msg5 = "fill only available for interval query";
  const char* msg6 = "start(end) time of query range required or time range too large";
  const char* msg7 = "illegal number of tables in from clause";
  const char* msg8 = "too many columns in selection clause";
  const char* msg9 = "TWA query requires both the start and end time";

  int32_t code = TSDB_CODE_SUCCESS;
5628

5629
  SSqlCmd* pCmd = &pSql->cmd;
5630

5631
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
5632
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5633
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
5634
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
5635
  }
H
hjxilinx 已提交
5636

5637 5638
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
5639
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651
  }

  /*
   * handle the sql expression without from subclause
   * select current_database();
   * select server_version();
   * select client_version();
   * select server_state();
   */
  if (pQuerySql->from == NULL) {
    assert(pQuerySql->fillType == NULL && pQuerySql->pGroupby == NULL && pQuerySql->pWhere == NULL &&
           pQuerySql->pSortOrder == NULL);
5652
    return doLocalQueryProcess(pQueryInfo, pQuerySql);
5653 5654 5655
  }

  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM) {
5656
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
5657 5658
  }

5659
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
5660

5661 5662 5663 5664 5665
  // set all query tables, which are maybe more than one.
  for (int32_t i = 0; i < pQuerySql->from->nExpr; ++i) {
    tVariant* pTableItem = &pQuerySql->from->a[i].pVar;

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
5666
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5667 5668 5669 5670 5671 5672
    }

    pTableItem->nLen = strdequote(pTableItem->pz);

    SSQLToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
5673
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5674 5675
    }

5676
    if (pQueryInfo->numOfTables <= i) {  // more than one table
H
hjxilinx 已提交
5677
      tscAddEmptyMetaInfo(pQueryInfo);
5678 5679
    }

H
hjxilinx 已提交
5680
    STableMetaInfo* pMeterInfo1 = tscGetMetaInfo(pQueryInfo, i);
5681

5682
    SSQLToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
5683
    if (setMeterID(pMeterInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
5684
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5685 5686
    }

H
hjxilinx 已提交
5687
    code = tscGetTableMeta(pSql, pMeterInfo1);
5688 5689 5690 5691 5692
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

5693
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr);
H
hjxilinx 已提交
5694 5695 5696 5697 5698 5699 5700
  
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
   int32_t code = tscGetSTableVgroupInfo(pSql, index);
   if (code != TSDB_CODE_SUCCESS) {
     return code;
   }
  }
5701

5702
  // parse the group by clause in the first place
5703
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
5704 5705 5706
    return TSDB_CODE_INVALID_SQL;
  }

H
hjxilinx 已提交
5707
  bool isSTable = UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo);
5708
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5709 5710 5711 5712
    return TSDB_CODE_INVALID_SQL;
  }

  // set interval value
5713
  if (parseIntervalClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5714 5715
    return TSDB_CODE_INVALID_SQL;
  } else {
5716
    if ((pQueryInfo->intervalTime > 0) &&
5717
        (validateFunctionsInIntervalOrGroupbyQuery(pQueryInfo) != TSDB_CODE_SUCCESS)) {
5718 5719 5720 5721 5722
      return TSDB_CODE_INVALID_SQL;
    }
  }

  // set order by info
H
hjxilinx 已提交
5723
  if (parseOrderbyClause(pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
5724 5725 5726 5727
    return TSDB_CODE_INVALID_SQL;
  }

  // set where info
H
hjxilinx 已提交
5728
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
5729
  
5730
  if (pQuerySql->pWhere != NULL) {
5731
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5732 5733 5734 5735
      return TSDB_CODE_INVALID_SQL;
    }

    pQuerySql->pWhere = NULL;
H
hjxilinx 已提交
5736
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
5737 5738
      pQueryInfo->stime = pQueryInfo->stime / 1000;
      pQueryInfo->etime = pQueryInfo->etime / 1000;
5739 5740
    }
  } else {  // set the time rang
5741 5742
    pQueryInfo->stime = 0;
    pQueryInfo->etime = INT64_MAX;
5743 5744 5745
  }

  // user does not specified the query time window, twa is not allowed in such case.
5746
  if ((pQueryInfo->stime == 0 || pQueryInfo->etime == INT64_MAX ||
H
hjxilinx 已提交
5747
       (pQueryInfo->etime == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
5748
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
5749 5750 5751
  }

  // no result due to invalid query time range
5752
  if (pQueryInfo->stime > pQueryInfo->etime) {
5753
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
5754 5755 5756
    return TSDB_CODE_SUCCESS;
  }

5757 5758
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
5759 5760 5761
  }

  // in case of join query, time range is required.
5762 5763
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    int64_t timeRange = labs(pQueryInfo->stime - pQueryInfo->etime);
5764

5765 5766
    if (timeRange == 0 && pQueryInfo->stime == 0) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
5767 5768 5769
    }
  }

5770
  if ((code = parseLimitClause(pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
5771 5772 5773
    return code;
  }

5774
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
5775 5776 5777
    return code;
  }

5778
  setColumnOffsetValueInResultset(pQueryInfo);
5779

5780 5781
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
    updateTagColumnIndex(pQueryInfo, i);
5782
  }
H
hjxilinx 已提交
5783

5784 5785 5786 5787 5788
  /*
   * fill options are set at the end position, when all columns are set properly
   * the columns may be increased due to group by operation
   */
  if (pQuerySql->fillType != NULL) {
5789
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
5790 5791
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
5792

5793
    if (pQueryInfo->intervalTime > 0) {
5794 5795
      int64_t timeRange = labs(pQueryInfo->stime - pQueryInfo->etime);
      // number of result is not greater than 10,000,000
5796
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_RETRIEVE_ROWS_IN_INTERVAL_QUERY) {
5797 5798 5799
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
      }
    }
H
hjxilinx 已提交
5800

5801 5802 5803 5804 5805
    int32_t ret = parseFillClause(pQueryInfo, pQuerySql);
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
5806 5807 5808

  return TSDB_CODE_SUCCESS;  // Does not build query message here
}
H
hjxilinx 已提交
5809

H
hjxilinx 已提交
5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842
static int32_t tSQLBinaryExprCreateFromSqlExpr(tSQLSyntaxNode **pExpr, tSQLExpr* pAst, int32_t* num,
    SColIndexEx** pColIndex, SSqlExprInfo* pExprInfo) {
  tSQLSyntaxNode* pLeft = NULL;
  tSQLSyntaxNode* pRight= NULL;
  
  if (pAst->pLeft != NULL) {
    int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pLeft, pAst->pLeft, num, pColIndex, pExprInfo);
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
  if (pAst->pRight != NULL) {
    int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pRight, pAst->pRight, num, pColIndex, pExprInfo);
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
  if (pAst->pLeft == NULL) {
    if (pAst->nSQLOptr >= TK_TINYINT && pAst->nSQLOptr <= TK_DOUBLE) {
      *pExpr = calloc(1, sizeof(tSQLSyntaxNode) + sizeof(tVariant));
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
      (*pExpr)->pVal = (tVariant*) ((char*)(*pExpr) + sizeof(tSQLSyntaxNode));
      tVariantAssign((*pExpr)->pVal, &pAst->val);
    } else if (pAst->nSQLOptr >= TK_COUNT && pAst->nSQLOptr <= TK_AVG_IRATE) {
      *pExpr = calloc(1, sizeof(tSQLSyntaxNode) + sizeof(SSchemaEx));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = (SSchema*)((char*)(*pExpr) + sizeof(tSQLSyntaxNode));
      strncpy((*pExpr)->pSchema->name, pAst->operand.z, pAst->operand.n);

      // set the input column data byte and type.
      for (int32_t i = 0; i < pExprInfo->numOfExprs; ++i) {
H
hjxilinx 已提交
5843 5844 5845
        if (strcmp((*pExpr)->pSchema->name, pExprInfo->pExprs[i]->aliasName) == 0) {
          (*pExpr)->pSchema->type = pExprInfo->pExprs[i]->resType;
          (*pExpr)->pSchema->bytes = pExprInfo->pExprs[i]->resBytes;
H
hjxilinx 已提交
5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885
          break;
        }
      }
    } else { //todo return error
      return TSDB_CODE_SUCCESS;
    }
    
    (*pExpr)->colId = -1;
    
    *pColIndex = realloc(*pColIndex, (++(*num)) * sizeof(SColIndexEx));
    memset(&(*pColIndex)[(*num) - 1], 0, sizeof(SColIndexEx));
    
    strncpy((*pColIndex)[(*num) - 1].name, pAst->operand.z, pAst->operand.n);
  } else {
    tSQLBinaryExpr *pBinExpr = (tSQLBinaryExpr *)calloc(1, sizeof(tSQLBinaryExpr));
    pBinExpr->filterOnPrimaryKey = false;
    pBinExpr->pLeft = pLeft;
    pBinExpr->pRight = pRight;
    SSQLToken t = {.type = pAst->nSQLOptr};
    pBinExpr->nSQLBinaryOptr = getBinaryExprOptr(&t);
  
    assert(pBinExpr->nSQLBinaryOptr != 0);
    
    (*pExpr) = malloc(sizeof(tSQLSyntaxNode));
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    (*pExpr)->pExpr = pBinExpr;
    (*pExpr)->colId = -1;
  
    if (pBinExpr->nSQLBinaryOptr == TSDB_BINARY_OP_DIVIDE) {
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
          return TSDB_CODE_INVALID_SQL;
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
          return TSDB_CODE_INVALID_SQL;
        }
      }
    }
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
5886
}