tscSQLParser.c 199.3 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);
212
  assert(pQueryInfo->numOfTables == 0);
H
hjxilinx 已提交
213

H
hjxilinx 已提交
214
  STableMetaInfo* pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
215

216 217 218 219 220 221 222 223
  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: {
224 225
      const char* msg1 = "invalid ip address";
      const char* msg2 = "invalid name";
226
      const char* msg3 = "param name too long";
H
hzcheng 已提交
227 228

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

233 234
      if (pInfo->type == TSDB_SQL_DROP_DB) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
235

H
hjxilinx 已提交
236
        code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pzName, NULL, NULL);
H
hzcheng 已提交
237
        if (code != TSDB_CODE_SUCCESS) {
238
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
239 240
        }

241 242
      } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
243

H
hjxilinx 已提交
244
        if (setMeterID(pTableMetaInfo, pzName, pSql) != TSDB_CODE_SUCCESS) {
245
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
246
        }
247 248
      } else if (pInfo->type == TSDB_SQL_DROP_DNODE) {
        if (!validateIpAddress(pzName->z, pzName->n)) {
249
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
250 251
        }

H
hjxilinx 已提交
252
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
253 254
      } else {  // drop user
        if (pzName->n > TSDB_USER_LEN) {
255
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
256 257
        }

H
hjxilinx 已提交
258
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
259 260
      }

261 262
      break;
    }
H
hzcheng 已提交
263

264 265 266
    case TSDB_SQL_USE_DB: {
      const char* msg = "invalid db name";
      SSQLToken*  pToken = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
267 268

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
269
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
270 271
      }

H
hjxilinx 已提交
272
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pToken, NULL, NULL);
H
hzcheng 已提交
273
      if (ret != TSDB_CODE_SUCCESS) {
274
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
275 276 277 278 279
      }

      break;
    }

280 281
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
282 283
    }

284 285 286
    case TSDB_SQL_SHOW: {
      if (setShowInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
287 288
      }

289 290 291 292 293 294 295 296
      break;
    }

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

297
      SCreateDBInfo* pCreateDB = &(pInfo->pDCLInfo->dbOpt);
H
hzcheng 已提交
298
      if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) {
299
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
300 301
      }

H
hjxilinx 已提交
302
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname), NULL, NULL);
H
hzcheng 已提交
303
      if (ret != TSDB_CODE_SUCCESS) {
304
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
305 306
      }

H
hjxilinx 已提交
307
      if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
308
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
309 310 311 312 313
      }

      break;
    }

314
    case TSDB_SQL_CREATE_DNODE: {  // todo parse hostname
S
slguan 已提交
315 316
      const char* msg = "invalid ip address";

317
      if (pInfo->pDCLInfo->nTokens > 1) {
318
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
319 320
      }

321 322
      SSQLToken* pIpAddr = &pInfo->pDCLInfo->a[0];
      if (!validateIpAddress(pIpAddr->z, pIpAddr->n)) {
323
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
324 325 326 327 328
      }

      break;
    }

329 330 331 332 333
    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 已提交
334

335 336
      SSQLToken* pName = &pInfo->pDCLInfo->user.user;
      SSQLToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
337

338 339
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
        return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
340 341
      }

342
      if (pName->n > TSDB_USER_LEN) {
343
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
344 345
      }

346
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
347
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
348 349 350
      }

      SCreateAcctSQL* pAcctOpt = &pInfo->pDCLInfo->acctOpt;
351
      if (pAcctOpt->stat.n > 0) {
H
hzcheng 已提交
352 353 354 355 356
        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 {
357
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
358 359
        }
      }
360

H
hzcheng 已提交
361 362 363
      break;
    }

364
    case TSDB_SQL_DESCRIBE_TABLE: {
S
slguan 已提交
365
      SSQLToken*  pToken = &pInfo->pDCLInfo->a[0];
366
      const char* msg2 = "table name is too long";
H
hjxilinx 已提交
367
      const char* msg1 = "invalid table name";
H
hzcheng 已提交
368

S
slguan 已提交
369
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
370
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
371
      }
S
slguan 已提交
372

S
slguan 已提交
373
      if (pToken->n > TSDB_TABLE_NAME_LEN) {
374
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
375 376
      }

H
hjxilinx 已提交
377
      if (setMeterID(pTableMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
378
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
379 380
      }

H
hjxilinx 已提交
381
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
382 383
    }

384
    case TSDB_SQL_CFG_DNODE: {
385 386
      const char* msg1 = "invalid ip address";
      const char* msg2 = "invalid configure options or values";
H
hzcheng 已提交
387

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

394 395
      /* validate the parameter names and options */
      if (validateDNodeConfig(pDCL) != TSDB_CODE_SUCCESS) {
396
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
397 398
      }

399 400
      char* pMsg = pCmd->payload + tsRpcHeadSize;
      pMsg += sizeof(SMgmtHead);
H
hzcheng 已提交
401

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

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

407 408 409 410
      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 已提交
411

412 413
      break;
    }
H
hzcheng 已提交
414

415 416 417 418 419 420
    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 已提交
421

422
      pCmd->command = pInfo->type;
H
hjxilinx 已提交
423
      // tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
424

425 426 427
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
      SSQLToken* pName = &pUser->user;
      SSQLToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
428

429
      if (pName->n > TSDB_USER_LEN) {
430
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
431
      }
H
hzcheng 已提交
432

433
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
434
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
435
      }
H
hzcheng 已提交
436

437 438 439 440 441 442 443 444
      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 已提交
445
          }
446
        } else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
L
lihui 已提交
447 448 449
          assert(pPwd->type == TSDB_DATA_TYPE_NULL);

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

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

H
hzcheng 已提交
465 466
      break;
    }
467 468

    case TSDB_SQL_CFG_LOCAL: {
S
slguan 已提交
469 470 471 472 473
      tDCLSQL*    pDCL = pInfo->pDCLInfo;
      const char* msg = "invalid configure options or values";

      // validate the parameter names and options
      if (validateLocalConfig(pDCL) != TSDB_CODE_SUCCESS) {
474
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
475 476 477 478 479 480 481
      }

      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 已提交
482 483 484 485

      break;
    }

486 487
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
488

489
      if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
490
        if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
491
          return code;
H
hzcheng 已提交
492 493
        }

494 495 496
      } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) {
        if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
497 498
        }

499 500 501
      } else if (pCreateTable->type == TSQL_CREATE_STREAM) {
        if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
S
slguan 已提交
502
        }
H
hzcheng 已提交
503 504 505 506 507
      }

      break;
    }

508
    case TSDB_SQL_SELECT: {
509
      assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
510
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
511

512
      for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) {
513 514 515 516
        SQueryInfo* pqi = NULL;
        if ((code = tscGetQueryInfoDetailSafely(pCmd, i, &pqi)) != TSDB_CODE_SUCCESS) {
          return code;
        }
517 518 519 520
      }

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

523 524
        if ((code = doCheckForQuery(pSql, pQuerySql, i)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
525
        }
H
hjxilinx 已提交
526

H
hjxilinx 已提交
527
        tscPrintSelectClause(pSql, i);
H
hzcheng 已提交
528
      }
H
hjxilinx 已提交
529

H
hjxilinx 已提交
530
      // set the command/global limit parameters from the first subclause to the sqlcmd object
531 532
      SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
      pCmd->command = pQueryInfo1->command;
H
hjxilinx 已提交
533

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

538 539 540
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
541
        }
542
      }
543 544

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

547 548 549
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
550 551 552 553 554
      }

      break;
    }

555 556 557 558
    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 已提交
559 560 561 562 563 564 565
        return code;
      }

      break;
    }

    default:
566
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
567 568
  }

569
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
570 571
}

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

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

S
slguan 已提交
585
  return false;
H
hzcheng 已提交
586 587
}

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

H
hjxilinx 已提交
592
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
593
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
594
  
H
hjxilinx 已提交
595
  if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
H
hzcheng 已提交
596 597 598 599 600
    return TSDB_CODE_SUCCESS;
  }

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

H
hjxilinx 已提交
605
  // if the unit of time window value is millisecond, change the value from microsecond
H
hjxilinx 已提交
606
  if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
607
    pQueryInfo->intervalTime = pQueryInfo->intervalTime / 1000;
H
hzcheng 已提交
608 609 610
  }

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

  // interval cannot be less than 10 milliseconds
614
  if (pQueryInfo->intervalTime < tsMinIntervalTime) {
615
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
616 617 618
  }

  // for top/bottom + interval query, we do not add additional timestamp column in the front
619
  if (isTopBottomQuery(pQueryInfo)) {
H
hjxilinx 已提交
620 621 622
    if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_INVALID_SQL;
    }
H
hjxilinx 已提交
623

H
hzcheng 已提交
624 625 626
    return TSDB_CODE_SUCCESS;
  }

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

H
hjxilinx 已提交
638 639 640
  /*
   * check invalid SQL:
   * select tbname, tags_fields from super_table_name interval(1s)
H
hjxilinx 已提交
641
   */
642
  if (tscQueryMetricTags(pQueryInfo) && pQueryInfo->intervalTime > 0) {
H
hjxilinx 已提交
643 644
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
  }
S
slguan 已提交
645 646

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

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

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

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

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

H
hjxilinx 已提交
667 668
  int32_t ret =
      insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hjxilinx 已提交
669 670 671
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }
H
hjxilinx 已提交
672

H
hjxilinx 已提交
673
  if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
674 675
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
676

H
hjxilinx 已提交
677
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
678 679
}

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

H
hjxilinx 已提交
684
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
685
  SSQLToken*      pSliding = &pQuerySql->sliding;
H
hjxilinx 已提交
686
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
687 688

  if (pSliding->n != 0) {
H
hjxilinx 已提交
689
    getTimestampInUsFromStr(pSliding->z, pSliding->n, &pQueryInfo->slidingTime);
H
hjxilinx 已提交
690
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
691
      pQueryInfo->slidingTime /= 1000;
H
hzcheng 已提交
692 693
    }

H
hjxilinx 已提交
694
    if (pQueryInfo->slidingTime < tsMinSlidingTime) {
695
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
696 697
    }

H
hjxilinx 已提交
698
    if (pQueryInfo->slidingTime > pQueryInfo->intervalTime) {
699
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
700
    }
H
hjxilinx 已提交
701
  } else {
H
hjxilinx 已提交
702
    pQueryInfo->slidingTime = pQueryInfo->intervalTime;
H
hzcheng 已提交
703 704 705 706 707
  }

  return TSDB_CODE_SUCCESS;
}

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

711 712
  SSqlCmd* pCmd = &pSql->cmd;
  int32_t  code = TSDB_CODE_SUCCESS;
S
slguan 已提交
713

H
hjxilinx 已提交
714 715
  // backup the old name in pTableMetaInfo
  size_t size = strlen(pTableMetaInfo->name);
H
hjxilinx 已提交
716
  char*  oldName = NULL;
717
  if (size > 0) {
H
hjxilinx 已提交
718
    oldName = strdup(pTableMetaInfo->name);
719
  }
H
hjxilinx 已提交
720

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

H
hjxilinx 已提交
728
    code = setObjFullName(pTableMetaInfo->name, NULL, &t, pzTableName, NULL);
H
hzcheng 已提交
729 730
  }

S
slguan 已提交
731
  if (code != TSDB_CODE_SUCCESS) {
732
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
733 734
  }

735 736 737 738
  if (code != TSDB_CODE_SUCCESS) {
    free(oldName);
    return code;
  }
H
hjxilinx 已提交
739

