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

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

S
slguan 已提交
20
#include "os.h"
H
Haojun Liao 已提交
21
#include "qAst.h"
H
hzcheng 已提交
22
#include "taos.h"
S
slguan 已提交
23
#include "taosmsg.h"
H
Haojun Liao 已提交
24 25
#include "tcompare.h"
#include "tname.h"
S
slguan 已提交
26
#include "tscLog.h"
H
hzcheng 已提交
27 28 29
#include "tscUtil.h"
#include "tschemautil.h"
#include "tsclient.h"
H
Haojun Liao 已提交
30 31
#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 95 96
static int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
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 已提交
97
static int32_t validateEp(char* ep);
H
hzcheng 已提交
98
static int32_t validateDNodeConfig(tDCLSQL* pOptions);
S
slguan 已提交
99
static int32_t validateLocalConfig(tDCLSQL* pOptions);
H
hzcheng 已提交
100
static int32_t validateColumnName(char* name);
101
static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType);
S
slguan 已提交
102

H
hjxilinx 已提交
103
static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField);
104
static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo);
105
static bool hasNormalColumnFilter(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
  /*
   * transfer sql functions that need secondary merge into another format
1333
   * in dealing with super table queries such as: count/first/last
H
Haojun Liao 已提交
1334
   */
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) {
1518 1519
  const char* msg1 = "not support column types";

H
hzcheng 已提交
1520 1521
  int16_t type = 0;
  int16_t bytes = 0;
1522
  char    columnName[TSDB_COL_NAME_LEN] = {0};
Y
TD-1230  
yihaoDeng 已提交
1523
  int32_t functionID = cvtFunc.execFuncId;
H
hzcheng 已提交
1524 1525

  if (functionID == TSDB_FUNC_SPREAD) {
1526 1527
    int32_t t1 = pSchema[pColIndex->columnIndex].type;
    if (t1 == TSDB_DATA_TYPE_BINARY || t1 == TSDB_DATA_TYPE_NCHAR || t1 == 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
  }
1544

1545
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, bytes, false);
B
Bomin Zhang 已提交
1546
  tstrncpy(pExpr->aliasName, columnName, sizeof(pExpr->aliasName));
1547

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

S
slguan 已提交
1604 1605 1606 1607
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
        if (pParamElem->pNode->nSQLOptr == TK_ALL) {
          // select table.*
          // check if the table name is valid or not
H
Haojun Liao 已提交
1608
          SStrToken tmpToken = pParamElem->pNode->colInfo;
S
slguan 已提交
1609

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

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
1616
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1617
        } else {
H
hjxilinx 已提交
1618
          // count the number of meters created according to the super table
1619 1620
          if (getColumnIndexByName(pCmd, pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1621 1622
          }

H
hjxilinx 已提交
1623
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1624 1625

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1626 1627
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1628
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1629
            isTag = true;
H
hzcheng 已提交
1630 1631
          }

S
slguan 已提交
1632
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1633
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1634
        }
S
slguan 已提交
1635 1636 1637
      } 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;
1638
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1639
      }
H
Haojun Liao 已提交
1640 1641 1642

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

H
hjxilinx 已提交
1643
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1644
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1645
      
S
slguan 已提交
1646
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1647 1648 1649 1650 1651
      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) {
1652
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1653 1654
        }
      }
H
Haojun Liao 已提交
1655 1656

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

S
slguan 已提交
1661
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1662 1663 1664
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1665 1666 1667 1668 1669 1670
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1671
    case TK_TWA:
H
hzcheng 已提交
1672 1673 1674 1675 1676 1677 1678 1679 1680
    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 */
1681
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1682 1683 1684 1685
      }

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

S
slguan 已提交
1689
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
Y
yihaoDeng 已提交
1690
      if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
1691
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1692
      }
Y
yihaoDeng 已提交
1693 1694 1695
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
H
hzcheng 已提交
1696 1697

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

H
hjxilinx 已提交
1702
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1703
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1704 1705 1706 1707
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
1708
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1709 1710 1711

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1712
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1713 1714
      }

S
slguan 已提交
1715 1716
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
1717
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1718
      }
H
hzcheng 已提交
1719

S
slguan 已提交
1720
      // set the first column ts for diff query
H
hzcheng 已提交
1721
      if (optr == TK_DIFF) {
1722
        colIndex += 1;
S
slguan 已提交
1723
        SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
H
hjxilinx 已提交
1724
        SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
1725
                         TSDB_KEYSIZE, false);
H
hzcheng 已提交
1726

S
slguan 已提交
1727
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1728
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1729 1730
      }

S
slguan 已提交
1731
      // functions can not be applied to tags
H
hjxilinx 已提交
1732
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1733
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1734 1735
      }

1736
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, resultSize, false);
H
hzcheng 已提交
1737 1738 1739 1740

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

S
slguan 已提交
1745
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1746 1747

        memset(val, 0, tListLen(val));
1748
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1749
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1750 1751
        }

S
slguan 已提交
1752
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1753 1754
      }

S
slguan 已提交
1755 1756 1757
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1758 1759
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1760
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1761 1762 1763
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
S
TD-1057  
Shengliang Guan 已提交
1764
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, (int32_t)pExpr->resType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
1765 1766
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1767
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1768 1769
        }
      }
H
Haojun Liao 已提交
1770 1771

      tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
S
slguan 已提交
1772
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1773 1774 1775 1776 1777 1778 1779 1780 1781
    }
    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 已提交
1782
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1783
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
B
Bomin Zhang 已提交
1784
      }
1785 1786

      // NOTE: has time range condition or normal column filter condition, the last_row query will be transferred to last query
Y
TD-1230  
yihaoDeng 已提交
1787
      SConvertFunc cvtFunc = {.originFuncId = functionID, .execFuncId = functionID};
1788
      if (functionID == TSDB_FUNC_LAST_ROW && ((!TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER)) || (hasNormalColumnFilter(pQueryInfo)))) {
Y
TD-1230  
yihaoDeng 已提交
1789 1790
        cvtFunc.execFuncId = TSDB_FUNC_LAST;
      }
1791

