tscSQLParser.c 229.9 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
19
#define _GNU_SOURCE
H
hzcheng 已提交
20

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

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

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

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

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

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

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

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

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

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

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);
H
Haojun Liao 已提交
73 74 75 76

static int32_t convertFunctionId(int32_t optr, int16_t* functionId);
static uint8_t convertOptr(SStrToken *pToken);

H
Haojun Liao 已提交
77
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery);
H
hzcheng 已提交
78

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

H
Haojun Liao 已提交
84
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
H
hzcheng 已提交
85

86
static int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
87
static int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
88
static int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
H
hzcheng 已提交
89

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

92
static int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql);
93 94
static int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL);
static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema);
H
hzcheng 已提交
95

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

H
hjxilinx 已提交
107
static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField);
108
static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo);
109
static bool hasNormalColumnFilter(SQueryInfo* pQueryInfo);
H
hjxilinx 已提交
110

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

H
Haojun Liao 已提交
117
static int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
118
static int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
119
static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
S
TD-1732  
Shengliang Guan 已提交
120
static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate);
H
hjxilinx 已提交
121

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

124
static int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo);
125 126 127
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);
H
Haojun Liao 已提交
128
static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid);
H
hjxilinx 已提交
129

H
Haojun Liao 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
static uint8_t convertOptr(SStrToken *pToken) {
  switch (pToken->type) {
    case TK_LT:
      return TSDB_RELATION_LESS;
    case TK_LE:
      return TSDB_RELATION_LESS_EQUAL;
    case TK_GT:
      return TSDB_RELATION_GREATER;
    case TK_GE:
      return TSDB_RELATION_GREATER_EQUAL;
    case TK_NE:
      return TSDB_RELATION_NOT_EQUAL;
    case TK_AND:
      return TSDB_RELATION_AND;
    case TK_OR:
      return TSDB_RELATION_OR;
    case TK_EQ:
      return TSDB_RELATION_EQUAL;
    case TK_PLUS:
      return TSDB_BINARY_OP_ADD;
    case TK_MINUS:
      return TSDB_BINARY_OP_SUBTRACT;
    case TK_STAR:
      return TSDB_BINARY_OP_MULTIPLY;
    case TK_SLASH:
    case TK_DIVIDE:
      return TSDB_BINARY_OP_DIVIDE;
    case TK_REM:
      return TSDB_BINARY_OP_REMAINDER;
    case TK_LIKE:
      return TSDB_RELATION_LIKE;
    case TK_ISNULL:
      return TSDB_RELATION_ISNULL;
    case TK_NOTNULL:
      return TSDB_RELATION_NOTNULL;
    default: { return 0; }
  }
}

H
hjxilinx 已提交
169 170 171 172
/*
 * Used during parsing query sql. Since the query sql usually small in length, error position
 * is not needed in the final error message.
 */
173 174
static int32_t invalidSqlErrMsg(char* dstBuffer, const char* errMsg) {
  return tscInvalidSQLErrMsg(dstBuffer, errMsg, NULL);
H
hjxilinx 已提交
175 176
}

177
static int setColumnFilterInfoForTimestamp(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tVariant* pVar) {
S
slguan 已提交
178 179 180 181 182
  int64_t     time = 0;
  const char* msg = "invalid timestamp";

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

H
hjxilinx 已提交
185
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
186
  
S
slguan 已提交
187
  if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
188
    if (taosParseTime(pVar->pz, &time, pVar->nLen, tinfo.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
189
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
190 191
    }
  } else {
192
    if (tVariantDump(pVar, (char*)&time, TSDB_DATA_TYPE_BIGINT, true)) {
193
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
194 195 196 197 198 199 200 201 202
    }
  }

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

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
203
static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) {
204 205 206 207 208
  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) {
209
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
210 211 212
  }

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

  if (pPwd->n <= 0) {
216
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
217 218
  }

B
Bomin Zhang 已提交
219
  if (pPwd->n >= TSDB_PASSWORD_LEN) {
220
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
221 222 223 224 225
  }

  return TSDB_CODE_SUCCESS;
}

H
hzcheng 已提交
226 227
int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
  if (pInfo == NULL || pSql == NULL || pSql->signature != pSql) {
228
    return TSDB_CODE_TSC_APP_ERROR;
H
hzcheng 已提交
229 230
  }

231 232
  SSqlCmd* pCmd = &pSql->cmd;
  SSqlRes* pRes = &pSql->res;
H
hzcheng 已提交
233

234
  int32_t code = TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
235 236
  if (!pInfo->valid || terrno == TSDB_CODE_TSC_SQL_SYNTAX_ERROR) {
    terrno = TSDB_CODE_SUCCESS;  // clear the error number
Y
TD-934  
yihaoDeng 已提交
237
    return tscSQLSyntaxErrMsg(tscGetErrorMsgPayload(pCmd), NULL, pInfo->pzErrMsg);
H
hzcheng 已提交
238 239
  }

240 241 242 243 244
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex);
  if (pQueryInfo == NULL) {
    pRes->code = terrno;
    return pRes->code;
  }
H
hjxilinx 已提交
245

246 247 248 249
  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 已提交
250
  }
251

252 253 254 255 256 257 258 259
  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: {
260
      const char* msg2 = "invalid name";
261
      const char* msg3 = "param name too long";
H
hzcheng 已提交
262

H
Haojun Liao 已提交
263
      SStrToken* pzName = &pInfo->pDCLInfo->a[0];
264
      if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (tscValidateName(pzName) != TSDB_CODE_SUCCESS)) {
265
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
266 267
      }

268 269
      if (pInfo->type == TSDB_SQL_DROP_DB) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
270

H
hjxilinx 已提交
271
        code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pzName, NULL, NULL);
H
hzcheng 已提交
272
        if (code != TSDB_CODE_SUCCESS) {
273
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
274 275
        }

276 277
      } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
278

Y
TD-1039  
yihaoDeng 已提交
279 280 281
        code = tscSetTableFullName(pTableMetaInfo, pzName, pSql);
        if(code != TSDB_CODE_SUCCESS) {
          return code; 
H
hzcheng 已提交
282
        }
283
      } else if (pInfo->type == TSDB_SQL_DROP_DNODE) {
S
slguan 已提交
284
        pzName->n = strdequote(pzName->z);
H
hjxilinx 已提交
285
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
286
      } else {  // drop user
B
Bomin Zhang 已提交
287
        if (pzName->n >= TSDB_USER_LEN) {
288
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
289 290
        }

H
hjxilinx 已提交
291
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
292 293
      }

294 295
      break;
    }
H
hzcheng 已提交
296

297 298
    case TSDB_SQL_USE_DB: {
      const char* msg = "invalid db name";
H
Haojun Liao 已提交
299
      SStrToken*  pToken = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
300 301

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
302
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
303 304
      }

H
hjxilinx 已提交
305
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pToken, NULL, NULL);
H
hzcheng 已提交
306
      if (ret != TSDB_CODE_SUCCESS) {
307
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
308 309 310 311 312
      }

      break;
    }

313 314
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
315 316
    }

317 318
    case TSDB_SQL_SHOW: {
      if (setShowInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
319
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
320 321
      }

322 323 324 325 326 327 328 329
      break;
    }

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

330
      SCreateDBInfo* pCreateDB = &(pInfo->pDCLInfo->dbOpt);
H
hzcheng 已提交
331
      if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) {
332
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
333 334
      }

H
hjxilinx 已提交
335
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname), NULL, NULL);
H
hzcheng 已提交
336
      if (ret != TSDB_CODE_SUCCESS) {
337
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
338 339
      }

H
hjxilinx 已提交
340
      if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
341
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
342 343 344 345 346
      }

      break;
    }

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

350
      if (pInfo->pDCLInfo->nTokens > 1) {
351
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
352 353
      }

H
Haojun Liao 已提交
354
      SStrToken* pIpAddr = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
355
      pIpAddr->n = strdequote(pIpAddr->z);
S
slguan 已提交
356 357 358
      break;
    }

359 360 361 362 363
    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 已提交
364

H
Haojun Liao 已提交
365 366
      SStrToken* pName = &pInfo->pDCLInfo->user.user;
      SStrToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
367

368
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
369
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
370 371
      }

B
Bomin Zhang 已提交
372
      if (pName->n >= TSDB_USER_LEN) {
373
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
374 375
      }

376
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
377
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
378 379 380
      }

      SCreateAcctSQL* pAcctOpt = &pInfo->pDCLInfo->acctOpt;
381
      if (pAcctOpt->stat.n > 0) {
H
hzcheng 已提交
382 383 384 385 386
        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 {
387
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
388 389
        }
      }
390

H
hzcheng 已提交
391 392 393
      break;
    }

394
    case TSDB_SQL_DESCRIBE_TABLE: {
H
Haojun Liao 已提交
395
      SStrToken*  pToken = &pInfo->pDCLInfo->a[0];
H
hjxilinx 已提交
396
      const char* msg1 = "invalid table name";
H
Haojun Liao 已提交
397
      const char* msg2 = "table name too long";
H
hzcheng 已提交
398

S
slguan 已提交
399
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
400
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
401
      }
S
slguan 已提交
402

H
Haojun Liao 已提交
403
      if (!tscValidateTableNameLength(pToken->n)) {
404
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
405 406
      }

H
Haojun Liao 已提交
407
      // additional msg has been attached already
H
Haojun Liao 已提交
408 409 410
      code = tscSetTableFullName(pTableMetaInfo, pToken, pSql);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
411 412
      }

H
hjxilinx 已提交
413
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
414
    }
415 416 417 418
    case TSDB_SQL_SHOW_CREATE_TABLE: {
      SStrToken*  pToken = &pInfo->pDCLInfo->a[0];
      const char* msg1 = "invalid table name";
      const char* msg2 = "table name is too long";
H
hzcheng 已提交
419

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

424 425 426 427
      if (!tscValidateTableNameLength(pToken->n)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
      }

H
Haojun Liao 已提交
428 429 430
      code = tscSetTableFullName(pTableMetaInfo, pToken, pSql);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
431
      }
H
Haojun Liao 已提交
432

433 434 435 436 437 438 439 440 441 442 443 444
      return tscGetTableMeta(pSql, pTableMetaInfo);
    }
    case TSDB_SQL_SHOW_CREATE_DATABASE: {
      const char* msg1 = "invalid database name";
      SStrToken*  pToken = &pInfo->pDCLInfo->a[0];

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
      }
      if (pToken->n > TSDB_DB_NAME_LEN) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
      }
H
Haojun Liao 已提交
445 446 447

      return tscSetTableFullName(pTableMetaInfo, pToken, pSql);
    }
448
    case TSDB_SQL_CFG_DNODE: {
S
Shengliang Guan 已提交
449
      const char* msg2 = "invalid configure options or values, such as resetlog / debugFlag 135 / balance 'vnode:2-dnode:2' / monitor 1 ";
H
Hui Li 已提交
450
      const char* msg3 = "invalid dnode ep";
H
hzcheng 已提交
451

452 453
      /* validate the ip address */
      tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
454

455 456
      /* validate the parameter names and options */
      if (validateDNodeConfig(pDCL) != TSDB_CODE_SUCCESS) {
457
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
458 459
      }

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

S
TD-1732  
Shengliang Guan 已提交
462
      SCfgDnodeMsg* pCfg = (SCfgDnodeMsg*)pMsg;
guanshengliang's avatar
guanshengliang 已提交
463 464
      pDCL->a[0].n = strdequote(pDCL->a[0].z);
      
J
jtao1735 已提交
465
      strncpy(pCfg->ep, pDCL->a[0].z, pDCL->a[0].n);
H
hzcheng 已提交
466

H
Hui Li 已提交
467 468 469 470
      if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }

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

473 474 475 476
      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 已提交
477

478 479
      break;
    }
H
hzcheng 已提交
480

481 482 483 484 485 486
    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 已提交
487

488
      pCmd->command = pInfo->type;
H
hzcheng 已提交
489

490
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
H
Haojun Liao 已提交
491 492
      SStrToken* pName = &pUser->user;
      SStrToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
493

B
Bomin Zhang 已提交
494
      if (pName->n >= TSDB_USER_LEN) {
495
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
496
      }
H
hzcheng 已提交
497

498
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
499
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
500
      }
H
hzcheng 已提交
501

502 503
      if (pCmd->command == TSDB_SQL_CREATE_USER) {
        if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
504
          return TSDB_CODE_TSC_INVALID_SQL;
505 506 507 508
        }
      } else {
        if (pUser->type == TSDB_ALTER_USER_PASSWD) {
          if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
509
            return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
510
          }
511
        } else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
L
lihui 已提交
512 513
          assert(pPwd->type == TSDB_DATA_TYPE_NULL);

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

L
lihui 已提交
516
          if (strncasecmp(pPrivilege->z, "super", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
517
            pCmd->count = 1;
L
lihui 已提交
518
          } else if (strncasecmp(pPrivilege->z, "read", 4) == 0 && pPrivilege->n == 4) {
H
hzcheng 已提交
519
            pCmd->count = 2;
L
lihui 已提交
520
          } else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
521 522
            pCmd->count = 3;
          } else {
523
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
524 525
          }
        } else {
526
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
527 528
        }
      }
529

H
hzcheng 已提交
530 531
      break;
    }
532 533

    case TSDB_SQL_CFG_LOCAL: {
S
slguan 已提交
534 535 536 537 538
      tDCLSQL*    pDCL = pInfo->pDCLInfo;
      const char* msg = "invalid configure options or values";

      // validate the parameter names and options
      if (validateLocalConfig(pDCL) != TSDB_CODE_SUCCESS) {
539
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
540 541 542 543 544 545 546
      }

      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 已提交
547 548 549 550

      break;
    }

551 552
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
553

554
      if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
555
        if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
556
          return code;
H
hzcheng 已提交
557 558
        }

559
      } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) {
560
        assert(pCmd->numOfCols == 0);
561 562
        if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
563 564
        }

565 566 567
      } else if (pCreateTable->type == TSQL_CREATE_STREAM) {
        if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
S
slguan 已提交
568
        }
H
hzcheng 已提交
569 570 571 572 573
      }

      break;
    }

574
    case TSDB_SQL_SELECT: {
H
hjxilinx 已提交
575
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
576

577
      for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) {
578 579 580 581
        SQueryInfo* pqi = tscGetQueryInfoDetailSafely(pCmd, i);
        if (pqi == NULL) {
          pRes->code = terrno;
          return pRes->code;
582
        }
583 584 585
      }

      assert(pCmd->numOfClause == pInfo->subclauseInfo.numOfClause);
H
Haojun Liao 已提交
586
      for (int32_t i = pCmd->clauseIndex; i < pInfo->subclauseInfo.numOfClause; ++i) {
587
        SQuerySQL* pQuerySql = pInfo->subclauseInfo.pClause[i];
H
Haojun Liao 已提交
588
        tscTrace("%p start to parse %dth subclause, total:%d", pSql, i, pInfo->subclauseInfo.numOfClause);
589 590
        if ((code = doCheckForQuery(pSql, pQuerySql, i)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
591
        }
H
hjxilinx 已提交
592

H
hjxilinx 已提交
593
        tscPrintSelectClause(pSql, i);
H
Haojun Liao 已提交
594
        pCmd->clauseIndex += 1;
H
hzcheng 已提交
595
      }
H
hjxilinx 已提交
596

H
Haojun Liao 已提交
597 598
      // restore the clause index
      pCmd->clauseIndex = 0;
H
hjxilinx 已提交
599
      // set the command/global limit parameters from the first subclause to the sqlcmd object
600 601
      SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
      pCmd->command = pQueryInfo1->command;
H
hjxilinx 已提交
602

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

607 608 609
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
610
        }
611
      }
612

613
      pCmd->parseFinished = 1;
614
      return TSDB_CODE_SUCCESS;  // do not build query message here
615
    }
H
hzcheng 已提交
616

617 618 619
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
620 621 622 623 624
      }

      break;
    }

625 626 627
    case TSDB_SQL_KILL_QUERY:
    case TSDB_SQL_KILL_STREAM:
    case TSDB_SQL_KILL_CONNECTION: {
628
      if ((code = setKillInfo(pSql, pInfo, pInfo->type)) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
629 630 631 632 633 634 635
        return code;
      }

      break;
    }

    default:
636
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
637 638
  }

dengyihao's avatar
dengyihao 已提交
639
  pSql->cmd.parseFinished = 1;
640
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
641 642
}

S
slguan 已提交
643 644 645 646
/*
 * if the top/bottom exists, only tags columns, tbname column, and primary timestamp column
 * are available.
 */
647
static bool isTopBottomQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
648 649 650
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = 0; i < size; ++i) {
651
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
652 653 654 655

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

S
slguan 已提交
658
  return false;
H
hzcheng 已提交
659 660
}

661
int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
S
slguan 已提交
662 663
  const char* msg1 = "invalid query expression";
  const char* msg2 = "interval cannot be less than 10 ms";
664
  const char* msg3 = "sliding cannot be used without interval";
665

666 667
  SSqlCmd* pCmd = &pSql->cmd;

H
hjxilinx 已提交
668
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
669
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
670
  
H
hjxilinx 已提交
671
  if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
672 673 674
    if (pQuerySql->sliding.n > 0) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
675 676 677
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
678 679 680 681 682
  // orderby column not set yet, set it to be the primary timestamp column
  if (pQueryInfo->order.orderColId == INT32_MIN) {
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
  }

H
hzcheng 已提交
683
  // interval is not null
684
  SStrToken* t = &pQuerySql->interval;
685
  if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval, &pQueryInfo->interval.intervalUnit) != TSDB_CODE_SUCCESS) {
686
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
687 688
  }

689
  if (pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') {
B
Bomin Zhang 已提交
690 691
    // if the unit of time window value is millisecond, change the value from microsecond
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
692
      pQueryInfo->interval.interval = pQueryInfo->interval.interval / 1000;
B
Bomin Zhang 已提交
693
    }
H
hzcheng 已提交
694

B
Bomin Zhang 已提交
695
    // interval cannot be less than 10 milliseconds
696
    if (pQueryInfo->interval.interval < tsMinIntervalTime) {
B
Bomin Zhang 已提交
697 698
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }
H
hzcheng 已提交
699 700 701
  }

  // for top/bottom + interval query, we do not add additional timestamp column in the front
702
  if (isTopBottomQuery(pQueryInfo)) {
703 704 705 706
    if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_TSC_INVALID_SQL;
    }

707
    if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
708
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
709
    }
H
hjxilinx 已提交
710

H
hzcheng 已提交
711 712 713
    return TSDB_CODE_SUCCESS;
  }

H
hjxilinx 已提交
714 715 716
  /*
   * check invalid SQL:
   * select count(tbname)/count(tag1)/count(tag2) from super_table_name interval(1d);
H
hjxilinx 已提交
717
   */
H
hjxilinx 已提交
718 719
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
720
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
721
    if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
722
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
723 724
    }
  }
H
hjxilinx 已提交
725

H
hjxilinx 已提交
726 727 728
  /*
   * check invalid SQL:
   * select tbname, tags_fields from super_table_name interval(1s)
H
hjxilinx 已提交
729
   */
730
  if (tscQueryTags(pQueryInfo) && pQueryInfo->interval.interval > 0) {
731
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
732
  }
