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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
154
static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) {
155 156 157 158 159
  const char* msg1 = "password can not be empty";
  const char* msg2 = "name or password too long";
  const char* msg3 = "password needs single quote marks enclosed";

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

182 183
  SSqlCmd* pCmd = &pSql->cmd;
  SSqlRes* pRes = &pSql->res;
H
hzcheng 已提交
184

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

190 191 192 193 194
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex);
  if (pQueryInfo == NULL) {
    pRes->code = terrno;
    return pRes->code;
  }
H
hjxilinx 已提交
195

196 197 198 199
  STableMetaInfo* pTableMetaInfo = (pQueryInfo->numOfTables == 0)? tscAddEmptyMetaInfo(pQueryInfo) : pQueryInfo->pTableMetaInfo[0];
  if (pTableMetaInfo == NULL) {
    pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
    return pRes->code;
H
hjxilinx 已提交
200
  }
201

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

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

218 219
      if (pInfo->type == TSDB_SQL_DROP_DB) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
220

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

226 227
      } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
228

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

H
hjxilinx 已提交
240
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
241 242
      }

243 244
      break;
    }
H
hzcheng 已提交
245

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

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
251
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
252 253
      }

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

      break;
    }

262 263
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
264 265
    }

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

271 272 273 274 275 276 277 278
      break;
    }

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

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

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

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

      break;
    }

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

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

H
Haojun Liao 已提交
303
      SStrToken* pIpAddr = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
304
      pIpAddr->n = strdequote(pIpAddr->z);
S
slguan 已提交
305 306 307
      break;
    }

308 309 310 311 312
    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 已提交
313

H
Haojun Liao 已提交
314 315
      SStrToken* pName = &pInfo->pDCLInfo->user.user;
      SStrToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
316

317
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
318
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
319 320
      }

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

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

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

H
hzcheng 已提交
340 341 342
      break;
    }

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

S
slguan 已提交
348
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
349
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
350
      }
S
slguan 已提交
351

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

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

H
hjxilinx 已提交
360
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
361 362
    }

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

367 368
      /* validate the ip address */
      tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
369

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

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

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

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

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

388 389 390 391
      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 已提交
392

393 394
      break;
    }
H
hzcheng 已提交
395

396 397 398 399 400 401
    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 已提交
402

403
      pCmd->command = pInfo->type;
H
hjxilinx 已提交
404
      // tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
405

406
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
H
Haojun Liao 已提交
407 408
      SStrToken* pName = &pUser->user;
      SStrToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
409

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

414
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
415
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
416
      }
H
hzcheng 已提交
417

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

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

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

H
hzcheng 已提交
446 447
      break;
    }
448 449

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

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

      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 已提交
463 464 465 466

      break;
    }

467 468
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
469

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

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

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

      break;
    }

490
    case TSDB_SQL_SELECT: {
H
hjxilinx 已提交
491
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
492

493
      for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) {
494 495 496 497
        SQueryInfo* pqi = tscGetQueryInfoDetailSafely(pCmd, i);
        if (pqi == NULL) {
          pRes->code = terrno;
          return pRes->code;
498
        }
499 500 501
      }

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

H
hjxilinx 已提交
509
        tscPrintSelectClause(pSql, i);
H
Haojun Liao 已提交
510
        pCmd->clauseIndex += 1;
H
hzcheng 已提交
511
      }
H
hjxilinx 已提交
512

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

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

523 524 525
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
526
        }
527
      }
528

529
      pCmd->parseFinished = 1;
530
      return TSDB_CODE_SUCCESS;  // do not build query message here
531
    }
H
hzcheng 已提交
532

533 534 535
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
536 537 538 539 540
      }

      break;
    }

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

      break;
    }

    default:
552
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
553 554
  }

dengyihao's avatar
dengyihao 已提交
555
  pSql->cmd.parseFinished = 1;
556
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
557 558
}

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

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

S
slguan 已提交
574
  return false;
H
hzcheng 已提交
575 576
}

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

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

  // interval is not null
B
Bomin Zhang 已提交
589 590
  SSQLToken* t = &pQuerySql->interval;
  if (parseDuration(t->z, t->n, &pQueryInfo->intervalTime, &pQueryInfo->intervalTimeUnit) != TSDB_CODE_SUCCESS) {
591
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
592 593
  }

B
Bomin Zhang 已提交
594 595 596 597 598
  if (pQueryInfo->intervalTimeUnit != 'n' && pQueryInfo->intervalTimeUnit != 'y') {
    // if the unit of time window value is millisecond, change the value from microsecond
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
      pQueryInfo->intervalTime = pQueryInfo->intervalTime / 1000;
    }
H
hzcheng 已提交
599

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

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

H
hzcheng 已提交
612 613 614
    return TSDB_CODE_SUCCESS;
  }

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

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

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

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

  if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
648
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
649 650
  }

H
Haojun Liao 已提交
651 652
  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));
653

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

657
  if (parseSlidingClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
658
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
659
  }
H
hjxilinx 已提交
660

H
hjxilinx 已提交
661
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
662 663
}

664
int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
665 666
  const char* msg0 = "sliding value too small";
  const char* msg1 = "sliding value no larger than the interval value";
H
Haojun Liao 已提交
667
  const char* msg2 = "sliding value can not less than 1% of interval value";
B
Bomin Zhang 已提交
668
  const char* msg3 = "does not support sliding when interval is natual month/year";
H
Haojun Liao 已提交
669 670

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

H
hjxilinx 已提交
672
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
673
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
674

B
Bomin Zhang 已提交
675 676 677 678 679 680
  SSQLToken* pSliding = &pQuerySql->sliding;
  if (pSliding->n == 0) {
    pQueryInfo->slidingTimeUnit = pQueryInfo->intervalTimeUnit;
    pQueryInfo->slidingTime = pQueryInfo->intervalTime;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
681

B
Bomin Zhang 已提交
682 683 684
  if (pQueryInfo->intervalTimeUnit == 'n' || pQueryInfo->intervalTimeUnit == 'y') {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
  }
H
hzcheng 已提交
685

B
Bomin Zhang 已提交
686 687 688 689 690 691 692 693 694 695 696
  getTimestampInUsFromStr(pSliding->z, pSliding->n, &pQueryInfo->slidingTime);
  if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
    pQueryInfo->slidingTime /= 1000;
  }

  if (pQueryInfo->slidingTime < tsMinSlidingTime) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
  }

  if (pQueryInfo->slidingTime > pQueryInfo->intervalTime) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
697 698
  }

H
Haojun Liao 已提交
699 700 701 702
  if ((pQueryInfo->intervalTime != 0) && (pQueryInfo->intervalTime/pQueryInfo->slidingTime > INTERVAL_SLIDING_FACTOR)) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
  }

H
hzcheng 已提交
703 704 705
  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

S
Shengliang Guan 已提交
750
  taosTFree(oldName);
751
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
752 753 754 755 756
}

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

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

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

  // first column must be timestamp
  if (pFieldList->p[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
773
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
774 775 776 777 778
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
dengyihao's avatar
dengyihao 已提交
779 780 781 782
    if (pFieldList->p[i].bytes == 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
      return false;
    }
H
hzcheng 已提交
783 784 785 786 787
    nLen += pFieldList->p[i].bytes;
  }

  // max row length must be less than TSDB_MAX_BYTES_PER_ROW
  if (nLen > TSDB_MAX_BYTES_PER_ROW) {
788
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
789 790 791 792 793 794 795
    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) {
796
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
797 798 799 800 801
      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))) {
802
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
803 804 805 806
      return false;
    }

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

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

  return true;
}

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

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

  // number of fields at least 1
  if (pTagsList->nField < 1 || pTagsList->nField > TSDB_MAX_TAGS) {
833
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
834 835 836 837 838
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
dengyihao's avatar
dengyihao 已提交
839 840 841 842
    if (pTagsList->p[i].bytes == 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
      return false;
    }
H
hzcheng 已提交
843 844 845 846 847
    nLen += pTagsList->p[i].bytes;
  }

  // max tag row length must be less than TSDB_MAX_TAGS_LEN
  if (nLen > TSDB_MAX_TAGS_LEN) {
848
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
849 850 851 852 853 854
    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) {
855
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
856 857 858 859 860 861 862
      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) {
863
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
864 865 866 867
      return false;
    }

    if (pTagsList->p[i].type < TSDB_DATA_TYPE_BOOL || pTagsList->p[i].type > TSDB_DATA_TYPE_NCHAR) {
868
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
869 870 871 872 873
      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)) {
874
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
875 876 877 878
      return false;
    }

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

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

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
896 897 898 899 900 901
  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 已提交
902

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

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

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

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

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

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

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

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

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

  // tags name can not be a keyword
  if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) {
946
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
947 948 949 950 951
    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) {
952
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
953 954 955 956
    return false;
  }

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

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

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
970 971 972 973 974 975
  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 已提交
976

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

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

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

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

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

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

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

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

  return true;
}

/* is contained in pFieldList or not */
H
hjxilinx 已提交
1030
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name) {
H
hzcheng 已提交
1031
  for (int32_t j = startIdx; j < pFieldList->nField; ++j) {
B
Bomin Zhang 已提交
1032 1033
    TAOS_FIELD* field = pFieldList->p + j;
    if (strncasecmp(name, field->name, sizeof(field->name) - 1) == 0) return true;
H
hzcheng 已提交
1034 1035 1036 1037 1038 1039 1040
  }

  return false;
}

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

H
Haojun Liao 已提交
1041
static void getCurrentDBName(SSqlObj* pSql, SStrToken* pDBToken) {
H
hzcheng 已提交
1042
  pDBToken->z = pSql->pTscObj->db;
S
TD-1057  
Shengliang Guan 已提交
1043
  pDBToken->n = (uint32_t)strlen(pSql->pTscObj->db);
H
hzcheng 已提交
1044 1045 1046
}

/* length limitation, strstr cannot be applied */
H
Haojun Liao 已提交
1047
static bool hasSpecifyDB(SStrToken* pTableName) {
S
TD-1057  
Shengliang Guan 已提交
1048
  for (uint32_t i = 0; i < pTableName->n; ++i) {
H
hzcheng 已提交
1049 1050 1051 1052 1053 1054 1055 1056
    if (pTableName->z[i] == TS_PATH_DELIMITER[0]) {
      return true;
    }
  }

  return false;
}

H
Haojun Liao 已提交
1057
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1058 1059 1060
  int32_t totalLen = 0;

  if (account != NULL) {
S
TD-1057  
Shengliang Guan 已提交
1061
    int32_t len = (int32_t)strlen(account);
H
hzcheng 已提交
1062 1063 1064 1065 1066 1067 1068
    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 已提交
1069
    if (pDB->n >= TSDB_ACCT_LEN + TSDB_DB_NAME_LEN) {
1070
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
    }

    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 已提交
1083
      if (!tscValidateTableNameLength(tableName->n)) {
1084
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1085 1086 1087
      }
    } else {  // pDB == NULL, the db prefix name is specified in tableName
      /* the length limitation includes tablename + dbname + sep */
B
Bomin Zhang 已提交
1088
      if (tableName->n >= TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN) {
1089
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
      }
    }

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

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

H
Haojun Liao 已提交
1101
  if (totalLen < TSDB_TABLE_FNAME_LEN) {
S
slguan 已提交
1102 1103 1104
    fullName[totalLen] = 0;
  }

H
Haojun Liao 已提交
1105
  return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1106 1107
}

1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
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;
  if (arithmeticType == NORMAL_ARITHMETIC) {
    pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;

    // all columns in arithmetic expression must belong to the same table
    for (int32_t f = 1; f < columnList.num; ++f) {
      if (columnList.ids[f].tableIndex != tableIndex) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
      }
    }

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

H
Haojun Liao 已提交
1141 1142 1143
    char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->token.z;
    size_t len = MIN(sizeof(pExpr->aliasName), pItem->pNode->token.n + 1);
    tstrncpy(pExpr->aliasName, name, len);
1144 1145 1146 1147 1148 1149

    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) {
1150 1151
      taosArrayDestroy(colList);
      tExprTreeDestroy(&pNode, NULL);
1152 1153 1154 1155 1156 1157
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }

    size_t numOfNode = taosArrayGetSize(colList);
    for(int32_t k = 0; k < numOfNode; ++k) {
      SColIndex* pIndex = taosArrayGet(colList, k);
1158 1159
      if (TSDB_COL_IS_TAG(pIndex->flag)) {
        tExprTreeDestroy(&pNode, NULL);
1160 1161
        taosArrayDestroy(colList);
        tExprTreeDestroy(&pNode, NULL);
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
        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

H
Haojun Liao 已提交
1176
    len = tbufTell(&bw);
1177 1178 1179
    char* c = tbufGetData(&bw, true);

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

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

    taosArrayDestroy(colList);
    tExprTreeDestroy(&pNode, NULL);
  } else {
    columnList.num = 0;
    columnList.ids[0] = (SColumnIndex) {0, 0};

H
Haojun Liao 已提交
1190 1191 1192 1193 1194 1195 1196
    char aliasName[TSDB_COL_NAME_LEN] = {0};
    if (pItem->aliasName != NULL) {
      tstrncpy(aliasName, pItem->aliasName, TSDB_COL_NAME_LEN);
    } else {
      int32_t nameLen = MIN(TSDB_COL_NAME_LEN, pItem->pNode->token.n + 1);
      tstrncpy(aliasName, pItem->pNode->token.z, nameLen);
    }
H
Haojun Liao 已提交
1197

H
Haojun Liao 已提交
1198
    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, aliasName, NULL);
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223

    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);
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
      }

      pInfo->pArithExprInfo = pArithExprInfo;
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