740 741 742 743 744
  /*
   * 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 已提交
745 746
    if (strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
      tscClearMeterMetaInfo(pTableMetaInfo, false);
747 748
    }
  } else {
H
hjxilinx 已提交
749
    assert(pTableMetaInfo->pTableMeta == NULL && pTableMetaInfo->pMetricMeta == NULL);
750
  }
H
hjxilinx 已提交
751

752 753
  tfree(oldName);
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
754 755 756 757 758
}

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

759 760 761 762 763 764 765
  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 已提交
766 767 768

  // number of fields no less than 2
  if (pFieldList->nField <= 1 || pFieldList->nField > TSDB_MAX_COLUMNS) {
769
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
770 771 772 773 774
    return false;
  }

  // first column must be timestamp
  if (pFieldList->p[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
775
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
776 777 778 779 780 781 782 783 784 785
    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) {
786
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
787 788 789 790 791 792 793
    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) {
794
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
795 796 797 798 799
      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))) {
800
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
801 802 803 804
      return false;
    }

    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
805
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
806 807 808 809
      return false;
    }

    if (has(pFieldList, i + 1, pFieldList->p[i].name) == true) {
810
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
811 812 813 814 815 816 817 818 819 820
      return false;
    }
  }

  return true;
}

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

821 822 823 824 825 826 827
  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 已提交
828 829 830

  // number of fields at least 1
  if (pTagsList->nField < 1 || pTagsList->nField > TSDB_MAX_TAGS) {
831
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
832 833 834 835 836 837 838 839 840 841
    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) {
842
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
843 844 845 846 847 848
    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) {
849
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
850 851 852 853 854 855 856
      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) {
857
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
858 859 860 861
      return false;
    }

    if (pTagsList->p[i].type < TSDB_DATA_TYPE_BOOL || pTagsList->p[i].type > TSDB_DATA_TYPE_NCHAR) {
862
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
863 864 865 866 867
      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)) {
868
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
869 870 871 872
      return false;
    }

    if (validateColumnName(pTagsList->p[i].name) != TSDB_CODE_SUCCESS) {
873
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
874 875 876 877
      return false;
    }

    if (has(pTagsList, i + 1, pTagsList->p[i].name) == true) {
878
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
879 880 881 882 883 884 885 886 887 888 889
      return false;
    }
  }

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
890 891 892 893 894 895
  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 已提交
896

897
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
898

899
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
900
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
901

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

910
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
911 912 913 914 915
    return false;
  }

  // no timestamp allowable
  if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) {
916
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
917 918 919
    return false;
  }

L
[#1236]  
lihui 已提交
920
  if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_NCHAR)) {
921
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
922 923 924
    return false;
  }

H
hjxilinx 已提交
925
  SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
926 927
  int32_t  nLen = 0;

H
hjxilinx 已提交
928
  for (int32_t i = 0; i < numOfTags; ++i) {
H
hzcheng 已提交
929 930 931 932 933
    nLen += pTagSchema[i].bytes;
  }

  // length less than TSDB_MAX_TASG_LEN
  if (nLen + pTagField->bytes > TSDB_MAX_TAGS_LEN) {
934
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
935 936 937 938 939
    return false;
  }

  // tags name can not be a keyword
  if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) {
940
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
941 942 943 944 945
    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) {
946
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
947 948 949 950
    return false;
  }

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

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

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
964 965 966 967 968 969
  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 已提交
970

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

  if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_NCHAR) {
985
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
986 987 988 989
    return false;
  }

  if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) {
990
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
991 992 993
    return false;
  }

H
hjxilinx 已提交
994
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
995 996
  int32_t  nLen = 0;

H
hjxilinx 已提交
997
  for (int32_t i = 0; i < numOfCols; ++i) {
H
hzcheng 已提交
998 999 1000 1001
    nLen += pSchema[i].bytes;
  }

  if (pColField->bytes <= 0) {
1002
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1003 1004 1005 1006 1007
    return false;
  }

  // length less than TSDB_MAX_BYTES_PER_ROW
  if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) {
1008
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1009 1010 1011 1012
    return false;
  }

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

  return true;
}

/* is contained in pFieldList or not */
H
hjxilinx 已提交
1024
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name) {
H
hzcheng 已提交
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
  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;
}

1050
int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQLToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
  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 已提交
1076
      if (tableName->n > TSDB_TABLE_NAME_LEN) {
H
hzcheng 已提交
1077 1078 1079 1080
        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 已提交
1081
      if (tableName->n > TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN + tListLen(TS_PATH_DELIMITER)) {
H
hzcheng 已提交
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
        return TSDB_CODE_INVALID_SQL;
      }
    }

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

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

S
slguan 已提交
1094
  if (totalLen < TSDB_TABLE_ID_LEN) {
S
slguan 已提交
1095 1096 1097
    fullName[totalLen] = 0;
  }

S
slguan 已提交
1098
  return (totalLen <= TSDB_TABLE_ID_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1099 1100
}

S
slguan 已提交
1101
static void extractColumnNameFromString(tSQLExprItem* pItem) {
H
hzcheng 已提交
1102
  if (pItem->pNode->nSQLOptr == TK_STRING) {
S
slguan 已提交
1103
    pItem->pNode->val.nLen = strdequote(pItem->pNode->val.pz);
H
hzcheng 已提交
1104 1105 1106 1107
    pItem->pNode->nSQLOptr = TK_ID;

    SSQLToken* pIdToken = &pItem->pNode->colInfo;
    pIdToken->type = TK_ID;
S
slguan 已提交
1108 1109
    pIdToken->z = pItem->pNode->val.pz;
    pIdToken->n = pItem->pNode->val.nLen;
H
hzcheng 已提交
1110 1111 1112
  }
}

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

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

1122
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
1123

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

S
slguan 已提交
1128 1129 1130
    // 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 已提交
1131
      if (pItem->pNode->nSQLOptr == TK_ID && (pItem->pNode->colInfo.z == NULL && pItem->pNode->colInfo.n == 0)) {
H
hjxilinx 已提交
1132
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1133 1134
      }

S
slguan 已提交
1135 1136
      // if the name of column is quoted, remove it and set the right information for later process
      extractColumnNameFromString(pItem);
1137
      pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
S
slguan 已提交
1138 1139

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

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
H
hjxilinx 已提交
1150
      // arithmetic function in select clause
1151
      SColumnList columnList = {0};
H
hjxilinx 已提交
1152 1153 1154
      int32_t     arithmeticType = NON_ARITHMEIC_EXPR;

      if (validateArithmeticSQLExpr(pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
1155
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1156
      }
1157 1158
      
      int32_t tableIndex = columnList.ids[0].tableIndex;
H
hzcheng 已提交
1159 1160
      char  arithmeticExprStr[1024] = {0};
      char* p = arithmeticExprStr;
H
hjxilinx 已提交
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
      
      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 已提交
1187
      } else {
H
hjxilinx 已提交
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
        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;

1204
          SSqlBinaryExprInfo* pBinExprInfo = &pFuncExpr->binExprInfo;
H
hjxilinx 已提交
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231
          
          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 已提交
1232 1233 1234 1235 1236 1237
      }
    } else {
      /*
       * not support such expression
       * e.g., select 12+5 from table_name
       */
1238
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1239 1240
    }

1241
    if (pQueryInfo->fieldsInfo.numOfOutputCols > TSDB_MAX_COLUMNS) {
H
hzcheng 已提交
1242 1243 1244 1245
      return TSDB_CODE_INVALID_SQL;
    }
  }

1246 1247
  if (!functionCompatibleCheck(pQueryInfo)) {
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1248 1249
  }

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

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

1266
    if (hasUnsupportFunctionsForSTableQuery(pQueryInfo)) {
H
hzcheng 已提交
1267 1268 1269 1270 1271 1272 1273
      return TSDB_CODE_INVALID_SQL;
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

1280
  tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, outputIndex, type, fieldName, bytes);
H
hjxilinx 已提交
1281 1282
  tscFieldInfoSetExpr(&pQueryInfo->fieldsInfo, outputIndex, pSqlExpr);
  
H
hzcheng 已提交
1283 1284 1285
  return TSDB_CODE_SUCCESS;
}

1286
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIdx, int32_t tableIndex) {
H
hjxilinx 已提交
1287
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1288 1289 1290 1291
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIdx);
H
hzcheng 已提交
1292

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

S
slguan 已提交
1295
  if (functionId == TSDB_FUNC_TAGPRJ) {
1296 1297
    addRequiredTagColumn(pQueryInfo, colIdx - numOfCols, tableIndex);
    pQueryInfo->type = TSDB_QUERY_TYPE_STABLE_QUERY;
S
slguan 已提交
1298
  } else {
1299
    pQueryInfo->type = TSDB_QUERY_TYPE_PROJECTION_QUERY;
H
hzcheng 已提交
1300 1301
  }

S
slguan 已提交
1302 1303
  SColumnIndex index = {tableIndex, colIdx};
  SSqlExpr*    pExpr =
1304
      tscSqlExprInsert(pQueryInfo, outputIndex, functionId, &index, pSchema->type, pSchema->bytes, pSchema->bytes);
S
slguan 已提交
1305 1306

  return pExpr;
H
hzcheng 已提交
1307 1308
}

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

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

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

H
hjxilinx 已提交
1326
        pTableMetaInfo->numOfTags++;
H
hzcheng 已提交
1327 1328 1329 1330 1331 1332
        break;
      }
    }
  }

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

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

H
hjxilinx 已提交
1339
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
H
hjxilinx 已提交
1340 1341 1342
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
1343

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

H
hjxilinx 已提交
1351
  if (pIndex->columnIndex >= tscGetNumOfColumns(pTableMeta) || pIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1352 1353
    ids.num = 0;
  }
H
hzcheng 已提交
1354

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

1358
void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1359
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
1360 1361
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
                                     pColSchema->bytes, pColSchema->bytes);
H
hzcheng 已提交
1362

S
slguan 已提交
1363 1364 1365 1366
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1367

H
hjxilinx 已提交
1368
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1369 1370 1371

  pExpr->colInfo.flag = flag;
  if (TSDB_COL_IS_TAG(flag)) {
1372
    addRequiredTagColumn(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex);
S
slguan 已提交
1373 1374 1375
  }
}

1376
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1377
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1378 1379

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1380 1381
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1382

H
hjxilinx 已提交
1383
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1384
  
H
hjxilinx 已提交
1385
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1386
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1387
  } else {
H
hjxilinx 已提交
1388
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1389 1390 1391
  }

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

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

    // tag columns do not add to source list
H
hjxilinx 已提交
1400
    ids.num = (j >= tscGetNumOfColumns(pTableMeta)) ? 0 : 1;
S
slguan 已提交
1401

H
hjxilinx 已提交
1402
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1403 1404 1405 1406 1407
  }

  return numOfTotalColumns;
}

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

H
hjxilinx 已提交
1412
  int32_t startPos = pQueryInfo->exprsInfo.numOfExprs;
S
slguan 已提交
1413 1414 1415

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

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

1433
    if (getColumnIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1434
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
1435
    }
H
hzcheng 已提交
1436

S
slguan 已提交
1437
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1438
      SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = TSDB_TABLE_NAME_LEN};
S
slguan 已提交
1439
      strcpy(colSchema.name, TSQL_TBNAME_L);
1440

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

H
hjxilinx 已提交
1447
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
1448
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1449 1450
      }

1451
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
hzcheng 已提交
1452 1453 1454 1455 1456 1457 1458 1459
    }
  } else {
    return TSDB_CODE_INVALID_SQL;
  }

  return TSDB_CODE_SUCCESS;
}

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

S
slguan 已提交
1465
  char        columnName[TSDB_COL_NAME_LEN] = {0};
1466
  const char* msg1 = "not support column types";