H
hzcheng 已提交
1792 1793
      if (!requireAllFields) {
        if (pItem->pNode->pParam->nExpr < 1) {
1794
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1795 1796
        }

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

H
hzcheng 已提交
1801 1802 1803 1804
        /* 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) {
1805
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1806 1807
          }

S
slguan 已提交
1808 1809 1810 1811
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

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

1814
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1815
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1816 1817
            }

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

H
hjxilinx 已提交
1821
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
1822
              index.columnIndex = j;
Y
TD-1230  
yihaoDeng 已提交
1823
              if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex++, &index) != 0) {
1824
                return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1825 1826
              }
            }
H
hzcheng 已提交
1827

S
slguan 已提交
1828
          } else {
1829 1830
            if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1831 1832
            }

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

            // functions can not be applied to tags
H
hjxilinx 已提交
1837
            if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
1838
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1839
            }
Y
TD-1230  
yihaoDeng 已提交
1840
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex + i, &index) != 0) {
1841
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1842
            }
1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858

            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 已提交
1859 1860
          }
        }
1861
        
S
slguan 已提交
1862 1863 1864 1865
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

H
Haojun Liao 已提交
1866
        // multicolumn selection does not support alias name
H
Haojun Liao 已提交
1867
        if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
1868
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
1869 1870
        }

1871
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
1872
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
1873
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1874

H
hjxilinx 已提交
1875
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
1876
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
Y
TD-1230  
yihaoDeng 已提交
1877
            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex, &index) != 0) {
1878
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1879
            }
H
Haojun Liao 已提交
1880 1881

            colIndex++;
H
hzcheng 已提交
1882
          }
S
slguan 已提交
1883

H
hjxilinx 已提交
1884
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1885 1886
        }

1887
        
S
slguan 已提交
1888
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1889 1890 1891 1892 1893 1894 1895 1896 1897
      }
    }
    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 */
1898
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1899 1900 1901 1902
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
1903
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1904
      }
H
hjxilinx 已提交
1905
      
S
slguan 已提交
1906
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1907 1908
      if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1909
      }
Y
yihaoDeng 已提交
1910 1911 1912 1913
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
      
H
hjxilinx 已提交
1914
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1915
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1916 1917

      // functions can not be applied to tags
H
hjxilinx 已提交
1918
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1919
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1920 1921 1922
      }

      // 2. valid the column type
S
slguan 已提交
1923
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
1924
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1925
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1926 1927 1928 1929
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
1930
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1931 1932 1933 1934
      }

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

S
slguan 已提交
1935 1936
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1937

H
hjxilinx 已提交
1938
      char    val[8] = {0};
H
hjxilinx 已提交
1939 1940
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
1941
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
1942
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
1943

L
lihui 已提交
1944
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
1945
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
1946
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958
        }

        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) {
1959
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1960
        }
dengyihao's avatar
dengyihao 已提交
1961 1962
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
        colIndex += 1;  // the first column is ts
H
hzcheng 已提交
1963

1964
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1965
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1966
      } else {
1967
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
1968

H
Haojun Liao 已提交
1969
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
1970
        if (nTop <= 0 || nTop > 100) {  // todo use macro
1971
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1972 1973 1974 1975
        }

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

H
Haojun Liao 已提交
1979
        // todo REFACTOR
H
hzcheng 已提交
1980
        // set the first column ts for top/bottom query
S
slguan 已提交
1981
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
1982 1983
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
            TSDB_KEYSIZE, false);
H
Haojun Liao 已提交
1984
        tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
S
slguan 已提交
1985

H
Haojun Liao 已提交
1986
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
1987
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
1988
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
1989
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
1990

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

1993
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1994
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
1995
      }
H
hjxilinx 已提交
1996 1997
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1998
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1999
  
S
slguan 已提交
2000
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
2001
      if (finalResult) {
2002
        insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
2003 2004
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
2005
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
2006 2007
        }
      }
S
slguan 已提交
2008

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

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
2057 2058 2059
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
2060
        s = tGetTableNameColumnSchema();
2061 2062 2063 2064
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
2065 2066
      int16_t bytes = 0;
      int16_t type  = 0;
2067
      int32_t inter = 0;
2068 2069 2070 2071

      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 已提交
2072
      s.type = (uint8_t)type;
2073 2074 2075 2076 2077
      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 已提交
2078
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2079
    }
2080
    
H
hzcheng 已提交
2081
    default:
2082
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2083
  }
2084
  
H
hzcheng 已提交
2085 2086
}

S
slguan 已提交
2087 2088
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
2089
  assert(num == 1 && tableIndex >= 0);
S
slguan 已提交
2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100

  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 已提交
2101 2102 2103 2104
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
S
TD-1057  
Shengliang Guan 已提交
2105
    int32_t len = ((int32_t)pItem->pNode->operand.n < nameLength) ? (int32_t)pItem->pNode->operand.n : nameLength;
H
hzcheng 已提交
2106 2107 2108 2109 2110 2111 2112 2113
    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 已提交
2114 2115 2116
static bool isTablenameToken(SStrToken* token) {
  SStrToken tmpToken = *token;
  SStrToken tableToken = {0};
S
slguan 已提交
2117 2118 2119 2120 2121 2122

  extractTableNameFromToken(&tmpToken, &tableToken);

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

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

H
hjxilinx 已提交
2126 2127
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2128 2129 2130 2131 2132 2133 2134 2135 2136 2137

  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 已提交
2138
      break;
S
slguan 已提交
2139 2140 2141 2142 2143 2144
    }
  }

  return columnIndex;
}

H
Haojun Liao 已提交
2145
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2146 2147 2148 2149 2150 2151 2152 2153 2154 2155
  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) {
2156 2157
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2158 2159 2160

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2161
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
2162 2163 2164 2165 2166 2167 2168
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2169
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2170 2171 2172 2173 2174 2175
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2176
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2177 2178 2179 2180 2181 2182
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2183
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2184 2185 2186
  }
}

H
Haojun Liao 已提交
2187
int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2188
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2189
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2190 2191 2192 2193 2194 2195 2196
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
2197
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2198
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
Haojun Liao 已提交
2199 2200
    char* name = pTableMetaInfo->aliasName;
    if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
S
slguan 已提交
2201 2202 2203 2204 2205 2206
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
2207
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2208 2209 2210 2211 2212
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
2213 2214
int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SStrToken tableToken = {0};
S
slguan 已提交
2215 2216
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2217
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2218
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2219 2220
  }

S
slguan 已提交
2221 2222
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2223

H
Haojun Liao 已提交
2224
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2225
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2226
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2227 2228
  }

H
Haojun Liao 已提交
2229
  SStrToken tmpToken = *pToken;
S
slguan 已提交
2230

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

2235
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248
}

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 已提交
2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266
    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 已提交
2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302
    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 已提交
2303 2304
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319
      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 已提交
2320
  SSqlCmd*        pCmd = &pSql->cmd;
2321
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2322
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2323

