tscSQLParser.c 219.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"

Y
TD-1230  
yihaoDeng 已提交
36 37
#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))

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

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

Y
TD-1230  
yihaoDeng 已提交
50 51 52 53
typedef struct SConvertFunc {
  int32_t originFuncId;
  int32_t execFuncId;
} SConvertFunc;
54
static SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex);
H
hzcheng 已提交
55 56

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

H
hjxilinx 已提交
59
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name);
H
Haojun Liao 已提交
60 61
static void getCurrentDBName(SSqlObj* pSql, SStrToken* pDBToken);
static bool hasSpecifyDB(SStrToken* pTableName);
H
hzcheng 已提交
62 63 64
static bool validateTableColumnInfo(tFieldList* pFieldList, SSqlCmd* pCmd);
static bool validateTagParams(tFieldList* pTagsList, tFieldList* pFieldList, SSqlCmd* pCmd);

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

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

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

76
static bool validateIpAddress(const char* ip, size_t size);
77
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
H
Haojun Liao 已提交
78
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery);
79
static void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo);
H
hzcheng 已提交
80

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

83 84
static int32_t parseIntervalClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
H
hzcheng 已提交
85

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

88
static int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql);
89 90
static int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL);
static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema);
H
hzcheng 已提交
91

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

H
hjxilinx 已提交
104
static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField);
105
static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo);
H
hjxilinx 已提交
106

107
static int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t index, SQuerySQL* pQuerySql, SSqlObj* pSql);
H
hjxilinx 已提交
108
static int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql);
H
Haojun Liao 已提交
109 110
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 已提交
111 112
static int32_t optrToString(tSQLExpr* pExpr, char** exprString);

H
Haojun Liao 已提交
113
static int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
114
static int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
115
static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
116
static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate);
H
hjxilinx 已提交
117

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

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

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

134
static int setColumnFilterInfoForTimestamp(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tVariant* pVar) {
S
slguan 已提交
135 136 137 138 139
  int64_t     time = 0;
  const char* msg = "invalid timestamp";

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

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

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

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
160
static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) {
161 162 163 164 165
  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) {
166
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
167 168 169
  }

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

  if (pPwd->n <= 0) {
173
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
174 175
  }

B
Bomin Zhang 已提交
176
  if (pPwd->n >= TSDB_PASSWORD_LEN) {
177
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
178 179 180 181 182
  }

  return TSDB_CODE_SUCCESS;
}

H
hzcheng 已提交
183 184
int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
  if (pInfo == NULL || pSql == NULL || pSql->signature != pSql) {
185
    return TSDB_CODE_TSC_APP_ERROR;
H
hzcheng 已提交
186 187
  }

188 189
  SSqlCmd* pCmd = &pSql->cmd;
  SSqlRes* pRes = &pSql->res;
H
hzcheng 已提交
190

191
  int32_t code = TSDB_CODE_SUCCESS;
192
  if (!pInfo->valid) {
Y
TD-934  
yihaoDeng 已提交
193
    return tscSQLSyntaxErrMsg(tscGetErrorMsgPayload(pCmd), NULL, pInfo->pzErrMsg);
H
hzcheng 已提交
194 195
  }

196 197 198 199 200
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex);
  if (pQueryInfo == NULL) {
    pRes->code = terrno;
    return pRes->code;
  }
H
hjxilinx 已提交
201

202 203 204 205
  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 已提交
206
  }
207

208 209 210 211 212 213 214 215
  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: {
216
      const char* msg2 = "invalid name";
217
      const char* msg3 = "param name too long";
H
hzcheng 已提交
218

H
Haojun Liao 已提交
219
      SStrToken* pzName = &pInfo->pDCLInfo->a[0];
220
      if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (tscValidateName(pzName) != TSDB_CODE_SUCCESS)) {
221
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
222 223
      }

224 225
      if (pInfo->type == TSDB_SQL_DROP_DB) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
226

H
hjxilinx 已提交
227
        code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pzName, NULL, NULL);
H
hzcheng 已提交
228
        if (code != TSDB_CODE_SUCCESS) {
229
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
230 231
        }

232 233
      } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
234

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

H
hjxilinx 已提交
246
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
247 248
      }

249 250
      break;
    }
H
hzcheng 已提交
251

252 253
    case TSDB_SQL_USE_DB: {
      const char* msg = "invalid db name";
H
Haojun Liao 已提交
254
      SStrToken*  pToken = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
255 256

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
257
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
258 259
      }

H
hjxilinx 已提交
260
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pToken, NULL, NULL);
H
hzcheng 已提交
261
      if (ret != TSDB_CODE_SUCCESS) {
262
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
263 264 265 266 267
      }

      break;
    }

268 269
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
270 271
    }

272 273
    case TSDB_SQL_SHOW: {
      if (setShowInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
274
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
275 276
      }

277 278 279 280 281 282 283 284
      break;
    }

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

285
      SCreateDBInfo* pCreateDB = &(pInfo->pDCLInfo->dbOpt);
H
hzcheng 已提交
286
      if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) {
287
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
288 289
      }

H
hjxilinx 已提交
290
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname), NULL, NULL);
H
hzcheng 已提交
291
      if (ret != TSDB_CODE_SUCCESS) {
292
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
293 294
      }

H
hjxilinx 已提交
295
      if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
296
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
297 298 299 300 301
      }

      break;
    }

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

305
      if (pInfo->pDCLInfo->nTokens > 1) {
306
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
307 308
      }

H
Haojun Liao 已提交
309
      SStrToken* pIpAddr = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
310
      pIpAddr->n = strdequote(pIpAddr->z);
S
slguan 已提交
311 312 313
      break;
    }

314 315 316 317 318
    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 已提交
319

H
Haojun Liao 已提交
320 321
      SStrToken* pName = &pInfo->pDCLInfo->user.user;
      SStrToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
322

323
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
324
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
325 326
      }

B
Bomin Zhang 已提交
327
      if (pName->n >= TSDB_USER_LEN) {
328
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
329 330
      }

331
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
332
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
333 334 335
      }

      SCreateAcctSQL* pAcctOpt = &pInfo->pDCLInfo->acctOpt;
336
      if (pAcctOpt->stat.n > 0) {
H
hzcheng 已提交
337 338 339 340 341
        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 {
342
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
343 344
        }
      }
345

H
hzcheng 已提交
346 347 348
      break;
    }

349
    case TSDB_SQL_DESCRIBE_TABLE: {
H
Haojun Liao 已提交
350
      SStrToken*  pToken = &pInfo->pDCLInfo->a[0];
351
      const char* msg2 = "table name is too long";
H
hjxilinx 已提交
352
      const char* msg1 = "invalid table name";
H
hzcheng 已提交
353

S
slguan 已提交
354
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
355
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
356
      }
S
slguan 已提交
357

H
Haojun Liao 已提交
358
      if (!tscValidateTableNameLength(pToken->n)) {
359
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
360 361
      }

H
Haojun Liao 已提交
362
      if (tscSetTableFullName(pTableMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
363
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
364 365
      }

H
hjxilinx 已提交
366
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
367 368
    }

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

373 374
      /* validate the ip address */
      tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
375

376 377
      /* validate the parameter names and options */
      if (validateDNodeConfig(pDCL) != TSDB_CODE_SUCCESS) {
378
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
379 380
      }

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

S
slguan 已提交
383
      SCMCfgDnodeMsg* pCfg = (SCMCfgDnodeMsg*)pMsg;
guanshengliang's avatar
guanshengliang 已提交
384 385
      pDCL->a[0].n = strdequote(pDCL->a[0].z);
      
J
jtao1735 已提交
386
      strncpy(pCfg->ep, pDCL->a[0].z, pDCL->a[0].n);
H
hzcheng 已提交
387

H
Hui Li 已提交
388 389 390 391
      if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }

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

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

399 400
      break;
    }
H
hzcheng 已提交
401

402 403 404 405 406 407
    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 已提交
408

409
      pCmd->command = pInfo->type;
H
hjxilinx 已提交
410
      // tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
411

412
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
H
Haojun Liao 已提交
413 414
      SStrToken* pName = &pUser->user;
      SStrToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
415

B
Bomin Zhang 已提交
416
      if (pName->n >= TSDB_USER_LEN) {
417
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
418
      }
H
hzcheng 已提交
419

420
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
421
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
422
      }
H
hzcheng 已提交
423

424 425
      if (pCmd->command == TSDB_SQL_CREATE_USER) {
        if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
426
          return TSDB_CODE_TSC_INVALID_SQL;
427 428 429 430
        }
      } else {
        if (pUser->type == TSDB_ALTER_USER_PASSWD) {
          if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
431
            return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
432
          }
433
        } else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
L
lihui 已提交
434 435
          assert(pPwd->type == TSDB_DATA_TYPE_NULL);

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

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

H
hzcheng 已提交
452 453
      break;
    }
454 455

    case TSDB_SQL_CFG_LOCAL: {
S
slguan 已提交
456 457 458 459 460
      tDCLSQL*    pDCL = pInfo->pDCLInfo;
      const char* msg = "invalid configure options or values";

      // validate the parameter names and options
      if (validateLocalConfig(pDCL) != TSDB_CODE_SUCCESS) {
461
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
462 463 464 465 466 467 468
      }

      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 已提交
469 470 471 472

      break;
    }

473 474
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
475

476
      if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
477
        if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
478
          return code;
H
hzcheng 已提交
479 480
        }

481
      } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) {
482
        assert(pCmd->numOfCols == 0);
483 484
        if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
485 486
        }

487 488 489
      } else if (pCreateTable->type == TSQL_CREATE_STREAM) {
        if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
S
slguan 已提交
490
        }
H
hzcheng 已提交
491 492 493 494 495
      }

      break;
    }

496
    case TSDB_SQL_SELECT: {
H
hjxilinx 已提交
497
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
498

499
      for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) {
500 501 502 503
        SQueryInfo* pqi = tscGetQueryInfoDetailSafely(pCmd, i);
        if (pqi == NULL) {
          pRes->code = terrno;
          return pRes->code;
504
        }
505 506 507
      }

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

H
hjxilinx 已提交
515
        tscPrintSelectClause(pSql, i);
H
Haojun Liao 已提交
516
        pCmd->clauseIndex += 1;
H
hzcheng 已提交
517
      }
H
hjxilinx 已提交
518

H
Haojun Liao 已提交
519 520
      // restore the clause index
      pCmd->clauseIndex = 0;
H
hjxilinx 已提交
521
      // set the command/global limit parameters from the first subclause to the sqlcmd object
522 523
      SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
      pCmd->command = pQueryInfo1->command;
H
hjxilinx 已提交
524

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

529 530 531
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
532
        }
533
      }
534

535
      pCmd->parseFinished = 1;
536
      return TSDB_CODE_SUCCESS;  // do not build query message here
537
    }
H
hzcheng 已提交
538

539 540 541
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
542 543 544 545 546
      }

      break;
    }

547 548 549
    case TSDB_SQL_KILL_QUERY:
    case TSDB_SQL_KILL_STREAM:
    case TSDB_SQL_KILL_CONNECTION: {
550
      if ((code = setKillInfo(pSql, pInfo, pInfo->type)) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
551 552 553 554 555 556 557
        return code;
      }

      break;
    }

    default:
558
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
559 560
  }

dengyihao's avatar
dengyihao 已提交
561
  pSql->cmd.parseFinished = 1;
562
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
563 564
}

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

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

S
slguan 已提交
580
  return false;
H
hzcheng 已提交
581 582
}

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

H
hjxilinx 已提交
587
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
588
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
589
  
H
hjxilinx 已提交
590
  if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
H
hzcheng 已提交
591 592 593 594
    return TSDB_CODE_SUCCESS;
  }

  // interval is not null
595
  SStrToken* t = &pQuerySql->interval;
B
Bomin Zhang 已提交
596
  if (parseDuration(t->z, t->n, &pQueryInfo->intervalTime, &pQueryInfo->intervalTimeUnit) != TSDB_CODE_SUCCESS) {
597
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
598 599
  }

B
Bomin Zhang 已提交
600 601 602 603 604
  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 已提交
605

B
Bomin Zhang 已提交
606 607 608 609
    // interval cannot be less than 10 milliseconds
    if (pQueryInfo->intervalTime < tsMinIntervalTime) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }
H
hzcheng 已提交
610 611 612
  }

  // for top/bottom + interval query, we do not add additional timestamp column in the front
613
  if (isTopBottomQuery(pQueryInfo)) {
614
    if (parseSlidingClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
615
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
616
    }
H
hjxilinx 已提交
617

H
hzcheng 已提交
618 619 620
    return TSDB_CODE_SUCCESS;
  }

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

H
hjxilinx 已提交
633 634 635
  /*
   * check invalid SQL:
   * select tbname, tags_fields from super_table_name interval(1s)
H
hjxilinx 已提交
636
   */
H
hjxilinx 已提交
637
  if (tscQueryTags(pQueryInfo) && pQueryInfo->intervalTime > 0) {
638
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
639
  }
S
slguan 已提交
640 641

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

  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
645
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
646
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
647
    if (pTableMetaInfo->pTableMeta->id.uid == uid) {
S
slguan 已提交
648 649 650 651 652 653
      tableIndex = i;
      break;
    }
  }

  if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
654
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
655 656
  }

H
Haojun Liao 已提交
657 658
  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));
659

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

663
  if (parseSlidingClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
664
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
665
  }
H
hjxilinx 已提交
666

H
hjxilinx 已提交
667
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
668 669
}

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

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

H
hjxilinx 已提交
678
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
679
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
680

681
  SStrToken* pSliding = &pQuerySql->sliding;
B
Bomin Zhang 已提交
682 683 684 685 686
  if (pSliding->n == 0) {
    pQueryInfo->slidingTimeUnit = pQueryInfo->intervalTimeUnit;
    pQueryInfo->slidingTime = pQueryInfo->intervalTime;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
687

B
Bomin Zhang 已提交
688 689 690
  if (pQueryInfo->intervalTimeUnit == 'n' || pQueryInfo->intervalTimeUnit == 'y') {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
  }
H
hzcheng 已提交
691

B
Bomin Zhang 已提交
692 693 694 695 696 697 698 699 700 701 702
  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 已提交
703 704
  }

H
Haojun Liao 已提交
705 706 707 708
  if ((pQueryInfo->intervalTime != 0) && (pQueryInfo->intervalTime/pQueryInfo->slidingTime > INTERVAL_SLIDING_FACTOR)) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
  }

H
hzcheng 已提交
709 710 711
  return TSDB_CODE_SUCCESS;
}

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

715 716
  SSqlCmd* pCmd = &pSql->cmd;
  int32_t  code = TSDB_CODE_SUCCESS;
S
slguan 已提交
717

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

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

H
hjxilinx 已提交
732
    code = setObjFullName(pTableMetaInfo->name, NULL, &t, pzTableName, NULL);