H
hzcheng 已提交
1467 1468

  if (functionID == TSDB_FUNC_SPREAD) {
S
slguan 已提交
1469 1470 1471
    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) {
1472
      invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1473 1474 1475 1476 1477 1478
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
S
slguan 已提交
1479 1480
    type = pSchema[pColIndex->columnIndex].type;
    bytes = pSchema[pColIndex->columnIndex].bytes;
H
hzcheng 已提交
1481 1482 1483 1484 1485
  }

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

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

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1502
int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem, bool finalResult) {
H
hjxilinx 已提交
1503
  STableMetaInfo* pTableMetaInfo = NULL;
S
slguan 已提交
1504 1505
  int32_t         optr = pItem->pNode->nSQLOptr;

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

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

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

H
hjxilinx 已提交
1525
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1526
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1527 1528 1529 1530

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

S
slguan 已提交
1534 1535 1536 1537 1538 1539
        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;

1540 1541
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
1542 1543 1544 1545
          }

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

H
hjxilinx 已提交
1553
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1554 1555

          // count tag is equalled to count(tbname)
H
hjxilinx 已提交
1556
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
S
slguan 已提交
1557
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
hzcheng 已提交
1558 1559
          }

S
slguan 已提交
1560
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
hjxilinx 已提交
1561
          pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
H
hzcheng 已提交
1562
        }
S
slguan 已提交
1563 1564 1565 1566
      } 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 已提交
1567
        pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
H
hzcheng 已提交
1568
      }
H
hjxilinx 已提交
1569 1570 1571 1572
      
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
      getColumnName(pItem, pExpr->aliasName, TSDB_COL_NAME_LEN);
      
S
slguan 已提交
1573
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1574 1575 1576 1577 1578 1579 1580 1581
      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]));
        }
      }
1582 1583 1584 1585
  
      SColumnIndex tsCol = {.tableIndex = index.tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
      tscColumnBaseInfoInsert(pQueryInfo, &tsCol);
  
S
slguan 已提交
1586
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1587 1588 1589
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1590 1591 1592 1593 1594 1595
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1596
    case TK_TWA:
H
hzcheng 已提交
1597 1598 1599 1600 1601 1602 1603 1604 1605
    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 */
1606
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1607 1608 1609 1610
      }

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

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

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

H
hjxilinx 已提交
1625
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1626
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1627 1628 1629 1630
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
S
slguan 已提交
1631
      int16_t intermediateResSize = 0;
H
hzcheng 已提交
1632 1633 1634

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

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

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

S
slguan 已提交
1650
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1651
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1652 1653
      }

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

1659
      SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, resultType, resultSize, resultSize);
H
hzcheng 已提交
1660 1661 1662 1663 1664 1665 1666 1667

      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 已提交
1668
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1669 1670 1671 1672 1673 1674

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

S
slguan 已提交
1675
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1676 1677
      }

S
slguan 已提交
1678 1679 1680
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692
  
      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]));
        }
      }
1693 1694 1695 1696
  
      SColumnIndex tsCol = {.tableIndex = index.tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
      tscColumnBaseInfoInsert(pQueryInfo, &tsCol);
      
S
slguan 已提交
1697
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710
    }
    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) {
1711
          return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1712 1713 1714 1715 1716 1717
        }

        /* 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) {
1718
            return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1719 1720
          }

S
slguan 已提交
1721 1722 1723 1724 1725 1726
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

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

1727 1728
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
1729 1730
            }

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

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

S
slguan 已提交
1741
          } else {
1742
            if (getColumnIndexByName(&pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1743
              return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
1744 1745
            }

H
hjxilinx 已提交
1746
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1747
            SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1748 1749

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

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

1764
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
1765
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
1766
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1767

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

H
hjxilinx 已提交
1776
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1777 1778
        }

1779
        
S
slguan 已提交
1780
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1781 1782 1783 1784 1785 1786 1787 1788 1789
      }
    }
    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 */
1790
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1791 1792 1793 1794
      }

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

H
hjxilinx 已提交
1803
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1804
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1805 1806

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

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

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

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

S
slguan 已提交
1824 1825
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1826

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

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

        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 已提交
1848
          return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1849 1850
        }

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

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

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

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

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

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

H
hjxilinx 已提交
1877
        pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize);
S
slguan 已提交
1878
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
1879
      }
H
hjxilinx 已提交
1880 1881 1882 1883
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
      getColumnName(pItem, pExpr->aliasName, TSDB_COL_NAME_LEN);
  
S
slguan 已提交
1884
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
1885 1886 1887 1888 1889 1890 1891
      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 已提交
1892 1893

      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1894 1895
    }
    default:
S
slguan 已提交
1896
      return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
1897
  }
1898 1899
  
  
H
hzcheng 已提交
1900 1901
}

S
slguan 已提交
1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915
// 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 已提交
1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928
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 已提交
1929 1930 1931 1932 1933 1934 1935 1936 1937
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));
}

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

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

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

1959
int32_t doGetColumnIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
  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) {
1970 1971
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
1972 1973 1974

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

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
1990
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
    }
  }

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

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

    return TSDB_CODE_SUCCESS;
  }

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

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

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

2030
int32_t getTableIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2031 2032 2033
  SSQLToken tableToken = {0};
  extractTableNameFromToken(pToken, &tableToken);

2034
  if (getMeterIndex(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2035
    return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
2036 2037
  }

S
slguan 已提交
2038 2039
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2040

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

S
slguan 已提交
2046 2047
  SSQLToken tmpToken = *pToken;

2048
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2049
    return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
2050 2051
  }

2052
  return doGetColumnIndexByName(&tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065
}

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 已提交
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083
    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 已提交
2084 2085 2086 2087 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
    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 已提交
2120 2121
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136
      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 已提交
2137
  SSqlCmd*        pCmd = &pSql->cmd;
2138
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2139
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2140

H
hzcheng 已提交
2141 2142
  pCmd->command = TSDB_SQL_SHOW;

2143
  const char* msg1 = "invalid name";
2144
  const char* msg2 = "pattern filter string too long";
2145 2146 2147 2148
  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 已提交
2149 2150 2151 2152 2153

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2154 2155 2156
  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 已提交
2157
    // db prefix in tagCond, show table conds in payload
2158 2159 2160
    SSQLToken* pDbPrefixToken = &pShowInfo->prefix;
    if (pDbPrefixToken->type != 0) {
      assert(pDbPrefixToken->n >= 0);
H
hzcheng 已提交
2161 2162

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

2166
      if (pDbPrefixToken->n <= 0) {
2167
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2168 2169
      }

2170
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2171
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2172 2173
      }

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

2180 2181 2182 2183
    // 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 已提交
2184

2185
      if (pPattern->n <= 0) {
2186
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2187
      }
H
hzcheng 已提交
2188

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

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

2204
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2205
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2206
    }
H
hzcheng 已提交
2207 2208 2209 2210 2211 2212
  }

  return TSDB_CODE_SUCCESS;
}

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

2216 2217
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
H
hzcheng 已提交
2218

2219 2220
  SSQLToken* ip = &(pInfo->pDCLInfo->ip);
  if (ip->n > TSDB_KILL_MSG_LEN) {
H
hzcheng 已提交
2221 2222 2223
    return TSDB_CODE_INVALID_SQL;
  }

2224
  strncpy(pCmd->payload, ip->z, ip->n);
H
hzcheng 已提交
2225 2226 2227

  const char delim = ':';

2228 2229 2230 2231
  char* ipStr = strtok(ip->z, &delim);
  char* portStr = strtok(NULL, &delim);

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

2234
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2235 2236
  }

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

  return TSDB_CODE_SUCCESS;
}

2246 2247 2248 2249 2250 2251 2252 2253 2254
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 已提交
2255 2256
}

2257
int32_t tscTansformSQLFunctionForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2258
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2259

H
hjxilinx 已提交
2260
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
S
slguan 已提交
2261
    return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
2262 2263
  }

H
hjxilinx 已提交
2264
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2265 2266 2267

  int16_t bytes = 0;
  int16_t type = 0;
S
slguan 已提交
2268
  int16_t intermediateBytes = 0;
H
hzcheng 已提交
2269

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

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

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

2291
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2292
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2293 2294 2295
}

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

H
hjxilinx 已提交
2302
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
2303
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
2304
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIdx);
H
hjxilinx 已提交
2305
    
H
hjxilinx 已提交
2306 2307 2308
//    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 已提交
2309 2310 2311
      // 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 已提交
2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324
      
      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 已提交
2325
                        &inter, 0, false);
H
hjxilinx 已提交
2326
//    }
H
hzcheng 已提交
2327 2328 2329
  }
}

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

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

2344 2345 2346
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
      invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
2347 2348
      return true;
    }
H
hzcheng 已提交
2349

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

H
hzcheng 已提交
2357 2358 2359
  return false;
}

2360
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
2361
  int32_t startIdx = 0;
2362
  int32_t functionID = tscSqlExprGet(pQueryInfo, startIdx)->functionId;
S
slguan 已提交
2363 2364

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

2369
  int32_t factor = funcCompatDefList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2370 2371 2372

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

    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 已提交
2382 2383 2384 2385
      continue;
    }

    if (funcCompatDefList[functionId] != factor) {
H
hzcheng 已提交
2386 2387 2388 2389 2390 2391 2392
      return false;
    }
  }

  return true;
}

2393
void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex) {
H
hjxilinx 已提交
2394
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
S
slguan 已提交
2395

H
hjxilinx 已提交
2396 2397 2398 2399
  /*
   * update tags column index for group by tags
   * group by columns belong to this table
   */
2400 2401 2402
  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 已提交
2403

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

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

S
slguan 已提交
2418
    if (!TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {  // not tags, continue
H
hzcheng 已提交
2419 2420
      continue;
    }
H
hjxilinx 已提交
2421

H
hjxilinx 已提交
2422
    // not belongs to this table
H
hjxilinx 已提交
2423
    if (pExpr->uid != pTableMetaInfo->pTableMeta->uid) {
H
hjxilinx 已提交
2424 2425
      continue;
    }
H
hzcheng 已提交
2426

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

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

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

H
hjxilinx 已提交
2443
  // the join condition expression node belongs to this table(super table)
H
hjxilinx 已提交
2444 2445 2446
  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 已提交
2447 2448 2449 2450
        pJoinInfo->left.tagCol = i;
      }
    }
  }
H
hjxilinx 已提交
2451

H
hjxilinx 已提交
2452 2453 2454
  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 已提交
2455 2456 2457 2458
        pJoinInfo->right.tagCol = i;
      }
    }
  }
H
hzcheng 已提交
2459 2460
}

2461
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2462 2463
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
H
hjxilinx 已提交
2464
  const char* msg3 = "group by columns must belong to one table";
S
slguan 已提交
2465 2466 2467
  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 已提交
2468

S
slguan 已提交
2469
  // todo : handle two meter situation
H
hjxilinx 已提交
2470
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2471 2472 2473 2474 2475

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

2476
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2477
  if (pList->nExpr > TSDB_MAX_TAGS) {
2478
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
2479 2480
  }

H
hjxilinx 已提交
2481
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2482
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2483
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2484

S
slguan 已提交
2485
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
H
hzcheng 已提交
2486 2487 2488 2489 2490

  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 已提交
2491
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
2492

2493
    if (getColumnIndexByName(&token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
2494
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
2495
    }
H
hzcheng 已提交
2496

S
slguan 已提交
2497
    if (tableIndex != index.tableIndex && tableIndex >= 0) {
2498
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
2499 2500
    }

S
slguan 已提交
2501
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2502

H
hjxilinx 已提交
2503
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2504
    pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
2505

S
slguan 已提交
2506 2507 2508
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2509
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2510
    }
H
hzcheng 已提交
2511

S
slguan 已提交
2512
    bool groupTag = false;
H
hjxilinx 已提交
2513
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= tscGetNumOfColumns(pTableMeta)) {
S
slguan 已提交
2514
      groupTag = true;
H
hzcheng 已提交
2515 2516
    }

