tscSQLParser.c 212.2 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 32
#include "tstoken.h"
#include "tstrbuild.h"
#include "ttime.h"
33
#include "ttokendef.h"
H
hjxilinx 已提交
34

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

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

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

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

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

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

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

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

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

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

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

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

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

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

87
static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
H
hzcheng 已提交
88
static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
89
static int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
S
slguan 已提交
90
static int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString);
91 92
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 已提交
93
static int32_t validateEp(char* ep);
H
hzcheng 已提交
94
static int32_t validateDNodeConfig(tDCLSQL* pOptions);
S
slguan 已提交
95
static int32_t validateLocalConfig(tDCLSQL* pOptions);
H
hzcheng 已提交
96
static int32_t validateColumnName(char* name);
97
static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType);
S
slguan 已提交
98

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

155 156 157 158 159 160
static int32_t handlePassword(SSqlCmd* pCmd, SSQLToken* pPwd) {
  const char* msg1 = "password can not be empty";
  const char* msg2 = "name or password too long";
  const char* msg3 = "password needs single quote marks enclosed";

  if (pPwd->type != TK_STRING) {
161
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
162 163 164
  }

  strdequote(pPwd->z);
H
Haojun Liao 已提交
165
  pPwd->n = strtrim(pPwd->z);  // trim space before and after passwords
166 167

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

240 241
      break;
    }
H
hzcheng 已提交
242

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

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

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

      break;
    }

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

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

268 269 270 271 272 273 274 275
      break;
    }

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

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

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

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

      break;
    }

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

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

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

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

311 312
      SSQLToken* pName = &pInfo->pDCLInfo->user.user;
      SSQLToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
313

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

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

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

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

H
hzcheng 已提交
337 338 339
      break;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

390 391
      break;
    }
H
hzcheng 已提交
392

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

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

403 404 405
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
      SSQLToken* pName = &pUser->user;
      SSQLToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
406

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

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

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

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

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

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

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

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

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

      break;
    }

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

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

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

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

      break;
    }

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

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

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

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

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

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

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

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

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

      break;
    }

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

      break;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

H
Haojun Liao 已提交
648 649
  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));
650

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

740 741
  tfree(oldName);
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
742 743 744 745 746
}

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

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

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

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

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

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

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

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

  return true;
}

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

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

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

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

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

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

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

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

  return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  return true;
}

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

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

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

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

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

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

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

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

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

  return true;
}

/* is contained in pFieldList or not */
H
hjxilinx 已提交
1020
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name) {
H
hzcheng 已提交
1021
  for (int32_t j = startIdx; j < pFieldList->nField; ++j) {
B
Bomin Zhang 已提交
1022 1023
    TAOS_FIELD* field = pFieldList->p + j;
    if (strncasecmp(name, field->name, sizeof(field->name) - 1) == 0) return true;
H
hzcheng 已提交
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
  }

  return false;
}

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

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

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

  return false;
}

1047
int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQLToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
  int32_t totalLen = 0;

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

  /* db name is not specified, the tableName dose not include db name */
  if (pDB != NULL) {
B
Bomin Zhang 已提交
1059
    if (pDB->n >= TSDB_ACCT_LEN + TSDB_DB_NAME_LEN) {
1060
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
    }

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

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

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

S
slguan 已提交
1091
  if (totalLen < TSDB_TABLE_ID_LEN) {
S
slguan 已提交
1092 1093 1094
    fullName[totalLen] = 0;
  }

B
Bomin Zhang 已提交
1095
  return (totalLen < TSDB_TABLE_ID_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1096 1097
}

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

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

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

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

1119
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
1120 1121 1122 1123 1124
  
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
H
hzcheng 已提交
1125
  for (int32_t i = 0; i < pSelection->nExpr; ++i) {
H
hjxilinx 已提交
1126
    int32_t outputIndex = tscSqlExprNumOfExprs(pQueryInfo);
H
hzcheng 已提交
1127 1128
    tSQLExprItem* pItem = &pSelection->a[i];

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

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

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

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

1155 1156
      if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1157
      }
1158 1159
      
      int32_t tableIndex = columnList.ids[0].tableIndex;
H
hzcheng 已提交
1160 1161
      char  arithmeticExprStr[1024] = {0};
      char* p = arithmeticExprStr;
H
hjxilinx 已提交
1162 1163 1164 1165 1166 1167 1168
      
      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) {
1169
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hjxilinx 已提交
1170 1171 1172 1173
          }
        }
  
        if (buildArithmeticExprString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
1174
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
1175 1176 1177 1178
        }
  
        // expr string is set as the parameter of function
        SColumnIndex index = {.tableIndex = tableIndex};
H
hjxilinx 已提交
1179
        SSqlExpr*    pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE,
1180
                                              sizeof(double), sizeof(double), false);
1181
        
H
hjxilinx 已提交
1182 1183
        /* todo alias name should use the original sql string */
        char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
B
Bomin Zhang 已提交
1184
        tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
1185 1186 1187 1188
        
        tExprNode* pNode = NULL;
        SArray* colList = taosArrayInit(10, sizeof(SColIndex));
        
1189
        int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
1190 1191
        if (ret != TSDB_CODE_SUCCESS) {
          tExprTreeDestroy(&pNode, NULL);
1192
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid arithmetic expression in select clause");
1193 1194
        }
        
1195 1196 1197 1198 1199 1200 1201 1202 1203
        SBufferWriter bw = tbufInitWriter(NULL, false);

        TRY(0) {
          exprTreeToBinary(&bw, pNode);
        } CATCH(code) {
          tbufCloseWriter(&bw);
          UNUSED(code);
          // TODO: other error handling
        } END_TRY
1204
        
1205 1206
        size_t len = tbufTell(&bw);
        char* c = tbufGetData(&bw, true);
1207 1208 1209 1210
        
        // set the serialized binary string as the parameter of arithmetic expression
        addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, len, index.tableIndex);
        
H
hjxilinx 已提交
1211
        insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
1212 1213 1214
        
        taosArrayDestroy(colList);
        tExprTreeDestroy(&pNode, NULL);
H
hzcheng 已提交
1215
      } else {
H
hjxilinx 已提交
1216 1217 1218
        columnList.num = 0;
        columnList.ids[0] = (SColumnIndex) {0, 0};
        
1219
        insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, "dummy_column", NULL);
H
hjxilinx 已提交
1220 1221
        
        int32_t slot = tscNumOfFields(pQueryInfo) - 1;
H
hjxilinx 已提交
1222
        SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);
H
hjxilinx 已提交
1223
        
H
hjxilinx 已提交
1224
        if (pInfo->pSqlExpr == NULL) {
1225
          SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));
H
hjxilinx 已提交
1226 1227
          
          // arithmetic expression always return result in the format of double float
1228 1229 1230
          pArithExprInfo->bytes = sizeof(double);
          pArithExprInfo->interBytes = sizeof(double);
          pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;
H
hjxilinx 已提交
1231

1232
          int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
H
hjxilinx 已提交
1233
          if (ret != TSDB_CODE_SUCCESS) {
1234
            tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
1235
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
H
hjxilinx 已提交
1236
          }
1237
  
1238
          pInfo->pArithExprInfo = pArithExprInfo;
H
hjxilinx 已提交
1239
        }
H
hzcheng 已提交
1240 1241 1242 1243 1244 1245
      }
    } else {
      /*
       * not support such expression
       * e.g., select 12+5 from table_name
       */
1246
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1247 1248
    }

H
hjxilinx 已提交
1249
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1250
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1251 1252 1253
    }
  }

1254
  if (!functionCompatibleCheck(pQueryInfo)) {
1255
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1256 1257
  }

H
Haojun Liao 已提交
1258 1259 1260 1261
  /*
   * transfer sql functions that need secondary merge into another format
   * in dealing with metric queries such as: count/first/last
   */
1262
  if (isSTable) {
H
hjxilinx 已提交
1263
    tscTansformSQLFuncForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1264

1265
    if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
1266
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1267 1268 1269 1270 1271 1272
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1273 1274
int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
    int8_t type, char* fieldName, SSqlExpr* pSqlExpr) {
1275
  
S
slguan 已提交
1276
  for (int32_t i = 0; i < pIdList->num; ++i) {
1277 1278 1279 1280 1281 1282 1283 1284
    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;
    }
    
1285
    tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i]));
H
hzcheng 已提交
1286
  }
H
hjxilinx 已提交
1287 1288
  
  TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
H
Haojun Liao 已提交
1289
  SFieldSupInfo* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
H
hjxilinx 已提交
1290
  pInfo->pSqlExpr = pSqlExpr;
H
hjxilinx 已提交
1291
  
H
hzcheng 已提交
1292 1293 1294
  return TSDB_CODE_SUCCESS;
}

1295
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1296
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1297 1298 1299
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
1300
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
H
hzcheng 已提交
1301

1302
  int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
1303 1304 1305 1306
  SColumnIndex index = {.tableIndex = tableIndex,};
  
  if (functionId == TSDB_FUNC_TAGPRJ) {
    index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta);
H
hjxilinx 已提交
1307 1308
  
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
1309 1310 1311 1312 1313 1314
  } else {
    index.columnIndex = colIndex;
  }
  
  return tscSqlExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes,
      pSchema->bytes, functionId == TSDB_FUNC_TAGPRJ);
H
hzcheng 已提交
1315 1316
}

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

H
hjxilinx 已提交
1320
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
H
hjxilinx 已提交
1321 1322 1323
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
1324

S
slguan 已提交
1325
  char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName;
B
Bomin Zhang 已提交
1326
  tstrncpy(pExpr->aliasName, colName, sizeof(pExpr->aliasName));
H
hjxilinx 已提交
1327
  
S
slguan 已提交
1328 1329 1330
  SColumnList ids = {0};
  ids.num = 1;
  ids.ids[0] = *pIndex;
H
hzcheng 已提交
1331

H
hjxilinx 已提交
1332
  if (pIndex->columnIndex >= tscGetNumOfColumns(pTableMeta) || pIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1333 1334
    ids.num = 0;
  }
H
hzcheng 已提交
1335

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

1339
void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1340
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
H
Haojun Liao 已提交
1341
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
1342
                                     pColSchema->bytes, pColSchema->bytes, flag);
H
Haojun Liao 已提交
1343
  tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName));
H
hzcheng 已提交
1344

S
slguan 已提交
1345 1346 1347 1348
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1349

H
hjxilinx 已提交
1350
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1351 1352

  pExpr->colInfo.flag = flag;
1353 1354
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  
S
slguan 已提交
1355
  if (TSDB_COL_IS_TAG(flag)) {
H
hjxilinx 已提交
1356
    tscColumnListInsert(pTableMetaInfo->tagColList, pIndex);
S
slguan 已提交
1357 1358 1359
  }
}

1360
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1361
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1362 1363

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1364 1365
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1366

H
hjxilinx 已提交
1367
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1368
  
weixin_48148422's avatar
weixin_48148422 已提交
1369
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1370
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1371
  } else {
H
hjxilinx 已提交
1372
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1373 1374 1375
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
hjxilinx 已提交
1376
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex);
B
Bomin Zhang 已提交
1377
    tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName));
S
slguan 已提交
1378 1379 1380 1381

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

H
hjxilinx 已提交
1384
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1385 1386 1387 1388 1389
  }

  return numOfTotalColumns;
}

H
Haojun Liao 已提交
1390 1391 1392 1393 1394
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tscColumnListInsert(pQueryInfo->colList, &tsCol);
}

1395
int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExprItem* pItem) {
S
slguan 已提交
1396
  const char* msg0 = "invalid column name";
H
hjxilinx 已提交
1397
  const char* msg1 = "tag for normal table query is not allowed";
H
hjxilinx 已提交
1398 1399
  
  int32_t startPos = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
1400 1401 1402

  if (pItem->pNode->nSQLOptr == TK_ALL) {  // project on all fields
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1403
    if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1404
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
1405 1406 1407 1408
    }

    // all meters columns are required
    if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) {  // all table columns are required.
1409
      for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
S
slguan 已提交
1410
        index.tableIndex = i;
1411
        int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1412
        startPos += inc;
H
hzcheng 已提交
1413 1414
      }
    } else {
1415
      doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1416 1417 1418 1419
    }
  } else if (pItem->pNode->nSQLOptr == TK_ID) {  // simple column projection query
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;

1420 1421
    if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
1422
    }
H
hzcheng 已提交
1423

S
slguan 已提交
1424
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
1425
      SSchema colSchema = tGetTableNameColumnSchema();
H
Haojun Liao 已提交
1426
      tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG);
