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

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

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

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

H
Haojun Liao 已提交
36 37
// -1 is tbname column index, so here use the -3 as the initial value
#define COLUMN_INDEX_INITIAL_VAL (-3)
S
slguan 已提交
38 39 40 41
#define COLUMN_INDEX_INITIALIZER \
  { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL }
#define COLUMN_INDEX_VALIDE(index) (((index).tableIndex >= 0) && ((index).columnIndex >= TSDB_TBNAME_COLUMN_INDEX))
#define TBNAME_LIST_SEP ","
H
hzcheng 已提交
42

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

114
static int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo);
115 116 117
static int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo);
static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo);
static int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index);
118
static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols);
H
hjxilinx 已提交
119

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

154 155 156 157 158 159
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) {
160
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
161 162 163
  }

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

198 199 200 201 202 203 204 205
  pCmd->command = pInfo->type;

  switch (pInfo->type) {
    case TSDB_SQL_DROP_TABLE:
    case TSDB_SQL_DROP_USER:
    case TSDB_SQL_DROP_ACCT:
    case TSDB_SQL_DROP_DNODE:
    case TSDB_SQL_DROP_DB: {
206
      const char* msg2 = "invalid name";
207
      const char* msg3 = "param name too long";
H
hzcheng 已提交
208 209

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

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

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

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

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

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

239 240
      break;
    }
H
hzcheng 已提交
241

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

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

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

      break;
    }

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

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

267 268 269 270 271 272 273 274
      break;
    }

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

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

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

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

      break;
    }

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

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

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

304 305 306 307 308
    case TSDB_SQL_CREATE_ACCT:
    case TSDB_SQL_ALTER_ACCT: {
      const char* msg1 = "invalid state option, available options[no, r, w, all]";
      const char* msg2 = "invalid user/account name";
      const char* msg3 = "name too long";
H
hzcheng 已提交
309

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

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

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

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

      SCreateAcctSQL* pAcctOpt = &pInfo->pDCLInfo->acctOpt;
326
      if (pAcctOpt->stat.n > 0) {
H
hzcheng 已提交
327 328 329 330 331
        if (pAcctOpt->stat.z[0] == 'r' && pAcctOpt->stat.n == 1) {
        } else if (pAcctOpt->stat.z[0] == 'w' && pAcctOpt->stat.n == 1) {
        } else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) {
        } else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) {
        } else {
332
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
333 334
        }
      }
335

H
hzcheng 已提交
336 337 338
      break;
    }

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

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

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

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

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

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

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

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

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

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

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

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

384 385 386 387
      if (pDCL->nTokens == 3) {
        pCfg->config[pDCL->a[1].n] = ' ';  // add sep
        strncpy(&pCfg->config[pDCL->a[1].n + 1], pDCL->a[2].z, pDCL->a[2].n);
      }
H
hzcheng 已提交
388

389 390
      break;
    }
H
hzcheng 已提交
391

392 393 394 395 396 397
    case TSDB_SQL_CREATE_USER:
    case TSDB_SQL_ALTER_USER: {
      const char* msg5 = "invalid user rights";
      const char* msg7 = "not support options";
      const char* msg2 = "invalid user/account name";
      const char* msg3 = "name too long";
H
hzcheng 已提交
398

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

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

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

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

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

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

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

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

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

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

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

      break;
    }

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

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

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

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

      break;
    }

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

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

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

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

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

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

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

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

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

      break;
    }

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

      break;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

727 728 729 730 731
  /*
   * the old name exists and is not equalled to the new name. Release the metermeta/metricmeta
   * that are corresponding to the old name for the new table name.
   */
  if (size > 0) {
H
hjxilinx 已提交
732
    if (strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
733
      tscClearTableMetaInfo(pTableMetaInfo, false);
734 735
    }
  } else {
H
hjxilinx 已提交
736
    assert(pTableMetaInfo->pTableMeta == NULL);
737
  }
H
hjxilinx 已提交
738

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

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

746 747 748 749 750 751 752
  const char* msg = "illegal number of columns";
  const char* msg1 = "first column must be timestamp";
  const char* msg2 = "row length exceeds max length";
  const char* msg3 = "duplicated column names";
  const char* msg4 = "invalid data types";
  const char* msg5 = "invalid binary/nchar column length";
  const char* msg6 = "invalid column name";
H
hzcheng 已提交
753 754 755

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

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

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

  // max row length must be less than TSDB_MAX_BYTES_PER_ROW
  if (nLen > TSDB_MAX_BYTES_PER_ROW) {
777
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
778 779 780 781 782 783 784
    return false;
  }

  // field name must be unique
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
    TAOS_FIELD* pField = &pFieldList->p[i];
    if (pField->type < TSDB_DATA_TYPE_BOOL || pField->type > TSDB_DATA_TYPE_NCHAR) {
785
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
786 787 788 789 790
      return false;
    }

    if ((pField->type == TSDB_DATA_TYPE_BINARY && (pField->bytes <= 0 || pField->bytes > TSDB_MAX_BINARY_LEN)) ||
        (pField->type == TSDB_DATA_TYPE_NCHAR && (pField->bytes <= 0 || pField->bytes > TSDB_MAX_NCHAR_LEN))) {
791
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
792 793 794 795
      return false;
    }

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

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

  return true;
}

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

812 813 814 815 816 817 818
  const char* msg1 = "invalid number of tag columns";
  const char* msg2 = "tag length too long";
  const char* msg3 = "duplicated column names";
  const char* msg4 = "timestamp not allowed in tags";
  const char* msg5 = "invalid data type in tags";
  const char* msg6 = "invalid tag name";
  const char* msg7 = "invalid binary/nchar tag length";
H
hzcheng 已提交
819 820 821

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

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

  // max tag row length must be less than TSDB_MAX_TAGS_LEN
  if (nLen > TSDB_MAX_TAGS_LEN) {
837
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
838 839 840 841 842 843
    return false;
  }

  // field name must be unique
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
    if (has(pFieldList, 0, pTagsList->p[i].name) == true) {
844
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
845 846 847 848 849 850 851
      return false;
    }
  }

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

    if (pTagsList->p[i].type < TSDB_DATA_TYPE_BOOL || pTagsList->p[i].type > TSDB_DATA_TYPE_NCHAR) {
857
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
858 859 860 861 862
      return false;
    }

    if ((pTagsList->p[i].type == TSDB_DATA_TYPE_BINARY && pTagsList->p[i].bytes <= 0) ||
        (pTagsList->p[i].type == TSDB_DATA_TYPE_NCHAR && pTagsList->p[i].bytes <= 0)) {
863
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
864 865 866 867
      return false;
    }

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

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

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
885 886 887 888 889 890
  const char* msg1 = "timestamp not allowed in tags";
  const char* msg2 = "duplicated column names";
  const char* msg3 = "tag length too long";
  const char* msg4 = "invalid tag name";
  const char* msg5 = "invalid binary/nchar tag length";
  const char* msg6 = "invalid data type in tags";
H
hzcheng 已提交
891

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

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

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

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

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

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

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

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

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

  // tags name can not be a keyword
  if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) {
935
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
936 937 938 939 940
    return false;
  }

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

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

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

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
959 960 961 962 963 964
  const char* msg1 = "too many columns";
  const char* msg2 = "duplicated column names";
  const char* msg3 = "column length too long";
  const char* msg4 = "invalid data types";
  const char* msg5 = "invalid column name";
  const char* msg6 = "invalid column length";
H
hzcheng 已提交
965

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

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

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

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

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

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

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

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

  return true;
}

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

  return false;
}

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

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

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

  return false;
}

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

  if (account != NULL) {
S
TD-1057  
Shengliang Guan 已提交
1050
    int32_t len = (int32_t)strlen(account);
H
hzcheng 已提交
1051 1052 1053 1054 1055 1056 1057
    strcpy(fullName, account);
    fullName[len] = TS_PATH_DELIMITER[0];
    totalLen += (len + 1);
  }

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

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

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

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

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

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

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

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

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

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

1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
  const char* msg1 = "invalid column name, or illegal column type";
  const char* msg2 = "invalid arithmetic expression in select clause";
  const char* msg3 = "tag columns can not be used in arithmetic expression";
  const char* msg4 = "columns from different table mixed up in arithmetic expression";

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

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

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

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

  // todo potential data overflow
S
Shengliang Guan 已提交
1128
  char* arithmeticExprStr = malloc(1024*1024);
1129 1130 1131 1132 1133 1134 1135 1136
  char* p = arithmeticExprStr;

  if (arithmeticType == NORMAL_ARITHMETIC) {
    pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;

    // all columns in arithmetic expression must belong to the same table
    for (int32_t f = 1; f < columnList.num; ++f) {
      if (columnList.ids[f].tableIndex != tableIndex) {
S
Shengliang Guan 已提交
1137
        taosTFree(arithmeticExprStr);
1138 1139 1140 1141 1142
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
      }
    }

    if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
S
Shengliang Guan 已提交
1143
      taosTFree(arithmeticExprStr);
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161
      return TSDB_CODE_TSC_INVALID_SQL;
    }

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

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

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

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

    int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
    if (ret != TSDB_CODE_SUCCESS) {
      tExprTreeDestroy(&pNode, NULL);
S
Shengliang Guan 已提交
1162
      taosTFree(arithmeticExprStr);
1163 1164 1165 1166 1167 1168 1169
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }

    size_t numOfNode = taosArrayGetSize(colList);
    for(int32_t k = 0; k < numOfNode; ++k) {
      SColIndex* pIndex = taosArrayGet(colList, k);
      if (pIndex->flag == 1) {
S
Shengliang Guan 已提交
1170
        taosTFree(arithmeticExprStr);
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }

    SBufferWriter bw = tbufInitWriter(NULL, false);

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

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

    // set the serialized binary string as the parameter of arithmetic expression
S
Shengliang Guan 已提交
1189
    addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len, index.tableIndex);