H
Haojun Liao 已提交
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSQLExprItem* pItem) {
  SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos, pIndex->columnIndex, pIndex->tableIndex);

  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;

  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);

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

  SColumnList ids = {0};
  ids.num = 1;
  ids.ids[0] = *pIndex;

  if (pIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX || pIndex->columnIndex == TSDB_UD_COLUMN_INDEX ||
      pIndex->columnIndex >= tscGetNumOfColumns(pTableMeta)) {
    ids.num = 0;
  }

  insertResultField(pQueryInfo, startPos, &ids, pExpr->resBytes, (int8_t)pExpr->resType, pExpr->aliasName, pExpr);
}

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

1255 1256
  const char* msg2 = "functions can not be mixed up";
  const char* msg3 = "not support query expression";
H
hjxilinx 已提交
1257
  const char* msg5 = "invalid function name";
H
hjxilinx 已提交
1258

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

1261 1262 1263
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
H
Haojun Liao 已提交
1264

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

S
slguan 已提交
1269
    // project on all fields
H
Haojun Liao 已提交
1270 1271
    int32_t optr = pItem->pNode->nSQLOptr;

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

S
slguan 已提交
1278
      // select table_name1.field_name1, table_name2.field_name2  from table_name1, table_name2
1279
      if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
1280
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1281
      }
1282
    } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_TBID) {
S
slguan 已提交
1283
      // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
1284
      if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
1285
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1286 1287 1288
      }

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
1289 1290 1291
      int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
1292 1293
      }
    } else {
1294
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1295 1296
    }

H
hjxilinx 已提交
1297
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1298
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1299 1300 1301
    }
  }

1302 1303 1304 1305
  // there is only one user-defined column in the final result field, add the timestamp column.
  size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
  if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo)) {
    SColumnIndex index = {0};
H
Haojun Liao 已提交
1306 1307 1308 1309 1310 1311

    // set the constant column value always attached to first table.
    STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, clauseIndex, 0);
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, PRIMARYKEY_TIMESTAMP_COL_INDEX);

    // add the timestamp column into the output columns
1312
    int32_t numOfCols = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
Haojun Liao 已提交
1313 1314 1315 1316 1317 1318
    tscAddSpecialColumnForSelect(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL);

    SFieldSupInfo* pSupInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, numOfCols);
    pSupInfo->visible = false;

    pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
1319 1320
  }

H
Haojun Liao 已提交
1321
  if (!functionCompatibleCheck(pQueryInfo, joinQuery)) {
1322
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1323 1324
  }

H
Haojun Liao 已提交
1325 1326 1327 1328
  /*
   * transfer sql functions that need secondary merge into another format
   * in dealing with metric queries such as: count/first/last
   */
1329
  if (isSTable) {
H
hjxilinx 已提交
1330
    tscTansformSQLFuncForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1331

1332
    if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
1333
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1334 1335 1336 1337 1338 1339
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1340 1341
int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
    int8_t type, char* fieldName, SSqlExpr* pSqlExpr) {
1342
  
S
slguan 已提交
1343
  for (int32_t i = 0; i < pIdList->num; ++i) {
1344 1345 1346 1347 1348 1349 1350 1351
    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;
    }
    
1352
    tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i]));
H
hzcheng 已提交
1353
  }
H
hjxilinx 已提交
1354 1355
  
  TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
H
Haojun Liao 已提交
1356
  SFieldSupInfo* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
H
hjxilinx 已提交
1357
  pInfo->pSqlExpr = pSqlExpr;
H
hjxilinx 已提交
1358
  
H
hzcheng 已提交
1359 1360 1361
  return TSDB_CODE_SUCCESS;
}

1362
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1363
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1364 1365 1366
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
1367
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
H
hzcheng 已提交
1368

1369
  int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
1370 1371 1372 1373
  SColumnIndex index = {.tableIndex = tableIndex,};
  
  if (functionId == TSDB_FUNC_TAGPRJ) {
    index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta);
H
hjxilinx 已提交
1374 1375
  
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
1376 1377 1378 1379 1380 1381
  } else {
    index.columnIndex = colIndex;
  }
  
  return tscSqlExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes,
      pSchema->bytes, functionId == TSDB_FUNC_TAGPRJ);
H
hzcheng 已提交
1382 1383
}

H
Haojun Liao 已提交
1384
SSqlExpr* tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1385
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
H
Haojun Liao 已提交
1386
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
H
Haojun Liao 已提交
1387
                                     pColSchema->bytes, pColSchema->bytes, TSDB_COL_IS_TAG(flag));
H
Haojun Liao 已提交
1388
  tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName));
H
hzcheng 已提交
1389

S
slguan 已提交
1390 1391 1392 1393
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1394

H
hjxilinx 已提交
1395
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1396 1397

  pExpr->colInfo.flag = flag;
1398 1399
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  
S
slguan 已提交
1400
  if (TSDB_COL_IS_TAG(flag)) {
H
hjxilinx 已提交
1401
    tscColumnListInsert(pTableMetaInfo->tagColList, pIndex);
S
slguan 已提交
1402
  }
H
Haojun Liao 已提交
1403 1404

  return pExpr;
S
slguan 已提交
1405 1406
}

1407
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1408
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1409 1410

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1411 1412
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1413

H
hjxilinx 已提交
1414
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1415
  
weixin_48148422's avatar
weixin_48148422 已提交
1416
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1417
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1418
  } else {
H
hjxilinx 已提交
1419
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1420 1421 1422
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
hjxilinx 已提交
1423
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex);
B
Bomin Zhang 已提交
1424
    tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName));
S
slguan 已提交
1425 1426 1427 1428

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

H
hjxilinx 已提交
1431
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1432 1433 1434 1435 1436
  }

  return numOfTotalColumns;
}

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

1441
  int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
Haojun Liao 已提交
1442 1443 1444 1445 1446
  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 已提交
1447
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1448
    if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1449
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
1450 1451 1452 1453
    }

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

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

H
Haojun Liao 已提交
1468
    // user-specified constant value as a new result column
1469 1470
    index.columnIndex = (pQueryInfo->udColumnId--);
    index.tableIndex = 0;
H
hzcheng 已提交
1471

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

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

1482 1483 1484
    if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
    }
H
Haojun Liao 已提交
1485

1486 1487 1488 1489 1490 1491
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      SSchema colSchema = tGetTableNameColumnSchema();
      tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG);
    } else {
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
Haojun Liao 已提交
1492

1493 1494
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1495 1496
      }

1497
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
Haojun Liao 已提交
1498
      pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
H
hzcheng 已提交
1499
    }
H
Haojun Liao 已提交
1500

1501 1502
    // add the primary timestamp column even though it is not required by user
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
hzcheng 已提交
1503
  } else {
1504
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1505 1506 1507 1508 1509
  }

  return TSDB_CODE_SUCCESS;
}

1510
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, int32_t functionID, char* aliasName,
S
slguan 已提交
1511
                                       int32_t resColIdx, SColumnIndex* pColIndex) {
H
hzcheng 已提交
1512 1513 1514
  int16_t type = 0;
  int16_t bytes = 0;

S
slguan 已提交
1515
  char        columnName[TSDB_COL_NAME_LEN] = {0};
1516
  const char* msg1 = "not support column types";
H
hzcheng 已提交
1517 1518

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

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

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

S
slguan 已提交
1553
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
S
TD-1057  
Shengliang Guan 已提交
1554
  insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, columnName, pExpr);
H
hzcheng 已提交
1555 1556 1557 1558

  return TSDB_CODE_SUCCESS;
}

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

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

H
hzcheng 已提交
1573 1574 1575
  switch (optr) {
    case TK_COUNT: {
        /* more than one parameter for count() function */
H
Haojun Liao 已提交
1576
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
1577
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1578 1579 1580 1581
      }

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1582
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1583 1584
      }

H
hjxilinx 已提交
1585
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1586
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1587 1588

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

S
slguan 已提交
1594 1595 1596 1597
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
        if (pParamElem->pNode->nSQLOptr == TK_ALL) {
          // select table.*
          // check if the table name is valid or not
H
Haojun Liao 已提交
1598
          SStrToken tmpToken = pParamElem->pNode->colInfo;
S
slguan 已提交
1599

1600
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1601
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1602 1603 1604 1605
          }

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

H
hjxilinx 已提交
1613
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1614 1615

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1616 1617
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1618
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1619
            isTag = true;
H
hzcheng 已提交
1620 1621
          }

S
slguan 已提交
1622
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1623
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1624
        }
S
slguan 已提交
1625 1626 1627
      } 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;
1628
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1629
      }
H
Haojun Liao 已提交
1630 1631 1632

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

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

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

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

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

S
slguan 已提交
1679
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
Y
yihaoDeng 已提交
1680
      if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
1681
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1682
      }
Y
yihaoDeng 已提交
1683 1684 1685
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
H
hzcheng 已提交
1686 1687

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

H
hjxilinx 已提交
1692
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1693
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1694 1695 1696 1697
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
1698
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1699 1700 1701

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1702
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1703 1704
      }

S
slguan 已提交
1705 1706
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
1707
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1708
      }
H
hzcheng 已提交
1709

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

S
slguan 已提交
1717
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1718
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1719 1720
      }

S
slguan 已提交
1721
      // functions can not be applied to tags
H
hjxilinx 已提交
1722
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1723
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1724 1725
      }

1726
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, resultSize, false);
H
hzcheng 已提交
1727 1728 1729 1730

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

S
slguan 已提交
1735
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1736 1737

        memset(val, 0, tListLen(val));
1738
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1739
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1740 1741
        }

S
slguan 已提交
1742
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1743 1744
      }

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

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

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

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

H
hzcheng 已提交
1785 1786 1787 1788
        /* 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) {
1789
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1790 1791
          }

S
slguan 已提交
1792 1793 1794 1795
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

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

1798
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1799
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1800 1801
            }

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

H
hjxilinx 已提交
1805
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
1806
              index.columnIndex = j;
1807
              if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex++, &index) != 0) {
1808
                return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1809 1810
              }
            }
H
hzcheng 已提交
1811

S
slguan 已提交
1812
          } else {
1813 1814
            if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1815 1816
            }

H
hjxilinx 已提交
1817
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1818
            SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1819 1820

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

1825
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i, &index) != 0) {
1826
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1827
            }
1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843

            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 已提交
1844 1845
          }
        }
1846
        
S
slguan 已提交
1847 1848 1849 1850
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

H
Haojun Liao 已提交
1851
        // multicolumn selection does not support alias name
H
Haojun Liao 已提交
1852
        if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
1853
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
1854 1855
        }

1856
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
1857
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
1858
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1859

H
hjxilinx 已提交
1860
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
1861
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
H
Haojun Liao 已提交
1862
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex, &index) != 0) {
1863
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1864
            }
H
Haojun Liao 已提交
1865 1866

            colIndex++;
H
hzcheng 已提交
1867
          }
S
slguan 已提交
1868

H
hjxilinx 已提交
1869
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1870 1871
        }

1872
        
S
slguan 已提交
1873
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1874 1875 1876 1877 1878 1879 1880 1881 1882
      }
    }
    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 */
1883
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1884 1885 1886 1887
      }

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

      // functions can not be applied to tags
H
hjxilinx 已提交
1903
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1904
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1905 1906 1907
      }

      // 2. valid the column type
S
slguan 已提交
1908
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
1909
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1910
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1911 1912 1913 1914
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
1915
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1916 1917 1918 1919
      }

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

S
slguan 已提交
1920 1921
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1922

H
hjxilinx 已提交
1923
      char    val[8] = {0};
H
hjxilinx 已提交
1924 1925
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
1926
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
1927
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
1928

L
lihui 已提交
1929
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
1930
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
1931
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943
        }

        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) {
1944
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1945
        }
dengyihao's avatar
dengyihao 已提交
1946 1947
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
        colIndex += 1;  // the first column is ts
H
hzcheng 已提交
1948

1949
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1950
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1951
      } else {
1952
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
1953

H
Haojun Liao 已提交
1954
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
1955
        if (nTop <= 0 || nTop > 100) {  // todo use macro
1956
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1957 1958 1959 1960
        }

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

H
Haojun Liao 已提交
1964
        // todo REFACTOR
H
hzcheng 已提交
1965
        // set the first column ts for top/bottom query
S
slguan 已提交
1966
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
1967 1968
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
            TSDB_KEYSIZE, false);