S
slguan 已提交
1427
    } else {
H
hjxilinx 已提交
1428
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1429
      STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
1430

weixin_48148422's avatar
weixin_48148422 已提交
1431
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
1432
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1433 1434
      }

1435
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
hzcheng 已提交
1436
    }
H
Haojun Liao 已提交
1437 1438

    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
hzcheng 已提交
1439
  } else {
1440
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1441 1442 1443 1444 1445
  }

  return TSDB_CODE_SUCCESS;
}

1446
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, int32_t functionID, char* aliasName,
S
slguan 已提交
1447
                                       int32_t resColIdx, SColumnIndex* pColIndex) {
H
hzcheng 已提交
1448 1449 1450
  int16_t type = 0;
  int16_t bytes = 0;

S
slguan 已提交
1451
  char        columnName[TSDB_COL_NAME_LEN] = {0};
1452
  const char* msg1 = "not support column types";
H
hzcheng 已提交
1453 1454

  if (functionID == TSDB_FUNC_SPREAD) {
S
slguan 已提交
1455 1456 1457
    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) {
1458
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1459 1460 1461 1462 1463 1464
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
S
slguan 已提交
1465 1466
    type = pSchema[pColIndex->columnIndex].type;
    bytes = pSchema[pColIndex->columnIndex].bytes;
H
hzcheng 已提交
1467 1468 1469
  }

  if (aliasName != NULL) {
B
Bomin Zhang 已提交
1470
    tstrncpy(columnName, aliasName, sizeof(columnName));
H
hzcheng 已提交
1471
  } else {
B
Bomin Zhang 已提交
1472
    getRevisedName(columnName, functionID, sizeof(columnName) - 1, pSchema[pColIndex->columnIndex].name);
H
hzcheng 已提交
1473
  }
H
hjxilinx 已提交
1474
  
1475
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, bytes, false);
B
Bomin Zhang 已提交
1476
  tstrncpy(pExpr->aliasName, columnName, sizeof(pExpr->aliasName));
1477 1478 1479 1480 1481 1482 1483

  // 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 已提交
1484
  
H
hjxilinx 已提交
1485
  // for all queries, the timestamp column needs to be loaded
S
slguan 已提交
1486
  SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1487
  tscColumnListInsert(pQueryInfo->colList, &index);
H
hzcheng 已提交
1488

S
slguan 已提交
1489
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
H
hjxilinx 已提交
1490
  insertResultField(pQueryInfo, resColIdx, &ids, bytes, type, columnName, pExpr);
H
hzcheng 已提交
1491 1492 1493 1494

  return TSDB_CODE_SUCCESS;
}

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

1499
  const char* msg1 = "not support column types";
S
slguan 已提交
1500
  const char* msg2 = "invalid parameters";
1501
  const char* msg3 = "illegal column name";
S
slguan 已提交
1502
  const char* msg4 = "invalid table name";
1503
  const char* msg5 = "parameter is out of range [0, 100]";
S
slguan 已提交
1504
  const char* msg6 = "function applied to tags not allowed";
1505
  const char* msg7 = "normal table can not apply this function";
H
Haojun Liao 已提交
1506
  const char* msg8 = "multi-columns selection does not support alias column name";
B
Bomin Zhang 已提交
1507
  const char* msg9 = "invalid function";
H
Haojun Liao 已提交
1508

H
hzcheng 已提交
1509 1510 1511
  switch (optr) {
    case TK_COUNT: {
        /* more than one parameter for count() function */
H
Haojun Liao 已提交
1512
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
1513
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1514 1515 1516 1517
      }

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1518
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1519 1520
      }

H
hjxilinx 已提交
1521
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1522
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1523 1524 1525 1526

      if (pItem->pNode->pParam != NULL) {
        SSQLToken* pToken = &pItem->pNode->pParam->a[0].pNode->colInfo;
        if (pToken->z == NULL || pToken->n == 0) {
1527
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1528 1529
        }

S
slguan 已提交
1530 1531 1532 1533 1534 1535
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
        if (pParamElem->pNode->nSQLOptr == TK_ALL) {
          // select table.*
          // check if the table name is valid or not
          SSQLToken tmpToken = pParamElem->pNode->colInfo;

1536
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1537
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1538 1539 1540 1541
          }

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
1542
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1543
        } else {
H
hjxilinx 已提交
1544
          // count the number of meters created according to the super table
1545 1546
          if (getColumnIndexByName(pCmd, pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1547 1548
          }

H
hjxilinx 已提交
1549
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1550 1551

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1552 1553
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1554
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1555
            isTag = true;
H
hzcheng 已提交
1556 1557
          }

S
slguan 已提交
1558
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1559
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1560
        }
S
slguan 已提交
1561 1562 1563
      } 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;
1564
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1565
      }
H
Haojun Liao 已提交
1566 1567 1568

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

H
hjxilinx 已提交
1569
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1570
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1571
      
S
slguan 已提交
1572
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1573 1574 1575 1576 1577
      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) {
1578
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1579 1580
        }
      }
H
Haojun Liao 已提交
1581 1582

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

S
slguan 已提交
1587
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1588 1589 1590
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1591 1592 1593 1594 1595 1596
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1597
    case TK_TWA:
H
hzcheng 已提交
1598 1599 1600 1601 1602 1603 1604 1605 1606
    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 */
1607
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1608 1609 1610 1611
      }

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

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

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

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

      int16_t resultType = 0;
      int16_t resultSize = 0;
1632
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1633 1634 1635

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

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

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

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

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

1660
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, resultSize, false);
H
hzcheng 已提交
1661 1662 1663 1664

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

S
slguan 已提交
1669
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1670 1671

        memset(val, 0, tListLen(val));
1672
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1673
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1674 1675
        }

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

S
slguan 已提交
1679 1680 1681
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1682 1683
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1684
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1685 1686 1687 1688 1689 1690
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, pExpr->resType, pExpr->aliasName, pExpr);
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1691
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1692 1693
        }
      }
H
Haojun Liao 已提交
1694 1695

      tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
S
slguan 已提交
1696
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1697 1698 1699 1700 1701 1702 1703 1704 1705
    }
    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 已提交
1706
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1707
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
B
Bomin Zhang 已提交
1708
      }
H
hzcheng 已提交
1709 1710 1711

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

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

H
hzcheng 已提交
1719 1720 1721 1722
        /* 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) {
1723
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1724 1725
          }

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

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

1732
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1733
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1734 1735
            }

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

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

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

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

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

1759
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i, &index) != 0) {
1760
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1761
            }
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777

            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 已提交
1778 1779
          }
        }
1780
        
S
slguan 已提交
1781 1782 1783 1784
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

H
Haojun Liao 已提交
1785
        // multicolumn selection does not support alias name
H
Haojun Liao 已提交
1786
        if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
1787
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
1788 1789
        }

1790
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
1791
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
1792
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1793

H
hjxilinx 已提交
1794
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
1795
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
1796
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i + j, &index) !=
1797
                0) {
1798
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1799
            }
H
hzcheng 已提交
1800
          }
S
slguan 已提交
1801

H
hjxilinx 已提交
1802
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1803 1804
        }

1805
        
S
slguan 已提交
1806
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1807 1808 1809 1810 1811 1812 1813 1814 1815
      }
    }
    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 */
1816
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1817 1818 1819 1820
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
1821
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1822
      }
H
hjxilinx 已提交
1823
      
S
slguan 已提交
1824
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1825 1826
      if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1827 1828
      }

H
hjxilinx 已提交
1829
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1830
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1831 1832

      // functions can not be applied to tags
H
hjxilinx 已提交
1833
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1834
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1835 1836 1837
      }

      // 2. valid the column type
S
slguan 已提交
1838
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
1839
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1840
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1841 1842 1843 1844
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
1845
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1846 1847 1848 1849
      }

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

S
slguan 已提交
1850 1851
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1852

H
hjxilinx 已提交
1853
      char    val[8] = {0};
H
hjxilinx 已提交
1854 1855
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
1856
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
1857
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
1858

L
lihui 已提交
1859
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
1860
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
1861
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873
        }

        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) {
1874
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1875 1876
        }

1877
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1878
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1879
      } else {
1880
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
1881

H
Haojun Liao 已提交
1882
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
1883
        if (nTop <= 0 || nTop > 100) {  // todo use macro
1884
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1885 1886 1887 1888
        }

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

H
Haojun Liao 已提交
1892
        // todo REFACTOR
H
hzcheng 已提交
1893
        // set the first column ts for top/bottom query
S
slguan 已提交
1894
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
1895 1896
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
            TSDB_KEYSIZE, false);
H
Haojun Liao 已提交
1897
        tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
S
slguan 已提交
1898

H
Haojun Liao 已提交
1899
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
1900
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
1901
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
1902
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
1903

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

1906
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1907
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
1908
      }
H
hjxilinx 已提交
1909 1910
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1911
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1912
  
S
slguan 已提交
1913
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
1914
      if (finalResult) {
1915
        insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
1916 1917
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1918
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1919 1920
        }
      }
S
slguan 已提交
1921

1922 1923 1924 1925 1926
      return TSDB_CODE_SUCCESS;
    };
    
    case TK_TBID: {
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
1927
      if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
1928
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
1929 1930 1931 1932
      }
    
      // no parameters or more than one parameter for function
      if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 1) {
1933
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
1934 1935 1936 1937 1938
      }
      
      tSQLExpr* pParam = pItem->pNode->pParam->a[0].pNode;
    
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1939 1940
      if (getColumnIndexByName(pCmd, &pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
1941 1942 1943 1944 1945 1946 1947
      }
    
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
  
      // functions can not be applied to normal columns
      int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
1948
      if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
1949
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
1950 1951
      }
    
1952 1953 1954
      if (index.columnIndex > 0) {
        index.columnIndex -= numOfCols;
      }
1955 1956
      
      // 2. valid the column type
1957 1958 1959 1960 1961 1962 1963 1964
      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) {
1965
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
1966 1967 1968 1969
      }

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
1970 1971 1972
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
1973
        s = tGetTableNameColumnSchema();
1974 1975 1976 1977
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
1978 1979
      int16_t bytes = 0;
      int16_t type  = 0;
1980
      int32_t inter = 0;
1981 1982 1983 1984 1985 1986 1987 1988 1989 1990

      int32_t ret = getResultDataInfo(s.type, s.bytes, TSDB_FUNC_TID_TAG, 0, &type, &bytes, &inter, 0, 0);
      assert(ret == TSDB_CODE_SUCCESS);
      
      s.type  = type;
      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 已提交
1991
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1992
    }
1993
    
H
hzcheng 已提交
1994
    default:
1995
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1996
  }
1997
  
H
hzcheng 已提交
1998 1999
}

S
slguan 已提交
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
  assert(num == 1 && columnIndex >= -1 && tableIndex >= 0);

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

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

  return columnList;
}

H
hzcheng 已提交
2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
    int32_t len = (pItem->pNode->operand.n < nameLength) ? pItem->pNode->operand.n : nameLength;
    strncpy(resultFieldName, pItem->pNode->operand.z, len);
  }
}

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

S
slguan 已提交
2027 2028 2029 2030 2031 2032 2033 2034 2035
static bool isTablenameToken(SSQLToken* token) {
  SSQLToken tmpToken = *token;
  SSQLToken tableToken = {0};

  extractTableNameFromToken(&tmpToken, &tableToken);

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

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

H
hjxilinx 已提交
2039 2040
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2041 2042 2043 2044 2045 2046 2047 2048 2049 2050

  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 已提交
2051
      break;
S
slguan 已提交
2052 2053 2054 2055 2056 2057
    }
  }

  return columnIndex;
}

2058
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2059 2060 2061 2062 2063 2064 2065 2066 2067 2068
  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) {
2069 2070
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2071 2072 2073

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2074
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
2075 2076 2077 2078 2079 2080 2081
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2082
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2083 2084 2085 2086 2087 2088
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2089
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2090 2091 2092 2093 2094 2095
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2096
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2097 2098 2099
  }
}

H
hjxilinx 已提交
2100
int32_t getTableIndexImpl(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2101
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2102
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2103 2104 2105 2106 2107 2108 2109
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
B
Bomin Zhang 已提交
2110
  char tableName[TSDB_TABLE_ID_LEN] = {0};
S
slguan 已提交
2111

2112
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2113
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
hjxilinx 已提交
2114
    extractTableName(pTableMetaInfo->name, tableName);
S
slguan 已提交
2115 2116 2117 2118 2119 2120 2121 2122

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

  if (pIndex->tableIndex < 0) {
2123
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2124 2125 2126 2127 2128
  }

  return TSDB_CODE_SUCCESS;
}