1190 1191 1192 1193 1194 1195 1196

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

    taosArrayDestroy(colList);
    tExprTreeDestroy(&pNode, NULL);
  } else {
    if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
S
Shengliang Guan 已提交
1197
      taosTFree(arithmeticExprStr);
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220
      return TSDB_CODE_TSC_INVALID_SQL;
    }

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

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

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

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

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

      int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
      if (ret != TSDB_CODE_SUCCESS) {
        tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
S
Shengliang Guan 已提交
1221
        taosTFree(arithmeticExprStr);
1222 1223 1224 1225 1226 1227 1228
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
      }

      pInfo->pArithExprInfo = pArithExprInfo;
    }
  }

S
Shengliang Guan 已提交
1229
  taosTFree(arithmeticExprStr);
1230 1231 1232
  return TSDB_CODE_SUCCESS;
}

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

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

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

1242 1243 1244
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
H
Haojun Liao 已提交
1245

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

S
slguan 已提交
1250
    // project on all fields
H
Haojun Liao 已提交
1251 1252 1253
    int32_t optr = pItem->pNode->nSQLOptr;

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

S
slguan 已提交
1259 1260 1261 1262
      // if the name of column is quoted, remove it and set the right information for later process
      extractColumnNameFromString(pItem);

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

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
1273 1274 1275
      int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
1276
      }
1277

H
hzcheng 已提交
1278 1279 1280 1281 1282
    } else {
      /*
       * not support such expression
       * e.g., select 12+5 from table_name
       */
1283
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1284 1285
    }

H
hjxilinx 已提交
1286
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1287
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1288 1289 1290
    }
  }

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

  return pExpr;
S
slguan 已提交
1397 1398
}

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

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

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

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

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

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

  return numOfTotalColumns;
}

H
Haojun Liao 已提交
1429 1430 1431 1432 1433
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tscColumnListInsert(pQueryInfo->colList, &tsCol);
}

1434
int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExprItem* pItem) {
S
slguan 已提交
1435
  const char* msg0 = "invalid column name";
H
hjxilinx 已提交
1436
  const char* msg1 = "tag for normal table query is not allowed";
H
hjxilinx 已提交
1437
  
S
TD-1057  
Shengliang Guan 已提交
1438
  int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
1439

H
Haojun Liao 已提交
1440 1441 1442 1443 1444
  int32_t optr = pItem->pNode->nSQLOptr;

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

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

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

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

H
Haojun Liao 已提交
1466 1467 1468 1469
    // user-specified constant value as a new result column
    if ((optr == TK_INTEGER || optr == TK_FLOAT) || (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
      index.columnIndex = TSDB_UD_COLUMN_INDEX;
      index.tableIndex = 0;
H
hzcheng 已提交
1470

H
Haojun Liao 已提交
1471 1472 1473 1474
      SSchema colSchema = tGetUserSpecifiedColumnSchema(pItem->pNode->val.pz, pItem->pNode->val.nType, pItem->aliasName);
      SSqlExpr* pExpr = tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC);
      pExpr->numOfParams = 1;
      tVariantAssign(&pExpr->param[0], &pItem->pNode->val);
H
hzcheng 已提交
1475

H
Haojun Liao 已提交
1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
    } else { // columns from the queried table
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY);

      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        SSchema colSchema = tGetTableNameColumnSchema();
        tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG);
      } else {
        STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
        STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;

        if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
        }

        addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
hzcheng 已提交
1491 1492
      }

H
Haojun Liao 已提交
1493 1494
      // add the primary timestamp column even though it is not required by user
      tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
hzcheng 已提交
1495
    }
H
Haojun Liao 已提交
1496

H
hzcheng 已提交
1497
  } else {
1498
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1499 1500 1501 1502 1503
  }

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

S
slguan 已提交
1588 1589 1590 1591 1592 1593
        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;

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

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

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

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

S
slguan 已提交
1616
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1617
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1618
        }
S
slguan 已提交
1619 1620 1621
      } else {  // count(*) is equalled to count(primary_timestamp_key)
        index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
        int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
1622
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1623
      }
H
Haojun Liao 已提交
1624 1625 1626

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

H
hjxilinx 已提交
1627
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1628
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1629
      
S
slguan 已提交
1630
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1631 1632 1633 1634 1635
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
        insertResultField(pQueryInfo, numOfOutput, &ids, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->aliasName, pExpr);
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1636
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1637 1638
        }
      }
H
Haojun Liao 已提交
1639 1640

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

S
slguan 已提交
1645
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1646 1647 1648
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1649 1650 1651 1652 1653 1654
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1655
    case TK_TWA:
H
hzcheng 已提交
1656 1657 1658 1659 1660 1661 1662 1663 1664
    case TK_MIN:
    case TK_MAX:
    case TK_DIFF:
    case TK_STDDEV:
    case TK_LEASTSQUARES: {
      // 1. valid the number of parameters
      if (pItem->pNode->pParam == NULL || (optr != TK_LEASTSQUARES && pItem->pNode->pParam->nExpr != 1) ||
          (optr == TK_LEASTSQUARES && pItem->pNode->pParam->nExpr != 3)) {
        /* no parameters or more than one parameter for function */
1665
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1666 1667 1668 1669
      }

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

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

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

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

      int16_t resultType = 0;
      int16_t resultSize = 0;
1690
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1691 1692 1693

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            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 已提交
1836 1837
          }
        }
1838
        
S
slguan 已提交
1839 1840 1841 1842
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

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

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

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

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

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

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
1879
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1880
      }
H
hjxilinx 已提交
1881
      
S
slguan 已提交
1882
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1883 1884
      if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1885 1886
      }

H
hjxilinx 已提交
1887
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1888
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1889 1890

      // functions can not be applied to tags
H
hjxilinx 已提交
1891
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1892
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1893 1894 1895
      }

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

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
1903
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1904 1905 1906 1907
      }

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

S
slguan 已提交
1908 1909
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1910

H
hjxilinx 已提交
1911
      char    val[8] = {0};
H
hjxilinx 已提交
1912 1913
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
1914
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
1915
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
1916

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

        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) {
1932
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1933
        }
dengyihao's avatar
dengyihao 已提交
1934 1935
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
        colIndex += 1;  // the first column is ts
H
hzcheng 已提交
1936

1937
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1938
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1939
      } else {
1940
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
1941

H
Haojun Liao 已提交
1942
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
1943
        if (nTop <= 0 || nTop > 100) {  // todo use macro
1944
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1945 1946 1947 1948
        }

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

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

H
Haojun Liao 已提交
1959
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
1960
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
1961
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
1962
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
1963

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

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

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

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

      int32_t ret = getResultDataInfo(s.type, s.bytes, TSDB_FUNC_TID_TAG, 0, &type, &bytes, &inter, 0, 0);
      assert(ret == TSDB_CODE_SUCCESS);
      
S
TD-1057  
Shengliang Guan 已提交
2045
      s.type = (uint8_t)type;
2046 2047 2048 2049 2050
      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 已提交
2051
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2052
    }
2053
    
H
hzcheng 已提交
2054
    default:
2055
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2056
  }
2057
  
H
hzcheng 已提交
2058 2059
}

S
slguan 已提交
2060 2061
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
H
Haojun Liao 已提交
2062
  assert(num == 1 && columnIndex >= -2 && tableIndex >= 0);
S
slguan 已提交
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073

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

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

H
hjxilinx 已提交
2099 2100
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2101 2102 2103 2104 2105 2106 2107 2108 2109 2110

  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 已提交
2111
      break;
S
slguan 已提交
2112 2113 2114 2115 2116 2117
    }
  }

  return columnIndex;
}

2118
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2119 2120 2121 2122 2123 2124 2125 2126 2127 2128
  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) {
2129 2130
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2131 2132 2133

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

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2149
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2150 2151 2152 2153 2154 2155
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2156
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2157 2158 2159
  }
}

H
hjxilinx 已提交
2160
int32_t getTableIndexImpl(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2161
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2162
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2163 2164 2165 2166 2167 2168 2169
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

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

  if (pIndex->tableIndex < 0) {
2180
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2181 2182 2183 2184 2185
  }

  return TSDB_CODE_SUCCESS;
}

2186
int32_t getTableIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2187 2188 2189
  SSQLToken tableToken = {0};
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2190
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2191
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2192 2193
  }

S
slguan 已提交
2194 2195
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2196

2197
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2198
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2199
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2200 2201
  }

S
slguan 已提交
2202 2203
  SSQLToken tmpToken = *pToken;

2204
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2205
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2206 2207
  }