S
slguan 已提交
733 734

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

  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
738
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
739
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
740
    if (pTableMetaInfo->pTableMeta->id.uid == uid) {
S
slguan 已提交
741 742 743 744 745 746
      tableIndex = i;
      break;
    }
  }

  if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
747
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
748 749
  }

H
Haojun Liao 已提交
750 751
  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));
752

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

756 757 758 759
  if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_TSC_INVALID_SQL;
  }

760
  if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
761
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
762
  }
H
hjxilinx 已提交
763

H
hjxilinx 已提交
764
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
765 766
}

767
int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
768 769 770 771
  const char* msg1 = "interval offset cannot be negative";
  const char* msg2 = "interval offset should be shorter than interval";
  const char* msg3 = "cannot use 'year' as offset when interval is 'month'";

772 773 774
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);

775 776 777 778
  SStrToken* t = &pQuerySql->offset;
  if (t->n == 0) {
    pQueryInfo->interval.offsetUnit = pQueryInfo->interval.intervalUnit;
    pQueryInfo->interval.offset = 0;
779 780 781
    return TSDB_CODE_SUCCESS;
  }

782
  if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.offset, &pQueryInfo->interval.offsetUnit) != TSDB_CODE_SUCCESS) {
783
    return TSDB_CODE_TSC_INVALID_SQL;
784 785
  }

786
  if (pQueryInfo->interval.offset < 0) {
787 788 789
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }

790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
  if (pQueryInfo->interval.offsetUnit != 'n' && pQueryInfo->interval.offsetUnit != 'y') {
    // if the unit of time window value is millisecond, change the value from microsecond
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
      pQueryInfo->interval.offset = pQueryInfo->interval.offset / 1000;
    }
    if (pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') {
      if (pQueryInfo->interval.offset >= pQueryInfo->interval.interval) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
      }
    }
  } else if (pQueryInfo->interval.offsetUnit == pQueryInfo->interval.intervalUnit) {
    if (pQueryInfo->interval.offset >= pQueryInfo->interval.interval) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }
  } else if (pQueryInfo->interval.intervalUnit == 'n' && pQueryInfo->interval.offsetUnit == 'y') {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
  } else if (pQueryInfo->interval.intervalUnit == 'y' && pQueryInfo->interval.offsetUnit == 'n') {
    if (pQueryInfo->interval.interval * 12 <= pQueryInfo->interval.offset) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }
  } else {
    // TODO: offset should be shorter than interval, but how to check
    // conflicts like 30days offset and 1 month interval
813 814 815 816 817
  }

  return TSDB_CODE_SUCCESS;
}

818
int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
819 820
  const char* msg0 = "sliding value too small";
  const char* msg1 = "sliding value no larger than the interval value";
H
Haojun Liao 已提交
821
  const char* msg2 = "sliding value can not less than 1% of interval value";
822
  const char* msg3 = "does not support sliding when interval is natural month/year";
H
Haojun Liao 已提交
823
//  const char* msg4 = "sliding not support yet in ordinary query";
H
Haojun Liao 已提交
824 825

  const static int32_t INTERVAL_SLIDING_FACTOR = 100;
826
  SSqlCmd* pCmd = &pSql->cmd;
H
hzcheng 已提交
827

H
hjxilinx 已提交
828
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
829
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
830

831
  SStrToken* pSliding = &pQuerySql->sliding;
B
Bomin Zhang 已提交
832
  if (pSliding->n == 0) {
833 834
    pQueryInfo->interval.slidingUnit = pQueryInfo->interval.intervalUnit;
    pQueryInfo->interval.sliding = pQueryInfo->interval.interval;
B
Bomin Zhang 已提交
835 836
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
837

838
  if (pQueryInfo->interval.intervalUnit == 'n' || pQueryInfo->interval.intervalUnit == 'y') {
B
Bomin Zhang 已提交
839 840
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
  }
H
hzcheng 已提交
841

842
  parseAbsoluteDuration(pSliding->z, pSliding->n, &pQueryInfo->interval.sliding);
B
Bomin Zhang 已提交
843
  if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
844
    pQueryInfo->interval.sliding /= 1000;
B
Bomin Zhang 已提交
845 846
  }

847
  if (pQueryInfo->interval.sliding < tsMinSlidingTime) {
B
Bomin Zhang 已提交
848 849 850
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
  }

851
  if (pQueryInfo->interval.sliding > pQueryInfo->interval.interval) {
B
Bomin Zhang 已提交
852
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
853 854
  }

855
  if ((pQueryInfo->interval.interval != 0) && (pQueryInfo->interval.interval/pQueryInfo->interval.sliding > INTERVAL_SLIDING_FACTOR)) {
H
Haojun Liao 已提交
856 857 858
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
  }

H
Haojun Liao 已提交
859 860 861
//  if (pQueryInfo->interval.sliding != pQueryInfo->interval.interval && pSql->pStream == NULL) {
//    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
//  }
862

H
hzcheng 已提交
863 864 865
  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
866
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql) {
Y
TD-1039  
yihaoDeng 已提交
867
  const char* msg1 = "name too long";
H
hzcheng 已提交
868

869 870
  SSqlCmd* pCmd = &pSql->cmd;
  int32_t  code = TSDB_CODE_SUCCESS;
S
slguan 已提交
871

H
hjxilinx 已提交
872
  // backup the old name in pTableMetaInfo
H
Haojun Liao 已提交
873 874
  char oldName[TSDB_TABLE_FNAME_LEN] = {0};
  tstrncpy(oldName, pTableMetaInfo->name, tListLen(oldName));
H
hjxilinx 已提交
875

H
Haojun Liao 已提交
876
  if (hasSpecifyDB(pzTableName)) { // db has been specified in sql string so we ignore current db path
H
hjxilinx 已提交
877
    code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), NULL, pzTableName, NULL);
H
Haojun Liao 已提交
878 879 880
    if (code != 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
    }
H
Haojun Liao 已提交
881
  } else {  // get current DB name first, and then set it into path
H
Haojun Liao 已提交
882
    SStrToken t = {0};
H
hzcheng 已提交
883
    getCurrentDBName(pSql, &t);
H
Haojun Liao 已提交
884
    if (t.n == 0) {  // current database not available or not specified
885
      code = TSDB_CODE_TSC_DB_NOT_SELECTED;
H
Haojun Liao 已提交
886 887 888 889 890
    } else {
      code = setObjFullName(pTableMetaInfo->name, NULL, &t, pzTableName, NULL);
      if (code != 0) {
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
      }
H
Haojun Liao 已提交
891
    }
H
hzcheng 已提交
892
  }
H
Haojun Liao 已提交
893

S
slguan 已提交
894
  if (code != TSDB_CODE_SUCCESS) {
895 896
    return code;
  }
H
hjxilinx 已提交
897

898
  /*
H
Haojun Liao 已提交
899
   * the old name exists and is not equalled to the new name. Release the table meta
900 901
   * that are corresponding to the old name for the new table name.
   */
H
Haojun Liao 已提交
902
  if (strlen(oldName) > 0 && strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
H
Haojun Liao 已提交
903
    tscClearTableMetaInfo(pTableMetaInfo, false);
904
  }
H
hjxilinx 已提交
905

906
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
907 908
}

H
Haojun Liao 已提交
909
static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
H
hzcheng 已提交
910 911
  assert(pFieldList != NULL);

912 913 914 915 916 917 918
  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 已提交
919 920

  // number of fields no less than 2
H
Haojun Liao 已提交
921 922
  size_t numOfCols = taosArrayGetSize(pFieldList);
  if (numOfCols <= 1 || numOfCols > TSDB_MAX_COLUMNS) {
923
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
924 925 926 927
    return false;
  }

  // first column must be timestamp
H
Haojun Liao 已提交
928 929
  TAOS_FIELD* pField = taosArrayGet(pFieldList, 0);
  if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) {
930
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
931 932 933 934
    return false;
  }

  int32_t nLen = 0;
H
Haojun Liao 已提交
935 936
  for (int32_t i = 0; i < numOfCols; ++i) {
    pField = taosArrayGet(pFieldList, i);
B
Bomin Zhang 已提交
937 938

    if (pField->bytes == 0) {
dengyihao's avatar
dengyihao 已提交
939 940 941
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
      return false;
    }
H
hzcheng 已提交
942 943

    if (pField->type < TSDB_DATA_TYPE_BOOL || pField->type > TSDB_DATA_TYPE_NCHAR) {
944
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
945 946 947 948 949
      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))) {
950
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
951 952 953 954
      return false;
    }

    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
955
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
956 957 958
      return false;
    }

B
Bomin Zhang 已提交
959
    // field name must be unique
H
Haojun Liao 已提交
960
    if (has(pFieldList, i + 1, pField->name) == true) {
961
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
962 963
      return false;
    }
B
Bomin Zhang 已提交
964 965 966 967 968 969 970 971

    nLen += pField->bytes;
  }

  // max row length must be less than TSDB_MAX_BYTES_PER_ROW
  if (nLen > TSDB_MAX_BYTES_PER_ROW) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    return false;
H
hzcheng 已提交
972 973 974 975 976
  }

  return true;
}

H
Haojun Liao 已提交
977
static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd) {
H
hzcheng 已提交
978 979
  assert(pTagsList != NULL);

980 981 982 983 984 985 986
  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 已提交
987 988

  // number of fields at least 1
H
Haojun Liao 已提交
989 990
  size_t numOfTags = taosArrayGetSize(pTagsList);
  if (numOfTags < 1 || numOfTags > TSDB_MAX_TAGS) {
991
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
992 993 994 995
    return false;
  }

  int32_t nLen = 0;
H
Haojun Liao 已提交
996 997 998
  for (int32_t i = 0; i < numOfTags; ++i) {
    TAOS_FIELD* p = taosArrayGet(pTagsList, i);
    if (p->bytes == 0) {
dengyihao's avatar
dengyihao 已提交
999 1000 1001
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
      return false;
    }
H
Haojun Liao 已提交
1002 1003

    nLen += p->bytes;
H
hzcheng 已提交
1004 1005 1006 1007
  }

  // max tag row length must be less than TSDB_MAX_TAGS_LEN
  if (nLen > TSDB_MAX_TAGS_LEN) {
1008
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1009 1010 1011 1012
    return false;
  }

  // field name must be unique
H
Haojun Liao 已提交
1013 1014 1015 1016
  for (int32_t i = 0; i < numOfTags; ++i) {
    TAOS_FIELD* p = taosArrayGet(pTagsList, i);

    if (has(pFieldList, 0, p->name) == true) {
1017
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1018 1019 1020 1021 1022
      return false;
    }
  }

  /* timestamp in tag is not allowed */
H
Haojun Liao 已提交
1023 1024 1025 1026
  for (int32_t i = 0; i < numOfTags; ++i) {
    TAOS_FIELD* p = taosArrayGet(pTagsList, i);

    if (p->type == TSDB_DATA_TYPE_TIMESTAMP) {
1027
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
1028 1029 1030
      return false;
    }

H
Haojun Liao 已提交
1031
    if (p->type < TSDB_DATA_TYPE_BOOL || p->type > TSDB_DATA_TYPE_NCHAR) {
1032
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1033 1034 1035
      return false;
    }

H
Haojun Liao 已提交
1036 1037
    if ((p->type == TSDB_DATA_TYPE_BINARY && p->bytes <= 0) ||
        (p->type == TSDB_DATA_TYPE_NCHAR && p->bytes <= 0)) {
1038
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
1039 1040 1041
      return false;
    }

H
Haojun Liao 已提交
1042
    if (validateColumnName(p->name) != TSDB_CODE_SUCCESS) {
1043
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1044 1045 1046
      return false;
    }

H
Haojun Liao 已提交
1047
    if (has(pTagsList, i + 1, p->name) == true) {
1048
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
      return false;
    }
  }

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
1060 1061 1062 1063 1064 1065
  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 已提交
1066

1067
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
1068

1069
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
1070
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
1071

H
hjxilinx 已提交
1072 1073 1074
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
1075
  // no more than 6 tags
H
hjxilinx 已提交
1076
  if (numOfTags == TSDB_MAX_TAGS) {
H
hzcheng 已提交
1077 1078 1079
    char msg[128] = {0};
    sprintf(msg, "tags no more than %d", TSDB_MAX_TAGS);

1080
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
1081 1082 1083 1084 1085
    return false;
  }

  // no timestamp allowable
  if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) {
1086
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1087 1088 1089
    return false;
  }

L
[#1236]  
lihui 已提交
1090
  if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_NCHAR)) {
1091
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1092 1093 1094
    return false;
  }

H
hjxilinx 已提交
1095
  SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1096 1097
  int32_t  nLen = 0;

H
hjxilinx 已提交
1098
  for (int32_t i = 0; i < numOfTags; ++i) {
H
hzcheng 已提交
1099 1100 1101 1102 1103
    nLen += pTagSchema[i].bytes;
  }

  // length less than TSDB_MAX_TASG_LEN
  if (nLen + pTagField->bytes > TSDB_MAX_TAGS_LEN) {
1104
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1105 1106 1107 1108 1109
    return false;
  }

  // tags name can not be a keyword
  if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) {
1110
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
1111 1112 1113 1114 1115
    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) {
1116
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1117 1118 1119 1120
    return false;
  }

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

H
hjxilinx 已提交
1123
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
1124
    if (strncasecmp(pTagField->name, pSchema[i].name, sizeof(pTagField->name) - 1) == 0) {
1125
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1126 1127 1128 1129 1130 1131 1132 1133
      return false;
    }
  }

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
1134 1135 1136 1137 1138 1139
  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 已提交
1140

1141
  assert(pCmd->numOfClause == 1);
1142
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
1143 1144 1145 1146 1147
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
1148
  // no more max columns
H
hjxilinx 已提交
1149
  if (numOfCols >= TSDB_MAX_COLUMNS || numOfTags + numOfCols >= TSDB_MAX_COLUMNS) {
1150
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1151 1152 1153 1154
    return false;
  }

  if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_NCHAR) {
1155
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
1156 1157 1158 1159
    return false;
  }

  if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) {
1160
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1161 1162 1163
    return false;
  }

H
hjxilinx 已提交
1164
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
1165 1166
  int32_t  nLen = 0;

H
hjxilinx 已提交
1167
  for (int32_t i = 0; i < numOfCols; ++i) {
H
hzcheng 已提交
1168 1169 1170 1171
    nLen += pSchema[i].bytes;
  }

  if (pColField->bytes <= 0) {
1172
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1173 1174 1175 1176 1177
    return false;
  }

  // length less than TSDB_MAX_BYTES_PER_ROW
  if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) {
1178
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1179 1180 1181 1182
    return false;
  }

  // field name must be unique
H
hjxilinx 已提交
1183
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
1184
    if (strncasecmp(pColField->name, pSchema[i].name, sizeof(pColField->name) - 1) == 0) {
1185
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1186 1187 1188 1189 1190 1191 1192 1193
      return false;
    }
  }

  return true;
}

/* is contained in pFieldList or not */
H
Haojun Liao 已提交
1194 1195 1196 1197
static bool has(SArray* pFieldList, int32_t startIdx, const char* name) {
  size_t numOfCols = taosArrayGetSize(pFieldList);
  for (int32_t j = startIdx; j < numOfCols; ++j) {
    TAOS_FIELD* field = taosArrayGet(pFieldList, j);
B
Bomin Zhang 已提交
1198
    if (strncasecmp(name, field->name, sizeof(field->name) - 1) == 0) return true;
H
hzcheng 已提交
1199 1200 1201 1202 1203 1204 1205
  }

  return false;
}

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

H
Haojun Liao 已提交
1206
static void getCurrentDBName(SSqlObj* pSql, SStrToken* pDBToken) {
H
hzcheng 已提交
1207
  pDBToken->z = pSql->pTscObj->db;
S
TD-1057  
Shengliang Guan 已提交
1208
  pDBToken->n = (uint32_t)strlen(pSql->pTscObj->db);
H
hzcheng 已提交
1209 1210 1211
}

/* length limitation, strstr cannot be applied */
H
Haojun Liao 已提交
1212
static bool hasSpecifyDB(SStrToken* pTableName) {
S
TD-1057  
Shengliang Guan 已提交
1213
  for (uint32_t i = 0; i < pTableName->n; ++i) {
H
hzcheng 已提交
1214 1215 1216 1217 1218 1219 1220 1221
    if (pTableName->z[i] == TS_PATH_DELIMITER[0]) {
      return true;
    }
  }

  return false;
}

H
Haojun Liao 已提交
1222
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1223 1224 1225
  int32_t totalLen = 0;

  if (account != NULL) {
S
TD-1057  
Shengliang Guan 已提交
1226
    int32_t len = (int32_t)strlen(account);
H
hzcheng 已提交
1227 1228 1229 1230 1231 1232 1233
    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) {
Y
TD-1039  
yihaoDeng 已提交
1234
    if (pDB->n >= TSDB_ACCT_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) {
1235
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
    }

    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 已提交
1248
      if (!tscValidateTableNameLength(tableName->n)) {
1249
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1250 1251 1252
      }
    } else {  // pDB == NULL, the db prefix name is specified in tableName
      /* the length limitation includes tablename + dbname + sep */
B
Bomin Zhang 已提交
1253
      if (tableName->n >= TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN) {
1254
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264
      }
    }

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

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

H
Haojun Liao 已提交
1266
  if (totalLen < TSDB_TABLE_FNAME_LEN) {
S
slguan 已提交
1267 1268 1269
    fullName[totalLen] = 0;
  }

H
Haojun Liao 已提交
1270
  return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1271 1272
}

Y
TD-1688  
yihaoDeng 已提交
1273 1274 1275 1276
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tscColumnListInsert(pQueryInfo->colList, &tsCol);
}
1277
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
1278
  const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables";
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309
  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 已提交
1310 1311 1312
    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);
1313 1314 1315 1316

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

H
Haojun Liao 已提交
1317
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo, colList, NULL);
1318
    if (ret != TSDB_CODE_SUCCESS) {
1319 1320
      taosArrayDestroy(colList);
      tExprTreeDestroy(&pNode, NULL);
1321 1322 1323 1324 1325 1326
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }

    size_t numOfNode = taosArrayGetSize(colList);
    for(int32_t k = 0; k < numOfNode; ++k) {
      SColIndex* pIndex = taosArrayGet(colList, k);
1327 1328
      if (TSDB_COL_IS_TAG(pIndex->flag)) {
        tExprTreeDestroy(&pNode, NULL);
1329 1330
        taosArrayDestroy(colList);
        tExprTreeDestroy(&pNode, NULL);
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
        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 已提交
1345
    len = tbufTell(&bw);
H
Haojun Liao 已提交
1346
    char* c = tbufGetData(&bw, false);
1347 1348

    // set the serialized binary string as the parameter of arithmetic expression
S
Shengliang Guan 已提交
1349
    addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len, index.tableIndex);
1350 1351

    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
Y
TD-1688  
yihaoDeng 已提交
1352 1353
    // add ts column
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
1354

H
Haojun Liao 已提交
1355
    tbufCloseWriter(&bw);
1356 1357 1358 1359 1360 1361
    taosArrayDestroy(colList);
    tExprTreeDestroy(&pNode, NULL);
  } else {
    columnList.num = 0;
    columnList.ids[0] = (SColumnIndex) {0, 0};

H
Haojun Liao 已提交
1362 1363 1364 1365 1366 1367 1368
    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 已提交
1369

H
Haojun Liao 已提交
1370
    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, aliasName, NULL);