S
slguan 已提交
2517
    if (groupTag) {
H
hjxilinx 已提交
2518
      if (!UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
2519
        return invalidSqlErrMsg(pQueryInfo->msg, msg9);
S
slguan 已提交
2520 2521 2522 2523
      }

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

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

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

      if (i == 0 && pList->nExpr > 1) {
2542
        return invalidSqlErrMsg(pQueryInfo->msg, msg7);
S
slguan 已提交
2543
      }
H
hzcheng 已提交
2544 2545 2546
    }
  }

2547
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
S
slguan 已提交
2548

H
hzcheng 已提交
2549 2550 2551
  return TSDB_CODE_SUCCESS;
}

2552 2553
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2554
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2555
  } else {
2556
    tscFieldInfoCalOffset(pQueryInfo);
H
hzcheng 已提交
2557 2558 2559
  }
}

S
slguan 已提交
2560 2561 2562 2563
static SColumnFilterInfo* addColumnFilterInfo(SColumnBase* pColumn) {
  if (pColumn == NULL) {
    return NULL;
  }
2564

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

S
slguan 已提交
2571
  pColumn->numOfFilters++;
2572

S
slguan 已提交
2573 2574 2575 2576
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2577 2578
}

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

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

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

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

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

S
slguan 已提交
2607 2608 2609 2610 2611 2612 2613 2614 2615
      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 已提交
2616
    } else {
S
slguan 已提交
2617
      tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType);
H
hzcheng 已提交
2618 2619 2620 2621 2622
    }
  }

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

2647
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2648 2649
}

S
slguan 已提交
2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663
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 已提交
2664

S
slguan 已提交
2665 2666 2667
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 已提交
2668
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2669 2670
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2671 2672

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

H
hjxilinx 已提交
2675 2676 2677 2678 2679 2680 2681
  } 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 已提交
2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700
    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 已提交
2701 2702 2703
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723
  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 已提交
2724 2725 2726 2727
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
2728 2729 2730 2731
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
2732 2733 2734 2735 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

  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 已提交
2788
static int32_t tablenameListToString(tSQLExpr* pExpr, /*char* str*/ SStringBuilder* sb) {
H
hzcheng 已提交
2789 2790 2791 2792 2793
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
2794
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2795
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2796 2797
  }

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

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

S
slguan 已提交
2806
    if (pSub->val.nLen <= 0 || pSub->val.nLen > TSDB_TABLE_NAME_LEN) {
H
hzcheng 已提交
2807 2808 2809 2810 2811 2812 2813
      return TSDB_CODE_INVALID_SQL;
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2814
static int32_t tablenameCondToString(tSQLExpr* pExpr, /*char* str*/ SStringBuilder* sb) {
H
hjxilinx 已提交
2815 2816
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2817 2818

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2819 2820
}

S
slguan 已提交
2821 2822 2823 2824 2825 2826
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2827

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

H
hjxilinx 已提交
2831 2832
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2833

S
slguan 已提交
2834 2835 2836
  const char* msg1 = "non binary column not support like operator";
  const char* msg2 = "binary column not support this operator";

2837
  SColumnBase*       pColumn = tscColumnBaseInfoInsert(pQueryInfo, pIndex);
S
slguan 已提交
2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862
  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) {
2863
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
2864
    }
S
slguan 已提交
2865 2866
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
2867
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
2868
    }
S
slguan 已提交
2869 2870 2871
  }

  pColumn->colIndex = *pIndex;
2872
  return doExtractColumnFilterInfo(pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
2873 2874
}

2875
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2876 2877 2878 2879 2880
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

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

2891
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2892 2893 2894 2895 2896 2897 2898
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

2900
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
2901
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2902
      return ret;
H
hzcheng 已提交
2903
    }
S
slguan 已提交
2904

2905
    relToString(pExpr, str);
S
slguan 已提交
2906

2907
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
2908 2909 2910 2911

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

H
hzcheng 已提交
2912 2913 2914
    return ret;
  }

S
slguan 已提交
2915 2916 2917
  return tSQLExprLeafToString(pExpr, true, str);
}

2918
static int32_t getTablenameCond(SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
2919 2920 2921 2922
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
2925 2926
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
2927

S
slguan 已提交
2928
  if (!isTablenameToken(&pLeft->colInfo)) {
H
hzcheng 已提交
2929 2930 2931
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
2932
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2933

S
slguan 已提交
2934
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
2935
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
2936
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
2937
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
2938
  }
H
hzcheng 已提交
2939

S
slguan 已提交
2940
  if (ret != TSDB_CODE_SUCCESS) {
2941
    invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
2942
  }
H
hzcheng 已提交
2943

S
slguan 已提交
2944 2945 2946
  return ret;
}

2947
static int32_t getColumnQueryCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
2948 2949 2950 2951 2952
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
2953
    int32_t ret = getColumnQueryCondInfo(pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
2954 2955 2956 2957
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

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

2965
    return extractColumnFilterInfo(pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
2966
  }
S
slguan 已提交
2967
}
H
hzcheng 已提交
2968

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

S
slguan 已提交
2972 2973 2974
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
2975

S
slguan 已提交
2976
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
2977
    return invalidSqlErrMsg(pQueryInfo->msg, msg);
S
slguan 已提交
2978 2979
  }

2980
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
2981 2982 2983 2984
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2985
  if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2986 2987 2988
    return TSDB_CODE_INVALID_SQL;
  }

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

H
hjxilinx 已提交
2992
  pLeft->uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
2993
  pLeft->tagCol = tagColIndex;
H
hjxilinx 已提交
2994
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
2995 2996

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
2997
  if (getColumnIndexByName(&pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2998 2999 3000
    return TSDB_CODE_INVALID_SQL;
  }

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

H
hjxilinx 已提交
3004
  pRight->uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
3005
  pRight->tagCol = tagColIndex;
H
hjxilinx 已提交
3006
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3007 3008

  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3009 3010 3011 3012
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3017
  *(*exprString)++ = '(';
H
hzcheng 已提交
3018 3019

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

  optrToString(pExpr, exprString);

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

H
hjxilinx 已提交
3039
  *(*exprString)++ = ')';
H
hzcheng 已提交
3040 3041 3042 3043

  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3052 3053 3054 3055 3056 3057
    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 已提交
3058
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3059 3060
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3061 3062 3063 3064 3065 3066
    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 已提交
3067 3068
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
    return TSDB_CODE_INVALID_SQL;
H
hjxilinx 已提交
3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082
  } 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 已提交
3083 3084 3085 3086 3087
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3088
static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3089 3090 3091 3092 3093 3094
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
H
hjxilinx 已提交
3108
    int32_t ret = validateArithmeticSQLExpr(pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3109 3110 3111 3112
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
H
hjxilinx 已提交
3113
    int32_t ret = validateSQLExpr(pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128
    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 已提交
3129 3130 3131
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3132 3133 3134
   *
   * However, columnA < 4+12 is valid
   */
L
lihui 已提交
3135 3136
  if ((pLeft->nSQLOptr >= TK_COUNT && pLeft->nSQLOptr <= TK_AVG_IRATE) ||
      (pRight->nSQLOptr >= TK_COUNT && pRight->nSQLOptr <= TK_AVG_IRATE) ||
H
hzcheng 已提交
3137 3138 3139 3140 3141 3142 3143 3144
      (pLeft->nSQLOptr >= TK_BOOL && pLeft->nSQLOptr <= TK_BINARY && pRight->nSQLOptr >= TK_BOOL &&
       pRight->nSQLOptr <= TK_BINARY)) {
    return false;
  }

  return true;
}

S
slguan 已提交
3145 3146 3147
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3148

S
slguan 已提交
3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173
  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 已提交
3174

S
slguan 已提交
3175 3176 3177 3178 3179
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3180
static bool validateJoinExprNode(SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194
  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) {
3195
    invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
3196 3197 3198 3199 3200
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3201
  if (getColumnIndexByName(&pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
3202
    invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3203
    return false;
H
hzcheng 已提交
3204 3205
  }

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

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

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

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

S
slguan 已提交
3232 3233
  return true;
}
H
hzcheng 已提交
3234

S
slguan 已提交
3235 3236 3237 3238 3239 3240
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 已提交
3241 3242 3243
    }
  }

S
slguan 已提交
3244
  return false;
H
hzcheng 已提交
3245 3246
}

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

S
slguan 已提交
3253 3254 3255 3256
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3257

S
slguan 已提交
3258 3259
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3260

3261
static int32_t handleExprInQueryCond(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr, int32_t* type,
S
slguan 已提交
3262 3263 3264 3265 3266
                                     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 已提交
3267 3268 3269
  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 已提交
3270

S
slguan 已提交
3271 3272
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3273

S
slguan 已提交
3274 3275 3276
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3277
  if (getColumnIndexByName(&pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3278
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
3279 3280
  }

S
slguan 已提交
3281 3282
  assert(isExprDirectParentOfLeaftNode(*pExpr));

H
hjxilinx 已提交
3283
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3284
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3285 3286

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

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
3293
      pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
S
slguan 已提交
3294 3295 3296 3297 3298 3299 3300 3301
      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 {
3302
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3303 3304 3305 3306
    }

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

    // 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 已提交
3320
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3321 3322 3323

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

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

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

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

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

3354 3355
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369
        *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
3370
      return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
3371 3372
    }

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

S
slguan 已提交
3377
  return ret;
H
hzcheng 已提交
3378 3379
}