2208
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221
}

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

H
hzcheng 已提交
2297 2298
  pCmd->command = TSDB_SQL_SHOW;

2299
  const char* msg1 = "invalid name";
2300
  const char* msg2 = "pattern filter string too long";
2301 2302 2303 2304
  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 已提交
2305 2306 2307 2308 2309

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2310 2311 2312
  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 已提交
2313
    // db prefix in tagCond, show table conds in payload
2314 2315
    SSQLToken* pDbPrefixToken = &pShowInfo->prefix;
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2316

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

2321
      if (pDbPrefixToken->n <= 0) {
2322
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2323 2324
      }

2325
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2326
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2327 2328
      }

H
hjxilinx 已提交
2329
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2330
      if (ret != TSDB_CODE_SUCCESS) {
2331
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2332
      }
2333
    }
H
hzcheng 已提交
2334

2335 2336 2337 2338
    // 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 已提交
2339

2340
      if (pPattern->n <= 0) {
2341
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2342
      }
H
hzcheng 已提交
2343

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

L
lihui 已提交
2353
    // show vnodes may be ip addr of dnode in payload
2354
    SSQLToken* pDnodeIp = &pShowInfo->prefix;
B
Bomin Zhang 已提交
2355
    if (pDnodeIp->n >= TSDB_IPv4ADDR_LEN) {  // ip addr is too long
2356
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2357
    }
L
lihui 已提交
2358

2359
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2360
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2361
    }
H
hzcheng 已提交
2362 2363 2364 2365 2366
  }

  return TSDB_CODE_SUCCESS;
}

2367 2368 2369 2370
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 已提交
2371

2372 2373
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2374
  
2375 2376
  SSQLToken* idStr = &(pInfo->pDCLInfo->ip);
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2377
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2378 2379
  }

2380
  strncpy(pCmd->payload, idStr->z, idStr->n);
2381

H
hzcheng 已提交
2382
  const char delim = ':';
2383 2384
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2385

2386 2387 2388 2389 2390
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2391

2392 2393 2394 2395 2396 2397
  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 已提交
2398
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2399 2400 2401 2402 2403
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2404
  }
2405
  
H
hzcheng 已提交
2406 2407 2408
  return TSDB_CODE_SUCCESS;
}

2409 2410 2411 2412 2413 2414
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);

2415
  in_addr_t epAddr = inet_addr(tmp);
2416

2417
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2418 2419
}

H
hjxilinx 已提交
2420
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2421
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2422

weixin_48148422's avatar
weixin_48148422 已提交
2423
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2424
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2425 2426
  }

H
hjxilinx 已提交
2427
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2428 2429 2430

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

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

2449
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2450
      // todo refactor
2451
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2452 2453 2454
    }
  }

2455
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2456
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2457 2458 2459
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2460
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2461
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2462
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2463 2464
    return;
  }
H
hjxilinx 已提交
2465 2466 2467
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2468
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2469
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2470
    
2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487
    // 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 已提交
2488 2489 2490
  }
}

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

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

2506 2507
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2508
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2509 2510
      return true;
    }
H
hzcheng 已提交
2511

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

H
hzcheng 已提交
2524 2525 2526
  return false;
}

2527
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
2528
  int32_t startIdx = 0;
H
hjxilinx 已提交
2529
  
H
hjxilinx 已提交
2530 2531
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2532 2533

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

H
Haojun Liao 已提交
2538
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2539 2540 2541

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2542 2543 2544
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2545
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2546

H
hjxilinx 已提交
2547
    int16_t functionId = pExpr1->functionId;
2548 2549 2550 2551
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
hjxilinx 已提交
2552
    if (functionId == TSDB_FUNC_PRJ && pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
2553 2554 2555
      continue;
    }

H
Haojun Liao 已提交
2556
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2557 2558 2559 2560 2561 2562 2563
      return false;
    }
  }

  return true;
}

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

2572
  // todo : handle two tables situation
H
hjxilinx 已提交
2573
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2574 2575 2576 2577 2578

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

2579 2580 2581 2582
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
2583
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2584
  if (pList->nExpr > TSDB_MAX_TAGS) {
2585
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2586 2587
  }

H
hjxilinx 已提交
2588
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2589
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2590
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2591

S
slguan 已提交
2592
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
2593
  
H
hzcheng 已提交
2594 2595 2596 2597
  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 已提交
2598
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2599 2600
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2601
    }
H
hzcheng 已提交
2602

S
slguan 已提交
2603
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2604

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

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

2630 2631 2632 2633
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2634

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

2646
      tscColumnListInsert(pQueryInfo->colList, &index);
2647
      
2648
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2649
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2650
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2651 2652

      if (i == 0 && pList->nExpr > 1) {
2653
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2654
      }
H
hzcheng 已提交
2655 2656 2657
    }
  }

2658
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2659 2660 2661
  return TSDB_CODE_SUCCESS;
}

2662 2663
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2664
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2665
  } else {
H
hjxilinx 已提交
2666
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2667 2668 2669
  }
}

2670
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2671 2672 2673
  if (pColumn == NULL) {
    return NULL;
  }
2674

S
slguan 已提交
2675
  int32_t size = pColumn->numOfFilters + 1;
L
lihui 已提交
2676
  char*   tmp = (char*)realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2677 2678
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2679 2680
  }

S
slguan 已提交
2681
  pColumn->numOfFilters++;
2682

S
slguan 已提交
2683 2684 2685 2686
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2687 2688
}

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

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

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

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

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

2717
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2718 2719 2720 2721
    } 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);

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

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

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

2757
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2758 2759
}

S
slguan 已提交
2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773
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 已提交
2774

H
hjxilinx 已提交
2775
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
2776 2777

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2778
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2779 2780
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2781 2782

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

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

S
slguan 已提交
2814 2815 2816 2817 2818 2819 2820 2821 2822 2823
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
2824
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2825 2826 2827 2828 2829 2830 2831 2832 2833
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
2834 2835 2836 2837
  return TSDB_CODE_SUCCESS;
}

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

  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:
2890
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2891 2892 2893 2894 2895 2896 2897
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2898
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
2899 2900
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
2901
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2902 2903
  }

S
slguan 已提交
2904
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2905
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2906 2907
  }

H
hzcheng 已提交
2908 2909
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
2910
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
2911 2912

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

H
Haojun Liao 已提交
2916
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
2917
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2918 2919 2920 2921 2922 2923
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2924
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
2925 2926
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2927 2928

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2929 2930
}

S
slguan 已提交
2931 2932 2933 2934 2935 2936
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2937

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

H
hjxilinx 已提交
2941 2942
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2943

S
slguan 已提交
2944
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
2945 2946
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
2947

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

2969
  pColFilter->filterstr =
S
slguan 已提交
2970 2971
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

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

  pColumn->colIndex = *pIndex;
2989
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
2990 2991
}

2992
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2993 2994 2995 2996 2997
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

2998
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
2999 3000 3001 3002 3003 3004 3005 3006 3007
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

3008
UNUSED_FUNC
3009
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3010 3011 3012 3013 3014 3015 3016
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3018
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
3019
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3020
      return ret;
H
hzcheng 已提交
3021
    }
S
slguan 已提交
3022

3023
    relToString(pExpr, str);
S
slguan 已提交
3024

3025
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
3026 3027 3028 3029

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

H
hzcheng 已提交
3030 3031 3032
    return ret;
  }

S
slguan 已提交
3033 3034 3035
  return tSQLExprLeafToString(pExpr, true, str);
}

3036
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
3037 3038 3039 3040
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
3043 3044
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
3045

S
slguan 已提交
3046
  if (!isTablenameToken(&pLeft->colInfo)) {
3047
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3048 3049
  }

S
slguan 已提交
3050
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3051

S
slguan 已提交
3052
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
3053
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
3054
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3055
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
3056
  }
H
hzcheng 已提交
3057

S
slguan 已提交
3058
  if (ret != TSDB_CODE_SUCCESS) {
3059
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3060
  }
H
hzcheng 已提交
3061

S
slguan 已提交
3062 3063 3064
  return ret;
}

3065
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3066 3067 3068 3069 3070
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
3071
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3072 3073 3074 3075
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

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

3083
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3084
  }
S
slguan 已提交
3085
}
H
hzcheng 已提交
3086

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

S
slguan 已提交
3092 3093 3094
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3095

S
slguan 已提交
3096
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
3097
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3098 3099
  }

3100
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3101 3102 3103 3104
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3105 3106
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3107 3108
  }

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

3112
  pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3113
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3114
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3115 3116

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3117 3118
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3119 3120
  }

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

3124
  pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3125
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3126
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3127

H
Haojun Liao 已提交
3128
  if (pTagSchema1->type != pTagSchema2->type) {
3129
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3130 3131
  }

S
slguan 已提交
3132
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3133 3134 3135 3136
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3141
  *(*exprString)++ = '(';
H
hzcheng 已提交
3142 3143

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3144
    doArithmeticExprToString(pLeft, exprString);