1371 1372

    int32_t slot = tscNumOfFields(pQueryInfo) - 1;
H
Haojun Liao 已提交
1373
    SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot);
1374 1375 1376 1377 1378

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

      // arithmetic expression always return result in the format of double float
H
Haojun Liao 已提交
1379
      pArithExprInfo->bytes      = sizeof(double);
1380
      pArithExprInfo->interBytes = sizeof(double);
H
Haojun Liao 已提交
1381
      pArithExprInfo->type       = TSDB_DATA_TYPE_DOUBLE;
1382

H
Haojun Liao 已提交
1383
      int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &pArithExprInfo->uid);
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395
      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;
}

1396

H
Haojun Liao 已提交
1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
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);
}

H
Haojun Liao 已提交
1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439
static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) {
  // primary timestamp column has been added already
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
    if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
      return;
    }
  }

  SColumnIndex index = {0};

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

  // add the timestamp column into the output columns
  int32_t numOfCols = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
  tscAddSpecialColumnForSelect(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL);

H
Haojun Liao 已提交
1440
  SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols);
H
Haojun Liao 已提交
1441 1442 1443 1444 1445
  pSupInfo->visible = false;

  pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
}

H
Haojun Liao 已提交
1446
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery) {
H
hzcheng 已提交
1447 1448
  assert(pSelection != NULL && pCmd != NULL);

1449 1450
  const char* msg2 = "functions can not be mixed up";
  const char* msg3 = "not support query expression";
H
hjxilinx 已提交
1451
  const char* msg5 = "invalid function name";
H
hjxilinx 已提交
1452

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

1455 1456 1457
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
H
Haojun Liao 已提交
1458

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

S
slguan 已提交
1463
    // project on all fields
H
Haojun Liao 已提交
1464 1465
    int32_t optr = pItem->pNode->nSQLOptr;

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

S
slguan 已提交
1472
      // select table_name1.field_name1, table_name2.field_name2  from table_name1, table_name2
1473
      if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
1474
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1475
      }
1476
    } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_TBID) {
S
slguan 已提交
1477
      // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
1478
      if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
1479
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1480 1481 1482
      }

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
1483 1484 1485
      int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
1486 1487
      }
    } else {
1488
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1489 1490
    }

H
hjxilinx 已提交
1491
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1492
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1493 1494 1495
    }
  }

1496 1497 1498
  // 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)) {
H
Haojun Liao 已提交
1499
    addPrimaryTsColIntoResult(pQueryInfo);
1500 1501
  }

H
Haojun Liao 已提交
1502
  if (!functionCompatibleCheck(pQueryInfo, joinQuery)) {
1503
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1504 1505
  }

H
Haojun Liao 已提交
1506 1507
  /*
   * transfer sql functions that need secondary merge into another format
1508
   * in dealing with super table queries such as: count/first/last
H
Haojun Liao 已提交
1509
   */
1510
  if (isSTable) {
H
hjxilinx 已提交
1511
    tscTansformSQLFuncForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1512

1513
    if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
1514
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1515 1516 1517 1518 1519 1520
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1521 1522
int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
    int8_t type, char* fieldName, SSqlExpr* pSqlExpr) {
1523
  
S
slguan 已提交
1524
  for (int32_t i = 0; i < pIdList->num; ++i) {
1525 1526 1527 1528 1529 1530 1531 1532
    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;
    }
    
1533
    tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i]));
H
hzcheng 已提交
1534
  }
H
hjxilinx 已提交
1535 1536
  
  TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
H
Haojun Liao 已提交
1537
  SInternalField* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
H
hjxilinx 已提交
1538
  pInfo->pSqlExpr = pSqlExpr;
H
hjxilinx 已提交
1539
  
H
hzcheng 已提交
1540 1541 1542
  return TSDB_CODE_SUCCESS;
}

1543
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1544
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1545 1546 1547
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
1548
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
H
hzcheng 已提交
1549

1550
  int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
1551 1552 1553 1554
  SColumnIndex index = {.tableIndex = tableIndex,};
  
  if (functionId == TSDB_FUNC_TAGPRJ) {
    index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta);
H
hjxilinx 已提交
1555 1556
  
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
1557 1558 1559 1560 1561 1562
  } else {
    index.columnIndex = colIndex;
  }
  
  return tscSqlExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes,
      pSchema->bytes, functionId == TSDB_FUNC_TAGPRJ);
H
hzcheng 已提交
1563 1564
}

H
Haojun Liao 已提交
1565
SSqlExpr* tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1566
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
H
Haojun Liao 已提交
1567
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
H
Haojun Liao 已提交
1568
                                     pColSchema->bytes, pColSchema->bytes, TSDB_COL_IS_TAG(flag));
H
Haojun Liao 已提交
1569
  tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName));
H
hzcheng 已提交
1570

S
slguan 已提交
1571 1572 1573 1574
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1575

H
hjxilinx 已提交
1576
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1577 1578

  pExpr->colInfo.flag = flag;
1579 1580
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  
S
slguan 已提交
1581
  if (TSDB_COL_IS_TAG(flag)) {
H
hjxilinx 已提交
1582
    tscColumnListInsert(pTableMetaInfo->tagColList, pIndex);
S
slguan 已提交
1583
  }
H
Haojun Liao 已提交
1584 1585

  return pExpr;
S
slguan 已提交
1586 1587
}

1588
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1589
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1590 1591

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1592 1593
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1594

H
hjxilinx 已提交
1595
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1596
  
weixin_48148422's avatar
weixin_48148422 已提交
1597
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1598
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1599
  } else {
H
hjxilinx 已提交
1600
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1601 1602 1603
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
hjxilinx 已提交
1604
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex);
B
Bomin Zhang 已提交
1605
    tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName));
S
slguan 已提交
1606 1607 1608 1609

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

H
hjxilinx 已提交
1612
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1613 1614 1615 1616 1617
  }

  return numOfTotalColumns;
}

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

1622
  int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
Haojun Liao 已提交
1623 1624 1625 1626 1627
  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 已提交
1628
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1629
    if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1630
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
1631 1632 1633 1634
    }

    // all meters columns are required
    if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) {  // all table columns are required.
1635
      for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
S
slguan 已提交
1636
        index.tableIndex = i;
1637
        int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1638
        startPos += inc;
H
hzcheng 已提交
1639 1640
      }
    } else {
1641
      doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1642
    }
H
Haojun Liao 已提交
1643 1644 1645

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

H
Haojun Liao 已提交
1649
    // user-specified constant value as a new result column
1650 1651
    index.columnIndex = (pQueryInfo->udColumnId--);
    index.tableIndex = 0;
H
hzcheng 已提交
1652

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

1657 1658 1659 1660 1661
    // 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 已提交
1662

1663 1664 1665
    if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
    }
H
Haojun Liao 已提交
1666

1667 1668 1669 1670 1671 1672
    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 已提交
1673

1674 1675
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1676 1677
      }

1678
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
Haojun Liao 已提交
1679
      pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
H
hzcheng 已提交
1680
    }
H
Haojun Liao 已提交
1681

1682 1683
    // add the primary timestamp column even though it is not required by user
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
hzcheng 已提交
1684
  } else {
1685
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1686 1687 1688 1689 1690
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
1691
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, SConvertFunc cvtFunc,
1692
                                       const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult) {
1693 1694
  const char* msg1 = "not support column types";

H
hzcheng 已提交
1695 1696
  int16_t type = 0;
  int16_t bytes = 0;
Y
TD-1230  
yihaoDeng 已提交
1697
  int32_t functionID = cvtFunc.execFuncId;
H
hzcheng 已提交
1698 1699

  if (functionID == TSDB_FUNC_SPREAD) {
1700
    int32_t t1 = pSchema->type;
1701
    if (t1 == TSDB_DATA_TYPE_BINARY || t1 == TSDB_DATA_TYPE_NCHAR || t1 == TSDB_DATA_TYPE_BOOL) {
1702
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1703 1704 1705 1706 1707 1708
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
1709 1710
    type = pSchema->type;
    bytes = pSchema->bytes;
H
hzcheng 已提交
1711
  }
Y
TD-1230  
yihaoDeng 已提交
1712
  
1713
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, bytes, false);
1714
  tstrncpy(pExpr->aliasName, name, tListLen(pExpr->aliasName));
1715

Y
TD-1230  
yihaoDeng 已提交
1716 1717 1718 1719
  if (cvtFunc.originFuncId == TSDB_FUNC_LAST_ROW && cvtFunc.originFuncId != functionID) {
    pExpr->colInfo.flag |= TSDB_COL_NULL;
  }

1720 1721 1722 1723 1724 1725
  // 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 已提交
1726
  
H
hjxilinx 已提交
1727
  // for all queries, the timestamp column needs to be loaded
S
slguan 已提交
1728
  SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1729
  tscColumnListInsert(pQueryInfo->colList, &index);
H
hzcheng 已提交
1730

H
Haojun Liao 已提交
1731
  // if it is not in the final result, do not add it
S
slguan 已提交
1732
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
H
Haojun Liao 已提交
1733
  if (finalResult) {
1734
    insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, pExpr->aliasName, pExpr);
H
Haojun Liao 已提交
1735 1736 1737
  } else {
    tscColumnListInsert(pQueryInfo->colList, &(ids.ids[0]));
  }
H
hzcheng 已提交
1738 1739 1740 1741

  return TSDB_CODE_SUCCESS;
}

1742 1743 1744 1745 1746 1747 1748 1749
void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrToken* pToken) {
  if (pItem->aliasName != NULL) {
    tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN);
  } else {
    char uname[TSDB_COL_NAME_LEN] = {0};
    int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN);
    tstrncpy(uname, pToken->z, len);

H
Haojun Liao 已提交
1750 1751 1752 1753 1754 1755
    int32_t size = TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].aName) + 2 + 1;
    char tmp[TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].aName) + 2 + 1] = {0};

    snprintf(tmp, size, "%s(%s)", aAggs[functionId].aName, uname);

    tstrncpy(name, tmp, TSDB_COL_NAME_LEN);
1756 1757 1758
  }
}

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

1763
  const char* msg1 = "not support column types";
S
slguan 已提交
1764
  const char* msg2 = "invalid parameters";
1765
  const char* msg3 = "illegal column name";
S
slguan 已提交
1766
  const char* msg4 = "invalid table name";
1767
  const char* msg5 = "parameter is out of range [0, 100]";
S
slguan 已提交
1768
  const char* msg6 = "function applied to tags not allowed";
1769
  const char* msg7 = "normal table can not apply this function";
H
Haojun Liao 已提交
1770
  const char* msg8 = "multi-columns selection does not support alias column name";
B
Bomin Zhang 已提交
1771
  const char* msg9 = "invalid function";
H
Haojun Liao 已提交
1772

H
hzcheng 已提交
1773 1774 1775
  switch (optr) {
    case TK_COUNT: {
        /* more than one parameter for count() function */
H
Haojun Liao 已提交
1776
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
1777
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1778 1779 1780
      }

      int16_t functionID = 0;
H
Haojun Liao 已提交
1781
      if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
1782
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1783 1784
      }

H
hjxilinx 已提交
1785
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1786
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1787 1788

      if (pItem->pNode->pParam != NULL) {
S
slguan 已提交
1789
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
Y
TD-1370  
yihaoDeng 已提交
1790
        SStrToken* pToken = &pParamElem->pNode->colInfo;
S
TD-1530  
Shengliang Guan 已提交
1791
        int16_t sqlOptr = pParamElem->pNode->nSQLOptr;
Y
TD-1370  
yihaoDeng 已提交
1792 1793 1794 1795 1796
        if ((pToken->z == NULL || pToken->n == 0) 
            && (TK_INTEGER != sqlOptr)) /*select count(1) from table*/ {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
        } 
        if (sqlOptr == TK_ALL) {
S
slguan 已提交
1797 1798
          // select table.*
          // check if the table name is valid or not
H
Haojun Liao 已提交
1799
          SStrToken tmpToken = pParamElem->pNode->colInfo;
S
slguan 已提交
1800

1801
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1802
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1803 1804 1805 1806
          }

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
1807
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
Y
TD-1370  
yihaoDeng 已提交
1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822
        } else if (sqlOptr == TK_INTEGER) { // select count(1) from table1
          char buf[8] = {0};  
          int64_t val = -1;
          tVariant* pVariant = &pParamElem->pNode->val;
          if (pVariant->nType == TSDB_DATA_TYPE_BIGINT) {
            tVariantDump(pVariant, buf, TSDB_DATA_TYPE_BIGINT, true);
            val = GET_INT64_VAL(buf); 
          }
          if (val == 1) {
            index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
            int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
            pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
          } else {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
          }
H
hzcheng 已提交
1823
        } else {
H
hjxilinx 已提交
1824
          // count the number of meters created according to the super table
1825 1826
          if (getColumnIndexByName(pCmd, pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1827 1828
          }

H
hjxilinx 已提交
1829
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1830 1831

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1832 1833
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1834
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1835
            isTag = true;
H
hzcheng 已提交
1836 1837
          }

S
slguan 已提交
1838
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1839
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1840
        }
S
slguan 已提交
1841 1842 1843
      } 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;
1844
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1845
      }
H
Haojun Liao 已提交
1846 1847 1848

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

H
hjxilinx 已提交
1849
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1850
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1851
      
S
slguan 已提交
1852
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1853 1854 1855 1856 1857
      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) {
1858
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1859 1860
        }
      }
H
Haojun Liao 已提交
1861 1862

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

S
slguan 已提交
1867
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1868 1869 1870
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1871 1872 1873 1874 1875 1876
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1877
    case TK_TWA:
H
hzcheng 已提交
1878 1879 1880 1881 1882 1883 1884 1885 1886
    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 */
1887
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1888 1889 1890 1891
      }

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

S
slguan 已提交
1895
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
Y
yihaoDeng 已提交
1896
      if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
1897
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1898
      }
Y
yihaoDeng 已提交
1899 1900 1901
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
H
hzcheng 已提交
1902 1903

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

H
hjxilinx 已提交
1908
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1909
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1910 1911 1912 1913
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
1914
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1915 1916

      int16_t functionID = 0;
H
Haojun Liao 已提交
1917
      if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
1918
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1919 1920
      }

S
slguan 已提交
1921 1922
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
1923
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1924
      }
H
hzcheng 已提交
1925

S
slguan 已提交
1926
      // set the first column ts for diff query
H
hzcheng 已提交
1927
      if (optr == TK_DIFF) {
1928
        colIndex += 1;
S
slguan 已提交
1929
        SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
H
hjxilinx 已提交
1930
        SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
1931
                         TSDB_KEYSIZE, false);
H
hzcheng 已提交
1932

S
slguan 已提交
1933
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1934
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1935 1936
      }

S
slguan 已提交
1937
      // functions can not be applied to tags
H
hjxilinx 已提交
1938
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1939
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1940 1941
      }

1942
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, resultSize, false);
H
hzcheng 已提交
1943 1944 1945 1946

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

S
slguan 已提交
1951
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1952 1953

        memset(val, 0, tListLen(val));
1954
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1955
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1956 1957
        }

S
slguan 已提交
1958
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1959 1960
      }

S
slguan 已提交
1961 1962 1963
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1964 1965
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1966
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1967 1968 1969
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
S
TD-1057  
Shengliang Guan 已提交
1970
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, (int32_t)pExpr->resType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
1971 1972
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1973
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1974 1975
        }
      }
H
Haojun Liao 已提交
1976 1977

      tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
S
slguan 已提交
1978
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1979 1980 1981 1982 1983 1984 1985 1986 1987
    }
    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;
H
Haojun Liao 已提交
1988
      if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
1989
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
B
Bomin Zhang 已提交
1990
      }
1991 1992

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

H
hzcheng 已提交
1998 1999
      if (!requireAllFields) {
        if (pItem->pNode->pParam->nExpr < 1) {
2000
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
2001 2002
        }

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

H
hzcheng 已提交
2007 2008 2009 2010
        /* 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) {
2011
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
2012 2013
          }

S
slguan 已提交
2014 2015
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

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

2019
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
2020
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
2021 2022
            }

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

2026
            char name[TSDB_COL_NAME_LEN] = {0};
H
hjxilinx 已提交
2027
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
2028
              index.columnIndex = j;
S
Shengliang Guan 已提交
2029
              SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
2030 2031 2032
              setResultColName(name, pItem, cvtFunc.originFuncId, &t);

              if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult) != 0) {
2033
                return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2034 2035
              }
            }
H
hzcheng 已提交
2036

S
slguan 已提交
2037
          } else {
2038 2039
            if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2040 2041
            }

H
hjxilinx 已提交
2042
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
2043 2044

            // functions can not be applied to tags
H
hjxilinx 已提交
2045
            if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
2046
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
2047
            }
H
Haojun Liao 已提交
2048

2049 2050 2051 2052 2053 2054
            char name[TSDB_COL_NAME_LEN] = {0};

            SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
            setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo);

            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
2055
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2056
            }
2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072

            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 已提交
2073 2074
          }
        }
2075
        
S
slguan 已提交
2076 2077 2078 2079
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

H
Haojun Liao 已提交
2080
        // multicolumn selection does not support alias name
H
Haojun Liao 已提交
2081
        if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
2082
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
2083 2084
        }

2085
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
2086
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
2087
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
2088

H
hjxilinx 已提交
2089
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
2090
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
2091 2092

            char name[TSDB_COL_NAME_LEN] = {0};
2093
            SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
2094 2095 2096
            setResultColName(name, pItem, cvtFunc.originFuncId, &t);

            if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) {
2097
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2098
            }
H
Haojun Liao 已提交
2099 2100

            colIndex++;
H
hzcheng 已提交
2101
          }
S
slguan 已提交
2102

H
hjxilinx 已提交
2103
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
2104 2105
        }

2106
        
S
slguan 已提交
2107
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2108 2109 2110 2111 2112 2113 2114 2115 2116
      }
    }
    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 */
2117
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2118 2119 2120 2121
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
2122
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2123
      }
H
hjxilinx 已提交
2124
      
S
slguan 已提交
2125
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2126 2127
      if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2128
      }
Y
yihaoDeng 已提交
2129 2130 2131 2132
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
      
H
hjxilinx 已提交
2133
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2134
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
2135 2136

      // functions can not be applied to tags
H
hjxilinx 已提交
2137
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
2138
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
2139 2140 2141
      }

      // 2. valid the column type
S
slguan 已提交
2142
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
2143
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
2144
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2145 2146 2147 2148
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
2149
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2150 2151 2152 2153
      }

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

S
slguan 已提交
2154 2155
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
2156

H
hjxilinx 已提交
2157
      char    val[8] = {0};
H
hjxilinx 已提交
2158 2159
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
2160
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
2161
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
2162

L
lihui 已提交
2163
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
2164
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
2165
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176
        }

        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;
H
Haojun Liao 已提交
2177
        if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
2178
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2179
        }
dengyihao's avatar
dengyihao 已提交
2180 2181
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
        colIndex += 1;  // the first column is ts
H
hzcheng 已提交
2182