H
Haojun Liao 已提交
1969
        tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
S
slguan 已提交
1970

H
Haojun Liao 已提交
1971
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
1972
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
1973
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
1974
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
1975

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

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

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

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
2042 2043 2044
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
2045
        s = tGetTableNameColumnSchema();
2046 2047 2048 2049
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
2050 2051
      int16_t bytes = 0;
      int16_t type  = 0;
2052
      int32_t inter = 0;
2053 2054 2055 2056

      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 已提交
2057
      s.type = (uint8_t)type;
2058 2059 2060 2061 2062
      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 已提交
2063
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2064
    }
2065
    
H
hzcheng 已提交
2066
    default:
2067
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2068
  }
2069
  
H
hzcheng 已提交
2070 2071
}

S
slguan 已提交
2072 2073
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
2074
  assert(num == 1 && tableIndex >= 0);
S
slguan 已提交
2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085

  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 已提交
2086 2087 2088 2089
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
S
TD-1057  
Shengliang Guan 已提交
2090
    int32_t len = ((int32_t)pItem->pNode->operand.n < nameLength) ? (int32_t)pItem->pNode->operand.n : nameLength;
H
hzcheng 已提交
2091 2092 2093 2094 2095 2096 2097 2098
    strncpy(resultFieldName, pItem->pNode->operand.z, len);
  }
}

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

H
Haojun Liao 已提交
2099 2100 2101
static bool isTablenameToken(SStrToken* token) {
  SStrToken tmpToken = *token;
  SStrToken tableToken = {0};
S
slguan 已提交
2102 2103 2104 2105 2106 2107

  extractTableNameFromToken(&tmpToken, &tableToken);

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

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

H
hjxilinx 已提交
2111 2112
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2113 2114 2115 2116 2117 2118 2119 2120 2121 2122

  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 已提交
2123
      break;
S
slguan 已提交
2124 2125 2126 2127 2128 2129
    }
  }

  return columnIndex;
}

H
Haojun Liao 已提交
2130
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2131 2132 2133 2134 2135 2136 2137 2138 2139 2140
  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) {
2141 2142
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2143 2144 2145

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2146
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
2147 2148 2149 2150 2151 2152 2153
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2154
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2155 2156 2157 2158 2159 2160
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2161
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2162 2163 2164 2165 2166 2167
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2168
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2169 2170 2171
  }
}

H
Haojun Liao 已提交
2172
int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2173
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2174
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2175 2176 2177 2178 2179 2180 2181
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
2182
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2183
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
Haojun Liao 已提交
2184 2185
    char* name = pTableMetaInfo->aliasName;
    if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
S
slguan 已提交
2186 2187 2188 2189 2190 2191
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
2192
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2193 2194 2195 2196 2197
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
2198 2199
int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SStrToken tableToken = {0};
S
slguan 已提交
2200 2201
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2202
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2203
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2204 2205
  }

S
slguan 已提交
2206 2207
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2208

H
Haojun Liao 已提交
2209
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2210
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2211
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2212 2213
  }

H
Haojun Liao 已提交
2214
  SStrToken tmpToken = *pToken;
S
slguan 已提交
2215

2216
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2217
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2218 2219
  }

2220
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
}

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

H
hzcheng 已提交
2309 2310
  pCmd->command = TSDB_SQL_SHOW;

2311
  const char* msg1 = "invalid name";
2312
  const char* msg2 = "pattern filter string too long";
2313 2314 2315 2316
  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 已提交
2317 2318 2319 2320 2321

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2322 2323 2324
  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 已提交
2325
    // db prefix in tagCond, show table conds in payload
H
Haojun Liao 已提交
2326
    SStrToken* pDbPrefixToken = &pShowInfo->prefix;
2327
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2328

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

2333
      if (pDbPrefixToken->n <= 0) {
2334
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2335 2336
      }

2337
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2338
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2339 2340
      }

H
hjxilinx 已提交
2341
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2342
      if (ret != TSDB_CODE_SUCCESS) {
2343
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2344
      }
2345
    }
H
hzcheng 已提交
2346

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

2352
      if (pPattern->n <= 0) {
2353
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2354
      }
H
hzcheng 已提交
2355

H
Haojun Liao 已提交
2356
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2357
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2358 2359
      }
    }
2360 2361
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2362
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2363 2364
    }

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

2371
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2372
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2373
    }
H
hzcheng 已提交
2374 2375 2376 2377 2378
  }

  return TSDB_CODE_SUCCESS;
}

2379 2380 2381 2382
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 已提交
2383

2384 2385
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2386
  
H
Haojun Liao 已提交
2387
  SStrToken* idStr = &(pInfo->pDCLInfo->ip);
2388
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2389
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2390 2391
  }

2392
  strncpy(pCmd->payload, idStr->z, idStr->n);
2393

H
hzcheng 已提交
2394
  const char delim = ':';
2395 2396
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2397

2398 2399 2400 2401 2402
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2403

2404 2405 2406 2407 2408 2409
  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 已提交
2410
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2411 2412 2413 2414 2415
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2416
  }
2417
  
H
hzcheng 已提交
2418 2419 2420
  return TSDB_CODE_SUCCESS;
}

2421 2422 2423 2424 2425 2426
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);

2427
  in_addr_t epAddr = taosInetAddr(tmp);
2428

2429
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2430 2431
}

H
hjxilinx 已提交
2432
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2433
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2434

weixin_48148422's avatar
weixin_48148422 已提交
2435
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2436
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2437 2438
  }

H
hjxilinx 已提交
2439
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2440 2441 2442

  int16_t bytes = 0;
  int16_t type = 0;
2443
  int32_t interBytes = 0;
H
hjxilinx 已提交
2444 2445 2446
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2447
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2448 2449
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

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

2461
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2462
      // todo refactor
2463
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2464 2465 2466
    }
  }

2467
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2468
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2469 2470 2471
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2472
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2473
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2474
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2475 2476
    return;
  }
H
hjxilinx 已提交
2477 2478 2479
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2480
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2481
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2482
    
2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499
    // 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 已提交
2500 2501 2502
  }
}

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

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

2518 2519
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2520
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2521 2522
      return true;
    }
H
hzcheng 已提交
2523

2524
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2525
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2526
      return true;
2527 2528 2529
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
2530
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2531 2532
        return true;
      }
H
hzcheng 已提交
2533 2534
    }
  }
S
slguan 已提交
2535

H
hzcheng 已提交
2536 2537 2538
  return false;
}

H
Haojun Liao 已提交
2539
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
H
hzcheng 已提交
2540
  int32_t startIdx = 0;
H
hjxilinx 已提交
2541
  
H
hjxilinx 已提交
2542 2543
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2544 2545

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

H
Haojun Liao 已提交
2550
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2551 2552 2553

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2554 2555 2556
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2557
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2558

H
hjxilinx 已提交
2559
    int16_t functionId = pExpr1->functionId;
2560 2561 2562 2563
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
hjxilinx 已提交
2564
    if (functionId == TSDB_FUNC_PRJ && pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
2565 2566 2567
      continue;
    }

H
Haojun Liao 已提交
2568
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2569 2570
      return false;
    }
H
Haojun Liao 已提交
2571 2572 2573 2574

    if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
      return false;
    }
H
hzcheng 已提交
2575 2576 2577 2578 2579
  }

  return true;
}

2580
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2581 2582
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
H
Haojun Liao 已提交
2583
//  const char* msg3 = "group by columns must belong to one table";
S
slguan 已提交
2584 2585 2586
  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 已提交
2587

2588
  // todo : handle two tables situation
H
hjxilinx 已提交
2589
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2590 2591 2592 2593 2594

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

2595 2596 2597 2598
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
2599
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2600
  if (pList->nExpr > TSDB_MAX_TAGS) {
2601
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2602 2603
  }

H
hjxilinx 已提交
2604
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2605
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2606
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2607

S
slguan 已提交
2608
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
2609
  
H
hzcheng 已提交
2610 2611
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tVariant* pVar = &pList->a[i].pVar;
H
Haojun Liao 已提交
2612
    SStrToken token = {pVar->nLen, pVar->nType, pVar->pz};
H
hzcheng 已提交
2613

S
slguan 已提交
2614
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2615 2616
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2617
    }
H
hzcheng 已提交
2618

S
slguan 已提交
2619
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2620

H
hjxilinx 已提交
2621
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2622
    pTableMeta = pTableMetaInfo->pTableMeta;
2623 2624
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2625 2626 2627
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2628
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2629
    }
H
hzcheng 已提交
2630

S
slguan 已提交
2631
    bool groupTag = false;
2632
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2633
      groupTag = true;
H
hzcheng 已提交
2634
    }
2635 2636 2637 2638 2639 2640
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2641
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2642
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2643
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
S
slguan 已提交
2644 2645
      }

2646 2647 2648 2649
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2650

H
hjxilinx 已提交
2651
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2652
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2653 2654 2655
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2656 2657
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
2658
      if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
2659
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
2660 2661
      }

2662
      tscColumnListInsert(pQueryInfo->colList, &index);
2663
      
2664
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2665
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2666
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2667 2668

      if (i == 0 && pList->nExpr > 1) {
2669
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2670
      }
H
hzcheng 已提交
2671 2672 2673
    }
  }

2674
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2675 2676 2677
  return TSDB_CODE_SUCCESS;
}

2678 2679
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2680
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2681
  } else {
H
hjxilinx 已提交
2682
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2683 2684 2685
  }
}

2686
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2687 2688 2689
  if (pColumn == NULL) {
    return NULL;
  }
2690

S
slguan 已提交
2691
  int32_t size = pColumn->numOfFilters + 1;
2692 2693

  char* tmp = (char*) realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2694 2695
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2696 2697
  } else {
    return NULL;
2698 2699
  }

S
slguan 已提交
2700
  pColumn->numOfFilters++;
2701

S
slguan 已提交
2702 2703 2704 2705
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2706 2707
}

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

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

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

S
slguan 已提交
2717
  int16_t colType = pSchema->type;
2718
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2719 2720 2721
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2722
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2723
    int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
2724 2725 2726
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2727 2728 2729
  }

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

2736
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2737 2738 2739 2740
    } 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);

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

H
[TD-92]  
Hui Li 已提交
2743
      size_t len = twcslen((wchar_t*)pColumnFilter->pz);
S
slguan 已提交
2744
      pColumnFilter->len = len * TSDB_NCHAR_SIZE;
H
hzcheng 已提交
2745
    } else {
2746
      tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
2747 2748 2749 2750 2751
    }
  }

  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
2752
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
2753 2754
      break;
    case TK_LT:
S
slguan 已提交
2755
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
2756 2757
      break;
    case TK_GT:
2758
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
2759 2760
      break;
    case TK_GE:
2761
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
2762 2763
      break;
    case TK_EQ:
S
slguan 已提交
2764
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
2765 2766
      break;
    case TK_NE:
S
slguan 已提交
2767
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
2768 2769
      break;
    case TK_LIKE:
S
slguan 已提交
2770
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
2771
      break;
S
slguan 已提交
2772
    default:
2773
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
2774
  }
S
slguan 已提交
2775

2776
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2777 2778
}

S
slguan 已提交
2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792
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 已提交
2793

H
hjxilinx 已提交
2794
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
2795 2796

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2797
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2798 2799
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2800 2801

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

H
hjxilinx 已提交
2804 2805 2806 2807 2808 2809 2810
  } 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 已提交
2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829
    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)) {
2830
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2831 2832
  }

S
slguan 已提交
2833 2834 2835 2836 2837 2838 2839 2840 2841 2842
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
2843
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2844 2845 2846 2847 2848 2849 2850 2851 2852
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
2853 2854 2855 2856
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
2857 2858 2859 2860
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908

  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:
2909
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2910 2911 2912 2913 2914 2915 2916
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2917
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
2918 2919
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
2920
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2921 2922
  }

S
slguan 已提交
2923
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2924
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2925 2926
  }

H
hzcheng 已提交
2927 2928
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
2929
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
2930 2931

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

H
Haojun Liao 已提交
2935
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
2936
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2937 2938 2939 2940 2941 2942
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2943
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
2944 2945
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2946 2947

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2948 2949
}

S
slguan 已提交
2950 2951 2952 2953 2954 2955
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2956

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

H
hjxilinx 已提交
2960 2961
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2962

S
slguan 已提交
2963
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
2964 2965
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
2966

H
hjxilinx 已提交
2967
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980
  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];
    }
2981 2982 2983 2984

    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
2985 2986 2987
  } else if (sqlOptr == TK_OR) {
    // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
    pColFilter = addColumnFilterInfo(pColumn);
2988 2989 2990
    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
2991
  } else {  // error;
2992
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2993 2994
  }

2995
  pColFilter->filterstr =
S
slguan 已提交
2996 2997
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

2998
  if (pColFilter->filterstr) {
S
slguan 已提交
2999
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
3000
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3001
    }
S
slguan 已提交
3002 3003
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
3004
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
3005
    }
H
Hui Li 已提交
3006 3007 3008
    
    if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
      if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
3009
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Hui Li 已提交
3010 3011
      }
    }