H
hzcheng 已提交
733 734
  }

S
slguan 已提交
735
  if (code != TSDB_CODE_SUCCESS) {
736
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
737 738
  }

739 740 741 742
  if (code != TSDB_CODE_SUCCESS) {
    free(oldName);
    return code;
  }
H
hjxilinx 已提交
743

744 745 746 747 748
  /*
   * 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 已提交
749
    if (strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
750
      tscClearTableMetaInfo(pTableMetaInfo, false);
751 752
    }
  } else {
H
hjxilinx 已提交
753
    assert(pTableMetaInfo->pTableMeta == NULL);
754
  }
H
hjxilinx 已提交
755

S
Shengliang Guan 已提交
756
  taosTFree(oldName);
757
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
758 759 760 761 762
}

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

763 764 765 766 767 768 769
  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 已提交
770 771 772

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

  // first column must be timestamp
  if (pFieldList->p[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
779
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
780 781 782 783 784
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
dengyihao's avatar
dengyihao 已提交
785 786 787 788
    if (pFieldList->p[i].bytes == 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
      return false;
    }
H
hzcheng 已提交
789 790 791 792 793
    nLen += pFieldList->p[i].bytes;
  }

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

    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
813
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
814 815 816 817
      return false;
    }

    if (has(pFieldList, i + 1, pFieldList->p[i].name) == true) {
818
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
819 820 821 822 823 824 825 826 827 828
      return false;
    }
  }

  return true;
}

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

829 830 831 832 833 834 835
  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 已提交
836 837 838

  // number of fields at least 1
  if (pTagsList->nField < 1 || pTagsList->nField > TSDB_MAX_TAGS) {
839
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
840 841 842 843 844
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
dengyihao's avatar
dengyihao 已提交
845 846 847 848
    if (pTagsList->p[i].bytes == 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
      return false;
    }
H
hzcheng 已提交
849 850 851 852 853
    nLen += pTagsList->p[i].bytes;
  }

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

    if (pTagsList->p[i].type < TSDB_DATA_TYPE_BOOL || pTagsList->p[i].type > TSDB_DATA_TYPE_NCHAR) {
874
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
875 876 877 878 879
      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)) {
880
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
881 882 883 884
      return false;
    }

    if (validateColumnName(pTagsList->p[i].name) != TSDB_CODE_SUCCESS) {
885
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
886 887 888 889
      return false;
    }

    if (has(pTagsList, i + 1, pTagsList->p[i].name) == true) {
890
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
891 892 893 894 895 896 897 898 899 900 901
      return false;
    }
  }

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
902 903 904 905 906 907
  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 已提交
908

909
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
910

911
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
912
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
913

H
hjxilinx 已提交
914 915 916
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
917
  // no more than 6 tags
H
hjxilinx 已提交
918
  if (numOfTags == TSDB_MAX_TAGS) {
H
hzcheng 已提交
919 920 921
    char msg[128] = {0};
    sprintf(msg, "tags no more than %d", TSDB_MAX_TAGS);

922
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
923 924 925 926 927
    return false;
  }

  // no timestamp allowable
  if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) {
928
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
929 930 931
    return false;
  }

L
[#1236]  
lihui 已提交
932
  if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_NCHAR)) {
933
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
934 935 936
    return false;
  }

H
hjxilinx 已提交
937
  SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
938 939
  int32_t  nLen = 0;

H
hjxilinx 已提交
940
  for (int32_t i = 0; i < numOfTags; ++i) {
H
hzcheng 已提交
941 942 943 944 945
    nLen += pTagSchema[i].bytes;
  }

  // length less than TSDB_MAX_TASG_LEN
  if (nLen + pTagField->bytes > TSDB_MAX_TAGS_LEN) {
946
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
947 948 949 950 951
    return false;
  }

  // tags name can not be a keyword
  if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) {
952
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
953 954 955 956 957
    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) {
958
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
959 960 961 962
    return false;
  }

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

H
hjxilinx 已提交
965
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
966
    if (strncasecmp(pTagField->name, pSchema[i].name, sizeof(pTagField->name) - 1) == 0) {
967
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
968 969 970 971 972 973 974 975
      return false;
    }
  }

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
976 977 978 979 980 981
  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 已提交
982

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

  if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_NCHAR) {
997
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
998 999 1000 1001
    return false;
  }

  if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) {
1002
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1003 1004 1005
    return false;
  }

H
hjxilinx 已提交
1006
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
1007 1008
  int32_t  nLen = 0;

H
hjxilinx 已提交
1009
  for (int32_t i = 0; i < numOfCols; ++i) {
H
hzcheng 已提交
1010 1011 1012 1013
    nLen += pSchema[i].bytes;
  }

  if (pColField->bytes <= 0) {
1014
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1015 1016 1017 1018 1019
    return false;
  }

  // length less than TSDB_MAX_BYTES_PER_ROW
  if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) {
1020
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1021 1022 1023 1024
    return false;
  }

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

  return true;
}

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

  return false;
}

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

H
Haojun Liao 已提交
1047
static void getCurrentDBName(SSqlObj* pSql, SStrToken* pDBToken) {
H
hzcheng 已提交
1048
  pDBToken->z = pSql->pTscObj->db;
S
TD-1057  
Shengliang Guan 已提交
1049
  pDBToken->n = (uint32_t)strlen(pSql->pTscObj->db);
H
hzcheng 已提交
1050 1051 1052
}

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

  return false;
}

H
Haojun Liao 已提交
1063
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1064 1065 1066
  int32_t totalLen = 0;

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

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

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

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

H
Haojun Liao 已提交
1107
  if (totalLen < TSDB_TABLE_FNAME_LEN) {
S
slguan 已提交
1108 1109 1110
    fullName[totalLen] = 0;
  }

H
Haojun Liao 已提交
1111
  return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
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 1141 1142 1143 1144 1145 1146
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 已提交
1147 1148 1149
    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);
1150 1151 1152 1153 1154 1155

    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) {
1156 1157
      taosArrayDestroy(colList);
      tExprTreeDestroy(&pNode, NULL);
1158 1159 1160 1161 1162 1163
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }

    size_t numOfNode = taosArrayGetSize(colList);
    for(int32_t k = 0; k < numOfNode; ++k) {
      SColIndex* pIndex = taosArrayGet(colList, k);
1164 1165
      if (TSDB_COL_IS_TAG(pIndex->flag)) {
        tExprTreeDestroy(&pNode, NULL);
1166 1167
        taosArrayDestroy(colList);
        tExprTreeDestroy(&pNode, NULL);
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
        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 已提交
1182
    len = tbufTell(&bw);
1183 1184 1185
    char* c = tbufGetData(&bw, true);

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

    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 已提交
1196 1197 1198 1199 1200 1201 1202
    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 已提交
1203

H
Haojun Liao 已提交
1204
    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, aliasName, NULL);
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229

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

1230 1231 1232 1233 1234
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tscColumnListInsert(pQueryInfo->colList, &tsCol);
}

H
Haojun Liao 已提交
1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258
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 已提交
1259 1260
  assert(pSelection != NULL && pCmd != NULL);

1261 1262
  const char* msg2 = "functions can not be mixed up";
  const char* msg3 = "not support query expression";
H
hjxilinx 已提交
1263
  const char* msg5 = "invalid function name";
H
hjxilinx 已提交
1264

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

1267 1268 1269
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
H
Haojun Liao 已提交
1270

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

S
slguan 已提交
1275
    // project on all fields
H
Haojun Liao 已提交
1276 1277
    int32_t optr = pItem->pNode->nSQLOptr;

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

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

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
1295 1296 1297
      int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
1298 1299
      }
    } else {
1300
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1301 1302
    }

H
hjxilinx 已提交
1303
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1304
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1305 1306 1307
    }
  }

1308 1309 1310 1311
  // 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 已提交
1312 1313 1314 1315 1316 1317

    // 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
1318
    int32_t numOfCols = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
Haojun Liao 已提交
1319 1320 1321 1322 1323 1324
    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;
1325 1326
  }

H
Haojun Liao 已提交
1327
  if (!functionCompatibleCheck(pQueryInfo, joinQuery)) {
1328
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1329 1330
  }

H
Haojun Liao 已提交
1331 1332 1333 1334
  /*
   * transfer sql functions that need secondary merge into another format
   * in dealing with metric queries such as: count/first/last
   */
1335
  if (isSTable) {
H
hjxilinx 已提交
1336
    tscTansformSQLFuncForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1337

1338
    if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
1339
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1340 1341 1342 1343 1344 1345
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

1368
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1369
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1370 1371 1372
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
1373
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
H
hzcheng 已提交
1374

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

H
Haojun Liao 已提交
1390
SSqlExpr* tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1391
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
H
Haojun Liao 已提交
1392
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
H
Haojun Liao 已提交
1393
                                     pColSchema->bytes, pColSchema->bytes, TSDB_COL_IS_TAG(flag));
H
Haojun Liao 已提交
1394
  tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName));
H
hzcheng 已提交
1395

S
slguan 已提交
1396 1397 1398 1399
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1400

H
hjxilinx 已提交
1401
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1402 1403

  pExpr->colInfo.flag = flag;
1404 1405
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  
S
slguan 已提交
1406
  if (TSDB_COL_IS_TAG(flag)) {
H
hjxilinx 已提交
1407
    tscColumnListInsert(pTableMetaInfo->tagColList, pIndex);
S
slguan 已提交
1408
  }
H
Haojun Liao 已提交
1409 1410

  return pExpr;
S
slguan 已提交
1411 1412
}

1413
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1414
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1415 1416

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1417 1418
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1419

H
hjxilinx 已提交
1420
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1421
  
weixin_48148422's avatar
weixin_48148422 已提交
1422
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1423
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1424
  } else {
H
hjxilinx 已提交
1425
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1426 1427 1428
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
hjxilinx 已提交
1429
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex);
B
Bomin Zhang 已提交
1430
    tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName));
S
slguan 已提交
1431 1432 1433 1434

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

H
hjxilinx 已提交
1437
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1438 1439 1440 1441 1442
  }

  return numOfTotalColumns;
}

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

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

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

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

H
Haojun Liao 已提交
1474
    // user-specified constant value as a new result column
1475 1476
    index.columnIndex = (pQueryInfo->udColumnId--);
    index.tableIndex = 0;
H
hzcheng 已提交
1477

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

1482 1483 1484 1485 1486
    // 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 已提交
1487

1488 1489 1490
    if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
    }
H
Haojun Liao 已提交
1491

1492 1493 1494 1495 1496 1497
    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 已提交
1498

1499 1500
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1501 1502
      }

1503
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
Haojun Liao 已提交
1504
      pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
H
hzcheng 已提交
1505
    }
H
Haojun Liao 已提交
1506

1507 1508
    // add the primary timestamp column even though it is not required by user
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
hzcheng 已提交
1509
  } else {
1510
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1511 1512 1513 1514 1515
  }

  return TSDB_CODE_SUCCESS;
}

Y
TD-1230  
yihaoDeng 已提交
1516
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, SConvertFunc cvtFunc, char* aliasName,
S
slguan 已提交
1517
                                       int32_t resColIdx, SColumnIndex* pColIndex) {
H
hzcheng 已提交
1518 1519
  int16_t type = 0;
  int16_t bytes = 0;
S
slguan 已提交
1520
  char        columnName[TSDB_COL_NAME_LEN] = {0};
1521
  const char* msg1 = "not support column types";
Y
TD-1230  
yihaoDeng 已提交
1522
  int32_t functionID = cvtFunc.execFuncId;
H
hzcheng 已提交
1523 1524

  if (functionID == TSDB_FUNC_SPREAD) {
S
slguan 已提交
1525 1526 1527
    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) {
1528
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1529 1530 1531 1532 1533 1534
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
S
slguan 已提交
1535 1536
    type = pSchema[pColIndex->columnIndex].type;
    bytes = pSchema[pColIndex->columnIndex].bytes;
H
hzcheng 已提交
1537
  }
Y
TD-1230  
yihaoDeng 已提交
1538
  
H
hzcheng 已提交
1539
  if (aliasName != NULL) {
B
Bomin Zhang 已提交
1540
    tstrncpy(columnName, aliasName, sizeof(columnName));
H
hzcheng 已提交
1541
  } else {
Y
TD-1230  
yihaoDeng 已提交
1542
    getRevisedName(columnName, cvtFunc.originFuncId, sizeof(columnName) - 1, pSchema[pColIndex->columnIndex].name);
H
hzcheng 已提交
1543
  }
H
hjxilinx 已提交
1544
  
Y
TD-1230  
yihaoDeng 已提交
1545
  
1546
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, bytes, false);
B
Bomin Zhang 已提交
1547
  tstrncpy(pExpr->aliasName, columnName, sizeof(pExpr->aliasName));
1548

Y
TD-1230  
yihaoDeng 已提交
1549 1550 1551 1552
  if (cvtFunc.originFuncId == TSDB_FUNC_LAST_ROW && cvtFunc.originFuncId != functionID) {
    pExpr->colInfo.flag |= TSDB_COL_NULL;
  }

1553 1554 1555 1556 1557 1558
  // 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 已提交
1559
  
H
hjxilinx 已提交
1560
  // for all queries, the timestamp column needs to be loaded
S
slguan 已提交
1561
  SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1562
  tscColumnListInsert(pQueryInfo->colList, &index);
H
hzcheng 已提交
1563

S
slguan 已提交
1564
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
S
TD-1057  
Shengliang Guan 已提交
1565
  insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, columnName, pExpr);
H
hzcheng 已提交
1566 1567 1568 1569

  return TSDB_CODE_SUCCESS;
}

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

1574
  const char* msg1 = "not support column types";
S
slguan 已提交
1575
  const char* msg2 = "invalid parameters";
1576
  const char* msg3 = "illegal column name";
S
slguan 已提交
1577
  const char* msg4 = "invalid table name";
1578
  const char* msg5 = "parameter is out of range [0, 100]";
S
slguan 已提交
1579
  const char* msg6 = "function applied to tags not allowed";
1580
  const char* msg7 = "normal table can not apply this function";
H
Haojun Liao 已提交
1581
  const char* msg8 = "multi-columns selection does not support alias column name";
B
Bomin Zhang 已提交
1582
  const char* msg9 = "invalid function";
H
Haojun Liao 已提交
1583

H
hzcheng 已提交
1584 1585 1586
  switch (optr) {
    case TK_COUNT: {
        /* more than one parameter for count() function */
H
Haojun Liao 已提交
1587
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
1588
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1589 1590 1591 1592
      }

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1593
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1594 1595
      }