3380 3381
int32_t getQueryCondExpr(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr, int32_t* type,
                         int32_t parentOptr) {
H
hzcheng 已提交
3382 3383 3384 3385
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3388 3389 3390 3391
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
H
hzcheng 已提交
3392 3393 3394
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
3395 3396
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3397

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

3404
    ret = getQueryCondExpr(pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3405 3406 3407
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3408

S
slguan 已提交
3409 3410 3411 3412 3413 3414
    /*
     *  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)) {
3415
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3416
      }
H
hzcheng 已提交
3417 3418
    }

S
slguan 已提交
3419 3420 3421
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3422

S
slguan 已提交
3423
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3424

3425
  return handleExprInQueryCond(pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3426
}
H
hzcheng 已提交
3427

S
slguan 已提交
3428 3429 3430 3431
static void doCompactQueryExpr(tSQLExpr** pExpr) {
  if (*pExpr == NULL || isExprDirectParentOfLeaftNode(*pExpr)) {
    return;
  }
H
hzcheng 已提交
3432

S
slguan 已提交
3433 3434 3435
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3436

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

S
slguan 已提交
3441 3442 3443 3444
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3445

S
slguan 已提交
3446 3447 3448
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3449

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

S
slguan 已提交
3455
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3456
  }
S
slguan 已提交
3457
}
H
hzcheng 已提交
3458

3459
static void doExtractExprForSTable(tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
S
slguan 已提交
3460 3461 3462 3463
  if (isExprDirectParentOfLeaftNode(*pExpr)) {
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3464
    if (getColumnIndexByName(&pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3465
      return;
H
hzcheng 已提交
3466 3467
    }

S
slguan 已提交
3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480
    if (index.tableIndex != tableIndex) {
      return;
    }

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

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

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

3481 3482
    doExtractExprForSTable(&(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(&(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3483 3484 3485
  }
}

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

S
slguan 已提交
3489
  if (*pExpr != NULL) {
3490
    doExtractExprForSTable(pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3491
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3492 3493
  }

S
slguan 已提交
3494
  return pResExpr;
H
hzcheng 已提交
3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509
}

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

3510 3511
static int32_t setTableCondForMetricQuery(SQueryInfo* pQueryInfo, const char* account, tSQLExpr* pExpr,
                                          int16_t tableCondIndex, SStringBuilder* sb) {
3512
  const char* msg = "table name too long";
H
hzcheng 已提交
3513

S
slguan 已提交
3514 3515 3516 3517
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3520
  STagCond* pTagCond = &pQueryInfo->tagCond;
H
hjxilinx 已提交
3521
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
3522 3523 3524 3525

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

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

H
hjxilinx 已提交
3531 3532
  SStringBuilder sb1 = {0};
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3533

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

S
slguan 已提交
3536
  // remove the duplicated input table names
H
hzcheng 已提交
3537
  int32_t num = 0;
H
hjxilinx 已提交
3538 3539 3540
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3541
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3542 3543 3544 3545 3546 3547 3548 3549 3550

  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 已提交
3551 3552 3553
  char* name = extractDBName(pTableMetaInfo->name, db);
  SSQLToken dbToken = {.type = TK_STRING, .z = name, .n = strlen(name)};
  
H
hzcheng 已提交
3554 3555
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3556
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3557
    }
H
hjxilinx 已提交
3558

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

3563
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3564
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3565
      taosStringBuilderDestroy(&sb1);
H
hzcheng 已提交
3566
      tfree(segments);
H
hjxilinx 已提交
3567

3568
      invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
3569 3570
      return ret;
    }
H
hjxilinx 已提交
3571

H
hjxilinx 已提交
3572
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3573
  }
H
hjxilinx 已提交
3574

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

H
hjxilinx 已提交
3578
  taosStringBuilderDestroy(&sb1);
H
hzcheng 已提交
3579 3580 3581 3582
  tfree(segments);
  return TSDB_CODE_SUCCESS;
}

3583 3584 3585
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
  for (int32_t i = 0; i < pQueryInfo->colList.numOfCols; ++i) {
    SColumnBase* pColBase = &pQueryInfo->colList.pColList[i];
3586

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

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

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

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

S
slguan 已提交
3615 3616
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    if (pExpr->nSQLOptr == TK_OR) {
3617
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3618
    }
H
hzcheng 已提交
3619

3620
    getTimeRangeFromExpr(pQueryInfo, pExpr->pLeft);
S
slguan 已提交
3621

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

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

    TSKEY stime = 0;
    TSKEY etime = INT64_MAX;

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

    // update the timestamp query range
3642 3643
    if (pQueryInfo->stime < stime) {
      pQueryInfo->stime = stime;
S
slguan 已提交
3644 3645
    }

3646 3647
    if (pQueryInfo->etime > etime) {
      pQueryInfo->etime = etime;
S
slguan 已提交
3648 3649 3650 3651 3652 3653
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

3659 3660
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
3661 3662
      return TSDB_CODE_SUCCESS;
    } else {
3663
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
3664 3665 3666
    }
  }

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

  if (!pCondExpr->tsJoin) {
3676
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
3677 3678
  }

S
slguan 已提交
3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703
  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);
  }
}

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

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

H
hjxilinx 已提交
3712
    int32_t columnInfo = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
3713
    addRequiredTagColumn(pQueryInfo, columnInfo, index.tableIndex);
H
hjxilinx 已提交
3714

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

H
hjxilinx 已提交
3718
    columnInfo = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
3719
    addRequiredTagColumn(pQueryInfo, columnInfo, index.tableIndex);
S
slguan 已提交
3720
  }
H
hjxilinx 已提交
3721
}
S
slguan 已提交
3722

3723
static int32_t getTagQueryCondExpr(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSQLExpr** pExpr) {
H
hjxilinx 已提交
3724
  int32_t ret = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
3725

H
hjxilinx 已提交
3726
  if (pCondExpr->pTagCond != NULL) {
3727 3728
    for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
      tSQLExpr* p1 = extractExprForSTable(pExpr, pQueryInfo, i);
H
hjxilinx 已提交
3729

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

H
hjxilinx 已提交
3732 3733
      char  c[TSDB_MAX_TAGS_LEN] = {0};
      char* str = c;
H
hjxilinx 已提交
3734

3735
      if ((ret = getTagCondString(p1, &str)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3736 3737
        return ret;
      }
H
hjxilinx 已提交
3738

H
hjxilinx 已提交
3739
      tsSetMetricQueryCond(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid, c);
H
hjxilinx 已提交
3740

H
hjxilinx 已提交
3741 3742 3743
      doCompactQueryExpr(pExpr);
      tSQLExprDestroy(p1);
    }
H
hjxilinx 已提交
3744

H
hjxilinx 已提交
3745 3746
    pCondExpr->pTagCond = NULL;
  }
H
hjxilinx 已提交
3747

S
slguan 已提交
3748 3749
  return ret;
}
3750
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
3751 3752 3753
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
3754

S
slguan 已提交
3755
  const char* msg = "invalid filter expression";
H
hjxilinx 已提交
3756
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
3757

H
hjxilinx 已提交
3758
  int32_t ret = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
3759

3760 3761
  pQueryInfo->stime = 0;
  pQueryInfo->etime = INT64_MAX;
S
slguan 已提交
3762

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

H
hjxilinx 已提交
3767
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
3768
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3769 3770
  }

H
hjxilinx 已提交
3771
  int32_t type = 0;
3772
  if ((ret = getQueryCondExpr(pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3773 3774
    return ret;
  }
H
hjxilinx 已提交
3775

S
slguan 已提交
3776
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
3777

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

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

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

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

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

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

S
slguan 已提交
3806
  // 6. join condition
3807
  if ((ret = getJoinCondInfo(pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3808
    return ret;
H
hzcheng 已提交
3809
  }
H
hjxilinx 已提交
3810

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

3814
  ret = setTableCondForMetricQuery(pQueryInfo, getAccountId(pSql), condExpr.pTableCond, condExpr.tableCondIndex, &sb);
H
hjxilinx 已提交
3815
  taosStringBuilderDestroy(&sb);
H
hjxilinx 已提交
3816

3817 3818
  if (!validateFilterExpr(pQueryInfo)) {
    return invalidSqlErrMsg(pQueryInfo->msg, msg);
3819
  }
H
hjxilinx 已提交
3820

3821
  doAddJoinTagsColumnsIntoTagList(pQueryInfo, &condExpr);
H
hjxilinx 已提交
3822

H
hjxilinx 已提交
3823
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
3824 3825 3826 3827
  return ret;
}

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

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

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

S
slguan 已提交
3846
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
3847 3848 3849 3850 3851 3852
    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 已提交
3853 3854 3855 3856 3857 3858 3859
    } 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 已提交
3860 3861 3862 3863
    }
  } 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 已提交
3864
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
3865 3866 3867 3868 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
     *
     * 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 已提交
3916
// todo error !!!!
3917
int32_t tsRewriteFieldNameIfNecessary(SQueryInfo* pQueryInfo) {
S
slguan 已提交
3918 3919
  const char rep[] = {'(', ')', '*', ',', '.', '/', '\\', '+', '-', '%', ' '};

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

H
hzcheng 已提交
3931 3932 3933 3934
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
3935 3936 3937 3938
  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) {
3939
        const char* msg = "duplicated column name in new table";
3940
        return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
3941 3942 3943 3944 3945 3946 3947
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

3948
int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
3949 3950 3951 3952
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
3953 3954 3955 3956

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

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

3962
  if (pQueryInfo->defaultVal == NULL) {
H
hjxilinx 已提交
3963
    pQueryInfo->defaultVal = calloc(pQueryInfo->exprsInfo.numOfExprs, sizeof(int64_t));
3964 3965 3966 3967 3968
    if (pQueryInfo->defaultVal == NULL) {
      return TSDB_CODE_CLI_OUT_OF_MEMORY;
    }
  }

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

    if (pFillToken->nExpr == 1) {
3985
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
3986 3987 3988 3989 3990 3991
    }

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

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

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

    int32_t j = 1;

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

4009 4010 4011 4012
      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 已提交
4013

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

H
hjxilinx 已提交
4020 4021
    if ((pFillToken->nExpr < pQueryInfo->exprsInfo.numOfExprs) ||
        ((pFillToken->nExpr - 1 < pQueryInfo->exprsInfo.numOfExprs) && (tscIsPointInterpQuery(pQueryInfo)))) {
H
hzcheng 已提交
4022 4023
      tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1];

H
hjxilinx 已提交
4024
      for (int32_t i = numOfFillVal; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4025
        TAOS_FIELD* pFields = tscFieldInfoGetField(pQueryInfo, i);
H
hzcheng 已提交
4026 4027

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

  return TSDB_CODE_SUCCESS;
}

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

4046 4047 4048
  if (isTopBottomQuery(pQueryInfo)) {
    pQueryInfo->order.order = TSQL_SO_ASC;
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4049
  } else {
4050
    pQueryInfo->order.orderColId = -1;
H
hzcheng 已提交
4051 4052 4053
  }

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

S
slguan 已提交
4059
int32_t parseOrderbyClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4060 4061 4062 4063
  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 已提交
4064

4065
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4066
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4067 4068 4069 4070 4071 4072

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

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4073 4074 4075 4076 4077 4078 4079

  /*
   * 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 已提交
4080
  if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4081
    if (pSortorder->nExpr > 1) {
4082
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
4083 4084 4085
    }
  } else {
    if (pSortorder->nExpr > 2) {
4086
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097
    }
  }

  // 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 已提交
4098 4099 4100
  SSQLToken    columnName = {pVar->nLen, pVar->nType, pVar->pz};
  SColumnIndex index = {0};

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

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

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

S
slguan 已提交
4118
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4119 4120 4121
      orderByTS = true;
    }

4122 4123
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4124 4125 4126 4127 4128 4129
    } else {
      assert(!(orderByTags && orderByTS));
    }

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

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

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

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

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

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

  } else {  // meter query
4175
    if (getColumnIndexByName(&columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4176
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4177 4178
    }

4179 4180
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4181 4182
    }

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

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

4193 4194
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4195 4196
      return TSDB_CODE_SUCCESS;
    }
4197

4198
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4199 4200 4201 4202 4203 4204
  }

  return TSDB_CODE_SUCCESS;
}

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

4207 4208 4209 4210 4211 4212
  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 已提交
4213 4214

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

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

4220
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4221
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
4222
  }
P
plum-lihui 已提交
4223

H
hjxilinx 已提交
4224
  if (setMeterID(pTableMetaInfo, &(pAlterSQL->name), pSql) != TSDB_CODE_SUCCESS) {
4225
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4226 4227
  }

H
hjxilinx 已提交
4228
  int32_t ret = tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
4229 4230 4231 4232
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

H
hjxilinx 已提交
4233
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4234

4235 4236
  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 已提交
4237
    if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
4238
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4239
    }
H
hjxilinx 已提交
4240
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo))) {
4241
    return invalidSqlErrMsg(pQueryInfo->msg, msg4);
4242
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4243
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4244
    return invalidSqlErrMsg(pQueryInfo->msg, msg6);
H
hzcheng 已提交
4245 4246
  }

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

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

4257
    tscFieldInfoSetValFromField(&pQueryInfo->fieldsInfo, 0, &pFieldList->p[0]);
4258
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
4259 4260 4261 4262 4263
    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 已提交
4264

H
hjxilinx 已提交
4265
    if (tscGetNumOfTags(pTableMeta) == 1) {
4266
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4267 4268 4269 4270
    }

    // numOfTags == 1
    if (pAlterSQL->varList->nExpr > 1) {
4271
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4272 4273 4274 4275
    }

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

4279
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
4280 4281
    SSQLToken    name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen, .type = TK_STRING};

4282
    if (getColumnIndexByName(&name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4283
      return TSDB_CODE_INVALID_SQL;
H
hzcheng 已提交
4284 4285
    }

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

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

H
hzcheng 已提交
4300 4301 4302 4303 4304
    tVariantList* pVarList = pAlterSQL->varList;
    if (pVarList->nExpr > 2) {
      return TSDB_CODE_INVALID_SQL;
    }

4305 4306 4307 4308
    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) {
4309
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4310 4311
    }

4312
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4313
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
4314
    }
H
hzcheng 已提交
4315

S
slguan 已提交
4316 4317
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4318

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

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

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

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

4341 4342
    // 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 已提交
4343 4344 4345
    tVariantList* pVarList = pAlterSQL->varList;
    tVariant*     pTagName = &pVarList->a[0].pVar;

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

H
hjxilinx 已提交
4352
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4353
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
4354 4355
    }

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

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

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

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

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

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

H
hjxilinx 已提交
4391
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
4392
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4393 4394 4395
    }

    if (pAlterSQL->varList->nExpr > 1) {
4396
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4397 4398 4399 4400
    }

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

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

4407
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4408
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
4409
    }
H
hzcheng 已提交
4410

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

  return TSDB_CODE_SUCCESS;
}

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

4424
  if (pQueryInfo->intervalTime != 0 && pQueryInfo->intervalTime < 10) {
4425
    return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
4426 4427
  }

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

  return TSDB_CODE_SUCCESS;
}

4438
int32_t validateFunctionsInIntervalOrGroupbyQuery(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4439
  bool        isProjectionFunction = false;
4440
  const char* msg1 = "column projection is not compatible with interval";
H
hjxilinx 已提交
4441

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

4446 4447 4448
    // 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 已提交
4449
      for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) {
4450
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
4451 4452 4453 4454 4455
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
4456

4457 4458 4459 4460
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4461

S
slguan 已提交
4462
    if (pExpr->functionId == TSDB_FUNC_PRJ || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4463
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4464 4465 4466
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4467 4468

  if (isProjectionFunction) {
4469
    invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4470 4471 4472 4473 4474 4475
  }

  return isProjectionFunction == true ? TSDB_CODE_INVALID_SQL : TSDB_CODE_SUCCESS;
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4476 4477
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4478 4479 4480 4481 4482 4483 4484
} SDNodeDynConfOption;

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

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

  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 已提交
4496
      const SDNodeDynConfOption* pOption = &DNODE_DYNAMIC_CFG_OPTIONS[i];
H
hzcheng 已提交
4497 4498 4499 4500
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
S
slguan 已提交
4501 4502 4503 4504 4505 4506 4507 4508
  } 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 已提交
4509 4510 4511 4512 4513 4514 4515 4516 4517
  } 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 已提交
4518
    for (int32_t i = 2; i < tListLen(DNODE_DYNAMIC_CFG_OPTIONS) - 1; ++i) {
H
hjxilinx 已提交
4519
      const SDNodeDynConfOption* pOption = &DNODE_DYNAMIC_CFG_OPTIONS[i];
H
hzcheng 已提交
4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530

      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 已提交
4531 4532 4533 4534 4535
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
    return TSDB_CODE_INVALID_SQL;
  }

H
hjxilinx 已提交
4536 4537
  SDNodeDynConfOption LOCAL_DYNAMIC_CFG_OPTIONS[6] = {{"resetLog", 8},    {"rpcDebugFlag", 12}, {"tmrDebugFlag", 12},
                                                      {"cDebugFlag", 10}, {"uDebugFlag", 10},   {"debugFlag", 9}};
S
slguan 已提交
4538 4539 4540 4541 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

  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 已提交
4569 4570 4571 4572 4573 4574
int32_t validateColumnName(char* name) {
  bool ret = isKeyWord(name, strlen(name));
  if (ret) {
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
4575
  SSQLToken token = {.z = name};
H
hzcheng 已提交
4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601
  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;
}

4602 4603
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
4604 4605 4606
    return true;
  }

4607
  return (pQueryInfo->stime == pQueryInfo->etime) && (pQueryInfo->stime != 0);
H
hzcheng 已提交
4608 4609
}

4610
int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* pQuerySql, SSqlObj* pSql) {
H
hjxilinx 已提交
4611
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4612

S
slguan 已提交
4613 4614 4615 4616
  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 已提交
4617

H
hzcheng 已提交
4618
  // handle the limit offset value, validate the limit
4619
  pQueryInfo->limit = pQuerySql->limit;
4620
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4621
  pQueryInfo->slimit = pQuerySql->slimit;
4622 4623 4624 4625
  
  tscTrace("%p limit:%d, offset:%" PRId64 " slimit:%d, soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
4626
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
4627
    return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
4628 4629
  }

4630
  if (pQueryInfo->limit.limit == 0) {
S
slguan 已提交
4631
    tscTrace("%p limit 0, no output result", pSql);
4632
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4633
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
4634 4635
  }

H
hjxilinx 已提交
4636
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
4637
    bool queryOnTags = false;
4638
    if (tscQueryOnlyMetricTags(pQueryInfo, &queryOnTags) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4639 4640 4641 4642
      return TSDB_CODE_INVALID_SQL;
    }

    if (queryOnTags == true) {  // local handle the metric tag query
4643
      pQueryInfo->command = TSDB_SQL_RETRIEVE_TAGS;
S
slguan 已提交
4644
    } else {
4645
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
4646 4647 4648
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
          return invalidSqlErrMsg(pQueryInfo->msg, msg3);
        }
H
hjxilinx 已提交
4649

4650
        // for projection query on super table, all queries are subqueries
4651
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
4652
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
4653
        }
S
slguan 已提交
4654
      }
H
hzcheng 已提交
4655 4656
    }

4657
    if (pQueryInfo->slimit.limit == 0) {
4658
      tscTrace("%p slimit 0, no output result", pSql);
4659
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4660 4661 4662 4663
      return TSDB_CODE_SUCCESS;
    }

    /*
4664 4665 4666 4667
     * 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 已提交
4668
     */
4669
    int32_t code = tscGetMetricMeta(pSql, clauseIndex);
H
hzcheng 已提交
4670 4671 4672 4673
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
4674
    // No tables included. No results generated. Query results are empty.
H
hjxilinx 已提交
4675 4676
    SSuperTableMeta* pMetricMeta = pTableMetaInfo->pMetricMeta;
    if (pTableMetaInfo->pTableMeta == NULL || pMetricMeta == NULL || pMetricMeta->numOfTables == 0) {
H
hzcheng 已提交
4677
      tscTrace("%p no table in metricmeta, no output result", pSql);
4678
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4679 4680 4681
    }

    // keep original limitation value in globalLimit
4682
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4683
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
4684

4685 4686 4687 4688 4689 4690 4691 4692 4693
    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 已提交
4694

4695 4696
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
4697
  } else {
4698 4699
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4700 4701
    }

S
slguan 已提交
4702
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
4703
    for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4704
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4705
      if (pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX) {
4706
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4707 4708 4709 4710 4711 4712
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}
4713

4714
static int32_t setKeepOption(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
hjxilinx 已提交
4715
  const char* msg = "invalid number of options";
H
hjxilinx 已提交
4716

4717 4718 4719
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
4720

H
hjxilinx 已提交
4721 4722 4723
  tVariantList* pKeep = pCreateDb->keep;
  if (pKeep != NULL) {
    switch (pKeep->nExpr) {
S
slguan 已提交
4724
      case 1:
H
hjxilinx 已提交
4725
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
4726 4727
        break;
      case 2: {
H
hjxilinx 已提交
4728 4729
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl(pKeep->a[1].pVar.i64Key);
4730 4731 4732
        break;
      }
      case 3: {
H
hjxilinx 已提交
4733 4734 4735
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl(pKeep->a[1].pVar.i64Key);
        pMsg->daysToKeep2 = htonl(pKeep->a[2].pVar.i64Key);
4736 4737
        break;
      }
4738
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
4739 4740
    }
  }
H
hjxilinx 已提交
4741

H
hjxilinx 已提交
4742 4743
  return TSDB_CODE_SUCCESS;
}
4744

4745
static int32_t setTimePrecisionOption(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDbInfo) {
H
hjxilinx 已提交
4746
  const char* msg = "invalid time precision";
H
hjxilinx 已提交
4747

H
hjxilinx 已提交
4748
  pMsg->precision = TSDB_TIME_PRECISION_MILLI;  // millisecond by default
H
hjxilinx 已提交
4749

H
hjxilinx 已提交
4750
  SSQLToken* pToken = &pCreateDbInfo->precision;
4751 4752
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
4753

4754 4755 4756 4757 4758
    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 已提交
4759
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
4760 4761
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
4762
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
4763 4764
    }
  }