S
slguan 已提交
3012 3013 3014
  }

  pColumn->colIndex = *pIndex;
3015
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
3016 3017
}

3018
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3019 3020 3021 3022 3023
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

3024
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
3025 3026 3027 3028 3029 3030 3031 3032 3033
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

3034
UNUSED_FUNC
3035
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3036 3037 3038 3039 3040 3041 3042
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3044
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
3045
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3046
      return ret;
H
hzcheng 已提交
3047
    }
S
slguan 已提交
3048

3049
    relToString(pExpr, str);
S
slguan 已提交
3050

3051
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
3052 3053 3054 3055

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

H
hzcheng 已提交
3056 3057 3058
    return ret;
  }

S
slguan 已提交
3059 3060 3061
  return tSQLExprLeafToString(pExpr, true, str);
}

3062
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
3063 3064 3065 3066
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
3069 3070
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
3071

S
slguan 已提交
3072
  if (!isTablenameToken(&pLeft->colInfo)) {
3073
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3074 3075
  }

S
slguan 已提交
3076
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3077

S
slguan 已提交
3078
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
3079
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
3080
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3081
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
3082
  }
H
hzcheng 已提交
3083

S
slguan 已提交
3084
  if (ret != TSDB_CODE_SUCCESS) {
3085
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3086
  }
H
hzcheng 已提交
3087

S
slguan 已提交
3088 3089 3090
  return ret;
}

3091
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3092 3093 3094 3095 3096
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
3097
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3098 3099 3100 3101
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3102
    return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3103 3104
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3105
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3106
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3107
    }
S
slguan 已提交
3108

3109
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3110
  }
S
slguan 已提交
3111
}
H
hzcheng 已提交
3112

3113
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
H
Haojun Liao 已提交
3114 3115 3116
  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 已提交
3117

S
slguan 已提交
3118 3119 3120
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3121

S
slguan 已提交
3122
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
3123
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3124 3125
  }

3126
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3127 3128 3129 3130
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3131 3132
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3133 3134
  }

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

3138
  pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3139
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3140
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3141 3142

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3143 3144
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3145 3146
  }

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

3150
  pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3151
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3152
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3153

H
Haojun Liao 已提交
3154
  if (pTagSchema1->type != pTagSchema2->type) {
3155
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3156 3157
  }

S
slguan 已提交
3158
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3159 3160 3161 3162
  return TSDB_CODE_SUCCESS;
}

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

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

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3170
    doArithmeticExprToString(pLeft, exprString);
H
hzcheng 已提交
3171
  } else {
S
slguan 已提交
3172
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3173
    if (ret != TSDB_CODE_SUCCESS) {
3174
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3175 3176 3177 3178 3179 3180
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3181
    doArithmeticExprToString(pRight, exprString);
H
hzcheng 已提交
3182
  } else {
S
slguan 已提交
3183
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3184
    if (ret != TSDB_CODE_SUCCESS) {
3185
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3186 3187 3188
    }
  }

H
hjxilinx 已提交
3189
  *(*exprString)++ = ')';
H
hzcheng 已提交
3190 3191 3192 3193

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
3194
static UNUSED_FUNC int32_t arithmeticExprToString(tSQLExpr* pExpr, char** str) {
3195 3196 3197 3198
  char* start = *str;

  int32_t code = doArithmeticExprToString(pExpr, str);
  if (code == TSDB_CODE_SUCCESS) { // remove out the parenthesis
S
Shengliang Guan 已提交
3199
    int32_t len = (int32_t)strlen(start);
3200 3201 3202 3203 3204 3205 3206
    memmove(start, start + 1, len - 2);
    start[len - 2] = 0;
  }

  return code;
}

3207
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3208
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3209 3210 3211
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
3212
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3213
    }
L
lihui 已提交
3214

H
hjxilinx 已提交
3215
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3216
    if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3217
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3218 3219 3220
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3221
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3222 3223
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3224 3225
    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)) {
3226
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3227 3228 3229
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3230
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
3231
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3232 3233 3234 3235
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
3236
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3237 3238
    }

S
TD-1057  
Shengliang Guan 已提交
3239
    int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
3240
  
H
hjxilinx 已提交
3241 3242 3243
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
    // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
3244
    if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
3245
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3246
    }
H
hzcheng 已提交
3247 3248 3249 3250 3251
  }

  return TSDB_CODE_SUCCESS;
}

3252
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3253 3254 3255 3256 3257 3258
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3259
    int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3260 3261 3262 3263
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3264
    int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3265 3266 3267 3268 3269 3270 3271
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3272
    int32_t ret = validateArithmeticSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3273 3274 3275 3276
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3277
    int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292
    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 已提交
3293 3294 3295
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3296 3297 3298
   *
   * However, columnA < 4+12 is valid
   */
B
Bomin Zhang 已提交
3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314
  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 已提交
3315 3316 3317 3318 3319 3320
    return false;
  }

  return true;
}

S
slguan 已提交
3321 3322 3323
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3324

S
slguan 已提交
3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349
  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 已提交
3350

S
slguan 已提交
3351 3352 3353 3354 3355
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3356
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369
  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) {
3370
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3371 3372 3373 3374 3375
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3376 3377
  if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3378
    return false;
H
hzcheng 已提交
3379 3380
  }

S
slguan 已提交
3381
  // todo extract function
H
hjxilinx 已提交
3382
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3383
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3384 3385
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3386
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3387
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3388 3389 3390
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3391
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3392 3393
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3394
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3395
    return false;
H
hzcheng 已提交
3396 3397
  }

S
slguan 已提交
3398
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3399
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3400
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
S
slguan 已提交
3401 3402
    return false;
  }
H
hzcheng 已提交
3403

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

S
slguan 已提交
3407 3408 3409 3410 3411 3412
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 已提交
3413 3414 3415
    }
  }

S
slguan 已提交
3416
  return false;
H
hzcheng 已提交
3417 3418
}

3419
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3420 3421
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3422
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3423
    }
H
hzcheng 已提交
3424

S
slguan 已提交
3425 3426 3427 3428
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3429

S
slguan 已提交
3430 3431
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3432

3433 3434
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                                     int32_t* type, int32_t parentOptr) {
3435
  const char* msg1 = "table query cannot use tags filter";
S
slguan 已提交
3436 3437 3438
  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 已提交
3439 3440 3441
  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";
3442 3443
  const char* msg8 = "wildcard string should be less than 20 characters";
  
S
slguan 已提交
3444 3445
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3446

S
slguan 已提交
3447 3448 3449
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3450 3451
  if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3452 3453
  }

S
slguan 已提交
3454 3455
  assert(isExprDirectParentOfLeaftNode(*pExpr));

H
hjxilinx 已提交
3456
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3457
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3458 3459

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3460
    if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3461
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3462
    }
S
slguan 已提交
3463 3464 3465

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
H
hjxilinx 已提交
3466
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
S
slguan 已提交
3467 3468 3469 3470 3471 3472 3473 3474
      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 {
3475
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3476 3477 3478 3479
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3480 3481
  } 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 已提交
3482
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3483
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3484 3485 3486 3487 3488
    }

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

H
hjxilinx 已提交
3492
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3493 3494 3495

      if ((!isTablenameToken(&pLeft->colInfo)) && pSchema[index.columnIndex].type != TSDB_DATA_TYPE_BINARY &&
          pSchema[index.columnIndex].type != TSDB_DATA_TYPE_NCHAR) {
3496
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3497 3498 3499 3500 3501 3502
      }
    }

    // in case of in operator, keep it in a seperate attribute
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3503
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
3504
      }
3505 3506
  
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
3507
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
3508
      }
S
slguan 已提交
3509 3510 3511 3512 3513 3514

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3515
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
3516 3517 3518 3519 3520 3521
      }

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

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

3530 3531
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545
        *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
3546
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
3547 3548
    }

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

S
slguan 已提交
3553
  return ret;
H
hzcheng 已提交
3554 3555
}

3556 3557
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                        int32_t* type, int32_t parentOptr) {
H
hzcheng 已提交
3558 3559 3560 3561
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3564 3565 3566 3567
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3568
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3569 3570
  }

S
slguan 已提交
3571 3572
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3573