H
hzcheng 已提交
2324 2325
  pCmd->command = TSDB_SQL_SHOW;

2326
  const char* msg1 = "invalid name";
2327
  const char* msg2 = "pattern filter string too long";
2328 2329 2330 2331
  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 已提交
2332 2333 2334 2335 2336

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2337 2338 2339
  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 已提交
2340
    // db prefix in tagCond, show table conds in payload
H
Haojun Liao 已提交
2341
    SStrToken* pDbPrefixToken = &pShowInfo->prefix;
2342
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2343

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

2348
      if (pDbPrefixToken->n <= 0) {
2349
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2350 2351
      }

2352
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2353
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2354 2355
      }

H
hjxilinx 已提交
2356
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2357
      if (ret != TSDB_CODE_SUCCESS) {
2358
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2359
      }
2360
    }
H
hzcheng 已提交
2361

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

2367
      if (pPattern->n <= 0) {
2368
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2369
      }
H
hzcheng 已提交
2370

H
Haojun Liao 已提交
2371
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2372
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2373 2374
      }
    }
2375 2376
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2377
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2378 2379
    }

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

2386
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2387
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2388
    }
H
hzcheng 已提交
2389 2390 2391 2392 2393
  }

  return TSDB_CODE_SUCCESS;
}

2394 2395 2396 2397
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 已提交
2398

2399 2400
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2401
  
H
Haojun Liao 已提交
2402
  SStrToken* idStr = &(pInfo->pDCLInfo->ip);
2403
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2404
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2405 2406
  }

2407
  strncpy(pCmd->payload, idStr->z, idStr->n);
2408

H
hzcheng 已提交
2409
  const char delim = ':';
2410 2411
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2412

2413 2414 2415 2416 2417
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2418

2419 2420 2421 2422 2423 2424
  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 已提交
2425
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2426 2427 2428 2429 2430
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2431
  }
2432
  
H
hzcheng 已提交
2433 2434 2435
  return TSDB_CODE_SUCCESS;
}

2436 2437 2438 2439 2440 2441
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);

2442
  in_addr_t epAddr = taosInetAddr(tmp);
2443

2444
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2445 2446
}

H
hjxilinx 已提交
2447
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2448
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2449

weixin_48148422's avatar
weixin_48148422 已提交
2450
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2451
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2452 2453
  }

H
hjxilinx 已提交
2454
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2455 2456 2457

  int16_t bytes = 0;
  int16_t type = 0;
2458
  int32_t interBytes = 0;
H
hjxilinx 已提交
2459 2460 2461
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2462
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2463 2464
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

2465
    int32_t colIndex = pExpr->colInfo.colIndex;
H
hjxilinx 已提交
2466
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2467
    
S
slguan 已提交
2468
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2469 2470
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
S
TD-1057  
Shengliang Guan 已提交
2471
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64Key, &type, &bytes,
2472
                            &interBytes, 0, true) != TSDB_CODE_SUCCESS) {
2473
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2474
      }
H
hzcheng 已提交
2475

2476
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2477
      // todo refactor
2478
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2479 2480 2481
    }
  }

2482
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2483
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2484 2485 2486
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2487
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2488
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2489
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2490 2491
    return;
  }
H
hjxilinx 已提交
2492 2493 2494
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2495
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2496
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2497
    
2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514
    // 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 已提交
2515 2516 2517
  }
}

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

S
slguan 已提交
2523
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2524 2525
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2526
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
2527
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
2528
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2529
      return true;
H
hzcheng 已提交
2530 2531 2532
    }
  }

2533 2534
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2535
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2536 2537
      return true;
    }
H
hzcheng 已提交
2538

2539
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2540
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2541
      return true;
2542 2543 2544
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
2545
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2546 2547
        return true;
      }
H
hzcheng 已提交
2548 2549
    }
  }
S
slguan 已提交
2550

H
hzcheng 已提交
2551 2552 2553
  return false;
}

H
Haojun Liao 已提交
2554
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
H
hzcheng 已提交
2555
  int32_t startIdx = 0;
H
hjxilinx 已提交
2556
  
H
hjxilinx 已提交
2557 2558
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2559 2560

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

H
Haojun Liao 已提交
2565
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2566 2567 2568

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2569 2570 2571
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2572
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2573

H
hjxilinx 已提交
2574
    int16_t functionId = pExpr1->functionId;
2575 2576 2577 2578
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
hjxilinx 已提交
2579
    if (functionId == TSDB_FUNC_PRJ && pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
2580 2581 2582
      continue;
    }

H
Haojun Liao 已提交
2583
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2584 2585
      return false;
    }
H
Haojun Liao 已提交
2586 2587 2588 2589

    if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
      return false;
    }
H
hzcheng 已提交
2590 2591 2592 2593 2594
  }

  return true;
}

2595
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2596 2597
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
H
Haojun Liao 已提交
2598
//  const char* msg3 = "group by columns must belong to one table";
S
slguan 已提交
2599 2600 2601
  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 已提交
2602

2603
  // todo : handle two tables situation
H
hjxilinx 已提交
2604
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2605 2606 2607 2608 2609

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

2610 2611 2612 2613
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
2614
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2615
  if (pList->nExpr > TSDB_MAX_TAGS) {
2616
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2617 2618
  }

H
hjxilinx 已提交
2619
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2620
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2621
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2622

S
slguan 已提交
2623
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
2624
  
H
hzcheng 已提交
2625 2626
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tVariant* pVar = &pList->a[i].pVar;
H
Haojun Liao 已提交
2627
    SStrToken token = {pVar->nLen, pVar->nType, pVar->pz};
H
hzcheng 已提交
2628

S
slguan 已提交
2629
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2630 2631
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2632
    }
H
hzcheng 已提交
2633

S
slguan 已提交
2634
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2635

H
hjxilinx 已提交
2636
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2637
    pTableMeta = pTableMetaInfo->pTableMeta;
2638 2639
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2640 2641 2642
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2643
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2644
    }
H
hzcheng 已提交
2645

S
slguan 已提交
2646
    bool groupTag = false;
2647
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2648
      groupTag = true;
H
hzcheng 已提交
2649
    }
2650 2651 2652 2653 2654 2655
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2656
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2657
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2658
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
S
slguan 已提交
2659 2660
      }

2661 2662 2663 2664
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2665

H
hjxilinx 已提交
2666
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2667
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2668 2669 2670
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2671 2672
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
2673
      if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
2674
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
2675 2676
      }

2677
      tscColumnListInsert(pQueryInfo->colList, &index);
2678
      