2183
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
2184
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
2185
      } else {
2186
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
2187

H
Haojun Liao 已提交
2188
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
2189
        if (nTop <= 0 || nTop > 100) {  // todo use macro
2190
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2191 2192 2193
        }

        int16_t functionId = 0;
H
Haojun Liao 已提交
2194
        if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
2195
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2196
        }
S
slguan 已提交
2197

H
Haojun Liao 已提交
2198
        // todo REFACTOR
H
hzcheng 已提交
2199
        // set the first column ts for top/bottom query
S
slguan 已提交
2200
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
2201 2202
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
            TSDB_KEYSIZE, false);
H
Haojun Liao 已提交
2203
        tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
S
slguan 已提交
2204

H
Haojun Liao 已提交
2205
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
2206
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
2207
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
2208
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
2209

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

2212
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
2213
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
2214
      }
H
hjxilinx 已提交
2215 2216
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
2217
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
2218
  
S
slguan 已提交
2219
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
2220
      if (finalResult) {
2221
        insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
2222 2223
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
2224
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
2225 2226
        }
      }
S
slguan 已提交
2227

2228 2229 2230 2231 2232
      return TSDB_CODE_SUCCESS;
    };
    
    case TK_TBID: {
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2233
      if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
2234
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
2235 2236 2237 2238
      }
    
      // no parameters or more than one parameter for function
      if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 1) {
2239
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2240 2241 2242 2243 2244
      }
      
      tSQLExpr* pParam = pItem->pNode->pParam->a[0].pNode;
    
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2245 2246
      if (getColumnIndexByName(pCmd, &pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2247 2248 2249 2250 2251 2252 2253
      }
    
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
  
      // functions can not be applied to normal columns
      int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
2254
      if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
2255
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2256 2257
      }
    
2258 2259 2260
      if (index.columnIndex > 0) {
        index.columnIndex -= numOfCols;
      }
2261 2262
      
      // 2. valid the column type
2263 2264 2265 2266 2267 2268 2269 2270
      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) {
2271
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
2272 2273 2274 2275
      }

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
2276 2277 2278
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
2279
        s = tGetTableNameColumnSchema();
2280 2281 2282 2283
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
2284 2285
      int16_t bytes = 0;
      int16_t type  = 0;
2286
      int32_t inter = 0;
2287 2288 2289 2290

      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 已提交
2291
      s.type = (uint8_t)type;
2292 2293 2294 2295 2296
      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 已提交
2297
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2298
    }
2299
    
H
hzcheng 已提交
2300
    default:
2301
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2302
  }
2303
  
H
hzcheng 已提交
2304 2305
}

S
slguan 已提交
2306 2307
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
2308
  assert(num == 1 && tableIndex >= 0);
S
slguan 已提交
2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319

  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 已提交
2320 2321 2322 2323
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
S
TD-1057  
Shengliang Guan 已提交
2324
    int32_t len = ((int32_t)pItem->pNode->operand.n < nameLength) ? (int32_t)pItem->pNode->operand.n : nameLength;
H
hzcheng 已提交
2325 2326 2327 2328
    strncpy(resultFieldName, pItem->pNode->operand.z, len);
  }
}

H
Haojun Liao 已提交
2329 2330 2331
static bool isTablenameToken(SStrToken* token) {
  SStrToken tmpToken = *token;
  SStrToken tableToken = {0};
S
slguan 已提交
2332 2333 2334 2335 2336 2337

  extractTableNameFromToken(&tmpToken, &tableToken);

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

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

H
hjxilinx 已提交
2341 2342
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2343 2344 2345 2346 2347 2348 2349 2350 2351 2352

  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 已提交
2353
      break;
S
slguan 已提交
2354 2355 2356 2357 2358 2359
    }
  }

  return columnIndex;
}

H
Haojun Liao 已提交
2360
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2361 2362 2363 2364 2365 2366 2367 2368 2369 2370
  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) {
2371 2372
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2373 2374 2375

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2376
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
2377 2378 2379 2380 2381 2382 2383
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2384
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2385 2386 2387 2388 2389 2390
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2391
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2392 2393 2394 2395 2396 2397
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2398
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2399 2400 2401
  }
}

H
Haojun Liao 已提交
2402
int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2403
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2404
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2405 2406 2407 2408 2409 2410 2411
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
2412
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2413
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
Haojun Liao 已提交
2414 2415
    char* name = pTableMetaInfo->aliasName;
    if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
S
slguan 已提交
2416 2417 2418 2419 2420 2421
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
2422
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2423 2424 2425 2426 2427
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
2428 2429
int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SStrToken tableToken = {0};
S
slguan 已提交
2430 2431
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2432
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2433
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2434 2435
  }

S
slguan 已提交
2436 2437
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2438

H
Haojun Liao 已提交
2439
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2440
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2441
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2442 2443
  }

H
Haojun Liao 已提交
2444
  SStrToken tmpToken = *pToken;
S
slguan 已提交
2445

2446
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2447
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2448 2449
  }

2450
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2451 2452
}

H
Haojun Liao 已提交
2453
int32_t convertFunctionId(int32_t optr, int16_t* functionId) {
H
hzcheng 已提交
2454 2455 2456 2457 2458 2459 2460 2461 2462 2463
  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 已提交
2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481
    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 已提交
2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517
    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 已提交
2518 2519
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534
      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 已提交
2535
  SSqlCmd*        pCmd = &pSql->cmd;
2536
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2537
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2538

H
hzcheng 已提交
2539 2540
  pCmd->command = TSDB_SQL_SHOW;

2541
  const char* msg1 = "invalid name";
2542
  const char* msg2 = "pattern filter string too long";
2543 2544 2545 2546
  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 已提交
2547 2548 2549 2550 2551

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2552 2553 2554
  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 已提交
2555
    // db prefix in tagCond, show table conds in payload
H
Haojun Liao 已提交
2556
    SStrToken* pDbPrefixToken = &pShowInfo->prefix;
2557
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2558

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

2563
      if (pDbPrefixToken->n <= 0) {
2564
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2565 2566
      }

2567
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2568
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2569 2570
      }

H
hjxilinx 已提交
2571
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2572
      if (ret != TSDB_CODE_SUCCESS) {
2573
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2574
      }
2575
    }
H
hzcheng 已提交
2576

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

2582
      if (pPattern->n <= 0) {
2583
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2584
      }
H
hzcheng 已提交
2585

H
Haojun Liao 已提交
2586
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2587
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2588 2589
      }
    }
2590 2591
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2592
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2593 2594
    }

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

2601
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2602
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2603
    }
H
hzcheng 已提交
2604 2605 2606 2607 2608
  }

  return TSDB_CODE_SUCCESS;
}

2609 2610 2611 2612
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 已提交
2613

2614 2615
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2616
  
H
Haojun Liao 已提交
2617
  SStrToken* idStr = &(pInfo->pDCLInfo->ip);
2618
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2619
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2620 2621
  }

2622
  strncpy(pCmd->payload, idStr->z, idStr->n);
2623

H
hzcheng 已提交
2624
  const char delim = ':';
2625 2626
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2627

2628 2629 2630 2631 2632
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2633

2634 2635 2636 2637 2638 2639
  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 已提交
2640
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2641 2642 2643 2644 2645
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2646
  }
2647
  
H
hzcheng 已提交
2648 2649 2650
  return TSDB_CODE_SUCCESS;
}

2651 2652 2653 2654 2655 2656
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);

2657
  in_addr_t epAddr = taosInetAddr(tmp);
2658

2659
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2660 2661
}

H
hjxilinx 已提交
2662
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2663
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2664

weixin_48148422's avatar
weixin_48148422 已提交
2665
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2666
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2667 2668
  }

H
hjxilinx 已提交
2669
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2670 2671 2672

  int16_t bytes = 0;
  int16_t type = 0;
2673
  int32_t interBytes = 0;
H
hjxilinx 已提交
2674 2675 2676
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2677
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2678 2679
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

2680
    int32_t colIndex = pExpr->colInfo.colIndex;
H
hjxilinx 已提交
2681
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2682
    
S
slguan 已提交
2683
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2684 2685
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
S
TD-1057  
Shengliang Guan 已提交
2686
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64Key, &type, &bytes,
2687
                            &interBytes, 0, true) != TSDB_CODE_SUCCESS) {
2688
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2689
      }
H
hzcheng 已提交
2690

2691
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2692
      // todo refactor
2693
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2694 2695 2696
    }
  }

2697
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2698
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2699 2700 2701
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2702
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2703
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2704
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2705 2706
    return;
  }
H
hjxilinx 已提交
2707 2708 2709
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2710
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2711
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2712
    
2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729
    // 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 已提交
2730 2731 2732
  }
}

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

S
slguan 已提交
2738
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2739 2740
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2741
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
2742
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
2743
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2744
      return true;
H
hzcheng 已提交
2745 2746 2747
    }
  }

2748 2749
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2750
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2751 2752
      return true;
    }
H
hzcheng 已提交
2753

2754
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2755
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2756
      return true;
2757 2758 2759
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
2760
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2761 2762
        return true;
      }
H
hzcheng 已提交
2763 2764
    }
  }
S
slguan 已提交
2765

H
hzcheng 已提交
2766 2767 2768
  return false;
}

H
Haojun Liao 已提交
2769
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
H
hzcheng 已提交
2770
  int32_t startIdx = 0;
2771 2772 2773 2774

  size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
  assert(numOfExpr > 0);

H
hjxilinx 已提交
2775 2776
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2777 2778

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

H
Haojun Liao 已提交
2783
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2784 2785 2786

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2787 2788 2789
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2790
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2791

H
hjxilinx 已提交
2792
    int16_t functionId = pExpr1->functionId;
2793 2794 2795 2796
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
Haojun Liao 已提交
2797
    if (functionId == TSDB_FUNC_PRJ && (pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->colInfo.flag))) {
S
slguan 已提交
2798 2799 2800
      continue;
    }

H
Haojun Liao 已提交
2801
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2802 2803
      return false;
    }
H
Haojun Liao 已提交
2804 2805 2806 2807

    if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
      return false;
    }
H
hzcheng 已提交
2808 2809 2810 2811 2812
  }

  return true;
}

H
Haojun Liao 已提交
2813
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) {
2814 2815
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
2816
  const char* msg3 = "columns from one table allowed as group by columns";
2817
  const char* msg4 = "join query does not support group by";
S
slguan 已提交
2818 2819 2820
  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 已提交
2821

2822
  // todo : handle two tables situation
H
hjxilinx 已提交
2823
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2824 2825 2826 2827 2828

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

2829 2830 2831 2832
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
H
Haojun Liao 已提交
2833 2834
  pQueryInfo->groupbyExpr.numOfGroupCols = taosArrayGetSize(pList);
  if (pQueryInfo->groupbyExpr.numOfGroupCols > TSDB_MAX_TAGS) {
2835
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2836 2837
  }

2838 2839 2840 2841
  if (pQueryInfo->numOfTables > 1) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
  }

H
hjxilinx 已提交
2842
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2843
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2844
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2845

S
slguan 已提交
2846
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
H
Haojun Liao 已提交
2847 2848 2849 2850 2851 2852

  size_t num = taosArrayGetSize(pList);
  for (int32_t i = 0; i < num; ++i) {
    tVariantListItem * pItem = taosArrayGet(pList, i);
    tVariant* pVar = &pItem->pVar;

H
Haojun Liao 已提交
2853
    SStrToken token = {pVar->nLen, pVar->nType, pVar->pz};
H
hzcheng 已提交
2854

S
slguan 已提交
2855
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2856 2857
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2858
    }
H
hzcheng 已提交
2859

2860 2861 2862 2863 2864
    if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
      tableIndex = index.tableIndex;
    } else if (tableIndex != index.tableIndex) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2865

H
hjxilinx 已提交
2866
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2867
    pTableMeta = pTableMetaInfo->pTableMeta;
2868 2869
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2870 2871 2872
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2873
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2874
    }
H
hzcheng 已提交
2875

S
slguan 已提交
2876
    bool groupTag = false;
2877
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2878
      groupTag = true;
H
hzcheng 已提交
2879
    }
2880 2881 2882 2883 2884 2885
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2886
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2887
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2888
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
S
slguan 已提交
2889 2890
      }

2891 2892 2893 2894
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2895

H
hjxilinx 已提交
2896
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2897
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2898 2899 2900
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2901 2902
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
H
Haojun Liao 已提交
2903
      if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) {
2904
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
2905 2906
      }

2907
      tscColumnListInsert(pQueryInfo->colList, &index);
2908
      
2909
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2910
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2911
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2912

H
Haojun Liao 已提交
2913
      if (i == 0 && num > 1) {
2914
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2915
      }
H
hzcheng 已提交
2916 2917 2918
    }
  }

2919
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2920 2921 2922
  return TSDB_CODE_SUCCESS;
}

2923 2924
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2925
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2926
  } else {
H
hjxilinx 已提交
2927
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2928 2929 2930
  }
}

2931
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2932 2933 2934
  if (pColumn == NULL) {
    return NULL;
  }
2935

S
slguan 已提交
2936
  int32_t size = pColumn->numOfFilters + 1;
2937 2938

  char* tmp = (char*) realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2939 2940
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2941 2942
  } else {
    return NULL;
2943 2944
  }

S
slguan 已提交
2945
  pColumn->numOfFilters++;
2946

S
slguan 已提交
2947 2948 2949 2950
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2951 2952
}

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

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

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

S
slguan 已提交
2962
  int16_t colType = pSchema->type;
2963
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2964 2965 2966
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2967
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2968
    int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
2969 2970 2971
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2972 2973
  }

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

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

B
Bomin Zhang 已提交
2984 2985 2986 2987 2988 2989
  } else if (colType == TSDB_DATA_TYPE_NCHAR) {
    // pRight->val.nLen + 1 is larger than the actual nchar string length
    pColumnFilter->pz = (int64_t)calloc(1, (pRight->val.nLen + 1) * TSDB_NCHAR_SIZE);
    retVal = tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
    size_t len = twcslen((wchar_t*)pColumnFilter->pz);
    pColumnFilter->len = len * TSDB_NCHAR_SIZE;
S
slguan 已提交
2990

B
Bomin Zhang 已提交
2991 2992
  } else {
    retVal = tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
2993 2994
  }

B
Bomin Zhang 已提交
2995 2996 2997 2998
  if (retVal != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  } 

H
hzcheng 已提交
2999 3000
  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
3001
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
3002 3003
      break;
    case TK_LT:
S
slguan 已提交
3004
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
3005 3006
      break;
    case TK_GT:
3007
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
3008 3009
      break;
    case TK_GE:
3010
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
3011 3012
      break;
    case TK_EQ:
S
slguan 已提交
3013
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
3014 3015
      break;
    case TK_NE:
S
slguan 已提交
3016
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
3017 3018
      break;
    case TK_LIKE:
S
slguan 已提交
3019
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
3020
      break;
H
Haojun Liao 已提交
3021 3022 3023 3024 3025 3026
    case TK_ISNULL:
      pColumnFilter->lowerRelOptr = TSDB_RELATION_ISNULL;
      break;
    case TK_NOTNULL:
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOTNULL;
      break;
S
slguan 已提交
3027
    default:
3028
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
3029
  }
S
slguan 已提交
3030

3031
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3032 3033
}

S
slguan 已提交
3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047
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 已提交
3048

H
hjxilinx 已提交
3049
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
3050 3051

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
3052
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
3053 3054
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
3055 3056

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

H
hjxilinx 已提交
3059 3060 3061 3062 3063 3064 3065
  } 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 已提交
3066 3067 3068 3069 3070 3071
    assert(false);
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
3072
// pExpr->nSQLOptr == 0 while handling "is null" query
S
slguan 已提交
3073 3074
static bool isExprLeafNode(tSQLExpr* pExpr) {
  return (pExpr->pRight == NULL && pExpr->pLeft == NULL) &&
H
Haojun Liao 已提交
3075
         (pExpr->nSQLOptr == 0 || pExpr->nSQLOptr == TK_ID || (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_NCHAR) || pExpr->nSQLOptr == TK_SET);
S
slguan 已提交
3076 3077
}

H
Haojun Liao 已提交
3078
static bool isExprDirectParentOfLeafNode(tSQLExpr* pExpr) {
S
slguan 已提交
3079 3080 3081 3082 3083
  return (pExpr->pLeft != NULL && pExpr->pRight != NULL) &&
         (isExprLeafNode(pExpr->pLeft) && isExprLeafNode(pExpr->pRight));
}

static int32_t tSQLExprLeafToString(tSQLExpr* pExpr, bool addParentheses, char** output) {
H
Haojun Liao 已提交
3084
  if (!isExprDirectParentOfLeafNode(pExpr)) {
3085
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3086 3087
  }

S
slguan 已提交
3088 3089 3090 3091 3092 3093 3094 3095 3096 3097
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
3098
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3099 3100 3101 3102 3103 3104 3105 3106 3107
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
3108 3109 3110 3111
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
3112 3113 3114 3115
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163

  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:
3164
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3165 3166 3167 3168 3169 3170 3171
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3172
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
3173 3174
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
3175
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3176 3177
  }

S
slguan 已提交
3178
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
3179
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
3180 3181
  }

H
hzcheng 已提交
3182 3183
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
3184
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
3185 3186

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

H
Haojun Liao 已提交
3190
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
3191
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3192 3193 3194 3195 3196 3197
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3198
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
3199 3200
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
3201 3202

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3203 3204
}

S
slguan 已提交
3205 3206 3207 3208 3209 3210
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
3211

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

H
hjxilinx 已提交
3215 3216
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
3217

S
slguan 已提交
3218
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
3219 3220
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
3221

H
hjxilinx 已提交
3222
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235
  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];
    }
3236 3237 3238 3239

    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3240 3241 3242
  } else if (sqlOptr == TK_OR) {
    // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
    pColFilter = addColumnFilterInfo(pColumn);
3243 3244 3245
    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3246
  } else {  // error;
3247
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3248 3249
  }

3250
  pColFilter->filterstr =
S
slguan 已提交
3251 3252
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

3253
  if (pColFilter->filterstr) {
S
slguan 已提交
3254
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
3255
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3256
    }
S
slguan 已提交
3257 3258
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
3259
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
3260
    }
H
Hui Li 已提交
3261 3262 3263
    
    if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
      if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
3264
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Hui Li 已提交
3265 3266
      }
    }
S
slguan 已提交
3267 3268 3269
  }

  pColumn->colIndex = *pIndex;
3270
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
3271 3272
}

3273
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3274 3275 3276 3277 3278
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

3279
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
3280 3281 3282 3283 3284 3285 3286 3287 3288
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

3289
UNUSED_FUNC
3290
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3291 3292 3293 3294
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
3295
  if (!isExprDirectParentOfLeafNode(pExpr)) {
S
slguan 已提交
3296 3297
    *(*str) = '(';
    *str += 1;
H
hzcheng 已提交
3298

3299
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
3300
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3301
      return ret;
H
hzcheng 已提交
3302
    }
S
slguan 已提交
3303

3304
    relToString(pExpr, str);
S
slguan 已提交
3305

3306
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
3307 3308 3309 3310

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

H
hzcheng 已提交
3311 3312 3313
    return ret;
  }

S
slguan 已提交
3314 3315 3316
  return tSQLExprLeafToString(pExpr, true, str);
}

3317
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
3318 3319 3320 3321
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
3324 3325
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
3326