S
slguan 已提交
3574
  if (!isExprDirectParentOfLeaftNode(*pExpr)) {
3575
    int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3576 3577 3578 3579
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3580
    ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3581 3582 3583
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3584

S
slguan 已提交
3585 3586 3587 3588 3589 3590
    /*
     *  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)) {
3591
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3592
      }
H
hzcheng 已提交
3593 3594
    }

S
slguan 已提交
3595 3596 3597
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3598

S
slguan 已提交
3599
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3600

3601
  return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3602
}
H
hzcheng 已提交
3603

S
slguan 已提交
3604 3605 3606 3607
static void doCompactQueryExpr(tSQLExpr** pExpr) {
  if (*pExpr == NULL || isExprDirectParentOfLeaftNode(*pExpr)) {
    return;
  }
H
hzcheng 已提交
3608

S
slguan 已提交
3609 3610 3611
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3612

S
slguan 已提交
3613 3614 3615
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3616

S
slguan 已提交
3617 3618 3619 3620
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3621

S
slguan 已提交
3622 3623 3624
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3625

S
slguan 已提交
3626 3627 3628 3629
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3630

S
slguan 已提交
3631
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3632
  }
S
slguan 已提交
3633
}
H
hzcheng 已提交
3634

3635
static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
S
slguan 已提交
3636 3637 3638 3639
  if (isExprDirectParentOfLeaftNode(*pExpr)) {
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3640
    if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3641
      return;
H
hzcheng 已提交
3642 3643
    }

S
slguan 已提交
3644 3645 3646 3647
    if (index.tableIndex != tableIndex) {
      return;
    }

H
Haojun Liao 已提交
3648
    SStrToken t = {0};
S
slguan 已提交
3649 3650 3651 3652 3653 3654 3655 3656
    extractTableNameFromToken(&pLeft->colInfo, &t);

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

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

3657 3658
    doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3659 3660 3661
  }
}

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

S
slguan 已提交
3665
  if (*pExpr != NULL) {
3666
    doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3667
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3668 3669
  }

S
slguan 已提交
3670
  return pResExpr;
H
hzcheng 已提交
3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685
}

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

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

S
slguan 已提交
3690 3691 3692 3693
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3696
  STagCond* pTagCond = &pQueryInfo->tagCond;
3697
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
S
slguan 已提交
3698 3699 3700 3701

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3702
    char* str = taosStringBuilderGetResult(sb, NULL);
3703
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3704 3705 3706
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
3707
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
3708
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3709

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

S
slguan 已提交
3712
  // remove the duplicated input table names
H
hzcheng 已提交
3713
  int32_t num = 0;
H
hjxilinx 已提交
3714 3715 3716
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3717
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3718 3719 3720 3721 3722 3723 3724 3725 3726

  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 已提交
3727
  char* name = extractDBName(pTableMetaInfo->name, db);
H
Haojun Liao 已提交
3728
  SStrToken dbToken = { .type = TK_STRING, .z = name, .n = (uint32_t)strlen(name) };
H
hjxilinx 已提交
3729
  
H
hzcheng 已提交
3730 3731
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3732
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3733
    }
H
hjxilinx 已提交
3734

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

3739
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3740
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3741
      taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3742
      taosTFree(segments);
H
hjxilinx 已提交
3743

3744
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
3745 3746
      return ret;
    }
H
hjxilinx 已提交
3747

H
hjxilinx 已提交
3748
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3749
  }
H
hjxilinx 已提交
3750

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

H
hjxilinx 已提交
3754
  taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3755
  taosTFree(segments);
H
hzcheng 已提交
3756 3757 3758
  return TSDB_CODE_SUCCESS;
}

3759
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
3760 3761 3762 3763 3764 3765
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
3766

3767 3768
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
3769 3770
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
3771

3772
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786
          (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;
}

3787
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
3788 3789
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
3790 3791 3792 3793 3794

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

S
slguan 已提交
3795 3796
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    if (pExpr->nSQLOptr == TK_OR) {
3797
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3798
    }
H
hzcheng 已提交
3799

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

3802
    return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
S
slguan 已提交
3803 3804
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3805
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3806
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3807 3808
    }

H
hjxilinx 已提交
3809
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3810
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3811
    
S
slguan 已提交
3812 3813
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3814 3815
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
3816
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3817 3818 3819
    }

    // update the timestamp query range
H
hjxilinx 已提交
3820 3821
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
3822 3823
    }

H
hjxilinx 已提交
3824 3825
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
3826 3827 3828 3829 3830 3831
    }
  }

  return TSDB_CODE_SUCCESS;
}

3832
static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
3833 3834 3835 3836
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

3837 3838
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
3839 3840
      return TSDB_CODE_SUCCESS;
    } else {
3841
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3842 3843 3844
    }
  }

H
hjxilinx 已提交
3845
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
3846
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // for stable join, tag columns
3847
                                                   // must be present for join
S
slguan 已提交
3848
    if (pCondExpr->pJoinExpr == NULL) {
3849
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3850 3851 3852 3853
    }
  }

  if (!pCondExpr->tsJoin) {
3854
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3855 3856
  }

S
slguan 已提交
3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881
  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);
  }
}

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

3887
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
3888 3889
      tscError("%p: invalid column name (left)", pQueryInfo);
    }
H
hjxilinx 已提交
3890
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3891 3892
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3893 3894
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
  
3895
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
3896 3897
      tscError("%p: invalid column name (right)", pQueryInfo);
    }
H
hjxilinx 已提交
3898
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3899 3900
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3901
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
3902
  }
H
hjxilinx 已提交
3903
}
S
slguan 已提交
3904

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

3908 3909 3910 3911 3912
  if (pCondExpr->pTagCond == NULL) {
    return ret;
  }
  
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
3913
    tSQLExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
H
Haojun Liao 已提交
3914 3915 3916 3917
    if (p1 == NULL) {  // no query condition on this table
      continue;
    }

3918
    tExprNode* p = NULL;
3919 3920
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
3921
    ret = exprTreeFromSqlExpr(pCmd, &p, p1, NULL, pQueryInfo, colList);
3922 3923 3924 3925 3926 3927 3928 3929 3930
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
3931
    
3932 3933
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
3934
    int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
3935 3936 3937 3938 3939 3940
    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 已提交
3941
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
3942 3943
    }
    
3944
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
3945 3946 3947 3948
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
3949 3950
    
    taosArrayDestroy(colList);
H
hjxilinx 已提交
3951
  }
H
hjxilinx 已提交
3952

3953
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
3954 3955
  return ret;
}
3956
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
3957 3958 3959
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
3960

H
hjxilinx 已提交
3961
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
3962
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
3963

H
hjxilinx 已提交
3964
  int32_t ret = TSDB_CODE_SUCCESS;
3965
  pQueryInfo->window = TSWINDOW_INITIALIZER;
S
slguan 已提交
3966

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

H
hjxilinx 已提交
3971
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
3972
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
S
slguan 已提交
3973 3974
  }

H
hjxilinx 已提交
3975
  int32_t type = 0;
3976
  if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3977 3978
    return ret;
  }
H
hjxilinx 已提交
3979

S
slguan 已提交
3980
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
3981

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

S
slguan 已提交
3985
  // 1. check if it is a join query
3986
  if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3987 3988
    return ret;
  }
H
hjxilinx 已提交
3989

S
slguan 已提交
3990
  // 2. get the query time range
3991
  if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3992 3993
    return ret;
  }
H
hjxilinx 已提交
3994

S
slguan 已提交
3995
  // 3. get the tag query condition
3996
  if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3997
    return ret;
S
slguan 已提交
3998
  }
H
hjxilinx 已提交
3999

S
slguan 已提交
4000
  // 4. get the table name query condition
4001
  if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4002 4003
    return ret;
  }
H
hjxilinx 已提交
4004

S
slguan 已提交
4005
  // 5. other column query condition
4006
  if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4007 4008
    return ret;
  }
H
hjxilinx 已提交
4009

S
slguan 已提交
4010
  // 6. join condition
4011
  if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4012
    return ret;
H
hzcheng 已提交
4013
  }
H
hjxilinx 已提交
4014

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

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

4021
  if (!validateFilterExpr(pQueryInfo)) {
4022
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
4023
  }
H
hjxilinx 已提交
4024

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

H
hjxilinx 已提交
4027
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
4028 4029 4030
  return ret;
}

H
hjxilinx 已提交
4031
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
4032 4033 4034 4035 4036
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
4037 4038
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
4039
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
4040 4041
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
4042
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4043
  }
H
hzcheng 已提交
4044 4045 4046 4047

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

S
slguan 已提交
4050
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
4051
    if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
4052
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4053 4054
        parsed = true;
      } else {
4055
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4056
      }
S
slguan 已提交
4057
    } else {
H
Haojun Liao 已提交
4058
      SStrToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
S
slguan 已提交
4059 4060 4061
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
4062
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4063
      }
H
hzcheng 已提交
4064 4065 4066 4067
    }
  } 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 已提交
4068
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083
     *
     * 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
     */
4084
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105

    /*
     * 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 已提交
4106
    win->ekey = val;
H
hzcheng 已提交
4107
  } else if (optr == TK_LT) {
H
hjxilinx 已提交
4108
    win->ekey = val - delta;
H
hzcheng 已提交
4109
  } else if (optr == TK_GT) {
H
hjxilinx 已提交
4110
    win->skey = val + delta;
H
hzcheng 已提交
4111
  } else if (optr == TK_GE) {
H
hjxilinx 已提交
4112
    win->skey = val;
H
hzcheng 已提交
4113
  } else if (optr == TK_EQ) {
H
hjxilinx 已提交
4114
    win->ekey = win->skey = val;
H
hzcheng 已提交
4115 4116 4117 4118
  }
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
4123 4124
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
B
Bomin Zhang 已提交
4125
    for (int32_t j = 0; j < (TSDB_COL_NAME_LEN - 1) && fieldName[j] != 0; ++j) {
S
slguan 已提交
4126 4127 4128 4129 4130
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
4131 4132
      }
    }
S
slguan 已提交
4133

H
hzcheng 已提交
4134 4135 4136 4137
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4138 4139 4140
  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 已提交
4141
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4142
        const char* msg = "duplicated column name in new table";
4143
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4144 4145 4146 4147 4148 4149 4150
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4151
int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
4152 4153 4154 4155
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
4156 4157 4158 4159

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

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4162
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4163
  }
H
hjxilinx 已提交
4164 4165 4166
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
4167 4168 4169
  if (pQueryInfo->fillVal == NULL) {
    pQueryInfo->fillVal = calloc(size, sizeof(int64_t));
    if (pQueryInfo->fillVal == NULL) {
4170
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4171 4172 4173
    }
  }

H
hzcheng 已提交
4174
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4175
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4176
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4177
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4178 4179
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
4180 4181 4182 4183 4184
      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 已提交
4185 4186
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4187
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4188
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4189
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4190
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4191
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4192 4193

    if (pFillToken->nExpr == 1) {
4194
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4195 4196 4197 4198 4199 4200
    }

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

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

H
hjxilinx 已提交
4204
      if (numOfFillVal > size) {
S
TD-1057  
Shengliang Guan 已提交
4205
        numOfFillVal = (int32_t)size;
H
hzcheng 已提交
4206 4207
      }
    } else {
S
TD-1057  
Shengliang Guan 已提交
4208
      numOfFillVal = (pFillToken->nExpr >  (int32_t)size) ? (int32_t)size : pFillToken->nExpr;
H
hzcheng 已提交
4209 4210 4211 4212 4213
    }

    int32_t j = 1;

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

4216
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4217
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
4218 4219
        continue;
      }
H
hjxilinx 已提交
4220

4221
      int32_t ret = tVariantDump(&pFillToken->a[j].pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4222
      if (ret != TSDB_CODE_SUCCESS) {
4223
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4224 4225
      }
    }
H
hjxilinx 已提交
4226
    
4227
    if ((pFillToken->nExpr < size) || ((pFillToken->nExpr - 1 < size) && (tscIsPointInterpQuery(pQueryInfo)))) {
H
hzcheng 已提交
4228 4229
      tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1];

H
hjxilinx 已提交
4230 4231
      for (int32_t i = numOfFillVal; i < size; ++i) {
        TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4232 4233

        if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4234
          setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
H
hjxilinx 已提交
4235
        } else {
4236
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4237 4238 4239 4240
        }
      }
    }
  } else {
4241
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4242 4243 4244 4245 4246
  }

  return TSDB_CODE_SUCCESS;
}

4247
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4248
  /* set default timestamp order information for all queries */
4249
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
hjxilinx 已提交
4250
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4251

4252
  if (isTopBottomQuery(pQueryInfo)) {
4253
    pQueryInfo->order.order = TSDB_ORDER_ASC;
4254
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4255
  } else {
4256
    pQueryInfo->order.orderColId = -1;
H
hzcheng 已提交
4257 4258
  }

H
hjxilinx 已提交
4259
  /* for super table query, set default ascending order for group output */
weixin_48148422's avatar
weixin_48148422 已提交
4260
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
4261
    pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
H
hzcheng 已提交
4262 4263 4264
  }
}

4265
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4266 4267 4268 4269
  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 已提交
4270

4271
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4272
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4273 4274 4275 4276 4277 4278

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

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4279 4280 4281 4282 4283 4284 4285

  /*
   * 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 已提交
4286
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4287
    if (pSortorder->nExpr > 1) {
4288
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4289 4290 4291
    }
  } else {
    if (pSortorder->nExpr > 2) {
4292
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303
    }
  }

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

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

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

weixin_48148422's avatar
weixin_48148422 已提交
4307
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4308 4309
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4310 4311 4312 4313
    }

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

H
hjxilinx 已提交
4315 4316
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4317
      
4318 4319
      // it is a tag column
      if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
4320
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4321
      }
4322 4323
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (relTagIndex == pColIndex->colIndex) {
H
hzcheng 已提交
4324 4325
        orderByTags = true;
      }
S
slguan 已提交
4326 4327
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4328 4329
    }

S
slguan 已提交
4330
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4331 4332 4333
      orderByTS = true;
    }

4334
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
4335
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4336 4337 4338 4339 4340 4341
    } else {
      assert(!(orderByTags && orderByTS));
    }

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

4349
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4350
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4351
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
4352
        }
4353

4354 4355
        pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4356
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4357
      } else {
4358 4359
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4360 4361 4362 4363
      }
    }

    if (pSortorder->nExpr == 2) {
S
slguan 已提交
4364
      if (orderByTags) {
H
hjxilinx 已提交
4365
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4366
        pQueryInfo->groupbyExpr.orderType = pQuerySql->pSortOrder->a[0].sortOrder;
S
slguan 已提交
4367
      } else {
4368 4369
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4370 4371
      }

H
hzcheng 已提交
4372
      tVariant* pVar2 = &pSortorder->a[1].pVar;
H
Haojun Liao 已提交
4373
      SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4374 4375
      if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4376 4377 4378
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4379
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4380
      } else {
4381 4382
        pQueryInfo->order.order = pSortorder->a[1].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4383 4384 4385 4386
      }
    }

  } else {  // meter query
4387 4388
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4389 4390
    }

4391
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
4392
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4393 4394
    }

4395
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4396
      /* order of top/bottom query in interval is not valid  */
4397
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4398
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4399

4400
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4401
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4402
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4403
      }
4404

4405 4406
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4407 4408
      return TSDB_CODE_SUCCESS;
    }
4409

4410
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4411 4412 4413 4414 4415 4416
  }

  return TSDB_CODE_SUCCESS;
}

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

4419 4420 4421 4422 4423 4424
  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 已提交
4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439
  
  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 已提交
4440 4441
  const char* msg19 = "invalid new tag name";

S
slguan 已提交
4442
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4443
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4444 4445
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4448
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4449
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
4450
  }
P
plum-lihui 已提交
4451

H
Haojun Liao 已提交
4452
  if (tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql) != TSDB_CODE_SUCCESS) {
4453
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4454 4455
  }

H
hjxilinx 已提交
4456
  int32_t ret = tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
4457 4458 4459 4460
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

H
hjxilinx 已提交
4461
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4462

4463 4464
  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 已提交
4465
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
4466
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4467
    }
weixin_48148422's avatar
weixin_48148422 已提交
4468
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) {
4469
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
4470
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4471
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4472
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
4473 4474
  }

4475
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
hzcheng 已提交
4476 4477
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4478
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
4479 4480 4481
    }

    if (!validateOneTags(pCmd, &pFieldList->p[0])) {
4482
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4483
    }
H
hjxilinx 已提交
4484 4485
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4486
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
H
hjxilinx 已提交
4487
    if (tscGetNumOfTags(pTableMeta) == 1) {
4488
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
4489 4490 4491 4492
    }

    // numOfTags == 1
    if (pAlterSQL->varList->nExpr > 1) {
4493
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
hzcheng 已提交
4494 4495 4496
    }

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

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

4504
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4505
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4506 4507
    }

H
Haojun Liao 已提交
4508 4509
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
4510
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
H
Haojun Liao 已提交
4511
    } else if (index.columnIndex == numOfCols) {
4512
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
H
hzcheng 已提交
4513 4514
    }

4515 4516
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4517 4518 4519
  
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4520
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
hzcheng 已提交
4521 4522
    tVariantList* pVarList = pAlterSQL->varList;
    if (pVarList->nExpr > 2) {
4523
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4524 4525
    }

4526 4527 4528 4529
    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) {
4530
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4531 4532
    }

4533
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4534
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
4535
    }
H
hzcheng 已提交
4536

S
slguan 已提交
4537 4538
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4539

H
Haojun Liao 已提交
4540
    SStrToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4541
    if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4542
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4543 4544
    }

H
Haojun Liao 已提交
4545
    SStrToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4546
    if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4547
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
H
hzcheng 已提交
4548 4549
    }

B
Bomin Zhang 已提交
4550
    char name[TSDB_COL_NAME_LEN] = {0};