2129
int32_t getTableIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2130 2131 2132
  SSQLToken tableToken = {0};
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2133
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2134
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2135 2136
  }

S
slguan 已提交
2137 2138
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2139

2140
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2141
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2142
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2143 2144
  }

S
slguan 已提交
2145 2146
  SSQLToken tmpToken = *pToken;

2147
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2148
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2149 2150
  }

2151
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164
}

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 已提交
2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182
    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 已提交
2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218
    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 已提交
2219 2220
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235
      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 已提交
2236
  SSqlCmd*        pCmd = &pSql->cmd;
2237
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2238
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2239

H
hzcheng 已提交
2240 2241
  pCmd->command = TSDB_SQL_SHOW;

2242
  const char* msg1 = "invalid name";
2243
  const char* msg2 = "pattern filter string too long";
2244 2245 2246 2247
  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 已提交
2248 2249 2250 2251 2252

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2253 2254 2255
  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 已提交
2256
    // db prefix in tagCond, show table conds in payload
2257 2258
    SSQLToken* pDbPrefixToken = &pShowInfo->prefix;
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2259

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

2264
      if (pDbPrefixToken->n <= 0) {
2265
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2266 2267
      }

2268
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2269
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2270 2271
      }

H
hjxilinx 已提交
2272
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2273
      if (ret != TSDB_CODE_SUCCESS) {
2274
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2275
      }
2276
    }
H
hzcheng 已提交
2277

2278 2279 2280 2281
    // show table/stable like 'xxxx', set the like pattern for show tables
    SSQLToken* pPattern = &pShowInfo->pattern;
    if (pPattern->type != 0) {
      pPattern->n = strdequote(pPattern->z);
S
slguan 已提交
2282

2283
      if (pPattern->n <= 0) {
2284
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2285
      }
H
hzcheng 已提交
2286

H
Haojun Liao 已提交
2287
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2288
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2289 2290
      }
    }
2291 2292
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2293
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2294 2295
    }

L
lihui 已提交
2296
    // show vnodes may be ip addr of dnode in payload
2297
    SSQLToken* pDnodeIp = &pShowInfo->prefix;
B
Bomin Zhang 已提交
2298
    if (pDnodeIp->n >= TSDB_IPv4ADDR_LEN) {  // ip addr is too long
2299
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2300
    }
L
lihui 已提交
2301

2302
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2303
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2304
    }
H
hzcheng 已提交
2305 2306 2307 2308 2309
  }

  return TSDB_CODE_SUCCESS;
}

2310 2311 2312 2313
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 已提交
2314

2315 2316
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2317
  
2318 2319
  SSQLToken* idStr = &(pInfo->pDCLInfo->ip);
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2320
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2321 2322
  }

2323
  strncpy(pCmd->payload, idStr->z, idStr->n);
2324

H
hzcheng 已提交
2325
  const char delim = ':';
2326 2327
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2328

2329 2330 2331 2332 2333
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2334

2335 2336 2337 2338 2339 2340
  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 已提交
2341
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2342 2343 2344 2345 2346
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2347
  }
2348
  
H
hzcheng 已提交
2349 2350 2351
  return TSDB_CODE_SUCCESS;
}

2352 2353 2354 2355 2356 2357
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);

2358
  in_addr_t epAddr = inet_addr(tmp);
2359

2360
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2361 2362
}

H
hjxilinx 已提交
2363
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2364
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2365

weixin_48148422's avatar
weixin_48148422 已提交
2366
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2367
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2368 2369
  }

H
hjxilinx 已提交
2370
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2371 2372 2373

  int16_t bytes = 0;
  int16_t type = 0;
2374
  int32_t interBytes = 0;
H
hjxilinx 已提交
2375 2376 2377
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2378
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2379 2380
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

2381
    int32_t colIndex = pExpr->colInfo.colIndex;
H
hjxilinx 已提交
2382
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2383
    
S
slguan 已提交
2384
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2385 2386
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
H
hjxilinx 已提交
2387
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, pExpr->param[0].i64Key, &type, &bytes,
2388
                            &interBytes, 0, true) != TSDB_CODE_SUCCESS) {
2389
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2390
      }
H
hzcheng 已提交
2391

2392
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2393
      // todo refactor
2394
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2395 2396 2397
    }
  }

2398
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2399
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2400 2401 2402
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2403
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2404
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2405
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2406 2407
    return;
  }
H
hjxilinx 已提交
2408 2409 2410
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2411
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2412
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2413
    
2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430
    // 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 已提交
2431 2432 2433
  }
}

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

S
slguan 已提交
2439
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2440 2441
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2442
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
2443
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
2444
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2445
      return true;
H
hzcheng 已提交
2446 2447 2448
    }
  }

2449 2450
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2451
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2452 2453
      return true;
    }
H
hzcheng 已提交
2454

2455
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2456
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2457
      return true;
2458 2459 2460
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
2461
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2462 2463
        return true;
      }
H
hzcheng 已提交
2464 2465
    }
  }
S
slguan 已提交
2466

H
hzcheng 已提交
2467 2468 2469
  return false;
}

2470
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
2471
  int32_t startIdx = 0;
H
hjxilinx 已提交
2472
  
H
hjxilinx 已提交
2473 2474
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2475 2476

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

H
Haojun Liao 已提交
2481
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2482 2483 2484

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2485 2486 2487
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2488
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2489

H
hjxilinx 已提交
2490
    int16_t functionId = pExpr1->functionId;
2491 2492 2493 2494
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
hjxilinx 已提交
2495
    if (functionId == TSDB_FUNC_PRJ && pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
2496 2497 2498
      continue;
    }

H
Haojun Liao 已提交
2499
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2500 2501 2502 2503 2504 2505 2506
      return false;
    }
  }

  return true;
}

2507
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2508 2509
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
H
Haojun Liao 已提交
2510
//  const char* msg3 = "group by columns must belong to one table";
S
slguan 已提交
2511 2512 2513
  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 已提交
2514

2515
  // todo : handle two tables situation
H
hjxilinx 已提交
2516
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2517 2518 2519 2520 2521

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

2522 2523 2524 2525
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
2526
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2527
  if (pList->nExpr > TSDB_MAX_TAGS) {
2528
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2529 2530
  }

H
hjxilinx 已提交
2531
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2532
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2533
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2534

S
slguan 已提交
2535
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
2536
  
H
hzcheng 已提交
2537 2538 2539 2540
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tVariant* pVar = &pList->a[i].pVar;
    SSQLToken token = {pVar->nLen, pVar->nType, pVar->pz};

S
slguan 已提交
2541
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2542 2543
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2544
    }
H
hzcheng 已提交
2545

S
slguan 已提交
2546
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2547

H
hjxilinx 已提交
2548
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2549
    pTableMeta = pTableMetaInfo->pTableMeta;
2550 2551
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2552 2553 2554
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2555
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2556
    }
H
hzcheng 已提交
2557

S
slguan 已提交
2558
    bool groupTag = false;
2559
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2560
      groupTag = true;
H
hzcheng 已提交
2561
    }
2562 2563 2564 2565 2566 2567
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2568
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2569
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2570
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
S
slguan 已提交
2571 2572
      }

2573 2574 2575 2576
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2577

H
hjxilinx 已提交
2578
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2579
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2580 2581 2582
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2583 2584
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
2585
      if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
2586
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
2587 2588
      }

2589
      tscColumnListInsert(pQueryInfo->colList, &index);
2590
      
2591
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2592
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2593
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2594 2595

      if (i == 0 && pList->nExpr > 1) {
2596
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2597
      }
H
hzcheng 已提交
2598 2599 2600
    }
  }

2601
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2602 2603 2604
  return TSDB_CODE_SUCCESS;
}

2605 2606
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2607
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2608
  } else {
H
hjxilinx 已提交
2609
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2610 2611 2612
  }
}

2613
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2614 2615 2616
  if (pColumn == NULL) {
    return NULL;
  }
2617

S
slguan 已提交
2618
  int32_t size = pColumn->numOfFilters + 1;
L
lihui 已提交
2619
  char*   tmp = (char*)realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2620 2621
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2622 2623
  }

S
slguan 已提交
2624
  pColumn->numOfFilters++;
2625

S
slguan 已提交
2626 2627 2628 2629
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2630 2631
}

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

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

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

S
slguan 已提交
2641
  int16_t colType = pSchema->type;
2642
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2643 2644 2645
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2646
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2647
    int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
2648 2649 2650
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2651 2652 2653
  }

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

2660
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2661 2662 2663 2664
    } 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);

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

H
[TD-92]  
Hui Li 已提交
2667
      size_t len = twcslen((wchar_t*)pColumnFilter->pz);
S
slguan 已提交
2668
      pColumnFilter->len = len * TSDB_NCHAR_SIZE;
H
hzcheng 已提交
2669
    } else {
2670
      tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
2671 2672 2673 2674 2675
    }
  }

  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
2676
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
2677 2678
      break;
    case TK_LT:
S
slguan 已提交
2679
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
2680 2681
      break;
    case TK_GT:
2682
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
2683 2684
      break;
    case TK_GE:
2685
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
2686 2687
      break;
    case TK_EQ:
S
slguan 已提交
2688
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
2689 2690
      break;
    case TK_NE:
S
slguan 已提交
2691
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
2692 2693
      break;
    case TK_LIKE:
S
slguan 已提交
2694
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
2695
      break;
S
slguan 已提交
2696
    default:
2697
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
2698
  }
S
slguan 已提交
2699

2700
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2701 2702
}

S
slguan 已提交
2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716
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 已提交
2717

H
hjxilinx 已提交
2718
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
2719 2720

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2721
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2722 2723
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2724 2725

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

H
hjxilinx 已提交
2728 2729 2730 2731 2732 2733 2734
  } 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 已提交
2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753
    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)) {
2754
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2755 2756
  }

S
slguan 已提交
2757 2758 2759 2760 2761 2762 2763 2764 2765 2766
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
2767
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2768 2769 2770 2771 2772 2773 2774 2775 2776
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
2777 2778 2779 2780
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
2781 2782 2783 2784
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832

  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:
2833
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2834 2835 2836 2837 2838 2839 2840
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2841
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
2842 2843
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
2844
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2845 2846
  }

S
slguan 已提交
2847
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2848
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2849 2850
  }

H
hzcheng 已提交
2851 2852
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
2853
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
2854 2855

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

H
Haojun Liao 已提交
2859
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
2860
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2861 2862 2863 2864 2865 2866
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2867
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
2868 2869
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2870 2871

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2872 2873
}

S
slguan 已提交
2874 2875 2876 2877 2878 2879
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2880

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

H
hjxilinx 已提交
2884 2885
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2886

S
slguan 已提交
2887
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
2888 2889
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
2890

H
hjxilinx 已提交
2891
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908
  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;
2909
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2910 2911
  }

2912
  pColFilter->filterstr =
S
slguan 已提交
2913 2914
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

2915
  if (pColFilter->filterstr) {
S
slguan 已提交
2916
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
2917
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2918
    }
S
slguan 已提交
2919 2920
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
2921
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2922
    }
H
Hui Li 已提交
2923 2924 2925
    
    if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
      if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
2926
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Hui Li 已提交
2927 2928
      }
    }
S
slguan 已提交
2929 2930 2931
  }

  pColumn->colIndex = *pIndex;
2932
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
2933 2934
}

2935
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2936 2937 2938 2939 2940
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

2941
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
2942 2943 2944 2945 2946 2947 2948 2949 2950
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

2951
UNUSED_FUNC
2952
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2953 2954 2955 2956 2957 2958 2959
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

2961
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
2962
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2963
      return ret;
H
hzcheng 已提交
2964
    }
S
slguan 已提交
2965

2966
    relToString(pExpr, str);
S
slguan 已提交
2967

2968
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
2969 2970 2971 2972

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

H
hzcheng 已提交
2973 2974 2975
    return ret;
  }

S
slguan 已提交
2976 2977 2978
  return tSQLExprLeafToString(pExpr, true, str);
}

2979
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
2980 2981 2982 2983
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
2986 2987
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
2988

S
slguan 已提交
2989
  if (!isTablenameToken(&pLeft->colInfo)) {
2990
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2991 2992
  }

S
slguan 已提交
2993
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2994

S
slguan 已提交
2995
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
2996
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
2997
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
2998
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
2999
  }
H
hzcheng 已提交
3000

S
slguan 已提交
3001
  if (ret != TSDB_CODE_SUCCESS) {
3002
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3003
  }
H
hzcheng 已提交
3004

S
slguan 已提交
3005 3006 3007
  return ret;
}