S
slguan 已提交
3327
  if (!isTablenameToken(&pLeft->colInfo)) {
3328
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3329 3330
  }

S
slguan 已提交
3331
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3332

S
slguan 已提交
3333
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
3334
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
3335
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3336
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
3337
  }
H
hzcheng 已提交
3338

S
slguan 已提交
3339
  if (ret != TSDB_CODE_SUCCESS) {
3340
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3341
  }
H
hzcheng 已提交
3342

S
slguan 已提交
3343 3344 3345
  return ret;
}

3346
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3347 3348 3349 3350
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
3351
  if (!isExprDirectParentOfLeafNode(pExpr)) {  // internal node
3352
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3353 3354 3355 3356
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3357
    return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3358 3359
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3360
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3361
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3362
    }
S
slguan 已提交
3363

3364
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3365
  }
S
slguan 已提交
3366
}
H
hzcheng 已提交
3367

3368
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
H
Haojun Liao 已提交
3369 3370 3371
  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 已提交
3372

S
slguan 已提交
3373 3374 3375
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3376

H
Haojun Liao 已提交
3377
  if (!isExprDirectParentOfLeafNode(pExpr)) {
3378
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3379 3380
  }

3381
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3382 3383 3384 3385
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3386 3387
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3388 3389
  }

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

3393
  pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3394
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3395
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3396 3397

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3398 3399
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3400 3401
  }

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

3405
  pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3406
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3407
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3408

H
Haojun Liao 已提交
3409
  if (pTagSchema1->type != pTagSchema2->type) {
3410
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3411 3412
  }

S
slguan 已提交
3413
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3414 3415 3416 3417
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3422
  *(*exprString)++ = '(';
H
hzcheng 已提交
3423 3424

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3425
    doArithmeticExprToString(pLeft, exprString);
H
hzcheng 已提交
3426
  } else {
S
slguan 已提交
3427
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3428
    if (ret != TSDB_CODE_SUCCESS) {
3429
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3430 3431 3432 3433 3434 3435
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3436
    doArithmeticExprToString(pRight, exprString);
H
hzcheng 已提交
3437
  } else {
S
slguan 已提交
3438
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3439
    if (ret != TSDB_CODE_SUCCESS) {
3440
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3441 3442 3443
    }
  }

H
hjxilinx 已提交
3444
  *(*exprString)++ = ')';
H
hzcheng 已提交
3445 3446 3447 3448

  return TSDB_CODE_SUCCESS;
}

3449 3450
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList,
    int32_t* type, uint64_t* uid) {
H
hzcheng 已提交
3451
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3452 3453 3454
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
3455
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3456
    }
L
lihui 已提交
3457

H
hjxilinx 已提交
3458
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3459
    if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3460
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3461 3462 3463
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3464
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3465 3466
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3467 3468
    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)) {
3469
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3470 3471 3472
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3473
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
3474
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3475 3476 3477 3478
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
3479
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3480 3481
    }

S
TD-1057  
Shengliang Guan 已提交
3482
    int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
3483
  
H
hjxilinx 已提交
3484 3485
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
H
Haojun Liao 已提交
3486 3487
    // sql function list in selection clause.
    // Append the sqlExpr into exprList of pQueryInfo structure sequentially
3488
    if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
3489
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3490
    }
H
Haojun Liao 已提交
3491 3492 3493 3494 3495 3496 3497 3498

    // It is invalid in case of more than one sqlExpr, such as first(ts, k) - last(ts, k)
    int32_t inc = (int32_t) tscSqlExprNumOfExprs(pQueryInfo) - outputIndex;
    if (inc > 1) {
      return TSDB_CODE_TSC_INVALID_SQL;
    }

    // Not supported data type in arithmetic expression
3499
    uint64_t id = -1;
H
Haojun Liao 已提交
3500 3501 3502 3503 3504 3505
    for(int32_t i = 0; i < inc; ++i) {
      SSqlExpr* p1 = tscSqlExprGet(pQueryInfo, i + outputIndex);
      int16_t t = p1->resType;
      if (t == TSDB_DATA_TYPE_BINARY || t == TSDB_DATA_TYPE_NCHAR || t == TSDB_DATA_TYPE_BOOL || t == TSDB_DATA_TYPE_TIMESTAMP) {
        return TSDB_CODE_TSC_INVALID_SQL;
      }
3506 3507 3508 3509 3510 3511

      if (i == 0) {
        id = p1->uid;
      } else if (id != p1->uid){
        return TSDB_CODE_TSC_INVALID_SQL;
      }
H
Haojun Liao 已提交
3512
    }
3513 3514

    *uid = id;
H
hzcheng 已提交
3515 3516 3517 3518 3519
  }

  return TSDB_CODE_SUCCESS;
}

3520
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3521 3522 3523 3524 3525
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
3526 3527 3528
  uint64_t uidLeft = 0;
  uint64_t uidRight = 0;

H
hzcheng 已提交
3529
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3530
    int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3531 3532 3533 3534
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3535
    int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type, &uidLeft);
H
hzcheng 已提交
3536 3537 3538 3539 3540 3541 3542
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3543
    int32_t ret = validateArithmeticSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3544 3545 3546 3547
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3548
    int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type, &uidRight);
H
hzcheng 已提交
3549 3550 3551
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
3552 3553

    // the expression not from the same table, return error
3554
    if (uidLeft != uidRight && uidLeft != 0 && uidRight != 0) {
3555 3556
      return TSDB_CODE_TSC_INVALID_SQL;
    }
H
hzcheng 已提交
3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568
  }

  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 已提交
3569 3570 3571
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3572 3573 3574
   *
   * However, columnA < 4+12 is valid
   */
B
Bomin Zhang 已提交
3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590
  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 已提交
3591 3592 3593 3594 3595 3596
    return false;
  }

  return true;
}

S
slguan 已提交
3597 3598 3599
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3600

S
slguan 已提交
3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625
  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 已提交
3626

S
slguan 已提交
3627 3628 3629 3630 3631
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3632
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645
  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) {
3646
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3647 3648 3649 3650 3651
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3652 3653
  if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3654
    return false;
H
hzcheng 已提交
3655 3656
  }

S
slguan 已提交
3657
  // todo extract function
H
hjxilinx 已提交
3658
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3659
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3660 3661
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3662
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3663
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3664 3665 3666
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3667
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3668 3669
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3670
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3671
    return false;
H
hzcheng 已提交
3672 3673
  }

S
slguan 已提交
3674
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3675
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3676
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
S
slguan 已提交
3677 3678
    return false;
  }
H
hzcheng 已提交
3679

S
slguan 已提交
3680 3681
  return true;
}
H
hzcheng 已提交
3682

S
slguan 已提交
3683 3684 3685 3686 3687 3688
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 已提交
3689 3690 3691
    }
  }

S
slguan 已提交
3692
  return false;
H
hzcheng 已提交
3693 3694
}

3695
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3696 3697
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3698
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3699
    }
H
hzcheng 已提交
3700

S
slguan 已提交
3701 3702 3703 3704
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3705

S
slguan 已提交
3706 3707
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3708

3709 3710
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                                     int32_t* type, int32_t parentOptr) {
3711
  const char* msg1 = "table query cannot use tags filter";
S
slguan 已提交
3712 3713 3714
  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 已提交
3715 3716 3717
  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";
3718 3719
  const char* msg8 = "wildcard string should be less than 20 characters";
  
S
slguan 已提交
3720 3721
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3722

S
slguan 已提交
3723 3724 3725
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3726 3727
  if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3728 3729
  }

H
Haojun Liao 已提交
3730
  assert(isExprDirectParentOfLeafNode(*pExpr));
S
slguan 已提交
3731

H
hjxilinx 已提交
3732
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3733
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3734 3735

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3736
    if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3737
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3738
    }
S
slguan 已提交
3739 3740 3741

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
H
hjxilinx 已提交
3742
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
S
slguan 已提交
3743 3744 3745 3746 3747 3748 3749 3750
      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 {
3751
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3752 3753 3754 3755
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3756 3757
  } 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 已提交
3758
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3759
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3760 3761 3762 3763 3764
    }

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

H
hjxilinx 已提交
3768
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3769 3770 3771

      if ((!isTablenameToken(&pLeft->colInfo)) && pSchema[index.columnIndex].type != TSDB_DATA_TYPE_BINARY &&
          pSchema[index.columnIndex].type != TSDB_DATA_TYPE_NCHAR) {
3772
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3773 3774 3775
      }
    }

H
Haojun Liao 已提交
3776
    // in case of in operator, keep it in a seprate attribute
S
slguan 已提交
3777 3778
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3779
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
3780
      }
3781 3782
  
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
3783
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
3784
      }
S
slguan 已提交
3785 3786 3787 3788 3789 3790

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3791
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
3792 3793 3794 3795 3796
      }

      *type = TSQL_EXPR_TBNAME;
      *pExpr = NULL;
    } else {
H
Haojun Liao 已提交
3797
      if (pRight != NULL && pRight->nSQLOptr == TK_ID) {  // join on tag columns for stable query
3798
        if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3799
          return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3800 3801 3802
        }

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

3806 3807
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821
        *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
3822
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
3823 3824
    }

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

S
slguan 已提交
3829
  return ret;
H
hzcheng 已提交
3830 3831
}

3832 3833
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                        int32_t* type, int32_t parentOptr) {
H
hzcheng 已提交
3834 3835 3836 3837
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3840 3841 3842 3843
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3844
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3845 3846
  }

S
slguan 已提交
3847 3848
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3849

H
Haojun Liao 已提交
3850
  if (!isExprDirectParentOfLeafNode(*pExpr)) {
3851
    int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3852 3853 3854 3855
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3856
    ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3857 3858 3859
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3860

S
slguan 已提交
3861 3862 3863 3864 3865 3866
    /*
     *  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)) {
3867
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3868
      }
H
hzcheng 已提交
3869 3870
    }

S
slguan 已提交
3871 3872 3873
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3874

S
slguan 已提交
3875
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3876

3877
  return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3878
}
H
hzcheng 已提交
3879

S
slguan 已提交
3880
static void doCompactQueryExpr(tSQLExpr** pExpr) {
3881
  if (*pExpr == NULL || isExprDirectParentOfLeafNode(*pExpr)) {
S
slguan 已提交
3882 3883
    return;
  }
H
hzcheng 已提交
3884

S
slguan 已提交
3885 3886 3887
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3888

S
slguan 已提交
3889 3890 3891
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3892

S
slguan 已提交
3893 3894 3895 3896
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3897

S
slguan 已提交
3898 3899 3900
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3901

S
slguan 已提交
3902 3903 3904 3905
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3906

S
slguan 已提交
3907
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3908
  }
S
slguan 已提交
3909
}
H
hzcheng 已提交
3910

3911
static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
H
Haojun Liao 已提交
3912
  if (isExprDirectParentOfLeafNode(*pExpr)) {
S
slguan 已提交
3913 3914 3915
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3916
    if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3917
      return;
H
hzcheng 已提交
3918 3919
    }

S
slguan 已提交
3920 3921 3922 3923
    if (index.tableIndex != tableIndex) {
      return;
    }

H
Haojun Liao 已提交
3924
    SStrToken t = {0};
S
slguan 已提交
3925 3926 3927 3928 3929 3930 3931 3932
    extractTableNameFromToken(&pLeft->colInfo, &t);

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

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

3933 3934
    doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3935 3936 3937
  }
}

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

S
slguan 已提交
3941
  if (*pExpr != NULL) {
3942
    doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3943
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3944 3945
  }

S
slguan 已提交
3946
  return pResExpr;
H
hzcheng 已提交
3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961
}

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

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

S
slguan 已提交
3966 3967 3968 3969
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3972
  STagCond* pTagCond = &pQueryInfo->tagCond;
3973
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
S
slguan 已提交
3974 3975 3976 3977

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3978
    char* str = taosStringBuilderGetResult(sb, NULL);
3979
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3980 3981 3982
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
3983
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
3984
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3985

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

S
slguan 已提交
3988
  // remove the duplicated input table names
H
hzcheng 已提交
3989
  int32_t num = 0;
H
hjxilinx 已提交
3990 3991 3992
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3993
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3994 3995 3996 3997 3998 3999 4000 4001 4002

  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 已提交
4003
  char* name = extractDBName(pTableMetaInfo->name, db);
H
Haojun Liao 已提交
4004
  SStrToken dbToken = { .type = TK_STRING, .z = name, .n = (uint32_t)strlen(name) };
H
hjxilinx 已提交
4005
  
H
hzcheng 已提交
4006 4007
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
4008
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
4009
    }
H
hjxilinx 已提交
4010

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

4015
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
4016
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4017
      taosStringBuilderDestroy(&sb1);
S
TD-1848  
Shengliang Guan 已提交
4018
      tfree(segments);
H
hjxilinx 已提交
4019

4020
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4021 4022
      return ret;
    }
H
hjxilinx 已提交
4023

H
hjxilinx 已提交
4024
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
4025
  }
H
hjxilinx 已提交
4026

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

H
hjxilinx 已提交
4030
  taosStringBuilderDestroy(&sb1);
S
TD-1848  
Shengliang Guan 已提交
4031
  tfree(segments);
H
hzcheng 已提交
4032 4033 4034
  return TSDB_CODE_SUCCESS;
}

4035
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
4036 4037 4038 4039 4040 4041
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
4042

4043 4044
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
4045 4046
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
4047

4048
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062
          (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;
}

4063
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
4064 4065
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
4066 4067 4068 4069 4070

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

H
Haojun Liao 已提交
4071
  if (!isExprDirectParentOfLeafNode(pExpr)) {
S
slguan 已提交
4072
    if (pExpr->nSQLOptr == TK_OR) {
4073
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4074
    }
H
hzcheng 已提交
4075

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

4078
    return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
S
slguan 已提交
4079 4080
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
4081
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4082
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4083 4084
    }

H
hjxilinx 已提交
4085
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4086
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4087
    
S
slguan 已提交
4088 4089
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
4090 4091
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
4092
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
4093 4094 4095
    }

    // update the timestamp query range
H
hjxilinx 已提交
4096 4097
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
4098 4099
    }

H
hjxilinx 已提交
4100 4101
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
4102 4103 4104 4105 4106 4107
    }
  }

  return TSDB_CODE_SUCCESS;
}

4108
static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
4109 4110 4111 4112
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

4113 4114
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
4115 4116
      return TSDB_CODE_SUCCESS;
    } else {
4117
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
4118 4119 4120
    }
  }

H
hjxilinx 已提交
4121
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
4122
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // for stable join, tag columns
4123
                                                   // must be present for join
S
slguan 已提交
4124
    if (pCondExpr->pJoinExpr == NULL) {
4125
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4126 4127 4128 4129
    }
  }

  if (!pCondExpr->tsJoin) {
4130
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4131 4132
  }

S
slguan 已提交
4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157
  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);
  }
}

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

4163
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
4164 4165
      tscError("%p: invalid column name (left)", pQueryInfo);
    }
H
hjxilinx 已提交
4166
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4167 4168
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4169 4170
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
  
4171
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
4172 4173
      tscError("%p: invalid column name (right)", pQueryInfo);
    }
H
hjxilinx 已提交
4174
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4175 4176
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4177
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
4178
  }
H
hjxilinx 已提交
4179
}
S
slguan 已提交
4180

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

4184 4185 4186 4187 4188
  if (pCondExpr->pTagCond == NULL) {
    return ret;
  }
  
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
4189
    tSQLExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
H
Haojun Liao 已提交
4190 4191 4192 4193
    if (p1 == NULL) {  // no query condition on this table
      continue;
    }

4194
    tExprNode* p = NULL;
4195 4196
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
H
Haojun Liao 已提交
4197
    ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL);
4198 4199 4200 4201 4202 4203 4204 4205 4206
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
4207
    
4208 4209
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
4210
    int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
4211 4212 4213 4214 4215 4216
    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 已提交
4217
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
4218 4219
    }
    
4220
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
4221 4222 4223 4224
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
4225 4226
    
    taosArrayDestroy(colList);
H
hjxilinx 已提交
4227
  }
H
hjxilinx 已提交
4228

4229
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
4230 4231
  return ret;
}
4232
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
4233 4234 4235
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
4236

H
hjxilinx 已提交
4237
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
4238
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
4239

H
hjxilinx 已提交
4240
  int32_t ret = TSDB_CODE_SUCCESS;
S
slguan 已提交
4241

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

H
hjxilinx 已提交
4246
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
4247
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
S
slguan 已提交
4248 4249
  }

H
hjxilinx 已提交
4250
  int32_t type = 0;
4251
  if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4252 4253
    return ret;
  }
H
hjxilinx 已提交
4254

S
slguan 已提交
4255
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
4256

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

S
slguan 已提交
4260
  // 1. check if it is a join query
4261
  if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4262 4263
    return ret;
  }
H
hjxilinx 已提交
4264

S
slguan 已提交
4265
  // 2. get the query time range
4266
  if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4267 4268
    return ret;
  }
H
hjxilinx 已提交
4269

S
slguan 已提交
4270
  // 3. get the tag query condition
4271
  if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4272
    return ret;
S
slguan 已提交
4273
  }
H
hjxilinx 已提交
4274

S
slguan 已提交
4275
  // 4. get the table name query condition
4276
  if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4277 4278
    return ret;
  }
H
hjxilinx 已提交
4279

S
slguan 已提交
4280
  // 5. other column query condition
4281
  if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4282 4283
    return ret;
  }
H
hjxilinx 已提交
4284

S
slguan 已提交
4285
  // 6. join condition
4286
  if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4287
    return ret;
H
hzcheng 已提交
4288
  }
H
hjxilinx 已提交
4289

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

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

4296
  if (!validateFilterExpr(pQueryInfo)) {
4297
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
4298
  }
H
hjxilinx 已提交
4299

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

H
hjxilinx 已提交
4302
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
4303 4304 4305
  return ret;
}

H
hjxilinx 已提交
4306
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
4307 4308 4309 4310 4311
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
4312 4313
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
4314
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
4315 4316
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
4317
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4318
  }
H
hzcheng 已提交
4319 4320 4321 4322

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

S
slguan 已提交
4325
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
4326
    if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
4327
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4328 4329
        parsed = true;
      } else {
4330
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4331
      }
S
slguan 已提交
4332
    } else {
H
Haojun Liao 已提交
4333
      SStrToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
S
slguan 已提交
4334 4335 4336
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
4337
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4338
      }
H
hzcheng 已提交
4339 4340 4341 4342
    }
  } 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 已提交
4343
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358
     *
     * 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
     */
4359
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380

    /*
     * 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 已提交
4381
    win->ekey = val;
H
hzcheng 已提交
4382
  } else if (optr == TK_LT) {
H
hjxilinx 已提交
4383
    win->ekey = val - delta;
H
hzcheng 已提交
4384
  } else if (optr == TK_GT) {
H
hjxilinx 已提交
4385
    win->skey = val + delta;
H
hzcheng 已提交
4386
  } else if (optr == TK_GE) {
H
hjxilinx 已提交
4387
    win->skey = val;
H
hzcheng 已提交
4388
  } else if (optr == TK_EQ) {
H
hjxilinx 已提交
4389
    win->ekey = win->skey = val;
H
hzcheng 已提交
4390 4391 4392 4393
  }
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
4398 4399
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
B
Bomin Zhang 已提交
4400
    for (int32_t j = 0; j < (TSDB_COL_NAME_LEN - 1) && fieldName[j] != 0; ++j) {
S
slguan 已提交
4401 4402 4403 4404 4405
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
4406 4407
      }
    }
S
slguan 已提交
4408

H
hzcheng 已提交
4409 4410 4411 4412
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4413 4414 4415
  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 已提交
4416
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4417
        const char* msg = "duplicated column name in new table";
4418
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4419 4420 4421 4422 4423 4424 4425
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4426
int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
Haojun Liao 已提交
4427 4428
  SArray*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = taosArrayGet(pFillToken, 0);
H
hzcheng 已提交
4429 4430

  const int32_t START_INTERPO_COL_IDX = 1;
4431 4432 4433 4434

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

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4437
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4438
  }
H
hjxilinx 已提交
4439 4440 4441
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
4442 4443 4444
  if (pQueryInfo->fillVal == NULL) {
    pQueryInfo->fillVal = calloc(size, sizeof(int64_t));
    if (pQueryInfo->fillVal == NULL) {
4445
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4446 4447 4448
    }
  }

H
hzcheng 已提交
4449
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4450
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4451
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4452
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4453 4454
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
4455 4456 4457 4458 4459
      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 已提交
4460 4461
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4462
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4463
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4464
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4465
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4466
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4467

H
Haojun Liao 已提交
4468 4469
    size_t num = taosArrayGetSize(pFillToken);
    if (num == 1) {
4470
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4471 4472 4473
    }

    int32_t startPos = 1;
H
Haojun Liao 已提交
4474
    int32_t numOfFillVal = num - 1;
H
hzcheng 已提交
4475 4476

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

H
hjxilinx 已提交
4480
      if (numOfFillVal > size) {
S
TD-1057  
Shengliang Guan 已提交
4481
        numOfFillVal = (int32_t)size;
H
hzcheng 已提交
4482 4483
      }
    } else {
H
Haojun Liao 已提交
4484
      numOfFillVal = (num >  (int32_t)size) ? (int32_t)size : num;
H
hzcheng 已提交
4485 4486 4487 4488 4489
    }

    int32_t j = 1;

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

4492
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4493
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
4494 4495
        continue;
      }
H
hjxilinx 已提交
4496

H
Haojun Liao 已提交
4497 4498
      tVariant* p = taosArrayGet(pFillToken, j);
      int32_t ret = tVariantDump(p, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4499
      if (ret != TSDB_CODE_SUCCESS) {
4500
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4501 4502
      }
    }
H
hjxilinx 已提交
4503
    
H
Haojun Liao 已提交
4504 4505
    if ((num < size) || ((num - 1 < size) && (tscIsPointInterpQuery(pQueryInfo)))) {
      tVariantListItem* lastItem = taosArrayGetLast(pFillToken);
H
hzcheng 已提交
4506

H
hjxilinx 已提交
4507 4508
      for (int32_t i = numOfFillVal; i < size; ++i) {
        TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4509 4510

        if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4511
          setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
H
hjxilinx 已提交
4512
        } else {
4513
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4514 4515 4516 4517
        }
      }
    }
  } else {
4518
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4519 4520 4521 4522 4523
  }

  return TSDB_CODE_SUCCESS;
}

4524
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4525
  /* set default timestamp order information for all queries */
H
hjxilinx 已提交
4526
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4527

H
Haojun Liao 已提交
4528
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
4529 4530 4531 4532 4533
  if (isTopBottomQuery(pQueryInfo)) {
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
  } else { // in case of select tbname from super_table, the defualt order column can not be the primary ts column
    pQueryInfo->order.orderColId = INT32_MIN;
  }
H
hzcheng 已提交
4534

H
hjxilinx 已提交
4535
  /* for super table query, set default ascending order for group output */
weixin_48148422's avatar
weixin_48148422 已提交
4536
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
4537
    pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
H
hzcheng 已提交
4538 4539 4540
  }
}