H
hzcheng 已提交
3145
  } else {
S
slguan 已提交
3146
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3147
    if (ret != TSDB_CODE_SUCCESS) {
3148
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3149 3150 3151 3152 3153 3154
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3155
    doArithmeticExprToString(pRight, exprString);
H
hzcheng 已提交
3156
  } else {
S
slguan 已提交
3157
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3158
    if (ret != TSDB_CODE_SUCCESS) {
3159
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3160 3161 3162
    }
  }

H
hjxilinx 已提交
3163
  *(*exprString)++ = ')';
H
hzcheng 已提交
3164 3165 3166 3167

  return TSDB_CODE_SUCCESS;
}

3168 3169 3170 3171 3172
static int32_t arithmeticExprToString(tSQLExpr* pExpr, char** str) {
  char* start = *str;

  int32_t code = doArithmeticExprToString(pExpr, str);
  if (code == TSDB_CODE_SUCCESS) { // remove out the parenthesis
S
Shengliang Guan 已提交
3173
    int32_t len = (int32_t)strlen(start);
3174 3175 3176 3177 3178 3179 3180
    memmove(start, start + 1, len - 2);
    start[len - 2] = 0;
  }

  return code;
}

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

H
hjxilinx 已提交
3189
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3190
    if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3191
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3192 3193 3194
    }

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

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

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

  return TSDB_CODE_SUCCESS;
}

3226
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3227 3228 3229 3230 3231 3232
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

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

  return true;
}

S
slguan 已提交
3295 3296 3297
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3298

S
slguan 已提交
3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323
  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 已提交
3324

S
slguan 已提交
3325 3326 3327 3328 3329
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3330
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343
  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) {
3344
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3345 3346 3347 3348 3349
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3350 3351
  if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3352
    return false;
H
hzcheng 已提交
3353 3354
  }

S
slguan 已提交
3355
  // todo extract function
H
hjxilinx 已提交
3356
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3357
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3358 3359
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3360
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3361
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3362 3363 3364
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3365
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3366 3367
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3368
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3369
    return false;
H
hzcheng 已提交
3370 3371
  }

S
slguan 已提交
3372
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3373
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3374
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
S
slguan 已提交
3375 3376
    return false;
  }
H
hzcheng 已提交
3377

S
slguan 已提交
3378 3379
  return true;
}
H
hzcheng 已提交
3380

S
slguan 已提交
3381 3382 3383 3384 3385 3386
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 已提交
3387 3388 3389
    }
  }

S
slguan 已提交
3390
  return false;
H
hzcheng 已提交
3391 3392
}

3393
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3394 3395
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3396
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3397
    }
H
hzcheng 已提交
3398

S
slguan 已提交
3399 3400 3401 3402
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3403

S
slguan 已提交
3404 3405
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3406

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

S
slguan 已提交
3421 3422 3423
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3424 3425
  if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3426 3427
  }

S
slguan 已提交
3428 3429
  assert(isExprDirectParentOfLeaftNode(*pExpr));

H
hjxilinx 已提交
3430
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3431
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3432 3433

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3434
    if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3435
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3436
    }
S
slguan 已提交
3437 3438 3439

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

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3454 3455
  } 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 已提交
3456
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3457
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3458 3459 3460 3461 3462
    }

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

H
hjxilinx 已提交
3466
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3467 3468 3469

      if ((!isTablenameToken(&pLeft->colInfo)) && pSchema[index.columnIndex].type != TSDB_DATA_TYPE_BINARY &&
          pSchema[index.columnIndex].type != TSDB_DATA_TYPE_NCHAR) {
3470
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3471 3472 3473 3474 3475 3476
      }
    }

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

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3489
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
3490 3491 3492 3493 3494 3495
      }

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

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

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

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

S
slguan 已提交
3527
  return ret;
H
hzcheng 已提交
3528 3529
}

3530 3531
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                        int32_t* type, int32_t parentOptr) {
H
hzcheng 已提交
3532 3533 3534 3535
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3538 3539 3540 3541
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3542
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3543 3544
  }

S
slguan 已提交
3545 3546
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3547

S
slguan 已提交
3548
  if (!isExprDirectParentOfLeaftNode(*pExpr)) {
3549
    int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3550 3551 3552 3553
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

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

S
slguan 已提交
3559 3560 3561 3562 3563 3564
    /*
     *  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)) {
3565
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3566
      }
H
hzcheng 已提交
3567 3568
    }

S
slguan 已提交
3569 3570 3571
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3572

S
slguan 已提交
3573
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3574

3575
  return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3576
}
H
hzcheng 已提交
3577

S
slguan 已提交
3578 3579 3580 3581
static void doCompactQueryExpr(tSQLExpr** pExpr) {
  if (*pExpr == NULL || isExprDirectParentOfLeaftNode(*pExpr)) {
    return;
  }
H
hzcheng 已提交
3582

S
slguan 已提交
3583 3584 3585
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3586

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

S
slguan 已提交
3591 3592 3593 3594
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3595

S
slguan 已提交
3596 3597 3598
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3599

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

S
slguan 已提交
3605
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3606
  }
S
slguan 已提交
3607
}
H
hzcheng 已提交
3608

3609
static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
S
slguan 已提交
3610 3611 3612 3613
  if (isExprDirectParentOfLeaftNode(*pExpr)) {
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3614
    if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3615
      return;
H
hzcheng 已提交
3616 3617
    }

S
slguan 已提交
3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630
    if (index.tableIndex != tableIndex) {
      return;
    }

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

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

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

3631 3632
    doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3633 3634 3635
  }
}

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

S
slguan 已提交
3639
  if (*pExpr != NULL) {
3640
    doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3641
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3642 3643
  }

S
slguan 已提交
3644
  return pResExpr;
H
hzcheng 已提交
3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659
}

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

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

S
slguan 已提交
3664 3665 3666 3667
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3670
  STagCond* pTagCond = &pQueryInfo->tagCond;
3671
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
S
slguan 已提交
3672 3673 3674 3675

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3676
    char* str = taosStringBuilderGetResult(sb, NULL);
3677
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3678 3679 3680
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
3681
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
3682
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3683

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

S
slguan 已提交
3686
  // remove the duplicated input table names
H
hzcheng 已提交
3687
  int32_t num = 0;
H
hjxilinx 已提交
3688 3689 3690
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3691
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3692 3693 3694 3695 3696 3697 3698 3699 3700

  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 已提交
3701
  char* name = extractDBName(pTableMetaInfo->name, db);
S
TD-1057  
Shengliang Guan 已提交
3702
  SSQLToken dbToken = { .type = TK_STRING, .z = name, .n = (uint32_t)strlen(name) };
H
hjxilinx 已提交
3703
  
H
hzcheng 已提交
3704 3705
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3706
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3707
    }
H
hjxilinx 已提交
3708

H
Haojun Liao 已提交
3709
    char      idBuf[TSDB_TABLE_FNAME_LEN] = {0};
S
TD-1057  
Shengliang Guan 已提交
3710
    int32_t   xlen = (int32_t)strlen(segments[i]);
H
hzcheng 已提交
3711 3712
    SSQLToken t = {.z = segments[i], .n = xlen, .type = TK_STRING};

3713
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3714
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3715
      taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3716
      taosTFree(segments);
H
hjxilinx 已提交
3717

3718
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
3719 3720
      return ret;
    }
H
hjxilinx 已提交
3721

H
hjxilinx 已提交
3722
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3723
  }
H
hjxilinx 已提交
3724

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

H
hjxilinx 已提交
3728
  taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3729
  taosTFree(segments);
H
hzcheng 已提交
3730 3731 3732
  return TSDB_CODE_SUCCESS;
}

3733
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
3734 3735 3736 3737 3738 3739
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
3740

3741 3742
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
3743 3744
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
3745

3746
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760
          (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;
}

3761
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
3762 3763
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
3764 3765 3766 3767 3768

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

S
slguan 已提交
3769 3770
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    if (pExpr->nSQLOptr == TK_OR) {
3771
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3772
    }
H
hzcheng 已提交
3773

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

3776
    return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
S
slguan 已提交
3777 3778
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3779
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3780
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3781 3782
    }

H
hjxilinx 已提交
3783
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3784
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3785
    
S
slguan 已提交
3786 3787
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3788 3789
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
3790
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3791 3792 3793
    }

    // update the timestamp query range
H
hjxilinx 已提交
3794 3795
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
3796 3797
    }

H
hjxilinx 已提交
3798 3799
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
3800 3801 3802 3803 3804 3805
    }
  }

  return TSDB_CODE_SUCCESS;
}

3806
static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
3807 3808 3809 3810
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

3811 3812
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
3813 3814
      return TSDB_CODE_SUCCESS;
    } else {
3815
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3816 3817 3818
    }
  }

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

  if (!pCondExpr->tsJoin) {
3828
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3829 3830
  }

S
slguan 已提交
3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855
  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);
  }
}

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

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

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

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

3892
    tExprNode* p = NULL;
3893 3894
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
3895
    ret = exprTreeFromSqlExpr(pCmd, &p, p1, NULL, pQueryInfo, colList);
3896 3897 3898 3899 3900 3901 3902 3903 3904
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
3905
    
3906 3907
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
3908
    int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
3909 3910 3911 3912 3913 3914
    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 已提交
3915
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
3916 3917
    }
    
3918
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
3919 3920 3921 3922
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
3923 3924
    
    taosArrayDestroy(colList);
H
hjxilinx 已提交
3925
  }
H
hjxilinx 已提交
3926

3927
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
3928 3929
  return ret;
}
3930
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
3931 3932 3933
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
3934

H
hjxilinx 已提交
3935
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
3936
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
3937

H
hjxilinx 已提交
3938
  int32_t ret = TSDB_CODE_SUCCESS;
3939
  pQueryInfo->window = TSWINDOW_INITIALIZER;
S
slguan 已提交
3940

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

H
hjxilinx 已提交
3945
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
3946
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
S
slguan 已提交
3947 3948
  }

H
hjxilinx 已提交
3949
  int32_t type = 0;
3950
  if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3951 3952
    return ret;
  }
H
hjxilinx 已提交
3953

S
slguan 已提交
3954
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
3955

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

S
slguan 已提交
3959
  // 1. check if it is a join query
3960
  if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3961 3962
    return ret;
  }
H
hjxilinx 已提交
3963

S
slguan 已提交
3964
  // 2. get the query time range
3965
  if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3966 3967
    return ret;
  }
H
hjxilinx 已提交
3968

S
slguan 已提交
3969
  // 3. get the tag query condition
3970
  if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3971
    return ret;
S
slguan 已提交
3972
  }
H
hjxilinx 已提交
3973

S
slguan 已提交
3974
  // 4. get the table name query condition
3975
  if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3976 3977
    return ret;
  }
H
hjxilinx 已提交
3978

S
slguan 已提交
3979
  // 5. other column query condition
3980
  if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3981 3982
    return ret;
  }
H
hjxilinx 已提交
3983

S
slguan 已提交
3984
  // 6. join condition
3985
  if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3986
    return ret;
H
hzcheng 已提交
3987
  }
H
hjxilinx 已提交
3988

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

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

3995
  if (!validateFilterExpr(pQueryInfo)) {
3996
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
3997
  }
H
hjxilinx 已提交
3998

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

H
hjxilinx 已提交
4001
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
4002 4003 4004
  return ret;
}

H
hjxilinx 已提交
4005
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
4006 4007 4008 4009 4010
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

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

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

S
slguan 已提交
4024
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
4025
    if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
4026
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4027 4028
        parsed = true;
      } else {
4029
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4030
      }
S
slguan 已提交
4031 4032 4033 4034 4035
    } 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) {
4036
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4037
      }
H
hzcheng 已提交
4038 4039 4040 4041
    }
  } 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 已提交
4042
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057
     *
     * 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
     */
4058
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079

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

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

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

H
hzcheng 已提交
4108 4109 4110 4111
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4112 4113 4114
  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 已提交
4115
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4116
        const char* msg = "duplicated column name in new table";
4117
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4118 4119 4120 4121 4122 4123 4124
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4125
int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
4126 4127 4128 4129
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
4130 4131 4132 4133

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

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

H
hzcheng 已提交
4148
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4149
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4150
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4151
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4152 4153
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
4154 4155 4156 4157 4158
      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 已提交
4159 4160
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4161
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4162
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4163
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4164
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4165
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4166 4167

    if (pFillToken->nExpr == 1) {
4168
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4169 4170 4171 4172 4173 4174
    }

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

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

H
hjxilinx 已提交
4178
      if (numOfFillVal > size) {
S
TD-1057  
Shengliang Guan 已提交
4179
        numOfFillVal = (int32_t)size;
H
hzcheng 已提交
4180 4181
      }
    } else {
S
TD-1057  
Shengliang Guan 已提交
4182
      numOfFillVal = (pFillToken->nExpr >  (int32_t)size) ? (int32_t)size : pFillToken->nExpr;
H
hzcheng 已提交
4183 4184 4185 4186 4187
    }

    int32_t j = 1;

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

