tscSQLParser.c 215.9 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

16 17
#define _BSD_SOURCE
#define _XOPEN_SOURCE 500
S
slguan 已提交
18
#define _DEFAULT_SOURCE
H
hzcheng 已提交
19

S
slguan 已提交
20
#include "os.h"
H
Haojun Liao 已提交
21
#include "qAst.h"
H
hzcheng 已提交
22
#include "taos.h"
S
slguan 已提交
23
#include "taosmsg.h"
H
Haojun Liao 已提交
24 25
#include "tcompare.h"
#include "tname.h"
S
slguan 已提交
26
#include "tscLog.h"
H
hzcheng 已提交
27 28 29
#include "tscUtil.h"
#include "tschemautil.h"
#include "tsclient.h"
H
Haojun Liao 已提交
30 31
#include "tstoken.h"
#include "tstrbuild.h"
32
#include "ttokendef.h"
H
hjxilinx 已提交
33

S
slguan 已提交
34 35
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"

H
Haojun Liao 已提交
36 37
// -1 is tbname column index, so here use the -3 as the initial value
#define COLUMN_INDEX_INITIAL_VAL (-3)
S
slguan 已提交
38 39 40 41
#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

H
Haojun Liao 已提交
43
typedef struct SColumnList {  // todo refactor
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 colIndex, 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
Haojun Liao 已提交
54 55
static void getCurrentDBName(SSqlObj* pSql, SStrToken* pDBToken);
static bool hasSpecifyDB(SStrToken* pTableName);
H
hzcheng 已提交
56 57 58
static bool validateTableColumnInfo(tFieldList* pFieldList, SSqlCmd* pCmd);
static bool validateTagParams(tFieldList* pTagsList, tFieldList* pFieldList, SSqlCmd* pCmd);

H
Haojun Liao 已提交
59
static int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* 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(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, 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(SSqlCmd* pCmd, 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 78
static int32_t parseIntervalClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
H
hzcheng 已提交
79

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

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

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

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

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

H
Haojun Liao 已提交
107
static int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
108
static int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
109
static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
110
static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate);
H
hjxilinx 已提交
111

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

114
static int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo);
115 116 117
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);
118
static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols);
H
hjxilinx 已提交
119

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

128
static int setColumnFilterInfoForTimestamp(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tVariant* pVar) {
S
slguan 已提交
129 130 131 132 133
  int64_t     time = 0;
  const char* msg = "invalid timestamp";

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

H
hjxilinx 已提交
136
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
137
  
S
slguan 已提交
138
  if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
139
    if (taosParseTime(pVar->pz, &time, pVar->nLen, tinfo.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
140
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
141 142
    }
  } else {
143
    if (tVariantDump(pVar, (char*)&time, TSDB_DATA_TYPE_BIGINT, true)) {
144
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
145 146 147 148 149 150 151 152 153
    }
  }

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

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
154
static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) {
155 156 157 158 159
  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) {
160
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
161 162 163
  }

  strdequote(pPwd->z);
S
TD-1057  
Shengliang Guan 已提交
164
  pPwd->n = (uint32_t)strtrim(pPwd->z);  // trim space before and after passwords
165 166

  if (pPwd->n <= 0) {
167
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
168 169
  }

B
Bomin Zhang 已提交
170
  if (pPwd->n >= TSDB_PASSWORD_LEN) {
171
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
172 173 174 175 176
  }

  return TSDB_CODE_SUCCESS;
}

H
hzcheng 已提交
177 178
int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
  if (pInfo == NULL || pSql == NULL || pSql->signature != pSql) {
179
    return TSDB_CODE_TSC_APP_ERROR;
H
hzcheng 已提交
180 181
  }

182
  SSqlCmd*    pCmd = &(pSql->cmd);
183
  SQueryInfo* pQueryInfo = NULL;
H
hzcheng 已提交
184

185
  if (!pInfo->valid) {
186
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), pInfo->pzErrMsg);
H
hzcheng 已提交
187 188
  }

189
  int32_t code = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex, &pQueryInfo);
H
hjxilinx 已提交
190

H
hjxilinx 已提交
191 192 193 194
  STableMetaInfo* pTableMetaInfo = NULL;
  if (pQueryInfo->numOfTables == 0) {
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
  } else {
195
    pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
H
hjxilinx 已提交
196
  }
197

198 199 200 201 202 203 204 205
  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: {
206
      const char* msg2 = "invalid name";
207
      const char* msg3 = "param name too long";
H
hzcheng 已提交
208

H
Haojun Liao 已提交
209
      SStrToken* pzName = &pInfo->pDCLInfo->a[0];
210
      if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (tscValidateName(pzName) != TSDB_CODE_SUCCESS)) {
211
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
212 213
      }

214 215
      if (pInfo->type == TSDB_SQL_DROP_DB) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
216

H
hjxilinx 已提交
217
        code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pzName, NULL, NULL);
H
hzcheng 已提交
218
        if (code != TSDB_CODE_SUCCESS) {
219
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
220 221
        }

222 223
      } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
224

H
Haojun Liao 已提交
225
        if (tscSetTableFullName(pTableMetaInfo, pzName, pSql) != TSDB_CODE_SUCCESS) {
226
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
227
        }
228
      } else if (pInfo->type == TSDB_SQL_DROP_DNODE) {
S
slguan 已提交
229
        pzName->n = strdequote(pzName->z);
H
hjxilinx 已提交
230
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
231
      } else {  // drop user
B
Bomin Zhang 已提交
232
        if (pzName->n >= TSDB_USER_LEN) {
233
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
234 235
        }

H
hjxilinx 已提交
236
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
237 238
      }

239 240
      break;
    }
H
hzcheng 已提交
241

242 243
    case TSDB_SQL_USE_DB: {
      const char* msg = "invalid db name";
H
Haojun Liao 已提交
244
      SStrToken*  pToken = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
245 246

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
247
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
248 249
      }

H
hjxilinx 已提交
250
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pToken, NULL, NULL);
H
hzcheng 已提交
251
      if (ret != TSDB_CODE_SUCCESS) {
252
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
253 254 255 256 257
      }

      break;
    }

258 259
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
260 261
    }

262 263
    case TSDB_SQL_SHOW: {
      if (setShowInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
264
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
265 266
      }

267 268 269 270 271 272 273 274
      break;
    }

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

275
      SCreateDBInfo* pCreateDB = &(pInfo->pDCLInfo->dbOpt);
H
hzcheng 已提交
276
      if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) {
277
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
278 279
      }

H
hjxilinx 已提交
280
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname), NULL, NULL);
H
hzcheng 已提交
281
      if (ret != TSDB_CODE_SUCCESS) {
282
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
283 284
      }

H
hjxilinx 已提交
285
      if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
286
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
287 288 289 290 291
      }

      break;
    }

292 293
    case TSDB_SQL_CREATE_DNODE: {  // todo hostname
      const char* msg = "invalid host name (ip address)";
S
slguan 已提交
294

295
      if (pInfo->pDCLInfo->nTokens > 1) {
296
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
297 298
      }

H
Haojun Liao 已提交
299
      SStrToken* pIpAddr = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
300
      pIpAddr->n = strdequote(pIpAddr->z);
S
slguan 已提交
301 302 303
      break;
    }

304 305 306 307 308
    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 已提交
309

H
Haojun Liao 已提交
310 311
      SStrToken* pName = &pInfo->pDCLInfo->user.user;
      SStrToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
312

313
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
314
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
315 316
      }

B
Bomin Zhang 已提交
317
      if (pName->n >= TSDB_USER_LEN) {
318
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
319 320
      }

321
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
322
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
323 324 325
      }

      SCreateAcctSQL* pAcctOpt = &pInfo->pDCLInfo->acctOpt;
326
      if (pAcctOpt->stat.n > 0) {
H
hzcheng 已提交
327 328 329 330 331
        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 {
332
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
333 334
        }
      }
335

H
hzcheng 已提交
336 337 338
      break;
    }

339
    case TSDB_SQL_DESCRIBE_TABLE: {
H
Haojun Liao 已提交
340
      SStrToken*  pToken = &pInfo->pDCLInfo->a[0];
341
      const char* msg2 = "table name is too long";
H
hjxilinx 已提交
342
      const char* msg1 = "invalid table name";
H
hzcheng 已提交
343

S
slguan 已提交
344
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
345
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
346
      }
S
slguan 已提交
347

H
Haojun Liao 已提交
348
      if (!tscValidateTableNameLength(pToken->n)) {
349
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
350 351
      }

H
Haojun Liao 已提交
352
      if (tscSetTableFullName(pTableMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
353
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
354 355
      }

H
hjxilinx 已提交
356
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
357 358
    }

359
    case TSDB_SQL_CFG_DNODE: {
S
Shengliang Guan 已提交
360
      const char* msg2 = "invalid configure options or values, such as resetlog / debugFlag 135 / balance 'vnode:2-dnode:2' / monitor 1 ";
H
Hui Li 已提交
361
      const char* msg3 = "invalid dnode ep";
H
hzcheng 已提交
362

363 364
      /* validate the ip address */
      tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
365

366 367
      /* validate the parameter names and options */
      if (validateDNodeConfig(pDCL) != TSDB_CODE_SUCCESS) {
368
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
369 370
      }

guanshengliang's avatar
guanshengliang 已提交
371
      char* pMsg = pCmd->payload;
H
hzcheng 已提交
372

S
slguan 已提交
373
      SCMCfgDnodeMsg* pCfg = (SCMCfgDnodeMsg*)pMsg;
guanshengliang's avatar
guanshengliang 已提交
374 375
      pDCL->a[0].n = strdequote(pDCL->a[0].z);
      
J
jtao1735 已提交
376
      strncpy(pCfg->ep, pDCL->a[0].z, pDCL->a[0].n);
H
hzcheng 已提交
377

H
Hui Li 已提交
378 379 380 381
      if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }

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

384 385 386 387
      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 已提交
388

389 390
      break;
    }
H
hzcheng 已提交
391

392 393 394 395 396 397
    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 已提交
398

399
      pCmd->command = pInfo->type;
H
hjxilinx 已提交
400
      // tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
401

402
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
H
Haojun Liao 已提交
403 404
      SStrToken* pName = &pUser->user;
      SStrToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
405

B
Bomin Zhang 已提交
406
      if (pName->n >= TSDB_USER_LEN) {
407
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
408
      }
H
hzcheng 已提交
409

410
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
411
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
412
      }
H
hzcheng 已提交
413

414 415
      if (pCmd->command == TSDB_SQL_CREATE_USER) {
        if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
416
          return TSDB_CODE_TSC_INVALID_SQL;
417 418 419 420
        }
      } else {
        if (pUser->type == TSDB_ALTER_USER_PASSWD) {
          if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
421
            return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
422
          }
423
        } else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
L
lihui 已提交
424 425
          assert(pPwd->type == TSDB_DATA_TYPE_NULL);

H
Haojun Liao 已提交
426
          SStrToken* pPrivilege = &pUser->privilege;
H
hzcheng 已提交
427

L
lihui 已提交
428
          if (strncasecmp(pPrivilege->z, "super", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
429
            pCmd->count = 1;
L
lihui 已提交
430
          } else if (strncasecmp(pPrivilege->z, "read", 4) == 0 && pPrivilege->n == 4) {
H
hzcheng 已提交
431
            pCmd->count = 2;
L
lihui 已提交
432
          } else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
433 434
            pCmd->count = 3;
          } else {
435
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
436 437
          }
        } else {
438
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
439 440
        }
      }
441

H
hzcheng 已提交
442 443
      break;
    }
444 445

    case TSDB_SQL_CFG_LOCAL: {
S
slguan 已提交
446 447 448 449 450
      tDCLSQL*    pDCL = pInfo->pDCLInfo;
      const char* msg = "invalid configure options or values";

      // validate the parameter names and options
      if (validateLocalConfig(pDCL) != TSDB_CODE_SUCCESS) {
451
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
452 453 454 455 456 457 458
      }

      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 已提交
459 460 461 462

      break;
    }

463 464
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
465

466
      if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
467
        if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
468
          return code;
H
hzcheng 已提交
469 470
        }

471
      } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) {
472
        assert(pCmd->numOfCols == 0);
473 474
        if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
475 476
        }

477 478 479
      } else if (pCreateTable->type == TSQL_CREATE_STREAM) {
        if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
S
slguan 已提交
480
        }
H
hzcheng 已提交
481 482 483 484 485
      }

      break;
    }

486
    case TSDB_SQL_SELECT: {
H
hjxilinx 已提交
487
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
488

489
      for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) {
490 491 492 493
        SQueryInfo* pqi = NULL;
        if ((code = tscGetQueryInfoDetailSafely(pCmd, i, &pqi)) != TSDB_CODE_SUCCESS) {
          return code;
        }
494 495 496
      }

      assert(pCmd->numOfClause == pInfo->subclauseInfo.numOfClause);
H
Haojun Liao 已提交
497
      for (int32_t i = pCmd->clauseIndex; i < pInfo->subclauseInfo.numOfClause; ++i) {
498
        SQuerySQL* pQuerySql = pInfo->subclauseInfo.pClause[i];
H
Haojun Liao 已提交
499
        tscTrace("%p start to parse %dth subclause, total:%d", pSql, i, pInfo->subclauseInfo.numOfClause);
500 501
        if ((code = doCheckForQuery(pSql, pQuerySql, i)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
502
        }
H
hjxilinx 已提交
503

H
hjxilinx 已提交
504
        tscPrintSelectClause(pSql, i);
H
Haojun Liao 已提交
505
        pCmd->clauseIndex += 1;
H
hzcheng 已提交
506
      }
H
hjxilinx 已提交
507

H
Haojun Liao 已提交
508 509
      // restore the clause index
      pCmd->clauseIndex = 0;
H
hjxilinx 已提交
510
      // set the command/global limit parameters from the first subclause to the sqlcmd object
511 512
      SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
      pCmd->command = pQueryInfo1->command;
H
hjxilinx 已提交
513

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

518 519 520
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
521
        }
522
      }
523

524
      pCmd->parseFinished = 1;
525
      return TSDB_CODE_SUCCESS;  // do not build query message here
526
    }
H
hzcheng 已提交
527

528 529 530
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
531 532 533 534 535
      }

      break;
    }

536 537 538
    case TSDB_SQL_KILL_QUERY:
    case TSDB_SQL_KILL_STREAM:
    case TSDB_SQL_KILL_CONNECTION: {
539
      if ((code = setKillInfo(pSql, pInfo, pInfo->type)) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
540 541 542 543 544 545 546
        return code;
      }

      break;
    }

    default:
547
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
548 549
  }

dengyihao's avatar
dengyihao 已提交
550
  pSql->cmd.parseFinished = 1;
551
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
552 553
}

S
slguan 已提交
554 555 556 557
/*
 * if the top/bottom exists, only tags columns, tbname column, and primary timestamp column
 * are available.
 */
558
static bool isTopBottomQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
559 560 561
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = 0; i < size; ++i) {
562
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
563 564 565 566

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

S
slguan 已提交
569
  return false;
H
hzcheng 已提交
570 571
}

572
int32_t parseIntervalClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
S
slguan 已提交
573 574
  const char* msg1 = "invalid query expression";
  const char* msg2 = "interval cannot be less than 10 ms";
575

H
hjxilinx 已提交
576
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
577
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
578
  
H
hjxilinx 已提交
579
  if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
H
hzcheng 已提交
580 581 582 583
    return TSDB_CODE_SUCCESS;
  }

  // interval is not null
H
Haojun Liao 已提交
584
  SStrToken* t = &pQuerySql->interval;
585
  if (getTimestampInUsFromStr(t->z, t->n, &pQueryInfo->intervalTime) != TSDB_CODE_SUCCESS) {
586
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
587 588
  }

H
hjxilinx 已提交
589
  // if the unit of time window value is millisecond, change the value from microsecond
H
hjxilinx 已提交
590
  if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
591
    pQueryInfo->intervalTime = pQueryInfo->intervalTime / 1000;
H
hzcheng 已提交
592 593 594
  }

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

  // interval cannot be less than 10 milliseconds
598
  if (pQueryInfo->intervalTime < tsMinIntervalTime) {
599
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
600 601 602
  }

  // for top/bottom + interval query, we do not add additional timestamp column in the front
603
  if (isTopBottomQuery(pQueryInfo)) {
604
    if (parseSlidingClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
605
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
606
    }
H
hjxilinx 已提交
607

H
hzcheng 已提交
608 609 610
    return TSDB_CODE_SUCCESS;
  }

H
hjxilinx 已提交
611 612 613
  /*
   * check invalid SQL:
   * select count(tbname)/count(tag1)/count(tag2) from super_table_name interval(1d);
H
hjxilinx 已提交
614
   */
H
hjxilinx 已提交
615 616
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
617
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
618
    if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
619
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
620 621
    }
  }
H
hjxilinx 已提交
622

H
hjxilinx 已提交
623 624 625
  /*
   * check invalid SQL:
   * select tbname, tags_fields from super_table_name interval(1s)
H
hjxilinx 已提交
626
   */
H
hjxilinx 已提交
627
  if (tscQueryTags(pQueryInfo) && pQueryInfo->intervalTime > 0) {
628
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
629
  }
S
slguan 已提交
630 631

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

  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
635
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
636
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
637
    if (pTableMetaInfo->pTableMeta->id.uid == uid) {
S
slguan 已提交
638 639 640 641 642 643
      tableIndex = i;
      break;
    }
  }

  if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
644
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
645 646
  }

H
Haojun Liao 已提交
647 648
  SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tstrncpy(s.name, aAggs[TSDB_FUNC_TS].aName, sizeof(s.name));
649

H
Haojun Liao 已提交
650 651
  SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tscAddSpecialColumnForSelect(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL);
H
hjxilinx 已提交
652

653
  if (parseSlidingClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
654
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
655
  }
H
hjxilinx 已提交
656

H
hjxilinx 已提交
657
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
658 659
}

660
int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
661 662
  const char* msg0 = "sliding value too small";
  const char* msg1 = "sliding value no larger than the interval value";
H
Haojun Liao 已提交
663 664 665
  const char* msg2 = "sliding value can not less than 1% of interval value";

  const static int32_t INTERVAL_SLIDING_FACTOR = 100;
H
hzcheng 已提交
666

H
hjxilinx 已提交
667
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
668
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
669

H
Haojun Liao 已提交
670
  SStrToken* pSliding = &pQuerySql->sliding;
H
hzcheng 已提交
671
  if (pSliding->n != 0) {
H
hjxilinx 已提交
672
    getTimestampInUsFromStr(pSliding->z, pSliding->n, &pQueryInfo->slidingTime);
H
hjxilinx 已提交
673
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
674
      pQueryInfo->slidingTime /= 1000;
H
hzcheng 已提交
675 676
    }