4541
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4542 4543
  const char* msg0 = "only support order by primary timestamp";
  const char* msg1 = "invalid column name";
4544 4545
  const char* msg2 = "only support order by primary timestamp or queried column";
  const char* msg3 = "only support order by primary timestamp or first tag in groupby clause";
H
hzcheng 已提交
4546

4547
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4548
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4549 4550 4551 4552 4553

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

H
Haojun Liao 已提交
4554
  SArray* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4555 4556 4557 4558 4559 4560 4561

  /*
   * 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.
   */
H
Haojun Liao 已提交
4562
  size_t size = taosArrayGetSize(pSortorder);
weixin_48148422's avatar
weixin_48148422 已提交
4563
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
Haojun Liao 已提交
4564
    if (size > 1) {
4565
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4566 4567
    }
  } else {
H
Haojun Liao 已提交
4568
    if (size > 2) {
4569
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4570 4571 4572 4573
    }
  }

  // handle the first part of order by
H
Haojun Liao 已提交
4574
  tVariant* pVar = taosArrayGet(pSortorder, 0);
H
hzcheng 已提交
4575 4576 4577 4578 4579 4580

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

weixin_48148422's avatar
weixin_48148422 已提交
4584
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4585 4586
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4587 4588 4589 4590
    }

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

H
hjxilinx 已提交
4592 4593
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4594
      
4595 4596
      // it is a tag column
      if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
4597
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4598
      }
4599 4600
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (relTagIndex == pColIndex->colIndex) {
H
hzcheng 已提交
4601 4602
        orderByTags = true;
      }
S
slguan 已提交
4603 4604
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4605 4606
    }

S
slguan 已提交
4607
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4608 4609 4610
      orderByTS = true;
    }

4611
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
4612
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4613 4614 4615 4616
    } else {
      assert(!(orderByTags && orderByTS));
    }

H
Haojun Liao 已提交
4617 4618
    size_t s = taosArrayGetSize(pSortorder);
    if (s == 1) {
H
hzcheng 已提交
4619
      if (orderByTags) {
H
hjxilinx 已提交
4620
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
Haojun Liao 已提交
4621 4622 4623

        tVariantListItem* p1 = taosArrayGet(pQuerySql->pSortOrder, 0);
        pQueryInfo->groupbyExpr.orderType = p1->sortOrder;
4624
      } else if (isTopBottomQuery(pQueryInfo)) {
S
slguan 已提交
4625
        /* order of top/bottom query in interval is not valid  */
4626
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4627 4628
        assert(pExpr->functionId == TSDB_FUNC_TS);

4629
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4630
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4631
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
4632
        }
4633

H
Haojun Liao 已提交
4634 4635
        tVariantListItem* p1 = taosArrayGet(pQuerySql->pSortOrder, 0);
        pQueryInfo->order.order = p1->sortOrder;
4636
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4637
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4638
      } else {
H
Haojun Liao 已提交
4639 4640 4641
        tVariantListItem* p1 = taosArrayGet(pQuerySql->pSortOrder, 0);

        pQueryInfo->order.order = p1->sortOrder;
4642
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
Haojun Liao 已提交
4643 4644 4645 4646 4647

        // orderby ts query on super table
        if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
          addPrimaryTsColIntoResult(pQueryInfo);
        }
H
hzcheng 已提交
4648 4649 4650
      }
    }

H
Haojun Liao 已提交
4651 4652
    if (s == 2) {
      tVariantListItem *pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
S
slguan 已提交
4653
      if (orderByTags) {
H
hjxilinx 已提交
4654
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
Haojun Liao 已提交
4655
        pQueryInfo->groupbyExpr.orderType = pItem->sortOrder;
S
slguan 已提交
4656
      } else {
H
Haojun Liao 已提交
4657
        pQueryInfo->order.order = pItem->sortOrder;
4658
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4659 4660
      }

H
Haojun Liao 已提交
4661 4662
      pItem = taosArrayGet(pQuerySql->pSortOrder, 1);
      tVariant* pVar2 = &pItem->pVar;
H
Haojun Liao 已提交
4663
      SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4664 4665
      if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4666 4667 4668
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4669
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4670
      } else {
H
Haojun Liao 已提交
4671 4672
        tVariantListItem* p1 = taosArrayGet(pSortorder, 1);
        pQueryInfo->order.order = p1->sortOrder;
4673
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4674 4675 4676 4677
      }
    }

  } else {  // meter query
4678 4679
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4680 4681
    }

4682
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
4683
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4684 4685
    }

4686
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4687
      /* order of top/bottom query in interval is not valid  */
4688
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4689
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4690

4691
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4692
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4693
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4694
      }
4695

H
Haojun Liao 已提交
4696 4697
      tVariantListItem* pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
      pQueryInfo->order.order = pItem->sortOrder;
4698
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4699 4700
      return TSDB_CODE_SUCCESS;
    }
4701

H
Haojun Liao 已提交
4702 4703
    tVariantListItem* pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
    pQueryInfo->order.order = pItem->sortOrder;
H
hzcheng 已提交
4704 4705 4706 4707 4708 4709
  }

  return TSDB_CODE_SUCCESS;
}

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

4712 4713 4714 4715 4716
  const char* msg1 = "invalid table name";
  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 已提交
4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731
  
  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 已提交
4732 4733
  const char* msg19 = "invalid new tag name";

H
Haojun Liao 已提交
4734 4735
  int32_t code = TSDB_CODE_SUCCESS;

S
slguan 已提交
4736
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4737
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4738 4739
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4742
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4743
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
4744
  }
P
plum-lihui 已提交
4745

H
Haojun Liao 已提交
4746 4747 4748
  code = tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
H
hzcheng 已提交
4749 4750
  }

H
Haojun Liao 已提交
4751 4752 4753
  code = tscGetTableMeta(pSql, pTableMetaInfo);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
H
hzcheng 已提交
4754 4755
  }

H
hjxilinx 已提交
4756
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4757

4758 4759
  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 已提交
4760
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
4761
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4762
    }
weixin_48148422's avatar
weixin_48148422 已提交
4763
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) {
4764
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
4765
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4766
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4767
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
4768 4769
  }

4770
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
Haojun Liao 已提交
4771 4772
    SArray* pFieldList = pAlterSQL->pAddColumns;
    if (taosArrayGetSize(pFieldList) > 1) {
4773
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
4774 4775
    }

H
Haojun Liao 已提交
4776 4777
    TAOS_FIELD* p = taosArrayGet(pFieldList, 0);
    if (!validateOneTags(pCmd, p)) {
4778
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4779
    }
H
hjxilinx 已提交
4780
  
H
Haojun Liao 已提交
4781
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p);
4782
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
H
hjxilinx 已提交
4783
    if (tscGetNumOfTags(pTableMeta) == 1) {
4784
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
4785 4786 4787
    }

    // numOfTags == 1
H
Haojun Liao 已提交
4788
    if (taosArrayGetSize(pAlterSQL->varList) > 1) {
4789
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
hzcheng 已提交
4790 4791
    }

H
Haojun Liao 已提交
4792
    tVariantListItem* pItem = taosArrayGet(pAlterSQL->varList, 0);
B
Bomin Zhang 已提交
4793
    if (pItem->pVar.nLen >= TSDB_COL_NAME_LEN) {
4794
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4795
    }
4796

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

4800
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4801
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4802 4803
    }

H
Haojun Liao 已提交
4804 4805
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
4806
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
H
Haojun Liao 已提交
4807
    } else if (index.columnIndex == numOfCols) {
4808
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
H
hzcheng 已提交
4809 4810
    }

4811 4812
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4813 4814 4815
  
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4816
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
Haojun Liao 已提交
4817 4818
    SArray* pVarList = pAlterSQL->varList;
    if (taosArrayGetSize(pVarList) > 2) {
4819
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4820 4821
    }

H
Haojun Liao 已提交
4822 4823
    tVariantListItem* pSrcItem = taosArrayGet(pAlterSQL->varList, 0);
    tVariantListItem* pDstItem = taosArrayGet(pAlterSQL->varList, 1);
4824 4825

    if (pSrcItem->pVar.nLen >= TSDB_COL_NAME_LEN || pDstItem->pVar.nLen >= TSDB_COL_NAME_LEN) {
4826
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4827 4828
    }

4829
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4830
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
4831
    }
H
hzcheng 已提交
4832

S
slguan 已提交
4833 4834
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4835

H
Haojun Liao 已提交
4836
    SStrToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4837
    if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4838
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4839 4840
    }

H
Haojun Liao 已提交
4841
    SStrToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4842
    if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4843
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
H
hzcheng 已提交
4844 4845
    }

H
Haojun Liao 已提交
4846 4847
    tVariantListItem* pItem = taosArrayGet(pVarList, 0);

B
Bomin Zhang 已提交
4848
    char name[TSDB_COL_NAME_LEN] = {0};
H
Haojun Liao 已提交
4849
    strncpy(name, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4850 4851
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4852

H
Haojun Liao 已提交
4853
    pItem = taosArrayGet(pVarList, 1);
H
hzcheng 已提交
4854
    memset(name, 0, tListLen(name));
H
Haojun Liao 已提交
4855 4856

    strncpy(name, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4857 4858
    f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4859 4860
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
    // Note: update can only be applied to table not super table.
4861 4862 4863
    // the following is used to handle tags value for table created according to super table
    pCmd->command = TSDB_SQL_UPDATE_TAGS_VAL;
    
H
Haojun Liao 已提交
4864 4865
    SArray* pVarList = pAlterSQL->varList;
    tVariantListItem* item = taosArrayGet(pVarList, 0);
4866
    int16_t       numOfTags = tscGetNumOfTags(pTableMeta);
H
hzcheng 已提交
4867

4868
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4869
    SStrToken    name = {.type = TK_STRING, .z = item->pVar.pz, .n = item->pVar.nLen};
4870
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4871
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4872 4873
    }

H
hjxilinx 已提交
4874
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4875
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12);
S
slguan 已提交
4876 4877
    }

H
Haojun Liao 已提交
4878
    tVariantListItem* pItem = taosArrayGet(pVarList, 1);
H
hjxilinx 已提交
4879
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
H
Haojun Liao 已提交
4880
    if (tVariantDump(&pItem->pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) {
4881
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg13);
H
hzcheng 已提交
4882
    }
4883
    
4884
    pAlterSQL->tagData.dataLen = pTagsSchema->bytes;
H
hzcheng 已提交
4885 4886

    // validate the length of binary
4887
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
H
Haojun Liao 已提交
4888
        varDataTLen(pAlterSQL->tagData.data) > pTagsSchema->bytes) {
4889
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg14);
H
hzcheng 已提交
4890
    }
4891 4892 4893 4894

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

4895 4896
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4897
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4898 4899
    }

4900
    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
4901
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
4902 4903
    pUpdateMsg->tid       = htonl(pTableMeta->id.tid);
    pUpdateMsg->uid       = htobe64(pTableMeta->id.uid);
H
Haojun Liao 已提交
4904
    pUpdateMsg->colId     = htons(pTagsSchema->colId);
H
Hongze Cheng 已提交
4905
    pUpdateMsg->type      = pTagsSchema->type;
H
Haojun Liao 已提交
4906 4907
    pUpdateMsg->bytes     = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion  = htons(pTableMeta->tversion);
4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924
    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
H
Haojun Liao 已提交
4925 4926
    pItem = taosArrayGet(pVarList, 1);
    tVariantDump(&pItem->pVar, pUpdateMsg->data + schemaLen, pTagsSchema->type, true);
4927 4928 4929 4930 4931
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
4932
      len = varDataTLen(pUpdateMsg->data + schemaLen);
4933 4934 4935 4936
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
4937
    int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen;
4938
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4939
    
4940
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
Haojun Liao 已提交
4941 4942
    SArray* pFieldList = pAlterSQL->pAddColumns;
    if (taosArrayGetSize(pFieldList) > 1) {
4943
      const char* msg = "only support add one column";
4944
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4945 4946
    }

H
Haojun Liao 已提交
4947 4948
    TAOS_FIELD* p = taosArrayGet(pFieldList, 0);
    if (!validateOneColumn(pCmd, p)) {
4949
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4950
    }
H
hjxilinx 已提交
4951
  
H
Haojun Liao 已提交
4952
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p);
4953
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
H
hjxilinx 已提交
4954
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
H
hjxilinx 已提交
4955
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15);
H
hzcheng 已提交
4956 4957
    }

H
Haojun Liao 已提交
4958 4959
    size_t size = taosArrayGetSize(pAlterSQL->varList);
    if (size > 1) {
H
hjxilinx 已提交
4960
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4961 4962
    }

H
Haojun Liao 已提交
4963
    tVariantListItem* pItem = taosArrayGet(pAlterSQL->varList, 0);
H
hzcheng 已提交
4964

4965
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4966
    SStrToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4967 4968
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4969 4970
    }

4971
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4972
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18);
4973
    }
H
hzcheng 已提交
4974

B
Bomin Zhang 已提交
4975 4976
    char name1[TSDB_COL_NAME_LEN] = {0};
    tstrncpy(name1, pItem->pVar.pz, sizeof(name1));
H
hjxilinx 已提交
4977 4978
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4979 4980 4981 4982 4983
  }

  return TSDB_CODE_SUCCESS;
}

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

4988 4989 4990
  if (pQueryInfo->interval.interval != 0 && pQueryInfo->interval.interval < 10 &&
     pQueryInfo->interval.intervalUnit != 'n' &&
     pQueryInfo->interval.intervalUnit != 'y') {
4991
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4992
  }
H
hjxilinx 已提交
4993
  
H
hjxilinx 已提交
4994
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4995
  for (int32_t i = 0; i < size; ++i) {
4996
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
4997
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
4998
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4999 5000 5001 5002 5003 5004
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
5009
  // multi-output set/ todo refactor
H
hjxilinx 已提交
5010
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5011 5012
  
  for (int32_t k = 0; k < size; ++k) {
5013
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
5014

5015 5016 5017
    // 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 已提交
5018
      for (int32_t j = 0; j < size; ++j) {
5019
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
5020 5021 5022 5023 5024
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
5025

5026 5027 5028 5029
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
5030

5031
    if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
5032
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
5033 5034 5035
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
5036 5037

  if (isProjectionFunction) {
5038
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
5039 5040
  }

5041
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5042 5043 5044
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
5045 5046
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
5047 5048
} SDNodeDynConfOption;

H
Hui Li 已提交
5049

5050
int32_t validateEp(char* ep) {  
H
Hui Li 已提交
5051 5052 5053
  char buf[TSDB_EP_LEN + 1] = {0};
  tstrncpy(buf, ep, TSDB_EP_LEN);

5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064
  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 已提交
5065 5066
  }

5067
  return TSDB_CODE_SUCCESS;
H
Hui Li 已提交
5068 5069
}

H
hzcheng 已提交
5070 5071
int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
5072
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5073 5074
  }

5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085
  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},
S
TD-1520  
Shengliang Guan 已提交
5086
      {"cqDebugFlag", 11},
5087
  };
H
hzcheng 已提交
5088

H
Haojun Liao 已提交
5089
  SStrToken* pOptionToken = &pOptions->a[1];