2679
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2680
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2681
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2682 2683

      if (i == 0 && pList->nExpr > 1) {
2684
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2685
      }
H
hzcheng 已提交
2686 2687 2688
    }
  }

2689
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2690 2691 2692
  return TSDB_CODE_SUCCESS;
}

2693 2694
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2695
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2696
  } else {
H
hjxilinx 已提交
2697
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2698 2699 2700
  }
}

2701
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2702 2703 2704
  if (pColumn == NULL) {
    return NULL;
  }
2705

S
slguan 已提交
2706
  int32_t size = pColumn->numOfFilters + 1;
2707 2708

  char* tmp = (char*) realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2709 2710
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2711 2712
  } else {
    return NULL;
2713 2714
  }

S
slguan 已提交
2715
  pColumn->numOfFilters++;
2716

S
slguan 已提交
2717 2718 2719 2720
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2721 2722
}

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

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

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

S
slguan 已提交
2732
  int16_t colType = pSchema->type;
2733
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2734 2735 2736
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2737
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2738
    int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
2739 2740 2741
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2742 2743 2744
  }

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

2751
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2752 2753 2754 2755
    } 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);

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

H
[TD-92]  
Hui Li 已提交
2758
      size_t len = twcslen((wchar_t*)pColumnFilter->pz);
S
slguan 已提交
2759
      pColumnFilter->len = len * TSDB_NCHAR_SIZE;
H
hzcheng 已提交
2760
    } else {
2761
      tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
2762 2763 2764 2765 2766
    }
  }

  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
2767
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
2768 2769
      break;
    case TK_LT:
S
slguan 已提交
2770
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
2771 2772
      break;
    case TK_GT:
2773
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
2774 2775
      break;
    case TK_GE:
2776
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
2777 2778
      break;
    case TK_EQ:
S
slguan 已提交
2779
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
2780 2781
      break;
    case TK_NE:
S
slguan 已提交
2782
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
2783 2784
      break;
    case TK_LIKE:
S
slguan 已提交
2785
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
2786
      break;
S
slguan 已提交
2787
    default:
2788
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
2789
  }
S
slguan 已提交
2790

2791
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2792 2793
}

S
slguan 已提交
2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807
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 已提交
2808

H
hjxilinx 已提交
2809
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
2810 2811

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2812
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2813 2814
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2815 2816

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

H
hjxilinx 已提交
2819 2820 2821 2822 2823 2824 2825
  } 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 已提交
2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844
    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)) {
2845
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2846 2847
  }

S
slguan 已提交
2848 2849 2850 2851 2852 2853 2854 2855 2856 2857
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
2858
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2859 2860 2861 2862 2863 2864 2865 2866 2867
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
2868 2869 2870 2871
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
2872 2873 2874 2875
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923

  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:
2924
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2925 2926 2927 2928 2929 2930 2931
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2932
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
2933 2934
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
2935
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2936 2937
  }

S
slguan 已提交
2938
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2939
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2940 2941
  }

H
hzcheng 已提交
2942 2943
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
2944
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
2945 2946

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

H
Haojun Liao 已提交
2950
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
2951
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2952 2953 2954 2955 2956 2957
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2958
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
2959 2960
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2961 2962

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2963 2964
}

S
slguan 已提交
2965 2966 2967 2968 2969 2970
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2971

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

H
hjxilinx 已提交
2975 2976
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2977

S
slguan 已提交
2978
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
2979 2980
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
2981

H
hjxilinx 已提交
2982
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995
  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];
    }
2996 2997 2998 2999

    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3000 3001 3002
  } else if (sqlOptr == TK_OR) {
    // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
    pColFilter = addColumnFilterInfo(pColumn);
3003 3004 3005
    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3006
  } else {  // error;
3007
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3008 3009
  }

3010
  pColFilter->filterstr =
S
slguan 已提交
3011 3012
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

3013
  if (pColFilter->filterstr) {
S
slguan 已提交
3014
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
3015
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3016
    }
S
slguan 已提交
3017 3018
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
3019
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
3020
    }
H
Hui Li 已提交
3021 3022 3023
    
    if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
      if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
3024
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Hui Li 已提交
3025 3026
      }
    }
S
slguan 已提交
3027 3028 3029
  }

  pColumn->colIndex = *pIndex;
3030
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
3031 3032
}

3033
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3034 3035 3036 3037 3038
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

3039
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
3040 3041 3042 3043 3044 3045 3046 3047 3048
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

3049
UNUSED_FUNC
3050
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3051 3052 3053 3054 3055 3056 3057
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3059
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
3060
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3061
      return ret;
H
hzcheng 已提交
3062
    }
S
slguan 已提交
3063

3064
    relToString(pExpr, str);
S
slguan 已提交
3065

3066
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
3067 3068 3069 3070

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

H
hzcheng 已提交
3071 3072 3073
    return ret;
  }

S
slguan 已提交
3074 3075 3076
  return tSQLExprLeafToString(pExpr, true, str);
}

3077
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
3078 3079 3080 3081
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
3084 3085
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
3086

S
slguan 已提交
3087
  if (!isTablenameToken(&pLeft->colInfo)) {
3088
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3089 3090
  }

S
slguan 已提交
3091
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3092

S
slguan 已提交
3093
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
3094
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
3095
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3096
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
3097
  }
H
hzcheng 已提交
3098

S
slguan 已提交
3099
  if (ret != TSDB_CODE_SUCCESS) {
3100
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3101
  }
H
hzcheng 已提交
3102

S
slguan 已提交
3103 3104 3105
  return ret;
}

3106
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3107 3108 3109 3110 3111
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
3112
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3113 3114 3115 3116
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3117
    return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3118 3119
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3120
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3121
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3122
    }
S
slguan 已提交
3123

3124
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3125
  }
S
slguan 已提交
3126
}
H
hzcheng 已提交
3127

3128
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
H
Haojun Liao 已提交
3129 3130 3131
  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 已提交
3132

S
slguan 已提交
3133 3134 3135
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3136

S
slguan 已提交
3137
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
3138
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3139 3140
  }

3141
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3142 3143 3144 3145
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3146 3147
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3148 3149
  }

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

3153
  pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3154
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3155
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3156 3157

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3158 3159
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3160 3161
  }

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

3165
  pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3166
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3167
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3168

H
Haojun Liao 已提交
3169
  if (pTagSchema1->type != pTagSchema2->type) {
3170
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3171 3172
  }

S
slguan 已提交
3173
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3174 3175 3176 3177
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3182
  *(*exprString)++ = '(';
H
hzcheng 已提交
3183 3184

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3185
    doArithmeticExprToString(pLeft, exprString);