3008
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3009 3010 3011 3012 3013
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
3014
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3015 3016 3017 3018
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3019
    return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3020 3021
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3022
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3023
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3024
    }
S
slguan 已提交
3025

3026
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3027
  }
S
slguan 已提交
3028
}
H
hzcheng 已提交
3029

3030
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
H
Haojun Liao 已提交
3031 3032 3033 3034
  const char* msg1 = "invalid join query condition";
  const char* msg2 = "join on binary/nchar not supported";
  const char* msg3 = "type of join columns must be identical";
  const char* msg4 = "invalid column name in join condition";
H
hzcheng 已提交
3035

S
slguan 已提交
3036 3037 3038
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3039

S
slguan 已提交
3040
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
3041
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3042 3043
  }

3044
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3045 3046 3047 3048
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3049 3050
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3051 3052
  }

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

H
hjxilinx 已提交
3056
  pLeft->uid = pTableMetaInfo->pTableMeta->uid;
H
Haojun Liao 已提交
3057
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3058
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3059 3060

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3061 3062
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3063 3064
  }

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

H
hjxilinx 已提交
3068
  pRight->uid = pTableMetaInfo->pTableMeta->uid;
H
Haojun Liao 已提交
3069
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3070
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3071

H
Haojun Liao 已提交
3072
  if (pTagSchema1->type != pTagSchema2->type) {
3073
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3074 3075 3076
  }

  if (pTagSchema1->type == TSDB_DATA_TYPE_BINARY || pTagSchema1->type == TSDB_DATA_TYPE_NCHAR) {
3077
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
Haojun Liao 已提交
3078 3079
  }

S
slguan 已提交
3080
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3081 3082 3083 3084
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3089
  *(*exprString)++ = '(';
H
hzcheng 已提交
3090 3091

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
S
slguan 已提交
3092
    buildArithmeticExprString(pLeft, exprString);
H
hzcheng 已提交
3093
  } else {
S
slguan 已提交
3094
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3095
    if (ret != TSDB_CODE_SUCCESS) {
3096
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3097 3098 3099 3100 3101 3102
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
S
slguan 已提交
3103
    buildArithmeticExprString(pRight, exprString);
H
hzcheng 已提交
3104
  } else {
S
slguan 已提交
3105
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3106
    if (ret != TSDB_CODE_SUCCESS) {
3107
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3108 3109 3110
    }
  }

H
hjxilinx 已提交
3111
  *(*exprString)++ = ')';
H
hzcheng 已提交
3112 3113 3114 3115

  return TSDB_CODE_SUCCESS;
}

3116
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3117
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3118 3119 3120
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
3121
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3122
    }
L
lihui 已提交
3123

H
hjxilinx 已提交
3124
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3125
    if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3126
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3127 3128 3129
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3130
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3131 3132
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3133 3134
    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)) {
3135
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3136 3137 3138
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3139
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
3140
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3141 3142 3143 3144
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
3145
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3146 3147
    }

H
hjxilinx 已提交
3148 3149
    int32_t outputIndex = tscSqlExprNumOfExprs(pQueryInfo);
  
H
hjxilinx 已提交
3150 3151 3152
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
    // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
3153
    if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
3154
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3155
    }
H
hzcheng 已提交
3156 3157 3158 3159 3160
  }

  return TSDB_CODE_SUCCESS;
}

3161
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3162 3163 3164 3165 3166 3167
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3168
    int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3169 3170 3171 3172
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3173
    int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3174 3175 3176 3177 3178 3179 3180
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3181
    int32_t ret = validateArithmeticSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3182 3183 3184 3185
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3186
    int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201
    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 已提交
3202 3203 3204
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3205 3206 3207
   *
   * However, columnA < 4+12 is valid
   */
B
Bomin Zhang 已提交
3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223
  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 已提交
3224 3225 3226 3227 3228 3229
    return false;
  }

  return true;
}

S
slguan 已提交
3230 3231 3232
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3233

S
slguan 已提交
3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258
  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 已提交
3259

S
slguan 已提交
3260 3261 3262 3263 3264
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3265
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278
  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) {
3279
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3280 3281 3282 3283 3284
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3285 3286
  if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3287
    return false;
H
hzcheng 已提交
3288 3289
  }

S
slguan 已提交
3290
  // todo extract function
H
hjxilinx 已提交
3291
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3292
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3293 3294
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3295
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3296
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3297 3298 3299
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3300
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3301 3302
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3303
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3304
    return false;
H
hzcheng 已提交
3305 3306
  }

S
slguan 已提交
3307
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3308
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3309
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
S
slguan 已提交
3310 3311
    return false;
  }
H
hzcheng 已提交
3312

S
slguan 已提交
3313 3314
  return true;
}
H
hzcheng 已提交
3315

S
slguan 已提交
3316 3317 3318 3319 3320 3321
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 已提交
3322 3323 3324
    }
  }

S
slguan 已提交
3325
  return false;
H
hzcheng 已提交
3326 3327
}

3328
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3329 3330
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3331
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3332
    }
H
hzcheng 已提交
3333

S
slguan 已提交
3334 3335 3336 3337
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3338

S
slguan 已提交
3339 3340
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3341

3342 3343
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                                     int32_t* type, int32_t parentOptr) {
3344
  const char* msg1 = "table query cannot use tags filter";
S
slguan 已提交
3345 3346 3347
  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 已提交
3348 3349 3350
  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";
3351 3352
  const char* msg8 = "wildcard string should be less than 20 characters";
  
S
slguan 已提交
3353 3354
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3355

S
slguan 已提交
3356 3357 3358
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3359 3360
  if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3361 3362
  }

S
slguan 已提交
3363 3364
  assert(isExprDirectParentOfLeaftNode(*pExpr));

H
hjxilinx 已提交
3365
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3366
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3367 3368

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3369
    if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3370
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3371
    }
S
slguan 已提交
3372 3373 3374

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
H
hjxilinx 已提交
3375
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
S
slguan 已提交
3376 3377 3378 3379 3380 3381 3382 3383
      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 {
3384
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3385 3386 3387 3388
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3389 3390
  } 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 已提交
3391
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3392
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3393 3394 3395 3396 3397
    }

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

H
hjxilinx 已提交
3401
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3402 3403 3404

      if ((!isTablenameToken(&pLeft->colInfo)) && pSchema[index.columnIndex].type != TSDB_DATA_TYPE_BINARY &&
          pSchema[index.columnIndex].type != TSDB_DATA_TYPE_NCHAR) {
3405
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3406 3407 3408 3409 3410 3411
      }
    }

    // in case of in operator, keep it in a seperate attribute
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3412
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
3413
      }
3414 3415
  
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
3416
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
3417
      }
S
slguan 已提交
3418 3419 3420 3421 3422 3423

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3424
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
3425 3426 3427 3428 3429 3430
      }

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

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

3439 3440
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454
        *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
3455
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
3456 3457
    }

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

S
slguan 已提交
3462
  return ret;
H
hzcheng 已提交
3463 3464
}

3465 3466
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                        int32_t* type, int32_t parentOptr) {
H
hzcheng 已提交
3467 3468 3469 3470
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3473 3474 3475 3476
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3477
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3478 3479
  }

S
slguan 已提交
3480 3481
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3482