H
hjxilinx 已提交
677
    if (pQueryInfo->slidingTime < tsMinSlidingTime) {
678
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
679 680
    }

H
hjxilinx 已提交
681
    if (pQueryInfo->slidingTime > pQueryInfo->intervalTime) {
682
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
683
    }
H
hjxilinx 已提交
684
  } else {
H
hjxilinx 已提交
685
    pQueryInfo->slidingTime = pQueryInfo->intervalTime;
H
hzcheng 已提交
686 687
  }

H
Haojun Liao 已提交
688 689 690 691
  if ((pQueryInfo->intervalTime != 0) && (pQueryInfo->intervalTime/pQueryInfo->slidingTime > INTERVAL_SLIDING_FACTOR)) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
  }

H
hzcheng 已提交
692 693 694
  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
695
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql) {
696
  const char* msg = "name too long";
H
hzcheng 已提交
697

698 699
  SSqlCmd* pCmd = &pSql->cmd;
  int32_t  code = TSDB_CODE_SUCCESS;
S
slguan 已提交
700

H
hjxilinx 已提交
701 702
  // backup the old name in pTableMetaInfo
  size_t size = strlen(pTableMetaInfo->name);
H
hjxilinx 已提交
703
  char*  oldName = NULL;
704
  if (size > 0) {
H
hjxilinx 已提交
705
    oldName = strdup(pTableMetaInfo->name);
706
  }
H
hjxilinx 已提交
707

H
hzcheng 已提交
708
  if (hasSpecifyDB(pzTableName)) {
709
    // db has been specified in sql string so we ignore current db path
H
hjxilinx 已提交
710
    code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), NULL, pzTableName, NULL);
S
slguan 已提交
711
  } else {  // get current DB name first, then set it into path
H
Haojun Liao 已提交
712
    SStrToken t = {0};
H
hzcheng 已提交
713 714
    getCurrentDBName(pSql, &t);

H
hjxilinx 已提交
715
    code = setObjFullName(pTableMetaInfo->name, NULL, &t, pzTableName, NULL);
H
hzcheng 已提交
716 717
  }

S
slguan 已提交
718
  if (code != TSDB_CODE_SUCCESS) {
719
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
720 721
  }

722 723 724 725
  if (code != TSDB_CODE_SUCCESS) {
    free(oldName);
    return code;
  }
H
hjxilinx 已提交
726

727 728 729 730 731
  /*
   * 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 已提交
732
    if (strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
733
      tscClearTableMetaInfo(pTableMetaInfo, false);
734 735
    }
  } else {
H
hjxilinx 已提交
736
    assert(pTableMetaInfo->pTableMeta == NULL);
737
  }
H
hjxilinx 已提交
738

S
Shengliang Guan 已提交
739
  taosTFree(oldName);
740
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
741 742 743 744 745
}

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

746 747 748 749 750 751 752
  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 已提交
753 754 755

  // number of fields no less than 2
  if (pFieldList->nField <= 1 || pFieldList->nField > TSDB_MAX_COLUMNS) {
756
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
757 758 759 760 761
    return false;
  }

  // first column must be timestamp
  if (pFieldList->p[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
762
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
763 764 765 766 767
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
dengyihao's avatar
dengyihao 已提交
768 769 770 771
    if (pFieldList->p[i].bytes == 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
      return false;
    }
H
hzcheng 已提交
772 773 774 775 776
    nLen += pFieldList->p[i].bytes;
  }

  // max row length must be less than TSDB_MAX_BYTES_PER_ROW
  if (nLen > TSDB_MAX_BYTES_PER_ROW) {
777
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
778 779 780 781 782 783 784
    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) {
785
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
786 787 788 789 790
      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))) {
791
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
792 793 794 795
      return false;
    }

    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
796
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
797 798 799 800
      return false;
    }

    if (has(pFieldList, i + 1, pFieldList->p[i].name) == true) {
801
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
802 803 804 805 806 807 808 809 810 811
      return false;
    }
  }

  return true;
}

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

812 813 814 815 816 817 818
  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 已提交
819 820 821

  // number of fields at least 1
  if (pTagsList->nField < 1 || pTagsList->nField > TSDB_MAX_TAGS) {
822
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
823 824 825 826 827
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
dengyihao's avatar
dengyihao 已提交
828 829 830 831
    if (pTagsList->p[i].bytes == 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
      return false;
    }
H
hzcheng 已提交
832 833 834 835 836
    nLen += pTagsList->p[i].bytes;
  }

  // max tag row length must be less than TSDB_MAX_TAGS_LEN
  if (nLen > TSDB_MAX_TAGS_LEN) {
837
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
838 839 840 841 842 843
    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) {
844
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
845 846 847 848 849 850 851
      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) {
852
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
853 854 855 856
      return false;
    }

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

    if (validateColumnName(pTagsList->p[i].name) != TSDB_CODE_SUCCESS) {
868
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
869 870 871 872
      return false;
    }

    if (has(pTagsList, i + 1, pTagsList->p[i].name) == true) {
873
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
874 875 876 877 878 879 880 881 882 883 884
      return false;
    }
  }

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
885 886 887 888 889 890
  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 已提交
891

892
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
893

894
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
895
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
896

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

905
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
906 907 908 909 910
    return false;
  }

  // no timestamp allowable
  if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) {
911
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
912 913 914
    return false;
  }

L
[#1236]  
lihui 已提交
915
  if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_NCHAR)) {
916
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
917 918 919
    return false;
  }

H
hjxilinx 已提交
920
  SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
921 922
  int32_t  nLen = 0;

H
hjxilinx 已提交
923
  for (int32_t i = 0; i < numOfTags; ++i) {
H
hzcheng 已提交
924 925 926 927 928
    nLen += pTagSchema[i].bytes;
  }

  // length less than TSDB_MAX_TASG_LEN
  if (nLen + pTagField->bytes > TSDB_MAX_TAGS_LEN) {
929
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
930 931 932 933 934
    return false;
  }

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

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

H
hjxilinx 已提交
948
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
949
    if (strncasecmp(pTagField->name, pSchema[i].name, sizeof(pTagField->name) - 1) == 0) {
950
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
951 952 953 954 955 956 957 958
      return false;
    }
  }

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
959 960 961 962 963 964
  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 已提交
965

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

  if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_NCHAR) {
980
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
981 982 983 984
    return false;
  }

  if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) {
985
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
986 987 988
    return false;
  }

H
hjxilinx 已提交
989
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
990 991
  int32_t  nLen = 0;

H
hjxilinx 已提交
992
  for (int32_t i = 0; i < numOfCols; ++i) {
H
hzcheng 已提交
993 994 995 996
    nLen += pSchema[i].bytes;
  }

  if (pColField->bytes <= 0) {
997
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
998 999 1000 1001 1002
    return false;
  }

  // length less than TSDB_MAX_BYTES_PER_ROW
  if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) {
1003
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1004 1005 1006 1007
    return false;
  }

  // field name must be unique
H
hjxilinx 已提交
1008
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
1009
    if (strncasecmp(pColField->name, pSchema[i].name, sizeof(pColField->name) - 1) == 0) {
1010
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1011 1012 1013 1014 1015 1016 1017 1018
      return false;
    }
  }

  return true;
}

/* is contained in pFieldList or not */
H
hjxilinx 已提交
1019
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name) {
H
hzcheng 已提交
1020
  for (int32_t j = startIdx; j < pFieldList->nField; ++j) {
B
Bomin Zhang 已提交
1021 1022
    TAOS_FIELD* field = pFieldList->p + j;
    if (strncasecmp(name, field->name, sizeof(field->name) - 1) == 0) return true;
H
hzcheng 已提交
1023 1024 1025 1026 1027 1028 1029
  }

  return false;
}

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

H
Haojun Liao 已提交
1030
static void getCurrentDBName(SSqlObj* pSql, SStrToken* pDBToken) {
H
hzcheng 已提交
1031
  pDBToken->z = pSql->pTscObj->db;
S
TD-1057  
Shengliang Guan 已提交
1032
  pDBToken->n = (uint32_t)strlen(pSql->pTscObj->db);
H
hzcheng 已提交
1033 1034 1035
}

/* length limitation, strstr cannot be applied */
H
Haojun Liao 已提交
1036
static bool hasSpecifyDB(SStrToken* pTableName) {
S
TD-1057  
Shengliang Guan 已提交
1037
  for (uint32_t i = 0; i < pTableName->n; ++i) {
H
hzcheng 已提交
1038 1039 1040 1041 1042 1043 1044 1045
    if (pTableName->z[i] == TS_PATH_DELIMITER[0]) {
      return true;
    }
  }

  return false;
}

H
Haojun Liao 已提交
1046
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1047 1048 1049
  int32_t totalLen = 0;

  if (account != NULL) {
S
TD-1057  
Shengliang Guan 已提交
1050
    int32_t len = (int32_t)strlen(account);
H
hzcheng 已提交
1051 1052 1053 1054 1055 1056 1057
    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) {
B
Bomin Zhang 已提交
1058
    if (pDB->n >= TSDB_ACCT_LEN + TSDB_DB_NAME_LEN) {
1059
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
    }

    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 */
H
Haojun Liao 已提交
1072
      if (!tscValidateTableNameLength(tableName->n)) {
1073
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1074 1075 1076
      }
    } else {  // pDB == NULL, the db prefix name is specified in tableName
      /* the length limitation includes tablename + dbname + sep */
B
Bomin Zhang 已提交
1077
      if (tableName->n >= TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN) {
1078
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
      }
    }

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

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

H
Haojun Liao 已提交
1090
  if (totalLen < TSDB_TABLE_FNAME_LEN) {
S
slguan 已提交
1091 1092 1093
    fullName[totalLen] = 0;
  }

H
Haojun Liao 已提交
1094
  return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1095 1096
}

1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
  const char* msg1 = "invalid column name, or illegal column type";
  const char* msg2 = "invalid arithmetic expression in select clause";
  const char* msg3 = "tag columns can not be used in arithmetic expression";
  const char* msg4 = "columns from different table mixed up in arithmetic expression";

  // arithmetic function in select clause
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);

  SColumnList columnList = {0};
  int32_t     arithmeticType = NON_ARITHMEIC_EXPR;

  if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }

  int32_t tableIndex = columnList.ids[0].tableIndex;

  // todo potential data overflow
S
Shengliang Guan 已提交
1116
  char* arithmeticExprStr = malloc(1024*1024);
1117 1118 1119 1120 1121 1122 1123 1124
  char* p = arithmeticExprStr;

  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) {
S
Shengliang Guan 已提交
1125
        taosTFree(arithmeticExprStr);
1126 1127 1128 1129 1130
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
      }
    }

    if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
S
Shengliang Guan 已提交
1131
      taosTFree(arithmeticExprStr);
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
      return TSDB_CODE_TSC_INVALID_SQL;
    }

    // expr string is set as the parameter of function
    SColumnIndex index = {.tableIndex = tableIndex};

    SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double),
                                       sizeof(double), false);

    char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
    tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));

    tExprNode* pNode = NULL;
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));

    int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
    if (ret != TSDB_CODE_SUCCESS) {
S
Shengliang Guan 已提交
1149
      taosTFree(arithmeticExprStr);
1150 1151
      taosArrayDestroy(colList);
      tExprTreeDestroy(&pNode, NULL);
1152 1153 1154 1155 1156 1157
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }

    size_t numOfNode = taosArrayGetSize(colList);
    for(int32_t k = 0; k < numOfNode; ++k) {
      SColIndex* pIndex = taosArrayGet(colList, k);
1158 1159
      if (TSDB_COL_IS_TAG(pIndex->flag)) {
        tExprTreeDestroy(&pNode, NULL);
S
Shengliang Guan 已提交
1160
        taosTFree(arithmeticExprStr);
1161 1162
        taosArrayDestroy(colList);
        tExprTreeDestroy(&pNode, NULL);
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }

    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
        exprTreeToBinary(&bw, pNode);
      } CATCH(code) {
        tbufCloseWriter(&bw);
        UNUSED(code);
        // TODO: other error handling
      } END_TRY

    size_t len = tbufTell(&bw);
    char* c = tbufGetData(&bw, true);

    // set the serialized binary string as the parameter of arithmetic expression
S
Shengliang Guan 已提交
1181
    addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len, index.tableIndex);
1182 1183 1184 1185 1186 1187 1188

    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);

    taosArrayDestroy(colList);
    tExprTreeDestroy(&pNode, NULL);
  } else {
    if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
S
Shengliang Guan 已提交
1189
      taosTFree(arithmeticExprStr);
1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212
      return TSDB_CODE_TSC_INVALID_SQL;
    }

    columnList.num = 0;
    columnList.ids[0] = (SColumnIndex) {0, 0};

    char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, name, NULL);

    int32_t slot = tscNumOfFields(pQueryInfo) - 1;
    SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);

    if (pInfo->pSqlExpr == NULL) {
      SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));

      // arithmetic expression always return result in the format of double float
      pArithExprInfo->bytes = sizeof(double);
      pArithExprInfo->interBytes = sizeof(double);
      pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;

      int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
      if (ret != TSDB_CODE_SUCCESS) {
        tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
S
Shengliang Guan 已提交
1213
        taosTFree(arithmeticExprStr);
1214 1215 1216 1217 1218 1219 1220
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
      }

      pInfo->pArithExprInfo = pArithExprInfo;
    }
  }

S
Shengliang Guan 已提交
1221
  taosTFree(arithmeticExprStr);
1222 1223 1224
  return TSDB_CODE_SUCCESS;
}

1225 1226 1227 1228 1229
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tscColumnListInsert(pQueryInfo->colList, &tsCol);
}

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

1233 1234
  const char* msg2 = "functions can not be mixed up";
  const char* msg3 = "not support query expression";
H
hjxilinx 已提交
1235
  const char* msg5 = "invalid function name";
H
hjxilinx 已提交
1236

1237
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
H
Haojun Liao 已提交
1238

1239 1240 1241
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
H
Haojun Liao 已提交
1242

H
hzcheng 已提交
1243
  for (int32_t i = 0; i < pSelection->nExpr; ++i) {
S
Shengliang Guan 已提交
1244
    int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hzcheng 已提交
1245 1246
    tSQLExprItem* pItem = &pSelection->a[i];

S
slguan 已提交
1247
    // project on all fields
H
Haojun Liao 已提交
1248 1249
    int32_t optr = pItem->pNode->nSQLOptr;

1250
    if (optr == TK_ALL || optr == TK_ID || optr == TK_STRING || optr == TK_INTEGER || optr == TK_FLOAT) {
S
slguan 已提交
1251
      // it is actually a function, but the function name is invalid
H
hzcheng 已提交
1252
      if (pItem->pNode->nSQLOptr == TK_ID && (pItem->pNode->colInfo.z == NULL && pItem->pNode->colInfo.n == 0)) {
H
hjxilinx 已提交
1253
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1254 1255
      }

S
slguan 已提交
1256
      // select table_name1.field_name1, table_name2.field_name2  from table_name1, table_name2
1257
      if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
1258
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1259
      }
1260
    } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_TBID) {
S
slguan 已提交
1261
      // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
1262
      if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
1263
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1264 1265 1266
      }

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
1267 1268 1269
      int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
1270
      }
1271

H
hzcheng 已提交
1272 1273 1274 1275 1276
    } else {
      /*
       * not support such expression
       * e.g., select 12+5 from table_name
       */
1277
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1278 1279
    }

H
hjxilinx 已提交
1280
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1281
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1282 1283 1284
    }
  }

1285 1286 1287 1288 1289 1290 1291
  // there is only one user-defined column in the final result field, add the timestamp column.
  size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
  if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo)) {
    SColumnIndex index = {0};
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
  }

1292
  if (!functionCompatibleCheck(pQueryInfo)) {
1293
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1294 1295
  }

H
Haojun Liao 已提交
1296 1297 1298 1299
  /*
   * transfer sql functions that need secondary merge into another format
   * in dealing with metric queries such as: count/first/last
   */
1300
  if (isSTable) {
H
hjxilinx 已提交
1301
    tscTansformSQLFuncForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1302

1303
    if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
1304
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1305 1306 1307 1308 1309 1310
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1311 1312
int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
    int8_t type, char* fieldName, SSqlExpr* pSqlExpr) {
1313
  
S
slguan 已提交
1314
  for (int32_t i = 0; i < pIdList->num; ++i) {
1315 1316 1317 1318 1319 1320 1321 1322
    int32_t tableId = pIdList->ids[i].tableIndex;
    STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[tableId];
    
    int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
    if (pIdList->ids[i].columnIndex >= numOfCols) {
      continue;
    }
    
1323
    tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i]));
H
hzcheng 已提交
1324
  }
H
hjxilinx 已提交
1325 1326
  
  TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
H
Haojun Liao 已提交
1327
  SFieldSupInfo* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
H
hjxilinx 已提交
1328
  pInfo->pSqlExpr = pSqlExpr;
H
hjxilinx 已提交
1329
  
H
hzcheng 已提交
1330 1331 1332
  return TSDB_CODE_SUCCESS;
}

1333
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1334
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1335 1336 1337
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
1338
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
H
hzcheng 已提交
1339

1340
  int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
1341 1342 1343 1344
  SColumnIndex index = {.tableIndex = tableIndex,};
  
  if (functionId == TSDB_FUNC_TAGPRJ) {
    index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta);
H
hjxilinx 已提交
1345 1346
  
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
1347 1348 1349 1350 1351 1352
  } else {
    index.columnIndex = colIndex;
  }
  
  return tscSqlExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes,
      pSchema->bytes, functionId == TSDB_FUNC_TAGPRJ);
H
hzcheng 已提交
1353 1354
}

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

H
hjxilinx 已提交
1358
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
H
hjxilinx 已提交
1359 1360 1361
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
1362

S
slguan 已提交
1363
  char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName;
B
Bomin Zhang 已提交
1364
  tstrncpy(pExpr->aliasName, colName, sizeof(pExpr->aliasName));
H
hjxilinx 已提交
1365
  
S
slguan 已提交
1366 1367 1368
  SColumnList ids = {0};
  ids.num = 1;
  ids.ids[0] = *pIndex;
H
hzcheng 已提交
1369

1370 1371
  if (pIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX || pIndex->columnIndex == TSDB_UD_COLUMN_INDEX ||
      pIndex->columnIndex >= tscGetNumOfColumns(pTableMeta)) {
S
slguan 已提交
1372 1373
    ids.num = 0;
  }
H
hzcheng 已提交
1374

S
TD-1057  
Shengliang Guan 已提交
1375
  insertResultField(pQueryInfo, startPos, &ids, pExpr->resBytes, (int8_t)pExpr->resType, pExpr->aliasName, pExpr);
S
slguan 已提交
1376
}
H
hzcheng 已提交
1377