H
hzcheng 已提交
3186
  } else {
S
slguan 已提交
3187
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3188
    if (ret != TSDB_CODE_SUCCESS) {
3189
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3190 3191 3192 3193 3194 3195
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3196
    doArithmeticExprToString(pRight, exprString);
H
hzcheng 已提交
3197
  } else {
S
slguan 已提交
3198
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3199
    if (ret != TSDB_CODE_SUCCESS) {
3200
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3201 3202 3203
    }
  }

H
hjxilinx 已提交
3204
  *(*exprString)++ = ')';
H
hzcheng 已提交
3205 3206 3207 3208

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

  return true;
}

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

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

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

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

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

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

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

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

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

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

S
slguan 已提交
3406 3407
  return true;
}
H
hzcheng 已提交
3408

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

S
slguan 已提交
3418
  return false;
H
hzcheng 已提交
3419 3420
}

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

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

S
slguan 已提交
3432 3433
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3434

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

S
slguan 已提交
3449 3450 3451
  int32_t ret = TSDB_CODE_SUCCESS;

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

S
slguan 已提交
3456 3457
  assert(isExprDirectParentOfLeaftNode(*pExpr));

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

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

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

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

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

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

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

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

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

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

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

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

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

S
slguan 已提交
3555
  return ret;
H
hzcheng 已提交
3556 3557
}

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

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

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

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

S
slguan 已提交
3573 3574
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3575

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

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

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

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

S
slguan 已提交
3601
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3602

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

H
hjxilinx 已提交
3966
  int32_t ret = TSDB_CODE_SUCCESS;
S
slguan 已提交
3967

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

  const int32_t START_INTERPO_COL_IDX = 1;
4157 4158 4159 4160

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

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

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

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

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

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

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

    int32_t j = 1;

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

H
Hui Li 已提交
4746

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  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 已提交
4855
    SStrToken* pValToken = &pOptions->a[1];
S
slguan 已提交
4856 4857 4858 4859

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}
5022

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      int32_t relIndex = index.columnIndex;

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

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

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

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

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

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

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

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

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

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

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

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

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

  return false;
}

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

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

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

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

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

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

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

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

H
hjxilinx 已提交
5340 5341 5342 5343 5344 5345
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5346

H
hjxilinx 已提交
5347
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5348 5349
    // 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.
5350
    if (numOfAggregation > 0) {
5351
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5352 5353 5354 5355 5356 5357
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5358 5359
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5360 5361 5362 5363 5364
    } 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 已提交
5365 5366
      for (int32_t i = 0; i < numOfExprs; ++i) {
        
5367
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5368 5369 5370 5371 5372
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5373
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5374 5375 5376
        }
      }

5377 5378
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5379 5380
    }
  } else {
5381
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5382
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5383
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5384
      }
H
hjxilinx 已提交
5385

H
hjxilinx 已提交
5386 5387
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5388 5389
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5390
      }
S
slguan 已提交
5391 5392 5393 5394 5395 5396
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

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

H
Haojun Liao 已提交
5402
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5403
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5404 5405 5406 5407
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5408
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5409
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5410
    int16_t colIndex = pColIndex->colIndex;
5411
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5412
      type  = s.type;
H
Haojun Liao 已提交
5413
      bytes = s.bytes;
H
Haojun Liao 已提交
5414
      name  = s.name;
S
slguan 已提交
5415
    } else {
5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426
      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 已提交
5427
    }
H
hjxilinx 已提交
5428 5429 5430
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5431
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5432
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5433
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5434
      
B
Bomin Zhang 已提交
5435 5436
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5437
      
S
slguan 已提交
5438 5439 5440
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5441
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
S
TD-1057  
Shengliang Guan 已提交
5442
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5443 5444
    } else {
      // if this query is "group by" normal column, interval is not allowed
5445
      if (pQueryInfo->intervalTime > 0) {
5446
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5447 5448 5449
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5450
      for (int32_t j = 0; j < size; ++j) {
5451
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5452 5453 5454 5455 5456 5457 5458 5459 5460 5461
        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) {
5462
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5463 5464 5465 5466 5467 5468 5469
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5470
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5471
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5472
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5473
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5474
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5475 5476

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5477
  if (tscQueryTags(pQueryInfo)) {
5478
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5479
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5480 5481 5482 5483 5484
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5485
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5486
    // check if all the tags prj columns belongs to the group by columns
5487 5488
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5489
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5490 5491 5492
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5493 5494
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5495
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5496 5497 5498 5499 5500 5501
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5502
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5503
        bool qualified = false;
5504
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5505
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5506 5507 5508 5509 5510 5511 5512
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5513
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5514 5515 5516 5517
        }
      }

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

5522
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5523
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5524 5525 5526
      }
    }

5527
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5528
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5529 5530 5531 5532 5533 5534
    }

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

H
hjxilinx 已提交
5539
    // projection query on super table does not compatible with "group by" syntax
5540
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5541
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5542
    }
H
hjxilinx 已提交
5543

H
hjxilinx 已提交
5544
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5545
  } else {
5546
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5547 5548
  }
}
5549
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5550 5551 5552
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5553

H
hjxilinx 已提交
5554 5555
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5556
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5557
  }
H
hjxilinx 已提交
5558

H
hjxilinx 已提交
5559 5560
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5561
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hjxilinx 已提交
5562
  }
H
hjxilinx 已提交
5563

H
hjxilinx 已提交
5564
  // TODO redefine the function
H
hjxilinx 已提交
5565 5566 5567 5568 5569 5570
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5571
  int32_t index = -1;
H
hjxilinx 已提交
5572
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5573
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5574
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5575 5576 5577 5578
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5579 5580 5581

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5582
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5583
    case 1:
H
Haojun Liao 已提交
5584 5585 5586
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5587
    case 3:
H
Haojun Liao 已提交
5588
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5589
    case 4:
H
Haojun Liao 已提交
5590
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5591
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5592
  }
5593 5594 5595 5596 5597 5598
  
  SColumnIndex ind = {0};
  SSqlExpr* pExpr1 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT,
                                      tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize, false);
  
  const char* name = (pExprList->a[0].aliasName != NULL)? pExprList->a[0].aliasName:functionsInfo[index].name;
B
Bomin Zhang 已提交
5599
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5600 5601
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5602
}
H
hjxilinx 已提交
5603 5604