H
hjxilinx 已提交
1596
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1597
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1598 1599

      if (pItem->pNode->pParam != NULL) {
S
slguan 已提交
1600
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
Y
TD-1370  
yihaoDeng 已提交
1601 1602 1603 1604 1605 1606 1607
        SStrToken* pToken = &pParamElem->pNode->colInfo;
        short sqlOptr = pParamElem->pNode->nSQLOptr;
        if ((pToken->z == NULL || pToken->n == 0) 
            && (TK_INTEGER != sqlOptr)) /*select count(1) from table*/ {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
        } 
        if (sqlOptr == TK_ALL) {
S
slguan 已提交
1608 1609
          // select table.*
          // check if the table name is valid or not
H
Haojun Liao 已提交
1610
          SStrToken tmpToken = pParamElem->pNode->colInfo;
S
slguan 已提交
1611

1612
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1613
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1614 1615 1616 1617
          }

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
1618
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
Y
TD-1370  
yihaoDeng 已提交
1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633
        } else if (sqlOptr == TK_INTEGER) { // select count(1) from table1
          char buf[8] = {0};  
          int64_t val = -1;
          tVariant* pVariant = &pParamElem->pNode->val;
          if (pVariant->nType == TSDB_DATA_TYPE_BIGINT) {
            tVariantDump(pVariant, buf, TSDB_DATA_TYPE_BIGINT, true);
            val = GET_INT64_VAL(buf); 
          }
          if (val == 1) {
            index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
            int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
            pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
          } else {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
          }
H
hzcheng 已提交
1634
        } else {
H
hjxilinx 已提交
1635
          // count the number of meters created according to the super table
1636 1637
          if (getColumnIndexByName(pCmd, pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1638 1639
          }

H
hjxilinx 已提交
1640
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1641 1642

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1643 1644
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1645
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1646
            isTag = true;
H
hzcheng 已提交
1647 1648
          }

S
slguan 已提交
1649
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1650
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1651
        }
S
slguan 已提交
1652 1653 1654
      } 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;
1655
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1656
      }
H
Haojun Liao 已提交
1657 1658 1659

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

H
hjxilinx 已提交
1660
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1661
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1662
      
S
slguan 已提交
1663
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1664 1665 1666 1667 1668
      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) {
1669
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1670 1671
        }
      }
H
Haojun Liao 已提交
1672 1673

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

S
slguan 已提交
1678
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1679 1680 1681
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1682 1683 1684 1685 1686 1687
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1688
    case TK_TWA:
H
hzcheng 已提交
1689 1690 1691 1692 1693 1694 1695 1696 1697
    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 */
1698
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1699 1700 1701 1702
      }

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

S
slguan 已提交
1706
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
Y
yihaoDeng 已提交
1707
      if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
1708
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1709
      }
Y
yihaoDeng 已提交
1710 1711 1712
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
H
hzcheng 已提交
1713 1714

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

H
hjxilinx 已提交
1719
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1720
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1721 1722 1723 1724
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
1725
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1726 1727 1728

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1729
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1730 1731
      }

S
slguan 已提交
1732 1733
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
1734
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1735
      }
H
hzcheng 已提交
1736

S
slguan 已提交
1737
      // set the first column ts for diff query
H
hzcheng 已提交
1738
      if (optr == TK_DIFF) {
1739
        colIndex += 1;
S
slguan 已提交
1740
        SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
H
hjxilinx 已提交
1741
        SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
1742
                         TSDB_KEYSIZE, false);
H
hzcheng 已提交
1743

S
slguan 已提交
1744
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1745
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1746 1747
      }

S
slguan 已提交
1748
      // functions can not be applied to tags
H
hjxilinx 已提交
1749
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1750
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1751 1752
      }

1753
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, resultSize, false);
H
hzcheng 已提交
1754 1755 1756 1757

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

S
slguan 已提交
1762
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1763 1764

        memset(val, 0, tListLen(val));
1765
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1766
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1767 1768
        }

S
slguan 已提交
1769
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1770 1771
      }

S
slguan 已提交
1772 1773 1774
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1775 1776
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1777
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1778 1779 1780
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
S
TD-1057  
Shengliang Guan 已提交
1781
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, (int32_t)pExpr->resType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
1782 1783
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1784
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1785 1786
        }
      }
H
Haojun Liao 已提交
1787 1788

      tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
S
slguan 已提交
1789
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1790 1791 1792 1793 1794 1795 1796 1797 1798
    }
    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 已提交
1799
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1800
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
B
Bomin Zhang 已提交
1801
      }
Y
TD-1230  
yihaoDeng 已提交
1802 1803 1804 1805
      SConvertFunc cvtFunc = {.originFuncId = functionID, .execFuncId = functionID};
      if (functionID == TSDB_FUNC_LAST_ROW && TSWINDOW_IS_EQUAL(pQueryInfo->window,TSWINDOW_INITIALIZER)) {
        cvtFunc.execFuncId = TSDB_FUNC_LAST;
      }
H
hzcheng 已提交
1806 1807
      if (!requireAllFields) {
        if (pItem->pNode->pParam->nExpr < 1) {
1808
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1809 1810
        }

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

H
hzcheng 已提交
1815 1816 1817 1818
        /* 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) {
1819
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1820 1821
          }

S
slguan 已提交
1822 1823 1824 1825
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

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

1828
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1829
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1830 1831
            }

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

H
hjxilinx 已提交
1835
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
1836
              index.columnIndex = j;
Y
TD-1230  
yihaoDeng 已提交
1837
              if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex++, &index) != 0) {
1838
                return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1839 1840
              }
            }
H
hzcheng 已提交
1841

S
slguan 已提交
1842
          } else {
1843 1844
            if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1845 1846
            }

H
hjxilinx 已提交
1847
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1848
            SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1849 1850

            // functions can not be applied to tags
H
hjxilinx 已提交
1851
            if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
1852
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1853
            }
Y
TD-1230  
yihaoDeng 已提交
1854
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex + i, &index) != 0) {
1855
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1856
            }
1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872

            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 已提交
1873 1874
          }
        }
1875
        
S
slguan 已提交
1876 1877 1878 1879
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

H
Haojun Liao 已提交
1880
        // multicolumn selection does not support alias name
H
Haojun Liao 已提交
1881
        if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
1882
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
1883 1884
        }

1885
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
1886
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
1887
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1888

H
hjxilinx 已提交
1889
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
1890
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
Y
TD-1230  
yihaoDeng 已提交
1891
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex, &index) != 0) {
1892
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1893
            }
H
Haojun Liao 已提交
1894 1895

            colIndex++;
H
hzcheng 已提交
1896
          }
S
slguan 已提交
1897

H
hjxilinx 已提交
1898
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1899 1900
        }

1901
        
S
slguan 已提交
1902
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1903 1904 1905 1906 1907 1908 1909 1910 1911
      }
    }
    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 */
1912
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1913 1914 1915 1916
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
1917
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1918
      }
H
hjxilinx 已提交
1919
      
S
slguan 已提交
1920
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1921 1922
      if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1923
      }
Y
yihaoDeng 已提交
1924 1925 1926 1927
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
      
H
hjxilinx 已提交
1928
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1929
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1930 1931

      // functions can not be applied to tags
H
hjxilinx 已提交
1932
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1933
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1934 1935 1936
      }

      // 2. valid the column type
S
slguan 已提交
1937
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
1938
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1939
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1940 1941 1942 1943
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
1944
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1945 1946 1947 1948
      }

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

S
slguan 已提交
1949 1950
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1951

H
hjxilinx 已提交
1952
      char    val[8] = {0};
H
hjxilinx 已提交
1953 1954
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
1955
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
1956
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
1957

L
lihui 已提交
1958
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
1959
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
1960
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972
        }

        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) {
1973
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1974
        }
dengyihao's avatar
dengyihao 已提交
1975 1976
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
        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_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1980
      } else {
1981
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
1982

H
Haojun Liao 已提交
1983
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
1984
        if (nTop <= 0 || nTop > 100) {  // todo use macro
1985
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1986 1987 1988 1989
        }

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

H
Haojun Liao 已提交
1993
        // todo REFACTOR
H
hzcheng 已提交
1994
        // set the first column ts for top/bottom query
S
slguan 已提交
1995
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
1996 1997
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
            TSDB_KEYSIZE, false);
H
Haojun Liao 已提交
1998
        tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
S
slguan 已提交
1999

H
Haojun Liao 已提交
2000
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
2001
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
2002
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
2003
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
2004

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

2007
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
2008
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
2009
      }
H
hjxilinx 已提交
2010 2011
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
2012
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
2013
  
S
slguan 已提交
2014
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
2015
      if (finalResult) {
2016
        insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
2017 2018
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
2019
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
2020 2021
        }
      }
S
slguan 已提交
2022

2023 2024 2025 2026 2027
      return TSDB_CODE_SUCCESS;
    };
    
    case TK_TBID: {
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2028
      if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
2029
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
2030 2031 2032 2033
      }
    
      // no parameters or more than one parameter for function
      if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 1) {
2034
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2035 2036 2037 2038 2039
      }
      
      tSQLExpr* pParam = pItem->pNode->pParam->a[0].pNode;
    
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2040 2041
      if (getColumnIndexByName(pCmd, &pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2042 2043 2044 2045 2046 2047 2048
      }
    
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
  
      // functions can not be applied to normal columns
      int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
2049
      if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
2050
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2051 2052
      }
    
2053 2054 2055
      if (index.columnIndex > 0) {
        index.columnIndex -= numOfCols;
      }
2056 2057
      
      // 2. valid the column type
2058 2059 2060 2061 2062 2063 2064 2065
      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) {
2066
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
2067 2068 2069 2070
      }

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
2071 2072 2073
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
2074
        s = tGetTableNameColumnSchema();
2075 2076 2077 2078
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
2079 2080
      int16_t bytes = 0;
      int16_t type  = 0;
2081
      int32_t inter = 0;
2082 2083 2084 2085

      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 已提交
2086
      s.type = (uint8_t)type;
2087 2088 2089 2090 2091
      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 已提交
2092
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2093
    }
2094
    
H
hzcheng 已提交
2095
    default:
2096
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2097
  }
2098
  
H
hzcheng 已提交
2099 2100
}

S
slguan 已提交
2101 2102
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
2103
  assert(num == 1 && tableIndex >= 0);
S
slguan 已提交
2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114

  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 已提交
2115 2116 2117 2118
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
S
TD-1057  
Shengliang Guan 已提交
2119
    int32_t len = ((int32_t)pItem->pNode->operand.n < nameLength) ? (int32_t)pItem->pNode->operand.n : nameLength;
H
hzcheng 已提交
2120 2121 2122 2123 2124 2125 2126 2127
    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 已提交
2128 2129 2130
static bool isTablenameToken(SStrToken* token) {
  SStrToken tmpToken = *token;
  SStrToken tableToken = {0};
S
slguan 已提交
2131 2132 2133 2134 2135 2136

  extractTableNameFromToken(&tmpToken, &tableToken);

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

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

H
hjxilinx 已提交
2140 2141
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2142 2143 2144 2145 2146 2147 2148 2149 2150 2151

  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 已提交
2152
      break;
S
slguan 已提交
2153 2154 2155 2156 2157 2158
    }
  }

  return columnIndex;
}

H
Haojun Liao 已提交
2159
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169
  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) {
2170 2171
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2172 2173 2174

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2175
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
2176 2177 2178 2179 2180 2181 2182
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2183
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2184 2185 2186 2187 2188 2189
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2190
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2191 2192 2193 2194 2195 2196
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2197
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2198 2199 2200
  }
}

H
Haojun Liao 已提交
2201
int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2202
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2203
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2204 2205 2206 2207 2208 2209 2210
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
2211
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2212
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
Haojun Liao 已提交
2213 2214
    char* name = pTableMetaInfo->aliasName;
    if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
S
slguan 已提交
2215 2216 2217 2218 2219 2220
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
2221
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2222 2223 2224 2225 2226
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
2227 2228
int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SStrToken tableToken = {0};
S
slguan 已提交
2229 2230
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2231
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2232
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2233 2234
  }

S
slguan 已提交
2235 2236
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2237

H
Haojun Liao 已提交
2238
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2239
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2240
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2241 2242
  }

H
Haojun Liao 已提交
2243
  SStrToken tmpToken = *pToken;
S
slguan 已提交
2244

2245
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2246
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2247 2248
  }

2249
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262
}

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 已提交
2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280
    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 已提交
2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316
    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 已提交
2317 2318
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333
      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 已提交
2334
  SSqlCmd*        pCmd = &pSql->cmd;
2335
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2336
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2337

H
hzcheng 已提交
2338 2339
  pCmd->command = TSDB_SQL_SHOW;

2340
  const char* msg1 = "invalid name";
2341
  const char* msg2 = "pattern filter string too long";
2342 2343 2344 2345
  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 已提交
2346 2347 2348 2349 2350

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2351 2352 2353
  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 已提交
2354
    // db prefix in tagCond, show table conds in payload
H
Haojun Liao 已提交
2355
    SStrToken* pDbPrefixToken = &pShowInfo->prefix;
2356
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2357

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

2362
      if (pDbPrefixToken->n <= 0) {
2363
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2364 2365
      }

2366
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2367
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2368 2369
      }

H
hjxilinx 已提交
2370
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2371
      if (ret != TSDB_CODE_SUCCESS) {
2372
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2373
      }
2374
    }
H
hzcheng 已提交
2375

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

2381
      if (pPattern->n <= 0) {
2382
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2383
      }
H
hzcheng 已提交
2384

H
Haojun Liao 已提交
2385
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2386
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2387 2388
      }
    }
2389 2390
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2391
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2392 2393
    }

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

2400
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2401
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2402
    }
H
hzcheng 已提交
2403 2404 2405 2406 2407
  }

  return TSDB_CODE_SUCCESS;
}

2408 2409 2410 2411
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 已提交
2412

2413 2414
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2415
  
H
Haojun Liao 已提交
2416
  SStrToken* idStr = &(pInfo->pDCLInfo->ip);
2417
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2418
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2419 2420
  }

2421
  strncpy(pCmd->payload, idStr->z, idStr->n);
2422

H
hzcheng 已提交
2423
  const char delim = ':';
2424 2425
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2426

2427 2428 2429 2430 2431
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2432

2433 2434 2435 2436 2437 2438
  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 已提交
2439
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2440 2441 2442 2443 2444
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2445
  }
2446
  
H
hzcheng 已提交
2447 2448 2449
  return TSDB_CODE_SUCCESS;
}

2450 2451 2452 2453 2454 2455
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);

2456
  in_addr_t epAddr = taosInetAddr(tmp);
2457

2458
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2459 2460
}

H
hjxilinx 已提交
2461
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2462
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2463

weixin_48148422's avatar
weixin_48148422 已提交
2464
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2465
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2466 2467
  }

H
hjxilinx 已提交
2468
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2469 2470 2471

  int16_t bytes = 0;
  int16_t type = 0;
2472
  int32_t interBytes = 0;
H
hjxilinx 已提交
2473 2474 2475
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2476
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2477 2478
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