H
Haojun Liao 已提交
1378
SSqlExpr* tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1379
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
H
Haojun Liao 已提交
1380
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
H
Haojun Liao 已提交
1381
                                     pColSchema->bytes, pColSchema->bytes, TSDB_COL_IS_TAG(flag));
H
Haojun Liao 已提交
1382
  tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName));
H
hzcheng 已提交
1383

S
slguan 已提交
1384 1385 1386 1387
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1388

H
hjxilinx 已提交
1389
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1390 1391

  pExpr->colInfo.flag = flag;
1392 1393
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  
S
slguan 已提交
1394
  if (TSDB_COL_IS_TAG(flag)) {
H
hjxilinx 已提交
1395
    tscColumnListInsert(pTableMetaInfo->tagColList, pIndex);
S
slguan 已提交
1396
  }
H
Haojun Liao 已提交
1397 1398

  return pExpr;
S
slguan 已提交
1399 1400
}

1401
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1402
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1403 1404

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1405 1406
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1407

H
hjxilinx 已提交
1408
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1409
  
weixin_48148422's avatar
weixin_48148422 已提交
1410
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1411
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1412
  } else {
H
hjxilinx 已提交
1413
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1414 1415 1416
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
hjxilinx 已提交
1417
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex);
B
Bomin Zhang 已提交
1418
    tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName));
S
slguan 已提交
1419 1420 1421 1422

    pIndex->columnIndex = j;
    SColumnList ids = {0};
    ids.ids[0] = *pIndex;
H
hjxilinx 已提交
1423
    ids.num = 1;
S
slguan 已提交
1424

H
hjxilinx 已提交
1425
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1426 1427 1428 1429 1430
  }

  return numOfTotalColumns;
}

1431
int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExprItem* pItem) {
S
slguan 已提交
1432
  const char* msg0 = "invalid column name";
H
hjxilinx 已提交
1433
  const char* msg1 = "tag for normal table query is not allowed";
S
slguan 已提交
1434

1435
  int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
Haojun Liao 已提交
1436 1437 1438 1439 1440
  int32_t optr = pItem->pNode->nSQLOptr;

  if (optr == TK_ALL) {  // project on all fields
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY);

S
slguan 已提交
1441
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1442
    if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1443
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
1444 1445 1446 1447
    }

    // all meters columns are required
    if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) {  // all table columns are required.
1448
      for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
S
slguan 已提交
1449
        index.tableIndex = i;
1450
        int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1451
        startPos += inc;
H
hzcheng 已提交
1452 1453
      }
    } else {
1454
      doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1455
    }
H
Haojun Liao 已提交
1456 1457 1458

    // add the primary timestamp column even though it is not required by user
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
1459
  } else if (optr == TK_STRING || optr == TK_INTEGER || optr == TK_FLOAT) {  // simple column projection query
S
slguan 已提交
1460 1461
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;

H
Haojun Liao 已提交
1462
    // user-specified constant value as a new result column
1463 1464
    index.columnIndex = (pQueryInfo->udColumnId--);
    index.tableIndex = 0;
H
hzcheng 已提交
1465

H
Haojun Liao 已提交
1466
    SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->val, &pItem->pNode->token, pItem->aliasName);
1467 1468
    SSqlExpr* pExpr =
        tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC);
H
hzcheng 已提交
1469

1470 1471 1472 1473 1474
    // NOTE: the first parameter is reserved for the tag column id during join query process.
    pExpr->numOfParams = 2;
    tVariantAssign(&pExpr->param[1], &pItem->pNode->val);
  } else if (optr == TK_ID) {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
1475

1476 1477 1478
    if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
    }
H
Haojun Liao 已提交
1479

1480 1481 1482 1483 1484 1485
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      SSchema colSchema = tGetTableNameColumnSchema();
      tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG);
    } else {
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
Haojun Liao 已提交
1486

1487 1488
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1489 1490
      }

1491
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
Haojun Liao 已提交
1492
      pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
H
hzcheng 已提交
1493
    }
H
Haojun Liao 已提交
1494

1495 1496
    // add the primary timestamp column even though it is not required by user
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
hzcheng 已提交
1497
  } else {
1498
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1499 1500 1501 1502 1503
  }

  return TSDB_CODE_SUCCESS;
}

1504
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, int32_t functionID, char* aliasName,
S
slguan 已提交
1505
                                       int32_t resColIdx, SColumnIndex* pColIndex) {
H
hzcheng 已提交
1506 1507 1508
  int16_t type = 0;
  int16_t bytes = 0;

S
slguan 已提交
1509
  char        columnName[TSDB_COL_NAME_LEN] = {0};
1510
  const char* msg1 = "not support column types";
H
hzcheng 已提交
1511 1512

  if (functionID == TSDB_FUNC_SPREAD) {
S
slguan 已提交
1513 1514 1515
    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) {
1516
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1517 1518 1519 1520 1521 1522
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
S
slguan 已提交
1523 1524
    type = pSchema[pColIndex->columnIndex].type;
    bytes = pSchema[pColIndex->columnIndex].bytes;
H
hzcheng 已提交
1525 1526 1527
  }

  if (aliasName != NULL) {
B
Bomin Zhang 已提交
1528
    tstrncpy(columnName, aliasName, sizeof(columnName));
H
hzcheng 已提交
1529
  } else {
B
Bomin Zhang 已提交
1530
    getRevisedName(columnName, functionID, sizeof(columnName) - 1, pSchema[pColIndex->columnIndex].name);
H
hzcheng 已提交
1531
  }
H
hjxilinx 已提交
1532
  
1533
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, bytes, false);
B
Bomin Zhang 已提交
1534
  tstrncpy(pExpr->aliasName, columnName, sizeof(pExpr->aliasName));
1535 1536 1537 1538 1539 1540 1541

  // set reverse order scan data blocks for last query
  if (functionID == TSDB_FUNC_LAST) {
    pExpr->numOfParams = 1;
    pExpr->param[0].i64Key = TSDB_ORDER_DESC;
    pExpr->param[0].nType = TSDB_DATA_TYPE_INT;
  }
H
hjxilinx 已提交
1542
  
H
hjxilinx 已提交
1543
  // for all queries, the timestamp column needs to be loaded
S
slguan 已提交
1544
  SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1545
  tscColumnListInsert(pQueryInfo->colList, &index);
H
hzcheng 已提交
1546

S
slguan 已提交
1547
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
S
TD-1057  
Shengliang Guan 已提交
1548
  insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, columnName, pExpr);
H
hzcheng 已提交
1549 1550 1551 1552

  return TSDB_CODE_SUCCESS;
}

1553
int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult) {
H
hjxilinx 已提交
1554
  STableMetaInfo* pTableMetaInfo = NULL;
1555
  int32_t optr = pItem->pNode->nSQLOptr;
S
slguan 已提交
1556

1557
  const char* msg1 = "not support column types";
S
slguan 已提交
1558
  const char* msg2 = "invalid parameters";
1559
  const char* msg3 = "illegal column name";
S
slguan 已提交
1560
  const char* msg4 = "invalid table name";
1561
  const char* msg5 = "parameter is out of range [0, 100]";
S
slguan 已提交
1562
  const char* msg6 = "function applied to tags not allowed";
1563
  const char* msg7 = "normal table can not apply this function";
H
Haojun Liao 已提交
1564
  const char* msg8 = "multi-columns selection does not support alias column name";
B
Bomin Zhang 已提交
1565
  const char* msg9 = "invalid function";
H
Haojun Liao 已提交
1566

H
hzcheng 已提交
1567 1568 1569
  switch (optr) {
    case TK_COUNT: {
        /* more than one parameter for count() function */
H
Haojun Liao 已提交
1570
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
1571
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1572 1573 1574 1575
      }

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1576
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1577 1578
      }

H
hjxilinx 已提交
1579
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1580
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1581 1582

      if (pItem->pNode->pParam != NULL) {
H
Haojun Liao 已提交
1583
        SStrToken* pToken = &pItem->pNode->pParam->a[0].pNode->colInfo;
H
hzcheng 已提交
1584
        if (pToken->z == NULL || pToken->n == 0) {
1585
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1586 1587
        }

S
slguan 已提交
1588 1589 1590 1591
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
        if (pParamElem->pNode->nSQLOptr == TK_ALL) {
          // select table.*
          // check if the table name is valid or not
H
Haojun Liao 已提交
1592
          SStrToken tmpToken = pParamElem->pNode->colInfo;
S
slguan 已提交
1593

1594
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1595
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1596 1597 1598 1599
          }

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
1600
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1601
        } else {
H
hjxilinx 已提交
1602
          // count the number of meters created according to the super table
1603 1604
          if (getColumnIndexByName(pCmd, pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1605 1606
          }

H
hjxilinx 已提交
1607
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1608 1609

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1610 1611
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1612
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1613
            isTag = true;
H
hzcheng 已提交
1614 1615
          }

S
slguan 已提交
1616
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1617
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1618
        }
S
slguan 已提交
1619 1620 1621
      } 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;
1622
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1623
      }
H
Haojun Liao 已提交
1624 1625 1626

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

H
hjxilinx 已提交
1627
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1628
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1629
      
S
slguan 已提交
1630
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1631 1632 1633 1634 1635
      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) {
1636
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1637 1638
        }
      }
H
Haojun Liao 已提交
1639 1640

      // the time stamp may be always needed
H
Haojun Liao 已提交
1641 1642
      if (index.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
Haojun Liao 已提交
1643 1644
      }

S
slguan 已提交
1645
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1646 1647 1648
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1649 1650 1651 1652 1653 1654
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1655
    case TK_TWA:
H
hzcheng 已提交
1656 1657 1658 1659 1660 1661 1662 1663 1664
    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 */
1665
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1666 1667 1668 1669
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ALL && pParamElem->pNode->nSQLOptr != TK_ID) {
1670
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1671 1672
      }

S
slguan 已提交
1673
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
Y
yihaoDeng 已提交
1674
      if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
1675
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1676
      }
Y
yihaoDeng 已提交
1677 1678 1679
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
H
hzcheng 已提交
1680 1681

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

H
hjxilinx 已提交
1686
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1687
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1688 1689 1690 1691
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
1692
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1693 1694 1695

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1696
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1697 1698
      }

S
slguan 已提交
1699 1700
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
1701
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1702
      }
H
hzcheng 已提交
1703

S
slguan 已提交
1704
      // set the first column ts for diff query
H
hzcheng 已提交
1705
      if (optr == TK_DIFF) {
1706
        colIndex += 1;
S
slguan 已提交
1707
        SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
H
hjxilinx 已提交
1708
        SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
1709
                         TSDB_KEYSIZE, false);
H
hzcheng 已提交
1710

S
slguan 已提交
1711
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1712
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1713 1714
      }

S
slguan 已提交
1715
      // functions can not be applied to tags
H
hjxilinx 已提交
1716
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1717
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1718 1719
      }

1720
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, resultSize, false);
H
hzcheng 已提交
1721 1722 1723 1724

      if (optr == TK_LEASTSQUARES) {
        /* set the leastsquares parameters */
        char val[8] = {0};
1725
        if (tVariantDump(&pParamElem[1].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1726
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1727 1728
        }

S
slguan 已提交
1729
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1730 1731

        memset(val, 0, tListLen(val));
1732
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1733
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1734 1735
        }

S
slguan 已提交
1736
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1737 1738
      }

S
slguan 已提交
1739 1740 1741
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1742 1743
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1744
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1745 1746 1747
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
S
TD-1057  
Shengliang Guan 已提交
1748
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, (int32_t)pExpr->resType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
1749 1750
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1751
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1752 1753
        }
      }
H
Haojun Liao 已提交
1754 1755

      tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
S
slguan 已提交
1756
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1757 1758 1759 1760 1761 1762 1763 1764 1765
    }
    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;
B
Bomin Zhang 已提交
1766
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1767
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
B
Bomin Zhang 已提交
1768
      }
H
hzcheng 已提交
1769 1770 1771

      if (!requireAllFields) {
        if (pItem->pNode->pParam->nExpr < 1) {
1772
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1773 1774
        }

H
Haojun Liao 已提交
1775
        if (pItem->pNode->pParam->nExpr > 1 && (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0)) {
1776
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
1777 1778
        }

H
hzcheng 已提交
1779 1780 1781 1782
        /* 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) {
1783
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1784 1785
          }

S
slguan 已提交
1786 1787 1788 1789
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

          if (pParamElem->pNode->nSQLOptr == TK_ALL) {
            // select table.*
H
Haojun Liao 已提交
1790
            SStrToken tmpToken = pParamElem->pNode->colInfo;
S
slguan 已提交
1791

1792
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1793
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1794 1795
            }

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

H
hjxilinx 已提交
1799
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
1800
              index.columnIndex = j;
1801
              if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex++, &index) != 0) {
1802
                return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1803 1804
              }
            }
H
hzcheng 已提交
1805

S
slguan 已提交
1806
          } else {
1807 1808
            if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1809 1810
            }

H
hjxilinx 已提交
1811
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1812
            SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1813 1814

            // functions can not be applied to tags
H
hjxilinx 已提交
1815
            if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
1816
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1817 1818
            }

1819
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i, &index) != 0) {
1820
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1821
            }
1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837

            if (optr == TK_LAST) {  // todo refactor
              SSqlGroupbyExpr* pGroupBy = &pQueryInfo->groupbyExpr;
              if (pGroupBy->numOfGroupCols > 0) {
                for(int32_t k = 0; k < pGroupBy->numOfGroupCols; ++k) {
                  SColIndex* pIndex = taosArrayGet(pGroupBy->columnInfo, k);
                  if (!TSDB_COL_IS_TAG(pIndex->flag) && pIndex->colIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { // group by normal columns
                    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, colIndex + i);
                    pExpr->numOfParams = 1;
                    pExpr->param->i64Key = TSDB_ORDER_ASC;

                    break;
                  }
                }
              }
            }
H
hzcheng 已提交
1838 1839
          }
        }
1840
        
S
slguan 已提交
1841 1842 1843 1844
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

H
Haojun Liao 已提交
1845
        // multicolumn selection does not support alias name
H
Haojun Liao 已提交
1846
        if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
1847
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
1848 1849
        }

1850
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
1851
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
1852
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1853

H
hjxilinx 已提交
1854
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
1855
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
1856
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i + j, &index) !=
1857
                0) {
1858
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1859
            }
H
hzcheng 已提交
1860
          }
S
slguan 已提交
1861

H
hjxilinx 已提交
1862
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1863 1864
        }

1865
        
S
slguan 已提交
1866
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1867 1868 1869 1870 1871 1872 1873 1874 1875
      }
    }
    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 */
1876
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1877 1878 1879 1880
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
1881
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1882
      }
H
hjxilinx 已提交
1883
      
S
slguan 已提交
1884
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1885 1886
      if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1887
      }
Y
yihaoDeng 已提交
1888 1889 1890 1891
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
      
H
hjxilinx 已提交
1892
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1893
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1894 1895

      // functions can not be applied to tags
H
hjxilinx 已提交
1896
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1897
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1898 1899 1900
      }

      // 2. valid the column type
S
slguan 已提交
1901
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
1902
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1903
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1904 1905 1906 1907
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
1908
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1909 1910 1911 1912
      }

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

S
slguan 已提交
1913 1914
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1915

H
hjxilinx 已提交
1916
      char    val[8] = {0};
H
hjxilinx 已提交
1917 1918
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
1919
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
1920
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
1921

L
lihui 已提交
1922
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
1923
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
1924
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936
        }

        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) {
1937
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1938
        }
dengyihao's avatar
dengyihao 已提交
1939 1940
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
        colIndex += 1;  // the first column is ts
H
hzcheng 已提交
1941

1942
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1943
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1944
      } else {
1945
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
1946

H
Haojun Liao 已提交
1947
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
1948
        if (nTop <= 0 || nTop > 100) {  // todo use macro
1949
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1950 1951 1952 1953
        }

        int16_t functionId = 0;
        if (changeFunctionID(optr, &functionId) != TSDB_CODE_SUCCESS) {
1954
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1955
        }
S
slguan 已提交
1956

H
Haojun Liao 已提交
1957
        // todo REFACTOR
H
hzcheng 已提交
1958
        // set the first column ts for top/bottom query
S
slguan 已提交
1959
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
1960 1961
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
            TSDB_KEYSIZE, false);
H
Haojun Liao 已提交
1962
        tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
S
slguan 已提交
1963

H
Haojun Liao 已提交
1964
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
1965
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
1966
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
1967
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
1968

1969
        colIndex += 1;  // the first column is ts
H
hzcheng 已提交
1970

1971
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1972
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
1973
      }
H
hjxilinx 已提交
1974 1975
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1976
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1977
  
S
slguan 已提交
1978
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
1979
      if (finalResult) {
1980
        insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
1981 1982
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1983
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1984 1985
        }
      }
S
slguan 已提交
1986

1987 1988 1989 1990 1991
      return TSDB_CODE_SUCCESS;
    };
    
    case TK_TBID: {
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
1992
      if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
1993
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
1994 1995 1996 1997
      }
    
      // no parameters or more than one parameter for function
      if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 1) {
1998
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
1999 2000 2001 2002 2003
      }
      
      tSQLExpr* pParam = pItem->pNode->pParam->a[0].pNode;
    
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2004 2005
      if (getColumnIndexByName(pCmd, &pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2006 2007 2008 2009 2010 2011 2012
      }
    
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
  
      // functions can not be applied to normal columns
      int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
2013
      if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
2014
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2015 2016
      }
    
2017 2018 2019
      if (index.columnIndex > 0) {
        index.columnIndex -= numOfCols;
      }
2020 2021
      
      // 2. valid the column type
2022 2023 2024 2025 2026 2027 2028 2029
      int16_t colType = 0;
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        colType = TSDB_DATA_TYPE_BINARY;
      } else {
        colType = pSchema[index.columnIndex].type;
      }
      
      if (colType == TSDB_DATA_TYPE_BOOL) {
2030
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
2031 2032 2033 2034
      }

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
2035 2036 2037
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
2038
        s = tGetTableNameColumnSchema();
2039 2040 2041 2042
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
2043 2044
      int16_t bytes = 0;
      int16_t type  = 0;
2045
      int32_t inter = 0;
2046 2047 2048 2049

      int32_t ret = getResultDataInfo(s.type, s.bytes, TSDB_FUNC_TID_TAG, 0, &type, &bytes, &inter, 0, 0);
      assert(ret == TSDB_CODE_SUCCESS);
      
S
TD-1057  
Shengliang Guan 已提交
2050
      s.type = (uint8_t)type;
2051 2052 2053 2054 2055
      s.bytes = bytes;

      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
      tscAddSpecialColumnForSelect(pQueryInfo, 0, TSDB_FUNC_TID_TAG, &index, &s, TSDB_COL_TAG);
      
S
slguan 已提交
2056
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2057
    }
2058
    
H
hzcheng 已提交
2059
    default:
2060
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2061
  }
2062
  