H
hzcheng 已提交
4551
    strncpy(name, pVarList->a[0].pVar.pz, pVarList->a[0].pVar.nLen);
H
hjxilinx 已提交
4552 4553
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4554 4555 4556

    memset(name, 0, tListLen(name));
    strncpy(name, pVarList->a[1].pVar.pz, pVarList->a[1].pVar.nLen);
H
hjxilinx 已提交
4557 4558
    f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4559 4560
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
    // Note: update can only be applied to table not super table.
4561 4562 4563
    // the following is used to handle tags value for table created according to super table
    pCmd->command = TSDB_SQL_UPDATE_TAGS_VAL;
    
H
hzcheng 已提交
4564 4565
    tVariantList* pVarList = pAlterSQL->varList;
    tVariant*     pTagName = &pVarList->a[0].pVar;
4566
    int16_t       numOfTags = tscGetNumOfTags(pTableMeta);
H
hzcheng 已提交
4567

4568
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4569
    SStrToken    name = {.type = TK_STRING, .z = pTagName->pz, .n = pTagName->nLen};
4570
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4571
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4572 4573
    }

H
hjxilinx 已提交
4574
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4575
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12);
S
slguan 已提交
4576 4577
    }

H
hjxilinx 已提交
4578
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
4579
    if (tVariantDump(&pVarList->a[1].pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) {
4580
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg13);
H
hzcheng 已提交
4581
    }
4582
    
4583
    pAlterSQL->tagData.dataLen = pTagsSchema->bytes;
H
hzcheng 已提交
4584 4585

    // validate the length of binary
4586
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
4587
        (pVarList->a[1].pVar.nLen + VARSTR_HEADER_SIZE) > pTagsSchema->bytes) {
4588
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg14);
H
hzcheng 已提交
4589
    }
4590 4591 4592 4593

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

4594 4595
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4596
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4597 4598
    }

4599
    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
4600
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
4601 4602
    pUpdateMsg->tid       = htonl(pTableMeta->id.tid);
    pUpdateMsg->uid       = htobe64(pTableMeta->id.uid);
H
Haojun Liao 已提交
4603
    pUpdateMsg->colId     = htons(pTagsSchema->colId);
H
Hongze Cheng 已提交
4604
    pUpdateMsg->type      = pTagsSchema->type;
H
Haojun Liao 已提交
4605 4606
    pUpdateMsg->bytes     = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion  = htons(pTableMeta->tversion);
4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624
    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);
4625 4626 4627 4628 4629
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
4630
      len = varDataTLen(pUpdateMsg->data + schemaLen);
4631 4632 4633 4634
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
4635
    int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen;
4636
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4637
    
4638
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
hzcheng 已提交
4639 4640
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4641
      const char* msg = "only support add one column";
4642
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4643 4644 4645
    }

    if (!validateOneColumn(pCmd, &pFieldList->p[0])) {
4646
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4647
    }
H
hjxilinx 已提交
4648 4649
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4650
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
H
hjxilinx 已提交
4651
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
H
hjxilinx 已提交
4652
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15);
H
hzcheng 已提交
4653 4654 4655
    }

    if (pAlterSQL->varList->nExpr > 1) {
H
hjxilinx 已提交
4656
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4657 4658 4659 4660
    }

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

4661
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4662
    SStrToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4663 4664
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4665 4666
    }

4667
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4668
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18);
4669
    }
H
hzcheng 已提交
4670

B
Bomin Zhang 已提交
4671 4672
    char name1[TSDB_COL_NAME_LEN] = {0};
    tstrncpy(name1, pItem->pVar.pz, sizeof(name1));
H
hjxilinx 已提交
4673 4674
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4675 4676 4677 4678 4679
  }

  return TSDB_CODE_SUCCESS;
}

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

4684 4685 4686
  if (pQueryInfo->intervalTime != 0 && pQueryInfo->intervalTime < 10 &&
     pQueryInfo->intervalTimeUnit != 'n' &&
     pQueryInfo->intervalTimeUnit != 'y') {
4687
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4688
  }
H
hjxilinx 已提交
4689
  
H
hjxilinx 已提交
4690
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4691
  for (int32_t i = 0; i < size; ++i) {
4692
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
4693
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
4694
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4695 4696 4697 4698 4699 4700
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
4705
  // multi-output set/ todo refactor
H
hjxilinx 已提交
4706
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4707 4708
  
  for (int32_t k = 0; k < size; ++k) {
4709
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
4710

4711 4712 4713
    // 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 已提交
4714
      for (int32_t j = 0; j < size; ++j) {
4715
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
4716 4717 4718 4719 4720
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
4721

4722 4723 4724 4725
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4726

4727
    if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4728
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4729 4730 4731
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4732 4733

  if (isProjectionFunction) {
4734
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4735 4736
  }

4737
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4738 4739 4740
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4741 4742
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4743 4744
} SDNodeDynConfOption;

H
Hui Li 已提交
4745

4746
int32_t validateEp(char* ep) {  
H
Hui Li 已提交
4747 4748 4749
  char buf[TSDB_EP_LEN + 1] = {0};
  tstrncpy(buf, ep, TSDB_EP_LEN);

4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760
  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 已提交
4761 4762
  }

4763
  return TSDB_CODE_SUCCESS;
H
Hui Li 已提交
4764 4765
}

H
hzcheng 已提交
4766 4767
int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
4768
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4769 4770
  }

4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782
  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 已提交
4783

H
Haojun Liao 已提交
4784
  SStrToken* pOptionToken = &pOptions->a[1];
H
hzcheng 已提交
4785 4786 4787

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
4788 4789
    for (int32_t i = 0; i < tokenLogEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4790 4791 4792 4793
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
4794 4795
  } else if ((strncasecmp(cfgOptions[tokenBalance].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenBalance].len == pOptionToken->n)) {
H
Haojun Liao 已提交
4796
    SStrToken* pValToken = &pOptions->a[2];
S
Shengliang Guan 已提交
4797 4798
    int32_t vnodeId = 0;
    int32_t dnodeId = 0;
4799
    strdequote(pValToken->z);
S
Shengliang Guan 已提交
4800
    bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId);
4801 4802 4803 4804 4805 4806
    if (!parseOk) {
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
    }
    return TSDB_CODE_SUCCESS;
  } else if ((strncasecmp(cfgOptions[tokenMonitor].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenMonitor].len == pOptionToken->n)) {
H
Haojun Liao 已提交
4807
    SStrToken* pValToken = &pOptions->a[2];
S
slguan 已提交
4808 4809
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
4810
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
S
slguan 已提交
4811 4812
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4813
  } else {
H
Haojun Liao 已提交
4814
    SStrToken* pValToken = &pOptions->a[2];
H
hzcheng 已提交
4815 4816

    int32_t val = strtol(pValToken->z, NULL, 10);
4817
    if (val < 0 || val > 256) {
H
hzcheng 已提交
4818
      /* options value is out of valid range */
4819
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4820 4821
    }

4822 4823
    for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4824 4825 4826 4827 4828 4829 4830 4831

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

4832
  return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4833 4834
}

S
slguan 已提交
4835 4836
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
4837
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4838 4839
  }

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

H
Haojun Liao 已提交
4843
  SStrToken* pOptionToken = &pOptions->a[0];
S
slguan 已提交
4844 4845 4846 4847 4848 4849 4850 4851 4852 4853

  if (pOptions->nTokens == 1) {
    // reset log does not need value
    for (int32_t i = 0; i < 1; ++i) {
      SDNodeDynConfOption* pOption = &LOCAL_DYNAMIC_CFG_OPTIONS[i];
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
  } else {
H
Haojun Liao 已提交
4854
    SStrToken* pValToken = &pOptions->a[1];
S
slguan 已提交
4855 4856 4857 4858

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
4859
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4860 4861 4862 4863 4864 4865 4866 4867 4868 4869
    }

    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;
      }
    }
  }
4870
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4871 4872
}

H
hzcheng 已提交
4873
int32_t validateColumnName(char* name) {
S
TD-1057  
Shengliang Guan 已提交
4874
  bool ret = isKeyWord(name, (int32_t)strlen(name));
H
hzcheng 已提交
4875
  if (ret) {
4876
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4877 4878
  }

H
Haojun Liao 已提交
4879
  SStrToken token = {.z = name};
H
hzcheng 已提交
4880 4881 4882
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
4883
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4884 4885 4886 4887
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
S
TD-1057  
Shengliang Guan 已提交
4888
    token.n = (uint32_t)strtrim(token.z);
H
hzcheng 已提交
4889 4890 4891

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
4892
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4893 4894 4895 4896 4897
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
4898
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4899 4900 4901 4902 4903 4904
    }
  }

  return TSDB_CODE_SUCCESS;
}

4905 4906
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
4907 4908 4909
    return true;
  }

H
hjxilinx 已提交
4910
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
4911 4912
}

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

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

H
hzcheng 已提交
4921
  // handle the limit offset value, validate the limit
4922
  pQueryInfo->limit = pQuerySql->limit;
4923
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4924
  pQueryInfo->slimit = pQuerySql->slimit;
4925
  
4926
  tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
4927 4928
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
4929
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
4930
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
4931 4932
  }

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

H
hjxilinx 已提交
4939
  // todo refactor
weixin_48148422's avatar
weixin_48148422 已提交
4940
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
4941
    if (!tscQueryTags(pQueryInfo)) {  // local handle the super table tag query
4942
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
4943
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
4944
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
4945
        }
H
hjxilinx 已提交
4946

4947
        // for projection query on super table, all queries are subqueries
H
hjxilinx 已提交
4948 4949
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
            !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
4950
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
4951
        }
S
slguan 已提交
4952
      }
H
hzcheng 已提交
4953 4954
    }

4955
    if (pQueryInfo->slimit.limit == 0) {
4956
      tscDebug("%p slimit 0, no output result", pSql);
4957
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4958 4959 4960 4961
      return TSDB_CODE_SUCCESS;
    }

    /*
4962 4963 4964 4965
     * 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 已提交
4966
     */
H
hjxilinx 已提交
4967
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
4968 4969 4970 4971
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
4972
    // No tables included. No results generated. Query results are empty.
4973
    if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
4974
      tscDebug("%p no table in super table, no output result", pSql);
4975
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4976
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4977 4978 4979
    }

    // keep original limitation value in globalLimit
4980
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4981
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
4982

4983 4984 4985 4986 4987 4988 4989 4990 4991
    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 已提交
4992

4993 4994
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
4995
  } else {
4996
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
4997
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4998
    }
H
hjxilinx 已提交
4999
  
H
hjxilinx 已提交
5000
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
5001 5002 5003
    
    bool hasTags = false;
    bool hasOtherFunc = false;
S
slguan 已提交
5004
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
5005
    for (int32_t i = 0; i < size; ++i) {
5006
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
5007 5008 5009 5010
      if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
        hasTags = true;
      } else {
        hasOtherFunc = true;
H
hzcheng 已提交
5011 5012
      }
    }
5013 5014
    
    if (hasTags && hasOtherFunc) {
5015
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5016
    }
H
hzcheng 已提交
5017 5018 5019 5020
  }

  return TSDB_CODE_SUCCESS;
}
5021

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

5025 5026 5027
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
5028

H
hjxilinx 已提交
5029 5030 5031
  tVariantList* pKeep = pCreateDb->keep;
  if (pKeep != NULL) {
    switch (pKeep->nExpr) {
S
slguan 已提交
5032
      case 1:
S
TD-1057  
Shengliang Guan 已提交
5033
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
5034 5035
        break;
      case 2: {
S
TD-1057  
Shengliang Guan 已提交
5036 5037
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)pKeep->a[1].pVar.i64Key);
5038 5039 5040
        break;
      }
      case 3: {
S
TD-1057  
Shengliang Guan 已提交
5041 5042 5043
        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);
5044 5045
        break;
      }
5046
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
5047 5048
    }
  }
H
hjxilinx 已提交
5049

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

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

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

H
Haojun Liao 已提交
5058
  SStrToken* pToken = &pCreateDbInfo->precision;
5059 5060
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
5061

5062 5063 5064 5065 5066
    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 已提交
5067
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
5068 5069
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
5070
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
5071 5072
    }
  }
H
hjxilinx 已提交
5073

H
hjxilinx 已提交
5074 5075
  return TSDB_CODE_SUCCESS;
}
5076

5077
static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
hjxilinx 已提交
5078 5079
  pMsg->maxTables = htonl(pCreateDb->maxTablesPerVnode);
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
5080
  pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
H
hjxilinx 已提交
5081
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
S
TD-1057  
Shengliang Guan 已提交
5082
  pMsg->commitTime = htonl((int32_t)pCreateDb->commitTime);
H
hjxilinx 已提交
5083 5084
  pMsg->minRowsPerFileBlock = htonl(pCreateDb->minRowsPerBlock);
  pMsg->maxRowsPerFileBlock = htonl(pCreateDb->maxRowsPerBlock);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5085
  pMsg->fsyncPeriod = htonl(pCreateDb->fsyncPeriod);