2479
    int32_t colIndex = pExpr->colInfo.colIndex;
H
hjxilinx 已提交
2480
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2481
    
S
slguan 已提交
2482
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2483 2484
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
S
TD-1057  
Shengliang Guan 已提交
2485
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64Key, &type, &bytes,
2486
                            &interBytes, 0, true) != TSDB_CODE_SUCCESS) {
2487
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2488
      }
H
hzcheng 已提交
2489

2490
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2491
      // todo refactor
2492
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2493 2494 2495
    }
  }

2496
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2497
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2498 2499 2500
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2501
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2502
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2503
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2504 2505
    return;
  }
H
hjxilinx 已提交
2506 2507 2508
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2509
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2510
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2511
    
2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528
    // 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 已提交
2529 2530 2531
  }
}

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

S
slguan 已提交
2537
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2538 2539
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2540
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
2541
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
2542
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2543
      return true;
H
hzcheng 已提交
2544 2545 2546
    }
  }

2547 2548
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2549
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2550 2551
      return true;
    }
H
hzcheng 已提交
2552

2553
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2554
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2555
      return true;
2556 2557 2558
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
2559
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2560 2561
        return true;
      }
H
hzcheng 已提交
2562 2563
    }
  }
S
slguan 已提交
2564

H
hzcheng 已提交
2565 2566 2567
  return false;
}

H
Haojun Liao 已提交
2568
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
H
hzcheng 已提交
2569
  int32_t startIdx = 0;
H
hjxilinx 已提交
2570
  
H
hjxilinx 已提交
2571 2572
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2573 2574

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

H
Haojun Liao 已提交
2579
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2580 2581 2582

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2583 2584 2585
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2586
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2587

H
hjxilinx 已提交
2588
    int16_t functionId = pExpr1->functionId;
2589 2590 2591 2592
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
hjxilinx 已提交
2593
    if (functionId == TSDB_FUNC_PRJ && pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
2594 2595 2596
      continue;
    }

H
Haojun Liao 已提交
2597
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2598 2599
      return false;
    }
H
Haojun Liao 已提交
2600 2601 2602 2603

    if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
      return false;
    }
H
hzcheng 已提交
2604 2605 2606 2607 2608
  }

  return true;
}

2609
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2610 2611
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
H
Haojun Liao 已提交
2612
//  const char* msg3 = "group by columns must belong to one table";
S
slguan 已提交
2613 2614 2615
  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 已提交
2616

2617
  // todo : handle two tables situation
H
hjxilinx 已提交
2618
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2619 2620 2621 2622 2623

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

2624 2625 2626 2627
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
2628
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2629
  if (pList->nExpr > TSDB_MAX_TAGS) {
2630
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2631 2632
  }

H
hjxilinx 已提交
2633
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2634
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2635
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2636

S
slguan 已提交
2637
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
2638
  
H
hzcheng 已提交
2639 2640
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tVariant* pVar = &pList->a[i].pVar;
H
Haojun Liao 已提交
2641
    SStrToken token = {pVar->nLen, pVar->nType, pVar->pz};
H
hzcheng 已提交
2642

S
slguan 已提交
2643
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2644 2645
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2646
    }
H
hzcheng 已提交
2647

S
slguan 已提交
2648
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2649

H
hjxilinx 已提交
2650
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2651
    pTableMeta = pTableMetaInfo->pTableMeta;
2652 2653
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2654 2655 2656
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2657
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2658
    }
H
hzcheng 已提交
2659

S
slguan 已提交
2660
    bool groupTag = false;
2661
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2662
      groupTag = true;
H
hzcheng 已提交
2663
    }
2664 2665 2666 2667 2668 2669
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2670
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2671
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2672
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
S
slguan 已提交
2673 2674
      }

2675 2676 2677 2678
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2679

H
hjxilinx 已提交
2680
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2681
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2682 2683 2684
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2685 2686
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
2687
      if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
2688
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
2689 2690
      }

2691
      tscColumnListInsert(pQueryInfo->colList, &index);
2692
      
2693
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2694
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2695
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2696 2697

      if (i == 0 && pList->nExpr > 1) {
2698
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2699
      }
H
hzcheng 已提交
2700 2701 2702
    }
  }

2703
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2704 2705 2706
  return TSDB_CODE_SUCCESS;
}

2707 2708
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2709
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2710
  } else {
H
hjxilinx 已提交
2711
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2712 2713 2714
  }
}

2715
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2716 2717 2718
  if (pColumn == NULL) {
    return NULL;
  }
2719

S
slguan 已提交
2720
  int32_t size = pColumn->numOfFilters + 1;
2721 2722

  char* tmp = (char*) realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2723 2724
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2725 2726
  } else {
    return NULL;
2727 2728
  }

S
slguan 已提交
2729
  pColumn->numOfFilters++;
2730

S
slguan 已提交
2731 2732 2733 2734
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2735 2736
}

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

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

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

S
slguan 已提交
2746
  int16_t colType = pSchema->type;
2747
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2748 2749 2750
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2751
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2752
    int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
2753 2754 2755
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2756 2757
  }

B
Bomin Zhang 已提交
2758
  int32_t retVal = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2759
  if (pExpr->nSQLOptr == TK_LE || pExpr->nSQLOptr == TK_LT) {
B
Bomin Zhang 已提交
2760
    retVal = tVariantDump(&pRight->val, (char*)&pColumnFilter->upperBndd, colType, false);
H
hzcheng 已提交
2761

B
Bomin Zhang 已提交
2762 2763 2764 2765 2766
  // TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
  } else if (colType == TSDB_DATA_TYPE_BINARY) {
    pColumnFilter->pz = (int64_t)calloc(1, pRight->val.nLen + TSDB_NCHAR_SIZE);
    pColumnFilter->len = pRight->val.nLen;
    retVal = tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2767

B
Bomin Zhang 已提交
2768 2769 2770 2771 2772 2773
  } 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);
    retVal = tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
    size_t len = twcslen((wchar_t*)pColumnFilter->pz);
    pColumnFilter->len = len * TSDB_NCHAR_SIZE;
S
slguan 已提交
2774

B
Bomin Zhang 已提交
2775 2776
  } else {
    retVal = tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
2777 2778
  }

B
Bomin Zhang 已提交
2779 2780 2781 2782
  if (retVal != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  } 

H
hzcheng 已提交
2783 2784
  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
2785
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
2786 2787
      break;
    case TK_LT:
S
slguan 已提交
2788
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
2789 2790
      break;
    case TK_GT:
2791
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
2792 2793
      break;
    case TK_GE:
2794
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
2795 2796
      break;
    case TK_EQ:
S
slguan 已提交
2797
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
2798 2799
      break;
    case TK_NE:
S
slguan 已提交
2800
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
2801 2802
      break;
    case TK_LIKE:
S
slguan 已提交
2803
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
2804
      break;
S
slguan 已提交
2805
    default:
2806
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
2807
  }
S
slguan 已提交
2808

2809
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2810 2811
}

S
slguan 已提交
2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825
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 已提交
2826

H
hjxilinx 已提交
2827
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
2828 2829

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2830
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2831 2832
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2833 2834

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

H
hjxilinx 已提交
2837 2838 2839 2840 2841 2842 2843
  } 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 已提交
2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862
    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)) {
2863
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2864 2865
  }

S
slguan 已提交
2866 2867 2868 2869 2870 2871 2872 2873 2874 2875
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
2876
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2877 2878 2879 2880 2881 2882 2883 2884 2885
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
2886 2887 2888 2889
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
2890 2891 2892 2893
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941

  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:
2942
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2943 2944 2945 2946 2947 2948 2949
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2950
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
2951 2952
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
2953
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2954 2955
  }

S
slguan 已提交
2956
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2957
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2958 2959
  }

H
hzcheng 已提交
2960 2961
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
2962
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
2963 2964

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

H
Haojun Liao 已提交
2968
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
2969
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2970 2971 2972 2973 2974 2975
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2976
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
2977 2978
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2979 2980

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2981 2982
}

S
slguan 已提交
2983 2984 2985 2986 2987 2988
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2989

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

H
hjxilinx 已提交
2993 2994
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2995

S
slguan 已提交
2996
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
2997 2998
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
2999

H
hjxilinx 已提交
3000
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013
  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];
    }
3014 3015 3016 3017

    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3018 3019 3020
  } else if (sqlOptr == TK_OR) {
    // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
    pColFilter = addColumnFilterInfo(pColumn);
3021 3022 3023
    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3024
  } else {  // error;
3025
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3026 3027
  }

3028
  pColFilter->filterstr =
S
slguan 已提交
3029 3030
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

3031
  if (pColFilter->filterstr) {
S
slguan 已提交
3032
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
3033
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3034
    }
S
slguan 已提交
3035 3036
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
3037
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
3038
    }
H
Hui Li 已提交
3039 3040 3041
    
    if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
      if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
3042
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Hui Li 已提交
3043 3044
      }
    }
S
slguan 已提交
3045 3046 3047
  }

  pColumn->colIndex = *pIndex;
3048
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
3049 3050
}

3051
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3052 3053 3054 3055 3056
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

3057
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
3058 3059 3060 3061 3062 3063 3064 3065 3066
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

3067
UNUSED_FUNC
3068
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3069 3070 3071 3072 3073 3074 3075
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3077
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
3078
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3079
      return ret;
H
hzcheng 已提交
3080
    }
S
slguan 已提交
3081

3082
    relToString(pExpr, str);
S
slguan 已提交
3083

3084
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
3085 3086 3087 3088

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

H
hzcheng 已提交
3089 3090 3091
    return ret;
  }

S
slguan 已提交
3092 3093 3094
  return tSQLExprLeafToString(pExpr, true, str);
}

3095
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
3096 3097 3098 3099
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
3102 3103
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
3104

S
slguan 已提交
3105
  if (!isTablenameToken(&pLeft->colInfo)) {
3106
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3107 3108
  }

S
slguan 已提交
3109
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3110

S
slguan 已提交
3111
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
3112
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
3113
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3114
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
3115
  }
H
hzcheng 已提交
3116

S
slguan 已提交
3117
  if (ret != TSDB_CODE_SUCCESS) {
3118
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3119
  }
H
hzcheng 已提交
3120

S
slguan 已提交
3121 3122 3123
  return ret;
}

3124
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3125 3126 3127 3128 3129
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
3130
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3131 3132 3133 3134
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3135
    return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3136 3137
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3138
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3139
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3140
    }
S
slguan 已提交
3141

3142
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3143
  }
S
slguan 已提交
3144
}
H
hzcheng 已提交
3145

3146
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
H
Haojun Liao 已提交
3147 3148 3149
  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 已提交
3150

S
slguan 已提交
3151 3152 3153
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3154

S
slguan 已提交
3155
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
3156
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3157 3158
  }

3159
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3160 3161 3162 3163
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3164 3165
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3166 3167
  }

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

3171
  pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3172
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3173
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3174 3175

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3176 3177
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3178 3179
  }

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

3183
  pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3184
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3185
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3186

H
Haojun Liao 已提交
3187
  if (pTagSchema1->type != pTagSchema2->type) {
3188
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3189 3190
  }

S
slguan 已提交
3191
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3192 3193 3194 3195
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3200
  *(*exprString)++ = '(';
H
hzcheng 已提交
3201 3202

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3203
    doArithmeticExprToString(pLeft, exprString);
H
hzcheng 已提交
3204
  } else {
S
slguan 已提交
3205
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3206
    if (ret != TSDB_CODE_SUCCESS) {
3207
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3208 3209 3210 3211 3212 3213
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3214
    doArithmeticExprToString(pRight, exprString);
H
hzcheng 已提交
3215
  } else {
S
slguan 已提交
3216
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3217
    if (ret != TSDB_CODE_SUCCESS) {
3218
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3219 3220 3221
    }
  }

H
hjxilinx 已提交
3222
  *(*exprString)++ = ')';
H
hzcheng 已提交
3223 3224 3225 3226

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
3227
static UNUSED_FUNC int32_t arithmeticExprToString(tSQLExpr* pExpr, char** str) {
3228 3229 3230 3231
  char* start = *str;

  int32_t code = doArithmeticExprToString(pExpr, str);
  if (code == TSDB_CODE_SUCCESS) { // remove out the parenthesis
S
Shengliang Guan 已提交
3232
    int32_t len = (int32_t)strlen(start);
3233 3234 3235 3236 3237 3238 3239
    memmove(start, start + 1, len - 2);
    start[len - 2] = 0;
  }

  return code;
}

3240
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3241
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3242 3243 3244
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
3245
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3246
    }
L
lihui 已提交
3247

H
hjxilinx 已提交
3248
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3249
    if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3250
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3251 3252 3253
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3254
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3255 3256
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3257 3258
    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)) {
3259
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3260 3261 3262
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3263
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
3264
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3265 3266 3267 3268
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
3269
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3270 3271
    }

S
TD-1057  
Shengliang Guan 已提交
3272
    int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
3273
  
H
hjxilinx 已提交
3274 3275 3276
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
    // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
3277
    if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
3278
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3279
    }
H
hzcheng 已提交
3280 3281 3282 3283 3284
  }

  return TSDB_CODE_SUCCESS;
}

3285
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3286 3287 3288 3289 3290 3291
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3292
    int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3293 3294 3295 3296
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3297
    int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3298 3299 3300 3301 3302 3303 3304
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3305
    int32_t ret = validateArithmeticSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3306 3307 3308 3309
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3310
    int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325
    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 已提交
3326 3327 3328
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3329 3330 3331
   *
   * However, columnA < 4+12 is valid
   */
B
Bomin Zhang 已提交
3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347
  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 已提交
3348 3349 3350 3351 3352 3353
    return false;
  }

  return true;
}

S
slguan 已提交
3354 3355 3356
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3357

S
slguan 已提交
3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382
  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 已提交
3383

S
slguan 已提交
3384 3385 3386 3387 3388
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3389
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402
  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) {
3403
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3404 3405 3406 3407 3408
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3409 3410
  if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3411
    return false;
H
hzcheng 已提交
3412 3413
  }

S
slguan 已提交
3414
  // todo extract function
H
hjxilinx 已提交
3415
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3416
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3417 3418
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3419
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3420
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3421 3422 3423
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3424
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3425 3426
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3427
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3428
    return false;
H
hzcheng 已提交
3429 3430
  }

S
slguan 已提交
3431
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3432
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3433
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
S
slguan 已提交
3434 3435
    return false;
  }
H
hzcheng 已提交
3436

S
slguan 已提交
3437 3438
  return true;
}
H
hzcheng 已提交
3439

S
slguan 已提交
3440 3441 3442 3443 3444 3445
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 已提交
3446 3447 3448
    }
  }

S
slguan 已提交
3449
  return false;
H
hzcheng 已提交
3450 3451
}

3452
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3453 3454
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3455
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3456
    }
H
hzcheng 已提交
3457