H
hzcheng 已提交
2063 2064
}

S
slguan 已提交
2065 2066
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
2067
  assert(num == 1 && tableIndex >= 0);
S
slguan 已提交
2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078

  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 已提交
2079 2080 2081 2082
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
S
TD-1057  
Shengliang Guan 已提交
2083
    int32_t len = ((int32_t)pItem->pNode->operand.n < nameLength) ? (int32_t)pItem->pNode->operand.n : nameLength;
H
hzcheng 已提交
2084 2085 2086 2087 2088 2089 2090 2091
    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);
}

H
Haojun Liao 已提交
2092 2093 2094
static bool isTablenameToken(SStrToken* token) {
  SStrToken tmpToken = *token;
  SStrToken tableToken = {0};
S
slguan 已提交
2095 2096 2097 2098 2099 2100

  extractTableNameFromToken(&tmpToken, &tableToken);

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

H
Haojun Liao 已提交
2101
static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken* pToken) {
H
hjxilinx 已提交
2102
  STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index)->pTableMeta;
S
slguan 已提交
2103

H
hjxilinx 已提交
2104 2105
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115

  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;
H
Hui Li 已提交
2116
      break;
S
slguan 已提交
2117 2118 2119 2120 2121 2122
    }
  }

  return columnIndex;
}

H
Haojun Liao 已提交
2123
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2124 2125 2126 2127 2128 2129 2130 2131 2132 2133
  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) {
2134 2135
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2136 2137 2138

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2139
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
2140 2141 2142 2143 2144 2145 2146
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2147
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2148 2149 2150 2151 2152 2153
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2154
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2155 2156 2157 2158 2159 2160
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2161
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2162 2163 2164
  }
}

H
Haojun Liao 已提交
2165
int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2166
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2167
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2168 2169 2170 2171 2172 2173 2174
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
2175
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2176
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
Haojun Liao 已提交
2177 2178
    char* name = pTableMetaInfo->aliasName;
    if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
S
slguan 已提交
2179 2180 2181 2182 2183 2184
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
2185
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2186 2187 2188 2189 2190
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
2191 2192
int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SStrToken tableToken = {0};
S
slguan 已提交
2193 2194
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2195
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2196
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2197 2198
  }

S
slguan 已提交
2199 2200
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2201

H
Haojun Liao 已提交
2202
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2203
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2204
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2205 2206
  }

H
Haojun Liao 已提交
2207
  SStrToken tmpToken = *pToken;
S
slguan 已提交
2208

2209
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2210
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2211 2212
  }

2213
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226
}

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 已提交
2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244
    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 已提交
2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280
    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 已提交
2281 2282
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297
      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 已提交
2298
  SSqlCmd*        pCmd = &pSql->cmd;
2299
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2300
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2301

H
hzcheng 已提交
2302 2303
  pCmd->command = TSDB_SQL_SHOW;

2304
  const char* msg1 = "invalid name";
2305
  const char* msg2 = "pattern filter string too long";
2306 2307 2308 2309
  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 已提交
2310 2311 2312 2313 2314

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2315 2316 2317
  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 已提交
2318
    // db prefix in tagCond, show table conds in payload
H
Haojun Liao 已提交
2319
    SStrToken* pDbPrefixToken = &pShowInfo->prefix;
2320
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2321

B
Bomin Zhang 已提交
2322
      if (pDbPrefixToken->n >= TSDB_DB_NAME_LEN) {  // db name is too long
2323
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
2324 2325
      }

2326
      if (pDbPrefixToken->n <= 0) {
2327
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2328 2329
      }

2330
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2331
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2332 2333
      }

H
hjxilinx 已提交
2334
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2335
      if (ret != TSDB_CODE_SUCCESS) {
2336
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2337
      }
2338
    }
H
hzcheng 已提交
2339

2340
    // show table/stable like 'xxxx', set the like pattern for show tables
H
Haojun Liao 已提交
2341
    SStrToken* pPattern = &pShowInfo->pattern;
2342 2343
    if (pPattern->type != 0) {
      pPattern->n = strdequote(pPattern->z);
S
slguan 已提交
2344

2345
      if (pPattern->n <= 0) {
2346
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2347
      }
H
hzcheng 已提交
2348

H
Haojun Liao 已提交
2349
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2350
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2351 2352
      }
    }
2353 2354
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2355
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2356 2357
    }

L
lihui 已提交
2358
    // show vnodes may be ip addr of dnode in payload
H
Haojun Liao 已提交
2359
    SStrToken* pDnodeIp = &pShowInfo->prefix;
B
Bomin Zhang 已提交
2360
    if (pDnodeIp->n >= TSDB_IPv4ADDR_LEN) {  // ip addr is too long
2361
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2362
    }
L
lihui 已提交
2363

2364
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2365
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2366
    }
H
hzcheng 已提交
2367 2368 2369 2370 2371
  }

  return TSDB_CODE_SUCCESS;
}

2372 2373 2374 2375
int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) {
  const char* msg1 = "invalid connection ID";
  const char* msg2 = "invalid query ID";
  const char* msg3 = "invalid stream ID";
H
hzcheng 已提交
2376

2377 2378
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2379
  
H
Haojun Liao 已提交
2380
  SStrToken* idStr = &(pInfo->pDCLInfo->ip);
2381
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2382
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2383 2384
  }

2385
  strncpy(pCmd->payload, idStr->z, idStr->n);
2386

H
hzcheng 已提交
2387
  const char delim = ':';
2388 2389
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2390

2391 2392 2393 2394 2395
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2396

2397 2398 2399 2400 2401 2402
  if (killType == TSDB_SQL_KILL_CONNECTION) {
    return TSDB_CODE_SUCCESS;
  }

  int32_t queryId = (int32_t)strtol(queryIdStr, NULL, 10);
  if (queryId <= 0) {
sangshuduo's avatar
sangshuduo 已提交
2403
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2404 2405 2406 2407 2408
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2409
  }
2410
  
H
hzcheng 已提交
2411 2412 2413
  return TSDB_CODE_SUCCESS;
}

2414 2415 2416 2417 2418 2419
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);

2420
  in_addr_t epAddr = taosInetAddr(tmp);
2421

2422
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2423 2424
}

H
hjxilinx 已提交
2425
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2426
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2427

weixin_48148422's avatar
weixin_48148422 已提交
2428
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2429
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2430 2431
  }

H
hjxilinx 已提交
2432
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2433 2434 2435

  int16_t bytes = 0;
  int16_t type = 0;
2436
  int32_t interBytes = 0;
H
hjxilinx 已提交
2437 2438 2439
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2440
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2441 2442
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

2443
    int32_t colIndex = pExpr->colInfo.colIndex;
H
hjxilinx 已提交
2444
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2445
    
S
slguan 已提交
2446
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2447 2448
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
S
TD-1057  
Shengliang Guan 已提交
2449
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64Key, &type, &bytes,
2450
                            &interBytes, 0, true) != TSDB_CODE_SUCCESS) {
2451
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2452
      }
H
hzcheng 已提交
2453

2454
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2455
      // todo refactor
2456
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2457 2458 2459
    }
  }

2460
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2461
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2462 2463 2464
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2465
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2466
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2467
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2468 2469
    return;
  }
H
hjxilinx 已提交
2470 2471 2472
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2473
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2474
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2475
    
2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492
    // the final result size and type in the same as query on single table.
    // so here, set the flag to be false;
    int32_t inter = 0;
    
    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,
                      &inter, 0, false);
H
hzcheng 已提交
2493 2494 2495
  }
}

2496
bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
2497
  const char* msg1 = "TWA not allowed to apply to super table directly";
H
hjxilinx 已提交
2498
  const char* msg2 = "TWA only support group by tbname for super table query";
2499
  const char* msg3 = "function not support for super table query";
H
hjxilinx 已提交
2500

S
slguan 已提交
2501
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2502 2503
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2504
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
2505
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
2506
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2507
      return true;
H
hzcheng 已提交
2508 2509 2510
    }
  }

2511 2512
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2513
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2514 2515
      return true;
    }
H
hzcheng 已提交
2516

2517
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2518
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2519
      return true;
2520 2521 2522
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
2523
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2524 2525
        return true;
      }
H
hzcheng 已提交
2526 2527
    }
  }
S
slguan 已提交
2528

H
hzcheng 已提交
2529 2530 2531
  return false;
}

2532
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
2533
  int32_t startIdx = 0;
H
hjxilinx 已提交
2534
  
H
hjxilinx 已提交
2535 2536
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2537 2538

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

H
Haojun Liao 已提交
2543
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2544 2545 2546

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2547 2548 2549
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2550
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2551

H
hjxilinx 已提交
2552
    int16_t functionId = pExpr1->functionId;
2553 2554 2555 2556
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
hjxilinx 已提交
2557
    if (functionId == TSDB_FUNC_PRJ && pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
2558 2559 2560
      continue;
    }

H
Haojun Liao 已提交
2561
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2562 2563 2564 2565 2566 2567 2568
      return false;
    }
  }

  return true;
}

2569
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2570 2571
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
H
Haojun Liao 已提交
2572
//  const char* msg3 = "group by columns must belong to one table";
S
slguan 已提交
2573 2574 2575
  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 已提交
2576

2577
  // todo : handle two tables situation
H
hjxilinx 已提交
2578
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2579 2580 2581 2582 2583

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

2584 2585 2586 2587
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
2588
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2589
  if (pList->nExpr > TSDB_MAX_TAGS) {
2590
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2591 2592
  }

H
hjxilinx 已提交
2593
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2594
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2595
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2596

S
slguan 已提交
2597
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
2598
  
H
hzcheng 已提交
2599 2600
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tVariant* pVar = &pList->a[i].pVar;
H
Haojun Liao 已提交
2601
    SStrToken token = {pVar->nLen, pVar->nType, pVar->pz};
H
hzcheng 已提交
2602

S
slguan 已提交
2603
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2604 2605
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2606
    }
H
hzcheng 已提交
2607

S
slguan 已提交
2608
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2609

H
hjxilinx 已提交
2610
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2611
    pTableMeta = pTableMetaInfo->pTableMeta;
2612 2613
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2614 2615 2616
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2617
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2618
    }
H
hzcheng 已提交
2619

S
slguan 已提交
2620
    bool groupTag = false;
2621
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2622
      groupTag = true;
H
hzcheng 已提交
2623
    }
2624 2625 2626 2627 2628 2629
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2630
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2631
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2632
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
S
slguan 已提交
2633 2634
      }

2635 2636 2637 2638
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2639

H
hjxilinx 已提交
2640
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2641
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2642 2643 2644
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2645 2646
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
2647
      if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
2648
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
2649 2650
      }

2651
      tscColumnListInsert(pQueryInfo->colList, &index);
2652
      
2653
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2654
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2655
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2656 2657

      if (i == 0 && pList->nExpr > 1) {
2658
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2659
      }
H
hzcheng 已提交
2660 2661 2662
    }
  }

2663
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2664 2665 2666
  return TSDB_CODE_SUCCESS;
}

2667 2668
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2669
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2670
  } else {
H
hjxilinx 已提交
2671
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2672 2673 2674
  }
}

2675
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2676 2677 2678
  if (pColumn == NULL) {
    return NULL;
  }
2679

S
slguan 已提交
2680
  int32_t size = pColumn->numOfFilters + 1;
L
lihui 已提交
2681
  char*   tmp = (char*)realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2682 2683
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2684 2685
  }

S
slguan 已提交
2686
  pColumn->numOfFilters++;
2687

S
slguan 已提交
2688 2689 2690 2691
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2692 2693
}

2694
static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SColumnFilterInfo* pColumnFilter,
2695
                                         SColumnIndex* columnIndex, tSQLExpr* pExpr) {
S
slguan 已提交
2696
  const char* msg = "not supported filter condition";
H
hzcheng 已提交
2697

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

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

S
slguan 已提交
2703
  int16_t colType = pSchema->type;
2704
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2705 2706 2707
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2708
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2709
    int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
2710 2711 2712
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2713 2714 2715
  }

  if (pExpr->nSQLOptr == TK_LE || pExpr->nSQLOptr == TK_LT) {
2716
    tVariantDump(&pRight->val, (char*)&pColumnFilter->upperBndd, colType, false);
S
slguan 已提交
2717
  } else {  // TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
H
hzcheng 已提交
2718
    if (colType == TSDB_DATA_TYPE_BINARY) {
H
Haojun Liao 已提交
2719
      pColumnFilter->pz = (int64_t)calloc(1, pRight->val.nLen + TSDB_NCHAR_SIZE);
S
slguan 已提交
2720
      pColumnFilter->len = pRight->val.nLen;
H
hzcheng 已提交
2721

2722
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2723 2724 2725 2726
    } 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);

2727
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2728

H
[TD-92]  
Hui Li 已提交
2729
      size_t len = twcslen((wchar_t*)pColumnFilter->pz);
S
slguan 已提交
2730
      pColumnFilter->len = len * TSDB_NCHAR_SIZE;
H
hzcheng 已提交
2731
    } else {
2732
      tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
2733 2734 2735 2736 2737
    }
  }

  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
2738
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
2739 2740
      break;
    case TK_LT:
S
slguan 已提交
2741
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
2742 2743
      break;
    case TK_GT:
2744
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
2745 2746
      break;
    case TK_GE:
2747
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
2748 2749
      break;
    case TK_EQ:
S
slguan 已提交
2750
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
2751 2752
      break;
    case TK_NE:
S
slguan 已提交
2753
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
2754 2755
      break;
    case TK_LIKE:
S
slguan 已提交
2756
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
2757
      break;
S
slguan 已提交
2758
    default:
2759
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
2760
  }
S
slguan 已提交
2761

2762
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2763 2764
}

S
slguan 已提交
2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778
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 已提交
2779

H
hjxilinx 已提交
2780
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
2781 2782

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2783
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2784 2785
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2786 2787

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

H
hjxilinx 已提交
2790 2791 2792 2793 2794 2795 2796
  } 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 已提交
2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815
    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)) {
2816
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2817 2818
  }

S
slguan 已提交
2819 2820 2821 2822 2823 2824 2825 2826 2827 2828
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
2829
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2830 2831 2832 2833 2834 2835 2836 2837 2838
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
2839 2840 2841 2842
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
2843 2844 2845 2846
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894

  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:
2895
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2896 2897 2898 2899 2900 2901 2902
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2903
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
2904 2905
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
2906
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2907 2908
  }

S
slguan 已提交
2909
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2910
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2911 2912
  }

H
hzcheng 已提交
2913 2914
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
2915
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
2916 2917

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

H
Haojun Liao 已提交
2921
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
2922
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2923 2924 2925 2926 2927 2928
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2929
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
2930 2931
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2932 2933

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2934 2935
}

S
slguan 已提交
2936 2937 2938 2939 2940 2941
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2942

2943
static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SColumnIndex* pIndex, tSQLExpr* pExpr, int32_t sqlOptr) {
H
hjxilinx 已提交
2944
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
2945

H
hjxilinx 已提交
2946 2947
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2948

S
slguan 已提交
2949
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
2950 2951
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
2952

H
hjxilinx 已提交
2953
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970
  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;
2971
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2972 2973
  }

2974
  pColFilter->filterstr =
S
slguan 已提交
2975 2976
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

2977
  if (pColFilter->filterstr) {
S
slguan 已提交
2978
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
2979
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2980
    }
S
slguan 已提交
2981 2982
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
2983
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2984
    }
H
Hui Li 已提交
2985 2986 2987
    
    if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
      if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
2988
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Hui Li 已提交
2989 2990
      }
    }
S
slguan 已提交
2991 2992 2993
  }

  pColumn->colIndex = *pIndex;
2994
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
2995 2996
}

2997
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2998 2999 3000 3001 3002
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

3003
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
3004 3005 3006 3007 3008 3009 3010 3011 3012
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

3013
UNUSED_FUNC
3014
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3015 3016 3017 3018 3019 3020 3021
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3023
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
3024
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3025
      return ret;
H
hzcheng 已提交
3026
    }
S
slguan 已提交
3027

3028
    relToString(pExpr, str);
S
slguan 已提交
3029

3030
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
3031 3032 3033 3034

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

H
hzcheng 已提交
3035 3036 3037
    return ret;
  }

S
slguan 已提交
3038 3039 3040
  return tSQLExprLeafToString(pExpr, true, str);
}

3041
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
3042 3043 3044 3045
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
3048 3049
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
3050

S
slguan 已提交
3051
  if (!isTablenameToken(&pLeft->colInfo)) {
3052
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3053 3054
  }

S
slguan 已提交
3055
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3056

S
slguan 已提交
3057
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
3058
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
3059
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3060
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
3061
  }
H
hzcheng 已提交
3062

S
slguan 已提交
3063
  if (ret != TSDB_CODE_SUCCESS) {
3064
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3065
  }
H
hzcheng 已提交
3066

S
slguan 已提交
3067 3068 3069
  return ret;
}

3070
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3071 3072 3073 3074 3075
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
3076
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3077 3078 3079 3080
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3081
    return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3082 3083
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3084
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3085
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3086
    }
S
slguan 已提交
3087

3088
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3089
  }
S
slguan 已提交
3090
}
H
hzcheng 已提交
3091

3092
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
H
Haojun Liao 已提交
3093 3094 3095
  const char* msg1 = "invalid join query condition";
  const char* msg3 = "type of join columns must be identical";
  const char* msg4 = "invalid column name in join condition";
H
hzcheng 已提交
3096

S
slguan 已提交
3097 3098 3099
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3100

S
slguan 已提交
3101
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
3102
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3103 3104
  }

3105
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3106 3107 3108 3109
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3110 3111
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3112 3113
  }

H
hjxilinx 已提交
3114
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
Haojun Liao 已提交
3115
  SSchema* pTagSchema1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
S
slguan 已提交
3116

3117
  pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3118
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3119
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3120 3121

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3122 3123
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3124 3125
  }

H
hjxilinx 已提交
3126
  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
Haojun Liao 已提交
3127
  SSchema* pTagSchema2 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
S
slguan 已提交
3128

3129
  pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3130
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3131
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3132

H
Haojun Liao 已提交
3133
  if (pTagSchema1->type != pTagSchema2->type) {
3134
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3135 3136
  }

S
slguan 已提交
3137
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3138 3139 3140 3141
  return TSDB_CODE_SUCCESS;
}

// todo error handle / such as and /or mixed with +/-/*/
3142
int32_t doArithmeticExprToString(tSQLExpr* pExpr, char** exprString) {
H
hzcheng 已提交
3143 3144 3145
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3146
  *(*exprString)++ = '(';
H
hzcheng 已提交
3147 3148

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3149
    doArithmeticExprToString(pLeft, exprString);
H
hzcheng 已提交
3150
  } else {
S
slguan 已提交
3151
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3152
    if (ret != TSDB_CODE_SUCCESS) {
3153
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3154 3155 3156 3157 3158 3159
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3160
    doArithmeticExprToString(pRight, exprString);
H
hzcheng 已提交
3161
  } else {
S
slguan 已提交
3162
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3163
    if (ret != TSDB_CODE_SUCCESS) {
3164
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3165 3166 3167
    }
  }

H
hjxilinx 已提交
3168
  *(*exprString)++ = ')';
H
hzcheng 已提交
3169 3170 3171 3172

  return TSDB_CODE_SUCCESS;
}