// can only perform the parameters based on the macro definitation
5605
int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate) {
H
hjxilinx 已提交
5606
  char msg[512] = {0};
H
hjxilinx 已提交
5607

H
hjxilinx 已提交
5608 5609
  if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) {
    snprintf(msg, tListLen(msg), "invalid db option walLevel: %d, only 0-2 allowed", pCreate->walLevel);
5610
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5611
  }
H
hjxilinx 已提交
5612

H
hjxilinx 已提交
5613
  if (pCreate->replications != -1 &&
5614
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5615
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5616
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5617
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5618
  }
H
hjxilinx 已提交
5619

5620 5621 5622 5623 5624 5625 5626
  if (pCreate->quorum != -1 &&
      (pCreate->quorum < TSDB_MIN_DB_REPLICA_OPTION || pCreate->quorum > TSDB_MAX_DB_REPLICA_OPTION)) {
    snprintf(msg, tListLen(msg), "invalid db option quorum: %d valid range: [%d, %d]", pCreate->quorum,
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  }

H
hjxilinx 已提交
5627
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5628
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5629
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5630
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5631
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5632
  }
H
hjxilinx 已提交
5633

H
hjxilinx 已提交
5634 5635 5636 5637
  val = htonl(pCreate->cacheBlockSize);
  if (val != -1 && (val < TSDB_MIN_CACHE_BLOCK_SIZE || val > TSDB_MAX_CACHE_BLOCK_SIZE)) {
    snprintf(msg, tListLen(msg), "invalid db option cacheBlockSize: %d valid range: [%d, %d]", val,
             TSDB_MIN_CACHE_BLOCK_SIZE, TSDB_MAX_CACHE_BLOCK_SIZE);
5638
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5639
  }
H
hjxilinx 已提交
5640

H
hjxilinx 已提交
5641
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5642
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5643
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5644
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5645
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5646
  }
H
hjxilinx 已提交
5647 5648 5649 5650

  if (pCreate->precision != TSDB_TIME_PRECISION_MILLI && pCreate->precision != TSDB_TIME_PRECISION_MICRO) {
    snprintf(msg, tListLen(msg), "invalid db option timePrecision: %d valid value: [%d, %d]", pCreate->precision,
             TSDB_TIME_PRECISION_MILLI, TSDB_TIME_PRECISION_MICRO);
5651
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5652
  }
H
hjxilinx 已提交
5653

H
hjxilinx 已提交
5654
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5655
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5656
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5657
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5658
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5659
  }
H
hjxilinx 已提交
5660

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5661 5662 5663 5664 5665 5666 5667
  val = htonl(pCreate->fsyncPeriod);
  if (val != -1 && (val < TSDB_MIN_FSYNC_PERIOD || val > TSDB_MAX_FSYNC_PERIOD)) {
    snprintf(msg, tListLen(msg), "invalid db option fsyncPeriod: %d valid range: [%d, %d]", val,
             TSDB_MIN_FSYNC_PERIOD, TSDB_MAX_FSYNC_PERIOD);
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  }

H
hjxilinx 已提交
5668
  if (pCreate->compression != -1 &&
S
slguan 已提交
5669
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5670
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5671
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5672
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5673
  }
H
hjxilinx 已提交
5674

H
hjxilinx 已提交
5675 5676
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5677 5678

// for debug purpose
H
hjxilinx 已提交
5679 5680
void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) {
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
5681

S
TD-1057  
Shengliang Guan 已提交
5682
  int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
5683
  if (size == 0) {
H
hjxilinx 已提交
5684 5685
    return;
  }
H
hjxilinx 已提交
5686

H
hjxilinx 已提交
5687
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5688 5689

  char    str[1024] = {0};
H
hjxilinx 已提交
5690
  int32_t offset = 0;
H
hjxilinx 已提交
5691

H
hjxilinx 已提交
5692 5693
  offset += sprintf(str, "num:%d [", size);
  for (int32_t i = 0; i < size; ++i) {
5694
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5695

L
lihui 已提交
5696
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5697 5698 5699
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5700 5701 5702
    if (tmpLen + offset > totalBufSize) break;

    offset += sprintf(str + offset, "%s", tmpBuf);
H
hjxilinx 已提交
5703

H
hjxilinx 已提交
5704
    if (i < size - 1) {
H
hjxilinx 已提交
5705 5706 5707
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5708

H
hjxilinx 已提交
5709
  str[offset] = ']';
5710
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5711
}
5712

5713
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5714 5715 5716
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5717 5718
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5719
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5720 5721 5722 5723 5724 5725 5726 5727 5728

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;

  tFieldList* pFieldList = pCreateTable->colInfo.pColumns;
  tFieldList* pTagList = pCreateTable->colInfo.pTagColumns;

  assert(pFieldList != NULL);

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
5729
  SStrToken* pzTableName = &(pCreateTable->name);
5730 5731

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5732
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5733 5734
  }

H
Haojun Liao 已提交
5735
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5736
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5737 5738 5739 5740
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
5741
    return TSDB_CODE_TSC_INVALID_SQL;
5742 5743 5744 5745
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
H
hjxilinx 已提交
5746
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[col]);
5747 5748 5749 5750
  }

  pCmd->numOfCols = (int16_t)pFieldList->nField;

H
hjxilinx 已提交
5751
  if (pTagList != NULL) {  // create super table[optional]
5752
    for (int32_t i = 0; i < pTagList->nField; ++i) {
H
hjxilinx 已提交
5753
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pTagList->p[i]);
5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770
    }

    pCmd->count = pTagList->nField;
  }

  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
  const char* msg1 = "invalid table name";
  const char* msg3 = "tag value too long";
  const char* msg4 = "illegal value or data overflow";
  const char* msg5 = "tags number not matched";

  SSqlCmd* pCmd = &pSql->cmd;

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
5771 5772 5773
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
5774 5775 5776
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
5777 5778 5779 5780

  const int32_t TABLE_INDEX = 0;
  const int32_t STABLE_INDEX = 1;

H
hjxilinx 已提交
5781
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5782 5783

  // super table name, create table by using dst
H
Haojun Liao 已提交
5784
  SStrToken* pToken = &(pCreateTable->usingInfo.stableName);
5785 5786

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5787
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5788 5789
  }

H
Haojun Liao 已提交
5790
  if (tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5791
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5792 5793 5794
  }

  // get meter meta from mnode
B
Bomin Zhang 已提交
5795
  tstrncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, sizeof(pCreateTable->usingInfo.tagdata.name));
5796 5797
  tVariantList* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;

H
hjxilinx 已提交
5798
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5799 5800 5801 5802
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5803
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5804
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5805 5806 5807
  }

  // too long tag values will return invalid sql, not be truncated automatically