S
slguan 已提交
5086
  pMsg->compression = pCreateDb->compressionLevel;
H
hjxilinx 已提交
5087
  pMsg->walLevel = (char)pCreateDb->walLevel;
H
hjxilinx 已提交
5088
  pMsg->replications = pCreateDb->replica;
5089
  pMsg->quorum = pCreateDb->quorum;
5090
  pMsg->ignoreExist = pCreateDb->ignoreExists;
H
hjxilinx 已提交
5091 5092 5093
}

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

H
hjxilinx 已提交
5097
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5098
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5099
  }
H
hjxilinx 已提交
5100

H
hjxilinx 已提交
5101
  if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5102
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5103
  }
H
hjxilinx 已提交
5104

H
hjxilinx 已提交
5105
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
5106
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5107
  }
H
hjxilinx 已提交
5108

5109
  return TSDB_CODE_SUCCESS;
H
huili 已提交
5110
}
S
slguan 已提交
5111

H
Haojun Liao 已提交
5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130
//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 已提交
5131

5132 5133
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
5134

5135 5136
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
H
hjxilinx 已提交
5137
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5138
  
S
TD-1057  
Shengliang Guan 已提交
5139
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1);
5140

S
slguan 已提交
5141
    if (pExpr->functionId != TSDB_FUNC_TAG) {
H
hjxilinx 已提交
5142
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
5143
      int16_t         columnInfo = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
5144
      SColumnIndex    index = {.tableIndex = 0, .columnIndex = columnInfo};
H
hjxilinx 已提交
5145
      SSchema*        pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5146 5147 5148 5149

      int16_t type = pSchema[index.columnIndex].type;
      int16_t bytes = pSchema[index.columnIndex].bytes;
      char*   name = pSchema[index.columnIndex].name;
H
hjxilinx 已提交
5150
  
5151
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
S
slguan 已提交
5152 5153 5154 5155
      pExpr->colInfo.flag = TSDB_COL_TAG;

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

      int32_t relIndex = index.columnIndex;

5160
      pExpr->colInfo.colIndex = relIndex;
5161 5162
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
5163

5164
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
5165
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
5166 5167 5168 5169
    }
  }
}

H
hjxilinx 已提交
5170 5171 5172
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
5173
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
5174 5175 5176
  pExpr->numOfParams = 1;
}

5177
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
5178
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
H
hjxilinx 已提交
5179
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
5180

H
Haojun Liao 已提交
5181 5182 5183 5184
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

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

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

S
TD-1057  
Shengliang Guan 已提交
5188
  SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, (int32_t)size);
H
Haojun Liao 已提交
5189
  doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
H
hjxilinx 已提交
5190
  pInfo->visible = false;
S
slguan 已提交
5191 5192
}

5193
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5194
  int32_t tagLength = 0;
H
hjxilinx 已提交
5195
  
H
hjxilinx 已提交
5196
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5197 5198
  
  for (int32_t i = 0; i < size; ++i) {
5199
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5200 5201 5202 5203 5204 5205 5206 5207 5208
    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 已提交
5209
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5210
  SSchema*        pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5211

H
hjxilinx 已提交
5212
  for (int32_t i = 0; i < size; ++i) {
5213
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5214
    if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) {
5215
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
S
TD-1057  
Shengliang Guan 已提交
5216
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64Key, &pExpr->resType,
5217
                        &pExpr->resBytes, &pExpr->interBytes, tagLength, true);
S
slguan 已提交
5218 5219 5220 5221
    }
  }
}

5222
static void doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5223
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5224 5225
  
  for (int32_t i = 0; i < size; ++i) {
5226
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5227 5228
    if (pExpr->functionId == TSDB_FUNC_PRJ) {
      bool qualifiedCol = false;
5229
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5230 5231 5232
        SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
  
        if (pExpr->colInfo.colId == pColIndex->colId) {
H
hjxilinx 已提交
5233
          qualifiedCol = true;
H
hjxilinx 已提交
5234
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5235 5236 5237 5238
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
5239

H
hjxilinx 已提交
5240 5241 5242 5243 5244
      assert(qualifiedCol);
    }
  }
}

S
slguan 已提交
5245 5246
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
5247 5248 5249
    SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j);
  
    if (columnId == pColIndex->colId && pColIndex->flag == TSDB_COL_TAG) {
S
slguan 已提交
5250 5251 5252 5253 5254 5255 5256
      return true;
    }
  }

  return false;
}

5257
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5258 5259
  bool hasTagPrj = false;
  bool hasColumnPrj = false;
H
hjxilinx 已提交
5260
  
H
hjxilinx 已提交
5261
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5262
  for (int32_t i = 0; i < size; ++i) {
5263
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274
    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
5275
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5276 5277
  bool allInGroupby = true;

H
hjxilinx 已提交
5278 5279
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5280
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5281 5282 5283 5284
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5285
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5286 5287 5288 5289 5290 5291 5292 5293 5294
      allInGroupby = false;
      break;
    }
  }

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

5295
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5296
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5297 5298
  
  for (int32_t i = 0; i < size; ++i) {
5299
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311
    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.
 */
5312
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) {
S
slguan 已提交
5313
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5314
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5315

S
slguan 已提交
5316 5317 5318 5319
  bool    tagColExists = false;
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5320
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5321
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5322
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5323 5324 5325 5326 5327 5328
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
      tagColExists = true;
      break;
    }
  }
H
hjxilinx 已提交
5329

H
hjxilinx 已提交
5330
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5331
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5332 5333
  
    int16_t functionId = pExpr->functionId;
5334
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5335
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5336
      continue;
S
slguan 已提交
5337
    }
H
hjxilinx 已提交
5338

H
hjxilinx 已提交
5339 5340 5341 5342 5343 5344
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5345

H
hjxilinx 已提交
5346
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5347 5348
    // 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.
5349
    if (numOfAggregation > 0) {
5350
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5351 5352 5353 5354 5355 5356
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5357 5358
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5359 5360 5361 5362 5363
    } 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 已提交
5364 5365
      for (int32_t i = 0; i < numOfExprs; ++i) {
        
5366
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5367 5368 5369 5370 5371
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5372
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5373 5374 5375
        }
      }

5376 5377
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5378 5379
    }
  } else {
5380
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5381
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5382
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5383
      }
H
hjxilinx 已提交
5384

H
hjxilinx 已提交
5385 5386
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5387 5388
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5389
      }
S
slguan 已提交
5390 5391 5392 5393 5394 5395
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

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

H
Haojun Liao 已提交
5401
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5402
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5403 5404 5405 5406
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5407
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5408
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5409
    int16_t colIndex = pColIndex->colIndex;
5410
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5411
      type  = s.type;
H
Haojun Liao 已提交
5412
      bytes = s.bytes;
H
Haojun Liao 已提交
5413
      name  = s.name;
S
slguan 已提交
5414
    } else {
5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425
      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 已提交
5426
    }
H
hjxilinx 已提交
5427 5428 5429
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5430
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5431
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5432
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5433
      
B
Bomin Zhang 已提交
5434 5435
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5436
      
S
slguan 已提交
5437 5438 5439
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5440
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
S
TD-1057  
Shengliang Guan 已提交
5441
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5442 5443
    } else {
      // if this query is "group by" normal column, interval is not allowed
5444
      if (pQueryInfo->intervalTime > 0) {
5445
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5446 5447 5448
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5449
      for (int32_t j = 0; j < size; ++j) {
5450
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5451 5452 5453 5454 5455 5456 5457 5458 5459 5460
        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) {
5461
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5462 5463 5464 5465 5466 5467 5468
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5469
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5470
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5471
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5472
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5473
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5474 5475

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5476
  if (tscQueryTags(pQueryInfo)) {
5477
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5478
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5479 5480 5481 5482 5483
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5484
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5485
    // check if all the tags prj columns belongs to the group by columns
5486 5487
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5488
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5489 5490 5491
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5492 5493
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5494
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5495 5496 5497 5498 5499 5500
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5501
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5502
        bool qualified = false;
5503
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5504
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5505 5506 5507 5508 5509 5510 5511
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5512
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5513 5514 5515 5516
        }
      }

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

5521
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5522
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5523 5524 5525
      }
    }

5526
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5527
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5528 5529 5530 5531 5532 5533
    }

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

H
hjxilinx 已提交
5538
    // projection query on super table does not compatible with "group by" syntax
5539
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5540
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5541
    }
H
hjxilinx 已提交
5542

H
hjxilinx 已提交
5543
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5544
  } else {
5545
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5546 5547
  }
}
H
hjxilinx 已提交
5548

5549
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5550 5551 5552
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5553

H
hjxilinx 已提交
5554 5555
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5556
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5557
  }
H
hjxilinx 已提交
5558

H
hjxilinx 已提交
5559 5560
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5561
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hjxilinx 已提交
5562
  }
H
hjxilinx 已提交
5563

H
hjxilinx 已提交
5564
  // TODO redefine the function
H
hjxilinx 已提交
5565 5566 5567 5568 5569 5570
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5571
  int32_t index = -1;
H
hjxilinx 已提交
5572
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5573
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5574
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5575 5576 5577 5578
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5579 5580 5581

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5582
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5583
    case 1:
H
Haojun Liao 已提交
5584 5585 5586
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5587
    case 3:
H
Haojun Liao 已提交
5588
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5589
    case 4:
H
Haojun Liao 已提交
5590
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5591
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5592
  }
5593 5594 5595 5596 5597 5598
  
  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 已提交
5599
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5600 5601
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5602
}
H
hjxilinx 已提交
5603 5604

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

H
hjxilinx 已提交
5608 5609
  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);
5610
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5611
  }
H
hjxilinx 已提交
5612

H
hjxilinx 已提交
5613
  if (pCreate->replications != -1 &&
5614
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5615
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5616
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5617
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5618
  }
H
hjxilinx 已提交
5619

5620 5621 5622 5623 5624 5625 5626
  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 已提交
5627
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5628
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5629
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5630
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5631
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5632
  }
H
hjxilinx 已提交
5633

H
hjxilinx 已提交
5634 5635 5636 5637
  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);
5638
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5639
  }
H
hjxilinx 已提交
5640

H
hjxilinx 已提交
5641
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5642
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5643
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5644
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5645
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5646
  }
H
hjxilinx 已提交
5647 5648 5649 5650

  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);
5651
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5652
  }
H
hjxilinx 已提交
5653

H
hjxilinx 已提交
5654
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5655
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5656
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5657
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5658
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5659
  }
H
hjxilinx 已提交
5660

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5661 5662 5663 5664 5665 5666 5667
  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 已提交
5668
  if (pCreate->compression != -1 &&
S
slguan 已提交
5669
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5670
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5671
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5672
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5673
  }
H
hjxilinx 已提交
5674

H
hjxilinx 已提交
5675 5676
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5677 5678

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

S
TD-1057  
Shengliang Guan 已提交
5682
  int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
5683
  if (size == 0) {
H
hjxilinx 已提交
5684 5685
    return;
  }
H
hjxilinx 已提交
5686

H
hjxilinx 已提交
5687
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5688 5689

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

H
hjxilinx 已提交
5692 5693
  offset += sprintf(str, "num:%d [", size);
  for (int32_t i = 0; i < size; ++i) {
5694
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5695

L
lihui 已提交
5696
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5697 5698 5699
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5700 5701 5702
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
5704
    if (i < size - 1) {
H
hjxilinx 已提交
5705 5706 5707
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5708

H
hjxilinx 已提交
5709
  str[offset] = ']';
5710
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5711
}
5712

5713
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5714 5715 5716
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5717 5718
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5719
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5720 5721 5722 5723 5724 5725 5726 5727 5728

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;

  tFieldList* pFieldList = pCreateTable->colInfo.pColumns;
  tFieldList* pTagList = pCreateTable->colInfo.pTagColumns;

  assert(pFieldList != NULL);

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
5729
  SStrToken* pzTableName = &(pCreateTable->name);
5730 5731

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5732
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5733 5734
  }

H
Haojun Liao 已提交
5735
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5736
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5737 5738 5739 5740
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
5741
    return TSDB_CODE_TSC_INVALID_SQL;
5742 5743 5744 5745
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
H
hjxilinx 已提交
5746
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[col]);
5747 5748 5749 5750
  }

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

H
hjxilinx 已提交
5751
  if (pTagList != NULL) {  // create super table[optional]
5752
    for (int32_t i = 0; i < pTagList->nField; ++i) {
H
hjxilinx 已提交
5753
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pTagList->p[i]);
5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770
    }

    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;
5771 5772 5773
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
5774 5775 5776
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
5777 5778 5779 5780

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

H
hjxilinx 已提交
5781
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5782 5783

  // super table name, create table by using dst
H
Haojun Liao 已提交
5784
  SStrToken* pToken = &(pCreateTable->usingInfo.stableName);
5785 5786

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5787
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5788 5789
  }

H
Haojun Liao 已提交
5790
  if (tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5791
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5792 5793 5794
  }

  // get meter meta from mnode