3173 3174 3175 3176 3177
static int32_t arithmeticExprToString(tSQLExpr* pExpr, char** str) {
  char* start = *str;

  int32_t code = doArithmeticExprToString(pExpr, str);
  if (code == TSDB_CODE_SUCCESS) { // remove out the parenthesis
S
Shengliang Guan 已提交
3178
    int32_t len = (int32_t)strlen(start);
3179 3180 3181 3182 3183 3184 3185
    memmove(start, start + 1, len - 2);
    start[len - 2] = 0;
  }

  return code;
}

3186
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3187
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3188 3189 3190
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
3191
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3192
    }
L
lihui 已提交
3193

H
hjxilinx 已提交
3194
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3195
    if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3196
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3197 3198 3199
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3200
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3201 3202
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3203 3204
    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)) {
3205
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3206 3207 3208
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3209
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
3210
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3211 3212 3213 3214
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
3215
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3216 3217
    }

S
TD-1057  
Shengliang Guan 已提交
3218
    int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
3219
  
H
hjxilinx 已提交
3220 3221 3222
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
    // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
3223
    if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
3224
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3225
    }
H
hzcheng 已提交
3226 3227 3228 3229 3230
  }

  return TSDB_CODE_SUCCESS;
}

3231
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3232 3233 3234 3235 3236 3237
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3238
    int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3239 3240 3241 3242
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3243
    int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3244 3245 3246 3247 3248 3249 3250
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3251
    int32_t ret = validateArithmeticSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3252 3253 3254 3255
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3256
    int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271
    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 已提交
3272 3273 3274
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3275 3276 3277
   *
   * However, columnA < 4+12 is valid
   */
B
Bomin Zhang 已提交
3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293
  if (pLeft->nSQLOptr >= TK_COUNT && pLeft->nSQLOptr <= TK_AVG_IRATE) {
    return false;
  }

  if (pRight == NULL) {
    return true;
  }

  if (pRight->nSQLOptr >= TK_COUNT && pRight->nSQLOptr <= TK_AVG_IRATE) {
    return false;
  }
  
  if (pLeft->nSQLOptr >= TK_BOOL
    && pLeft->nSQLOptr <= TK_BINARY
    && pRight->nSQLOptr >= TK_BOOL
    && pRight->nSQLOptr <= TK_BINARY) {
H
hzcheng 已提交
3294 3295 3296 3297 3298 3299
    return false;
  }

  return true;
}

S
slguan 已提交
3300 3301 3302
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3303

S
slguan 已提交
3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328
  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 已提交
3329

S
slguan 已提交
3330 3331 3332 3333 3334
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3335
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348
  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)";

  tSQLExpr* pRight = pExpr->pRight;

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

  if (pExpr->nSQLOptr != TK_EQ) {
3349
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3350 3351 3352 3353 3354
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3355 3356
  if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3357
    return false;
H
hzcheng 已提交
3358 3359
  }

S
slguan 已提交
3360
  // todo extract function
H
hjxilinx 已提交
3361
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3362
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3363 3364
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3365
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3366
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3367 3368 3369
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3370
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3371 3372
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3373
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3374
    return false;
H
hzcheng 已提交
3375 3376
  }

S
slguan 已提交
3377
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3378
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3379
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
S
slguan 已提交
3380 3381
    return false;
  }
H
hzcheng 已提交
3382

S
slguan 已提交
3383 3384
  return true;
}
H
hzcheng 已提交
3385

S
slguan 已提交
3386 3387 3388 3389 3390 3391
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 已提交
3392 3393 3394
    }
  }

S
slguan 已提交
3395
  return false;
H
hzcheng 已提交
3396 3397
}

3398
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3399 3400
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3401
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3402
    }
H
hzcheng 已提交
3403

S
slguan 已提交
3404 3405 3406 3407
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3408

S
slguan 已提交
3409 3410
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3411

3412 3413
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                                     int32_t* type, int32_t parentOptr) {
3414
  const char* msg1 = "table query cannot use tags filter";
S
slguan 已提交
3415 3416 3417
  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 已提交
3418 3419 3420
  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";
3421 3422
  const char* msg8 = "wildcard string should be less than 20 characters";
  
S
slguan 已提交
3423 3424
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3425

S
slguan 已提交
3426 3427 3428
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3429 3430
  if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3431 3432
  }

S
slguan 已提交
3433 3434
  assert(isExprDirectParentOfLeaftNode(*pExpr));

H
hjxilinx 已提交
3435
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3436
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3437 3438

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3439
    if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3440
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3441
    }
S
slguan 已提交
3442 3443 3444

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
H
hjxilinx 已提交
3445
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
S
slguan 已提交
3446 3447 3448 3449 3450 3451 3452 3453
      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 {
3454
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3455 3456 3457 3458
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3459 3460
  } else if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
    // query on tags, check for tag query condition
weixin_48148422's avatar
weixin_48148422 已提交
3461
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3462
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3463 3464 3465 3466 3467
    }

    // check for like expression
    if ((*pExpr)->nSQLOptr == TK_LIKE) {
      if (pRight->val.nLen > TSDB_PATTERN_STRING_MAX_LEN) {
3468
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
3469 3470
      }

H
hjxilinx 已提交
3471
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3472 3473 3474

      if ((!isTablenameToken(&pLeft->colInfo)) && pSchema[index.columnIndex].type != TSDB_DATA_TYPE_BINARY &&
          pSchema[index.columnIndex].type != TSDB_DATA_TYPE_NCHAR) {
3475
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3476 3477 3478 3479 3480 3481
      }
    }

    // in case of in operator, keep it in a seperate attribute
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3482
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
3483
      }
3484 3485
  
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
3486
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
3487
      }
S
slguan 已提交
3488 3489 3490 3491 3492 3493

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3494
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
3495 3496 3497 3498 3499 3500
      }

      *type = TSQL_EXPR_TBNAME;
      *pExpr = NULL;
    } else {
      if (pRight->nSQLOptr == TK_ID) {  // join on tag columns for stable query
3501
        if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3502
          return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3503 3504 3505
        }

        if (pCondExpr->pJoinExpr != NULL) {
3506
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3507 3508
        }

3509 3510
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524
        *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
3525
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
3526 3527
    }

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

S
slguan 已提交
3532
  return ret;
H
hzcheng 已提交
3533 3534
}

3535 3536
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                        int32_t* type, int32_t parentOptr) {
H
hzcheng 已提交
3537 3538 3539 3540
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3543 3544 3545 3546
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3547
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3548 3549
  }

S
slguan 已提交
3550 3551
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3552

S
slguan 已提交
3553
  if (!isExprDirectParentOfLeaftNode(*pExpr)) {
3554
    int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3555 3556 3557 3558
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3559
    ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3560 3561 3562
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3563

S
slguan 已提交
3564 3565 3566 3567 3568 3569
    /*
     *  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)) {
3570
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3571
      }
H
hzcheng 已提交
3572 3573
    }

S
slguan 已提交
3574 3575 3576
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3577

S
slguan 已提交
3578
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3579

3580
  return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3581
}
H
hzcheng 已提交
3582

S
slguan 已提交
3583 3584 3585 3586
static void doCompactQueryExpr(tSQLExpr** pExpr) {
  if (*pExpr == NULL || isExprDirectParentOfLeaftNode(*pExpr)) {
    return;
  }
H
hzcheng 已提交
3587

S
slguan 已提交
3588 3589 3590
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3591

S
slguan 已提交
3592 3593 3594
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3595

S
slguan 已提交
3596 3597 3598 3599
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3600

S
slguan 已提交
3601 3602 3603
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3604

S
slguan 已提交
3605 3606 3607 3608
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3609

S
slguan 已提交
3610
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3611
  }
S
slguan 已提交
3612
}
H
hzcheng 已提交
3613

3614
static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
S
slguan 已提交
3615 3616 3617 3618
  if (isExprDirectParentOfLeaftNode(*pExpr)) {
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3619
    if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3620
      return;
H
hzcheng 已提交
3621 3622
    }

S
slguan 已提交
3623 3624 3625 3626
    if (index.tableIndex != tableIndex) {
      return;
    }

H
Haojun Liao 已提交
3627
    SStrToken t = {0};
S
slguan 已提交
3628 3629 3630 3631 3632 3633 3634 3635
    extractTableNameFromToken(&pLeft->colInfo, &t);

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

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

3636 3637
    doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3638 3639 3640
  }
}

3641
static tSQLExpr* extractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, int32_t tableIndex) {
S
slguan 已提交
3642
  tSQLExpr* pResExpr = NULL;
H
hzcheng 已提交
3643

S
slguan 已提交
3644
  if (*pExpr != NULL) {
3645
    doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3646
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3647 3648
  }

S
slguan 已提交
3649
  return pResExpr;
H
hzcheng 已提交
3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664
}

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

3665 3666
static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, const char* account,
                                          tSQLExpr* pExpr, int16_t tableCondIndex, SStringBuilder* sb) {
3667
  const char* msg = "table name too long";
H
hzcheng 已提交
3668

S
slguan 已提交
3669 3670 3671 3672
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3675
  STagCond* pTagCond = &pQueryInfo->tagCond;
3676
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
S
slguan 已提交
3677 3678 3679 3680

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3681
    char* str = taosStringBuilderGetResult(sb, NULL);
3682
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3683 3684 3685
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
3686
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
3687
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3688

H
Haojun Liao 已提交
3689
  char db[TSDB_TABLE_FNAME_LEN] = {0};
H
hzcheng 已提交
3690

S
slguan 已提交
3691
  // remove the duplicated input table names
H
hzcheng 已提交
3692
  int32_t num = 0;
H
hjxilinx 已提交
3693 3694 3695
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3696
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3697 3698 3699 3700 3701 3702 3703 3704 3705

  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 已提交
3706
  char* name = extractDBName(pTableMetaInfo->name, db);
H
Haojun Liao 已提交
3707
  SStrToken dbToken = { .type = TK_STRING, .z = name, .n = (uint32_t)strlen(name) };
H
hjxilinx 已提交
3708
  
H
hzcheng 已提交
3709 3710
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3711
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3712
    }
H
hjxilinx 已提交
3713

H
Haojun Liao 已提交
3714
    char      idBuf[TSDB_TABLE_FNAME_LEN] = {0};
S
TD-1057  
Shengliang Guan 已提交
3715
    int32_t   xlen = (int32_t)strlen(segments[i]);
H
Haojun Liao 已提交
3716
    SStrToken t = {.z = segments[i], .n = xlen, .type = TK_STRING};
H
hzcheng 已提交
3717

3718
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3719
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3720
      taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3721
      taosTFree(segments);
H
hjxilinx 已提交
3722

3723
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
3724 3725
      return ret;
    }
H
hjxilinx 已提交
3726

H
hjxilinx 已提交
3727
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3728
  }
H
hjxilinx 已提交
3729

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

H
hjxilinx 已提交
3733
  taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3734
  taosTFree(segments);
H
hzcheng 已提交
3735 3736 3737
  return TSDB_CODE_SUCCESS;
}

3738
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
3739 3740 3741 3742 3743 3744
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
3745

3746 3747
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
3748 3749
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
3750

3751
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765
          (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;
}

3766
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
3767 3768
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
3769 3770 3771 3772 3773

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

S
slguan 已提交
3774 3775
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    if (pExpr->nSQLOptr == TK_OR) {
3776
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3777
    }
H
hzcheng 已提交
3778

3779
    getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft);
S
slguan 已提交
3780

3781
    return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
S
slguan 已提交
3782 3783
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3784
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3785
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3786 3787
    }

H
hjxilinx 已提交
3788
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3789
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3790
    
S
slguan 已提交
3791 3792
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3793 3794
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
3795
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3796 3797 3798
    }

    // update the timestamp query range
H
hjxilinx 已提交
3799 3800
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
3801 3802
    }

H
hjxilinx 已提交
3803 3804
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
3805 3806 3807 3808 3809 3810
    }
  }

  return TSDB_CODE_SUCCESS;
}

3811
static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
3812 3813 3814 3815
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

3816 3817
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
3818 3819
      return TSDB_CODE_SUCCESS;
    } else {
3820
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3821 3822 3823
    }
  }

H
hjxilinx 已提交
3824
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
3825
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // for stable join, tag columns
3826
                                                   // must be present for join
S
slguan 已提交
3827
    if (pCondExpr->pJoinExpr == NULL) {
3828
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3829 3830 3831 3832
    }
  }

  if (!pCondExpr->tsJoin) {
3833
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3834 3835
  }

S
slguan 已提交
3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860
  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);
  }
}

3861
static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
H
hjxilinx 已提交
3862
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
3863
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
S
slguan 已提交
3864
    SColumnIndex index = {0};
H
hjxilinx 已提交
3865

3866
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
3867 3868
      tscError("%p: invalid column name (left)", pQueryInfo);
    }
H
hjxilinx 已提交
3869
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3870 3871
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3872 3873
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
  
3874
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
3875 3876
      tscError("%p: invalid column name (right)", pQueryInfo);
    }
H
hjxilinx 已提交
3877
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3878 3879
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3880
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
3881
  }
H
hjxilinx 已提交
3882
}
S
slguan 已提交
3883

3884
static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSQLExpr** pExpr) {
H
hjxilinx 已提交
3885
  int32_t ret = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
3886

3887 3888 3889 3890 3891
  if (pCondExpr->pTagCond == NULL) {
    return ret;
  }
  
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
3892
    tSQLExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
H
Haojun Liao 已提交
3893 3894 3895 3896
    if (p1 == NULL) {  // no query condition on this table
      continue;
    }

3897
    tExprNode* p = NULL;
3898 3899
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
3900
    ret = exprTreeFromSqlExpr(pCmd, &p, p1, NULL, pQueryInfo, colList);
3901 3902 3903 3904 3905 3906 3907 3908 3909
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
3910
    
3911 3912
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
3913
    int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
3914 3915 3916 3917 3918 3919
    int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
    
    size_t num = taosArrayGetSize(colList);
    for(int32_t j = 0; j < num; ++j) {
      SColIndex* pIndex = taosArrayGet(colList, j);
      SColumnIndex index = {.tableIndex = i, .columnIndex = pIndex->colIndex - numOfCols};
H
hjxilinx 已提交
3920
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
3921 3922
    }
    
3923
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
3924 3925 3926 3927
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
3928 3929
    
    taosArrayDestroy(colList);
H
hjxilinx 已提交
3930
  }
H
hjxilinx 已提交
3931

3932
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
3933 3934
  return ret;
}
3935
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
3936 3937 3938
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
3939

H
hjxilinx 已提交
3940
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
3941
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
3942

H
hjxilinx 已提交
3943
  int32_t ret = TSDB_CODE_SUCCESS;
3944
  pQueryInfo->window = TSWINDOW_INITIALIZER;
S
slguan 已提交
3945

H
hjxilinx 已提交
3946
  // tags query condition may be larger than 512bytes, therefore, we need to prepare enough large space
S
Shuduo Sang 已提交
3947
  SStringBuilder sb; memset(&sb, 0, sizeof(sb));
H
hjxilinx 已提交
3948
  SCondExpr      condExpr = {0};
S
slguan 已提交
3949

H
hjxilinx 已提交
3950
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
3951
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
S
slguan 已提交
3952 3953
  }

H
hjxilinx 已提交
3954
  int32_t type = 0;
3955
  if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3956 3957
    return ret;
  }
H
hjxilinx 已提交
3958

S
slguan 已提交
3959
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
3960

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

S
slguan 已提交
3964
  // 1. check if it is a join query
3965
  if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3966 3967
    return ret;
  }
H
hjxilinx 已提交
3968

S
slguan 已提交
3969
  // 2. get the query time range
3970
  if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3971 3972
    return ret;
  }
H
hjxilinx 已提交
3973

S
slguan 已提交
3974
  // 3. get the tag query condition
3975
  if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3976
    return ret;
S
slguan 已提交
3977
  }
H
hjxilinx 已提交
3978

S
slguan 已提交
3979
  // 4. get the table name query condition
3980
  if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3981 3982
    return ret;
  }
H
hjxilinx 已提交
3983

S
slguan 已提交
3984
  // 5. other column query condition
3985
  if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3986 3987
    return ret;
  }
H
hjxilinx 已提交
3988

S
slguan 已提交
3989
  // 6. join condition
3990
  if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3991
    return ret;
H
hzcheng 已提交
3992
  }
H
hjxilinx 已提交
3993

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

3997
  ret = setTableCondForSTableQuery(&pSql->cmd, pQueryInfo, getAccountId(pSql), condExpr.pTableCond, condExpr.tableCondIndex, &sb);
H
hjxilinx 已提交
3998
  taosStringBuilderDestroy(&sb);
H
hjxilinx 已提交
3999

4000
  if (!validateFilterExpr(pQueryInfo)) {
4001
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
4002
  }
H
hjxilinx 已提交
4003

4004
  doAddJoinTagsColumnsIntoTagList(&pSql->cmd, pQueryInfo, &condExpr);
H
hjxilinx 已提交
4005

H
hjxilinx 已提交
4006
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
4007 4008 4009
  return ret;
}

H
hjxilinx 已提交
4010
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
4011 4012 4013 4014 4015
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
4016 4017
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
4018
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
4019 4020
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
4021
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4022
  }
H
hzcheng 已提交
4023 4024 4025 4026

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

S
slguan 已提交
4029
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
4030
    if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
4031
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4032 4033
        parsed = true;
      } else {
4034
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4035
      }
S
slguan 已提交
4036
    } else {
H
Haojun Liao 已提交
4037
      SStrToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
S
slguan 已提交
4038 4039 4040
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
4041
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4042
      }
H
hzcheng 已提交
4043 4044 4045 4046
    }
  } 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 已提交
4047
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062
     *
     * 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
     */
4063
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084

    /*
     * 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) {
H
hjxilinx 已提交
4085
    win->ekey = val;
H
hzcheng 已提交
4086
  } else if (optr == TK_LT) {
H
hjxilinx 已提交
4087
    win->ekey = val - delta;
H
hzcheng 已提交
4088
  } else if (optr == TK_GT) {
H
hjxilinx 已提交
4089
    win->skey = val + delta;
H
hzcheng 已提交
4090
  } else if (optr == TK_GE) {
H
hjxilinx 已提交
4091
    win->skey = val;
H
hzcheng 已提交
4092
  } else if (optr == TK_EQ) {
H
hjxilinx 已提交
4093
    win->ekey = win->skey = val;
H
hzcheng 已提交
4094 4095 4096 4097
  }
  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
4098
// todo error !!!!
4099
int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
4100 4101
  const char rep[] = {'(', ')', '*', ',', '.', '/', '\\', '+', '-', '%', ' '};

H
hjxilinx 已提交
4102 4103
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
B
Bomin Zhang 已提交
4104
    for (int32_t j = 0; j < (TSDB_COL_NAME_LEN - 1) && fieldName[j] != 0; ++j) {
S
slguan 已提交
4105 4106 4107 4108 4109
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
4110 4111
      }
    }
S
slguan 已提交
4112

H
hzcheng 已提交
4113 4114 4115 4116
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4117 4118 4119
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
    for (int32_t j = i + 1; j < pQueryInfo->fieldsInfo.numOfOutput; ++j) {
B
Bomin Zhang 已提交
4120
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4121
        const char* msg = "duplicated column name in new table";
4122
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4123 4124 4125 4126 4127 4128 4129
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4130
int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
4131 4132 4133 4134
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
4135 4136 4137 4138

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

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4141
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4142
  }
H
hjxilinx 已提交
4143 4144 4145
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
4146 4147 4148
  if (pQueryInfo->fillVal == NULL) {
    pQueryInfo->fillVal = calloc(size, sizeof(int64_t));
    if (pQueryInfo->fillVal == NULL) {
4149
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4150 4151 4152
    }
  }

H
hzcheng 已提交
4153
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4154
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4155
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4156
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4157 4158
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
4159 4160 4161 4162 4163
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
      } else {
        setNull((char*)&pQueryInfo->fillVal[i], pFields->type, pFields->bytes);
      };
H
hzcheng 已提交
4164 4165
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4166
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4167
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4168
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4169
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4170
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4171 4172

    if (pFillToken->nExpr == 1) {
4173
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4174 4175 4176 4177 4178 4179
    }

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

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

H
hjxilinx 已提交
4183
      if (numOfFillVal > size) {
S
TD-1057  
Shengliang Guan 已提交
4184
        numOfFillVal = (int32_t)size;
H
hzcheng 已提交
4185 4186
      }
    } else {
S
TD-1057  
Shengliang Guan 已提交
4187
      numOfFillVal = (pFillToken->nExpr >  (int32_t)size) ? (int32_t)size : pFillToken->nExpr;
H
hzcheng 已提交
4188 4189 4190 4191 4192
    }

    int32_t j = 1;

    for (int32_t i = startPos; i < numOfFillVal; ++i, ++j) {
H
hjxilinx 已提交
4193
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hjxilinx 已提交
4194

4195
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4196
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
4197 4198
        continue;
      }
H
hjxilinx 已提交
4199

4200
      int32_t ret = tVariantDump(&pFillToken->a[j].pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4201
      if (ret != TSDB_CODE_SUCCESS) {
4202
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4203 4204
      }
    }
H
hjxilinx 已提交
4205
    
4206
    if ((pFillToken->nExpr < size) || ((pFillToken->nExpr - 1 < size) && (tscIsPointInterpQuery(pQueryInfo)))) {
H
hzcheng 已提交
4207 4208
      tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1];

H
hjxilinx 已提交
4209 4210
      for (int32_t i = numOfFillVal; i < size; ++i) {
        TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4211 4212

        if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4213
          setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
H
hjxilinx 已提交
4214
        } else {
4215
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4216 4217 4218 4219
        }
      }
    }
  } else {
4220
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4221 4222 4223 4224 4225
  }

  return TSDB_CODE_SUCCESS;
}

4226
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4227
  /* set default timestamp order information for all queries */
4228
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
hjxilinx 已提交
4229
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4230

4231
  if (isTopBottomQuery(pQueryInfo)) {
4232
    pQueryInfo->order.order = TSDB_ORDER_ASC;
4233
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4234
  } else {
4235
    pQueryInfo->order.orderColId = -1;
H
hzcheng 已提交
4236 4237
  }

H
hjxilinx 已提交
4238
  /* for super table query, set default ascending order for group output */
weixin_48148422's avatar
weixin_48148422 已提交
4239
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
4240
    pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
H
hzcheng 已提交
4241 4242 4243
  }
}