H
hzcheng 已提交
5090 5091 5092

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
5093 5094
    for (int32_t i = 0; i < tokenLogEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
5095 5096 5097 5098
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
5099 5100
  } else if ((strncasecmp(cfgOptions[tokenBalance].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenBalance].len == pOptionToken->n)) {
H
Haojun Liao 已提交
5101
    SStrToken* pValToken = &pOptions->a[2];
S
Shengliang Guan 已提交
5102 5103
    int32_t vnodeId = 0;
    int32_t dnodeId = 0;
5104
    strdequote(pValToken->z);
S
Shengliang Guan 已提交
5105
    bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId);
5106 5107 5108 5109 5110 5111
    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 已提交
5112
    SStrToken* pValToken = &pOptions->a[2];
S
slguan 已提交
5113 5114
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
5115
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
S
slguan 已提交
5116 5117
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5118
  } else {
H
Haojun Liao 已提交
5119
    SStrToken* pValToken = &pOptions->a[2];
H
hzcheng 已提交
5120 5121

    int32_t val = strtol(pValToken->z, NULL, 10);
5122
    if (val < 0 || val > 256) {
H
hzcheng 已提交
5123
      /* options value is out of valid range */
5124
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5125 5126
    }

5127 5128
    for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
5129 5130 5131 5132 5133 5134 5135 5136

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

5137
  return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5138 5139
}

S
slguan 已提交
5140 5141
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
5142
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5143 5144
  }

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

H
Haojun Liao 已提交
5148
  SStrToken* pOptionToken = &pOptions->a[0];
S
slguan 已提交
5149 5150 5151 5152 5153 5154 5155 5156 5157 5158

  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 已提交
5159
    SStrToken* pValToken = &pOptions->a[1];
S
slguan 已提交
5160 5161 5162 5163

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
5164
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5165 5166 5167 5168 5169 5170 5171 5172 5173 5174
    }

    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;
      }
    }
  }
5175
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5176 5177
}

H
hzcheng 已提交
5178
int32_t validateColumnName(char* name) {
S
TD-1057  
Shengliang Guan 已提交
5179
  bool ret = isKeyWord(name, (int32_t)strlen(name));
H
hzcheng 已提交
5180
  if (ret) {
5181
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5182 5183
  }

H
Haojun Liao 已提交
5184
  SStrToken token = {.z = name};
H
hzcheng 已提交
5185 5186 5187
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
5188
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5189 5190 5191 5192
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
S
TD-1057  
Shengliang Guan 已提交
5193
    token.n = (uint32_t)strtrim(token.z);
H
hzcheng 已提交
5194 5195 5196

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
5197
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5198 5199 5200 5201 5202
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
5203
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5204 5205 5206 5207 5208 5209
    }
  }

  return TSDB_CODE_SUCCESS;
}

5210 5211
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
5212 5213 5214
    return true;
  }

H
hjxilinx 已提交
5215
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
5216 5217
}

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

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

H
hzcheng 已提交
5226
  // handle the limit offset value, validate the limit
5227
  pQueryInfo->limit = pQuerySql->limit;
5228
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
5229
  pQueryInfo->slimit = pQuerySql->slimit;
5230
  
5231
  tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
5232 5233
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
5234
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
5235
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
5236 5237
  }

5238
  if (pQueryInfo->limit.limit == 0) {
5239
    tscDebug("%p limit 0, no output result", pSql);
5240
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
5241
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5242 5243
  }

H
hjxilinx 已提交
5244
  // todo refactor
weixin_48148422's avatar
weixin_48148422 已提交
5245
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
5246
    if (!tscQueryTags(pQueryInfo)) {  // local handle the super table tag query
5247
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
5248
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
5249
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5250
        }
H
hjxilinx 已提交
5251

5252
        // for projection query on super table, all queries are subqueries
H
hjxilinx 已提交
5253 5254
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
            !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
5255
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
5256
        }
S
slguan 已提交
5257
      }
H
hzcheng 已提交
5258 5259
    }

5260
    if (pQueryInfo->slimit.limit == 0) {
5261
      tscDebug("%p slimit 0, no output result", pSql);
5262
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
5263 5264 5265 5266
      return TSDB_CODE_SUCCESS;
    }

    /*
5267 5268 5269 5270
     * 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 已提交
5271
     */
H
hjxilinx 已提交
5272
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
5273 5274 5275 5276
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
5277
    // No tables included. No results generated. Query results are empty.
5278
    if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
5279
      tscDebug("%p no table in super table, no output result", pSql);
5280
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
5281
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5282 5283 5284
    }

    // keep original limitation value in globalLimit
5285
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
5286
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
5287

5288 5289 5290 5291 5292 5293 5294 5295 5296
    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 已提交
5297

5298 5299
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
5300
  } else {
5301
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
5302
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
5303
    }
H
hjxilinx 已提交
5304
  
H
hjxilinx 已提交
5305
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
5306 5307 5308
    
    bool hasTags = false;
    bool hasOtherFunc = false;
S
slguan 已提交
5309
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
5310
    for (int32_t i = 0; i < size; ++i) {
5311
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
5312 5313 5314 5315
      if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
        hasTags = true;
      } else {
        hasOtherFunc = true;
H
hzcheng 已提交
5316 5317
      }
    }
5318 5319
    
    if (hasTags && hasOtherFunc) {
5320
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5321
    }
H
hzcheng 已提交
5322 5323 5324 5325
  }

  return TSDB_CODE_SUCCESS;
}
5326

S
TD-1732  
Shengliang Guan 已提交
5327
static int32_t setKeepOption(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
hjxilinx 已提交
5328
  const char* msg = "invalid number of options";
H
hjxilinx 已提交
5329

5330 5331 5332
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
5333

H
Haojun Liao 已提交
5334
  SArray* pKeep = pCreateDb->keep;
H
hjxilinx 已提交
5335
  if (pKeep != NULL) {
H
Haojun Liao 已提交
5336 5337 5338 5339 5340 5341
    size_t s = taosArrayGetSize(pKeep);
    tVariantListItem* p0 = taosArrayGet(pKeep, 0);
    switch (s) {
      case 1: {
        pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64Key);
      }
5342 5343
        break;
      case 2: {
H
Haojun Liao 已提交
5344 5345 5346
        tVariantListItem* p1 = taosArrayGet(pKeep, 1);
        pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)p1->pVar.i64Key);
5347 5348 5349
        break;
      }
      case 3: {
H
Haojun Liao 已提交
5350 5351 5352 5353 5354 5355
        tVariantListItem* p1 = taosArrayGet(pKeep, 1);
        tVariantListItem* p2 = taosArrayGet(pKeep, 2);

        pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)p1->pVar.i64Key);
        pMsg->daysToKeep2 = htonl((int32_t)p2->pVar.i64Key);
5356 5357
        break;
      }
5358
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
5359 5360
    }
  }
H
hjxilinx 已提交
5361

H
hjxilinx 已提交
5362 5363
  return TSDB_CODE_SUCCESS;
}
5364

S
TD-1732  
Shengliang Guan 已提交
5365
static int32_t setTimePrecision(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDbInfo) {
H
hjxilinx 已提交
5366
  const char* msg = "invalid time precision";
H
hjxilinx 已提交
5367

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

H
Haojun Liao 已提交
5370
  SStrToken* pToken = &pCreateDbInfo->precision;
5371 5372
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
5373

5374 5375 5376 5377 5378
    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 已提交
5379
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
5380 5381
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
5382
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
5383 5384
    }
  }
H
hjxilinx 已提交
5385

H
hjxilinx 已提交
5386 5387
  return TSDB_CODE_SUCCESS;
}
5388

S
TD-1732  
Shengliang Guan 已提交
5389
static void setCreateDBOption(SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
Haojun Liao 已提交
5390
  pMsg->maxTables = htonl(-1);  // max tables can not be set anymore
H
hjxilinx 已提交
5391
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
5392
  pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
H
hjxilinx 已提交
5393
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
S
TD-1057  
Shengliang Guan 已提交
5394
  pMsg->commitTime = htonl((int32_t)pCreateDb->commitTime);
H
hjxilinx 已提交
5395 5396
  pMsg->minRowsPerFileBlock = htonl(pCreateDb->minRowsPerBlock);
  pMsg->maxRowsPerFileBlock = htonl(pCreateDb->maxRowsPerBlock);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5397
  pMsg->fsyncPeriod = htonl(pCreateDb->fsyncPeriod);
S
slguan 已提交
5398
  pMsg->compression = pCreateDb->compressionLevel;
H
hjxilinx 已提交
5399
  pMsg->walLevel = (char)pCreateDb->walLevel;
H
hjxilinx 已提交
5400
  pMsg->replications = pCreateDb->replica;
5401
  pMsg->quorum = pCreateDb->quorum;
5402
  pMsg->ignoreExist = pCreateDb->ignoreExists;
Y
yihaoDeng 已提交
5403
  pMsg->update = pCreateDb->update;
H
hjxilinx 已提交
5404 5405 5406
}

int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) {
S
TD-1732  
Shengliang Guan 已提交
5407
  SCreateDbMsg* pMsg = (SCreateDbMsg *)(pCmd->payload);
H
hjxilinx 已提交
5408
  setCreateDBOption(pMsg, pCreateDbSql);
H
hjxilinx 已提交
5409

H
hjxilinx 已提交
5410
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5411
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5412
  }
H
hjxilinx 已提交
5413

H
hjxilinx 已提交
5414
  if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5415
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5416
  }
H
hjxilinx 已提交
5417

H
hjxilinx 已提交
5418
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
5419
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5420
  }
H
hjxilinx 已提交
5421

5422
  return TSDB_CODE_SUCCESS;
H
huili 已提交
5423
}
S
slguan 已提交
5424

5425 5426
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
5427

5428 5429
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
H
Haojun Liao 已提交
5430 5431
    SSqlExpr* pExpr = NULL;

H
hjxilinx 已提交
5432
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
Haojun Liao 已提交
5433 5434 5435
    if (size > 0) {
      pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1);
    }
5436

H
Haojun Liao 已提交
5437
    if (pExpr == NULL || pExpr->functionId != TSDB_FUNC_TAG) {
H
Haojun Liao 已提交
5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pParentQueryInfo, tableIndex);

      int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);

      SSchema* pTagSchema = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, colId);
      int16_t colIndex = tscGetTagColIndexById(pTableMetaInfo->pTableMeta, colId);
      SColumnIndex    index = {.tableIndex = 0, .columnIndex = colIndex};

      char*   name = pTagSchema->name;
      int16_t type = pTagSchema->type;
      int16_t bytes = pTagSchema->bytes;

5450
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
S
slguan 已提交
5451 5452 5453 5454
      pExpr->colInfo.flag = TSDB_COL_TAG;

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

      int32_t relIndex = index.columnIndex;

5459
      pExpr->colInfo.colIndex = relIndex;
5460 5461
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
5462

5463
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
5464
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
5465 5466 5467 5468
    }
  }
}

H
hjxilinx 已提交
5469 5470 5471
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
5472
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
5473 5474 5475
  pExpr->numOfParams = 1;
}

5476
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
5477
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
H
hjxilinx 已提交
5478
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
5479

H
Haojun Liao 已提交
5480 5481 5482 5483
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

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

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

H
Haojun Liao 已提交
5487
  SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, (int32_t)size);
H
Haojun Liao 已提交
5488
  doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
H
hjxilinx 已提交
5489
  pInfo->visible = false;
S
slguan 已提交
5490 5491
}

5492
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5493
  int32_t tagLength = 0;
H
hjxilinx 已提交
5494
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
5495 5496 5497 5498 5499

//todo is 0??
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);

H
hjxilinx 已提交
5500
  for (int32_t i = 0; i < size; ++i) {
5501
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5502 5503 5504 5505 5506 5507 5508 5509 5510
    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;
    }
  }

5511
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5512

H
hjxilinx 已提交
5513
  for (int32_t i = 0; i < size; ++i) {
5514
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
Haojun Liao 已提交
5515 5516
    if ((pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) &&
       !(pExpr->functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->colInfo.flag))) {
5517
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
S
TD-1057  
Shengliang Guan 已提交
5518
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64Key, &pExpr->resType,
5519
                        &pExpr->resBytes, &pExpr->interBytes, tagLength, isSTable);
S
slguan 已提交
5520 5521 5522 5523
    }
  }
}

H
Haojun Liao 已提交
5524
static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5525
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5526 5527
  
  for (int32_t i = 0; i < size; ++i) {
5528
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
Haojun Liao 已提交
5529

5530
    if (pExpr->functionId == TSDB_FUNC_PRJ && (!TSDB_COL_IS_UD_COL(pExpr->colInfo.flag) && (pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX))) {
H
hjxilinx 已提交
5531
      bool qualifiedCol = false;
5532
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5533 5534 5535
        SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
  
        if (pExpr->colInfo.colId == pColIndex->colId) {
H
hjxilinx 已提交
5536
          qualifiedCol = true;
H
hjxilinx 已提交
5537
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5538 5539 5540 5541
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
5542

H
Haojun Liao 已提交
5543 5544 5545 5546
      // it is not a tag column/tbname column/user-defined column, return error
      if (!qualifiedCol) {
        return TSDB_CODE_TSC_INVALID_SQL;
      }
H
hjxilinx 已提交
5547 5548
    }
  }
H
Haojun Liao 已提交
5549 5550

  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5551 5552
}

S
slguan 已提交
5553 5554
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
5555 5556
    SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j);
  
Y
TD-1230  
yihaoDeng 已提交
5557
    if (columnId == pColIndex->colId && TSDB_COL_IS_TAG(pColIndex->flag )) {
S
slguan 已提交
5558 5559 5560 5561 5562 5563 5564
      return true;
    }
  }

  return false;
}

5565
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5566 5567
  bool hasTagPrj = false;
  bool hasColumnPrj = false;
H
hjxilinx 已提交
5568
  
H
hjxilinx 已提交
5569
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5570
  for (int32_t i = 0; i < size; ++i) {
5571
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582
    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
5583
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5584 5585
  bool allInGroupby = true;

H
hjxilinx 已提交
5586 5587
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5588
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5589 5590 5591 5592
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5593
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5594 5595 5596 5597 5598 5599 5600 5601 5602
      allInGroupby = false;
      break;
    }
  }

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

5603
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5604
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5605 5606
  
  for (int32_t i = 0; i < size; ++i) {
5607
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619
    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.
 */
5620
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) {
S
slguan 已提交
5621
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5622
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5623

H
Haojun Liao 已提交
5624
  bool    tagTsColExists = false;
S
slguan 已提交
5625 5626 5627
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5628
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5629
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5630
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5631 5632
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
H
Haojun Liao 已提交
5633
      tagTsColExists = true;  // selectivity + ts/tag column
S
slguan 已提交
5634 5635 5636
      break;
    }
  }
H
hjxilinx 已提交
5637

H
hjxilinx 已提交
5638
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5639
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5640 5641
  
    int16_t functionId = pExpr->functionId;
5642
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5643
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5644
      continue;
S
slguan 已提交
5645
    }
H
hjxilinx 已提交
5646

H
hjxilinx 已提交
5647 5648 5649 5650 5651 5652
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5653

H
Haojun Liao 已提交
5654
  if (tagTsColExists) {  // check if the selectivity function exists
S
slguan 已提交
5655 5656
    // 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.
5657
    if (numOfAggregation > 0) {
5658
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5659 5660 5661 5662 5663 5664
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5665
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
H
Haojun Liao 已提交
5666 5667 5668 5669 5670
      int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
      }

S
slguan 已提交
5671 5672 5673 5674 5675
    } 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 已提交
5676
      for (int32_t i = 0; i < numOfExprs; ++i) {
H
Haojun Liao 已提交
5677 5678 5679
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
        int16_t functionId = pExpr->functionId;
        if (functionId == TSDB_FUNC_TAGPRJ || (aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == 0) {
S
slguan 已提交
5680 5681 5682
          continue;
        }

H
Haojun Liao 已提交
5683 5684 5685 5686
        if ((functionId == TSDB_FUNC_LAST_ROW) ||
             (functionId == TSDB_FUNC_LAST_DST && (pExpr->colInfo.flag & TSDB_COL_NULL) != 0)) {
          // do nothing
        } else {
5687
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5688 5689 5690
        }
      }

5691
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
H
Haojun Liao 已提交
5692 5693 5694 5695
      int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
      }
H
hjxilinx 已提交
5696 5697
    }
  } else {
5698
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5699
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5700
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5701
      }
H
hjxilinx 已提交
5702

H
hjxilinx 已提交
5703 5704
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5705
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
H
Haojun Liao 已提交
5706 5707 5708 5709
        int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
        if (code != TSDB_CODE_SUCCESS) {
          return code;
        }
H
hjxilinx 已提交
5710
      }
S
slguan 已提交
5711 5712 5713 5714 5715 5716
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

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

H
Haojun Liao 已提交
5722
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5723
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5724 5725 5726 5727
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5728
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5729
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5730
    int16_t colIndex = pColIndex->colIndex;
5731
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5732
      type  = s.type;
H
Haojun Liao 已提交
5733
      bytes = s.bytes;
H
Haojun Liao 已提交
5734
      name  = s.name;
S
slguan 已提交
5735
    } else {
5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746
      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 已提交
5747
    }
H
hjxilinx 已提交
5748 5749 5750
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5751
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5752
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5753
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5754
      
B
Bomin Zhang 已提交
5755 5756
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5757
      
S
slguan 已提交
5758 5759 5760
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5761
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
S
TD-1057  
Shengliang Guan 已提交
5762
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5763 5764
    } else {
      // if this query is "group by" normal column, interval is not allowed
5765
      if (pQueryInfo->interval.interval > 0) {
5766
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5767 5768 5769
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5770
      for (int32_t j = 0; j < size; ++j) {
5771
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5772 5773 5774 5775 5776 5777 5778 5779 5780 5781
        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) {
5782
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5783 5784 5785 5786 5787 5788 5789
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5790
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5791
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5792
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5793
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5794
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5795 5796

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5797
  if (tscQueryTags(pQueryInfo)) {
5798
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) {
5799
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5800 5801 5802 5803 5804
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5805
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5806
    // check if all the tags prj columns belongs to the group by columns
5807 5808
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5809
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5810 5811 5812
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5813 5814
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5815
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5816 5817 5818 5819 5820 5821
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5822
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5823
        bool qualified = false;
5824
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5825
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5826 5827 5828 5829 5830 5831 5832
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5833
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5834 5835 5836 5837
        }
      }

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

5842
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5843
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5844 5845 5846
      }
    }

5847
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5848
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5849 5850 5851 5852 5853 5854
    }

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

H
hjxilinx 已提交
5859
    // projection query on super table does not compatible with "group by" syntax
5860
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5861
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5862
    }
H
hjxilinx 已提交
5863

H
hjxilinx 已提交
5864
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5865
  } else {
5866
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5867 5868
  }
}
5869
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5870 5871 5872
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5873

H
hjxilinx 已提交
5874 5875
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5876
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5877
  }
H
hjxilinx 已提交
5878

H
hjxilinx 已提交
5879 5880
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5881
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hjxilinx 已提交
5882
  }
H
hjxilinx 已提交
5883

H
hjxilinx 已提交
5884
  // TODO redefine the function
H
hjxilinx 已提交
5885 5886 5887 5888 5889 5890
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5891
  int32_t index = -1;
H
hjxilinx 已提交
5892
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5893
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5894
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5895 5896 5897 5898
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5899 5900 5901

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5902
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5903
    case 1:
H
Haojun Liao 已提交
5904 5905 5906
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5907
    case 3:
H
Haojun Liao 已提交
5908
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5909
    case 4:
H
Haojun Liao 已提交
5910
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5911
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5912
  }
5913 5914 5915 5916 5917 5918
  
  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 已提交
5919
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5920 5921
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5922
}
H
hjxilinx 已提交
5923 5924

// can only perform the parameters based on the macro definitation
S
TD-1732  
Shengliang Guan 已提交
5925
int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) {
H
hjxilinx 已提交
5926
  char msg[512] = {0};
H
hjxilinx 已提交
5927

H
hjxilinx 已提交
5928
  if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) {
S
TD-1388  
Shengliang Guan 已提交
5929
    snprintf(msg, tListLen(msg), "invalid db option walLevel: %d, only 1-2 allowed", pCreate->walLevel);
5930
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5931
  }
H
hjxilinx 已提交
5932

H
hjxilinx 已提交
5933
  if (pCreate->replications != -1 &&
5934
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5935
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5936
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5937
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5938
  }
H
hjxilinx 已提交
5939

5940 5941 5942 5943 5944 5945 5946
  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 已提交
5947
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5948
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5949
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5950
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5951
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5952
  }
H
hjxilinx 已提交
5953

H
hjxilinx 已提交
5954 5955 5956 5957
  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);
5958
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5959
  }
H
hjxilinx 已提交
5960

H
hjxilinx 已提交
5961
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5962
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5963
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5964
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5965
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5966
  }
H
hjxilinx 已提交
5967 5968 5969 5970

  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);
5971
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5972
  }
H
hjxilinx 已提交
5973

H
hjxilinx 已提交
5974
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5975
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5976
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5977
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5978
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5979
  }
H
hjxilinx 已提交
5980

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5981 5982 5983 5984 5985 5986 5987
  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 已提交
5988
  if (pCreate->compression != -1 &&
S
slguan 已提交
5989
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5990
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5991
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5992
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5993
  }
H
hjxilinx 已提交
5994

H
hjxilinx 已提交
5995 5996
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5997 5998

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

S
TD-1057  
Shengliang Guan 已提交
6002
  int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
6003
  if (size == 0) {
H
hjxilinx 已提交
6004 6005
    return;
  }
H
hjxilinx 已提交
6006

H
hjxilinx 已提交
6007
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
6008 6009

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

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

L
lihui 已提交
6016
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
6017 6018 6019
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
6020 6021 6022
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
6024
    if (i < size - 1) {
H
hjxilinx 已提交
6025 6026 6027
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
6028

H
hjxilinx 已提交
6029
  str[offset] = ']';
6030
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
6031
}
6032

6033
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
6034 6035
  const char* msg1 = "invalid table name";

6036 6037
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
6038
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
6039 6040 6041

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;

H
Haojun Liao 已提交
6042 6043
  SArray* pFieldList = pCreateTable->colInfo.pColumns;
  SArray* pTagList = pCreateTable->colInfo.pTagColumns;
6044 6045 6046 6047

  assert(pFieldList != NULL);

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

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
6051
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6052 6053
  }

H
Haojun Liao 已提交
6054 6055 6056
  int32_t code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql);
  if(code != TSDB_CODE_SUCCESS) {
    return code;
6057 6058 6059 6060
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
6061
    return TSDB_CODE_TSC_INVALID_SQL;
6062 6063 6064
  }

  int32_t col = 0;
H
Haojun Liao 已提交
6065 6066 6067
  size_t numOfFields = taosArrayGetSize(pFieldList);

  for (; col < numOfFields; ++col) {
H
Haojun Liao 已提交
6068
    TAOS_FIELD* p = taosArrayGet(pFieldList, col);
H
Haojun Liao 已提交
6069
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p);
6070 6071
  }

H
Haojun Liao 已提交
6072
  pCmd->numOfCols = (int16_t)numOfFields;
6073

H
hjxilinx 已提交
6074
  if (pTagList != NULL) {  // create super table[optional]
H
Haojun Liao 已提交
6075 6076
    size_t numOfTags = taosArrayGetSize(pTagList);
    for (int32_t i = 0; i < numOfTags; ++i) {
H
Haojun Liao 已提交
6077 6078
      TAOS_FIELD* p = taosArrayGet(pTagList, i);
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p);
6079 6080
    }

H
Haojun Liao 已提交
6081
    pCmd->count = numOfTags;
6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095
  }

  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;
6096 6097 6098
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
6099 6100 6101
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
6102 6103 6104 6105

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

H
hjxilinx 已提交
6106
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
6107 6108

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

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
6112
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6113 6114
  }

H
Haojun Liao 已提交
6115 6116 6117
  int32_t code = tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
6118 6119 6120
  }

  // get meter meta from mnode
B
Bomin Zhang 已提交
6121
  tstrncpy(pCreateTable->usingInfo.tagdata.name, pStableMeterMetaInfo->name, sizeof(pCreateTable->usingInfo.tagdata.name));
H
Haojun Liao 已提交
6122
  SArray* pList = pInfo->pCreateTableInfo->usingInfo.pTagVals;
6123

H
Haojun Liao 已提交
6124
  code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
6125 6126 6127 6128
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
Haojun Liao 已提交
6129 6130
  size_t size = taosArrayGetSize(pList);
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != size) {
6131
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
6132 6133 6134
  }

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

6137
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
B
Bomin Zhang 已提交
6138 6139 6140 6141 6142
  SKVRowBuilder kvRowBuilder = {0};
  if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
hjxilinx 已提交
6143
  int32_t ret = TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
6144
  for (int32_t i = 0; i < size; ++i) {
H
Haojun Liao 已提交
6145
    SSchema* pSchema = &pTagSchema[i];
H
Haojun Liao 已提交
6146 6147
    tVariantListItem* pItem = taosArrayGet(pList, i);

H
Haojun Liao 已提交
6148
    char tagVal[TSDB_MAX_TAGS_LEN];
B
Bomin Zhang 已提交
6149
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
H
Haojun Liao 已提交
6150
      if (pItem->pVar.nLen > pSchema->bytes) {
B
Bomin Zhang 已提交
6151
        tdDestroyKVRowBuilder(&kvRowBuilder);
H
hjxilinx 已提交
6152 6153 6154
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
H
Haojun Liao 已提交
6155

H
Haojun Liao 已提交
6156
    ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true);
H
Haojun Liao 已提交
6157 6158 6159 6160 6161 6162 6163 6164 6165 6166

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

6167
    if (ret != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
6168
      tdDestroyKVRowBuilder(&kvRowBuilder);
6169
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
6170 6171
    }

H
Haojun Liao 已提交
6172 6173


B
Bomin Zhang 已提交
6174
    tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
6175 6176
  }

B
Bomin Zhang 已提交
6177
  SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
B
Bomin Zhang 已提交
6178 6179 6180 6181 6182
  tdDestroyKVRowBuilder(&kvRowBuilder);
  if (row == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  tdSortKVRowByColIdx(row);
B
Bomin Zhang 已提交
6183
  pTag->dataLen = kvRowLen(row);
B
Bomin Zhang 已提交
6184
  kvRowCpy(pTag->data, row);
B
Bomin Zhang 已提交
6185 6186
  free(row);

6187 6188
  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
6189
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6190 6191
  }

H
hjxilinx 已提交
6192
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
6193
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205
  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* 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 已提交
6206 6207
  const char* msg6 = "from missing in subclause";
  
6208
  SSqlCmd*    pCmd = &pSql->cmd;
6209
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
6210 6211
  assert(pQueryInfo->numOfTables == 1);

6212
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
6213
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
6214 6215

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
6216
  SStrToken* pzTableName = &(pCreateTable->name);
6217 6218 6219
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
6220
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6221
  }
H
Haojun Liao 已提交
6222
  
H
Haojun Liao 已提交
6223 6224
  SArray* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
  if (pSrcMeterName == NULL || taosArrayGetSize(pSrcMeterName) == 0) {
H
Haojun Liao 已提交
6225 6226 6227
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
H
Haojun Liao 已提交
6228 6229
  tVariantListItem* p1 = taosArrayGet(pSrcMeterName, 0);
  SStrToken srcToken = {.z = p1->pVar.pz, .n = p1->pVar.nLen, .type = TK_STRING};
6230
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
6231
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6232 6233
  }

H
Haojun Liao 已提交
6234 6235 6236
  int32_t code = tscSetTableFullName(pTableMetaInfo, &srcToken, pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
6237 6238
  }

H
Haojun Liao 已提交
6239
  code = tscGetTableMeta(pSql, pTableMetaInfo);
6240 6241 6242 6243
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
6244
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
H
Haojun Liao 已提交
6245
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false) != TSDB_CODE_SUCCESS) {
6246
    return TSDB_CODE_TSC_INVALID_SQL;
6247 6248 6249
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
6250
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
6251
      return TSDB_CODE_TSC_INVALID_SQL;
6252 6253 6254 6255
    }
  }

  // set interval value
6256
  if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6257
    return TSDB_CODE_TSC_INVALID_SQL;
6258
  } else {
6259
    if ((pQueryInfo->interval.interval > 0) &&
6260
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6261
      return TSDB_CODE_TSC_INVALID_SQL;
6262 6263 6264 6265
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
6266 6267 6268
  code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
6269 6270 6271
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
6272
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
6273 6274
  }

6275
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
6276
    return TSDB_CODE_TSC_INVALID_SQL;
6277 6278
  }

H
hjxilinx 已提交
6279
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
6280

6281
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
6282
    return TSDB_CODE_TSC_INVALID_SQL;
6283 6284 6285 6286 6287 6288 6289
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
6290
    if (pQueryInfo->interval.interval == 0) {
6291
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
6292 6293
    }

H
Haojun Liao 已提交
6294
    tVariantListItem* pItem = taosArrayGet(pQuerySql->fillType, 0);
6295 6296 6297
    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))) {
6298
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
6299 6300 6301 6302 6303
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
6304
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
6305 6306 6307 6308
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
H
Haojun Liao 已提交
6309
  assert(pQuerySql != NULL && (pQuerySql->from == NULL || taosArrayGetSize(pQuerySql->from) > 0));
6310

H
Haojun Liao 已提交
6311 6312 6313 6314 6315 6316 6317 6318 6319
  const char* msg0  = "invalid table name";
  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";
6320 6321

  int32_t code = TSDB_CODE_SUCCESS;
6322

6323
  SSqlCmd* pCmd = &pSql->cmd;
6324

6325
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
6326
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
6327
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
6328
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
6329
  }
H
hjxilinx 已提交
6330

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

6333 6334
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
6335
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347
  }

  /*
   * 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);
6348
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
6349 6350
  }

H
Haojun Liao 已提交
6351 6352
  size_t fromSize = taosArrayGetSize(pQuerySql->from);
  if (fromSize > TSDB_MAX_JOIN_TABLE_NUM * 2) {
6353
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
6354 6355
  }

6356
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
6357

H
Haojun Liao 已提交
6358
  if (fromSize > 4) {
H
Haojun Liao 已提交
6359 6360 6361
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

6362
  // set all query tables, which are maybe more than one.
H
Haojun Liao 已提交
6363 6364 6365
  for (int32_t i = 0; i < fromSize; ) {
    tVariantListItem* item = taosArrayGet(pQuerySql->from, i);
    tVariant* pTableItem = &item->pVar;
6366 6367

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
6368
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6369 6370 6371 6372
    }

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

H
Haojun Liao 已提交
6373
    SStrToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
6374
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
6375
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6376 6377
    }

H
Haojun Liao 已提交
6378
    if (pQueryInfo->numOfTables <= i/2) {  // more than one table
H
hjxilinx 已提交
6379
      tscAddEmptyMetaInfo(pQueryInfo);
6380 6381
    }

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

H
Haojun Liao 已提交
6384
    SStrToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
6385 6386 6387
    code = tscSetTableFullName(pTableMetaInfo1, &t, pSql);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
6388 6389
    }

H
Haojun Liao 已提交
6390 6391
    tVariantListItem* p1 = taosArrayGet(pQuerySql->from, i);
    if (p1->pVar.nType != TSDB_DATA_TYPE_BINARY) {
H
Haojun Liao 已提交
6392 6393 6394
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

H
Haojun Liao 已提交
6395
    SStrToken aliasName = {.z = p1->pVar.pz, .n = p1->pVar.nLen, .type = TK_STRING};
H
Haojun Liao 已提交
6396 6397 6398 6399
    if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

6400
    // has no table alias name
H
Haojun Liao 已提交
6401
    if (memcmp(pTableItem->pz, p1->pVar.pz, p1->pVar.nLen) == 0) {
6402 6403
      extractTableName(pTableMetaInfo1->name, pTableMetaInfo1->aliasName);
    } else {
H
Haojun Liao 已提交
6404
      tstrncpy(pTableMetaInfo1->aliasName, p1->pVar.pz, sizeof(pTableMetaInfo1->aliasName));
6405
    }
H
Haojun Liao 已提交
6406 6407

    code = tscGetTableMeta(pSql, pTableMetaInfo1);
6408 6409 6410
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
H
Haojun Liao 已提交
6411 6412

    i += 2;
6413 6414
  }

H
Haojun Liao 已提交
6415
  assert(pQueryInfo->numOfTables == taosArrayGetSize(pQuerySql->from) / 2);
H
hjxilinx 已提交
6416
  bool isSTable = false;
H
hjxilinx 已提交
6417
  
weixin_48148422's avatar
weixin_48148422 已提交
6418
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
6419 6420 6421 6422 6423 6424 6425
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
6426 6427
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
6428
  }
6429

6430
  // parse the group by clause in the first place
6431
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
6432
    return TSDB_CODE_TSC_INVALID_SQL;
6433 6434
  }

6435 6436
  // set where info
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
Y
TD-1230  
yihaoDeng 已提交
6437

6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448
  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
H
Haojun Liao 已提交
6449
    if (taosArrayGetSize(pQuerySql->from) > 2) { // it is a join query, no wher clause is not allowed.
6450 6451
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "condition missing for join query ");
    }
Y
TD-1230  
yihaoDeng 已提交
6452
  }
6453

H
Haojun Liao 已提交
6454
  int32_t joinQuery = (pQuerySql->from != NULL && taosArrayGetSize(pQuerySql->from) > 2);
6455

H
Haojun Liao 已提交
6456
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery) != TSDB_CODE_SUCCESS) {
6457
    return TSDB_CODE_TSC_INVALID_SQL;
6458 6459
  }

H
Haojun Liao 已提交
6460 6461 6462 6463 6464
  // set order by info
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_TSC_INVALID_SQL;
  }

6465
  // set interval value
6466
  if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6467
    return TSDB_CODE_TSC_INVALID_SQL;
6468
  } else {
6469
    if ((pQueryInfo->interval.interval > 0) &&
6470
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6471
      return TSDB_CODE_TSC_INVALID_SQL;
6472 6473 6474 6475
    }
  }

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

  // no result due to invalid query time range
H
hjxilinx 已提交
6482
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6483
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6484 6485 6486
    return TSDB_CODE_SUCCESS;
  }

6487
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6488
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6489 6490 6491
  }

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

H
hjxilinx 已提交
6495
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6496
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6497 6498 6499
    }
  }

6500
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6501 6502 6503
    return code;
  }

6504
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6505 6506 6507
    return code;
  }

6508
  setColumnOffsetValueInResultset(pQueryInfo);
6509

6510 6511 6512 6513 6514
  /*
   * 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) {
6515
    if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6516 6517
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6518

6519
    if (pQueryInfo->interval.interval > 0 && pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') {
H
Haojun Liao 已提交
6520 6521 6522 6523 6524
      bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER);
      if (initialWindows) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }

S
TD-1057  
Shengliang Guan 已提交
6525
      int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6526
      // number of result is not greater than 10,000,000
6527
      if ((timeRange == 0) || (timeRange / pQueryInfo->interval.interval) > MAX_INTERVAL_TIME_WINDOW) {
6528
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6529 6530
      }
    }
H
hjxilinx 已提交
6531

6532
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6533 6534 6535 6536
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6537 6538 6539

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

H
Haojun Liao 已提交
6541
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid) {
H
hjxilinx 已提交
6542 6543
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6544
  
6545
  if (pSqlExpr->pLeft != NULL) {
H
Haojun Liao 已提交
6546
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pQueryInfo, pCols, uid);
H
hjxilinx 已提交
6547 6548 6549 6550 6551
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6552
  if (pSqlExpr->pRight != NULL) {
H
Haojun Liao 已提交
6553
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid);
H
hjxilinx 已提交
6554 6555 6556 6557
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
H
Haojun Liao 已提交
6558 6559 6560 6561 6562

  if (pSqlExpr->pLeft == NULL && pSqlExpr->pRight == NULL && pSqlExpr->nSQLOptr == 0) {
    *pExpr = calloc(1, sizeof(tExprNode));
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
6563
  
6564
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6565
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6566
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6567
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6568 6569 6570
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6571
      return TSDB_CODE_SUCCESS;
6572
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6573
      // arithmetic expression on the results of aggregation functions
6574
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6575
      (*pExpr)->nodeType = TSQL_NODE_COL;
6576 6577 6578
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6579
      // set the input column data byte and type.
H
Haojun Liao 已提交
6580
      size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
6581 6582
      
      for (int32_t i = 0; i < size; ++i) {
H
Haojun Liao 已提交
6583
        SSqlExpr* p1 = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
6584 6585
        
        if (strcmp((*pExpr)->pSchema->name, p1->aliasName) == 0) {
H
Haojun Liao 已提交
6586
          (*pExpr)->pSchema->type  = (uint8_t)p1->resType;
H
hjxilinx 已提交
6587
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
Haojun Liao 已提交
6588 6589 6590 6591 6592

          if (uid != NULL) {
            *uid = p1->uid;
          }

H
hjxilinx 已提交
6593 6594 6595
          break;
        }
      }
6596
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6597
      SColumnIndex index = {0};
6598
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6599 6600 6601
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
H
Haojun Liao 已提交
6602 6603 6604 6605

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

6606 6607 6608
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
H
Haojun Liao 已提交
6609

6610 6611
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6612 6613 6614
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6615
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6616 6617
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
H
Haojun Liao 已提交
6618 6619
        colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;

6620 6621
        taosArrayPush(pCols, &colIndex);
      }
6622
      
H
hjxilinx 已提交
6623
      return TSDB_CODE_SUCCESS;
6624
    } else {
6625
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6626 6627 6628
    }
    
  } else {
H
hjxilinx 已提交
6629
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6630 6631
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6632 6633 6634
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6635
    
H
Haojun Liao 已提交
6636
    SStrToken t = {.type = pSqlExpr->nSQLOptr};
H
Haojun Liao 已提交
6637
    (*pExpr)->_node.optr = convertOptr(&t);
6638
    
H
[td-32]  
hjxilinx 已提交
6639
    assert((*pExpr)->_node.optr != 0);
6640 6641

    // check for dividing by 0
H
[td-32]  
hjxilinx 已提交
6642
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6643 6644
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6645
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6646
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6647
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6648 6649 6650
        }
      }
    }
H
Hui Li 已提交
6651

6652
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6653
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
6654
      if (pRight != NULL && pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6655 6656 6657
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6658 6659
      }
    }
H
hjxilinx 已提交
6660 6661 6662
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6663
}
6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674

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