H
hjxilinx 已提交
4765

H
hjxilinx 已提交
4766 4767
  return TSDB_CODE_SUCCESS;
}
4768

4769
static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
S
slguan 已提交
4770
  pMsg->blocksPerTable = htons(pCreateDb->numOfBlocksPerTable);
H
hjxilinx 已提交
4771 4772
  pMsg->compression = pCreateDb->compressionLevel;

H
hjxilinx 已提交
4773
  pMsg->commitLog = (char)pCreateDb->commitLog;
H
hjxilinx 已提交
4774 4775 4776 4777 4778 4779 4780 4781 4782 4783
  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) {
4784
  SCMCreateDbMsg* pMsg = (SCMCreateDbMsg*)(pCmd->payload);
H
hjxilinx 已提交
4785
  setCreateDBOption(pMsg, pCreateDbSql);
H
hjxilinx 已提交
4786

H
hjxilinx 已提交
4787 4788 4789
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
4790

H
hjxilinx 已提交
4791 4792 4793
  if (setTimePrecisionOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
4794

H
hjxilinx 已提交
4795 4796 4797
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
4798

4799
  return TSDB_CODE_SUCCESS;
H
huili 已提交
4800
}
S
slguan 已提交
4801

4802
void tscAddTimestampColumn(SQueryInfo* pQueryInfo, int16_t functionId, int16_t tableIndex) {
S
slguan 已提交
4803 4804
  // the first column not timestamp column, add it
  SSqlExpr* pExpr = NULL;
4805 4806
  if (pQueryInfo->exprsInfo.numOfExprs > 0) {
    pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4807 4808 4809 4810 4811
  }

  if (pExpr == NULL || pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX || pExpr->functionId != functionId) {
    SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};

4812
    pExpr = tscSqlExprInsert(pQueryInfo, 0, functionId, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE);
S
slguan 已提交
4813 4814 4815 4816 4817
    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 已提交
4818
    insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, "ts", pExpr);
S
slguan 已提交
4819 4820 4821
  }
}

4822 4823
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
4824

4825 4826
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
4827 4828
    int32_t     num = pQueryInfo->exprsInfo.numOfExprs;

4829
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, num - 1);
4830

S
slguan 已提交
4831
    if (pExpr->functionId != TSDB_FUNC_TAG) {
H
hjxilinx 已提交
4832
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
4833
      int16_t         columnInfo = tscGetJoinTagColIndexByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid);
4834
      SColumnIndex    index = {.tableIndex = 0, .columnIndex = columnInfo};
H
hjxilinx 已提交
4835
      SSchema*        pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
4836 4837 4838 4839 4840

      int16_t type = pSchema[index.columnIndex].type;
      int16_t bytes = pSchema[index.columnIndex].bytes;
      char*   name = pSchema[index.columnIndex].name;

H
hjxilinx 已提交
4841
      pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_TAG, &index, type, bytes,
4842
                               bytes);
S
slguan 已提交
4843 4844 4845 4846
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
      SColumnList ids = {0};
H
hjxilinx 已提交
4847
      insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, &ids, bytes, type, name, pExpr);
S
slguan 已提交
4848 4849 4850 4851

      int32_t relIndex = index.columnIndex;

      pExpr->colInfo.colIdx = relIndex;
4852
      pQueryInfo->groupbyExpr.columnInfo[0].colIdx = relIndex;
S
slguan 已提交
4853

4854
      addRequiredTagColumn(pQueryInfo, pQueryInfo->groupbyExpr.columnInfo[0].colIdx, 0);
S
slguan 已提交
4855 4856 4857 4858
    }
  }
}

H
hjxilinx 已提交
4859 4860 4861
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
4862
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
4863 4864 4865
  pExpr->numOfParams = 1;
}

4866 4867
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
  int32_t index = pQueryInfo->groupbyExpr.columnInfo[tagIndex].colIdx;