S
slguan 已提交
3458 3459 3460 3461
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3462

S
slguan 已提交
3463 3464
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3465

3466 3467
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                                     int32_t* type, int32_t parentOptr) {
3468
  const char* msg1 = "table query cannot use tags filter";
S
slguan 已提交
3469 3470 3471
  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 已提交
3472 3473 3474
  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";
3475 3476
  const char* msg8 = "wildcard string should be less than 20 characters";
  
S
slguan 已提交
3477 3478
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3479

S
slguan 已提交
3480 3481 3482
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3483 3484
  if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3485 3486
  }

S
slguan 已提交
3487 3488
  assert(isExprDirectParentOfLeaftNode(*pExpr));

H
hjxilinx 已提交
3489
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3490
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3491 3492

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3493
    if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3494
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3495
    }
S
slguan 已提交
3496 3497 3498

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
H
hjxilinx 已提交
3499
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
S
slguan 已提交
3500 3501 3502 3503 3504 3505 3506 3507
      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 {
3508
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3509 3510 3511 3512
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3513 3514
  } 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 已提交
3515
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3516
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3517 3518 3519 3520 3521
    }

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

H
hjxilinx 已提交
3525
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3526 3527 3528

      if ((!isTablenameToken(&pLeft->colInfo)) && pSchema[index.columnIndex].type != TSDB_DATA_TYPE_BINARY &&
          pSchema[index.columnIndex].type != TSDB_DATA_TYPE_NCHAR) {
3529
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3530 3531 3532 3533 3534 3535
      }
    }

    // in case of in operator, keep it in a seperate attribute
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3536
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
3537
      }
3538 3539
  
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
3540
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
3541
      }
S
slguan 已提交
3542 3543 3544 3545 3546 3547

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3548
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
3549 3550 3551 3552 3553 3554
      }

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

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

3563 3564
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578
        *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
3579
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
3580 3581
    }

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

S
slguan 已提交
3586
  return ret;
H
hzcheng 已提交
3587 3588
}

3589 3590
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                        int32_t* type, int32_t parentOptr) {
H
hzcheng 已提交
3591 3592 3593 3594
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3597 3598 3599 3600
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3601
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3602 3603
  }

S
slguan 已提交
3604 3605
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3606

S
slguan 已提交
3607
  if (!isExprDirectParentOfLeaftNode(*pExpr)) {
3608
    int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3609 3610 3611 3612
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3613
    ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3614 3615 3616
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3617

S
slguan 已提交
3618 3619 3620 3621 3622 3623
    /*
     *  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)) {
3624
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3625
      }
H
hzcheng 已提交
3626 3627
    }

S
slguan 已提交
3628 3629 3630
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3631

S
slguan 已提交
3632
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3633

3634
  return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3635
}
H
hzcheng 已提交
3636

S
slguan 已提交
3637 3638 3639 3640
static void doCompactQueryExpr(tSQLExpr** pExpr) {
  if (*pExpr == NULL || isExprDirectParentOfLeaftNode(*pExpr)) {
    return;
  }
H
hzcheng 已提交
3641

S
slguan 已提交
3642 3643 3644
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3645

S
slguan 已提交
3646 3647 3648
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3649

S
slguan 已提交
3650 3651 3652 3653
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3654

S
slguan 已提交
3655 3656 3657
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3658

S
slguan 已提交
3659 3660 3661 3662
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3663

S
slguan 已提交
3664
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3665
  }
S
slguan 已提交
3666
}
H
hzcheng 已提交
3667

3668
static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
S
slguan 已提交
3669 3670 3671 3672
  if (isExprDirectParentOfLeaftNode(*pExpr)) {
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3673
    if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3674
      return;
H
hzcheng 已提交
3675 3676
    }

S
slguan 已提交
3677 3678 3679 3680
    if (index.tableIndex != tableIndex) {
      return;
    }

H
Haojun Liao 已提交
3681
    SStrToken t = {0};
S
slguan 已提交
3682 3683 3684 3685 3686 3687 3688 3689
    extractTableNameFromToken(&pLeft->colInfo, &t);

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

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

3690 3691
    doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3692 3693 3694
  }
}

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

S
slguan 已提交
3698
  if (*pExpr != NULL) {
3699
    doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3700
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3701 3702
  }

S
slguan 已提交
3703
  return pResExpr;
H
hzcheng 已提交
3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718
}

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

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

S
slguan 已提交
3723 3724 3725 3726
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3729
  STagCond* pTagCond = &pQueryInfo->tagCond;
3730
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
S
slguan 已提交
3731 3732 3733 3734

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3735
    char* str = taosStringBuilderGetResult(sb, NULL);
3736
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3737 3738 3739
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
3740
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
3741
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3742

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

S
slguan 已提交
3745
  // remove the duplicated input table names
H
hzcheng 已提交
3746
  int32_t num = 0;
H
hjxilinx 已提交
3747 3748 3749
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3750
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3751 3752 3753 3754 3755 3756 3757 3758 3759

  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 已提交
3760
  char* name = extractDBName(pTableMetaInfo->name, db);
H
Haojun Liao 已提交
3761
  SStrToken dbToken = { .type = TK_STRING, .z = name, .n = (uint32_t)strlen(name) };
H
hjxilinx 已提交
3762
  
H
hzcheng 已提交
3763 3764
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3765
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3766
    }
H
hjxilinx 已提交
3767

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

3772
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3773
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3774
      taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3775
      taosTFree(segments);
H
hjxilinx 已提交
3776

3777
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
3778 3779
      return ret;
    }
H
hjxilinx 已提交
3780

H
hjxilinx 已提交
3781
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3782
  }
H
hjxilinx 已提交
3783

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

H
hjxilinx 已提交
3787
  taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3788
  taosTFree(segments);
H
hzcheng 已提交
3789 3790 3791
  return TSDB_CODE_SUCCESS;
}

3792
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
3793 3794 3795 3796 3797 3798
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
3799

3800 3801
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
3802 3803
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
3804

3805
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819
          (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;
}

3820
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
3821 3822
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
3823 3824 3825 3826 3827

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

S
slguan 已提交
3828 3829
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    if (pExpr->nSQLOptr == TK_OR) {
3830
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3831
    }
H
hzcheng 已提交
3832

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

3835
    return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
S
slguan 已提交
3836 3837
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3838
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3839
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3840 3841
    }

H
hjxilinx 已提交
3842
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3843
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3844
    
S
slguan 已提交
3845 3846
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3847 3848
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
3849
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3850 3851 3852
    }

    // update the timestamp query range
H
hjxilinx 已提交
3853 3854
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
3855 3856
    }

H
hjxilinx 已提交
3857 3858
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
3859 3860 3861 3862 3863 3864
    }
  }

  return TSDB_CODE_SUCCESS;
}

3865
static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
3866 3867 3868 3869
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

3870 3871
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
3872 3873
      return TSDB_CODE_SUCCESS;
    } else {
3874
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3875 3876 3877
    }
  }

H
hjxilinx 已提交
3878
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
3879
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // for stable join, tag columns
3880
                                                   // must be present for join
S
slguan 已提交
3881
    if (pCondExpr->pJoinExpr == NULL) {
3882
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3883 3884 3885 3886
    }
  }

  if (!pCondExpr->tsJoin) {
3887
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3888 3889
  }

S
slguan 已提交
3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914
  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);
  }
}

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

3920
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
3921 3922
      tscError("%p: invalid column name (left)", pQueryInfo);
    }
H
hjxilinx 已提交
3923
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3924 3925
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3926 3927
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
  
3928
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
3929 3930
      tscError("%p: invalid column name (right)", pQueryInfo);
    }
H
hjxilinx 已提交
3931
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3932 3933
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3934
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
3935
  }
H
hjxilinx 已提交
3936
}
S
slguan 已提交
3937

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

3941 3942 3943 3944 3945
  if (pCondExpr->pTagCond == NULL) {
    return ret;
  }
  
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
3946
    tSQLExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
H
Haojun Liao 已提交
3947 3948 3949 3950
    if (p1 == NULL) {  // no query condition on this table
      continue;
    }

3951
    tExprNode* p = NULL;
3952 3953
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
3954
    ret = exprTreeFromSqlExpr(pCmd, &p, p1, NULL, pQueryInfo, colList);
3955 3956 3957 3958 3959 3960 3961 3962 3963
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
3964
    
3965 3966
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
3967
    int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
3968 3969 3970 3971 3972 3973
    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 已提交
3974
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
3975 3976
    }
    
3977
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
3978 3979 3980 3981
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
3982 3983
    
    taosArrayDestroy(colList);
H
hjxilinx 已提交
3984
  }
H
hjxilinx 已提交
3985

3986
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
3987 3988
  return ret;
}
3989
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
3990 3991 3992
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
3993

H
hjxilinx 已提交
3994
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
3995
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
3996

H
hjxilinx 已提交
3997
  int32_t ret = TSDB_CODE_SUCCESS;
3998
  pQueryInfo->window = TSWINDOW_INITIALIZER;
S
slguan 已提交
3999

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

H
hjxilinx 已提交
4004
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
4005
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
S
slguan 已提交
4006 4007
  }

H
hjxilinx 已提交
4008
  int32_t type = 0;
4009
  if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4010 4011
    return ret;
  }
H
hjxilinx 已提交
4012

S
slguan 已提交
4013
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
4014

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

S
slguan 已提交
4018
  // 1. check if it is a join query
4019
  if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4020 4021
    return ret;
  }
H
hjxilinx 已提交
4022

S
slguan 已提交
4023
  // 2. get the query time range
4024
  if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4025 4026
    return ret;
  }
H
hjxilinx 已提交
4027

S
slguan 已提交
4028
  // 3. get the tag query condition
4029
  if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4030
    return ret;
S
slguan 已提交
4031
  }
H
hjxilinx 已提交
4032

S
slguan 已提交
4033
  // 4. get the table name query condition
4034
  if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4035 4036
    return ret;
  }
H
hjxilinx 已提交
4037

S
slguan 已提交
4038
  // 5. other column query condition
4039
  if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4040 4041
    return ret;
  }
H
hjxilinx 已提交
4042

S
slguan 已提交
4043
  // 6. join condition
4044
  if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4045
    return ret;
H
hzcheng 已提交
4046
  }
H
hjxilinx 已提交
4047

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

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

4054
  if (!validateFilterExpr(pQueryInfo)) {
4055
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
4056
  }
H
hjxilinx 已提交
4057

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

H
hjxilinx 已提交
4060
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
4061 4062 4063
  return ret;
}

H
hjxilinx 已提交
4064
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
4065 4066 4067 4068 4069
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
4070 4071
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
4072
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
4073 4074
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
4075
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4076
  }
H
hzcheng 已提交
4077 4078 4079 4080

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

S
slguan 已提交
4083
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
4084
    if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
4085
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4086 4087
        parsed = true;
      } else {
4088
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4089
      }
S
slguan 已提交
4090
    } else {
H
Haojun Liao 已提交
4091
      SStrToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
S
slguan 已提交
4092 4093 4094
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
4095
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4096
      }
H
hzcheng 已提交
4097 4098 4099 4100
    }
  } 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 已提交
4101
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116
     *
     * 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
     */
4117
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138

    /*
     * 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 已提交
4139
    win->ekey = val;
H
hzcheng 已提交
4140
  } else if (optr == TK_LT) {
H
hjxilinx 已提交
4141
    win->ekey = val - delta;
H
hzcheng 已提交
4142
  } else if (optr == TK_GT) {
H
hjxilinx 已提交
4143
    win->skey = val + delta;
H
hzcheng 已提交
4144
  } else if (optr == TK_GE) {
H
hjxilinx 已提交
4145
    win->skey = val;
H
hzcheng 已提交
4146
  } else if (optr == TK_EQ) {
H
hjxilinx 已提交
4147
    win->ekey = win->skey = val;
H
hzcheng 已提交
4148 4149 4150 4151
  }
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
4156 4157
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
B
Bomin Zhang 已提交
4158
    for (int32_t j = 0; j < (TSDB_COL_NAME_LEN - 1) && fieldName[j] != 0; ++j) {
S
slguan 已提交
4159 4160 4161 4162 4163
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
4164 4165
      }
    }
S
slguan 已提交
4166

H
hzcheng 已提交
4167 4168 4169 4170
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4171 4172 4173
  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 已提交
4174
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4175
        const char* msg = "duplicated column name in new table";
4176
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4177 4178 4179 4180 4181 4182 4183
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4184
int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
4185 4186 4187 4188
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
4189 4190 4191 4192

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

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4195
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4196
  }
H
hjxilinx 已提交
4197 4198 4199
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
4200 4201 4202
  if (pQueryInfo->fillVal == NULL) {
    pQueryInfo->fillVal = calloc(size, sizeof(int64_t));
    if (pQueryInfo->fillVal == NULL) {
4203
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4204 4205 4206
    }
  }

H
hzcheng 已提交
4207
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4208
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4209
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4210
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4211 4212
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
4213 4214 4215 4216 4217
      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 已提交
4218 4219
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4220
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4221
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4222
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4223
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4224
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4225 4226

    if (pFillToken->nExpr == 1) {
4227
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4228 4229 4230 4231 4232 4233
    }

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

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

H
hjxilinx 已提交
4237
      if (numOfFillVal > size) {
S
TD-1057  
Shengliang Guan 已提交
4238
        numOfFillVal = (int32_t)size;
H
hzcheng 已提交
4239 4240
      }
    } else {
S
TD-1057  
Shengliang Guan 已提交
4241
      numOfFillVal = (pFillToken->nExpr >  (int32_t)size) ? (int32_t)size : pFillToken->nExpr;
H
hzcheng 已提交
4242 4243 4244 4245 4246
    }

    int32_t j = 1;

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

4249
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4250
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
4251 4252
        continue;
      }
H
hjxilinx 已提交
4253

4254
      int32_t ret = tVariantDump(&pFillToken->a[j].pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4255
      if (ret != TSDB_CODE_SUCCESS) {
4256
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4257 4258
      }
    }
H
hjxilinx 已提交
4259
    
4260
    if ((pFillToken->nExpr < size) || ((pFillToken->nExpr - 1 < size) && (tscIsPointInterpQuery(pQueryInfo)))) {
H
hzcheng 已提交
4261 4262
      tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1];

H
hjxilinx 已提交
4263 4264
      for (int32_t i = numOfFillVal; i < size; ++i) {
        TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4265 4266

        if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4267
          setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
H
hjxilinx 已提交
4268
        } else {
4269
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4270 4271 4272 4273
        }
      }
    }
  } else {
4274
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4275 4276 4277 4278 4279
  }

  return TSDB_CODE_SUCCESS;
}

4280
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4281
  /* set default timestamp order information for all queries */
4282
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
hjxilinx 已提交
4283
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4284

4285
  if (isTopBottomQuery(pQueryInfo)) {
4286
    pQueryInfo->order.order = TSDB_ORDER_ASC;
4287
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4288
  } else {
4289
    pQueryInfo->order.orderColId = -1;
H
hzcheng 已提交
4290 4291
  }

H
hjxilinx 已提交
4292
  /* for super table query, set default ascending order for group output */
weixin_48148422's avatar
weixin_48148422 已提交
4293
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
4294
    pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
H
hzcheng 已提交
4295 4296 4297
  }
}