4244
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4245 4246 4247 4248
  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 已提交
4249

4250
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4251
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4252 4253 4254 4255 4256 4257

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

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4258 4259 4260 4261 4262 4263 4264

  /*
   * 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.
   */
weixin_48148422's avatar
weixin_48148422 已提交
4265
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4266
    if (pSortorder->nExpr > 1) {
4267
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4268 4269 4270
    }
  } else {
    if (pSortorder->nExpr > 2) {
4271
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282
    }
  }

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

H
Haojun Liao 已提交
4283
  SStrToken    columnName = {pVar->nLen, pVar->nType, pVar->pz};
S
slguan 已提交
4284 4285
  SColumnIndex index = {0};

weixin_48148422's avatar
weixin_48148422 已提交
4286
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4287 4288
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4289 4290 4291 4292
    }

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

H
hjxilinx 已提交
4294 4295
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4296
      
4297 4298
      // it is a tag column
      if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
4299
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4300
      }
4301 4302
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (relTagIndex == pColIndex->colIndex) {
H
hzcheng 已提交
4303 4304
        orderByTags = true;
      }
S
slguan 已提交
4305 4306
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4307 4308
    }

S
slguan 已提交
4309
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4310 4311 4312
      orderByTS = true;
    }

4313
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
4314
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4315 4316 4317 4318 4319 4320
    } else {
      assert(!(orderByTags && orderByTS));
    }

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

4328
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4329
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4330
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
4331
        }
4332

4333 4334
        pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4335
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4336
      } else {
4337 4338
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4339 4340 4341 4342
      }
    }

    if (pSortorder->nExpr == 2) {
S
slguan 已提交
4343
      if (orderByTags) {
H
hjxilinx 已提交
4344
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4345
        pQueryInfo->groupbyExpr.orderType = pQuerySql->pSortOrder->a[0].sortOrder;
S
slguan 已提交
4346
      } else {
4347 4348
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4349 4350
      }

H
hzcheng 已提交
4351
      tVariant* pVar2 = &pSortorder->a[1].pVar;
H
Haojun Liao 已提交
4352
      SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4353 4354
      if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4355 4356 4357
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4358
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4359
      } else {
4360 4361
        pQueryInfo->order.order = pSortorder->a[1].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4362 4363 4364 4365
      }
    }

  } else {  // meter query
4366 4367
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4368 4369
    }

4370
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
4371
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4372 4373
    }

4374
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4375
      /* order of top/bottom query in interval is not valid  */
4376
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4377
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4378

4379
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4380
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4381
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4382
      }
4383

4384 4385
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4386 4387
      return TSDB_CODE_SUCCESS;
    }
4388

4389
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4390 4391 4392 4393 4394 4395
  }

  return TSDB_CODE_SUCCESS;
}

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

4398 4399 4400 4401 4402 4403
  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";
H
hjxilinx 已提交
4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418
  
  const char* msg7 = "no tags can be dropped";
  const char* msg8 = "only support one tag";
  const char* msg9 = "tag name too long";
  
  const char* msg10 = "invalid tag name";
  const char* msg11 = "primary tag cannot be dropped";
  const char* msg12 = "update normal column not supported";
  const char* msg13 = "invalid tag value";
  const char* msg14 = "tag value too long";
  
  const char* msg15 = "no columns can be dropped";
  const char* msg16 = "only support one column";
  const char* msg17 = "invalid column name";
  const char* msg18 = "primary timestamp column cannot be dropped";
H
Haojun Liao 已提交
4419 4420
  const char* msg19 = "invalid new tag name";

S
slguan 已提交
4421
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4422
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4423 4424
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4427
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4428
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
4429
  }
P
plum-lihui 已提交
4430

H
Haojun Liao 已提交
4431
  if (tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql) != TSDB_CODE_SUCCESS) {
4432
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4433 4434
  }

H
hjxilinx 已提交
4435
  int32_t ret = tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
4436 4437 4438 4439
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

H
hjxilinx 已提交
4440
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4441

4442 4443
  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) {
weixin_48148422's avatar
weixin_48148422 已提交
4444
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
4445
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4446
    }
weixin_48148422's avatar
weixin_48148422 已提交
4447
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) {
4448
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
4449
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4450
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4451
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
4452 4453
  }

4454
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
hzcheng 已提交
4455 4456
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4457
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
4458 4459 4460
    }

    if (!validateOneTags(pCmd, &pFieldList->p[0])) {
4461
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4462
    }
H
hjxilinx 已提交
4463 4464
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4465
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
H
hjxilinx 已提交
4466
    if (tscGetNumOfTags(pTableMeta) == 1) {
4467
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
4468 4469 4470 4471
    }

    // numOfTags == 1
    if (pAlterSQL->varList->nExpr > 1) {
4472
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
hzcheng 已提交
4473 4474 4475
    }

    tVariantListItem* pItem = &pAlterSQL->varList->a[0];
B
Bomin Zhang 已提交
4476
    if (pItem->pVar.nLen >= TSDB_COL_NAME_LEN) {
4477
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4478
    }
4479

4480
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4481
    SStrToken    name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen, .type = TK_STRING};
4482

4483
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4484
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4485 4486
    }

H
Haojun Liao 已提交
4487 4488
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
4489
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
H
Haojun Liao 已提交
4490
    } else if (index.columnIndex == numOfCols) {
4491
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
H
hzcheng 已提交
4492 4493
    }

4494 4495
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4496 4497 4498
  
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4499
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
hzcheng 已提交
4500 4501
    tVariantList* pVarList = pAlterSQL->varList;
    if (pVarList->nExpr > 2) {
4502
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4503 4504
    }

4505 4506 4507 4508
    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) {
4509
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4510 4511
    }

4512
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4513
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
4514
    }
H
hzcheng 已提交
4515

S
slguan 已提交
4516 4517
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4518

H
Haojun Liao 已提交
4519
    SStrToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4520
    if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4521
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4522 4523
    }

H
Haojun Liao 已提交
4524
    SStrToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4525
    if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4526
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
H
hzcheng 已提交
4527 4528
    }

B
Bomin Zhang 已提交
4529
    char name[TSDB_COL_NAME_LEN] = {0};
H
hzcheng 已提交
4530
    strncpy(name, pVarList->a[0].pVar.pz, pVarList->a[0].pVar.nLen);
H
hjxilinx 已提交
4531 4532
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4533 4534 4535

    memset(name, 0, tListLen(name));
    strncpy(name, pVarList->a[1].pVar.pz, pVarList->a[1].pVar.nLen);
H
hjxilinx 已提交
4536 4537
    f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4538 4539
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
    // Note: update can only be applied to table not super table.
4540 4541 4542
    // the following is used to handle tags value for table created according to super table
    pCmd->command = TSDB_SQL_UPDATE_TAGS_VAL;
    
H
hzcheng 已提交
4543 4544
    tVariantList* pVarList = pAlterSQL->varList;
    tVariant*     pTagName = &pVarList->a[0].pVar;
4545
    int16_t       numOfTags = tscGetNumOfTags(pTableMeta);
H
hzcheng 已提交
4546

4547
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4548
    SStrToken    name = {.type = TK_STRING, .z = pTagName->pz, .n = pTagName->nLen};
4549
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4550
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4551 4552
    }

H
hjxilinx 已提交
4553
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4554
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12);
S
slguan 已提交
4555 4556
    }

H
hjxilinx 已提交
4557
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
4558
    if (tVariantDump(&pVarList->a[1].pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) {
4559
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg13);
H
hzcheng 已提交
4560
    }
4561
    
4562
    pAlterSQL->tagData.dataLen = pTagsSchema->bytes;
H
hzcheng 已提交
4563 4564

    // validate the length of binary
4565
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
4566
        (pVarList->a[1].pVar.nLen + VARSTR_HEADER_SIZE) > pTagsSchema->bytes) {
4567
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg14);
H
hzcheng 已提交
4568
    }
4569 4570 4571 4572

    int32_t schemaLen = sizeof(STColumn) * numOfTags;
    int32_t size = sizeof(SUpdateTableTagValMsg) + pTagsSchema->bytes + schemaLen + TSDB_EXTRA_PAYLOAD_SIZE;

4573 4574
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4575
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4576 4577
    }

4578
    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
4579
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
4580 4581
    pUpdateMsg->tid       = htonl(pTableMeta->id.tid);
    pUpdateMsg->uid       = htobe64(pTableMeta->id.uid);
H
Haojun Liao 已提交
4582
    pUpdateMsg->colId     = htons(pTagsSchema->colId);
H
Hongze Cheng 已提交
4583
    pUpdateMsg->type      = pTagsSchema->type;
H
Haojun Liao 已提交
4584 4585
    pUpdateMsg->bytes     = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion  = htons(pTableMeta->tversion);
4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603
    pUpdateMsg->numOfTags = htons(numOfTags);
    pUpdateMsg->schemaLen = htonl(schemaLen);

    // the schema is located after the msg body, then followed by true tag value
    char* d = pUpdateMsg->data;
    SSchema* pTagCols = tscGetTableTagSchema(pTableMeta);
    for (int i = 0; i < numOfTags; ++i) {
      STColumn* pCol = (STColumn*) d;
      pCol->colId = htons(pTagCols[i].colId);
      pCol->bytes = htons(pTagCols[i].bytes);
      pCol->type  = pTagCols[i].type;
      pCol->offset = 0;

      d += sizeof(STColumn);
    }

    // copy the tag value to msg body
    tVariantDump(&pVarList->a[1].pVar, pUpdateMsg->data + schemaLen, pTagsSchema->type, true);
4604 4605 4606 4607 4608
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
4609
      len = varDataTLen(pUpdateMsg->data + schemaLen);
4610 4611 4612 4613
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
4614
    int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen;
4615
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4616
    
4617
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
hzcheng 已提交
4618 4619
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4620
      const char* msg = "only support add one column";
4621
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4622 4623 4624
    }

    if (!validateOneColumn(pCmd, &pFieldList->p[0])) {
4625
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4626
    }
H
hjxilinx 已提交
4627 4628
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4629
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
H
hjxilinx 已提交
4630
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
H
hjxilinx 已提交
4631
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15);
H
hzcheng 已提交
4632 4633 4634
    }

    if (pAlterSQL->varList->nExpr > 1) {
H
hjxilinx 已提交
4635
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4636 4637 4638 4639
    }

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

4640
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4641
    SStrToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4642 4643
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4644 4645
    }

4646
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4647
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18);
4648
    }
H
hzcheng 已提交
4649

B
Bomin Zhang 已提交
4650 4651
    char name1[TSDB_COL_NAME_LEN] = {0};
    tstrncpy(name1, pItem->pVar.pz, sizeof(name1));
H
hjxilinx 已提交
4652 4653
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4654 4655 4656 4657 4658
  }

  return TSDB_CODE_SUCCESS;
}

4659
int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
4660 4661
  const char* msg0 = "sample interval can not be less than 10ms.";
  const char* msg1 = "functions not allowed in select clause";
H
hzcheng 已提交
4662

4663
  if (pQueryInfo->intervalTime != 0 && pQueryInfo->intervalTime < 10) {
4664
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4665
  }
H
hjxilinx 已提交
4666
  
H
hjxilinx 已提交
4667
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4668
  for (int32_t i = 0; i < size; ++i) {
4669
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
4670
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
4671
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4672 4673 4674 4675 4676 4677
    }
  }

  return TSDB_CODE_SUCCESS;
}

4678
int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
4679
  bool        isProjectionFunction = false;
4680
  const char* msg1 = "column projection is not compatible with interval";
H
hjxilinx 已提交
4681

H
hzcheng 已提交
4682
  // multi-output set/ todo refactor
H
hjxilinx 已提交
4683
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4684 4685
  
  for (int32_t k = 0; k < size; ++k) {
4686
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
4687

4688 4689 4690
    // 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 已提交
4691
      for (int32_t j = 0; j < size; ++j) {
4692
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
4693 4694 4695 4696 4697
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
4698

4699 4700 4701 4702
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4703

4704
    if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4705
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4706 4707 4708
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4709 4710

  if (isProjectionFunction) {
4711
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4712 4713
  }

4714
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4715 4716 4717
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4718 4719
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4720 4721
} SDNodeDynConfOption;

H
Hui Li 已提交
4722

4723
int32_t validateEp(char* ep) {  
H
Hui Li 已提交
4724 4725 4726
  char buf[TSDB_EP_LEN + 1] = {0};
  tstrncpy(buf, ep, TSDB_EP_LEN);

4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737
  char* pos = strchr(buf, ':');
  if (NULL == pos) {
    int32_t val = strtol(ep, NULL, 10);
    if (val <= 0 || val > 65536) {
      return TSDB_CODE_TSC_INVALID_SQL;
    }
  } else {
    uint16_t port = atoi(pos + 1);
    if (0 == port) {
      return TSDB_CODE_TSC_INVALID_SQL;
    }
H
Hui Li 已提交
4738 4739
  }

4740
  return TSDB_CODE_SUCCESS;
H
Hui Li 已提交
4741 4742
}

H
hzcheng 已提交
4743 4744
int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
4745
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4746 4747
  }

4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759
  const int tokenLogEnd = 2;
  const int tokenBalance = 2;
  const int tokenMonitor = 3;
  const int tokenDebugFlag = 4;
  const int tokenDebugFlagEnd = 20;
  const SDNodeDynConfOption cfgOptions[] = {
      {"resetLog", 8},    {"resetQueryCache", 15},  {"balance", 7},     {"monitor", 7},
      {"debugFlag", 9},   {"monitorDebugFlag", 16}, {"vDebugFlag", 10}, {"mDebugFlag", 10},
      {"cDebugFlag", 10}, {"httpDebugFlag", 13},    {"qDebugflag", 10}, {"sdbDebugFlag", 12},
      {"uDebugFlag", 10}, {"tsdbDebugFlag", 13},    {"sDebugflag", 10}, {"rpcDebugFlag", 12},
      {"dDebugFlag", 10}, {"mqttDebugFlag", 13},    {"wDebugFlag", 10}, {"tmrDebugFlag", 12},
  };
H
hzcheng 已提交
4760

H
Haojun Liao 已提交
4761
  SStrToken* pOptionToken = &pOptions->a[1];
H
hzcheng 已提交
4762 4763 4764

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
4765 4766
    for (int32_t i = 0; i < tokenLogEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4767 4768 4769 4770
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
4771 4772
  } else if ((strncasecmp(cfgOptions[tokenBalance].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenBalance].len == pOptionToken->n)) {
H
Haojun Liao 已提交
4773
    SStrToken* pValToken = &pOptions->a[2];
S
Shengliang Guan 已提交
4774 4775
    int32_t vnodeId = 0;
    int32_t dnodeId = 0;
4776
    strdequote(pValToken->z);
S
Shengliang Guan 已提交
4777
    bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId);