S
slguan 已提交
4868

H
hjxilinx 已提交
4869
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
4870

H
hjxilinx 已提交
4871
  SSchema*     pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index);
S
slguan 已提交
4872 4873
  SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = index};

H
hjxilinx 已提交
4874
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_PRJ, &colIndex,
4875
                                     pSchema->type, pSchema->bytes, pSchema->bytes);
S
slguan 已提交
4876 4877

  pExpr->colInfo.flag = TSDB_COL_NORMAL;
H
hjxilinx 已提交
4878
  doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
4879

S
slguan 已提交
4880 4881 4882 4883 4884
  // NOTE: tag column does not add to source column list
  SColumnList list = {0};
  list.num = 1;
  list.ids[0] = colIndex;

H
hjxilinx 已提交
4885
  insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs - 1, &list, pSchema->bytes, pSchema->type,
H
hjxilinx 已提交
4886
                    pSchema->name, pExpr);
H
hjxilinx 已提交
4887
  tscFieldInfoUpdateVisible(&pQueryInfo->fieldsInfo, pQueryInfo->exprsInfo.numOfExprs - 1, false);
S
slguan 已提交
4888 4889
}

4890
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4891
  int32_t tagLength = 0;
H
hjxilinx 已提交
4892
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4893
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4894 4895 4896 4897 4898 4899 4900 4901 4902
    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 已提交
4903
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
4904
  SSchema*        pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
4905

H
hjxilinx 已提交
4906
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4907
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4908
    if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) {
S
slguan 已提交
4909
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIdx];
S
slguan 已提交
4910 4911 4912 4913 4914 4915
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, pExpr->param[0].i64Key, &pExpr->resType,
                        &pExpr->resBytes, &pExpr->interResBytes, tagLength, true);
    }
  }
}

4916
static void doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
4917
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4918
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
4919 4920
    if (pExpr->functionId == TSDB_FUNC_PRJ) {
      bool qualifiedCol = false;
4921 4922
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
        if (pExpr->colInfo.colId == pQueryInfo->groupbyExpr.columnInfo[j].colId) {
H
hjxilinx 已提交
4923
          qualifiedCol = true;
H
hjxilinx 已提交
4924
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
4925 4926 4927 4928
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
4929

H
hjxilinx 已提交
4930 4931 4932 4933 4934
      assert(qualifiedCol);
    }
  }
}

S
slguan 已提交
4935 4936 4937 4938 4939 4940 4941 4942 4943 4944
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;
}

4945
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4946 4947 4948
  bool hasTagPrj = false;
  bool hasColumnPrj = false;

H
hjxilinx 已提交
4949
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4950
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961
    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
4962
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4963 4964
  bool allInGroupby = true;

H
hjxilinx 已提交
4965
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4966
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4967 4968 4969 4970
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

4971
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
4972 4973 4974 4975 4976 4977 4978 4979 4980
      allInGroupby = false;
      break;
    }
  }

  // all selected tag columns belong to the group by columns set, always correct
  return allInGroupby;
}

4981
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
4982
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
4983
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995
    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.
 */
4996
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4997
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
4998
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
4999

S
slguan 已提交
5000 5001 5002 5003
  bool    tagColExists = false;
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5004
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
5005
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5006 5007 5008 5009 5010 5011
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
      tagColExists = true;
      break;
    }
  }
H
hjxilinx 已提交
5012

H
hjxilinx 已提交
5013
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
5014
    int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
5015
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5016
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5017
      continue;
S
slguan 已提交
5018
    }
H
hjxilinx 已提交
5019

H
hjxilinx 已提交
5020 5021 5022 5023 5024 5025
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5026

H
hjxilinx 已提交
5027
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5028 5029
    // 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.
5030
    if (numOfAggregation > 0) {
5031
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5032 5033 5034 5035 5036 5037
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5038 5039
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5040 5041 5042 5043 5044
    } 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 已提交
5045
      for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
5046
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5047 5048 5049 5050 5051
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5052
          return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5053 5054 5055
        }
      }

5056 5057
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5058 5059
    }
  } else {
5060 5061 5062
    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 已提交
5063
      }
H
hjxilinx 已提交
5064

H
hjxilinx 已提交
5065 5066
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5067 5068
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5069
      }
S
slguan 已提交
5070 5071 5072 5073 5074 5075
    }
  }

  return TSDB_CODE_SUCCESS;
}

5076
static int32_t doAddGroupbyColumnsOnDemand(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5077 5078
  const char* msg2 = "interval not allowed in group by normal column";

H
hjxilinx 已提交
5079
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
5080

H
hjxilinx 已提交
5081
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5082 5083 5084 5085
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5086 5087
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
    SColIndexEx* pColIndex = &pQueryInfo->groupbyExpr.columnInfo[i];
S
slguan 已提交
5088 5089 5090 5091

    int16_t colIndex = pColIndex->colIdx;
    if (pColIndex->colIdx == TSDB_TBNAME_COLUMN_INDEX) {
      type = TSDB_DATA_TYPE_BINARY;
S
slguan 已提交
5092
      bytes = TSDB_TABLE_NAME_LEN;
S
slguan 已提交
5093 5094
      name = TSQL_TBNAME_L;
    } else {
H
hjxilinx 已提交
5095
      colIndex = (TSDB_COL_IS_TAG(pColIndex->flag)) ? tscGetNumOfColumns(pTableMetaInfo->pTableMeta) + pColIndex->colIdx
S
slguan 已提交
5096 5097 5098 5099 5100 5101 5102 5103
                                                    : pColIndex->colIdx;

      type = pSchema[colIndex].type;
      bytes = pSchema[colIndex].bytes;
      name = pSchema[colIndex].name;
    }

    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5104
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
S
slguan 已提交
5105

H
hjxilinx 已提交
5106
      SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs, TSDB_FUNC_TAG, &index,
5107
                                         type, bytes, bytes);
S
slguan 已提交
5108 5109 5110 5111 5112

      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
      SColumnList ids = {0};
H
hjxilinx 已提交
5113
      insertResultField(pQueryInfo, pQueryInfo->exprsInfo.numOfExprs-1, &ids, bytes, type, name, pExpr);
S
slguan 已提交
5114 5115
    } else {
      // if this query is "group by" normal column, interval is not allowed
5116
      if (pQueryInfo->intervalTime > 0) {
5117
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
5118 5119 5120
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5121
      for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) {
5122
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5123 5124 5125 5126 5127 5128 5129 5130 5131 5132
        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) {
5133
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5134 5135 5136 5137 5138 5139 5140
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5141
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5142
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5143
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5144
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5145
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5146 5147 5148

  // only retrieve tags, group by is not supportted
  if (pCmd->command == TSDB_SQL_RETRIEVE_TAGS) {
5149
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5150
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5151 5152 5153 5154 5155
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5156
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5157
    // check if all the tags prj columns belongs to the group by columns
5158 5159 5160
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
      return doAddGroupbyColumnsOnDemand(pQueryInfo);
S
slguan 已提交
5161 5162 5163
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5164
    for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
5165
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5166 5167 5168 5169 5170 5171
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5172
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5173
        bool qualified = false;
5174 5175
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
          SColIndexEx* pColIndex = &pQueryInfo->groupbyExpr.columnInfo[j];
S
slguan 已提交
5176 5177 5178 5179 5180 5181 5182
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5183
          return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
5184 5185 5186 5187
        }
      }

      if (IS_MULTIOUTPUT(aAggs[functId].nStatus) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM &&
H
hjxilinx 已提交
5188
          functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) {
5189
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5190 5191 5192
      }

      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX) {
5193
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5194 5195 5196
      }
    }

5197
    if (checkUpdateTagPrjFunctions(pQueryInfo) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
5198 5199 5200 5201 5202 5203 5204
      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.
     */
5205
    if (doAddGroupbyColumnsOnDemand(pQueryInfo) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
5206 5207 5208 5209
      return TSDB_CODE_INVALID_SQL;
    }

    // projection query on metric does not compatible with "group by" syntax
5210
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5211
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5212
    }
H
hjxilinx 已提交
5213

H
hjxilinx 已提交
5214
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5215
  } else {
5216
    return checkUpdateTagPrjFunctions(pQueryInfo);
S
slguan 已提交
5217 5218
  }
}
H
hjxilinx 已提交
5219

5220
int32_t doLocalQueryProcess(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5221 5222 5223
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5224

H
hjxilinx 已提交
5225 5226
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5227
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hjxilinx 已提交
5228
  }
H
hjxilinx 已提交
5229

H
hjxilinx 已提交
5230 5231
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5232
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hjxilinx 已提交
5233
  }
H
hjxilinx 已提交
5234

H
hjxilinx 已提交
5235
  // TODO redefine the function
H
hjxilinx 已提交
5236 5237 5238 5239 5240 5241
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5242
  int32_t index = -1;
H
hjxilinx 已提交
5243
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5244
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5245
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5246 5247 5248 5249
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5250

5251
  SSqlExpr* pExpr1 = tscSqlExprInsertEmpty(pQueryInfo, 0, TSDB_FUNC_TAG_DUMMY);
H
hjxilinx 已提交
5252 5253
  const char* name = (pExprList->a[0].aliasName != NULL)? pExprList->a[0].aliasName:functionsInfo[index].name;
  strncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
hjxilinx 已提交
5254 5255 5256

  switch (index) {
    case 0:
5257
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;
H
hjxilinx 已提交
5258 5259
      return TSDB_CODE_SUCCESS;
    case 1:
5260
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;
H
hjxilinx 已提交
5261 5262
      return TSDB_CODE_SUCCESS;
    case 2:
5263
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;
H
hjxilinx 已提交
5264 5265
      return TSDB_CODE_SUCCESS;
    case 3:
5266
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;
H
hjxilinx 已提交
5267 5268
      return TSDB_CODE_SUCCESS;
    case 4:
5269
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;
H
hjxilinx 已提交
5270
      return TSDB_CODE_SUCCESS;
5271
    default: { return invalidSqlErrMsg(pQueryInfo->msg, msg3); }
H
hjxilinx 已提交
5272 5273
  }
}
H
hjxilinx 已提交
5274 5275

// can only perform the parameters based on the macro definitation
5276
int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate) {
H
hjxilinx 已提交
5277
  char msg[512] = {0};
H
hjxilinx 已提交
5278

H
hjxilinx 已提交
5279 5280
  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);
5281
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5282
  }
H
hjxilinx 已提交
5283

H
hjxilinx 已提交
5284 5285
  if (pCreate->replications != -1 &&
      (pCreate->replications < TSDB_REPLICA_MIN_NUM || pCreate->replications > TSDB_REPLICA_MAX_NUM)) {
H
hjxilinx 已提交
5286 5287
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
             TSDB_REPLICA_MIN_NUM, TSDB_REPLICA_MAX_NUM);
5288
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5289
  }
H
hjxilinx 已提交
5290

H
hjxilinx 已提交
5291 5292 5293 5294
  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);
5295
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5296
  }
H
hjxilinx 已提交
5297

H
hjxilinx 已提交
5298 5299 5300 5301
  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);
5302
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5303
  }
H
hjxilinx 已提交
5304

H
hjxilinx 已提交
5305 5306 5307 5308
  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);
5309
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5310
  }
H
hjxilinx 已提交
5311

H
hjxilinx 已提交
5312 5313
  val = htonl(pCreate->maxSessions);
  if (val != -1 && (val < TSDB_MIN_TABLES_PER_VNODE || val > TSDB_MAX_TABLES_PER_VNODE)) {
H
hjxilinx 已提交
5314 5315
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
             TSDB_MIN_TABLES_PER_VNODE, TSDB_MAX_TABLES_PER_VNODE);
5316
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5317
  }
H
hjxilinx 已提交
5318 5319 5320 5321

  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);
5322
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5323
  }
H
hjxilinx 已提交
5324