4298
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4299 4300 4301 4302
  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 已提交
4303

4304
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4305
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4306 4307 4308 4309 4310 4311

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

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4312 4313 4314 4315 4316 4317 4318

  /*
   * 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 已提交
4319
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4320
    if (pSortorder->nExpr > 1) {
4321
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4322 4323 4324
    }
  } else {
    if (pSortorder->nExpr > 2) {
4325
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336
    }
  }

  // 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 已提交
4337
  SStrToken    columnName = {pVar->nLen, pVar->nType, pVar->pz};
S
slguan 已提交
4338 4339
  SColumnIndex index = {0};

weixin_48148422's avatar
weixin_48148422 已提交
4340
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4341 4342
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4343 4344 4345 4346
    }

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

H
hjxilinx 已提交
4348 4349
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4350
      
4351 4352
      // it is a tag column
      if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
4353
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4354
      }
4355 4356
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (relTagIndex == pColIndex->colIndex) {
H
hzcheng 已提交
4357 4358
        orderByTags = true;
      }
S
slguan 已提交
4359 4360
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4361 4362
    }

S
slguan 已提交
4363
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4364 4365 4366
      orderByTS = true;
    }

4367
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
4368
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4369 4370 4371 4372 4373 4374
    } else {
      assert(!(orderByTags && orderByTS));
    }

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

4382
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4383
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4384
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
4385
        }
4386

4387 4388
        pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4389
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4390
      } else {
4391 4392
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4393 4394 4395 4396
      }
    }

    if (pSortorder->nExpr == 2) {
S
slguan 已提交
4397
      if (orderByTags) {
H
hjxilinx 已提交
4398
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4399
        pQueryInfo->groupbyExpr.orderType = pQuerySql->pSortOrder->a[0].sortOrder;
S
slguan 已提交
4400
      } else {
4401 4402
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4403 4404
      }

H
hzcheng 已提交
4405
      tVariant* pVar2 = &pSortorder->a[1].pVar;
H
Haojun Liao 已提交
4406
      SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4407 4408
      if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4409 4410 4411
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4412
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4413
      } else {
4414 4415
        pQueryInfo->order.order = pSortorder->a[1].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4416 4417 4418 4419
      }
    }

  } else {  // meter query
4420 4421
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4422 4423
    }

4424
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
4425
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4426 4427
    }

4428
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4429
      /* order of top/bottom query in interval is not valid  */
4430
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4431
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4432

4433
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4434
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4435
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4436
      }
4437

4438 4439
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4440 4441
      return TSDB_CODE_SUCCESS;
    }
4442

4443
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4444 4445 4446 4447 4448 4449
  }

  return TSDB_CODE_SUCCESS;
}

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

4452 4453 4454 4455 4456 4457
  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 已提交
4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472
  
  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 已提交
4473 4474
  const char* msg19 = "invalid new tag name";

S
slguan 已提交
4475
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4476
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4477 4478
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4481
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4482
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
4483
  }
P
plum-lihui 已提交
4484

H
Haojun Liao 已提交
4485
  if (tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql) != TSDB_CODE_SUCCESS) {
4486
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4487 4488
  }

H
hjxilinx 已提交
4489
  int32_t ret = tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
4490 4491 4492 4493
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

H
hjxilinx 已提交
4494
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4495

4496 4497
  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 已提交
4498
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
4499
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4500
    }
weixin_48148422's avatar
weixin_48148422 已提交
4501
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) {
4502
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
4503
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4504
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4505
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
4506 4507
  }

4508
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
hzcheng 已提交
4509 4510
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4511
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
4512 4513 4514
    }

    if (!validateOneTags(pCmd, &pFieldList->p[0])) {
4515
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4516
    }
H
hjxilinx 已提交
4517 4518
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4519
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
H
hjxilinx 已提交
4520
    if (tscGetNumOfTags(pTableMeta) == 1) {
4521
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
4522 4523 4524 4525
    }

    // numOfTags == 1
    if (pAlterSQL->varList->nExpr > 1) {
4526
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
hzcheng 已提交
4527 4528 4529
    }

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

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

4537
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4538
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4539 4540
    }

H
Haojun Liao 已提交
4541 4542
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
4543
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
H
Haojun Liao 已提交
4544
    } else if (index.columnIndex == numOfCols) {
4545
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
H
hzcheng 已提交
4546 4547
    }

4548 4549
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4550 4551 4552
  
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4553
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
hzcheng 已提交
4554 4555
    tVariantList* pVarList = pAlterSQL->varList;
    if (pVarList->nExpr > 2) {
4556
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4557 4558
    }

4559 4560 4561 4562
    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) {
4563
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4564 4565
    }

4566
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4567
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
4568
    }
H
hzcheng 已提交
4569

S
slguan 已提交
4570 4571
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4572

H
Haojun Liao 已提交
4573
    SStrToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4574
    if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4575
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4576 4577
    }

H
Haojun Liao 已提交
4578
    SStrToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4579
    if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4580
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
H
hzcheng 已提交
4581 4582
    }

B
Bomin Zhang 已提交
4583
    char name[TSDB_COL_NAME_LEN] = {0};
H
hzcheng 已提交
4584
    strncpy(name, pVarList->a[0].pVar.pz, pVarList->a[0].pVar.nLen);
H
hjxilinx 已提交
4585 4586
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4587 4588 4589

    memset(name, 0, tListLen(name));
    strncpy(name, pVarList->a[1].pVar.pz, pVarList->a[1].pVar.nLen);
H
hjxilinx 已提交
4590 4591
    f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4592 4593
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
    // Note: update can only be applied to table not super table.
4594 4595 4596
    // the following is used to handle tags value for table created according to super table
    pCmd->command = TSDB_SQL_UPDATE_TAGS_VAL;
    
H
hzcheng 已提交
4597 4598
    tVariantList* pVarList = pAlterSQL->varList;
    tVariant*     pTagName = &pVarList->a[0].pVar;
4599
    int16_t       numOfTags = tscGetNumOfTags(pTableMeta);
H
hzcheng 已提交
4600

4601
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4602
    SStrToken    name = {.type = TK_STRING, .z = pTagName->pz, .n = pTagName->nLen};
4603
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4604
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4605 4606
    }

H
hjxilinx 已提交
4607
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4608
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12);
S
slguan 已提交
4609 4610
    }

H
hjxilinx 已提交
4611
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
4612
    if (tVariantDump(&pVarList->a[1].pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) {
4613
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg13);
H
hzcheng 已提交
4614
    }
4615
    
4616
    pAlterSQL->tagData.dataLen = pTagsSchema->bytes;
H
hzcheng 已提交
4617 4618

    // validate the length of binary
4619
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
4620
        (pVarList->a[1].pVar.nLen + VARSTR_HEADER_SIZE) > pTagsSchema->bytes) {
4621
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg14);
H
hzcheng 已提交
4622
    }
4623 4624 4625 4626

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

4627 4628
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4629
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4630 4631
    }

4632
    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
4633
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
4634 4635
    pUpdateMsg->tid       = htonl(pTableMeta->id.tid);
    pUpdateMsg->uid       = htobe64(pTableMeta->id.uid);
H
Haojun Liao 已提交
4636
    pUpdateMsg->colId     = htons(pTagsSchema->colId);
H
Hongze Cheng 已提交
4637
    pUpdateMsg->type      = pTagsSchema->type;
H
Haojun Liao 已提交
4638 4639
    pUpdateMsg->bytes     = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion  = htons(pTableMeta->tversion);
4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657
    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);
4658 4659 4660 4661 4662
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
4663
      len = varDataTLen(pUpdateMsg->data + schemaLen);
4664 4665 4666 4667
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
4668
    int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen;
4669
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4670
    
4671
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
hzcheng 已提交
4672 4673
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4674
      const char* msg = "only support add one column";
4675
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4676 4677 4678
    }

    if (!validateOneColumn(pCmd, &pFieldList->p[0])) {
4679
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4680
    }
H
hjxilinx 已提交
4681 4682
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4683
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
H
hjxilinx 已提交
4684
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
H
hjxilinx 已提交
4685
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15);
H
hzcheng 已提交
4686 4687 4688
    }

    if (pAlterSQL->varList->nExpr > 1) {
H
hjxilinx 已提交
4689
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4690 4691 4692 4693
    }

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

4694
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4695
    SStrToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4696 4697
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4698 4699
    }

4700
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4701
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18);
4702
    }
H
hzcheng 已提交
4703

B
Bomin Zhang 已提交
4704 4705
    char name1[TSDB_COL_NAME_LEN] = {0};
    tstrncpy(name1, pItem->pVar.pz, sizeof(name1));
H
hjxilinx 已提交
4706 4707
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4708 4709 4710 4711 4712
  }

  return TSDB_CODE_SUCCESS;
}

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

4717 4718 4719
  if (pQueryInfo->intervalTime != 0 && pQueryInfo->intervalTime < 10 &&
     pQueryInfo->intervalTimeUnit != 'n' &&
     pQueryInfo->intervalTimeUnit != 'y') {
4720
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4721
  }
H
hjxilinx 已提交
4722
  
H
hjxilinx 已提交
4723
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4724
  for (int32_t i = 0; i < size; ++i) {
4725
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
4726
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
4727
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4728 4729 4730 4731 4732 4733
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
4738
  // multi-output set/ todo refactor
H
hjxilinx 已提交
4739
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4740 4741
  
  for (int32_t k = 0; k < size; ++k) {
4742
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
4743

4744 4745 4746
    // 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 已提交
4747
      for (int32_t j = 0; j < size; ++j) {
4748
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
4749 4750 4751 4752 4753
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
4754

4755 4756 4757 4758
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4759

4760
    if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4761
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4762 4763 4764
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4765 4766

  if (isProjectionFunction) {
4767
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4768 4769
  }

4770
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4771 4772 4773
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4774 4775
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4776 4777
} SDNodeDynConfOption;

H
Hui Li 已提交
4778

4779
int32_t validateEp(char* ep) {  
H
Hui Li 已提交
4780 4781 4782
  char buf[TSDB_EP_LEN + 1] = {0};
  tstrncpy(buf, ep, TSDB_EP_LEN);

4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793
  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 已提交
4794 4795
  }

4796
  return TSDB_CODE_SUCCESS;
H
Hui Li 已提交
4797 4798
}

H
hzcheng 已提交
4799 4800
int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
4801
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4802 4803
  }

4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815
  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 已提交
4816

H
Haojun Liao 已提交
4817
  SStrToken* pOptionToken = &pOptions->a[1];
H
hzcheng 已提交
4818 4819 4820

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
4821 4822
    for (int32_t i = 0; i < tokenLogEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4823 4824 4825 4826
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
4827 4828
  } else if ((strncasecmp(cfgOptions[tokenBalance].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenBalance].len == pOptionToken->n)) {
H
Haojun Liao 已提交
4829
    SStrToken* pValToken = &pOptions->a[2];
S
Shengliang Guan 已提交
4830 4831
    int32_t vnodeId = 0;
    int32_t dnodeId = 0;
4832
    strdequote(pValToken->z);
S
Shengliang Guan 已提交
4833
    bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId);
4834 4835 4836 4837 4838 4839
    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 已提交
4840
    SStrToken* pValToken = &pOptions->a[2];
S
slguan 已提交
4841 4842
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
4843
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
S
slguan 已提交
4844 4845
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4846
  } else {
H
Haojun Liao 已提交
4847
    SStrToken* pValToken = &pOptions->a[2];
H
hzcheng 已提交
4848 4849

    int32_t val = strtol(pValToken->z, NULL, 10);
4850
    if (val < 0 || val > 256) {
H
hzcheng 已提交
4851
      /* options value is out of valid range */
4852
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4853 4854
    }

4855 4856
    for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
4857 4858 4859 4860 4861 4862 4863 4864

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

4865
  return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4866 4867
}

S
slguan 已提交
4868 4869
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
4870
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4871 4872
  }

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

H
Haojun Liao 已提交
4876
  SStrToken* pOptionToken = &pOptions->a[0];
S
slguan 已提交
4877 4878 4879 4880 4881 4882 4883 4884 4885 4886

  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 已提交
4887
    SStrToken* pValToken = &pOptions->a[1];
S
slguan 已提交
4888 4889 4890 4891

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
4892
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4893 4894 4895 4896 4897 4898 4899 4900 4901 4902
    }

    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;
      }
    }
  }
4903
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4904 4905
}

H
hzcheng 已提交
4906
int32_t validateColumnName(char* name) {
S
TD-1057  
Shengliang Guan 已提交
4907
  bool ret = isKeyWord(name, (int32_t)strlen(name));
H
hzcheng 已提交
4908
  if (ret) {
4909
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4910 4911
  }

H
Haojun Liao 已提交
4912
  SStrToken token = {.z = name};
H
hzcheng 已提交
4913 4914 4915
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
4916
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4917 4918 4919 4920
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
S
TD-1057  
Shengliang Guan 已提交
4921
    token.n = (uint32_t)strtrim(token.z);
H
hzcheng 已提交
4922 4923 4924

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
4925
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4926 4927 4928 4929 4930
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
4931
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4932 4933 4934 4935 4936 4937
    }
  }

  return TSDB_CODE_SUCCESS;
}

4938 4939
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
4940 4941 4942
    return true;
  }

H
hjxilinx 已提交
4943
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
4944 4945
}

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

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

H
hzcheng 已提交
4954
  // handle the limit offset value, validate the limit
4955
  pQueryInfo->limit = pQuerySql->limit;
4956
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4957
  pQueryInfo->slimit = pQuerySql->slimit;
4958
  
4959
  tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
4960 4961
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
4962
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
4963
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
4964 4965
  }

4966
  if (pQueryInfo->limit.limit == 0) {
4967
    tscDebug("%p limit 0, no output result", pSql);
4968
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4969
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
4970 4971
  }

H
hjxilinx 已提交
4972
  // todo refactor
weixin_48148422's avatar
weixin_48148422 已提交
4973
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
4974
    if (!tscQueryTags(pQueryInfo)) {  // local handle the super table tag query
4975
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
4976
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
4977
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
4978
        }
H
hjxilinx 已提交
4979

4980
        // for projection query on super table, all queries are subqueries
H
hjxilinx 已提交
4981 4982
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
            !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
4983
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
4984
        }
S
slguan 已提交
4985
      }
H
hzcheng 已提交
4986 4987
    }