4190
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4191
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
4192 4193
        continue;
      }
H
hjxilinx 已提交
4194

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

H
hjxilinx 已提交
4204 4205
      for (int32_t i = numOfFillVal; i < size; ++i) {
        TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4206 4207

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

  return TSDB_CODE_SUCCESS;
}

4221
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4222
  /* set default timestamp order information for all queries */
4223
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
hjxilinx 已提交
4224
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4225

4226
  if (isTopBottomQuery(pQueryInfo)) {
4227
    pQueryInfo->order.order = TSDB_ORDER_ASC;
4228
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4229
  } else {
4230
    pQueryInfo->order.orderColId = -1;
H
hzcheng 已提交
4231 4232
  }

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

4239
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4240 4241 4242 4243
  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 已提交
4244

4245
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4246
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4247 4248 4249 4250 4251 4252

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

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4253 4254 4255 4256 4257 4258 4259

  /*
   * 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 已提交
4260
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4261
    if (pSortorder->nExpr > 1) {
4262
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4263 4264 4265
    }
  } else {
    if (pSortorder->nExpr > 2) {
4266
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277
    }
  }

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

weixin_48148422's avatar
weixin_48148422 已提交
4281
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4282 4283
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4284 4285 4286 4287
    }

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

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

S
slguan 已提交
4304
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4305 4306 4307
      orderByTS = true;
    }

4308
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
4309
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4310 4311 4312 4313 4314 4315
    } else {
      assert(!(orderByTags && orderByTS));
    }

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

4323
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4324
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4325
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
4326
        }
4327

4328 4329
        pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4330
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4331
      } else {
4332 4333
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4334 4335 4336 4337
      }
    }

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

H
hzcheng 已提交
4346 4347
      tVariant* pVar2 = &pSortorder->a[1].pVar;
      SSQLToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4348 4349
      if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4350 4351 4352
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4353
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4354
      } else {
4355 4356
        pQueryInfo->order.order = pSortorder->a[1].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4357 4358 4359 4360
      }
    }

  } else {  // meter query
4361 4362
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4363 4364
    }

4365
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
4366
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4367 4368
    }

4369
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4370
      /* order of top/bottom query in interval is not valid  */
4371
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4372
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4373

4374
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4375
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4376
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4377
      }
4378

4379 4380
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4381 4382
      return TSDB_CODE_SUCCESS;
    }
4383

4384
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4385 4386 4387 4388 4389 4390
  }

  return TSDB_CODE_SUCCESS;
}

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

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

S
slguan 已提交
4416
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4417
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4418 4419
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4422
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4423
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
4424
  }
P
plum-lihui 已提交
4425

H
Haojun Liao 已提交
4426
  if (tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql) != TSDB_CODE_SUCCESS) {
4427
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4428 4429
  }

H
hjxilinx 已提交
4430
  int32_t ret = tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
4431 4432 4433 4434
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

H
hjxilinx 已提交
4435
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4436

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

4449
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
hzcheng 已提交
4450 4451
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4452
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
4453 4454 4455
    }

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

    // numOfTags == 1
    if (pAlterSQL->varList->nExpr > 1) {
4467
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
hzcheng 已提交
4468 4469 4470
    }

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

4475
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
4476 4477
    SSQLToken    name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen, .type = TK_STRING};

4478
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4479
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4480 4481
    }

H
Haojun Liao 已提交
4482 4483
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
4484
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
H
Haojun Liao 已提交
4485
    } else if (index.columnIndex == numOfCols) {
4486
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
H
hzcheng 已提交
4487 4488
    }

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

4500 4501 4502 4503
    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) {
4504
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4505 4506
    }

4507
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4508
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
4509
    }
H
hzcheng 已提交
4510

S
slguan 已提交
4511 4512
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4513

S
slguan 已提交
4514
    SSQLToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4515
    if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4516
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4517 4518
    }

S
slguan 已提交
4519
    SSQLToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4520
    if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4521
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
H
hzcheng 已提交
4522 4523
    }

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

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

4542 4543
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
    SSQLToken    name = {.type = TK_STRING, .z = pTagName->pz, .n = pTagName->nLen};
4544
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4545
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4546 4547
    }

H
hjxilinx 已提交
4548
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4549
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12);
S
slguan 已提交
4550 4551
    }

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

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

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

4568 4569
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4570
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4571 4572
    }

4573
    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
4574
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
4575 4576
    pUpdateMsg->tid       = htonl(pTableMeta->id.tid);
    pUpdateMsg->uid       = htobe64(pTableMeta->id.uid);
H
Haojun Liao 已提交
4577
    pUpdateMsg->colId     = htons(pTagsSchema->colId);
H
Hongze Cheng 已提交
4578
    pUpdateMsg->type      = pTagsSchema->type;
H
Haojun Liao 已提交
4579 4580
    pUpdateMsg->bytes     = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion  = htons(pTableMeta->tversion);
4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598
    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);
4599 4600 4601 4602 4603
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
4604
      len = varDataTLen(pUpdateMsg->data + schemaLen);
4605 4606 4607 4608
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
4609
    int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen;
4610
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4611
    
4612
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
hzcheng 已提交
4613 4614
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4615
      const char* msg = "only support add one column";
4616
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4617 4618 4619
    }

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

    if (pAlterSQL->varList->nExpr > 1) {
H
hjxilinx 已提交
4630
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4631 4632 4633 4634
    }

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

4635 4636
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
    SSQLToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4637 4638
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4639 4640
    }

4641
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4642
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18);
4643
    }
H
hzcheng 已提交
4644

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

  return TSDB_CODE_SUCCESS;
}

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

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

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
4677
  // multi-output set/ todo refactor