S
slguan 已提交
3483
  if (!isExprDirectParentOfLeaftNode(*pExpr)) {
3484
    int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3485 3486 3487 3488
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3489
    ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3490 3491 3492
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3493

S
slguan 已提交
3494 3495 3496 3497 3498 3499
    /*
     *  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)) {
3500
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3501
      }
H
hzcheng 已提交
3502 3503
    }

S
slguan 已提交
3504 3505 3506
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3507

S
slguan 已提交
3508
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3509

3510
  return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3511
}
H
hzcheng 已提交
3512

S
slguan 已提交
3513 3514 3515 3516
static void doCompactQueryExpr(tSQLExpr** pExpr) {
  if (*pExpr == NULL || isExprDirectParentOfLeaftNode(*pExpr)) {
    return;
  }
H
hzcheng 已提交
3517

S
slguan 已提交
3518 3519 3520
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3521

S
slguan 已提交
3522 3523 3524
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3525

S
slguan 已提交
3526 3527 3528 3529
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3530

S
slguan 已提交
3531 3532 3533
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3534

S
slguan 已提交
3535 3536 3537 3538
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3539

S
slguan 已提交
3540
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3541
  }
S
slguan 已提交
3542
}
H
hzcheng 已提交
3543

3544
static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
S
slguan 已提交
3545 3546 3547 3548
  if (isExprDirectParentOfLeaftNode(*pExpr)) {
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3549
    if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3550
      return;
H
hzcheng 已提交
3551 3552
    }

S
slguan 已提交
3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565
    if (index.tableIndex != tableIndex) {
      return;
    }

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

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

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

3566 3567
    doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3568 3569 3570
  }
}

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

S
slguan 已提交
3574
  if (*pExpr != NULL) {
3575
    doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3576
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3577 3578
  }

S
slguan 已提交
3579
  return pResExpr;
H
hzcheng 已提交
3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594
}

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

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

S
slguan 已提交
3599 3600 3601 3602
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3605
  STagCond* pTagCond = &pQueryInfo->tagCond;
H
hjxilinx 已提交
3606
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
3607 3608 3609 3610

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3611
    char* str = taosStringBuilderGetResult(sb, NULL);
3612
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3613 3614 3615
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
3616
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
3617
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3618

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

S
slguan 已提交
3621
  // remove the duplicated input table names
H
hzcheng 已提交
3622
  int32_t num = 0;
H
hjxilinx 已提交
3623 3624 3625
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3626
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3627 3628 3629 3630 3631 3632 3633 3634 3635

  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 已提交
3636 3637 3638
  char* name = extractDBName(pTableMetaInfo->name, db);
  SSQLToken dbToken = {.type = TK_STRING, .z = name, .n = strlen(name)};
  
H
hzcheng 已提交
3639 3640
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3641
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3642
    }
H
hjxilinx 已提交
3643

B
Bomin Zhang 已提交
3644
    char      idBuf[TSDB_TABLE_ID_LEN] = {0};
S
slguan 已提交
3645
    int32_t   xlen = strlen(segments[i]);
H
hzcheng 已提交
3646 3647
    SSQLToken t = {.z = segments[i], .n = xlen, .type = TK_STRING};

3648
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3649
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3650
      taosStringBuilderDestroy(&sb1);
H
hzcheng 已提交
3651
      tfree(segments);
H
hjxilinx 已提交
3652

3653
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
3654 3655
      return ret;
    }
H
hjxilinx 已提交
3656

H
hjxilinx 已提交
3657
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3658
  }
H
hjxilinx 已提交
3659

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

H
hjxilinx 已提交
3663
  taosStringBuilderDestroy(&sb1);
H
hzcheng 已提交
3664 3665 3666 3667
  tfree(segments);
  return TSDB_CODE_SUCCESS;
}

3668
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
3669 3670 3671 3672 3673 3674
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
3675

3676 3677
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
3678 3679
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
3680

3681
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695
          (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;
}

3696
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
3697 3698
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
3699 3700 3701 3702 3703

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

S
slguan 已提交
3704 3705
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    if (pExpr->nSQLOptr == TK_OR) {
3706
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3707
    }
H
hzcheng 已提交
3708

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

3711
    return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
S
slguan 已提交
3712 3713
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3714
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3715
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3716 3717
    }

H
hjxilinx 已提交
3718
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3719
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3720
    
S
slguan 已提交
3721 3722
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3723 3724
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
3725
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3726 3727 3728
    }

    // update the timestamp query range
H
hjxilinx 已提交
3729 3730
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
3731 3732
    }

H
hjxilinx 已提交
3733 3734
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
3735 3736 3737 3738 3739 3740
    }
  }

  return TSDB_CODE_SUCCESS;
}

3741
static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
3742 3743 3744 3745
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

3746 3747
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
3748 3749
      return TSDB_CODE_SUCCESS;
    } else {
3750
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3751 3752 3753
    }
  }

H
hjxilinx 已提交
3754
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
3755
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // for stable join, tag columns
3756
                                                   // must be present for join
S
slguan 已提交
3757
    if (pCondExpr->pJoinExpr == NULL) {
3758
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3759 3760 3761 3762
    }
  }

  if (!pCondExpr->tsJoin) {
3763
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3764 3765
  }

S
slguan 已提交
3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790
  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);
  }
}

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

3796
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
3797 3798
      tscError("%p: invalid column name (left)", pQueryInfo);
    }
H
hjxilinx 已提交
3799
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3800 3801
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3802 3803
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
  
3804
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
3805 3806
      tscError("%p: invalid column name (right)", pQueryInfo);
    }
H
hjxilinx 已提交
3807
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3808 3809
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3810
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
3811
  }
H
hjxilinx 已提交
3812
}
S
slguan 已提交
3813

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

3817 3818 3819 3820 3821
  if (pCondExpr->pTagCond == NULL) {
    return ret;
  }
  
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
3822
    tSQLExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
H
Haojun Liao 已提交
3823 3824 3825 3826
    if (p1 == NULL) {  // no query condition on this table
      continue;
    }

3827
    tExprNode* p = NULL;
3828 3829
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
3830
    ret = exprTreeFromSqlExpr(pCmd, &p, p1, NULL, pQueryInfo, colList);
3831 3832 3833 3834 3835 3836 3837 3838 3839
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
3840
    
3841 3842 3843 3844 3845 3846 3847 3848 3849
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
    int64_t uid = pTableMetaInfo->pTableMeta->uid;
    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 已提交
3850
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
3851 3852
    }
    
3853
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
3854 3855 3856 3857
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
3858 3859
    
    taosArrayDestroy(colList);
H
hjxilinx 已提交
3860
  }
H
hjxilinx 已提交
3861

3862
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
3863 3864
  return ret;
}
3865
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
3866 3867 3868
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
3869

H
hjxilinx 已提交
3870
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
3871
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
3872

H
hjxilinx 已提交
3873
  int32_t ret = TSDB_CODE_SUCCESS;
3874
  pQueryInfo->window = TSWINDOW_INITIALIZER;
S
slguan 已提交
3875

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

H
hjxilinx 已提交
3880
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
3881
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
S
slguan 已提交
3882 3883
  }

H
hjxilinx 已提交
3884
  int32_t type = 0;
3885
  if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3886 3887
    return ret;
  }
H
hjxilinx 已提交
3888

S
slguan 已提交
3889
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
3890

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

S
slguan 已提交
3894
  // 1. check if it is a join query
3895
  if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3896 3897
    return ret;
  }
H
hjxilinx 已提交
3898

S
slguan 已提交
3899
  // 2. get the query time range
3900
  if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3901 3902
    return ret;
  }
H
hjxilinx 已提交
3903

S
slguan 已提交
3904
  // 3. get the tag query condition
3905
  if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3906
    return ret;
S
slguan 已提交
3907
  }
H
hjxilinx 已提交
3908

S
slguan 已提交
3909
  // 4. get the table name query condition
3910
  if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3911 3912
    return ret;
  }
H
hjxilinx 已提交
3913

S
slguan 已提交
3914
  // 5. other column query condition
3915
  if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3916 3917
    return ret;
  }
H
hjxilinx 已提交
3918

S
slguan 已提交
3919
  // 6. join condition
3920
  if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3921
    return ret;
H
hzcheng 已提交
3922
  }
H
hjxilinx 已提交
3923

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

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

3930
  if (!validateFilterExpr(pQueryInfo)) {
3931
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
3932
  }
H
hjxilinx 已提交
3933

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

H
hjxilinx 已提交
3936
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
3937 3938 3939
  return ret;
}

H
hjxilinx 已提交
3940
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
3941 3942 3943 3944 3945
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
3946 3947
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
3948
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
3949 3950
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
3951
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3952
  }
H
hzcheng 已提交
3953 3954 3955 3956

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

S
slguan 已提交
3959
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
3960
    if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
3961
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
3962 3963
        parsed = true;
      } else {
3964
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3965
      }
S
slguan 已提交
3966 3967 3968 3969 3970
    } else {
      SSQLToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
3971
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3972
      }
H
hzcheng 已提交
3973 3974 3975 3976
    }
  } 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 已提交
3977
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992
     *
     * 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
     */
3993
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014

    /*
     * 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 已提交
4015
    win->ekey = val;
H
hzcheng 已提交
4016
  } else if (optr == TK_LT) {
H
hjxilinx 已提交
4017
    win->ekey = val - delta;
H
hzcheng 已提交
4018
  } else if (optr == TK_GT) {
H
hjxilinx 已提交
4019
    win->skey = val + delta;
H
hzcheng 已提交
4020
  } else if (optr == TK_GE) {
H
hjxilinx 已提交
4021
    win->skey = val;
H
hzcheng 已提交
4022
  } else if (optr == TK_EQ) {
H
hjxilinx 已提交
4023
    win->ekey = win->skey = val;
H
hzcheng 已提交
4024 4025 4026 4027
  }
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
4032 4033
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
B
Bomin Zhang 已提交
4034
    for (int32_t j = 0; j < (TSDB_COL_NAME_LEN - 1) && fieldName[j] != 0; ++j) {
S
slguan 已提交
4035 4036 4037 4038 4039
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
4040 4041
      }
    }
S
slguan 已提交
4042

H
hzcheng 已提交
4043 4044 4045 4046
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4047 4048 4049
  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 已提交
4050
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4051
        const char* msg = "duplicated column name in new table";
4052
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4053 4054 4055 4056 4057 4058 4059
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4060
int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
4061 4062 4063 4064
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
4065 4066 4067 4068

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

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4071
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4072
  }
H
hjxilinx 已提交
4073 4074 4075
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
4076 4077 4078
  if (pQueryInfo->fillVal == NULL) {
    pQueryInfo->fillVal = calloc(size, sizeof(int64_t));
    if (pQueryInfo->fillVal == NULL) {
4079
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4080 4081 4082
    }
  }

H
hzcheng 已提交
4083
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4084
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4085
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4086
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4087 4088
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
4089 4090 4091 4092 4093
      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 已提交
4094 4095
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4096
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4097
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4098
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4099
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4100
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4101 4102

    if (pFillToken->nExpr == 1) {
4103
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4104 4105 4106 4107 4108 4109
    }

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

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

H
hjxilinx 已提交
4113 4114
      if (numOfFillVal > size) {
        numOfFillVal = size;
H
hzcheng 已提交
4115 4116
      }
    } else {
H
hjxilinx 已提交
4117
      numOfFillVal = (pFillToken->nExpr > size) ? size : pFillToken->nExpr;
H
hzcheng 已提交
4118 4119 4120 4121 4122
    }

    int32_t j = 1;

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

4125
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4126
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
4127 4128
        continue;
      }
H
hjxilinx 已提交
4129

4130
      int32_t ret = tVariantDump(&pFillToken->a[j].pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4131
      if (ret != TSDB_CODE_SUCCESS) {
4132
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4133 4134
      }
    }
H
hjxilinx 已提交
4135
    
4136
    if ((pFillToken->nExpr < size) || ((pFillToken->nExpr - 1 < size) && (tscIsPointInterpQuery(pQueryInfo)))) {
H
hzcheng 已提交
4137 4138
      tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1];

H
hjxilinx 已提交
4139 4140
      for (int32_t i = numOfFillVal; i < size; ++i) {
        TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4141 4142

        if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4143
          setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
H
hjxilinx 已提交
4144
        } else {
4145
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4146 4147 4148 4149
        }
      }
    }
  } else {
4150
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4151 4152 4153 4154 4155
  }

  return TSDB_CODE_SUCCESS;
}

4156
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4157
  /* set default timestamp order information for all queries */
4158
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
hjxilinx 已提交
4159
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4160

4161
  if (isTopBottomQuery(pQueryInfo)) {
4162
    pQueryInfo->order.order = TSDB_ORDER_ASC;
4163
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4164
  } else {
4165
    pQueryInfo->order.orderColId = -1;
H
hzcheng 已提交
4166 4167
  }

H
hjxilinx 已提交
4168
  /* for super table query, set default ascending order for group output */
weixin_48148422's avatar
weixin_48148422 已提交
4169
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
4170
    pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
H
hzcheng 已提交
4171 4172 4173
  }
}

4174
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4175 4176 4177 4178
  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 已提交
4179

4180
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4181
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4182 4183 4184 4185 4186 4187

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

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4188 4189 4190 4191 4192 4193 4194

  /*
   * 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 已提交
4195
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4196
    if (pSortorder->nExpr > 1) {
4197
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4198 4199 4200
    }
  } else {
    if (pSortorder->nExpr > 2) {
4201
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212
    }
  }

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

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

S
slguan 已提交
4213 4214 4215
  SSQLToken    columnName = {pVar->nLen, pVar->nType, pVar->pz};
  SColumnIndex index = {0};

weixin_48148422's avatar
weixin_48148422 已提交
4216
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4217 4218
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4219 4220 4221 4222
    }

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

H
hjxilinx 已提交
4224 4225
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4226
      
4227 4228
      // it is a tag column
      if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
4229
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4230
      }
4231 4232
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (relTagIndex == pColIndex->colIndex) {
H
hzcheng 已提交
4233 4234
        orderByTags = true;
      }
S
slguan 已提交
4235 4236
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4237 4238
    }

S
slguan 已提交
4239
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4240 4241 4242
      orderByTS = true;
    }

4243
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
4244
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4245 4246 4247 4248 4249 4250
    } else {
      assert(!(orderByTags && orderByTS));
    }

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

4258
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4259
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4260
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
4261
        }
4262

4263 4264
        pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4265
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4266
      } else {
4267 4268
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4269 4270 4271 4272
      }
    }

    if (pSortorder->nExpr == 2) {
S
slguan 已提交
4273
      if (orderByTags) {
H
hjxilinx 已提交
4274
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4275
        pQueryInfo->groupbyExpr.orderType = pQuerySql->pSortOrder->a[0].sortOrder;
S
slguan 已提交
4276
      } else {
4277 4278
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4279 4280
      }

H
hzcheng 已提交
4281 4282
      tVariant* pVar2 = &pSortorder->a[1].pVar;
      SSQLToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4283 4284
      if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4285 4286 4287
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4288
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4289
      } else {
4290 4291
        pQueryInfo->order.order = pSortorder->a[1].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4292 4293 4294 4295
      }
    }

  } else {  // meter query
4296 4297
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4298 4299
    }

4300
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
4301
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4302 4303
    }

4304
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4305
      /* order of top/bottom query in interval is not valid  */
4306
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4307
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4308

4309
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4310
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4311
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4312
      }
4313

4314 4315
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4316 4317
      return TSDB_CODE_SUCCESS;
    }
4318

4319
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4320 4321 4322 4323 4324 4325
  }

  return TSDB_CODE_SUCCESS;
}

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

4328 4329 4330 4331 4332 4333
  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 已提交
4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349
  
  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";
  
S
slguan 已提交
4350
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4351
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4352 4353
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4356
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4357
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
4358
  }
P
plum-lihui 已提交
4359

H
Haojun Liao 已提交
4360
  if (tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql) != TSDB_CODE_SUCCESS) {
4361
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4362 4363
  }

H
hjxilinx 已提交
4364
  int32_t ret = tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
4365 4366 4367 4368
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

H
hjxilinx 已提交
4369
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4370

4371 4372
  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 已提交
4373
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
4374
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4375
    }
weixin_48148422's avatar
weixin_48148422 已提交
4376
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) {
4377
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
4378
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4379
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4380
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
4381 4382
  }

4383
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
hzcheng 已提交
4384 4385
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4386
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
4387 4388 4389
    }

    if (!validateOneTags(pCmd, &pFieldList->p[0])) {
4390
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4391
    }
H
hjxilinx 已提交
4392 4393
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4394
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
H
hjxilinx 已提交
4395
    if (tscGetNumOfTags(pTableMeta) == 1) {
4396
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
4397 4398 4399 4400
    }

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

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

4409
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
4410 4411
    SSQLToken    name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen, .type = TK_STRING};

4412
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4413
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4414 4415
    }

H
Haojun Liao 已提交
4416 4417
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
4418
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
H
Haojun Liao 已提交
4419
    } else if (index.columnIndex == numOfCols) {
4420
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
H
hzcheng 已提交
4421 4422
    }

4423 4424
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4425 4426 4427
  
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4428
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
hzcheng 已提交
4429 4430
    tVariantList* pVarList = pAlterSQL->varList;
    if (pVarList->nExpr > 2) {
4431
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4432 4433
    }

4434 4435 4436 4437
    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) {
4438
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4439 4440
    }

4441
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4442
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
4443
    }
H
hzcheng 已提交
4444

S
slguan 已提交
4445 4446
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4447

S
slguan 已提交
4448
    SSQLToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4449
    if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
4450
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4451 4452
    }

S
slguan 已提交
4453
    SSQLToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4454
    if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
4455
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4456 4457
    }

B
Bomin Zhang 已提交
4458
    char name[TSDB_COL_NAME_LEN] = {0};
H
hzcheng 已提交
4459
    strncpy(name, pVarList->a[0].pVar.pz, pVarList->a[0].pVar.nLen);