4988
    if (pQueryInfo->slimit.limit == 0) {
4989
      tscDebug("%p slimit 0, no output result", pSql);
4990
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4991 4992 4993 4994
      return TSDB_CODE_SUCCESS;
    }

    /*
4995 4996 4997 4998
     * 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 已提交
4999
     */
H
hjxilinx 已提交
5000
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
5001 5002 5003 5004
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
5005
    // No tables included. No results generated. Query results are empty.
5006
    if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
5007
      tscDebug("%p no table in super table, no output result", pSql);
5008
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
5009
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5010 5011 5012
    }

    // keep original limitation value in globalLimit
5013
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
5014
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
5015

5016 5017 5018 5019 5020 5021 5022 5023 5024
    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 已提交
5025

5026 5027
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
5028
  } else {
5029
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
5030
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
5031
    }
H
hjxilinx 已提交
5032
  
H
hjxilinx 已提交
5033
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
5034 5035 5036
    
    bool hasTags = false;
    bool hasOtherFunc = false;
S
slguan 已提交
5037
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
5038
    for (int32_t i = 0; i < size; ++i) {
5039
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
5040 5041 5042 5043
      if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
        hasTags = true;
      } else {
        hasOtherFunc = true;
H
hzcheng 已提交
5044 5045
      }
    }
5046 5047
    
    if (hasTags && hasOtherFunc) {
5048
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5049
    }
H
hzcheng 已提交
5050 5051 5052 5053
  }

  return TSDB_CODE_SUCCESS;
}
5054

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

5058 5059 5060
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
5061

H
hjxilinx 已提交
5062 5063 5064
  tVariantList* pKeep = pCreateDb->keep;
  if (pKeep != NULL) {
    switch (pKeep->nExpr) {
S
slguan 已提交
5065
      case 1:
S
TD-1057  
Shengliang Guan 已提交
5066
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
5067 5068
        break;
      case 2: {
S
TD-1057  
Shengliang Guan 已提交
5069 5070
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)pKeep->a[1].pVar.i64Key);
5071 5072 5073
        break;
      }
      case 3: {
S
TD-1057  
Shengliang Guan 已提交
5074 5075 5076
        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);
5077 5078
        break;
      }
5079
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
5080 5081
    }
  }
H
hjxilinx 已提交
5082

H
hjxilinx 已提交
5083 5084
  return TSDB_CODE_SUCCESS;
}
5085

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

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

H
Haojun Liao 已提交
5091
  SStrToken* pToken = &pCreateDbInfo->precision;
5092 5093
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
5094

5095 5096 5097 5098 5099
    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 已提交
5100
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
5101 5102
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
5103
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
5104 5105
    }
  }
H
hjxilinx 已提交
5106

H
hjxilinx 已提交
5107 5108
  return TSDB_CODE_SUCCESS;
}
5109

5110
static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
Haojun Liao 已提交
5111
  pMsg->maxTables = htonl(-1);  // max tables can not be set anymore
H
hjxilinx 已提交
5112
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
5113
  pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
H
hjxilinx 已提交
5114
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
S
TD-1057  
Shengliang Guan 已提交
5115
  pMsg->commitTime = htonl((int32_t)pCreateDb->commitTime);
H
hjxilinx 已提交
5116 5117
  pMsg->minRowsPerFileBlock = htonl(pCreateDb->minRowsPerBlock);
  pMsg->maxRowsPerFileBlock = htonl(pCreateDb->maxRowsPerBlock);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5118
  pMsg->fsyncPeriod = htonl(pCreateDb->fsyncPeriod);
S
slguan 已提交
5119
  pMsg->compression = pCreateDb->compressionLevel;
H
hjxilinx 已提交
5120
  pMsg->walLevel = (char)pCreateDb->walLevel;
H
hjxilinx 已提交
5121
  pMsg->replications = pCreateDb->replica;
5122
  pMsg->quorum = pCreateDb->quorum;
5123
  pMsg->ignoreExist = pCreateDb->ignoreExists;
H
hjxilinx 已提交
5124 5125 5126
}

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

H
hjxilinx 已提交
5130
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5131
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5132
  }
H
hjxilinx 已提交
5133

H
hjxilinx 已提交
5134
  if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5135
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5136
  }
H
hjxilinx 已提交
5137

H
hjxilinx 已提交
5138
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
5139
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5140
  }
H
hjxilinx 已提交
5141

5142
  return TSDB_CODE_SUCCESS;
H
huili 已提交
5143
}
S
slguan 已提交
5144

H
Haojun Liao 已提交
5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163
//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 已提交
5164

5165 5166
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
5167

5168 5169
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
H
hjxilinx 已提交
5170
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5171
  
S
TD-1057  
Shengliang Guan 已提交
5172
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1);
5173

S
slguan 已提交
5174
    if (pExpr->functionId != TSDB_FUNC_TAG) {
H
hjxilinx 已提交
5175
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
5176
      int16_t         columnInfo = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
5177
      SColumnIndex    index = {.tableIndex = 0, .columnIndex = columnInfo};
H
hjxilinx 已提交
5178
      SSchema*        pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5179 5180 5181 5182

      int16_t type = pSchema[index.columnIndex].type;
      int16_t bytes = pSchema[index.columnIndex].bytes;
      char*   name = pSchema[index.columnIndex].name;
H
hjxilinx 已提交
5183
  
5184
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
S
slguan 已提交
5185 5186 5187 5188
      pExpr->colInfo.flag = TSDB_COL_TAG;

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

      int32_t relIndex = index.columnIndex;

5193
      pExpr->colInfo.colIndex = relIndex;
5194 5195
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
5196

5197
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
5198
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
5199 5200 5201 5202
    }
  }
}

H
hjxilinx 已提交
5203 5204 5205
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
5206
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
5207 5208 5209
  pExpr->numOfParams = 1;
}

5210
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
5211
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
H
hjxilinx 已提交
5212
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
5213

H
Haojun Liao 已提交
5214 5215 5216 5217
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

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

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

S
TD-1057  
Shengliang Guan 已提交
5221
  SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, (int32_t)size);
H
Haojun Liao 已提交
5222
  doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
H
hjxilinx 已提交
5223
  pInfo->visible = false;
S
slguan 已提交
5224 5225
}

5226
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5227
  int32_t tagLength = 0;
H
hjxilinx 已提交
5228
  
H
hjxilinx 已提交
5229
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5230 5231
  
  for (int32_t i = 0; i < size; ++i) {
5232
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5233 5234 5235 5236 5237 5238 5239 5240 5241
    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 已提交
5242
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5243
  SSchema*        pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5244

H
hjxilinx 已提交
5245
  for (int32_t i = 0; i < size; ++i) {
5246
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5247
    if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) {
5248
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
S
TD-1057  
Shengliang Guan 已提交
5249
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64Key, &pExpr->resType,
5250
                        &pExpr->resBytes, &pExpr->interBytes, tagLength, true);
S
slguan 已提交
5251 5252 5253 5254
    }
  }
}

5255
static void doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5256
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5257 5258
  
  for (int32_t i = 0; i < size; ++i) {
5259
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5260 5261
    if (pExpr->functionId == TSDB_FUNC_PRJ) {
      bool qualifiedCol = false;
5262
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5263 5264 5265
        SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
  
        if (pExpr->colInfo.colId == pColIndex->colId) {
H
hjxilinx 已提交
5266
          qualifiedCol = true;
H
hjxilinx 已提交
5267
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5268 5269 5270 5271
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
5272

H
hjxilinx 已提交
5273 5274 5275 5276 5277
      assert(qualifiedCol);
    }
  }
}

S
slguan 已提交
5278 5279
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
5280 5281
    SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j);
  
Y
TD-1230  
yihaoDeng 已提交
5282
    if (columnId == pColIndex->colId && TSDB_COL_IS_TAG(pColIndex->flag )) {
S
slguan 已提交
5283 5284 5285 5286 5287 5288 5289
      return true;
    }
  }

  return false;
}

5290
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5291 5292
  bool hasTagPrj = false;
  bool hasColumnPrj = false;
H
hjxilinx 已提交
5293
  
H
hjxilinx 已提交
5294
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5295
  for (int32_t i = 0; i < size; ++i) {
5296
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307
    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
5308
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5309 5310
  bool allInGroupby = true;

H
hjxilinx 已提交
5311 5312
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5313
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5314 5315 5316 5317
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5318
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5319 5320 5321 5322 5323 5324 5325 5326 5327
      allInGroupby = false;
      break;
    }
  }

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

5328
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5329
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5330 5331
  
  for (int32_t i = 0; i < size; ++i) {
5332
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344
    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.
 */
5345
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) {
S
slguan 已提交
5346
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5347
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5348

S
slguan 已提交
5349 5350 5351 5352
  bool    tagColExists = false;
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5353
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5354
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5355
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5356 5357 5358 5359 5360 5361
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
      tagColExists = true;
      break;
    }
  }
H
hjxilinx 已提交
5362

H
hjxilinx 已提交
5363
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5364
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5365 5366
  
    int16_t functionId = pExpr->functionId;
5367
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5368
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5369
      continue;
S
slguan 已提交
5370
    }
H
hjxilinx 已提交
5371

H
hjxilinx 已提交
5372 5373 5374 5375 5376 5377
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5378

H
hjxilinx 已提交
5379
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5380 5381
    // 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.
5382
    if (numOfAggregation > 0) {
5383
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5384 5385 5386 5387 5388 5389
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5390 5391
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5392 5393 5394 5395 5396
    } 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 已提交
5397 5398
      for (int32_t i = 0; i < numOfExprs; ++i) {
        
5399
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5400 5401 5402 5403 5404
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5405
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5406 5407 5408
        }
      }

5409 5410
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5411 5412
    }
  } else {
5413
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5414
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5415
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5416
      }
H
hjxilinx 已提交
5417

H
hjxilinx 已提交
5418 5419
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5420 5421
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5422
      }
S
slguan 已提交
5423 5424 5425 5426 5427 5428
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

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

H
Haojun Liao 已提交
5434
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5435
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5436 5437 5438 5439
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5440
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5441
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5442
    int16_t colIndex = pColIndex->colIndex;
5443
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5444
      type  = s.type;
H
Haojun Liao 已提交
5445
      bytes = s.bytes;
H
Haojun Liao 已提交
5446
      name  = s.name;
S
slguan 已提交
5447
    } else {
5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458
      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 已提交
5459
    }
H
hjxilinx 已提交
5460 5461 5462
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5463
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5464
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5465
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5466
      
B
Bomin Zhang 已提交
5467 5468
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5469
      
S
slguan 已提交
5470 5471 5472
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5473
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
S
TD-1057  
Shengliang Guan 已提交
5474
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5475 5476
    } else {
      // if this query is "group by" normal column, interval is not allowed
5477
      if (pQueryInfo->intervalTime > 0) {
5478
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5479 5480 5481
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5482
      for (int32_t j = 0; j < size; ++j) {
5483
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5484 5485 5486 5487 5488 5489 5490 5491 5492 5493
        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) {
5494
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5495 5496 5497 5498 5499 5500 5501
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5502
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5503
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5504
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5505
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5506
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5507 5508

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5509
  if (tscQueryTags(pQueryInfo)) {
5510
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5511
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5512 5513 5514 5515 5516
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5517
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5518
    // check if all the tags prj columns belongs to the group by columns
5519 5520
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5521
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5522 5523 5524
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5525 5526
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5527
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5528 5529 5530 5531 5532 5533
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5534
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5535
        bool qualified = false;
5536
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5537
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5538 5539 5540 5541 5542 5543 5544
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5545
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5546 5547 5548 5549
        }
      }

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

5554
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5555
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5556 5557 5558
      }
    }

5559
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5560
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5561 5562 5563 5564 5565 5566
    }

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

H
hjxilinx 已提交
5571
    // projection query on super table does not compatible with "group by" syntax
5572
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5573
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5574
    }
H
hjxilinx 已提交
5575

H
hjxilinx 已提交
5576
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5577
  } else {
5578
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5579 5580
  }
}
5581
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5582 5583 5584
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5585

H
hjxilinx 已提交
5586 5587
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5588
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5589
  }
H
hjxilinx 已提交
5590

H
hjxilinx 已提交
5591 5592
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5593
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hjxilinx 已提交
5594
  }
H
hjxilinx 已提交
5595

H
hjxilinx 已提交
5596
  // TODO redefine the function
H
hjxilinx 已提交
5597 5598 5599 5600 5601 5602
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5603
  int32_t index = -1;
H
hjxilinx 已提交
5604
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5605
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5606
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5607 5608 5609 5610
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5611 5612 5613

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5614
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5615
    case 1:
H
Haojun Liao 已提交
5616 5617 5618
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5619
    case 3:
H
Haojun Liao 已提交
5620
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5621
    case 4:
H
Haojun Liao 已提交
5622
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5623
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5624
  }
5625 5626 5627 5628 5629 5630
  
  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 已提交
5631
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5632 5633
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5634
}
H
hjxilinx 已提交
5635 5636

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

H
hjxilinx 已提交
5640 5641
  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);
5642
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5643
  }
H
hjxilinx 已提交
5644

H
hjxilinx 已提交
5645
  if (pCreate->replications != -1 &&
5646
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5647
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5648
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5649
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5650
  }
H
hjxilinx 已提交
5651

5652 5653 5654 5655 5656 5657 5658
  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 已提交
5659
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5660
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5661
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5662
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5663
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5664
  }
H
hjxilinx 已提交
5665

H
hjxilinx 已提交
5666 5667 5668 5669
  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);
5670
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5671
  }
H
hjxilinx 已提交
5672

H
hjxilinx 已提交
5673
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5674
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5675
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5676
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5677
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5678
  }
H
hjxilinx 已提交
5679 5680 5681 5682

  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);
5683
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5684
  }
H
hjxilinx 已提交
5685

H
hjxilinx 已提交
5686
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5687
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5688
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5689
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5690
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5691
  }
H
hjxilinx 已提交
5692

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5693 5694 5695 5696 5697 5698 5699
  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 已提交
5700
  if (pCreate->compression != -1 &&
S
slguan 已提交
5701
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5702
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5703
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5704
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5705
  }
H
hjxilinx 已提交
5706

H
hjxilinx 已提交
5707 5708
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5709 5710

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

S
TD-1057  
Shengliang Guan 已提交
5714
  int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
5715
  if (size == 0) {
H
hjxilinx 已提交
5716 5717
    return;
  }
H
hjxilinx 已提交
5718

H
hjxilinx 已提交
5719
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5720 5721

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

H
hjxilinx 已提交
5724 5725
  offset += sprintf(str, "num:%d [", size);
  for (int32_t i = 0; i < size; ++i) {
5726
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5727

L
lihui 已提交
5728
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5729 5730 5731
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5732 5733 5734
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
5736
    if (i < size - 1) {
H
hjxilinx 已提交
5737 5738 5739
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5740

H
hjxilinx 已提交
5741
  str[offset] = ']';
5742
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5743
}
5744

5745
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5746 5747 5748
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5749 5750
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5751
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5752 5753 5754 5755 5756 5757 5758 5759 5760

  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 已提交
5761
  SStrToken* pzTableName = &(pCreateTable->name);
5762 5763

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5764
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5765 5766
  }