H
hjxilinx 已提交
5325
  if (pCreate->cacheNumOfBlocks.fraction != -1 && (pCreate->cacheNumOfBlocks.fraction < TSDB_MIN_AVG_BLOCKS ||
H
hjxilinx 已提交
5326 5327 5328
                                                   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);
5329
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5330
  }
H
hjxilinx 已提交
5331

H
hjxilinx 已提交
5332 5333 5334 5335
  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);
5336
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5337
  }
H
hjxilinx 已提交
5338

H
hjxilinx 已提交
5339 5340
  if (pCreate->compression != -1 &&
      (pCreate->compression < TSDB_MIN_COMPRESSION_LEVEL || pCreate->compression > TSDB_MAX_COMPRESSION_LEVEL)) {
H
hjxilinx 已提交
5341 5342
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
             TSDB_MIN_COMPRESSION_LEVEL, TSDB_MAX_COMPRESSION_LEVEL);
5343
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5344
  }
H
hjxilinx 已提交
5345

H
hjxilinx 已提交
5346 5347
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5348 5349

// for debug purpose
H
hjxilinx 已提交
5350 5351
void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) {
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
5352

H
hjxilinx 已提交
5353
  if (pQueryInfo->exprsInfo.numOfExprs == 0) {
H
hjxilinx 已提交
5354 5355
    return;
  }
H
hjxilinx 已提交
5356

H
hjxilinx 已提交
5357
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5358 5359

  char    str[1024] = {0};
H
hjxilinx 已提交
5360
  int32_t offset = 0;
H
hjxilinx 已提交
5361

H
hjxilinx 已提交
5362
  offset += sprintf(str, "num:%d [", pQueryInfo->exprsInfo.numOfExprs);
5363 5364
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5365

L
lihui 已提交
5366
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5367 5368 5369
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5370 5371 5372
    if (tmpLen + offset > totalBufSize) break;

    offset += sprintf(str + offset, "%s", tmpBuf);
H
hjxilinx 已提交
5373

5374
    if (i < pQueryInfo->exprsInfo.numOfExprs - 1) {
H
hjxilinx 已提交
5375 5376 5377
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5378

H
hjxilinx 已提交
5379
  str[offset] = ']';
H
hjxilinx 已提交
5380
  tscTrace("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5381
}
5382

5383
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5384 5385 5386
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5387 5388
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5389
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401

  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) {
5402
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5403 5404
  }

H
hjxilinx 已提交
5405
  if (setMeterID(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5406
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5407 5408 5409 5410 5411 5412 5413 5414 5415
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
    return TSDB_CODE_INVALID_SQL;
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
5416
    tscFieldInfoSetValFromField(&pQueryInfo->fieldsInfo, col, &pFieldList->p[col]);
5417 5418 5419 5420 5421 5422
  }

  pCmd->numOfCols = (int16_t)pFieldList->nField;

  if (pTagList != NULL) {  // create metric[optional]
    for (int32_t i = 0; i < pTagList->nField; ++i) {
5423
      tscFieldInfoSetValFromField(&pQueryInfo->fieldsInfo, col++, &pTagList->p[i]);
5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440
    }

    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;
5441 5442 5443
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
H
hjxilinx 已提交
5444
  tscAddEmptyMetaInfo(pQueryInfo);
5445 5446 5447 5448 5449
  assert(pQueryInfo->numOfTables == 2);

  const int32_t TABLE_INDEX = 0;
  const int32_t STABLE_INDEX = 1;

H
hjxilinx 已提交
5450
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5451 5452 5453 5454 5455

  // super table name, create table by using dst
  SSQLToken* pToken = &(pCreateTable->usingInfo.stableName);

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5456
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5457 5458
  }

5459
  if (setMeterID(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5460
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5461 5462 5463
  }

  // get meter meta from mnode
S
slguan 已提交
5464
  strncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, TSDB_TABLE_ID_LEN);
5465 5466
  tVariantList* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;

H
hjxilinx 已提交
5467
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5468 5469 5470 5471
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5472
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5473
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5474 5475 5476
  }

  // too long tag values will return invalid sql, not be truncated automatically
H
hjxilinx 已提交
5477
  SSchema* pTagSchema = tscGetTableTagSchema(pStableMeterMetaInfo->pTableMeta);
5478 5479 5480 5481 5482

  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) {
5483
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5484 5485 5486 5487 5488
    }

    // 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) {
5489
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
5490 5491 5492 5493 5494 5495 5496
    }

    tagVal += pTagSchema[i].bytes;
  }

  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5497
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5498 5499
  }

H
hjxilinx 已提交
5500
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
5501
  int32_t         ret = setMeterID(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515
  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

5516
  SSqlCmd*    pCmd = &pSql->cmd;
5517
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5518 5519
  assert(pQueryInfo->numOfTables == 1);

5520
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5521
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5522 5523 5524 5525 5526 5527

  // if sql specifies db, use it, otherwise use default db
  SSQLToken* pzTableName = &(pCreateTable->name);
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5528
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5529 5530 5531 5532 5533 5534 5535
  }

  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) {
5536
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
5537 5538
  }

H
hjxilinx 已提交
5539
  if (setMeterID(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5540
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
5541 5542
  }

H
hjxilinx 已提交
5543
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5544 5545 5546 5547
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5548
  bool isSTable = UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo);
5549
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5550 5551 5552 5553
    return TSDB_CODE_INVALID_SQL;
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5554
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5555 5556 5557 5558 5559
      return TSDB_CODE_INVALID_SQL;
    }
  }

  // set interval value
5560
  if (parseIntervalClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5561 5562
    return TSDB_CODE_INVALID_SQL;
  } else {
5563
    if ((pQueryInfo->intervalTime > 0) &&
5564
        (validateFunctionsInIntervalOrGroupbyQuery(pQueryInfo) != TSDB_CODE_SUCCESS)) {
5565 5566 5567 5568 5569
      return TSDB_CODE_INVALID_SQL;
    }
  }

  // set the created table[stream] name
H
hjxilinx 已提交
5570
  if (setMeterID(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5571
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
5572 5573 5574
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5575
    return invalidSqlErrMsg(pQueryInfo->msg, msg5);
5576 5577
  }

5578
  if (tsRewriteFieldNameIfNecessary(pQueryInfo) != TSDB_CODE_SUCCESS) {
5579 5580 5581
    return TSDB_CODE_INVALID_SQL;
  }

5582
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutputCols;
5583

5584
  if (validateSqlFunctionInStreamSql(pQueryInfo) != TSDB_CODE_SUCCESS) {
5585 5586 5587 5588 5589 5590 5591 5592
    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) {
5593
    if (pQueryInfo->intervalTime == 0) {
5594
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
5595 5596 5597 5598 5599 5600
    }

    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))) {
5601
        return invalidSqlErrMsg(pQueryInfo->msg, msg4);
5602 5603 5604 5605 5606
      }
    }
  }

  // set the number of stream table columns
5607
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutputCols;
5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623
  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;
5624

5625
  SSqlCmd* pCmd = &pSql->cmd;
5626

5627
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
5628
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5629
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
5630
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
5631
  }
H
hjxilinx 已提交
5632

5633 5634
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
5635
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647
  }

  /*
   * 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);
5648
    return doLocalQueryProcess(pQueryInfo, pQuerySql);
5649 5650 5651
  }

  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM) {
5652
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
5653 5654
  }

5655
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
5656

5657 5658 5659 5660 5661
  // 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) {
5662
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5663 5664 5665 5666 5667 5668
    }

    pTableItem->nLen = strdequote(pTableItem->pz);

    SSQLToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
5669
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5670 5671
    }

5672
    if (pQueryInfo->numOfTables <= i) {  // more than one table
H
hjxilinx 已提交
5673
      tscAddEmptyMetaInfo(pQueryInfo);
5674 5675
    }

H
hjxilinx 已提交
5676
    STableMetaInfo* pMeterInfo1 = tscGetMetaInfo(pQueryInfo, i);
5677

5678
    SSQLToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
5679
    if (setMeterID(pMeterInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
5680
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5681 5682
    }

H
hjxilinx 已提交
5683
    code = tscGetTableMeta(pSql, pMeterInfo1);
5684 5685 5686 5687 5688
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

5689 5690
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr);

5691
  // parse the group by clause in the first place
5692
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
5693 5694 5695
    return TSDB_CODE_INVALID_SQL;
  }

H
hjxilinx 已提交
5696
  bool isSTable = UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo);
5697
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5698 5699 5700 5701
    return TSDB_CODE_INVALID_SQL;
  }

  // set interval value
5702
  if (parseIntervalClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5703 5704
    return TSDB_CODE_INVALID_SQL;
  } else {
5705
    if ((pQueryInfo->intervalTime > 0) &&
5706
        (validateFunctionsInIntervalOrGroupbyQuery(pQueryInfo) != TSDB_CODE_SUCCESS)) {
5707 5708 5709 5710 5711
      return TSDB_CODE_INVALID_SQL;
    }
  }

  // set order by info
H
hjxilinx 已提交
5712
  if (parseOrderbyClause(pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
5713 5714 5715 5716
    return TSDB_CODE_INVALID_SQL;
  }

  // set where info
H
hjxilinx 已提交
5717
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
5718
  
5719
  if (pQuerySql->pWhere != NULL) {
5720
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5721 5722 5723 5724
      return TSDB_CODE_INVALID_SQL;
    }

    pQuerySql->pWhere = NULL;
H
hjxilinx 已提交
5725
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
5726 5727
      pQueryInfo->stime = pQueryInfo->stime / 1000;
      pQueryInfo->etime = pQueryInfo->etime / 1000;
5728 5729
    }
  } else {  // set the time rang
5730 5731
    pQueryInfo->stime = 0;
    pQueryInfo->etime = INT64_MAX;
5732 5733 5734
  }

  // user does not specified the query time window, twa is not allowed in such case.
5735
  if ((pQueryInfo->stime == 0 || pQueryInfo->etime == INT64_MAX ||
H
hjxilinx 已提交
5736
       (pQueryInfo->etime == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
5737
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
5738 5739 5740
  }

  // no result due to invalid query time range
5741
  if (pQueryInfo->stime > pQueryInfo->etime) {
5742
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
5743 5744 5745
    return TSDB_CODE_SUCCESS;
  }

5746 5747
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
5748 5749 5750
  }

  // in case of join query, time range is required.
5751 5752
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    int64_t timeRange = labs(pQueryInfo->stime - pQueryInfo->etime);
5753

5754 5755
    if (timeRange == 0 && pQueryInfo->stime == 0) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
5756 5757 5758
    }
  }

5759
  if ((code = parseLimitClause(pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
5760 5761 5762
    return code;
  }

5763
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
5764 5765 5766
    return code;
  }

5767
  setColumnOffsetValueInResultset(pQueryInfo);
5768

5769 5770
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
    updateTagColumnIndex(pQueryInfo, i);
5771
  }
H
hjxilinx 已提交
5772

5773 5774 5775 5776 5777
  /*
   * 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) {
5778
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
5779 5780
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
5781

5782
    if (pQueryInfo->intervalTime > 0) {
5783 5784
      int64_t timeRange = labs(pQueryInfo->stime - pQueryInfo->etime);
      // number of result is not greater than 10,000,000
5785
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_RETRIEVE_ROWS_IN_INTERVAL_QUERY) {
5786 5787 5788
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
      }
    }
H
hjxilinx 已提交
5789

5790 5791 5792 5793 5794
    int32_t ret = parseFillClause(pQueryInfo, pQuerySql);
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
5795 5796 5797

  return TSDB_CODE_SUCCESS;  // Does not build query message here
}
H
hjxilinx 已提交
5798

H
hjxilinx 已提交
5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831
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 已提交
5832 5833 5834
        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 已提交
5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 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
          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 已提交
5875
}