H
hjxilinx 已提交
4460 4461
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4462 4463 4464

    memset(name, 0, tListLen(name));
    strncpy(name, pVarList->a[1].pVar.pz, pVarList->a[1].pVar.nLen);
H
hjxilinx 已提交
4465 4466
    f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4467 4468
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
    // Note: update can only be applied to table not super table.
4469 4470 4471
    // the following is used to handle tags value for table created according to super table
    pCmd->command = TSDB_SQL_UPDATE_TAGS_VAL;
    
H
hzcheng 已提交
4472 4473
    tVariantList* pVarList = pAlterSQL->varList;
    tVariant*     pTagName = &pVarList->a[0].pVar;
4474
    int16_t       numOfTags = tscGetNumOfTags(pTableMeta);
H
hzcheng 已提交
4475

4476 4477
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
    SSQLToken    name = {.type = TK_STRING, .z = pTagName->pz, .n = pTagName->nLen};
4478
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4479
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4480 4481
    }

H
hjxilinx 已提交
4482
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4483
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12);
S
slguan 已提交
4484 4485
    }

H
hjxilinx 已提交
4486
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
4487
    if (tVariantDump(&pVarList->a[1].pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) {
4488
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg13);
H
hzcheng 已提交
4489
    }
4490
    
4491
    pAlterSQL->tagData.dataLen = pTagsSchema->bytes;
H
hzcheng 已提交
4492 4493

    // validate the length of binary
4494
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
4495
        (pVarList->a[1].pVar.nLen + VARSTR_HEADER_SIZE) > pTagsSchema->bytes) {
4496
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg14);
H
hzcheng 已提交
4497
    }
4498 4499 4500 4501

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

4502 4503
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4504
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4505 4506
    }

4507
    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
4508
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
H
Haojun Liao 已提交
4509 4510 4511
    pUpdateMsg->tid       = htonl(pTableMeta->sid);
    pUpdateMsg->uid       = htobe64(pTableMeta->uid);
    pUpdateMsg->colId     = htons(pTagsSchema->colId);
H
Hongze Cheng 已提交
4512
    pUpdateMsg->type      = pTagsSchema->type;
H
Haojun Liao 已提交
4513 4514
    pUpdateMsg->bytes     = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion  = htons(pTableMeta->tversion);
4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532
    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);
4533 4534 4535 4536 4537
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
4538
      len = varDataTLen(pUpdateMsg->data + schemaLen);
4539 4540 4541 4542
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
4543
    int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen;
4544
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4545
    
4546
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
hzcheng 已提交
4547 4548
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4549
      const char* msg = "only support add one column";
4550
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4551 4552 4553
    }

    if (!validateOneColumn(pCmd, &pFieldList->p[0])) {
4554
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4555
    }
H
hjxilinx 已提交
4556 4557
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4558
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
H
hjxilinx 已提交
4559
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
H
hjxilinx 已提交
4560
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15);
H
hzcheng 已提交
4561 4562 4563
    }

    if (pAlterSQL->varList->nExpr > 1) {
H
hjxilinx 已提交
4564
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4565 4566 4567 4568
    }

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

4569 4570
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
    SSQLToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4571 4572
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4573 4574
    }

4575
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4576
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18);
4577
    }
H
hzcheng 已提交
4578

B
Bomin Zhang 已提交
4579 4580
    char name1[TSDB_COL_NAME_LEN] = {0};
    tstrncpy(name1, pItem->pVar.pz, sizeof(name1));
H
hjxilinx 已提交
4581 4582
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4583 4584 4585 4586 4587
  }

  return TSDB_CODE_SUCCESS;
}

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

4592
  if (pQueryInfo->intervalTime != 0 && pQueryInfo->intervalTime < 10) {
4593
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4594
  }
H
hjxilinx 已提交
4595
  
H
hjxilinx 已提交
4596
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4597
  for (int32_t i = 0; i < size; ++i) {
4598
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
4599
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
4600
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4601 4602 4603 4604 4605 4606
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
4611
  // multi-output set/ todo refactor
H
hjxilinx 已提交
4612
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4613 4614
  
  for (int32_t k = 0; k < size; ++k) {
4615
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
4616

4617 4618 4619
    // 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 已提交
4620
      for (int32_t j = 0; j < size; ++j) {
4621
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
4622 4623 4624 4625 4626
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
4627

4628 4629 4630 4631
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4632

S
slguan 已提交
4633
    if (pExpr->functionId == TSDB_FUNC_PRJ || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4634
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4635 4636 4637
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4638 4639

  if (isProjectionFunction) {
4640
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4641 4642
  }

4643
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4644 4645 4646
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4647 4648
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4649 4650
} SDNodeDynConfOption;

H
Hui Li 已提交
4651

4652
int32_t validateEp(char* ep) {  
H
Hui Li 已提交
4653 4654 4655
  char buf[TSDB_EP_LEN + 1] = {0};
  tstrncpy(buf, ep, TSDB_EP_LEN);

4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666
  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 已提交
4667 4668
  }

4669
  return TSDB_CODE_SUCCESS;
H
Hui Li 已提交
4670 4671
}

H
hzcheng 已提交
4672 4673
int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
4674
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4675 4676
  }

4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688
  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 已提交
4689 4690 4691 4692 4693

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

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
4694 4695
    for (int32_t i = 0; i < tokenLogEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4696 4697 4698 4699
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
4700 4701 4702
  } else if ((strncasecmp(cfgOptions[tokenBalance].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenBalance].len == pOptionToken->n)) {
    SSQLToken* pValToken = &pOptions->a[2];
S
Shengliang Guan 已提交
4703 4704
    int32_t vnodeId = 0;
    int32_t dnodeId = 0;
4705
    strdequote(pValToken->z);
S
Shengliang Guan 已提交
4706
    bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId);
4707 4708 4709 4710 4711 4712
    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)) {
S
slguan 已提交
4713 4714 4715
    SSQLToken* pValToken = &pOptions->a[2];
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
4716
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
S
slguan 已提交
4717 4718
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4719 4720 4721 4722
  } else {
    SSQLToken* pValToken = &pOptions->a[2];

    int32_t val = strtol(pValToken->z, NULL, 10);
4723
    if (val < 0 || val > 256) {
H
hzcheng 已提交
4724
      /* options value is out of valid range */
4725
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4726 4727
    }

4728 4729
    for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4730 4731 4732 4733 4734 4735 4736 4737

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

4738
  return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4739 4740
}

S
slguan 已提交
4741 4742
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
4743
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4744 4745
  }

H
hjxilinx 已提交
4746 4747
  SDNodeDynConfOption LOCAL_DYNAMIC_CFG_OPTIONS[6] = {{"resetLog", 8},    {"rpcDebugFlag", 12}, {"tmrDebugFlag", 12},
                                                      {"cDebugFlag", 10}, {"uDebugFlag", 10},   {"debugFlag", 9}};
S
slguan 已提交
4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764

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

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

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
4765
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4766 4767 4768 4769 4770 4771 4772 4773 4774 4775
    }

    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;
      }
    }
  }
4776
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4777 4778
}

H
hzcheng 已提交
4779 4780 4781
int32_t validateColumnName(char* name) {
  bool ret = isKeyWord(name, strlen(name));
  if (ret) {
4782
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4783 4784
  }

S
slguan 已提交
4785
  SSQLToken token = {.z = name};
H
hzcheng 已提交
4786 4787 4788
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
4789
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4790 4791 4792 4793
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
H
Haojun Liao 已提交
4794
    token.n = strtrim(token.z);
H
hzcheng 已提交
4795 4796 4797

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
4798
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4799 4800 4801 4802 4803
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
4804
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4805 4806 4807 4808 4809 4810
    }
  }

  return TSDB_CODE_SUCCESS;
}

4811 4812
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
4813 4814 4815
    return true;
  }

H
hjxilinx 已提交
4816
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
4817 4818
}

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

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

H
hzcheng 已提交
4827
  // handle the limit offset value, validate the limit
4828
  pQueryInfo->limit = pQuerySql->limit;
4829
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4830
  pQueryInfo->slimit = pQuerySql->slimit;
4831
  
4832
  tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
4833 4834
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
4835
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
4836
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
4837 4838
  }

4839
  if (pQueryInfo->limit.limit == 0) {
4840
    tscDebug("%p limit 0, no output result", pSql);
4841
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4842
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
4843 4844
  }

H
hjxilinx 已提交
4845
  // todo refactor
weixin_48148422's avatar
weixin_48148422 已提交
4846
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
4847
    if (!tscQueryTags(pQueryInfo)) {  // local handle the super table tag query
4848
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
4849
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
4850
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
4851
        }
H
hjxilinx 已提交
4852

4853
        // for projection query on super table, all queries are subqueries
H
hjxilinx 已提交
4854 4855
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
            !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
4856
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
4857
        }
S
slguan 已提交
4858
      }
H
hzcheng 已提交
4859 4860
    }

4861
    if (pQueryInfo->slimit.limit == 0) {
4862
      tscDebug("%p slimit 0, no output result", pSql);
4863
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4864 4865 4866 4867
      return TSDB_CODE_SUCCESS;
    }

    /*
4868 4869 4870 4871
     * 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 已提交
4872
     */
H
hjxilinx 已提交
4873
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
4874 4875 4876 4877
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
4878
    // No tables included. No results generated. Query results are empty.
4879
    if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
4880
      tscDebug("%p no table in super table, no output result", pSql);
4881
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4882
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4883 4884 4885
    }

    // keep original limitation value in globalLimit
4886
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4887
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
4888

4889 4890 4891 4892 4893 4894 4895 4896 4897
    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 已提交
4898

4899 4900
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
4901
  } else {
4902
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
4903
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4904
    }
H
hjxilinx 已提交
4905
  
H
hjxilinx 已提交
4906
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
4907 4908 4909
    
    bool hasTags = false;
    bool hasOtherFunc = false;
S
slguan 已提交
4910
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
4911
    for (int32_t i = 0; i < size; ++i) {
4912
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
4913 4914 4915 4916
      if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
        hasTags = true;
      } else {
        hasOtherFunc = true;
H
hzcheng 已提交
4917 4918
      }
    }
4919 4920
    
    if (hasTags && hasOtherFunc) {
4921
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4922
    }
H
hzcheng 已提交
4923 4924 4925 4926
  }

  return TSDB_CODE_SUCCESS;
}
4927

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

4931 4932 4933
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
4934

H
hjxilinx 已提交
4935 4936 4937
  tVariantList* pKeep = pCreateDb->keep;
  if (pKeep != NULL) {
    switch (pKeep->nExpr) {
S
slguan 已提交
4938
      case 1:
H
hjxilinx 已提交
4939
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
4940 4941
        break;
      case 2: {
H
hjxilinx 已提交
4942 4943
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl(pKeep->a[1].pVar.i64Key);
4944 4945 4946
        break;
      }
      case 3: {
H
hjxilinx 已提交
4947 4948 4949
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl(pKeep->a[1].pVar.i64Key);
        pMsg->daysToKeep2 = htonl(pKeep->a[2].pVar.i64Key);
4950 4951
        break;
      }
4952
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
4953 4954
    }
  }
H
hjxilinx 已提交
4955

H
hjxilinx 已提交
4956 4957
  return TSDB_CODE_SUCCESS;
}
4958

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

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

H
hjxilinx 已提交
4964
  SSQLToken* pToken = &pCreateDbInfo->precision;
4965 4966
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
4967

4968 4969 4970 4971 4972
    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 已提交
4973
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
4974 4975
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
4976
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
4977 4978
    }
  }
H
hjxilinx 已提交
4979

H
hjxilinx 已提交
4980 4981
  return TSDB_CODE_SUCCESS;
}
4982

4983
static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
hjxilinx 已提交
4984 4985
  pMsg->maxTables = htonl(pCreateDb->maxTablesPerVnode);
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
4986
  pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
H
hjxilinx 已提交
4987
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
S
slguan 已提交
4988
  pMsg->commitTime = htonl(pCreateDb->commitTime);
H
hjxilinx 已提交
4989 4990
  pMsg->minRowsPerFileBlock = htonl(pCreateDb->minRowsPerBlock);
  pMsg->maxRowsPerFileBlock = htonl(pCreateDb->maxRowsPerBlock);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
4991
  pMsg->fsyncPeriod = htonl(pCreateDb->fsyncPeriod);
S
slguan 已提交
4992
  pMsg->compression = pCreateDb->compressionLevel;
H
hjxilinx 已提交
4993
  pMsg->walLevel = (char)pCreateDb->walLevel;