H
Haojun Liao 已提交
5767
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5768
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5769 5770 5771 5772
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
5773
    return TSDB_CODE_TSC_INVALID_SQL;
5774 5775 5776 5777
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
H
hjxilinx 已提交
5778
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[col]);
5779 5780 5781 5782
  }

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

H
hjxilinx 已提交
5783
  if (pTagList != NULL) {  // create super table[optional]
5784
    for (int32_t i = 0; i < pTagList->nField; ++i) {
H
hjxilinx 已提交
5785
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pTagList->p[i]);
5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802
    }

    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;
5803 5804 5805
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
5806 5807 5808
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
5809 5810 5811 5812

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

H
hjxilinx 已提交
5813
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5814 5815

  // super table name, create table by using dst
H
Haojun Liao 已提交
5816
  SStrToken* pToken = &(pCreateTable->usingInfo.stableName);
5817 5818

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5819
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5820 5821
  }

H
Haojun Liao 已提交
5822
  if (tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5823
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5824 5825 5826
  }

  // get meter meta from mnode
B
Bomin Zhang 已提交
5827
  tstrncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, sizeof(pCreateTable->usingInfo.tagdata.name));
5828 5829
  tVariantList* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;

H
hjxilinx 已提交
5830
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5831 5832 5833 5834
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5835
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5836
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5837 5838 5839
  }

  // too long tag values will return invalid sql, not be truncated automatically
H
hjxilinx 已提交
5840
  SSchema* pTagSchema = tscGetTableTagSchema(pStableMeterMetaInfo->pTableMeta);
5841

5842
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
B
Bomin Zhang 已提交
5843 5844 5845 5846 5847
  SKVRowBuilder kvRowBuilder = {0};
  if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
hjxilinx 已提交
5848
  int32_t ret = TSDB_CODE_SUCCESS;
5849
  for (int32_t i = 0; i < pList->nExpr; ++i) {
H
Haojun Liao 已提交
5850 5851 5852
    SSchema* pSchema = &pTagSchema[i];
    
    char tagVal[TSDB_MAX_TAGS_LEN];
B
Bomin Zhang 已提交
5853
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
H
Haojun Liao 已提交
5854
      if (pList->a[i].pVar.nLen > pSchema->bytes) {
B
Bomin Zhang 已提交
5855
        tdDestroyKVRowBuilder(&kvRowBuilder);
H
hjxilinx 已提交
5856 5857 5858
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
H
Haojun Liao 已提交
5859

B
Bomin Zhang 已提交
5860
    ret = tVariantDump(&(pList->a[i].pVar), tagVal, pSchema->type, true);
H
Haojun Liao 已提交
5861 5862 5863 5864 5865 5866 5867 5868 5869 5870

    // check again after the convert since it may be converted from binary to nchar.
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
      int16_t len = varDataTLen(tagVal);
      if (len > pSchema->bytes) {
        tdDestroyKVRowBuilder(&kvRowBuilder);
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }

5871
    if (ret != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
5872
      tdDestroyKVRowBuilder(&kvRowBuilder);
5873
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5874 5875
    }

H
Haojun Liao 已提交
5876 5877


B
Bomin Zhang 已提交
5878
    tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
5879 5880
  }

B
Bomin Zhang 已提交
5881
  SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
B
Bomin Zhang 已提交
5882 5883 5884 5885 5886
  tdDestroyKVRowBuilder(&kvRowBuilder);
  if (row == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  tdSortKVRowByColIdx(row);
B
Bomin Zhang 已提交
5887
  pTag->dataLen = kvRowLen(row);
B
Bomin Zhang 已提交
5888
  kvRowCpy(pTag->data, row);
B
Bomin Zhang 已提交
5889 5890
  free(row);

5891 5892
  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5893
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5894 5895
  }

H
hjxilinx 已提交
5896
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
5897
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910
  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 已提交
5911 5912
  const char* msg6 = "from missing in subclause";
  
5913
  SSqlCmd*    pCmd = &pSql->cmd;
5914
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5915 5916
  assert(pQueryInfo->numOfTables == 1);

5917
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5918
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5919 5920

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
5921
  SStrToken* pzTableName = &(pCreateTable->name);
5922 5923 5924
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5925
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5926
  }
H
Haojun Liao 已提交
5927
  
5928
  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
H
Haojun Liao 已提交
5929 5930 5931 5932 5933
  if (pSrcMeterName == NULL || pSrcMeterName->nExpr == 0) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
  tVariant* pVar = &pSrcMeterName->a[0].pVar;
H
Haojun Liao 已提交
5934
  SStrToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
5935
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
5936
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5937 5938
  }

H
Haojun Liao 已提交
5939
  if (tscSetTableFullName(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5940
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5941 5942
  }

H
hjxilinx 已提交
5943
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5944 5945 5946 5947
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
5948
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
H
Haojun Liao 已提交
5949
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false) != TSDB_CODE_SUCCESS) {
5950
    return TSDB_CODE_TSC_INVALID_SQL;
5951 5952 5953
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5954
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5955
      return TSDB_CODE_TSC_INVALID_SQL;
5956 5957 5958 5959
    }
  }

  // set interval value
5960
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5961
    return TSDB_CODE_TSC_INVALID_SQL;
5962
  } else {
5963
    if ((pQueryInfo->intervalTime > 0) &&
5964
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
5965
      return TSDB_CODE_TSC_INVALID_SQL;
5966 5967 5968 5969
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
5970
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5971
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5972 5973 5974
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5975
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5976 5977
  }

5978
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5979
    return TSDB_CODE_TSC_INVALID_SQL;
5980 5981
  }

H
hjxilinx 已提交
5982
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5983

5984
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5985
    return TSDB_CODE_TSC_INVALID_SQL;
5986 5987 5988 5989 5990 5991 5992
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
5993
    if (pQueryInfo->intervalTime == 0) {
5994
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
5995 5996 5997 5998 5999 6000
    }

    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))) {
6001
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
6002 6003 6004 6005 6006
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
6007
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
6008 6009 6010 6011 6012 6013
  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 已提交
6014 6015 6016 6017 6018 6019 6020 6021 6022 6023
  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";
6024 6025

  int32_t code = TSDB_CODE_SUCCESS;
6026

6027
  SSqlCmd* pCmd = &pSql->cmd;
6028

6029
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
6030
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
6031
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
6032
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
6033
  }
H
hjxilinx 已提交
6034

H
Haojun Liao 已提交
6035 6036
  assert(pCmd->clauseIndex == index);

6037 6038
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
6039
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051
  }

  /*
   * 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);
6052
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
6053 6054
  }

H
Haojun Liao 已提交
6055
  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM * 2) {
6056
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
6057 6058
  }

6059
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
6060

H
Haojun Liao 已提交
6061
  if (pQuerySql->from->nExpr > 4) {
H
Haojun Liao 已提交
6062 6063 6064
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

6065
  // set all query tables, which are maybe more than one.
H
Haojun Liao 已提交
6066
  for (int32_t i = 0; i < pQuerySql->from->nExpr; ) {
6067 6068 6069
    tVariant* pTableItem = &pQuerySql->from->a[i].pVar;

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
6070
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6071 6072 6073 6074
    }

    pTableItem->nLen = strdequote(pTableItem->pz);

H
Haojun Liao 已提交
6075
    SStrToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
6076
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
6077
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6078 6079
    }

H
Haojun Liao 已提交
6080
    if (pQueryInfo->numOfTables <= i/2) {  // more than one table
H
hjxilinx 已提交
6081
      tscAddEmptyMetaInfo(pQueryInfo);
6082 6083
    }

H
Haojun Liao 已提交
6084
    STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i/2);
6085

H
Haojun Liao 已提交
6086
    SStrToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
6087
    if (tscSetTableFullName(pTableMetaInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
6088
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6089 6090
    }

H
Haojun Liao 已提交
6091
    tVariant* pTableItem1 = &pQuerySql->from->a[i + 1].pVar;
H
Haojun Liao 已提交
6092
    SStrToken aliasName = {.z = pTableItem1->pz, .n = pTableItem1->nLen, .type = TK_STRING};
H
Haojun Liao 已提交
6093 6094 6095 6096
    if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

6097 6098 6099 6100 6101 6102
    // 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 已提交
6103 6104

    code = tscGetTableMeta(pSql, pTableMetaInfo1);
6105 6106 6107
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
H
Haojun Liao 已提交
6108 6109

    i += 2;
6110 6111
  }

H
Haojun Liao 已提交
6112
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr / 2);
H
hjxilinx 已提交
6113
  bool isSTable = false;
H
hjxilinx 已提交
6114
  
weixin_48148422's avatar
weixin_48148422 已提交
6115
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
6116 6117 6118 6119 6120 6121 6122
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
6123 6124
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
6125
  }
6126

6127
  // parse the group by clause in the first place
6128
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
6129
    return TSDB_CODE_TSC_INVALID_SQL;
6130 6131
  }

H
Haojun Liao 已提交
6132
  int32_t joinQuery = (pQuerySql->from != NULL && pQuerySql->from->nExpr > 2);
Y
TD-1230  
yihaoDeng 已提交
6133 6134 6135 6136

  if (pQuerySql->pWhere) {
    pQueryInfo->window = TSWINDOW_INITIALIZER;
  }
H
Haojun Liao 已提交
6137
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery) != TSDB_CODE_SUCCESS) {
6138
    return TSDB_CODE_TSC_INVALID_SQL;
6139 6140 6141
  }

  // set interval value
6142
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6143
    return TSDB_CODE_TSC_INVALID_SQL;
6144
  } else {
6145
    if ((pQueryInfo->intervalTime > 0) &&
6146
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6147
      return TSDB_CODE_TSC_INVALID_SQL;
6148 6149 6150 6151
    }
  }

  // set order by info
6152
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
6153
    return TSDB_CODE_TSC_INVALID_SQL;
6154 6155 6156
  }

  // set where info
H
hjxilinx 已提交
6157
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
6158
  
6159
  if (pQuerySql->pWhere != NULL) {
6160
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
6161
      return TSDB_CODE_TSC_INVALID_SQL;
6162 6163 6164
    }

    pQuerySql->pWhere = NULL;
H
hjxilinx 已提交
6165
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
6166 6167
      pQueryInfo->window.skey = pQueryInfo->window.skey / 1000;
      pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000;
6168 6169
    }
  } else {  // set the time rang
H
Haojun Liao 已提交
6170
    pQueryInfo->window = TSWINDOW_INITIALIZER;
H
Haojun Liao 已提交
6171 6172 6173
    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 ");
    }
6174 6175 6176
  }

  // user does not specified the query time window, twa is not allowed in such case.
H
Haojun Liao 已提交
6177
  if ((pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX ||
H
hjxilinx 已提交
6178
       (pQueryInfo->window.ekey == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
6179
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
6180 6181 6182
  }

  // no result due to invalid query time range
H
hjxilinx 已提交
6183
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6184
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6185 6186 6187
    return TSDB_CODE_SUCCESS;
  }

6188
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6189
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6190 6191 6192
  }

  // in case of join query, time range is required.
6193
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
S
TD-1057  
Shengliang Guan 已提交
6194
    int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6195

H
hjxilinx 已提交
6196
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6197
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6198 6199 6200
    }
  }

6201
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6202 6203 6204
    return code;
  }

6205
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6206 6207 6208
    return code;
  }

6209
  setColumnOffsetValueInResultset(pQueryInfo);
6210

6211 6212 6213 6214 6215
  /*
   * 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) {
6216
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6217 6218
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6219

6220
    if (pQueryInfo->intervalTime > 0 && pQueryInfo->intervalTimeUnit != 'n' && pQueryInfo->intervalTimeUnit != 'y') {
S
TD-1057  
Shengliang Guan 已提交
6221
      int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6222
      // number of result is not greater than 10,000,000
6223
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_INTERVAL_TIME_WINDOW) {
6224
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6225 6226
      }
    }
H
hjxilinx 已提交
6227

6228
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6229 6230 6231 6232
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6233 6234 6235

  return TSDB_CODE_SUCCESS;  // Does not build query message here
}
H
hjxilinx 已提交
6236

6237
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols) {
H
hjxilinx 已提交
6238 6239
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6240
  
6241
  if (pSqlExpr->pLeft != NULL) {
6242
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6243 6244 6245 6246 6247
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6248
  if (pSqlExpr->pRight != NULL) {
6249
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6250 6251 6252 6253 6254
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6255
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6256
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6257
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6258
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6259 6260 6261
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6262
      return TSDB_CODE_SUCCESS;
6263
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6264
      // arithmetic expression on the results of aggregation functions
6265
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6266
      (*pExpr)->nodeType = TSQL_NODE_COL;
6267 6268 6269
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6270
      // set the input column data byte and type.
H
hjxilinx 已提交
6271 6272 6273 6274 6275 6276
      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 已提交
6277
          (*pExpr)->pSchema->type = (uint8_t)p1->resType;
H
hjxilinx 已提交
6278
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
hjxilinx 已提交
6279 6280 6281
          break;
        }
      }
6282
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6283
      SColumnIndex index = {0};
6284
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6285 6286 6287
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
H
Haojun Liao 已提交
6288 6289 6290 6291

      STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
      int32_t numOfColumns = tscGetNumOfColumns(pTableMeta);

6292 6293 6294
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
H
Haojun Liao 已提交
6295

6296 6297
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6298 6299 6300
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6301
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6302 6303
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
H
Haojun Liao 已提交
6304 6305
        colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;

6306 6307
        taosArrayPush(pCols, &colIndex);
      }
6308
      
H
hjxilinx 已提交
6309
      return TSDB_CODE_SUCCESS;
6310
    } else {
6311
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6312 6313 6314
    }
    
  } else {
H
hjxilinx 已提交
6315
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6316 6317
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6318 6319 6320
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6321
    
H
Haojun Liao 已提交
6322
    SStrToken t = {.type = pSqlExpr->nSQLOptr};
H
[td-32]  
hjxilinx 已提交
6323
    (*pExpr)->_node.optr = getBinaryExprOptr(&t);
6324
    
H
[td-32]  
hjxilinx 已提交
6325
    assert((*pExpr)->_node.optr != 0);
H
hjxilinx 已提交
6326
    
H
[td-32]  
hjxilinx 已提交
6327
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6328 6329
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6330
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6331
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6332
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6333 6334 6335
        }
      }
    }
H
Hui Li 已提交
6336

6337
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6338 6339
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
      if (pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6340 6341 6342
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6343 6344
      }
    }
H
hjxilinx 已提交
6345 6346 6347
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6348
}