B
Bomin Zhang 已提交
5795
  tstrncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, sizeof(pCreateTable->usingInfo.tagdata.name));
5796 5797
  tVariantList* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;

H
hjxilinx 已提交
5798
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5799 5800 5801 5802
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5803
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5804
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5805 5806 5807
  }

  // too long tag values will return invalid sql, not be truncated automatically
H
hjxilinx 已提交
5808
  SSchema* pTagSchema = tscGetTableTagSchema(pStableMeterMetaInfo->pTableMeta);
5809

5810
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
B
Bomin Zhang 已提交
5811 5812 5813 5814 5815
  SKVRowBuilder kvRowBuilder = {0};
  if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
hjxilinx 已提交
5816
  int32_t ret = TSDB_CODE_SUCCESS;
5817
  for (int32_t i = 0; i < pList->nExpr; ++i) {
B
Bomin Zhang 已提交
5818 5819
    SSchema* pSchema = pTagSchema + i;
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
H
hjxilinx 已提交
5820
      // validate the length of binary
B
Bomin Zhang 已提交
5821
      if (pList->a[i].pVar.nLen + VARSTR_HEADER_SIZE > pSchema->bytes) {
B
Bomin Zhang 已提交
5822
        tdDestroyKVRowBuilder(&kvRowBuilder);
H
hjxilinx 已提交
5823 5824 5825 5826
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
    
B
Bomin Zhang 已提交
5827 5828
    char tagVal[TSDB_MAX_TAGS_LEN];
    ret = tVariantDump(&(pList->a[i].pVar), tagVal, pSchema->type, true);
5829
    if (ret != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
5830
      tdDestroyKVRowBuilder(&kvRowBuilder);
5831
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5832 5833
    }

B
Bomin Zhang 已提交
5834
    tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
5835 5836
  }

B
Bomin Zhang 已提交
5837
  SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
B
Bomin Zhang 已提交
5838 5839 5840 5841 5842
  tdDestroyKVRowBuilder(&kvRowBuilder);
  if (row == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  tdSortKVRowByColIdx(row);
B
Bomin Zhang 已提交
5843
  pTag->dataLen = kvRowLen(row);
B
Bomin Zhang 已提交
5844
  kvRowCpy(pTag->data, row);
B
Bomin Zhang 已提交
5845 5846
  free(row);

5847 5848
  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5849
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5850 5851
  }

H
hjxilinx 已提交
5852
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
5853
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866
  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 已提交
5867 5868
  const char* msg6 = "from missing in subclause";
  
5869
  SSqlCmd*    pCmd = &pSql->cmd;
5870
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5871 5872
  assert(pQueryInfo->numOfTables == 1);

5873
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5874
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5875 5876

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
5877
  SStrToken* pzTableName = &(pCreateTable->name);
5878 5879 5880
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5881
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5882
  }
H
Haojun Liao 已提交
5883
  
5884
  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
H
Haojun Liao 已提交
5885 5886 5887 5888 5889
  if (pSrcMeterName == NULL || pSrcMeterName->nExpr == 0) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
  tVariant* pVar = &pSrcMeterName->a[0].pVar;
H
Haojun Liao 已提交
5890
  SStrToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
5891
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
5892
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5893 5894
  }

H
Haojun Liao 已提交
5895
  if (tscSetTableFullName(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5896
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5897 5898
  }

H
hjxilinx 已提交
5899
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5900 5901 5902 5903
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
5904
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
H
Haojun Liao 已提交
5905
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false) != TSDB_CODE_SUCCESS) {
5906
    return TSDB_CODE_TSC_INVALID_SQL;
5907 5908 5909
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5910
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5911
      return TSDB_CODE_TSC_INVALID_SQL;
5912 5913 5914 5915
    }
  }

  // set interval value
5916
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5917
    return TSDB_CODE_TSC_INVALID_SQL;
5918
  } else {
5919
    if ((pQueryInfo->intervalTime > 0) &&
5920
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
5921
      return TSDB_CODE_TSC_INVALID_SQL;
5922 5923 5924 5925
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
5926
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5927
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5928 5929 5930
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5931
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5932 5933
  }

5934
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5935
    return TSDB_CODE_TSC_INVALID_SQL;
5936 5937
  }

H
hjxilinx 已提交
5938
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5939

5940
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5941
    return TSDB_CODE_TSC_INVALID_SQL;
5942 5943 5944 5945 5946 5947 5948
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
5949
    if (pQueryInfo->intervalTime == 0) {
5950
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
5951 5952 5953 5954 5955 5956
    }

    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))) {
5957
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5958 5959 5960 5961 5962
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
5963
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5964 5965 5966 5967 5968 5969
  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 已提交
5970 5971 5972 5973 5974 5975 5976 5977 5978 5979
  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";
5980 5981

  int32_t code = TSDB_CODE_SUCCESS;
5982

5983
  SSqlCmd* pCmd = &pSql->cmd;
5984

5985
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
5986
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5987
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
5988
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
5989
  }
H
hjxilinx 已提交
5990

H
Haojun Liao 已提交
5991 5992
  assert(pCmd->clauseIndex == index);

5993 5994
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
5995
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007
  }

  /*
   * 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);
6008
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
6009 6010
  }

H
Haojun Liao 已提交
6011
  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM * 2) {
6012
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
6013 6014
  }

6015
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
6016

H
Haojun Liao 已提交
6017
  if (pQuerySql->from->nExpr > 4) {
H
Haojun Liao 已提交
6018 6019 6020
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

6021
  // set all query tables, which are maybe more than one.
H
Haojun Liao 已提交
6022
  for (int32_t i = 0; i < pQuerySql->from->nExpr; ) {
6023 6024 6025
    tVariant* pTableItem = &pQuerySql->from->a[i].pVar;

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
6026
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6027 6028 6029 6030
    }

    pTableItem->nLen = strdequote(pTableItem->pz);

H
Haojun Liao 已提交
6031
    SStrToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
6032
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
6033
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6034 6035
    }

H
Haojun Liao 已提交
6036
    if (pQueryInfo->numOfTables <= i/2) {  // more than one table
H
hjxilinx 已提交
6037
      tscAddEmptyMetaInfo(pQueryInfo);
6038 6039
    }

H
Haojun Liao 已提交
6040
    STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i/2);
6041

H
Haojun Liao 已提交
6042
    SStrToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
6043
    if (tscSetTableFullName(pTableMetaInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
6044
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6045 6046
    }

H
Haojun Liao 已提交
6047
    tVariant* pTableItem1 = &pQuerySql->from->a[i + 1].pVar;
H
Haojun Liao 已提交
6048
    SStrToken aliasName = {.z = pTableItem1->pz, .n = pTableItem1->nLen, .type = TK_STRING};
H
Haojun Liao 已提交
6049 6050 6051 6052
    if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

6053 6054 6055 6056 6057 6058
    // 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 已提交
6059 6060

    code = tscGetTableMeta(pSql, pTableMetaInfo1);
6061 6062 6063
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
H
Haojun Liao 已提交
6064 6065

    i += 2;
6066 6067
  }

H
Haojun Liao 已提交
6068
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr / 2);
H
hjxilinx 已提交
6069
  bool isSTable = false;
H
hjxilinx 已提交
6070
  
weixin_48148422's avatar
weixin_48148422 已提交
6071
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
6072 6073 6074 6075 6076 6077 6078
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
6079 6080
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
6081
  }
6082

6083
  // parse the group by clause in the first place
6084
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
6085
    return TSDB_CODE_TSC_INVALID_SQL;
6086 6087
  }

H
Haojun Liao 已提交
6088 6089
  int32_t joinQuery = (pQuerySql->from != NULL && pQuerySql->from->nExpr > 2);
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery) != TSDB_CODE_SUCCESS) {
6090
    return TSDB_CODE_TSC_INVALID_SQL;
6091 6092 6093
  }

  // set interval value
6094
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6095
    return TSDB_CODE_TSC_INVALID_SQL;
6096
  } else {
6097
    if ((pQueryInfo->intervalTime > 0) &&
6098
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6099
      return TSDB_CODE_TSC_INVALID_SQL;
6100 6101 6102 6103
    }
  }

  // set order by info
6104
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
6105
    return TSDB_CODE_TSC_INVALID_SQL;
6106 6107 6108
  }

  // set where info
H
hjxilinx 已提交
6109
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
6110
  
6111
  if (pQuerySql->pWhere != NULL) {
6112
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
6113
      return TSDB_CODE_TSC_INVALID_SQL;
6114 6115 6116
    }

    pQuerySql->pWhere = NULL;
H
hjxilinx 已提交
6117
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
6118 6119
      pQueryInfo->window.skey = pQueryInfo->window.skey / 1000;
      pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000;
6120 6121
    }
  } else {  // set the time rang
H
Haojun Liao 已提交
6122
    pQueryInfo->window = TSWINDOW_INITIALIZER;
H
Haojun Liao 已提交
6123 6124 6125
    if (pQuerySql->from->nExpr > 2) { // it is a join query, no wher clause is not allowed.
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "condition missing for join query ");
    }
6126 6127 6128
  }

  // user does not specified the query time window, twa is not allowed in such case.
H
Haojun Liao 已提交
6129
  if ((pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX ||
H
hjxilinx 已提交
6130
       (pQueryInfo->window.ekey == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
6131
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
6132 6133 6134
  }

  // no result due to invalid query time range
H
hjxilinx 已提交
6135
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6136
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6137 6138 6139
    return TSDB_CODE_SUCCESS;
  }

6140
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6141
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6142 6143 6144
  }

  // in case of join query, time range is required.
6145
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
S
TD-1057  
Shengliang Guan 已提交
6146
    int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6147

H
hjxilinx 已提交
6148
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6149
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6150 6151 6152
    }
  }

6153
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6154 6155 6156
    return code;
  }

6157
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6158 6159 6160
    return code;
  }

6161
  setColumnOffsetValueInResultset(pQueryInfo);
6162

6163 6164 6165 6166 6167
  /*
   * 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) {
6168
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6169 6170
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6171

6172
    if (pQueryInfo->intervalTime > 0 && pQueryInfo->intervalTimeUnit != 'n' && pQueryInfo->intervalTimeUnit != 'y') {
S
TD-1057  
Shengliang Guan 已提交
6173
      int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6174
      // number of result is not greater than 10,000,000
6175
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_INTERVAL_TIME_WINDOW) {
6176
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6177 6178
      }
    }
H
hjxilinx 已提交
6179

6180
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6181 6182 6183 6184
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6185 6186 6187

  return TSDB_CODE_SUCCESS;  // Does not build query message here
}
H
hjxilinx 已提交
6188

6189
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols) {
H
hjxilinx 已提交
6190 6191
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6192
  
6193
  if (pSqlExpr->pLeft != NULL) {
6194
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6195 6196 6197 6198 6199
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6200
  if (pSqlExpr->pRight != NULL) {
6201
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6202 6203 6204 6205 6206
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6207
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6208
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6209
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6210
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6211 6212 6213
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6214
      return TSDB_CODE_SUCCESS;
6215
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6216
      // arithmetic expression on the results of aggregation functions
6217
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6218
      (*pExpr)->nodeType = TSQL_NODE_COL;
6219 6220 6221
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6222
      // set the input column data byte and type.
H
hjxilinx 已提交
6223 6224 6225 6226 6227 6228
      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 已提交
6229
          (*pExpr)->pSchema->type = (uint8_t)p1->resType;
H
hjxilinx 已提交
6230
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
hjxilinx 已提交
6231 6232 6233
          break;
        }
      }
6234
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6235
      SColumnIndex index = {0};
6236
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6237 6238 6239
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
H
Haojun Liao 已提交
6240 6241 6242 6243

      STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
      int32_t numOfColumns = tscGetNumOfColumns(pTableMeta);

6244 6245 6246
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
H
Haojun Liao 已提交
6247

6248 6249
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6250 6251 6252
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6253
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6254 6255
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
H
Haojun Liao 已提交
6256 6257
        colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;

6258 6259
        taosArrayPush(pCols, &colIndex);
      }
6260
      
H
hjxilinx 已提交
6261
      return TSDB_CODE_SUCCESS;
6262
    } else {
6263
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6264 6265 6266
    }
    
  } else {
H
hjxilinx 已提交
6267
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6268 6269
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6270 6271 6272
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6273
    
H
Haojun Liao 已提交
6274
    SStrToken t = {.type = pSqlExpr->nSQLOptr};
H
[td-32]  
hjxilinx 已提交
6275
    (*pExpr)->_node.optr = getBinaryExprOptr(&t);
6276
    
H
[td-32]  
hjxilinx 已提交
6277
    assert((*pExpr)->_node.optr != 0);
H
hjxilinx 已提交
6278
    
H
[td-32]  
hjxilinx 已提交
6279
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6280 6281
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6282
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6283
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6284
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6285 6286 6287
        }
      }
    }
H
Hui Li 已提交
6288

6289
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6290 6291
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
      if (pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6292 6293 6294
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6295 6296
      }
    }
H
hjxilinx 已提交
6297 6298 6299
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6300
}