H
hjxilinx 已提交
4994
  pMsg->replications = pCreateDb->replica;
4995
  pMsg->ignoreExist = pCreateDb->ignoreExists;
H
hjxilinx 已提交
4996 4997 4998
}

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

H
hjxilinx 已提交
5002
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5003
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5004
  }
H
hjxilinx 已提交
5005

H
hjxilinx 已提交
5006
  if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5007
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5008
  }
H
hjxilinx 已提交
5009

H
hjxilinx 已提交
5010
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
5011
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5012
  }
H
hjxilinx 已提交
5013

5014
  return TSDB_CODE_SUCCESS;
H
huili 已提交
5015
}
S
slguan 已提交
5016

H
Haojun Liao 已提交
5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035
//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 已提交
5036

5037 5038
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
5039

5040 5041
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
H
hjxilinx 已提交
5042
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5043 5044
  
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, size - 1);
5045

S
slguan 已提交
5046
    if (pExpr->functionId != TSDB_FUNC_TAG) {
H
hjxilinx 已提交
5047
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
Haojun Liao 已提交
5048
      int16_t         columnInfo = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid);
5049
      SColumnIndex    index = {.tableIndex = 0, .columnIndex = columnInfo};
H
hjxilinx 已提交
5050
      SSchema*        pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5051 5052 5053 5054

      int16_t type = pSchema[index.columnIndex].type;
      int16_t bytes = pSchema[index.columnIndex].bytes;
      char*   name = pSchema[index.columnIndex].name;
H
hjxilinx 已提交
5055
  
5056
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
S
slguan 已提交
5057 5058 5059 5060
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
      SColumnList ids = {0};
H
hjxilinx 已提交
5061
      insertResultField(pQueryInfo, size, &ids, bytes, type, name, pExpr);
S
slguan 已提交
5062 5063 5064

      int32_t relIndex = index.columnIndex;

5065
      pExpr->colInfo.colIndex = relIndex;
5066 5067
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
5068

5069
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
5070
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
5071 5072 5073 5074
    }
  }
}

H
hjxilinx 已提交
5075 5076 5077
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
5078
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
5079 5080 5081
  pExpr->numOfParams = 1;
}

5082
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
5083
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
H
hjxilinx 已提交
5084
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
5085

H
Haojun Liao 已提交
5086 5087 5088 5089
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

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

H
Haojun Liao 已提交
5091
  tscAddSpecialColumnForSelect(pQueryInfo, size, TSDB_FUNC_PRJ, &colIndex, pSchema, TSDB_COL_NORMAL);
S
slguan 已提交
5092

H
Haojun Liao 已提交
5093 5094
  SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, size);
  doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
H
hjxilinx 已提交
5095
  pInfo->visible = false;
S
slguan 已提交
5096 5097
}

5098
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5099
  int32_t tagLength = 0;
H
hjxilinx 已提交
5100
  
H
hjxilinx 已提交
5101
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5102 5103
  
  for (int32_t i = 0; i < size; ++i) {
5104
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5105 5106 5107 5108 5109 5110 5111 5112 5113
    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 已提交
5114
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5115
  SSchema*        pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5116

H
hjxilinx 已提交
5117
  for (int32_t i = 0; i < size; ++i) {
5118
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5119
    if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) {
5120
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
S
slguan 已提交
5121
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, pExpr->param[0].i64Key, &pExpr->resType,
5122
                        &pExpr->resBytes, &pExpr->interBytes, tagLength, true);
S
slguan 已提交
5123 5124 5125 5126
    }
  }
}

5127
static void doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5128
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5129 5130
  
  for (int32_t i = 0; i < size; ++i) {
5131
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5132 5133
    if (pExpr->functionId == TSDB_FUNC_PRJ) {
      bool qualifiedCol = false;
5134
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5135 5136 5137
        SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
  
        if (pExpr->colInfo.colId == pColIndex->colId) {
H
hjxilinx 已提交
5138
          qualifiedCol = true;
H
hjxilinx 已提交
5139
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5140 5141 5142 5143
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
5144

H
hjxilinx 已提交
5145 5146 5147 5148 5149
      assert(qualifiedCol);
    }
  }
}

S
slguan 已提交
5150 5151
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
5152 5153 5154
    SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j);
  
    if (columnId == pColIndex->colId && pColIndex->flag == TSDB_COL_TAG) {
S
slguan 已提交
5155 5156 5157 5158 5159 5160 5161
      return true;
    }
  }

  return false;
}

5162
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5163 5164
  bool hasTagPrj = false;
  bool hasColumnPrj = false;
H
hjxilinx 已提交
5165
  
H
hjxilinx 已提交
5166
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5167
  for (int32_t i = 0; i < size; ++i) {
5168
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179
    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
5180
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5181 5182
  bool allInGroupby = true;

H
hjxilinx 已提交
5183 5184
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5185
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5186 5187 5188 5189
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5190
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5191 5192 5193 5194 5195 5196 5197 5198 5199
      allInGroupby = false;
      break;
    }
  }

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

5200
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5201
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5202 5203
  
  for (int32_t i = 0; i < size; ++i) {
5204
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216
    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.
 */
5217
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) {
S
slguan 已提交
5218
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5219
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5220

S
slguan 已提交
5221 5222 5223 5224
  bool    tagColExists = false;
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5225
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5226
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5227
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5228 5229 5230 5231 5232 5233
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
      tagColExists = true;
      break;
    }
  }
H
hjxilinx 已提交
5234

H
hjxilinx 已提交
5235
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5236
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5237 5238
  
    int16_t functionId = pExpr->functionId;
5239
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5240
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5241
      continue;
S
slguan 已提交
5242
    }
H
hjxilinx 已提交
5243

H
hjxilinx 已提交
5244 5245 5246 5247 5248 5249
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5250

H
hjxilinx 已提交
5251
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5252 5253
    // 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.
5254
    if (numOfAggregation > 0) {
5255
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5256 5257 5258 5259 5260 5261
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5262 5263
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5264 5265 5266 5267 5268
    } 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 已提交
5269 5270
      for (int32_t i = 0; i < numOfExprs; ++i) {
        
5271
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5272 5273 5274 5275 5276
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5277
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5278 5279 5280
        }
      }

5281 5282
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5283 5284
    }
  } else {
5285
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5286
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5287
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5288
      }
H
hjxilinx 已提交
5289

H
hjxilinx 已提交
5290 5291
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5292 5293
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5294
      }
S
slguan 已提交
5295 5296 5297 5298 5299 5300
    }
  }

  return TSDB_CODE_SUCCESS;
}

5301
static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5302 5303
  const char* msg2 = "interval not allowed in group by normal column";

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

H
Haojun Liao 已提交
5306
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5307
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5308 5309 5310 5311
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5312
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5313
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5314
    int16_t colIndex = pColIndex->colIndex;
5315
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5316
      type  = s.type;
H
Haojun Liao 已提交
5317
      bytes = s.bytes;
H
Haojun Liao 已提交
5318
      name  = s.name;
S
slguan 已提交
5319
    } else {
5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330
      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 已提交
5331
    }
H
hjxilinx 已提交
5332 5333 5334
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5335
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5336
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5337
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5338
      
B
Bomin Zhang 已提交
5339 5340
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5341
      
S
slguan 已提交
5342 5343 5344
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5345
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
5346
      insertResultField(pQueryInfo, size, &ids, bytes, type, name, pExpr);
S
slguan 已提交
5347 5348
    } else {
      // if this query is "group by" normal column, interval is not allowed
5349
      if (pQueryInfo->intervalTime > 0) {
5350
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5351 5352 5353
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5354
      for (int32_t j = 0; j < size; ++j) {
5355
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5356 5357 5358 5359 5360 5361 5362 5363 5364 5365
        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) {
5366
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5367 5368 5369 5370 5371 5372 5373
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5374
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5375
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5376
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5377
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5378
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5379 5380

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5381
  if (tscQueryTags(pQueryInfo)) {
5382
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5383
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5384 5385 5386 5387 5388
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5389
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5390
    // check if all the tags prj columns belongs to the group by columns
5391 5392
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5393
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5394 5395 5396
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5397 5398
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5399
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5400 5401 5402 5403 5404 5405
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5406
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5407
        bool qualified = false;
5408
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5409
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5410 5411 5412 5413 5414 5415 5416
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5417
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5418 5419 5420 5421
        }
      }

      if (IS_MULTIOUTPUT(aAggs[functId].nStatus) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM &&
H
hjxilinx 已提交
5422
          functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) {
5423
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5424 5425
      }

5426
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5427
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5428 5429 5430
      }
    }

5431
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5432
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5433 5434 5435 5436 5437 5438
    }

    /*
     * group by tag function must be not changed the function name, otherwise, the group operation may fail to
     * divide the subset of final result.
     */
5439
    if (doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5440
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5441 5442
    }

H
hjxilinx 已提交
5443
    // projection query on super table does not compatible with "group by" syntax
5444
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5445
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5446
    }
H
hjxilinx 已提交
5447

H
hjxilinx 已提交
5448
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5449
  } else {
5450
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5451 5452
  }
}
H
hjxilinx 已提交
5453

5454
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5455 5456 5457
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5458

H
hjxilinx 已提交
5459 5460
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5461
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5462
  }
H
hjxilinx 已提交
5463

H
hjxilinx 已提交
5464 5465
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5466
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hjxilinx 已提交
5467
  }
H
hjxilinx 已提交
5468

H
hjxilinx 已提交
5469
  // TODO redefine the function
H
hjxilinx 已提交
5470 5471 5472 5473 5474 5475
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5476
  int32_t index = -1;
H
hjxilinx 已提交
5477
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5478
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5479
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5480 5481 5482 5483
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5484 5485 5486

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5487
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5488
    case 1:
H
Haojun Liao 已提交
5489 5490 5491
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5492
    case 3:
H
Haojun Liao 已提交
5493
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5494
    case 4:
H
Haojun Liao 已提交
5495
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5496
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5497
  }
5498 5499 5500 5501 5502 5503
  
  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 已提交
5504
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5505 5506
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5507
}
H
hjxilinx 已提交
5508 5509

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

H
hjxilinx 已提交
5513 5514
  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);
5515
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5516
  }
H
hjxilinx 已提交
5517

H
hjxilinx 已提交
5518
  if (pCreate->replications != -1 &&
5519
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5520
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5521
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5522
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5523
  }
H
hjxilinx 已提交
5524

H
hjxilinx 已提交
5525
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5526
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5527
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5528
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5529
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5530
  }
H
hjxilinx 已提交
5531

H
hjxilinx 已提交
5532 5533 5534 5535
  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);
5536
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5537
  }
H
hjxilinx 已提交
5538

H
hjxilinx 已提交
5539
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5540
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5541
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5542
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5543
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5544
  }
H
hjxilinx 已提交
5545 5546 5547 5548

  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);
5549
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5550
  }
H
hjxilinx 已提交
5551

H
hjxilinx 已提交
5552
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5553
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5554
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5555
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5556
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5557
  }
H
hjxilinx 已提交
5558

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5559 5560 5561 5562 5563 5564 5565
  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 已提交
5566
  if (pCreate->compression != -1 &&
S
slguan 已提交
5567
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5568
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5569
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5570
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5571
  }
H
hjxilinx 已提交
5572

H
hjxilinx 已提交
5573 5574
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5575 5576

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

H
hjxilinx 已提交
5580 5581
  int32_t size = tscSqlExprNumOfExprs(pQueryInfo);
  if (size == 0) {
H
hjxilinx 已提交
5582 5583
    return;
  }
H
hjxilinx 已提交
5584

H
hjxilinx 已提交
5585
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5586 5587

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

H
hjxilinx 已提交
5590 5591
  offset += sprintf(str, "num:%d [", size);
  for (int32_t i = 0; i < size; ++i) {
5592
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5593

L
lihui 已提交
5594
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5595 5596 5597
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5598 5599 5600
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
5602
    if (i < size - 1) {
H
hjxilinx 已提交
5603 5604 5605
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5606

H
hjxilinx 已提交
5607
  str[offset] = ']';
5608
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5609
}
5610

5611
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5612 5613 5614
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5615 5616
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5617
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;

  tFieldList* pFieldList = pCreateTable->colInfo.pColumns;
  tFieldList* pTagList = pCreateTable->colInfo.pTagColumns;

  assert(pFieldList != NULL);

  // if sql specifies db, use it, otherwise use default db
  SSQLToken* pzTableName = &(pCreateTable->name);

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5630
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5631 5632
  }

H
Haojun Liao 已提交
5633
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5634
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5635 5636 5637 5638
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
5639
    return TSDB_CODE_TSC_INVALID_SQL;