H
hjxilinx 已提交
5808
  SSchema* pTagSchema = tscGetTableTagSchema(pStableMeterMetaInfo->pTableMeta);
5809

5810
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
B
Bomin Zhang 已提交
5811 5812 5813 5814 5815
  SKVRowBuilder kvRowBuilder = {0};
  if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
hjxilinx 已提交
5816
  int32_t ret = TSDB_CODE_SUCCESS;
5817
  for (int32_t i = 0; i < pList->nExpr; ++i) {
H
Haojun Liao 已提交
5818 5819 5820
    SSchema* pSchema = &pTagSchema[i];
    
    char tagVal[TSDB_MAX_TAGS_LEN];
B
Bomin Zhang 已提交
5821
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
H
Haojun Liao 已提交
5822
      if (pList->a[i].pVar.nLen > pSchema->bytes) {
B
Bomin Zhang 已提交
5823
        tdDestroyKVRowBuilder(&kvRowBuilder);
H
hjxilinx 已提交
5824 5825 5826
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
H
Haojun Liao 已提交
5827

B
Bomin Zhang 已提交
5828
    ret = tVariantDump(&(pList->a[i].pVar), tagVal, pSchema->type, true);
H
Haojun Liao 已提交
5829 5830 5831 5832 5833 5834 5835 5836 5837 5838

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

5839
    if (ret != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
5840
      tdDestroyKVRowBuilder(&kvRowBuilder);
5841
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5842 5843
    }

H
Haojun Liao 已提交
5844 5845


B
Bomin Zhang 已提交
5846
    tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
5847 5848
  }

B
Bomin Zhang 已提交
5849
  SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
B
Bomin Zhang 已提交
5850 5851 5852 5853 5854
  tdDestroyKVRowBuilder(&kvRowBuilder);
  if (row == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  tdSortKVRowByColIdx(row);
B
Bomin Zhang 已提交
5855
  pTag->dataLen = kvRowLen(row);
B
Bomin Zhang 已提交
5856
  kvRowCpy(pTag->data, row);
B
Bomin Zhang 已提交
5857 5858
  free(row);

5859 5860
  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5861
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5862 5863
  }

H
hjxilinx 已提交
5864
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
5865
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878
  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 已提交
5879 5880
  const char* msg6 = "from missing in subclause";
  
5881
  SSqlCmd*    pCmd = &pSql->cmd;
5882
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5883 5884
  assert(pQueryInfo->numOfTables == 1);

5885
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5886
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5887 5888

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
5889
  SStrToken* pzTableName = &(pCreateTable->name);
5890 5891 5892
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5893
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5894
  }
H
Haojun Liao 已提交
5895
  
5896
  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
H
Haojun Liao 已提交
5897 5898 5899 5900 5901
  if (pSrcMeterName == NULL || pSrcMeterName->nExpr == 0) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
  tVariant* pVar = &pSrcMeterName->a[0].pVar;
H
Haojun Liao 已提交
5902
  SStrToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
5903
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
5904
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5905 5906
  }

H
Haojun Liao 已提交
5907
  if (tscSetTableFullName(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5908
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5909 5910
  }

H
hjxilinx 已提交
5911
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5912 5913 5914 5915
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
5916
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
H
Haojun Liao 已提交
5917
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false) != TSDB_CODE_SUCCESS) {
5918
    return TSDB_CODE_TSC_INVALID_SQL;
5919 5920 5921
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5922
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5923
      return TSDB_CODE_TSC_INVALID_SQL;
5924 5925 5926 5927
    }
  }

  // set interval value
5928
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5929
    return TSDB_CODE_TSC_INVALID_SQL;
5930
  } else {
5931
    if ((pQueryInfo->intervalTime > 0) &&
5932
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
5933
      return TSDB_CODE_TSC_INVALID_SQL;
5934 5935 5936 5937
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
5938
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5939
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5940 5941 5942
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5943
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5944 5945
  }

5946
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5947
    return TSDB_CODE_TSC_INVALID_SQL;
5948 5949
  }

H
hjxilinx 已提交
5950
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5951

5952
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
5953
    return TSDB_CODE_TSC_INVALID_SQL;
5954 5955 5956 5957 5958 5959 5960
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
5961
    if (pQueryInfo->intervalTime == 0) {
5962
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
5963 5964 5965 5966 5967 5968
    }

    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))) {
5969
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5970 5971 5972 5973 5974
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
5975
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5976 5977 5978 5979 5980 5981
  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 已提交
5982 5983 5984 5985 5986 5987 5988 5989 5990 5991
  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";
5992 5993

  int32_t code = TSDB_CODE_SUCCESS;
5994

5995
  SSqlCmd* pCmd = &pSql->cmd;
5996

5997
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
5998
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5999
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
6000
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
6001
  }
H
hjxilinx 已提交
6002

H
Haojun Liao 已提交
6003 6004
  assert(pCmd->clauseIndex == index);