H
hjxilinx 已提交
4678
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4679 4680
  
  for (int32_t k = 0; k < size; ++k) {
4681
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
4682

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

4694 4695 4696 4697
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4698

S
slguan 已提交
4699
    if (pExpr->functionId == TSDB_FUNC_PRJ || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4700
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4701 4702 4703
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4704 4705

  if (isProjectionFunction) {
4706
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4707 4708
  }

4709
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4710 4711 4712
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4713 4714
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4715 4716
} SDNodeDynConfOption;

H
Hui Li 已提交
4717

4718
int32_t validateEp(char* ep) {  
H
Hui Li 已提交
4719 4720 4721
  char buf[TSDB_EP_LEN + 1] = {0};
  tstrncpy(buf, ep, TSDB_EP_LEN);

4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732
  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 已提交
4733 4734
  }

4735
  return TSDB_CODE_SUCCESS;
H
Hui Li 已提交
4736 4737
}

H
hzcheng 已提交
4738 4739
int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
4740
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4741 4742
  }

4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754
  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 已提交
4755 4756 4757 4758 4759

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

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

    int32_t val = strtol(pValToken->z, NULL, 10);
4789
    if (val < 0 || val > 256) {
H
hzcheng 已提交
4790
      /* options value is out of valid range */
4791
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4792 4793
    }

4794 4795
    for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4796 4797 4798 4799 4800 4801 4802 4803

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

4804
  return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4805 4806
}

S
slguan 已提交
4807 4808
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
4809
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4810 4811
  }

H
hjxilinx 已提交
4812 4813
  SDNodeDynConfOption LOCAL_DYNAMIC_CFG_OPTIONS[6] = {{"resetLog", 8},    {"rpcDebugFlag", 12}, {"tmrDebugFlag", 12},
                                                      {"cDebugFlag", 10}, {"uDebugFlag", 10},   {"debugFlag", 9}};
S
slguan 已提交
4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830

  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
4831
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4832 4833 4834 4835 4836 4837 4838 4839 4840 4841
    }

    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;
      }
    }
  }
4842
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4843 4844
}

H
hzcheng 已提交
4845
int32_t validateColumnName(char* name) {
S
TD-1057  
Shengliang Guan 已提交
4846
  bool ret = isKeyWord(name, (int32_t)strlen(name));
H
hzcheng 已提交
4847
  if (ret) {
4848
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4849 4850
  }

S
slguan 已提交
4851
  SSQLToken token = {.z = name};
H
hzcheng 已提交
4852 4853 4854
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
4855
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4856 4857 4858 4859
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
S
TD-1057  
Shengliang Guan 已提交
4860
    token.n = (uint32_t)strtrim(token.z);
H
hzcheng 已提交
4861 4862 4863

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
4864
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4865 4866 4867 4868 4869
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
4870
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4871 4872 4873 4874 4875 4876
    }
  }

  return TSDB_CODE_SUCCESS;
}

4877 4878
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
4879 4880 4881
    return true;
  }

H
hjxilinx 已提交
4882
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
4883 4884
}

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

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

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

4905
  if (pQueryInfo->limit.limit == 0) {
4906
    tscDebug("%p limit 0, no output result", pSql);
4907
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4908
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
4909 4910
  }

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

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

4927
    if (pQueryInfo->slimit.limit == 0) {
4928
      tscDebug("%p slimit 0, no output result", pSql);
4929
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4930 4931 4932 4933
      return TSDB_CODE_SUCCESS;
    }

    /*
4934 4935 4936 4937
     * 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 已提交
4938
     */
H
hjxilinx 已提交
4939
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
4940 4941 4942 4943
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

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

    // keep original limitation value in globalLimit
4952
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4953
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
4954

4955 4956 4957 4958 4959 4960 4961 4962 4963
    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 已提交
4964

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

  return TSDB_CODE_SUCCESS;
}
4993

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

4997 4998 4999
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
5000

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

H
hjxilinx 已提交
5022 5023
  return TSDB_CODE_SUCCESS;
}
5024

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

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

H
hjxilinx 已提交
5030
  SSQLToken* pToken = &pCreateDbInfo->precision;
5031 5032
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
5033

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

H
hjxilinx 已提交
5046 5047
  return TSDB_CODE_SUCCESS;
}
5048

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

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

H
hjxilinx 已提交
5069
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5070
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5071
  }
H
hjxilinx 已提交
5072

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

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

5081
  return TSDB_CODE_SUCCESS;
H
huili 已提交
5082
}
S
slguan 已提交
5083

H
Haojun Liao 已提交
5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102
//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 已提交
5103

5104 5105
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
5106

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

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

      int16_t type = pSchema[index.columnIndex].type;
      int16_t bytes = pSchema[index.columnIndex].bytes;
      char*   name = pSchema[index.columnIndex].name;
H
hjxilinx 已提交
5122
  
5123
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
S
slguan 已提交
5124 5125 5126 5127
      pExpr->colInfo.flag = TSDB_COL_TAG;

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

      int32_t relIndex = index.columnIndex;

5132
      pExpr->colInfo.colIndex = relIndex;
5133 5134
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
5135

5136
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
5137
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
5138 5139 5140 5141
    }
  }
}

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

5149
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
5150
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
H
hjxilinx 已提交
5151
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
5152

H
Haojun Liao 已提交
5153 5154 5155 5156
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

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

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

S
TD-1057  
Shengliang Guan 已提交
5160
  SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, (int32_t)size);
H
Haojun Liao 已提交
5161
  doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
H
hjxilinx 已提交
5162
  pInfo->visible = false;
S
slguan 已提交
5163 5164
}

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

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

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

H
hjxilinx 已提交
5212 5213 5214 5215 5216
      assert(qualifiedCol);
    }
  }
}

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

  return false;
}

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

H
hjxilinx 已提交
5250 5251
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5252
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5253 5254 5255 5256
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5257
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5258 5259 5260 5261 5262 5263 5264 5265 5266
      allInGroupby = false;
      break;
    }
  }

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

5267
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5268
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5269 5270
  
  for (int32_t i = 0; i < size; ++i) {
5271
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283
    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.
 */
5284
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) {
S
slguan 已提交
5285
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5286
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5287

S
slguan 已提交
5288 5289 5290 5291
  bool    tagColExists = false;
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5292
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5293
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5294
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5295 5296 5297 5298 5299 5300
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
      tagColExists = true;
      break;
    }
  }
H
hjxilinx 已提交
5301

H
hjxilinx 已提交
5302
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5303
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5304 5305
  
    int16_t functionId = pExpr->functionId;
5306
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5307
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5308
      continue;
S
slguan 已提交
5309
    }
H
hjxilinx 已提交
5310

H
hjxilinx 已提交
5311 5312 5313 5314 5315 5316
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5317

H
hjxilinx 已提交
5318
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5319 5320
    // 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.
5321
    if (numOfAggregation > 0) {
5322
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5323 5324 5325 5326 5327 5328
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5329 5330
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5331 5332 5333 5334 5335
    } 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 已提交
5336 5337
      for (int32_t i = 0; i < numOfExprs; ++i) {
        
5338
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5339 5340 5341 5342 5343
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5344
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5345 5346 5347
        }
      }

5348 5349
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5350 5351
    }
  } else {
5352
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5353
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5354
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5355
      }
H
hjxilinx 已提交
5356

H
hjxilinx 已提交
5357 5358
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5359 5360
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5361
      }
S
slguan 已提交
5362 5363 5364 5365 5366 5367
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

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

H
Haojun Liao 已提交
5373
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5374
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5375 5376 5377 5378
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5379
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5380
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5381
    int16_t colIndex = pColIndex->colIndex;
5382
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5383
      type  = s.type;
H
Haojun Liao 已提交
5384
      bytes = s.bytes;
H
Haojun Liao 已提交
5385
      name  = s.name;
S
slguan 已提交
5386
    } else {
5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397
      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 已提交
5398
    }
H
hjxilinx 已提交
5399 5400 5401
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5402
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5403
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5404
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5405
      
B
Bomin Zhang 已提交
5406 5407
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5408
      
S
slguan 已提交
5409 5410 5411
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5412
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
S
TD-1057  
Shengliang Guan 已提交
5413
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5414 5415
    } else {
      // if this query is "group by" normal column, interval is not allowed
5416
      if (pQueryInfo->intervalTime > 0) {
5417
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5418 5419 5420
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5421
      for (int32_t j = 0; j < size; ++j) {
5422
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5423 5424 5425 5426 5427 5428 5429 5430 5431 5432
        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) {
5433
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5434 5435 5436 5437 5438 5439 5440
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5441
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5442
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5443
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5444
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5445
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5446 5447

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5448
  if (tscQueryTags(pQueryInfo)) {
5449
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5450
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5451 5452 5453 5454 5455
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5456
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5457
    // check if all the tags prj columns belongs to the group by columns
5458 5459
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5460
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5461 5462 5463
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5464 5465
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5466
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5467 5468 5469 5470 5471 5472
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5473
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5474
        bool qualified = false;
5475
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5476
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5477 5478 5479 5480 5481 5482 5483
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5484
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5485 5486 5487 5488
        }
      }

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

5493
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5494
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5495 5496 5497
      }
    }