4778 4779 4780 4781 4782 4783
    if (!parseOk) {
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
    }
    return TSDB_CODE_SUCCESS;
  } else if ((strncasecmp(cfgOptions[tokenMonitor].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenMonitor].len == pOptionToken->n)) {
H
Haojun Liao 已提交
4784
    SStrToken* pValToken = &pOptions->a[2];
S
slguan 已提交
4785 4786
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
4787
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
S
slguan 已提交
4788 4789
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4790
  } else {
H
Haojun Liao 已提交
4791
    SStrToken* pValToken = &pOptions->a[2];
H
hzcheng 已提交
4792 4793

    int32_t val = strtol(pValToken->z, NULL, 10);
4794
    if (val < 0 || val > 256) {
H
hzcheng 已提交
4795
      /* options value is out of valid range */
4796
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4797 4798
    }

4799 4800
    for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4801 4802 4803 4804 4805 4806 4807 4808

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

4809
  return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4810 4811
}

S
slguan 已提交
4812 4813
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
4814
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4815 4816
  }

H
hjxilinx 已提交
4817 4818
  SDNodeDynConfOption LOCAL_DYNAMIC_CFG_OPTIONS[6] = {{"resetLog", 8},    {"rpcDebugFlag", 12}, {"tmrDebugFlag", 12},
                                                      {"cDebugFlag", 10}, {"uDebugFlag", 10},   {"debugFlag", 9}};
S
slguan 已提交
4819

H
Haojun Liao 已提交
4820
  SStrToken* pOptionToken = &pOptions->a[0];
S
slguan 已提交
4821 4822 4823 4824 4825 4826 4827 4828 4829 4830

  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 {
H
Haojun Liao 已提交
4831
    SStrToken* pValToken = &pOptions->a[1];
S
slguan 已提交
4832 4833 4834 4835

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
4836
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4837 4838 4839 4840 4841 4842 4843 4844 4845 4846
    }

    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;
      }
    }
  }
4847
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4848 4849
}

H
hzcheng 已提交
4850
int32_t validateColumnName(char* name) {
S
TD-1057  
Shengliang Guan 已提交
4851
  bool ret = isKeyWord(name, (int32_t)strlen(name));
H
hzcheng 已提交
4852
  if (ret) {
4853
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4854 4855
  }

H
Haojun Liao 已提交
4856
  SStrToken token = {.z = name};
H
hzcheng 已提交
4857 4858 4859
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
4860
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4861 4862 4863 4864
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
S
TD-1057  
Shengliang Guan 已提交
4865
    token.n = (uint32_t)strtrim(token.z);
H
hzcheng 已提交
4866 4867 4868

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
4869
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4870 4871 4872 4873 4874
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
4875
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4876 4877 4878 4879 4880 4881
    }
  }

  return TSDB_CODE_SUCCESS;
}

4882 4883
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
4884 4885 4886
    return true;
  }

H
hjxilinx 已提交
4887
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
4888 4889
}

4890
int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* pQuerySql, SSqlObj* pSql) {
H
hjxilinx 已提交
4891
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4892

S
slguan 已提交
4893 4894
  const char* msg0 = "soffset/offset can not be less than 0";
  const char* msg1 = "slimit/soffset only available for STable query";
4895
  const char* msg2 = "functions mixed up in table query";
S
slguan 已提交
4896
  const char* msg3 = "slimit/soffset can not apply to projection query";
H
hjxilinx 已提交
4897

H
hzcheng 已提交
4898
  // handle the limit offset value, validate the limit
4899
  pQueryInfo->limit = pQuerySql->limit;
4900
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4901
  pQueryInfo->slimit = pQuerySql->slimit;
4902
  
4903
  tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
4904 4905
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
4906
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
4907
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
4908 4909
  }

4910
  if (pQueryInfo->limit.limit == 0) {
4911
    tscDebug("%p limit 0, no output result", pSql);
4912
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4913
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
4914 4915
  }

H
hjxilinx 已提交
4916
  // todo refactor
weixin_48148422's avatar
weixin_48148422 已提交
4917
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
4918
    if (!tscQueryTags(pQueryInfo)) {  // local handle the super table tag query
4919
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
4920
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
4921
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
4922
        }
H
hjxilinx 已提交
4923

4924
        // for projection query on super table, all queries are subqueries
H
hjxilinx 已提交
4925 4926
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
            !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
4927
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
4928
        }
S
slguan 已提交
4929
      }
H
hzcheng 已提交
4930 4931
    }

4932
    if (pQueryInfo->slimit.limit == 0) {
4933
      tscDebug("%p slimit 0, no output result", pSql);
4934
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4935 4936 4937 4938
      return TSDB_CODE_SUCCESS;
    }

    /*
4939 4940 4941 4942
     * 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 已提交
4943
     */
H
hjxilinx 已提交
4944
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
4945 4946 4947 4948
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
4949
    // No tables included. No results generated. Query results are empty.
4950
    if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
4951
      tscDebug("%p no table in super table, no output result", pSql);
4952
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4953
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4954 4955 4956
    }

    // keep original limitation value in globalLimit
4957
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4958
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
4959

4960 4961 4962 4963 4964 4965 4966 4967 4968
    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 已提交
4969

4970 4971
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
4972
  } else {
4973
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
4974
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4975
    }
H
hjxilinx 已提交
4976
  
H
hjxilinx 已提交
4977
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
4978 4979 4980
    
    bool hasTags = false;
    bool hasOtherFunc = false;
S
slguan 已提交
4981
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
4982
    for (int32_t i = 0; i < size; ++i) {
4983
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
4984 4985 4986 4987
      if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
        hasTags = true;
      } else {
        hasOtherFunc = true;
H
hzcheng 已提交
4988 4989
      }
    }
4990 4991
    
    if (hasTags && hasOtherFunc) {
4992
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4993
    }
H
hzcheng 已提交
4994 4995 4996 4997
  }

  return TSDB_CODE_SUCCESS;
}
4998

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

5002 5003 5004
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
5005

H
hjxilinx 已提交
5006 5007 5008
  tVariantList* pKeep = pCreateDb->keep;
  if (pKeep != NULL) {
    switch (pKeep->nExpr) {
S
slguan 已提交
5009
      case 1:
S
TD-1057  
Shengliang Guan 已提交
5010
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
5011 5012
        break;
      case 2: {
S
TD-1057  
Shengliang Guan 已提交
5013 5014
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)pKeep->a[1].pVar.i64Key);
5015 5016 5017
        break;
      }
      case 3: {
S
TD-1057  
Shengliang Guan 已提交
5018 5019 5020
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)pKeep->a[1].pVar.i64Key);
        pMsg->daysToKeep2 = htonl((int32_t)pKeep->a[2].pVar.i64Key);
5021 5022
        break;
      }
5023
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
5024 5025
    }
  }
H
hjxilinx 已提交
5026

H
hjxilinx 已提交
5027 5028
  return TSDB_CODE_SUCCESS;
}
5029

H
hjxilinx 已提交
5030
static int32_t setTimePrecision(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDbInfo) {
H
hjxilinx 已提交
5031
  const char* msg = "invalid time precision";
H
hjxilinx 已提交
5032

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

H
Haojun Liao 已提交
5035
  SStrToken* pToken = &pCreateDbInfo->precision;
5036 5037
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
5038

5039 5040 5041 5042 5043
    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 已提交
5044
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
5045 5046
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
5047
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
5048 5049
    }
  }
H
hjxilinx 已提交
5050

H
hjxilinx 已提交
5051 5052
  return TSDB_CODE_SUCCESS;
}
5053

5054
static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
hjxilinx 已提交
5055 5056
  pMsg->maxTables = htonl(pCreateDb->maxTablesPerVnode);
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
5057
  pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
H
hjxilinx 已提交
5058
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
S
TD-1057  
Shengliang Guan 已提交
5059
  pMsg->commitTime = htonl((int32_t)pCreateDb->commitTime);
H
hjxilinx 已提交
5060 5061
  pMsg->minRowsPerFileBlock = htonl(pCreateDb->minRowsPerBlock);
  pMsg->maxRowsPerFileBlock = htonl(pCreateDb->maxRowsPerBlock);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5062
  pMsg->fsyncPeriod = htonl(pCreateDb->fsyncPeriod);
S
slguan 已提交
5063
  pMsg->compression = pCreateDb->compressionLevel;
H
hjxilinx 已提交
5064
  pMsg->walLevel = (char)pCreateDb->walLevel;
H
hjxilinx 已提交
5065
  pMsg->replications = pCreateDb->replica;
5066
  pMsg->quorum = pCreateDb->quorum;
5067
  pMsg->ignoreExist = pCreateDb->ignoreExists;
H
hjxilinx 已提交
5068 5069 5070
}

int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) {
5071
  SCMCreateDbMsg* pMsg = (SCMCreateDbMsg*)(pCmd->payload);
H
hjxilinx 已提交
5072
  setCreateDBOption(pMsg, pCreateDbSql);
H
hjxilinx 已提交
5073

H
hjxilinx 已提交
5074
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5075
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5076
  }
H
hjxilinx 已提交
5077

H
hjxilinx 已提交
5078
  if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5079
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5080
  }
H
hjxilinx 已提交
5081

H
hjxilinx 已提交
5082
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
5083
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5084
  }
H
hjxilinx 已提交
5085

5086
  return TSDB_CODE_SUCCESS;
H
huili 已提交
5087
}
S
slguan 已提交
5088

H
Haojun Liao 已提交
5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107
//void tscAddTimestampColumn(SQueryInfo* pQueryInfo, int16_t functionId, int16_t tableIndex) {
//  // the first column not timestamp column, add it
//  SSqlExpr* pExpr = NULL;
//  if (tscSqlExprNumOfExprs(pQueryInfo) > 0) {
//    pExpr = tscSqlExprGet(pQueryInfo, 0);
//  }
//
//  if (pExpr == NULL || pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX || pExpr->functionId != functionId) {
//    SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
//
//    pExpr = tscSqlExprInsert(pQueryInfo, 0, functionId, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE, false);
//    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);
//
//    insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, "ts", pExpr);
//  }
//}
S
slguan 已提交
5108

5109 5110
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
5111

5112 5113
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
H
hjxilinx 已提交
5114
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5115
  
S
TD-1057  
Shengliang Guan 已提交
5116
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1);
5117

S
slguan 已提交
5118
    if (pExpr->functionId != TSDB_FUNC_TAG) {
H
hjxilinx 已提交
5119
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
5120
      int16_t         columnInfo = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
5121
      SColumnIndex    index = {.tableIndex = 0, .columnIndex = columnInfo};
H
hjxilinx 已提交
5122
      SSchema*        pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5123 5124 5125 5126

      int16_t type = pSchema[index.columnIndex].type;
      int16_t bytes = pSchema[index.columnIndex].bytes;
      char*   name = pSchema[index.columnIndex].name;
H
hjxilinx 已提交
5127
  
5128
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
S
slguan 已提交
5129 5130 5131 5132
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
      SColumnList ids = {0};
S
TD-1057  
Shengliang Guan 已提交
5133
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5134 5135 5136

      int32_t relIndex = index.columnIndex;

5137
      pExpr->colInfo.colIndex = relIndex;
5138 5139
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
5140

5141
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
5142
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
5143 5144 5145 5146
    }
  }
}

H
hjxilinx 已提交
5147 5148 5149
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
5150
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
5151 5152 5153
  pExpr->numOfParams = 1;
}

5154
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
5155
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
H
hjxilinx 已提交
5156
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
5157

H
Haojun Liao 已提交
5158 5159 5160 5161
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

  SSchema*     pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->colIndex);
  SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pColIndex->colIndex};
H
hjxilinx 已提交
5162

S
TD-1057  
Shengliang Guan 已提交
5163
  tscAddSpecialColumnForSelect(pQueryInfo, (int32_t)size, TSDB_FUNC_PRJ, &colIndex, pSchema, TSDB_COL_NORMAL);
S
slguan 已提交
5164

S
TD-1057  
Shengliang Guan 已提交
5165
  SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, (int32_t)size);
H
Haojun Liao 已提交
5166
  doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
H
hjxilinx 已提交
5167
  pInfo->visible = false;
S
slguan 已提交
5168 5169
}

5170
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5171
  int32_t tagLength = 0;
H
hjxilinx 已提交
5172
  
H
hjxilinx 已提交
5173
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5174 5175
  
  for (int32_t i = 0; i < size; ++i) {
5176
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5177 5178 5179 5180 5181 5182 5183 5184 5185
    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 已提交
5186
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5187
  SSchema*        pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5188

H
hjxilinx 已提交
5189
  for (int32_t i = 0; i < size; ++i) {
5190
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5191
    if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) {
5192
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
S
TD-1057  
Shengliang Guan 已提交
5193
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64Key, &pExpr->resType,
5194
                        &pExpr->resBytes, &pExpr->interBytes, tagLength, true);
S
slguan 已提交
5195 5196 5197 5198
    }
  }
}

5199
static void doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5200
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5201 5202
  
  for (int32_t i = 0; i < size; ++i) {
5203
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5204 5205
    if (pExpr->functionId == TSDB_FUNC_PRJ) {
      bool qualifiedCol = false;
5206
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5207 5208 5209
        SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
  
        if (pExpr->colInfo.colId == pColIndex->colId) {
H
hjxilinx 已提交
5210
          qualifiedCol = true;
H
hjxilinx 已提交
5211
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5212 5213 5214 5215
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
5216

H
hjxilinx 已提交
5217 5218 5219 5220 5221
      assert(qualifiedCol);
    }
  }
}

S
slguan 已提交
5222 5223
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
5224 5225 5226
    SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j);
  
    if (columnId == pColIndex->colId && pColIndex->flag == TSDB_COL_TAG) {
S
slguan 已提交
5227 5228 5229 5230 5231 5232 5233
      return true;
    }
  }

  return false;
}

5234
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5235 5236
  bool hasTagPrj = false;
  bool hasColumnPrj = false;
H
hjxilinx 已提交
5237
  
H
hjxilinx 已提交
5238
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5239
  for (int32_t i = 0; i < size; ++i) {
5240
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251
    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
5252
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5253 5254
  bool allInGroupby = true;

H
hjxilinx 已提交
5255 5256
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5257
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5258 5259 5260 5261
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5262
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5263 5264 5265 5266 5267 5268 5269 5270 5271
      allInGroupby = false;
      break;
    }
  }

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

5272
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5273
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5274 5275
  
  for (int32_t i = 0; i < size; ++i) {
5276
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288
    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.
 */
5289
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) {
S
slguan 已提交
5290
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5291
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5292

S
slguan 已提交
5293 5294 5295 5296
  bool    tagColExists = false;
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5297
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5298
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5299
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5300 5301 5302 5303 5304 5305
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
      tagColExists = true;
      break;
    }
  }
H
hjxilinx 已提交
5306

H
hjxilinx 已提交
5307
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5308
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5309 5310
  
    int16_t functionId = pExpr->functionId;
5311
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5312
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5313
      continue;
S
slguan 已提交
5314
    }
H
hjxilinx 已提交
5315

H
hjxilinx 已提交
5316 5317 5318 5319 5320 5321
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5322

H
hjxilinx 已提交
5323
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5324 5325
    // 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.
5326
    if (numOfAggregation > 0) {
5327
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5328 5329 5330 5331 5332 5333
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5334 5335
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5336 5337 5338 5339 5340
    } 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 已提交
5341 5342
      for (int32_t i = 0; i < numOfExprs; ++i) {
        
5343
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5344 5345 5346 5347 5348
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5349
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5350 5351 5352
        }
      }

5353 5354
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5355 5356
    }
  } else {
5357
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5358
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5359
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5360
      }
H
hjxilinx 已提交
5361

H
hjxilinx 已提交
5362 5363
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5364 5365
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5366
      }
S
slguan 已提交
5367 5368 5369 5370 5371 5372
    }
  }

  return TSDB_CODE_SUCCESS;
}

5373
static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5374 5375
  const char* msg2 = "interval not allowed in group by normal column";

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

H
Haojun Liao 已提交
5378
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5379
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5380 5381 5382 5383
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5384
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5385
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5386
    int16_t colIndex = pColIndex->colIndex;
5387
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5388
      type  = s.type;
H
Haojun Liao 已提交
5389
      bytes = s.bytes;
H
Haojun Liao 已提交
5390
      name  = s.name;
S
slguan 已提交
5391
    } else {
5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402
      if (TSDB_COL_IS_TAG(pColIndex->flag)) {
        SSchema* tagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
        
        type  = tagSchema[colIndex].type;
        bytes = tagSchema[colIndex].bytes;
        name  = tagSchema[colIndex].name;
      } else {
        type  = pSchema[colIndex].type;
        bytes = pSchema[colIndex].bytes;
        name  = pSchema[colIndex].name;
      }
S
slguan 已提交
5403
    }
H
hjxilinx 已提交
5404 5405 5406
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5407
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5408
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5409
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5410
      
B
Bomin Zhang 已提交
5411 5412
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5413
      
S
slguan 已提交
5414 5415 5416
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5417
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
S
TD-1057  
Shengliang Guan 已提交
5418
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5419 5420
    } else {
      // if this query is "group by" normal column, interval is not allowed
5421
      if (pQueryInfo->intervalTime > 0) {
5422
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5423 5424 5425
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5426
      for (int32_t j = 0; j < size; ++j) {
5427
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5428 5429 5430 5431 5432 5433 5434 5435 5436 5437
        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) {
5438
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5439 5440 5441 5442 5443 5444 5445
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5446
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5447
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5448
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5449
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5450
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5451 5452

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5453
  if (tscQueryTags(pQueryInfo)) {
5454
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5455
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5456 5457 5458 5459 5460
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5461
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5462
    // check if all the tags prj columns belongs to the group by columns
5463 5464
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5465
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5466 5467 5468
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5469 5470
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5471
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5472 5473 5474 5475 5476 5477
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5478
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5479
        bool qualified = false;
5480
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5481
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5482 5483 5484 5485 5486 5487 5488
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5489
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5490 5491 5492 5493
        }
      }

      if (IS_MULTIOUTPUT(aAggs[functId].nStatus) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM &&
H
hjxilinx 已提交
5494
          functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) {
5495
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5496 5497
      }

5498
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5499
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5500 5501 5502
      }
    }

5503
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5504
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5505 5506 5507 5508 5509 5510
    }

    /*
     * group by tag function must be not changed the function name, otherwise, the group operation may fail to
     * divide the subset of final result.
     */
5511
    if (doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5512
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5513 5514
    }

H
hjxilinx 已提交
5515
    // projection query on super table does not compatible with "group by" syntax
5516
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5517
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5518
    }
H
hjxilinx 已提交
5519

H
hjxilinx 已提交
5520
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5521
  } else {
5522
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5523 5524
  }
}
H
hjxilinx 已提交
5525