6005 6006
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
6007
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019
  }

  /*
   * 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);
6020
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
6021 6022
  }

H
Haojun Liao 已提交
6023
  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM * 2) {
6024
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
6025 6026
  }

6027
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
6028

H
Haojun Liao 已提交
6029
  if (pQuerySql->from->nExpr > 4) {
H
Haojun Liao 已提交
6030 6031 6032
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

6033
  // set all query tables, which are maybe more than one.
H
Haojun Liao 已提交
6034
  for (int32_t i = 0; i < pQuerySql->from->nExpr; ) {
6035 6036 6037
    tVariant* pTableItem = &pQuerySql->from->a[i].pVar;

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
6038
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6039 6040 6041 6042
    }

    pTableItem->nLen = strdequote(pTableItem->pz);

H
Haojun Liao 已提交
6043
    SStrToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
6044
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
6045
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6046 6047
    }

H
Haojun Liao 已提交
6048
    if (pQueryInfo->numOfTables <= i/2) {  // more than one table
H
hjxilinx 已提交
6049
      tscAddEmptyMetaInfo(pQueryInfo);
6050 6051
    }

H
Haojun Liao 已提交
6052
    STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i/2);
6053

H
Haojun Liao 已提交
6054
    SStrToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
6055
    if (tscSetTableFullName(pTableMetaInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
6056
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6057 6058
    }

H
Haojun Liao 已提交
6059
    tVariant* pTableItem1 = &pQuerySql->from->a[i + 1].pVar;
H
Haojun Liao 已提交
6060
    SStrToken aliasName = {.z = pTableItem1->pz, .n = pTableItem1->nLen, .type = TK_STRING};
H
Haojun Liao 已提交
6061 6062 6063 6064
    if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

6065 6066 6067 6068 6069 6070
    // 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 已提交
6071 6072

    code = tscGetTableMeta(pSql, pTableMetaInfo1);
6073 6074 6075
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
H
Haojun Liao 已提交
6076 6077

    i += 2;
6078 6079
  }

H
Haojun Liao 已提交
6080
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr / 2);
H
hjxilinx 已提交
6081
  bool isSTable = false;
H
hjxilinx 已提交
6082
  
weixin_48148422's avatar
weixin_48148422 已提交
6083
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
6084 6085 6086 6087 6088 6089 6090
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
6091 6092
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
6093
  }
6094

6095
  // parse the group by clause in the first place
6096
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
6097
    return TSDB_CODE_TSC_INVALID_SQL;
6098 6099
  }

6100 6101
  // set where info
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
Y
TD-1230  
yihaoDeng 已提交
6102

6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116
  if (pQuerySql->pWhere != NULL) {
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_TSC_INVALID_SQL;
    }

    pQuerySql->pWhere = NULL;
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
      pQueryInfo->window.skey = pQueryInfo->window.skey / 1000;
      pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000;
    }
  } else {  // set the time rang
    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 ");
    }
Y
TD-1230  
yihaoDeng 已提交
6117
  }
6118 6119 6120

  int32_t joinQuery = (pQuerySql->from != NULL && pQuerySql->from->nExpr > 2);

H
Haojun Liao 已提交
6121
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery) != TSDB_CODE_SUCCESS) {
6122
    return TSDB_CODE_TSC_INVALID_SQL;
6123 6124 6125
  }

  // set interval value
6126
  if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6127
    return TSDB_CODE_TSC_INVALID_SQL;
6128
  } else {
6129
    if ((pQueryInfo->intervalTime > 0) &&
6130
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6131
      return TSDB_CODE_TSC_INVALID_SQL;
6132 6133 6134 6135
    }
  }

  // set order by info
6136
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
6137
    return TSDB_CODE_TSC_INVALID_SQL;
6138 6139 6140
  }

  // user does not specified the query time window, twa is not allowed in such case.
H
Haojun Liao 已提交
6141
  if ((pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX ||
H
hjxilinx 已提交
6142
       (pQueryInfo->window.ekey == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
6143
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
6144 6145 6146
  }

  // no result due to invalid query time range
H
hjxilinx 已提交
6147
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6148
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6149 6150 6151
    return TSDB_CODE_SUCCESS;
  }

6152
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6153
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6154 6155 6156
  }

  // in case of join query, time range is required.
6157
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
S
TD-1057  
Shengliang Guan 已提交
6158
    int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6159

H
hjxilinx 已提交
6160
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6161
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6162 6163 6164
    }
  }

6165
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6166 6167 6168
    return code;
  }

6169
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6170 6171 6172
    return code;
  }

6173
  setColumnOffsetValueInResultset(pQueryInfo);
6174

6175 6176 6177 6178 6179
  /*
   * 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) {
6180
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6181 6182
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6183

6184
    if (pQueryInfo->intervalTime > 0 && pQueryInfo->intervalTimeUnit != 'n' && pQueryInfo->intervalTimeUnit != 'y') {
S
TD-1057  
Shengliang Guan 已提交
6185
      int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6186
      // number of result is not greater than 10,000,000
6187
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_INTERVAL_TIME_WINDOW) {
6188
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6189 6190
      }
    }
H
hjxilinx 已提交
6191

6192
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6193 6194 6195 6196
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6197 6198 6199

  return TSDB_CODE_SUCCESS;  // Does not build query message here
}
H
hjxilinx 已提交
6200

6201
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols) {
H
hjxilinx 已提交
6202 6203
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6204
  
6205
  if (pSqlExpr->pLeft != NULL) {
6206
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6207 6208 6209 6210 6211
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6212
  if (pSqlExpr->pRight != NULL) {
6213
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
6214 6215 6216 6217 6218
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6219
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6220
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6221
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6222
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6223 6224 6225
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6226
      return TSDB_CODE_SUCCESS;
6227
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6228
      // arithmetic expression on the results of aggregation functions
6229
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6230
      (*pExpr)->nodeType = TSQL_NODE_COL;
6231 6232 6233
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6234
      // set the input column data byte and type.
H
hjxilinx 已提交
6235 6236 6237 6238 6239 6240
      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 已提交
6241
          (*pExpr)->pSchema->type = (uint8_t)p1->resType;
H
hjxilinx 已提交
6242
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
hjxilinx 已提交
6243 6244 6245
          break;
        }
      }
6246
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6247
      SColumnIndex index = {0};
6248
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6249 6250 6251
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
H
Haojun Liao 已提交
6252 6253 6254 6255

      STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
      int32_t numOfColumns = tscGetNumOfColumns(pTableMeta);

6256 6257 6258
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
H
Haojun Liao 已提交
6259

6260 6261
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6262 6263 6264
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6265
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6266 6267
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
H
Haojun Liao 已提交
6268 6269
        colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;

6270 6271
        taosArrayPush(pCols, &colIndex);
      }
6272
      
H
hjxilinx 已提交
6273
      return TSDB_CODE_SUCCESS;
6274
    } else {
6275
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6276 6277 6278
    }
    
  } else {
H
hjxilinx 已提交
6279
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6280 6281
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6282 6283 6284
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6285
    
H
Haojun Liao 已提交
6286
    SStrToken t = {.type = pSqlExpr->nSQLOptr};
H
[td-32]  
hjxilinx 已提交
6287
    (*pExpr)->_node.optr = getBinaryExprOptr(&t);
6288
    
H
[td-32]  
hjxilinx 已提交
6289
    assert((*pExpr)->_node.optr != 0);
6290 6291

    // check for dividing by 0
H
[td-32]  
hjxilinx 已提交
6292
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6293 6294
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6295
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6296
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6297
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6298 6299 6300
        }
      }
    }
H
Hui Li 已提交
6301

6302
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6303
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
6304
      if (pRight != NULL && pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6305 6306 6307
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6308 6309
      }
    }
H
hjxilinx 已提交
6310 6311 6312
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6313
}
6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325

bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) {
  size_t numOfCols = taosArrayGetSize(pQueryInfo->colList);
  for (int32_t i = 0; i < numOfCols; ++i) {
    SColumn* pCol = taosArrayGetP(pQueryInfo->colList, i);
    if (pCol->numOfFilters > 0) {
      return true;
    }
  }

  return false;
}