5498
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5499
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5500 5501 5502 5503 5504 5505
    }

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

H
hjxilinx 已提交
5510
    // projection query on super table does not compatible with "group by" syntax
5511
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5512
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5513
    }
H
hjxilinx 已提交
5514

H
hjxilinx 已提交
5515
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5516
  } else {
5517
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5518 5519
  }
}
H
hjxilinx 已提交
5520

5521
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5522 5523 5524
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5525

H
hjxilinx 已提交
5526 5527
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5528
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5529
  }
H
hjxilinx 已提交
5530

H
hjxilinx 已提交
5531 5532
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5533
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hjxilinx 已提交
5534
  }
H
hjxilinx 已提交
5535

H
hjxilinx 已提交
5536
  // TODO redefine the function
H
hjxilinx 已提交
5537 5538 5539 5540 5541 5542
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5543
  int32_t index = -1;
H
hjxilinx 已提交
5544
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5545
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5546
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5547 5548 5549 5550
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5551 5552 5553

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5554
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5555
    case 1:
H
Haojun Liao 已提交
5556 5557 5558
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5559
    case 3:
H
Haojun Liao 已提交
5560
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5561
    case 4:
H
Haojun Liao 已提交
5562
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5563
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5564
  }
5565 5566 5567 5568 5569 5570
  
  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 已提交
5571
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5572 5573
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5574
}
H
hjxilinx 已提交
5575 5576

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

H
hjxilinx 已提交
5580 5581
  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);
5582
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5583
  }
H
hjxilinx 已提交
5584

H
hjxilinx 已提交
5585
  if (pCreate->replications != -1 &&
5586
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5587
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5588
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5589
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5590
  }
H
hjxilinx 已提交
5591

5592 5593 5594 5595 5596 5597 5598
  if (pCreate->quorum != -1 &&
      (pCreate->quorum < TSDB_MIN_DB_REPLICA_OPTION || pCreate->quorum > TSDB_MAX_DB_REPLICA_OPTION)) {
    snprintf(msg, tListLen(msg), "invalid db option quorum: %d valid range: [%d, %d]", pCreate->quorum,
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  }

H
hjxilinx 已提交
5599
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5600
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5601
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5602
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5603
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5604
  }
H
hjxilinx 已提交
5605

H
hjxilinx 已提交
5606 5607 5608 5609
  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);
5610
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5611
  }
H
hjxilinx 已提交
5612

H
hjxilinx 已提交
5613
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5614
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5615
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5616
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5617
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5618
  }
H
hjxilinx 已提交
5619 5620 5621 5622

  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);
5623
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5624
  }
H
hjxilinx 已提交
5625

H
hjxilinx 已提交
5626
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5627
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5628
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5629
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5630
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5631
  }
H
hjxilinx 已提交
5632

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5633 5634 5635 5636 5637 5638 5639
  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 已提交
5640
  if (pCreate->compression != -1 &&
S
slguan 已提交
5641
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5642
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5643
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5644
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5645
  }
H
hjxilinx 已提交
5646

H
hjxilinx 已提交
5647 5648
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5649 5650

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

S
TD-1057  
Shengliang Guan 已提交
5654
  int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
5655
  if (size == 0) {
H
hjxilinx 已提交
5656 5657
    return;
  }
H
hjxilinx 已提交
5658

H
hjxilinx 已提交
5659
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5660 5661

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

H
hjxilinx 已提交
5664 5665
  offset += sprintf(str, "num:%d [", size);
  for (int32_t i = 0; i < size; ++i) {
5666
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5667

L
lihui 已提交
5668
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5669 5670 5671
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5672 5673 5674
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
5676
    if (i < size - 1) {
H
hjxilinx 已提交
5677 5678 5679
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5680

H
hjxilinx 已提交
5681
  str[offset] = ']';
5682
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5683
}
5684

5685
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5686 5687 5688
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5689 5690
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5691
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703

  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) {
5704
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5705 5706
  }

H
Haojun Liao 已提交
5707
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5708
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5709 5710 5711 5712
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
5713
    return TSDB_CODE_TSC_INVALID_SQL;
5714 5715 5716 5717
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
H
hjxilinx 已提交
5718
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[col]);
5719 5720 5721 5722
  }

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

H
hjxilinx 已提交
5723
  if (pTagList != NULL) {  // create super table[optional]
5724
    for (int32_t i = 0; i < pTagList->nField; ++i) {
H
hjxilinx 已提交
5725
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pTagList->p[i]);
5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742
    }

    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;
5743 5744 5745
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
5746 5747 5748
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
5749 5750 5751 5752

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

H
hjxilinx 已提交
5753
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5754 5755 5756 5757 5758

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

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5759
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5760 5761
  }

H
Haojun Liao 已提交
5762
  if (tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5763
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5764 5765 5766
  }

  // get meter meta from mnode
B
Bomin Zhang 已提交
5767
  tstrncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, sizeof(pCreateTable->usingInfo.tagdata.name));
5768 5769
  tVariantList* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;

H
hjxilinx 已提交
5770
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5771 5772 5773 5774
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5775
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5776
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5777 5778 5779
  }

  // too long tag values will return invalid sql, not be truncated automatically
H
hjxilinx 已提交
5780
  SSchema* pTagSchema = tscGetTableTagSchema(pStableMeterMetaInfo->pTableMeta);
5781

5782
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
B
Bomin Zhang 已提交
5783 5784 5785 5786 5787
  SKVRowBuilder kvRowBuilder = {0};
  if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
hjxilinx 已提交
5788
  int32_t ret = TSDB_CODE_SUCCESS;
5789
  for (int32_t i = 0; i < pList->nExpr; ++i) {
B
Bomin Zhang 已提交
5790 5791
    SSchema* pSchema = pTagSchema + i;
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
H
hjxilinx 已提交
5792
      // validate the length of binary
B
Bomin Zhang 已提交
5793
      if (pList->a[i].pVar.nLen + VARSTR_HEADER_SIZE > pSchema->bytes) {
B
Bomin Zhang 已提交
5794
        tdDestroyKVRowBuilder(&kvRowBuilder);
H
hjxilinx 已提交
5795 5796 5797 5798
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
    
B
Bomin Zhang 已提交
5799 5800
    char tagVal[TSDB_MAX_TAGS_LEN];
    ret = tVariantDump(&(pList->a[i].pVar), tagVal, pSchema->type, true);
5801
    if (ret != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
5802
      tdDestroyKVRowBuilder(&kvRowBuilder);
5803
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5804 5805
    }

B
Bomin Zhang 已提交
5806
    tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
5807 5808
  }

B
Bomin Zhang 已提交
5809
  SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
B
Bomin Zhang 已提交
5810 5811 5812 5813 5814
  tdDestroyKVRowBuilder(&kvRowBuilder);
  if (row == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  tdSortKVRowByColIdx(row);
B
Bomin Zhang 已提交
5815
  pTag->dataLen = kvRowLen(row);
B
Bomin Zhang 已提交
5816
  kvRowCpy(pTag->data, row);
B
Bomin Zhang 已提交
5817 5818
  free(row);

5819 5820
  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5821
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5822 5823
  }

H
hjxilinx 已提交
5824
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
5825
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838
  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 已提交
5839 5840
  const char* msg6 = "from missing in subclause";
  
5841
  SSqlCmd*    pCmd = &pSql->cmd;
5842
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5843 5844
  assert(pQueryInfo->numOfTables == 1);

5845
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5846
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5847 5848 5849 5850 5851 5852

  // if sql specifies db, use it, otherwise use default db
  SSQLToken* pzTableName = &(pCreateTable->name);
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5853
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5854
  }
H
Haojun Liao 已提交
5855
  
5856
  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
H
Haojun Liao 已提交
5857 5858 5859 5860 5861
  if (pSrcMeterName == NULL || pSrcMeterName->nExpr == 0) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
  tVariant* pVar = &pSrcMeterName->a[0].pVar;
5862 5863
  SSQLToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
5864
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5865 5866
  }

H
Haojun Liao 已提交
5867
  if (tscSetTableFullName(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5868
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5869 5870
  }

H
hjxilinx 已提交
5871
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5872 5873 5874 5875
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
5876
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
5877
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5878
    return TSDB_CODE_TSC_INVALID_SQL;
5879 5880 5881
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5882
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5883
      return TSDB_CODE_TSC_INVALID_SQL;
5884 5885 5886 5887
    }
  }

  // set interval value
5888
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5889
    return TSDB_CODE_TSC_INVALID_SQL;
5890
  } else {
5891
    if ((pQueryInfo->intervalTime > 0) &&
5892
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
5893
      return TSDB_CODE_TSC_INVALID_SQL;
5894 5895 5896 5897
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
5898
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5899
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5900 5901 5902
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5903
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5904 5905
  }

5906
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5907
    return TSDB_CODE_TSC_INVALID_SQL;
5908 5909
  }

H
hjxilinx 已提交
5910
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5911

5912
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5913
    return TSDB_CODE_TSC_INVALID_SQL;
5914 5915 5916 5917 5918 5919 5920
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
5921
    if (pQueryInfo->intervalTime == 0) {
5922
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
5923 5924 5925 5926 5927 5928
    }

    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))) {
5929
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5930 5931 5932 5933 5934
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
5935
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5936 5937 5938 5939 5940 5941
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
  assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0));