5526
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5527 5528 5529
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5530

H
hjxilinx 已提交
5531 5532
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5533
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5534
  }
H
hjxilinx 已提交
5535

H
hjxilinx 已提交
5536 5537
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5538
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hjxilinx 已提交
5539
  }
H
hjxilinx 已提交
5540

H
hjxilinx 已提交
5541
  // TODO redefine the function
H
hjxilinx 已提交
5542 5543 5544 5545 5546 5547
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5548
  int32_t index = -1;
H
hjxilinx 已提交
5549
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5550
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5551
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5552 5553 5554 5555
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5556 5557 5558

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5559
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5560
    case 1:
H
Haojun Liao 已提交
5561 5562 5563
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5564
    case 3:
H
Haojun Liao 已提交
5565
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5566
    case 4:
H
Haojun Liao 已提交
5567
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5568
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5569
  }
5570 5571 5572 5573 5574 5575
  
  SColumnIndex ind = {0};
  SSqlExpr* pExpr1 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT,
                                      tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize, false);
  
  const char* name = (pExprList->a[0].aliasName != NULL)? pExprList->a[0].aliasName:functionsInfo[index].name;
B
Bomin Zhang 已提交
5576
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5577 5578
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5579
}
H
hjxilinx 已提交
5580 5581

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

H
hjxilinx 已提交
5585 5586
  if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) {
    snprintf(msg, tListLen(msg), "invalid db option walLevel: %d, only 0-2 allowed", pCreate->walLevel);
5587
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5588
  }
H
hjxilinx 已提交
5589

H
hjxilinx 已提交
5590
  if (pCreate->replications != -1 &&
5591
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5592
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5593
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5594
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5595
  }
H
hjxilinx 已提交
5596

5597 5598 5599 5600 5601 5602 5603
  if (pCreate->quorum != -1 &&
      (pCreate->quorum < TSDB_MIN_DB_REPLICA_OPTION || pCreate->quorum > TSDB_MAX_DB_REPLICA_OPTION)) {
    snprintf(msg, tListLen(msg), "invalid db option quorum: %d valid range: [%d, %d]", pCreate->quorum,
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  }

H
hjxilinx 已提交
5604
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5605
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5606
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5607
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5608
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5609
  }
H
hjxilinx 已提交
5610

H
hjxilinx 已提交
5611 5612 5613 5614
  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);
5615
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5616
  }
H
hjxilinx 已提交
5617

H
hjxilinx 已提交
5618
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5619
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5620
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5621
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5622
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5623
  }
H
hjxilinx 已提交
5624 5625 5626 5627

  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);
5628
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5629
  }
H
hjxilinx 已提交
5630

H
hjxilinx 已提交
5631
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5632
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5633
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5634
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5635
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5636
  }
H
hjxilinx 已提交
5637

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5638 5639 5640 5641 5642 5643 5644
  val = htonl(pCreate->fsyncPeriod);
  if (val != -1 && (val < TSDB_MIN_FSYNC_PERIOD || val > TSDB_MAX_FSYNC_PERIOD)) {
    snprintf(msg, tListLen(msg), "invalid db option fsyncPeriod: %d valid range: [%d, %d]", val,
             TSDB_MIN_FSYNC_PERIOD, TSDB_MAX_FSYNC_PERIOD);
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  }

H
hjxilinx 已提交
5645
  if (pCreate->compression != -1 &&
S
slguan 已提交
5646
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5647
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5648
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5649
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5650
  }
H
hjxilinx 已提交
5651

H
hjxilinx 已提交
5652 5653
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5654 5655

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

S
TD-1057  
Shengliang Guan 已提交
5659
  int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
5660
  if (size == 0) {
H
hjxilinx 已提交
5661 5662
    return;
  }
H
hjxilinx 已提交
5663

H
hjxilinx 已提交
5664
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5665 5666

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

H
hjxilinx 已提交
5669 5670
  offset += sprintf(str, "num:%d [", size);
  for (int32_t i = 0; i < size; ++i) {
5671
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5672

L
lihui 已提交
5673
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5674 5675 5676
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5677 5678 5679
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
5681
    if (i < size - 1) {
H
hjxilinx 已提交
5682 5683 5684
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5685

H
hjxilinx 已提交
5686
  str[offset] = ']';
5687
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5688
}
5689

5690
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5691 5692 5693
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5694 5695
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5696
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5697 5698 5699 5700 5701 5702 5703 5704 5705

  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
H
Haojun Liao 已提交
5706
  SStrToken* pzTableName = &(pCreateTable->name);
5707 5708

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5709
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5710 5711
  }

H
Haojun Liao 已提交
5712
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5713
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5714 5715 5716 5717
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
5718
    return TSDB_CODE_TSC_INVALID_SQL;
5719 5720 5721 5722
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
H
hjxilinx 已提交
5723
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[col]);
5724 5725 5726 5727
  }

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

H
hjxilinx 已提交
5728
  if (pTagList != NULL) {  // create super table[optional]
5729
    for (int32_t i = 0; i < pTagList->nField; ++i) {
H
hjxilinx 已提交
5730
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pTagList->p[i]);
5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747
    }

    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;
5748 5749 5750
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
5751 5752 5753
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
5754 5755 5756 5757

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

H
hjxilinx 已提交
5758
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5759 5760

  // super table name, create table by using dst
H
Haojun Liao 已提交
5761
  SStrToken* pToken = &(pCreateTable->usingInfo.stableName);
5762 5763

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5764
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5765 5766
  }

H
Haojun Liao 已提交
5767
  if (tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5768
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5769 5770 5771
  }

  // get meter meta from mnode
B
Bomin Zhang 已提交
5772
  tstrncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, sizeof(pCreateTable->usingInfo.tagdata.name));
5773 5774
  tVariantList* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;

H
hjxilinx 已提交
5775
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5776 5777 5778 5779
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5780
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5781
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5782 5783 5784
  }

  // too long tag values will return invalid sql, not be truncated automatically
H
hjxilinx 已提交
5785
  SSchema* pTagSchema = tscGetTableTagSchema(pStableMeterMetaInfo->pTableMeta);
5786

5787
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
B
Bomin Zhang 已提交
5788 5789 5790 5791 5792
  SKVRowBuilder kvRowBuilder = {0};
  if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
hjxilinx 已提交
5793
  int32_t ret = TSDB_CODE_SUCCESS;
5794
  for (int32_t i = 0; i < pList->nExpr; ++i) {
B
Bomin Zhang 已提交
5795 5796
    SSchema* pSchema = pTagSchema + i;
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
H
hjxilinx 已提交
5797
      // validate the length of binary
B
Bomin Zhang 已提交
5798
      if (pList->a[i].pVar.nLen + VARSTR_HEADER_SIZE > pSchema->bytes) {
B
Bomin Zhang 已提交
5799
        tdDestroyKVRowBuilder(&kvRowBuilder);
H
hjxilinx 已提交
5800 5801 5802 5803
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
    
B
Bomin Zhang 已提交
5804 5805
    char tagVal[TSDB_MAX_TAGS_LEN];
    ret = tVariantDump(&(pList->a[i].pVar), tagVal, pSchema->type, true);
5806
    if (ret != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
5807
      tdDestroyKVRowBuilder(&kvRowBuilder);
5808
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5809 5810
    }

B
Bomin Zhang 已提交
5811
    tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
5812 5813
  }

B
Bomin Zhang 已提交
5814
  SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
B
Bomin Zhang 已提交
5815 5816 5817 5818 5819
  tdDestroyKVRowBuilder(&kvRowBuilder);
  if (row == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  tdSortKVRowByColIdx(row);
B
Bomin Zhang 已提交
5820
  pTag->dataLen = kvRowLen(row);
B
Bomin Zhang 已提交
5821
  kvRowCpy(pTag->data, row);
B
Bomin Zhang 已提交
5822 5823
  free(row);

5824 5825
  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5826
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5827 5828
  }

H
hjxilinx 已提交
5829
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
5830
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843
  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
H
Haojun Liao 已提交
5844 5845
  const char* msg6 = "from missing in subclause";
  
5846
  SSqlCmd*    pCmd = &pSql->cmd;
5847
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5848 5849
  assert(pQueryInfo->numOfTables == 1);

5850
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5851
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5852 5853

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
5854
  SStrToken* pzTableName = &(pCreateTable->name);
5855 5856 5857
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5858
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5859
  }
H
Haojun Liao 已提交
5860
  
5861
  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
H
Haojun Liao 已提交
5862 5863 5864 5865 5866
  if (pSrcMeterName == NULL || pSrcMeterName->nExpr == 0) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
  tVariant* pVar = &pSrcMeterName->a[0].pVar;
H
Haojun Liao 已提交
5867
  SStrToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
5868
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
5869
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5870 5871
  }

H
Haojun Liao 已提交
5872
  if (tscSetTableFullName(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5873
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5874 5875
  }

H
hjxilinx 已提交
5876
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5877 5878 5879 5880
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
5881
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
5882
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5883
    return TSDB_CODE_TSC_INVALID_SQL;
5884 5885 5886
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5887
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5888
      return TSDB_CODE_TSC_INVALID_SQL;
5889 5890 5891 5892
    }
  }

  // set interval value
5893
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5894
    return TSDB_CODE_TSC_INVALID_SQL;
5895
  } else {
5896
    if ((pQueryInfo->intervalTime > 0) &&
5897
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
5898
      return TSDB_CODE_TSC_INVALID_SQL;
5899 5900 5901 5902
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
5903
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5904
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5905 5906 5907
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5908
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5909 5910
  }

5911
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5912
    return TSDB_CODE_TSC_INVALID_SQL;
5913 5914
  }

H
hjxilinx 已提交
5915
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5916

5917
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5918
    return TSDB_CODE_TSC_INVALID_SQL;
5919 5920 5921 5922 5923 5924 5925
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
5926
    if (pQueryInfo->intervalTime == 0) {
5927
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
5928 5929 5930 5931 5932 5933
    }

    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))) {
5934
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5935 5936 5937 5938 5939
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
5940
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5941 5942 5943 5944 5945 5946
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
  assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0));

H
Haojun Liao 已提交
5947 5948 5949 5950 5951 5952 5953 5954 5955 5956
  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";
  const char* msg10 = "too many tables in from clause";
  const char* msg11 = "invalid table alias name";
5957 5958

  int32_t code = TSDB_CODE_SUCCESS;
5959

5960
  SSqlCmd* pCmd = &pSql->cmd;
5961

5962
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
5963
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5964
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
5965
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
5966
  }
H
hjxilinx 已提交
5967

H
Haojun Liao 已提交
5968 5969
  assert(pCmd->clauseIndex == index);

5970 5971
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
5972
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984
  }

  /*
   * 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);
5985
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
5986 5987
  }

H
Haojun Liao 已提交
5988
  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM * 2) {
5989
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
5990 5991
  }

5992
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
5993

H
Haojun Liao 已提交
5994
  if (pQuerySql->from->nExpr > 4) {
H
Haojun Liao 已提交
5995 5996 5997
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

5998
  // set all query tables, which are maybe more than one.
H
Haojun Liao 已提交
5999
  for (int32_t i = 0; i < pQuerySql->from->nExpr; ) {
6000 6001 6002
    tVariant* pTableItem = &pQuerySql->from->a[i].pVar;

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
6003
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6004 6005 6006 6007
    }

    pTableItem->nLen = strdequote(pTableItem->pz);

H
Haojun Liao 已提交
6008
    SStrToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
6009
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
6010
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6011 6012
    }

H
Haojun Liao 已提交
6013
    if (pQueryInfo->numOfTables <= i/2) {  // more than one table
H
hjxilinx 已提交
6014
      tscAddEmptyMetaInfo(pQueryInfo);
6015 6016
    }

H
Haojun Liao 已提交
6017
    STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i/2);
6018

H
Haojun Liao 已提交
6019
    SStrToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
6020
    if (tscSetTableFullName(pTableMetaInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
6021
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6022 6023
    }

H
Haojun Liao 已提交
6024
    tVariant* pTableItem1 = &pQuerySql->from->a[i + 1].pVar;
H
Haojun Liao 已提交
6025
    SStrToken aliasName = {.z = pTableItem1->pz, .n = pTableItem1->nLen, .type = TK_STRING};
H
Haojun Liao 已提交
6026 6027 6028 6029
    if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

6030 6031 6032 6033 6034 6035
    // has no table alias name
    if (memcmp(pTableItem->pz, pTableItem1->pz, pTableItem1->nLen) == 0) {
      extractTableName(pTableMetaInfo1->name, pTableMetaInfo1->aliasName);
    } else {
      tstrncpy(pTableMetaInfo1->aliasName, pTableItem1->pz, sizeof(pTableMetaInfo1->aliasName));
    }
H
Haojun Liao 已提交
6036 6037

    code = tscGetTableMeta(pSql, pTableMetaInfo1);
6038 6039 6040
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
H
Haojun Liao 已提交
6041 6042

    i += 2;
6043 6044
  }

H
Haojun Liao 已提交
6045
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr / 2);
H
hjxilinx 已提交
6046
  bool isSTable = false;
H
hjxilinx 已提交
6047
  
weixin_48148422's avatar
weixin_48148422 已提交
6048
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
6049 6050 6051 6052 6053 6054 6055
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
6056 6057
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
6058
  }
6059

6060
  // parse the group by clause in the first place
6061
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
6062
    return TSDB_CODE_TSC_INVALID_SQL;
6063 6064
  }

6065
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
6066
    return TSDB_CODE_TSC_INVALID_SQL;
6067 6068 6069
  }

  // set interval value
6070
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6071
    return TSDB_CODE_TSC_INVALID_SQL;
6072
  } else {
6073
    if ((pQueryInfo->intervalTime > 0) &&
6074
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6075
      return TSDB_CODE_TSC_INVALID_SQL;
6076 6077 6078 6079
    }
  }

  // set order by info
6080
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
6081
    return TSDB_CODE_TSC_INVALID_SQL;
6082 6083 6084
  }

  // set where info
H
hjxilinx 已提交
6085
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
6086
  
6087
  if (pQuerySql->pWhere != NULL) {
6088
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
6089
      return TSDB_CODE_TSC_INVALID_SQL;
6090 6091 6092
    }

    pQuerySql->pWhere = NULL;
H
hjxilinx 已提交
6093
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
6094 6095
      pQueryInfo->window.skey = pQueryInfo->window.skey / 1000;
      pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000;
6096 6097
    }
  } else {  // set the time rang
H
Haojun Liao 已提交
6098
    pQueryInfo->window = TSWINDOW_INITIALIZER;
6099 6100 6101
  }

  // user does not specified the query time window, twa is not allowed in such case.
H
Haojun Liao 已提交
6102
  if ((pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX ||
H
hjxilinx 已提交
6103
       (pQueryInfo->window.ekey == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
6104
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
6105 6106 6107
  }

  // no result due to invalid query time range
H
hjxilinx 已提交
6108
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6109
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6110 6111 6112
    return TSDB_CODE_SUCCESS;
  }

6113
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6114
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6115 6116 6117
  }

  // in case of join query, time range is required.
6118
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
S
TD-1057  
Shengliang Guan 已提交
6119
    int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6120

H
hjxilinx 已提交
6121
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6122
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6123 6124 6125
    }
  }

6126
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6127 6128 6129
    return code;
  }

6130
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6131 6132 6133
    return code;
  }

6134
  setColumnOffsetValueInResultset(pQueryInfo);
6135

6136 6137 6138 6139 6140
  /*
   * 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) {
6141
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6142 6143
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6144

6145
    if (pQueryInfo->intervalTime > 0) {
S
TD-1057  
Shengliang Guan 已提交
6146
      int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6147
      // number of result is not greater than 10,000,000
6148
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_INTERVAL_TIME_WINDOW) {
6149
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6150 6151
      }
    }
H
hjxilinx 已提交
6152

6153
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6154 6155 6156 6157
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6158 6159 6160

  return TSDB_CODE_SUCCESS;  // Does not build query message here
}
H
hjxilinx 已提交
6161

6162
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols) {
H
hjxilinx 已提交
6163 6164
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6165
  
6166
  if (pSqlExpr->pLeft != NULL) {
6167
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6168 6169 6170 6171 6172
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6173
  if (pSqlExpr->pRight != NULL) {
6174
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6175 6176 6177 6178 6179
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6180
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6181
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6182
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6183
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6184 6185 6186
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6187
      return TSDB_CODE_SUCCESS;
6188
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6189
      // arithmetic expression on the results of aggregation functions
6190
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6191
      (*pExpr)->nodeType = TSQL_NODE_COL;
6192 6193 6194
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6195
      // set the input column data byte and type.
H
hjxilinx 已提交
6196 6197 6198 6199 6200 6201
      size_t size = taosArrayGetSize(pExprInfo);
      
      for (int32_t i = 0; i < size; ++i) {
        SSqlExpr* p1 = taosArrayGetP(pExprInfo, i);
        
        if (strcmp((*pExpr)->pSchema->name, p1->aliasName) == 0) {
S
TD-1057  
Shengliang Guan 已提交
6202
          (*pExpr)->pSchema->type = (uint8_t)p1->resType;
H
hjxilinx 已提交
6203
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
hjxilinx 已提交
6204 6205 6206
          break;
        }
      }
6207
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6208
      SColumnIndex index = {0};
6209
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6210 6211 6212
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
H
Haojun Liao 已提交
6213 6214 6215 6216

      STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
      int32_t numOfColumns = tscGetNumOfColumns(pTableMeta);

6217 6218 6219
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
H
Haojun Liao 已提交
6220

6221 6222
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6223 6224 6225
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6226
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6227 6228
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
H
Haojun Liao 已提交
6229 6230
        colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;

6231 6232
        taosArrayPush(pCols, &colIndex);
      }
6233
      
H
hjxilinx 已提交
6234
      return TSDB_CODE_SUCCESS;
6235
    } else {
6236
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6237 6238 6239
    }
    
  } else {
H
hjxilinx 已提交
6240
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6241 6242
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6243 6244 6245
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6246
    
H
Haojun Liao 已提交
6247
    SStrToken t = {.type = pSqlExpr->nSQLOptr};
H
[td-32]  
hjxilinx 已提交
6248
    (*pExpr)->_node.optr = getBinaryExprOptr(&t);
6249
    
H
[td-32]  
hjxilinx 已提交
6250
    assert((*pExpr)->_node.optr != 0);
H
hjxilinx 已提交
6251
    
H
[td-32]  
hjxilinx 已提交
6252
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6253 6254
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6255
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6256
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6257
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6258 6259 6260
        }
      }
    }
H
Hui Li 已提交
6261

6262
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6263 6264
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
      if (pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6265 6266 6267
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6268 6269
      }
    }
H
hjxilinx 已提交
6270 6271 6272
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6273
}