5640 5641 5642 5643
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
H
hjxilinx 已提交
5644
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[col]);
5645 5646 5647 5648
  }

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

H
hjxilinx 已提交
5649
  if (pTagList != NULL) {  // create super table[optional]
5650
    for (int32_t i = 0; i < pTagList->nField; ++i) {
H
hjxilinx 已提交
5651
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pTagList->p[i]);
5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668
    }

    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;
5669 5670 5671
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
5672 5673 5674
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
5675 5676 5677 5678

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

H
hjxilinx 已提交
5679
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5680 5681 5682 5683 5684

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

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5685
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5686 5687
  }

H
Haojun Liao 已提交
5688
  if (tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5689
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5690 5691 5692
  }

  // get meter meta from mnode
B
Bomin Zhang 已提交
5693
  tstrncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, sizeof(pCreateTable->usingInfo.tagdata.name));
5694 5695
  tVariantList* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;

H
hjxilinx 已提交
5696
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5697 5698 5699 5700
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5701
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5702
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5703 5704 5705
  }

  // too long tag values will return invalid sql, not be truncated automatically
H
hjxilinx 已提交
5706
  SSchema* pTagSchema = tscGetTableTagSchema(pStableMeterMetaInfo->pTableMeta);
5707

5708
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
B
Bomin Zhang 已提交
5709 5710 5711 5712 5713
  SKVRowBuilder kvRowBuilder = {0};
  if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
hjxilinx 已提交
5714
  int32_t ret = TSDB_CODE_SUCCESS;
5715
  for (int32_t i = 0; i < pList->nExpr; ++i) {
B
Bomin Zhang 已提交
5716 5717
    SSchema* pSchema = pTagSchema + i;
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
H
hjxilinx 已提交
5718
      // validate the length of binary
B
Bomin Zhang 已提交
5719
      if (pList->a[i].pVar.nLen + VARSTR_HEADER_SIZE > pSchema->bytes) {
B
Bomin Zhang 已提交
5720
        tdDestroyKVRowBuilder(&kvRowBuilder);
H
hjxilinx 已提交
5721 5722 5723 5724
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
    
B
Bomin Zhang 已提交
5725 5726
    char tagVal[TSDB_MAX_TAGS_LEN];
    ret = tVariantDump(&(pList->a[i].pVar), tagVal, pSchema->type, true);
5727
    if (ret != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
5728
      tdDestroyKVRowBuilder(&kvRowBuilder);
5729
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5730 5731
    }

B
Bomin Zhang 已提交
5732
    tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
5733 5734
  }

B
Bomin Zhang 已提交
5735
  SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
B
Bomin Zhang 已提交
5736 5737 5738 5739 5740
  tdDestroyKVRowBuilder(&kvRowBuilder);
  if (row == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  tdSortKVRowByColIdx(row);
B
Bomin Zhang 已提交
5741
  pTag->dataLen = kvRowLen(row);
B
Bomin Zhang 已提交
5742
  kvRowCpy(pTag->data, row);
B
Bomin Zhang 已提交
5743 5744
  free(row);

5745 5746
  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5747
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5748 5749
  }

H
hjxilinx 已提交
5750
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
5751
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764
  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 已提交
5765 5766
  const char* msg6 = "from missing in subclause";
  
5767
  SSqlCmd*    pCmd = &pSql->cmd;
5768
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5769 5770
  assert(pQueryInfo->numOfTables == 1);

5771
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5772
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5773 5774 5775 5776 5777 5778

  // if sql specifies db, use it, otherwise use default db
  SSQLToken* pzTableName = &(pCreateTable->name);
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5779
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5780
  }
H
Haojun Liao 已提交
5781
  
5782
  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
H
Haojun Liao 已提交
5783 5784 5785 5786 5787
  if (pSrcMeterName == NULL || pSrcMeterName->nExpr == 0) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
  tVariant* pVar = &pSrcMeterName->a[0].pVar;
5788 5789
  SSQLToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
5790
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5791 5792
  }

H
Haojun Liao 已提交
5793
  if (tscSetTableFullName(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5794
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5795 5796
  }

H
hjxilinx 已提交
5797
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5798 5799 5800 5801
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
5802
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
5803
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5804
    return TSDB_CODE_TSC_INVALID_SQL;
5805 5806 5807
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5808
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5809
      return TSDB_CODE_TSC_INVALID_SQL;
5810 5811 5812 5813
    }
  }

  // set interval value
5814
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5815
    return TSDB_CODE_TSC_INVALID_SQL;
5816
  } else {
5817
    if ((pQueryInfo->intervalTime > 0) &&
5818
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
5819
      return TSDB_CODE_TSC_INVALID_SQL;
5820 5821 5822 5823
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
5824
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5825
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5826 5827 5828
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5829
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5830 5831
  }

5832
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5833
    return TSDB_CODE_TSC_INVALID_SQL;
5834 5835
  }

H
hjxilinx 已提交
5836
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5837

5838
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5839
    return TSDB_CODE_TSC_INVALID_SQL;
5840 5841 5842 5843 5844 5845 5846
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
5847
    if (pQueryInfo->intervalTime == 0) {
5848
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
5849 5850 5851 5852 5853 5854
    }

    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))) {
5855
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5856 5857 5858 5859 5860
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
5861
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
  assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0));

  const char* msg0 = "invalid table name";
  const char* msg1 = "table name too long";
  const char* msg2 = "point interpolation query needs timestamp";
  const char* msg5 = "fill only available for interval query";
  const char* msg6 = "start(end) time of query range required or time range too large";
  const char* msg7 = "illegal number of tables in from clause";
  const char* msg8 = "too many columns in selection clause";
  const char* msg9 = "TWA query requires both the start and end time";
H
Haojun Liao 已提交
5876
  const char* msg10= "too many tables in from clause";
5877 5878

  int32_t code = TSDB_CODE_SUCCESS;
5879

5880
  SSqlCmd* pCmd = &pSql->cmd;
5881

5882
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
5883
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5884
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
5885
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
5886
  }
H
hjxilinx 已提交
5887

H
Haojun Liao 已提交
5888 5889
  assert(pCmd->clauseIndex == index);

5890 5891
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
5892
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904
  }

  /*
   * 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);
5905
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
5906 5907 5908
  }

  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM) {
5909
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
5910 5911
  }

5912
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
5913

H
Haojun Liao 已提交
5914 5915 5916 5917
  if (pQuerySql->from->nExpr > 2) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

5918 5919 5920 5921 5922
  // set all query tables, which are maybe more than one.
  for (int32_t i = 0; i < pQuerySql->from->nExpr; ++i) {
    tVariant* pTableItem = &pQuerySql->from->a[i].pVar;

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
5923
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5924 5925 5926 5927 5928 5929
    }

    pTableItem->nLen = strdequote(pTableItem->pz);

    SSQLToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
5930
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5931 5932
    }

5933
    if (pQueryInfo->numOfTables <= i) {  // more than one table
H
hjxilinx 已提交
5934
      tscAddEmptyMetaInfo(pQueryInfo);
5935 5936
    }

H
hjxilinx 已提交
5937
    STableMetaInfo* pMeterInfo1 = tscGetMetaInfo(pQueryInfo, i);
5938

5939
    SSQLToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
5940
    if (tscSetTableFullName(pMeterInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
5941
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5942 5943
    }

H
hjxilinx 已提交
5944
    code = tscGetTableMeta(pSql, pMeterInfo1);
5945 5946 5947 5948 5949
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

5950
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr);
H
hjxilinx 已提交
5951
  bool isSTable = false;
H
hjxilinx 已提交
5952
  
weixin_48148422's avatar
weixin_48148422 已提交
5953
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
5954 5955 5956 5957 5958 5959 5960
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
5961 5962
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
5963
  }
5964

5965
  // parse the group by clause in the first place
5966
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
5967
    return TSDB_CODE_TSC_INVALID_SQL;
5968 5969
  }

5970
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5971
    return TSDB_CODE_TSC_INVALID_SQL;
5972 5973 5974
  }

  // set interval value
5975
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5976
    return TSDB_CODE_TSC_INVALID_SQL;
5977
  } else {
5978
    if ((pQueryInfo->intervalTime > 0) &&
5979
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
5980
      return TSDB_CODE_TSC_INVALID_SQL;
5981 5982 5983 5984
    }
  }

  // set order by info
5985
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
5986
    return TSDB_CODE_TSC_INVALID_SQL;
5987 5988 5989
  }

  // set where info
H
hjxilinx 已提交
5990
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
5991
  
5992
  if (pQuerySql->pWhere != NULL) {
5993
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5994
      return TSDB_CODE_TSC_INVALID_SQL;
5995 5996 5997
    }

    pQuerySql->pWhere = NULL;
H
hjxilinx 已提交
5998
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
5999 6000
      pQueryInfo->window.skey = pQueryInfo->window.skey / 1000;
      pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000;
6001 6002
    }
  } else {  // set the time rang
H
Haojun Liao 已提交
6003
    pQueryInfo->window = TSWINDOW_INITIALIZER;
6004 6005 6006
  }

  // user does not specified the query time window, twa is not allowed in such case.
H
Haojun Liao 已提交
6007
  if ((pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX ||
H
hjxilinx 已提交
6008
       (pQueryInfo->window.ekey == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
6009
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
6010 6011 6012
  }

  // no result due to invalid query time range
H
hjxilinx 已提交
6013
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6014
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6015 6016 6017
    return TSDB_CODE_SUCCESS;
  }

6018
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6019
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6020 6021 6022
  }

  // in case of join query, time range is required.
6023
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
H
hjxilinx 已提交
6024
    int64_t timeRange = labs(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6025

H
hjxilinx 已提交
6026
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6027
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6028 6029 6030
    }
  }

6031
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6032 6033 6034
    return code;
  }

6035
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6036 6037 6038
    return code;
  }

6039
  setColumnOffsetValueInResultset(pQueryInfo);
6040

6041 6042 6043 6044 6045
  /*
   * 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) {
6046
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6047 6048
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6049

6050
    if (pQueryInfo->intervalTime > 0) {
H
hjxilinx 已提交
6051
      int64_t timeRange = labs(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6052
      // number of result is not greater than 10,000,000
6053
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_RETRIEVE_ROWS_IN_INTERVAL_QUERY) {
6054
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6055 6056
      }
    }
H
hjxilinx 已提交
6057

6058
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6059 6060 6061 6062
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6063 6064 6065

  return TSDB_CODE_SUCCESS;  // Does not build query message here
}
H
hjxilinx 已提交
6066

6067
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols) {
H
hjxilinx 已提交
6068 6069
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6070
  
6071
  if (pSqlExpr->pLeft != NULL) {
6072
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6073 6074 6075 6076 6077
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6078
  if (pSqlExpr->pRight != NULL) {
6079
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6080 6081 6082 6083 6084
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6085
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6086
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6087
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6088
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6089 6090 6091
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6092
      return TSDB_CODE_SUCCESS;
6093
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6094
      // arithmetic expression on the results of aggregation functions
6095
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6096
      (*pExpr)->nodeType = TSQL_NODE_COL;
6097 6098 6099
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6100
      // set the input column data byte and type.
H
hjxilinx 已提交
6101 6102 6103 6104 6105 6106 6107 6108
      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) {
          (*pExpr)->pSchema->type = p1->resType;
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
hjxilinx 已提交
6109 6110 6111
          break;
        }
      }
6112
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6113
      SColumnIndex index = {0};
6114
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
  
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      
      STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6126 6127 6128
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6129
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6130 6131 6132 6133 6134
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
        
        taosArrayPush(pCols, &colIndex);
      }
6135
      
H
hjxilinx 已提交
6136
      return TSDB_CODE_SUCCESS;
6137
    } else {
6138
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6139 6140 6141
    }
    
  } else {
H
hjxilinx 已提交
6142
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6143 6144
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6145 6146 6147
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6148 6149
    
    SSQLToken t = {.type = pSqlExpr->nSQLOptr};
H
[td-32]  
hjxilinx 已提交
6150
    (*pExpr)->_node.optr = getBinaryExprOptr(&t);
6151
    
H
[td-32]  
hjxilinx 已提交
6152
    assert((*pExpr)->_node.optr != 0);
H
hjxilinx 已提交
6153
    
H
[td-32]  
hjxilinx 已提交
6154
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6155 6156
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6157
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6158
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6159
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6160 6161 6162
        }
      }
    }
H
Hui Li 已提交
6163

6164
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6165 6166
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
      if (pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6167 6168 6169
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6170 6171
      }
    }
H
hjxilinx 已提交
6172 6173 6174
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6175
}