H
Haojun Liao 已提交
5942 5943 5944 5945 5946 5947 5948 5949 5950 5951
  const char* msg0  = "invalid table name";
  const char* msg1  = "table name too long";
  const char* msg2  = "point interpolation query needs timestamp";
  const char* msg5  = "fill only available for interval query";
  const char* msg6  = "start(end) time of query range required or time range too large";
  const char* msg7  = "illegal number of tables in from clause";
  const char* msg8  = "too many columns in selection clause";
  const char* msg9  = "TWA query requires both the start and end time";
  const char* msg10 = "too many tables in from clause";
  const char* msg11 = "invalid table alias name";
5952 5953

  int32_t code = TSDB_CODE_SUCCESS;
5954

5955
  SSqlCmd* pCmd = &pSql->cmd;
5956

5957
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
5958
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5959
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
5960
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
5961
  }
H
hjxilinx 已提交
5962

H
Haojun Liao 已提交
5963 5964
  assert(pCmd->clauseIndex == index);

5965 5966
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
5967
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979
  }

  /*
   * 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);
5980
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
5981 5982
  }

H
Haojun Liao 已提交
5983
  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM * 2) {
5984
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
5985 5986
  }

5987
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
5988

H
Haojun Liao 已提交
5989
  if (pQuerySql->from->nExpr > 4) {
H
Haojun Liao 已提交
5990 5991 5992
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

5993
  // set all query tables, which are maybe more than one.
H
Haojun Liao 已提交
5994
  for (int32_t i = 0; i < pQuerySql->from->nExpr; ) {
5995 5996 5997
    tVariant* pTableItem = &pQuerySql->from->a[i].pVar;

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
5998
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5999 6000 6001 6002 6003 6004
    }

    pTableItem->nLen = strdequote(pTableItem->pz);

    SSQLToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
6005
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6006 6007
    }

H
Haojun Liao 已提交
6008
    if (pQueryInfo->numOfTables <= i/2) {  // more than one table
H
hjxilinx 已提交
6009
      tscAddEmptyMetaInfo(pQueryInfo);
6010 6011
    }

H
Haojun Liao 已提交
6012
    STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i/2);
6013

6014
    SSQLToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
6015
    if (tscSetTableFullName(pTableMetaInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
6016
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6017 6018
    }

H
Haojun Liao 已提交
6019 6020 6021 6022 6023 6024
    tVariant* pTableItem1 = &pQuerySql->from->a[i + 1].pVar;
    SSQLToken aliasName = {.z = pTableItem1->pz, .n = pTableItem1->nLen, .type = TK_STRING};
    if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

6025 6026 6027 6028 6029 6030
    // has no table alias name
    if (memcmp(pTableItem->pz, pTableItem1->pz, pTableItem1->nLen) == 0) {
      extractTableName(pTableMetaInfo1->name, pTableMetaInfo1->aliasName);
    } else {
      tstrncpy(pTableMetaInfo1->aliasName, pTableItem1->pz, sizeof(pTableMetaInfo1->aliasName));
    }
H
Haojun Liao 已提交
6031 6032

    code = tscGetTableMeta(pSql, pTableMetaInfo1);
6033 6034 6035
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
H
Haojun Liao 已提交
6036 6037

    i += 2;
6038 6039
  }

H
Haojun Liao 已提交
6040
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr / 2);
H
hjxilinx 已提交
6041
  bool isSTable = false;
H
hjxilinx 已提交
6042
  
weixin_48148422's avatar
weixin_48148422 已提交
6043
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
6044 6045 6046 6047 6048 6049 6050
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
6051 6052
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
6053
  }
6054

6055
  // parse the group by clause in the first place
6056
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
6057
    return TSDB_CODE_TSC_INVALID_SQL;
6058 6059
  }

6060
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
6061
    return TSDB_CODE_TSC_INVALID_SQL;
6062 6063 6064
  }

  // set interval value
6065
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6066
    return TSDB_CODE_TSC_INVALID_SQL;
6067
  } else {
6068
    if ((pQueryInfo->intervalTime > 0) &&
6069
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6070
      return TSDB_CODE_TSC_INVALID_SQL;
6071 6072 6073 6074
    }
  }

  // set order by info
6075
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
6076
    return TSDB_CODE_TSC_INVALID_SQL;
6077 6078 6079
  }

  // set where info
H
hjxilinx 已提交
6080
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
6081
  
6082
  if (pQuerySql->pWhere != NULL) {
6083
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
6084
      return TSDB_CODE_TSC_INVALID_SQL;
6085 6086 6087
    }

    pQuerySql->pWhere = NULL;
H
hjxilinx 已提交
6088
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
6089 6090
      pQueryInfo->window.skey = pQueryInfo->window.skey / 1000;
      pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000;
6091 6092
    }
  } else {  // set the time rang
H
Haojun Liao 已提交
6093
    pQueryInfo->window = TSWINDOW_INITIALIZER;
6094 6095 6096
  }

  // user does not specified the query time window, twa is not allowed in such case.
H
Haojun Liao 已提交
6097
  if ((pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX ||
H
hjxilinx 已提交
6098
       (pQueryInfo->window.ekey == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
6099
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
6100 6101 6102
  }

  // no result due to invalid query time range
H
hjxilinx 已提交
6103
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6104
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6105 6106 6107
    return TSDB_CODE_SUCCESS;
  }

6108
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6109
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6110 6111 6112
  }

  // in case of join query, time range is required.
6113
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
S
TD-1057  
Shengliang Guan 已提交
6114
    int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6115

H
hjxilinx 已提交
6116
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6117
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6118 6119 6120
    }
  }

6121
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6122 6123 6124
    return code;
  }

6125
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6126 6127 6128
    return code;
  }

6129
  setColumnOffsetValueInResultset(pQueryInfo);
6130

6131 6132 6133 6134 6135
  /*
   * 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) {
6136
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6137 6138
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6139

6140
    if (pQueryInfo->intervalTime > 0) {
S
TD-1057  
Shengliang Guan 已提交
6141
      int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6142
      // number of result is not greater than 10,000,000
6143
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_RETRIEVE_ROWS_IN_INTERVAL_QUERY) {
6144
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6145 6146
      }
    }
H
hjxilinx 已提交
6147

6148
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6149 6150 6151 6152
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6153 6154 6155

  return TSDB_CODE_SUCCESS;  // Does not build query message here
}
H
hjxilinx 已提交
6156

6157
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols) {
H
hjxilinx 已提交
6158 6159
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6160
  
6161
  if (pSqlExpr->pLeft != NULL) {
6162
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6163 6164 6165 6166 6167
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6168
  if (pSqlExpr->pRight != NULL) {
6169
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6170 6171 6172 6173 6174
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6175
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6176
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6177
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6178
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6179 6180 6181
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6182
      return TSDB_CODE_SUCCESS;
6183
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6184
      // arithmetic expression on the results of aggregation functions
6185
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6186
      (*pExpr)->nodeType = TSQL_NODE_COL;
6187 6188 6189
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6190
      // set the input column data byte and type.
H
hjxilinx 已提交
6191 6192 6193 6194 6195 6196
      size_t size = taosArrayGetSize(pExprInfo);
      
      for (int32_t i = 0; i < size; ++i) {
        SSqlExpr* p1 = taosArrayGetP(pExprInfo, i);
        
        if (strcmp((*pExpr)->pSchema->name, p1->aliasName) == 0) {
S
TD-1057  
Shengliang Guan 已提交
6197
          (*pExpr)->pSchema->type = (uint8_t)p1->resType;
H
hjxilinx 已提交
6198
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
hjxilinx 已提交
6199 6200 6201
          break;
        }
      }
6202
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6203
      SColumnIndex index = {0};
6204
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6205 6206 6207
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
H
Haojun Liao 已提交
6208 6209 6210 6211

      STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
      int32_t numOfColumns = tscGetNumOfColumns(pTableMeta);

6212 6213 6214
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
H
Haojun Liao 已提交
6215

6216 6217
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6218 6219 6220
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6221
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6222 6223
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
H
Haojun Liao 已提交
6224 6225
        colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;

6226 6227
        taosArrayPush(pCols, &colIndex);
      }
6228
      
H
hjxilinx 已提交
6229
      return TSDB_CODE_SUCCESS;
6230
    } else {
6231
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6232 6233 6234
    }
    
  } else {
H
hjxilinx 已提交
6235
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6236 6237
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6238 6239 6240
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6241 6242
    
    SSQLToken t = {.type = pSqlExpr->nSQLOptr};
H
[td-32]  
hjxilinx 已提交
6243
    (*pExpr)->_node.optr = getBinaryExprOptr(&t);
6244
    
H
[td-32]  
hjxilinx 已提交
6245
    assert((*pExpr)->_node.optr != 0);
H
hjxilinx 已提交
6246
    
H
[td-32]  
hjxilinx 已提交
6247
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6248 6249
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6250
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6251
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6252
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6253 6254 6255
        }
      }
    }
H
Hui Li 已提交
6256

6257
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6258 6259
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
      if (pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6260 6261 6262
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6263 6264
      }
    }
H
hjxilinx 已提交
6265 6266 6267
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6268
}