tscSQLParser.c 232.7 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;
H
Haojun Liao 已提交
55 56

static SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex);
H
hzcheng 已提交
57 58

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

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

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

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

71
static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult);
72
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
H
hjxilinx 已提交
73
                                 int8_t type, char* fieldName, SSqlExpr* pSqlExpr);
H
Haojun Liao 已提交
74 75 76 77

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

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

80
static bool validateIpAddress(const char* ip, size_t size);
81
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
H
Haojun Liao 已提交
82
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery);
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
int16_t getNewResColId(SQueryInfo* pQueryInfo) {
  return pQueryInfo->resColumnId--;
}

H
Haojun Liao 已提交
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 169 170 171 172
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 已提交
173 174 175 176
/*
 * Used during parsing query sql. Since the query sql usually small in length, error position
 * is not needed in the final error message.
 */
177 178
static int32_t invalidSqlErrMsg(char* dstBuffer, const char* errMsg) {
  return tscInvalidSQLErrMsg(dstBuffer, errMsg, NULL);
H
hjxilinx 已提交
179 180
}

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

  if (pPwd->n <= 0) {
220
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
221 222
  }

B
Bomin Zhang 已提交
223
  if (pPwd->n >= TSDB_PASSWORD_LEN) {
224
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
225 226 227 228 229
  }

  return TSDB_CODE_SUCCESS;
}

H
hzcheng 已提交
230 231
int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
  if (pInfo == NULL || pSql == NULL || pSql->signature != pSql) {
232
    return TSDB_CODE_TSC_APP_ERROR;
H
hzcheng 已提交
233 234
  }

235 236
  SSqlCmd* pCmd = &pSql->cmd;
  SSqlRes* pRes = &pSql->res;
H
hzcheng 已提交
237

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

244 245 246 247 248
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex);
  if (pQueryInfo == NULL) {
    pRes->code = terrno;
    return pRes->code;
  }
H
hjxilinx 已提交
249

250 251 252 253
  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 已提交
254
  }
255

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

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

272 273
      if (pInfo->type == TSDB_SQL_DROP_DB) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
274

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

280 281
      } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
282

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

H
hjxilinx 已提交
295
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
296 297
      }

298 299
      break;
    }
H
hzcheng 已提交
300

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

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
306
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
307 308
      }

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

      break;
    }

317 318
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
319 320
    }

321 322
    case TSDB_SQL_SHOW: {
      if (setShowInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
323
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
324 325
      }

326 327 328 329 330 331 332 333
      break;
    }

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

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

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

H
hjxilinx 已提交
344
      if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
345
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
346 347 348 349 350
      }

      break;
    }

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

354
      if (pInfo->pDCLInfo->nTokens > 1) {
355
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
356 357
      }

H
Haojun Liao 已提交
358
      SStrToken* pIpAddr = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
359
      pIpAddr->n = strdequote(pIpAddr->z);
S
slguan 已提交
360 361 362
      break;
    }

363 364 365 366 367
    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 已提交
368

H
Haojun Liao 已提交
369 370
      SStrToken* pName = &pInfo->pDCLInfo->user.user;
      SStrToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
371

372
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
373
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
374 375
      }

B
Bomin Zhang 已提交
376
      if (pName->n >= TSDB_USER_LEN) {
377
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
378 379
      }

380
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
381
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
382 383 384
      }

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

H
hzcheng 已提交
395 396 397
      break;
    }

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

S
slguan 已提交
403
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
404
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
405
      }
S
slguan 已提交
406

H
Haojun Liao 已提交
407
      if (!tscValidateTableNameLength(pToken->n)) {
408
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
409 410
      }

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

H
hjxilinx 已提交
417
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
418
    }
419 420 421 422
    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 已提交
423

424 425 426
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
      }
H
hzcheng 已提交
427

428 429 430 431
      if (!tscValidateTableNameLength(pToken->n)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
      }

H
Haojun Liao 已提交
432 433 434
      code = tscSetTableFullName(pTableMetaInfo, pToken, pSql);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
435
      }
H
Haojun Liao 已提交
436

437 438 439 440 441 442 443 444 445 446 447 448
      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 已提交
449 450 451

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

456 457
      /* validate the ip address */
      tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
458

459 460
      /* validate the parameter names and options */
      if (validateDNodeConfig(pDCL) != TSDB_CODE_SUCCESS) {
461
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
462 463
      }

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

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

H
Hui Li 已提交
471 472 473 474
      if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }

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

477 478 479 480
      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 已提交
481

482 483
      break;
    }
H
hzcheng 已提交
484

485 486 487 488 489 490
    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 已提交
491

492
      pCmd->command = pInfo->type;
H
hzcheng 已提交
493

494
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
H
Haojun Liao 已提交
495 496
      SStrToken* pName = &pUser->user;
      SStrToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
497

B
Bomin Zhang 已提交
498
      if (pName->n >= TSDB_USER_LEN) {
499
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
500
      }
H
hzcheng 已提交
501

502
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
503
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
504
      }
H
hzcheng 已提交
505

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

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

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

H
hzcheng 已提交
534 535
      break;
    }
536 537

    case TSDB_SQL_CFG_LOCAL: {
S
slguan 已提交
538 539 540 541 542
      tDCLSQL*    pDCL = pInfo->pDCLInfo;
      const char* msg = "invalid configure options or values";

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

      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 已提交
551 552 553 554

      break;
    }

555 556
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
557

558
      if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
559
        if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
560
          return code;
H
hzcheng 已提交
561 562
        }

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

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

      break;
    }

578
    case TSDB_SQL_SELECT: {
H
hjxilinx 已提交
579
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
580

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

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

H
hjxilinx 已提交
597
        tscPrintSelectClause(pSql, i);
H
Haojun Liao 已提交
598
        pCmd->clauseIndex += 1;
H
hzcheng 已提交
599
      }
H
hjxilinx 已提交
600

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

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

611 612 613
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
614
        }
615
      }
616

617
      pCmd->parseFinished = 1;
618
      return TSDB_CODE_SUCCESS;  // do not build query message here
619
    }
H
hzcheng 已提交
620

621 622 623
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
624 625 626 627 628
      }

      break;
    }

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

      break;
    }

    default:
640
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
641 642
  }

dengyihao's avatar
dengyihao 已提交
643
  pSql->cmd.parseFinished = 1;
644
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
645 646
}

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

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

S
slguan 已提交
662
  return false;
H
hzcheng 已提交
663 664
}

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

670 671
  SSqlCmd* pCmd = &pSql->cmd;

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

H
Haojun Liao 已提交
682 683 684 685 686
  // 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 已提交
687
  // interval is not null
688
  SStrToken* t = &pQuerySql->interval;
689
  if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval, &pQueryInfo->interval.intervalUnit) != TSDB_CODE_SUCCESS) {
690
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
691 692
  }

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

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

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

711
    if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
712
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
713
    }
H
hjxilinx 已提交
714

H
hzcheng 已提交
715 716 717
    return TSDB_CODE_SUCCESS;
  }

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

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

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

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

  if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
751
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
752 753
  }

H
Haojun Liao 已提交
754 755
  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));
756

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

760 761 762 763
  if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_TSC_INVALID_SQL;
  }

764
  if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
765
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
766
  }
H
hjxilinx 已提交
767

H
hjxilinx 已提交
768
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
769 770
}

771
int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
772 773 774 775
  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'";

776 777 778
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);

779 780 781 782
  SStrToken* t = &pQuerySql->offset;
  if (t->n == 0) {
    pQueryInfo->interval.offsetUnit = pQueryInfo->interval.intervalUnit;
    pQueryInfo->interval.offset = 0;
783 784 785
    return TSDB_CODE_SUCCESS;
  }

786
  if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.offset, &pQueryInfo->interval.offsetUnit) != TSDB_CODE_SUCCESS) {
787
    return TSDB_CODE_TSC_INVALID_SQL;
788 789
  }

790
  if (pQueryInfo->interval.offset < 0) {
791 792 793
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }

794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
  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
817 818 819 820 821
  }

  return TSDB_CODE_SUCCESS;
}

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

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

H
hjxilinx 已提交
832
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
833
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
834

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

842
  if (pQueryInfo->interval.intervalUnit == 'n' || pQueryInfo->interval.intervalUnit == 'y') {
B
Bomin Zhang 已提交
843 844
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
  }
H
hzcheng 已提交
845

846
  parseAbsoluteDuration(pSliding->z, pSliding->n, &pQueryInfo->interval.sliding);
B
Bomin Zhang 已提交
847
  if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
848
    pQueryInfo->interval.sliding /= 1000;
B
Bomin Zhang 已提交
849 850
  }

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

855
  if (pQueryInfo->interval.sliding > pQueryInfo->interval.interval) {
B
Bomin Zhang 已提交
856
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
857 858
  }

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

H
Haojun Liao 已提交
863 864 865
//  if (pQueryInfo->interval.sliding != pQueryInfo->interval.interval && pSql->pStream == NULL) {
//    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
//  }
866

H
hzcheng 已提交
867 868 869
  return TSDB_CODE_SUCCESS;
}

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

873 874
  SSqlCmd* pCmd = &pSql->cmd;
  int32_t  code = TSDB_CODE_SUCCESS;
S
slguan 已提交
875

H
hjxilinx 已提交
876
  // backup the old name in pTableMetaInfo
H
Haojun Liao 已提交
877 878
  char oldName[TSDB_TABLE_FNAME_LEN] = {0};
  tstrncpy(oldName, pTableMetaInfo->name, tListLen(oldName));
H
hjxilinx 已提交
879

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

S
slguan 已提交
898
  if (code != TSDB_CODE_SUCCESS) {
899 900
    return code;
  }
H
hjxilinx 已提交
901

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

910
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
911 912
}

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

916 917 918 919 920 921 922
  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 已提交
923 924

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

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

  int32_t nLen = 0;
H
Haojun Liao 已提交
939 940
  for (int32_t i = 0; i < numOfCols; ++i) {
    pField = taosArrayGet(pFieldList, i);
B
Bomin Zhang 已提交
941 942

    if (pField->bytes == 0) {
dengyihao's avatar
dengyihao 已提交
943 944 945
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
      return false;
    }
H
hzcheng 已提交
946 947

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

    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
959
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
960 961 962
      return false;
    }

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

    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 已提交
976 977 978 979 980
  }

  return true;
}

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

984 985 986 987 988 989 990
  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 已提交
991 992

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

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

    nLen += p->bytes;
H
hzcheng 已提交
1008 1009 1010 1011
  }

  // max tag row length must be less than TSDB_MAX_TAGS_LEN
  if (nLen > TSDB_MAX_TAGS_LEN) {
1012
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1013 1014 1015 1016
    return false;
  }

  // field name must be unique
H
Haojun Liao 已提交
1017 1018 1019 1020
  for (int32_t i = 0; i < numOfTags; ++i) {
    TAOS_FIELD* p = taosArrayGet(pTagsList, i);

    if (has(pFieldList, 0, p->name) == true) {
1021
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1022 1023 1024 1025 1026
      return false;
    }
  }

  /* timestamp in tag is not allowed */
H
Haojun Liao 已提交
1027 1028 1029 1030
  for (int32_t i = 0; i < numOfTags; ++i) {
    TAOS_FIELD* p = taosArrayGet(pTagsList, i);

    if (p->type == TSDB_DATA_TYPE_TIMESTAMP) {
1031
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
1032 1033 1034
      return false;
    }

H
Haojun Liao 已提交
1035
    if (p->type < TSDB_DATA_TYPE_BOOL || p->type > TSDB_DATA_TYPE_NCHAR) {
1036
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1037 1038 1039
      return false;
    }

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

H
Haojun Liao 已提交
1046
    if (validateColumnName(p->name) != TSDB_CODE_SUCCESS) {
1047
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1048 1049 1050
      return false;
    }

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

  return true;
}

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

1071
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
1072

1073
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
1074
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
1075

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

1084
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
1085 1086 1087 1088 1089
    return false;
  }

  // no timestamp allowable
  if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) {
1090
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1091 1092 1093
    return false;
  }

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

H
hjxilinx 已提交
1099
  SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1100 1101
  int32_t  nLen = 0;

H
hjxilinx 已提交
1102
  for (int32_t i = 0; i < numOfTags; ++i) {
H
hzcheng 已提交
1103 1104 1105 1106 1107
    nLen += pTagSchema[i].bytes;
  }

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

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

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

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

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
1138 1139 1140 1141 1142 1143
  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 已提交
1144

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

  if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_NCHAR) {
1159
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
1160 1161 1162 1163
    return false;
  }

  if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) {
1164
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1165 1166 1167
    return false;
  }

H
hjxilinx 已提交
1168
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
1169 1170
  int32_t  nLen = 0;

H
hjxilinx 已提交
1171
  for (int32_t i = 0; i < numOfCols; ++i) {
H
hzcheng 已提交
1172 1173 1174 1175
    nLen += pSchema[i].bytes;
  }

  if (pColField->bytes <= 0) {
1176
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1177 1178 1179 1180 1181
    return false;
  }

  // length less than TSDB_MAX_BYTES_PER_ROW
  if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) {
1182
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1183 1184 1185 1186
    return false;
  }

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

  return true;
}

/* is contained in pFieldList or not */
H
Haojun Liao 已提交
1198 1199 1200 1201
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 已提交
1202
    if (strncasecmp(name, field->name, sizeof(field->name) - 1) == 0) return true;
H
hzcheng 已提交
1203 1204 1205 1206 1207 1208 1209
  }

  return false;
}

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

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

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

  return false;
}

H
Haojun Liao 已提交
1226
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1227 1228 1229
  int32_t totalLen = 0;

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

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

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

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

H
Haojun Liao 已提交
1270
  if (totalLen < TSDB_TABLE_FNAME_LEN) {
S
slguan 已提交
1271 1272 1273
    fullName[totalLen] = 0;
  }

H
Haojun Liao 已提交
1274
  return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1275 1276
}

Y
TD-1688  
yihaoDeng 已提交
1277 1278 1279 1280
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tscColumnListInsert(pQueryInfo->colList, &tsCol);
}
H
Haojun Liao 已提交
1281

1282
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
1283
  const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables";
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 1310 1311 1312
  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),
H
Haojun Liao 已提交
1313
                                       getNewResColId(pQueryInfo), sizeof(double), false);
1314

H
Haojun Liao 已提交
1315 1316 1317
    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);
1318 1319 1320 1321

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

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

H
Haojun Liao 已提交
1329
    // check for if there is a tag in the arithmetic express
1330 1331 1332
    size_t numOfNode = taosArrayGetSize(colList);
    for(int32_t k = 0; k < numOfNode; ++k) {
      SColIndex* pIndex = taosArrayGet(colList, k);
1333 1334
      if (TSDB_COL_IS_TAG(pIndex->flag)) {
        tExprTreeDestroy(&pNode, NULL);
1335 1336
        taosArrayDestroy(colList);
        tExprTreeDestroy(&pNode, NULL);
1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350
        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 已提交
1351
    len = tbufTell(&bw);
H
Haojun Liao 已提交
1352
    char* c = tbufGetData(&bw, false);
1353 1354

    // set the serialized binary string as the parameter of arithmetic expression
H
Haojun Liao 已提交
1355
    addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len);
1356
    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
H
Haojun Liao 已提交
1357

Y
TD-1688  
yihaoDeng 已提交
1358 1359
    // add ts column
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
1360

H
Haojun Liao 已提交
1361
    tbufCloseWriter(&bw);
1362 1363 1364 1365 1366 1367
    taosArrayDestroy(colList);
    tExprTreeDestroy(&pNode, NULL);
  } else {
    columnList.num = 0;
    columnList.ids[0] = (SColumnIndex) {0, 0};

H
Haojun Liao 已提交
1368 1369 1370 1371 1372 1373 1374
    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 已提交
1375

H
Haojun Liao 已提交
1376
    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, aliasName, NULL);
1377 1378

    int32_t slot = tscNumOfFields(pQueryInfo) - 1;
H
Haojun Liao 已提交
1379
    SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot);
1380 1381 1382 1383 1384

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

      // arithmetic expression always return result in the format of double float
H
Haojun Liao 已提交
1385
      pArithExprInfo->bytes      = sizeof(double);
1386
      pArithExprInfo->interBytes = sizeof(double);
H
Haojun Liao 已提交
1387
      pArithExprInfo->type       = TSDB_DATA_TYPE_DOUBLE;
1388

H
Haojun Liao 已提交
1389 1390 1391 1392
      pArithExprInfo->base.functionId = TSDB_FUNC_ARITHM;
      pArithExprInfo->base.numOfParams = 1;
      pArithExprInfo->base.resColId = getNewResColId(pQueryInfo);

H
Haojun Liao 已提交
1393
      int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &pArithExprInfo->uid);
1394 1395 1396 1397 1398 1399 1400
      if (ret != TSDB_CODE_SUCCESS) {
        tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
      }

      pInfo->pArithExprInfo = pArithExprInfo;
    }
H
Haojun Liao 已提交
1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411

    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, pInfo->pArithExprInfo->pExpr);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: other error handling
    } END_TRY

H
Haojun Liao 已提交
1412 1413 1414 1415 1416 1417
    SSqlFuncMsg* pFuncMsg = &pInfo->pArithExprInfo->base;
    pFuncMsg->arg[0].argBytes = (int16_t) tbufTell(&bw);
    pFuncMsg->arg[0].argValue.pz = tbufGetData(&bw, true);
    pFuncMsg->arg[0].argType = TSDB_DATA_TYPE_BINARY;

//    tbufCloseWriter(&bw); // TODO there is a memory leak
1418 1419 1420 1421 1422
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
1423
static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSQLExprItem* pItem) {
H
Haojun Liao 已提交
1424
  SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex);
H
Haojun Liao 已提交
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445

  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 已提交
1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461
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;
    }
  }


  // 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
H
Haojun Liao 已提交
1462
  SColumnIndex index = {0};  // primary timestamp column info
H
Haojun Liao 已提交
1463 1464 1465
  int32_t numOfCols = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
  tscAddSpecialColumnForSelect(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL);

H
Haojun Liao 已提交
1466
  SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols);
H
Haojun Liao 已提交
1467 1468 1469 1470 1471
  pSupInfo->visible = false;

  pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
}

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

1475 1476
  const char* msg2 = "functions can not be mixed up";
  const char* msg3 = "not support query expression";
H
hjxilinx 已提交
1477
  const char* msg5 = "invalid function name";
H
hjxilinx 已提交
1478

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

1481 1482 1483
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
H
Haojun Liao 已提交
1484

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

S
slguan 已提交
1489
    // project on all fields
H
Haojun Liao 已提交
1490 1491
    int32_t optr = pItem->pNode->nSQLOptr;

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

S
slguan 已提交
1498
      // select table_name1.field_name1, table_name2.field_name2  from table_name1, table_name2
1499
      if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
1500
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1501
      }
1502
    } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_TBID) {
S
slguan 已提交
1503
      // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
1504
      if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
1505
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1506 1507 1508
      }

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
1509 1510 1511
      int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
1512 1513
      }
    } else {
1514
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1515 1516
    }

H
hjxilinx 已提交
1517
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1518
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1519 1520 1521
    }
  }

1522 1523 1524
  // 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 已提交
1525
    addPrimaryTsColIntoResult(pQueryInfo);
1526 1527
  }

H
Haojun Liao 已提交
1528
  if (!functionCompatibleCheck(pQueryInfo, joinQuery)) {
1529
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1530 1531
  }

H
Haojun Liao 已提交
1532 1533
  /*
   * transfer sql functions that need secondary merge into another format
1534
   * in dealing with super table queries such as: count/first/last
H
Haojun Liao 已提交
1535
   */
1536
  if (isSTable) {
H
hjxilinx 已提交
1537
    tscTansformSQLFuncForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1538

1539
    if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
1540
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1541 1542 1543 1544 1545 1546
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1547 1548
int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
    int8_t type, char* fieldName, SSqlExpr* pSqlExpr) {
1549
  
S
slguan 已提交
1550
  for (int32_t i = 0; i < pIdList->num; ++i) {
1551 1552 1553 1554 1555 1556 1557 1558
    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;
    }
    
1559
    tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i]));
H
hzcheng 已提交
1560
  }
H
hjxilinx 已提交
1561 1562
  
  TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
H
Haojun Liao 已提交
1563
  SInternalField* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
H
hjxilinx 已提交
1564
  pInfo->pSqlExpr = pSqlExpr;
H
hjxilinx 已提交
1565
  
H
hzcheng 已提交
1566 1567 1568
  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
1569
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1570
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1571 1572 1573
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
1574
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
H
hzcheng 已提交
1575

1576
  int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
1577 1578 1579 1580
  SColumnIndex index = {.tableIndex = tableIndex,};
  
  if (functionId == TSDB_FUNC_TAGPRJ) {
    index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta);
H
hjxilinx 已提交
1581
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
1582 1583 1584
  } else {
    index.columnIndex = colIndex;
  }
H
Haojun Liao 已提交
1585 1586 1587 1588

  int16_t colId = getNewResColId(pQueryInfo);
  return tscSqlExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes, colId, pSchema->bytes,
                          (functionId == TSDB_FUNC_TAGPRJ));
H
hzcheng 已提交
1589 1590
}

H
Haojun Liao 已提交
1591
SSqlExpr* tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1592
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
H
Haojun Liao 已提交
1593 1594
  int16_t colId = getNewResColId(pQueryInfo);

H
Haojun Liao 已提交
1595
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
H
Haojun Liao 已提交
1596
                                     pColSchema->bytes, colId, pColSchema->bytes, TSDB_COL_IS_TAG(flag));
H
Haojun Liao 已提交
1597
  tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName));
H
hzcheng 已提交
1598

S
slguan 已提交
1599 1600 1601 1602
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1603

H
hjxilinx 已提交
1604
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1605 1606

  pExpr->colInfo.flag = flag;
1607 1608
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  
S
slguan 已提交
1609
  if (TSDB_COL_IS_TAG(flag)) {
H
hjxilinx 已提交
1610
    tscColumnListInsert(pTableMetaInfo->tagColList, pIndex);
S
slguan 已提交
1611
  }
H
Haojun Liao 已提交
1612 1613

  return pExpr;
S
slguan 已提交
1614 1615
}

1616
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1617
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1618 1619

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1620 1621
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1622

H
hjxilinx 已提交
1623
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1624
  
weixin_48148422's avatar
weixin_48148422 已提交
1625
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1626
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1627
  } else {
H
hjxilinx 已提交
1628
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1629 1630 1631
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
Haojun Liao 已提交
1632
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, j, pIndex->tableIndex);
B
Bomin Zhang 已提交
1633
    tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName));
S
slguan 已提交
1634 1635 1636 1637

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

H
hjxilinx 已提交
1640
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1641 1642 1643 1644 1645
  }

  return numOfTotalColumns;
}

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

1650
  int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
Haojun Liao 已提交
1651 1652 1653 1654 1655
  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 已提交
1656
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1657
    if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1658
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
1659 1660 1661 1662
    }

    // all meters columns are required
    if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) {  // all table columns are required.
1663
      for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
S
slguan 已提交
1664
        index.tableIndex = i;
1665
        int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1666
        startPos += inc;
H
hzcheng 已提交
1667 1668
      }
    } else {
1669
      doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1670
    }
H
Haojun Liao 已提交
1671 1672 1673

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

H
Haojun Liao 已提交
1677
    // user-specified constant value as a new result column
1678 1679
    index.columnIndex = (pQueryInfo->udColumnId--);
    index.tableIndex = 0;
H
hzcheng 已提交
1680

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

1685 1686 1687 1688 1689
    // 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 已提交
1690

1691 1692 1693
    if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
    }
H
Haojun Liao 已提交
1694

1695 1696 1697 1698 1699 1700
    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 已提交
1701

1702 1703
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1704 1705
      }

1706
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
Haojun Liao 已提交
1707
      pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
H
hzcheng 已提交
1708
    }
H
Haojun Liao 已提交
1709

1710 1711
    // add the primary timestamp column even though it is not required by user
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
hzcheng 已提交
1712
  } else {
1713
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1714 1715 1716 1717 1718
  }

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
1723 1724
  int16_t type = 0;
  int16_t bytes = 0;
Y
TD-1230  
yihaoDeng 已提交
1725
  int32_t functionID = cvtFunc.execFuncId;
H
hzcheng 已提交
1726 1727

  if (functionID == TSDB_FUNC_SPREAD) {
1728
    int32_t t1 = pSchema->type;
1729
    if (t1 == TSDB_DATA_TYPE_BINARY || t1 == TSDB_DATA_TYPE_NCHAR || t1 == TSDB_DATA_TYPE_BOOL) {
1730
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1731 1732 1733 1734 1735 1736
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
1737 1738
    type = pSchema->type;
    bytes = pSchema->bytes;
H
hzcheng 已提交
1739
  }
Y
TD-1230  
yihaoDeng 已提交
1740
  
H
Haojun Liao 已提交
1741
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, getNewResColId(pQueryInfo), bytes, false);
1742
  tstrncpy(pExpr->aliasName, name, tListLen(pExpr->aliasName));
1743

Y
TD-1230  
yihaoDeng 已提交
1744 1745 1746 1747
  if (cvtFunc.originFuncId == TSDB_FUNC_LAST_ROW && cvtFunc.originFuncId != functionID) {
    pExpr->colInfo.flag |= TSDB_COL_NULL;
  }

1748 1749 1750 1751 1752 1753
  // 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 已提交
1754
  
H
hjxilinx 已提交
1755
  // for all queries, the timestamp column needs to be loaded
S
slguan 已提交
1756
  SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1757
  tscColumnListInsert(pQueryInfo->colList, &index);
H
hzcheng 已提交
1758

H
Haojun Liao 已提交
1759
  // if it is not in the final result, do not add it
S
slguan 已提交
1760
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
H
Haojun Liao 已提交
1761
  if (finalResult) {
1762
    insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, pExpr->aliasName, pExpr);
H
Haojun Liao 已提交
1763 1764 1765
  } else {
    tscColumnListInsert(pQueryInfo->colList, &(ids.ids[0]));
  }
H
hzcheng 已提交
1766 1767 1768 1769

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
1770
void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrToken* pToken, bool multiCols) {
1771 1772
  if (pItem->aliasName != NULL) {
    tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN);
H
Haojun Liao 已提交
1773
  } else if (multiCols) {
1774 1775 1776 1777
    char uname[TSDB_COL_NAME_LEN] = {0};
    int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN);
    tstrncpy(uname, pToken->z, len);

1778 1779 1780 1781 1782 1783
    if (tsKeepOriginalColumnName) { // keep the original column name
      tstrncpy(name, uname, TSDB_COL_NAME_LEN);
    } else {
      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);
H
Haojun Liao 已提交
1784

1785 1786
      tstrncpy(name, tmp, TSDB_COL_NAME_LEN);
    }
H
Haojun Liao 已提交
1787 1788 1789
  } else  { // use the user-input result column name
    int32_t len = MIN(pItem->pNode->token.n + 1, TSDB_COL_NAME_LEN);
    tstrncpy(name, pItem->pNode->token.z, len);
1790 1791 1792
  }
}

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

1797
  const char* msg1 = "not support column types";
S
slguan 已提交
1798
  const char* msg2 = "invalid parameters";
1799
  const char* msg3 = "illegal column name";
S
slguan 已提交
1800
  const char* msg4 = "invalid table name";
1801
  const char* msg5 = "parameter is out of range [0, 100]";
S
slguan 已提交
1802
  const char* msg6 = "function applied to tags not allowed";
1803
  const char* msg7 = "normal table can not apply this function";
H
Haojun Liao 已提交
1804
  const char* msg8 = "multi-columns selection does not support alias column name";
B
Bomin Zhang 已提交
1805
  const char* msg9 = "invalid function";
H
Haojun Liao 已提交
1806

H
hzcheng 已提交
1807 1808 1809
  switch (optr) {
    case TK_COUNT: {
        /* more than one parameter for count() function */
H
Haojun Liao 已提交
1810
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
1811
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1812 1813 1814
      }

      int16_t functionID = 0;
H
Haojun Liao 已提交
1815
      if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
1816
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1817 1818
      }

H
hjxilinx 已提交
1819
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1820
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1821 1822

      if (pItem->pNode->pParam != NULL) {
S
slguan 已提交
1823
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
Y
TD-1370  
yihaoDeng 已提交
1824
        SStrToken* pToken = &pParamElem->pNode->colInfo;
S
TD-1530  
Shengliang Guan 已提交
1825
        int16_t sqlOptr = pParamElem->pNode->nSQLOptr;
Y
TD-1370  
yihaoDeng 已提交
1826 1827 1828 1829 1830
        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 已提交
1831 1832
          // select table.*
          // check if the table name is valid or not
H
Haojun Liao 已提交
1833
          SStrToken tmpToken = pParamElem->pNode->colInfo;
S
slguan 已提交
1834

1835
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1836
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1837 1838 1839 1840
          }

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1841
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
Y
TD-1370  
yihaoDeng 已提交
1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852
        } 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;
H
Haojun Liao 已提交
1853
            pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
Y
TD-1370  
yihaoDeng 已提交
1854 1855 1856
          } else {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
          }
H
hzcheng 已提交
1857
        } else {
H
hjxilinx 已提交
1858
          // count the number of meters created according to the super table
1859 1860
          if (getColumnIndexByName(pCmd, pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1861 1862
          }

H
hjxilinx 已提交
1863
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1864 1865

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1866 1867
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1868
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1869
            isTag = true;
H
hzcheng 已提交
1870 1871
          }

S
slguan 已提交
1872
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1873
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, isTag);
H
hzcheng 已提交
1874
        }
S
slguan 已提交
1875 1876 1877
      } 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;
H
Haojun Liao 已提交
1878
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
H
hzcheng 已提交
1879
      }
H
Haojun Liao 已提交
1880 1881 1882

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

H
hjxilinx 已提交
1883
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1884
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1885
      
S
slguan 已提交
1886
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1887 1888 1889 1890 1891
      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) {
1892
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1893 1894
        }
      }
H
Haojun Liao 已提交
1895 1896

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

S
slguan 已提交
1901
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1902 1903 1904
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1905 1906 1907 1908 1909 1910
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1911
    case TK_TWA:
H
hzcheng 已提交
1912 1913 1914 1915 1916 1917 1918 1919 1920
    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 */
1921
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1922 1923 1924 1925
      }

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

S
slguan 已提交
1929
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
Y
yihaoDeng 已提交
1930
      if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
1931
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1932
      }
Y
yihaoDeng 已提交
1933 1934 1935
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
H
hzcheng 已提交
1936 1937

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

H
hjxilinx 已提交
1942
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1943
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1944 1945 1946 1947
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
1948
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1949 1950

      int16_t functionID = 0;
H
Haojun Liao 已提交
1951
      if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
1952
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1953 1954
      }

S
slguan 已提交
1955 1956
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
1957
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1958
      }
H
hzcheng 已提交
1959

S
slguan 已提交
1960
      // set the first column ts for diff query
H
hzcheng 已提交
1961
      if (optr == TK_DIFF) {
1962
        colIndex += 1;
S
slguan 已提交
1963
        SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
H
hjxilinx 已提交
1964
        SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
H
Haojun Liao 已提交
1965
                                           getNewResColId(pQueryInfo), TSDB_KEYSIZE, false);
H
hzcheng 已提交
1966

S
slguan 已提交
1967
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1968
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1969 1970
      }

S
slguan 已提交
1971
      // functions can not be applied to tags
H
hjxilinx 已提交
1972
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1973
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1974 1975
      }

H
Haojun Liao 已提交
1976
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false);
H
hzcheng 已提交
1977 1978 1979 1980

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

H
Haojun Liao 已提交
1985
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES);
H
hzcheng 已提交
1986 1987

        memset(val, 0, tListLen(val));
1988
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1989
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1990 1991
        }

H
Haojun Liao 已提交
1992
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
H
hzcheng 已提交
1993 1994
      }

S
slguan 已提交
1995 1996 1997
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1998 1999
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
2000
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
2001 2002 2003
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
S
TD-1057  
Shengliang Guan 已提交
2004
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, (int32_t)pExpr->resType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
2005 2006
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
2007
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
2008 2009
        }
      }
H
Haojun Liao 已提交
2010 2011

      tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
S
slguan 已提交
2012
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2013 2014 2015 2016 2017 2018 2019 2020 2021
    }
    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 已提交
2022
      if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
2023
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
B
Bomin Zhang 已提交
2024
      }
2025 2026

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

H
hzcheng 已提交
2032 2033
      if (!requireAllFields) {
        if (pItem->pNode->pParam->nExpr < 1) {
2034
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
2035 2036
        }

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

H
hzcheng 已提交
2041 2042 2043 2044
        /* 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) {
2045
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
2046 2047
          }

S
slguan 已提交
2048 2049
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

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

2053
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
2054
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
2055 2056
            }

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

2060
            char name[TSDB_COL_NAME_LEN] = {0};
H
hjxilinx 已提交
2061
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
2062
              index.columnIndex = j;
S
Shengliang Guan 已提交
2063
              SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
H
Haojun Liao 已提交
2064
              setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
2065 2066

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

S
slguan 已提交
2071
          } else {
2072 2073
            if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2074 2075
            }

H
hjxilinx 已提交
2076
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
2077 2078

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

2083 2084 2085
            char name[TSDB_COL_NAME_LEN] = {0};

            SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
H
Haojun Liao 已提交
2086 2087 2088

            bool multiColOutput = pItem->pNode->pParam->nExpr > 1;
            setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo, multiColOutput);
2089 2090

            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
2091
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2092
            }
2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108

            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 已提交
2109 2110
          }
        }
2111
        
S
slguan 已提交
2112 2113 2114 2115
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

H
Haojun Liao 已提交
2116
        // multicolumn selection does not support alias name
H
Haojun Liao 已提交
2117
        if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
2118
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
2119 2120
        }

2121
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
2122
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
2123
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
2124

H
hjxilinx 已提交
2125
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
2126
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
2127 2128

            char name[TSDB_COL_NAME_LEN] = {0};
2129
            SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
H
Haojun Liao 已提交
2130
            setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
2131 2132

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

            colIndex++;
H
hzcheng 已提交
2137
          }
S
slguan 已提交
2138

H
hjxilinx 已提交
2139
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
2140 2141
        }

2142
        
S
slguan 已提交
2143
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2144 2145 2146 2147 2148 2149 2150 2151 2152
      }
    }
    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 */
2153
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2154 2155 2156 2157
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
2158
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2159
      }
H
hjxilinx 已提交
2160
      
S
slguan 已提交
2161
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2162 2163
      if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2164
      }
Y
yihaoDeng 已提交
2165 2166 2167 2168
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
      
H
hjxilinx 已提交
2169
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2170
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
2171 2172

      // functions can not be applied to tags
H
hjxilinx 已提交
2173
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
2174
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
2175 2176 2177
      }

      // 2. valid the column type
S
slguan 已提交
2178
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
2179
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
2180
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2181 2182 2183 2184
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
2185
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2186 2187 2188 2189
      }

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

S
slguan 已提交
2190 2191
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
2192

H
hjxilinx 已提交
2193
      char    val[8] = {0};
H
hjxilinx 已提交
2194 2195
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
2196
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
2197
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
2198

L
lihui 已提交
2199
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
2200
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
2201
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212
        }

        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 已提交
2213
        if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
2214
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2215
        }
dengyihao's avatar
dengyihao 已提交
2216 2217
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
        colIndex += 1;  // the first column is ts
H
hzcheng 已提交
2218

H
Haojun Liao 已提交
2219 2220
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false);
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
H
hzcheng 已提交
2221
      } else {
2222
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
2223

H
Haojun Liao 已提交
2224
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
2225
        if (nTop <= 0 || nTop > 100) {  // todo use macro
2226
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2227 2228 2229
        }

        int16_t functionId = 0;
H
Haojun Liao 已提交
2230
        if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
2231
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2232
        }
S
slguan 已提交
2233

H
Haojun Liao 已提交
2234
        // todo REFACTOR
H
hzcheng 已提交
2235
        // set the first column ts for top/bottom query
S
slguan 已提交
2236
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
H
Haojun Liao 已提交
2237 2238
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pQueryInfo),
                                 TSDB_KEYSIZE, false);
H
Haojun Liao 已提交
2239
        tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
S
slguan 已提交
2240

H
Haojun Liao 已提交
2241
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
2242
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
2243
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
2244
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
2245

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

H
Haojun Liao 已提交
2248 2249
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false);
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t));
H
hzcheng 已提交
2250
      }
H
hjxilinx 已提交
2251 2252
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
2253
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
2254
  
S
slguan 已提交
2255
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
2256
      if (finalResult) {
2257
        insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
2258 2259
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
2260
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
2261 2262
        }
      }
S
slguan 已提交
2263

2264 2265 2266 2267 2268
      return TSDB_CODE_SUCCESS;
    };
    
    case TK_TBID: {
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2269
      if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
2270
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
2271 2272 2273 2274
      }
    
      // no parameters or more than one parameter for function
      if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 1) {
2275
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2276 2277 2278 2279 2280
      }
      
      tSQLExpr* pParam = pItem->pNode->pParam->a[0].pNode;
    
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2281 2282
      if (getColumnIndexByName(pCmd, &pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2283 2284 2285 2286 2287 2288 2289
      }
    
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
  
      // functions can not be applied to normal columns
      int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
2290
      if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
2291
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2292 2293
      }
    
2294 2295 2296
      if (index.columnIndex > 0) {
        index.columnIndex -= numOfCols;
      }
2297 2298
      
      // 2. valid the column type
2299 2300 2301 2302 2303 2304 2305 2306
      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) {
2307
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
2308 2309 2310 2311
      }

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
2312 2313 2314
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
2315
        s = tGetTableNameColumnSchema();
2316 2317 2318 2319
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
2320 2321
      int16_t bytes = 0;
      int16_t type  = 0;
2322
      int32_t inter = 0;
2323 2324 2325 2326

      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 已提交
2327
      s.type = (uint8_t)type;
2328 2329 2330 2331 2332
      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 已提交
2333
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2334
    }
2335
    
H
hzcheng 已提交
2336
    default:
2337
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2338
  }
2339
  
H
hzcheng 已提交
2340 2341
}

S
slguan 已提交
2342 2343
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
2344
  assert(num == 1 && tableIndex >= 0);
S
slguan 已提交
2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355

  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 已提交
2356 2357 2358 2359
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
S
TD-1057  
Shengliang Guan 已提交
2360
    int32_t len = ((int32_t)pItem->pNode->operand.n < nameLength) ? (int32_t)pItem->pNode->operand.n : nameLength;
H
hzcheng 已提交
2361 2362 2363 2364
    strncpy(resultFieldName, pItem->pNode->operand.z, len);
  }
}

H
Haojun Liao 已提交
2365 2366 2367
static bool isTablenameToken(SStrToken* token) {
  SStrToken tmpToken = *token;
  SStrToken tableToken = {0};
S
slguan 已提交
2368 2369 2370 2371 2372 2373

  extractTableNameFromToken(&tmpToken, &tableToken);

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

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

H
hjxilinx 已提交
2377 2378
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2379 2380 2381 2382 2383 2384 2385 2386 2387 2388

  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 已提交
2389
      break;
S
slguan 已提交
2390 2391 2392 2393 2394 2395
    }
  }

  return columnIndex;
}

H
Haojun Liao 已提交
2396
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2397 2398 2399 2400 2401 2402 2403 2404 2405 2406
  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) {
2407 2408
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2409 2410 2411

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2412
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
2413 2414 2415 2416 2417 2418 2419
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2420
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2421 2422 2423 2424 2425 2426
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2427
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2428 2429 2430 2431 2432 2433
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2434
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2435 2436 2437
  }
}

H
Haojun Liao 已提交
2438
int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2439
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2440
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2441
      pIndex->tableIndex = 0;
2442 2443
    } else {
      pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
S
slguan 已提交
2444 2445 2446 2447 2448 2449
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
2450
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2451
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
Haojun Liao 已提交
2452 2453
    char* name = pTableMetaInfo->aliasName;
    if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
S
slguan 已提交
2454 2455 2456 2457 2458 2459
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
2460
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2461 2462 2463 2464 2465
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
2466 2467
int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SStrToken tableToken = {0};
S
slguan 已提交
2468 2469
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2470
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2471
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2472 2473
  }

S
slguan 已提交
2474 2475
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2476

H
Haojun Liao 已提交
2477
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2478
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2479
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2480 2481
  }

H
Haojun Liao 已提交
2482
  SStrToken tmpToken = *pToken;
S
slguan 已提交
2483

2484
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2485
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2486 2487
  }

2488
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2489 2490
}

H
Haojun Liao 已提交
2491
int32_t convertFunctionId(int32_t optr, int16_t* functionId) {
H
hzcheng 已提交
2492 2493 2494 2495 2496 2497 2498 2499 2500 2501
  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 已提交
2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519
    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 已提交
2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555
    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 已提交
2556 2557
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572
      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 已提交
2573
  SSqlCmd*        pCmd = &pSql->cmd;
2574
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2575
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2576

H
hzcheng 已提交
2577 2578
  pCmd->command = TSDB_SQL_SHOW;

2579
  const char* msg1 = "invalid name";
2580
  const char* msg2 = "pattern filter string too long";
2581 2582 2583 2584
  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 已提交
2585 2586 2587 2588 2589

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2590 2591 2592
  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 已提交
2593
    // db prefix in tagCond, show table conds in payload
H
Haojun Liao 已提交
2594
    SStrToken* pDbPrefixToken = &pShowInfo->prefix;
2595
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2596

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

2601
      if (pDbPrefixToken->n <= 0) {
2602
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2603 2604
      }

2605
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2606
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2607 2608
      }

H
hjxilinx 已提交
2609
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2610
      if (ret != TSDB_CODE_SUCCESS) {
2611
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2612
      }
2613
    }
H
hzcheng 已提交
2614

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

2620
      if (pPattern->n <= 0) {
2621
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2622
      }
H
hzcheng 已提交
2623

H
Haojun Liao 已提交
2624
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2625
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2626 2627
      }
    }
2628 2629
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2630
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2631 2632
    }

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

2639
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2640
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2641
    }
H
hzcheng 已提交
2642 2643 2644 2645 2646
  }

  return TSDB_CODE_SUCCESS;
}

2647 2648 2649 2650
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 已提交
2651

2652 2653
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2654
  
H
Haojun Liao 已提交
2655
  SStrToken* idStr = &(pInfo->pDCLInfo->ip);
2656
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2657
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2658 2659
  }

2660
  strncpy(pCmd->payload, idStr->z, idStr->n);
2661

H
hzcheng 已提交
2662
  const char delim = ':';
2663 2664
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2665

2666 2667 2668 2669 2670
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2671

2672 2673 2674 2675 2676 2677
  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 已提交
2678
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2679 2680 2681 2682 2683
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2684
  }
2685
  
H
hzcheng 已提交
2686 2687 2688
  return TSDB_CODE_SUCCESS;
}

2689 2690 2691 2692 2693 2694
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);

2695
  in_addr_t epAddr = taosInetAddr(tmp);
2696

2697
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2698 2699
}

H
hjxilinx 已提交
2700
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2701
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2702

weixin_48148422's avatar
weixin_48148422 已提交
2703
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2704
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2705 2706
  }

H
hjxilinx 已提交
2707
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2708 2709 2710

  int16_t bytes = 0;
  int16_t type = 0;
2711
  int32_t interBytes = 0;
H
hjxilinx 已提交
2712 2713 2714
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2715
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2716 2717
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

2718
    int32_t colIndex = pExpr->colInfo.colIndex;
H
hjxilinx 已提交
2719
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2720
    
S
slguan 已提交
2721
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2722 2723
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
S
TD-1057  
Shengliang Guan 已提交
2724
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64Key, &type, &bytes,
2725
                            &interBytes, 0, true) != TSDB_CODE_SUCCESS) {
2726
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2727
      }
H
hzcheng 已提交
2728

2729
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2730
      // todo refactor
2731
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2732 2733 2734
    }
  }

H
Haojun Liao 已提交
2735
  tscFieldInfoUpdateOffset(pQueryInfo);
S
slguan 已提交
2736
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2737 2738 2739
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2740
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2741
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2742
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2743 2744
    return;
  }
H
hjxilinx 已提交
2745 2746 2747
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2748
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2749
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2750
    
2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767
    // 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 已提交
2768 2769 2770
  }
}

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

S
slguan 已提交
2776
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2777 2778
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2779
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
2780
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
2781
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2782
      return true;
H
hzcheng 已提交
2783 2784 2785
    }
  }

2786 2787
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2788
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2789 2790
      return true;
    }
H
hzcheng 已提交
2791

2792
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2793
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2794
      return true;
2795 2796 2797
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
2798
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2799 2800
        return true;
      }
H
hzcheng 已提交
2801 2802
    }
  }
S
slguan 已提交
2803

H
hzcheng 已提交
2804 2805 2806
  return false;
}

H
Haojun Liao 已提交
2807
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
H
hzcheng 已提交
2808
  int32_t startIdx = 0;
2809 2810 2811 2812

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

H
hjxilinx 已提交
2813 2814
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2815 2816

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

H
Haojun Liao 已提交
2821
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2822 2823 2824

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2825 2826 2827
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2828
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2829

H
hjxilinx 已提交
2830
    int16_t functionId = pExpr1->functionId;
2831 2832 2833 2834
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
Haojun Liao 已提交
2835
    if (functionId == TSDB_FUNC_PRJ && (pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->colInfo.flag))) {
S
slguan 已提交
2836 2837 2838
      continue;
    }

H
Haojun Liao 已提交
2839
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2840
      return false;
2841 2842 2843 2844
    } else {
      if (factor == -1) { // two functions with the same -1 flag
        return false;
      }
H
hzcheng 已提交
2845
    }
H
Haojun Liao 已提交
2846 2847 2848 2849

    if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
      return false;
    }
H
hzcheng 已提交
2850 2851 2852 2853 2854
  }

  return true;
}

H
Haojun Liao 已提交
2855
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) {
2856 2857
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
2858
  const char* msg3 = "columns from one table allowed as group by columns";
2859
  const char* msg4 = "join query does not support group by";
S
slguan 已提交
2860 2861 2862
  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 已提交
2863

2864
  // todo : handle two tables situation
H
hjxilinx 已提交
2865
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2866 2867 2868 2869 2870

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

2871 2872 2873 2874
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
S
Shengliang Guan 已提交
2875
  pQueryInfo->groupbyExpr.numOfGroupCols = (int16_t)taosArrayGetSize(pList);
H
Haojun Liao 已提交
2876
  if (pQueryInfo->groupbyExpr.numOfGroupCols > TSDB_MAX_TAGS) {
2877
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2878 2879
  }

2880 2881 2882 2883
  if (pQueryInfo->numOfTables > 1) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
  }

H
hjxilinx 已提交
2884
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2885
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2886
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2887

S
slguan 已提交
2888
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
H
Haojun Liao 已提交
2889 2890 2891 2892 2893 2894

  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 已提交
2895
    SStrToken token = {pVar->nLen, pVar->nType, pVar->pz};
H
hzcheng 已提交
2896

S
slguan 已提交
2897
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2898 2899
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2900
    }
H
hzcheng 已提交
2901

2902 2903 2904 2905 2906
    if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
      tableIndex = index.tableIndex;
    } else if (tableIndex != index.tableIndex) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2907

H
hjxilinx 已提交
2908
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2909
    pTableMeta = pTableMetaInfo->pTableMeta;
2910 2911
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2912 2913 2914
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2915
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2916
    }
H
hzcheng 已提交
2917

S
slguan 已提交
2918
    bool groupTag = false;
2919
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2920
      groupTag = true;
H
hzcheng 已提交
2921
    }
2922 2923 2924 2925 2926 2927
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2928
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2929
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2930
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
S
slguan 已提交
2931 2932
      }

2933 2934 2935 2936
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2937

H
hjxilinx 已提交
2938
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2939
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2940 2941 2942
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2943 2944
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
H
Haojun Liao 已提交
2945
      if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) {
2946
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
2947 2948
      }

2949
      tscColumnListInsert(pQueryInfo->colList, &index);
2950
      
2951
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2952
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2953
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2954

H
Haojun Liao 已提交
2955
      if (i == 0 && num > 1) {
2956
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2957
      }
H
hzcheng 已提交
2958 2959 2960
    }
  }

2961
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2962 2963 2964
  return TSDB_CODE_SUCCESS;
}

2965
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2966 2967 2968
  if (pColumn == NULL) {
    return NULL;
  }
2969

S
slguan 已提交
2970
  int32_t size = pColumn->numOfFilters + 1;
2971 2972

  char* tmp = (char*) realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2973 2974
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2975 2976
  } else {
    return NULL;
2977 2978
  }

S
slguan 已提交
2979
  pColumn->numOfFilters++;
2980

S
slguan 已提交
2981 2982 2983 2984
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2985 2986
}

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

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

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

S
slguan 已提交
2996
  int16_t colType = pSchema->type;
2997
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2998 2999 3000
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
3001
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
3002
    int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
3003 3004 3005
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
3006 3007
  }

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

B
Bomin Zhang 已提交
3012 3013 3014 3015 3016
  // 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 已提交
3017

B
Bomin Zhang 已提交
3018 3019 3020 3021 3022 3023
  } 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 已提交
3024

B
Bomin Zhang 已提交
3025 3026
  } else {
    retVal = tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
3027 3028
  }

B
Bomin Zhang 已提交
3029 3030 3031 3032
  if (retVal != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  } 

H
hzcheng 已提交
3033 3034
  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
3035
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
3036 3037
      break;
    case TK_LT:
S
slguan 已提交
3038
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
3039 3040
      break;
    case TK_GT:
3041
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
3042 3043
      break;
    case TK_GE:
3044
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
3045 3046
      break;
    case TK_EQ:
S
slguan 已提交
3047
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
3048 3049
      break;
    case TK_NE:
S
slguan 已提交
3050
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
3051 3052
      break;
    case TK_LIKE:
S
slguan 已提交
3053
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
3054
      break;
H
Haojun Liao 已提交
3055 3056 3057 3058 3059 3060
    case TK_ISNULL:
      pColumnFilter->lowerRelOptr = TSDB_RELATION_ISNULL;
      break;
    case TK_NOTNULL:
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOTNULL;
      break;
S
slguan 已提交
3061
    default:
3062
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
3063
  }
S
slguan 已提交
3064

3065
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3066 3067
}

S
slguan 已提交
3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081
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 已提交
3082

H
hjxilinx 已提交
3083
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
3084 3085

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
3086
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
3087 3088
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
3089 3090

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

H
hjxilinx 已提交
3093 3094 3095 3096 3097 3098 3099
  } 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 已提交
3100 3101 3102 3103 3104 3105
    assert(false);
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
3106
// pExpr->nSQLOptr == 0 while handling "is null" query
S
slguan 已提交
3107 3108
static bool isExprLeafNode(tSQLExpr* pExpr) {
  return (pExpr->pRight == NULL && pExpr->pLeft == NULL) &&
H
Haojun Liao 已提交
3109
         (pExpr->nSQLOptr == 0 || pExpr->nSQLOptr == TK_ID || (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_NCHAR) || pExpr->nSQLOptr == TK_SET);
S
slguan 已提交
3110 3111
}

H
Haojun Liao 已提交
3112
static bool isExprDirectParentOfLeafNode(tSQLExpr* pExpr) {
S
slguan 已提交
3113 3114 3115 3116 3117
  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 已提交
3118
  if (!isExprDirectParentOfLeafNode(pExpr)) {
3119
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3120 3121
  }

S
slguan 已提交
3122 3123 3124 3125 3126 3127 3128 3129 3130 3131
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
3132
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3133 3134 3135 3136 3137 3138 3139 3140 3141
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
3142 3143 3144 3145
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
3146 3147 3148 3149
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197

  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:
3198
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3199 3200 3201 3202 3203 3204 3205
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3206
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
3207 3208
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
3209
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3210 3211
  }

S
slguan 已提交
3212
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
3213
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
3214 3215
  }

H
hzcheng 已提交
3216 3217
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
3218
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
3219 3220

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

H
Haojun Liao 已提交
3224
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
3225
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3226 3227 3228 3229 3230 3231
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3232
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
3233 3234
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
3235 3236

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3237 3238
}

S
slguan 已提交
3239 3240 3241 3242 3243 3244
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
3245

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

H
hjxilinx 已提交
3249 3250
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
3251

S
slguan 已提交
3252
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
3253 3254
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
3255

H
hjxilinx 已提交
3256
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269
  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];
    }
3270 3271 3272 3273

    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3274 3275 3276
  } else if (sqlOptr == TK_OR) {
    // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
    pColFilter = addColumnFilterInfo(pColumn);
3277 3278 3279
    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3280
  } else {  // error;
3281
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3282 3283
  }

3284
  pColFilter->filterstr =
S
slguan 已提交
3285 3286
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

3287
  if (pColFilter->filterstr) {
3288 3289 3290 3291 3292 3293
    if (pExpr->nSQLOptr != TK_EQ
      && pExpr->nSQLOptr != TK_NE
      && pExpr->nSQLOptr != TK_ISNULL
      && pExpr->nSQLOptr != TK_NOTNULL
      && pExpr->nSQLOptr != TK_LIKE
      ) {
3294
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3295
    }
S
slguan 已提交
3296 3297
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
3298
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
3299
    }
H
Hui Li 已提交
3300 3301 3302
    
    if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
      if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
3303
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Hui Li 已提交
3304 3305
      }
    }
S
slguan 已提交
3306 3307 3308
  }

  pColumn->colIndex = *pIndex;
3309
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
3310 3311
}

3312
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3313 3314 3315 3316 3317
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

3318
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
3319 3320 3321 3322 3323 3324 3325 3326 3327
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

3328
UNUSED_FUNC
3329
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3330 3331 3332 3333
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
3334
  if (!isExprDirectParentOfLeafNode(pExpr)) {
S
slguan 已提交
3335 3336
    *(*str) = '(';
    *str += 1;
H
hzcheng 已提交
3337

3338
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
3339
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3340
      return ret;
H
hzcheng 已提交
3341
    }
S
slguan 已提交
3342

3343
    relToString(pExpr, str);
S
slguan 已提交
3344

3345
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
3346 3347 3348 3349

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

H
hzcheng 已提交
3350 3351 3352
    return ret;
  }

S
slguan 已提交
3353 3354 3355
  return tSQLExprLeafToString(pExpr, true, str);
}

3356
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
3357 3358 3359 3360
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
3363 3364
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
3365

S
slguan 已提交
3366
  if (!isTablenameToken(&pLeft->colInfo)) {
3367
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3368 3369
  }

S
slguan 已提交
3370
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3371

S
slguan 已提交
3372
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
3373
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
3374
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3375
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
3376
  }
H
hzcheng 已提交
3377

S
slguan 已提交
3378
  if (ret != TSDB_CODE_SUCCESS) {
3379
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3380
  }
H
hzcheng 已提交
3381

S
slguan 已提交
3382 3383 3384
  return ret;
}

3385
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3386 3387 3388 3389
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
3390
  if (!isExprDirectParentOfLeafNode(pExpr)) {  // internal node
3391
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3392 3393 3394 3395
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3396
    return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3397 3398
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3399
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3400
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3401
    }
S
slguan 已提交
3402

3403
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3404
  }
S
slguan 已提交
3405
}
H
hzcheng 已提交
3406

3407
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
H
Haojun Liao 已提交
3408 3409 3410
  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 已提交
3411

S
slguan 已提交
3412 3413 3414
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3415

H
Haojun Liao 已提交
3416
  if (!isExprDirectParentOfLeafNode(pExpr)) {
3417
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3418 3419
  }

3420
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3421 3422 3423 3424
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3425 3426
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3427 3428
  }

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

3432
  pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3433
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3434
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3435 3436

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3437 3438
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3439 3440
  }

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

3444
  pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3445
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3446
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3447

H
Haojun Liao 已提交
3448
  if (pTagSchema1->type != pTagSchema2->type) {
3449
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3450 3451
  }

S
slguan 已提交
3452
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3453 3454 3455 3456
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3461
  *(*exprString)++ = '(';
H
hzcheng 已提交
3462 3463

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3464
    doArithmeticExprToString(pLeft, exprString);
H
hzcheng 已提交
3465
  } else {
S
slguan 已提交
3466
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3467
    if (ret != TSDB_CODE_SUCCESS) {
3468
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3469 3470 3471 3472 3473 3474
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3475
    doArithmeticExprToString(pRight, exprString);
H
hzcheng 已提交
3476
  } else {
S
slguan 已提交
3477
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3478
    if (ret != TSDB_CODE_SUCCESS) {
3479
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3480 3481 3482
    }
  }

H
hjxilinx 已提交
3483
  *(*exprString)++ = ')';
H
hzcheng 已提交
3484 3485 3486 3487

  return TSDB_CODE_SUCCESS;
}

3488 3489
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList,
    int32_t* type, uint64_t* uid) {
H
hzcheng 已提交
3490
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3491 3492 3493
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
3494
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3495
    }
L
lihui 已提交
3496

H
hjxilinx 已提交
3497
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3498
    if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3499
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3500 3501 3502
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3503
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3504 3505
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3506 3507
    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)) {
3508
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3509 3510 3511
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3512
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
3513
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3514 3515 3516 3517
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
3518
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3519 3520
    }

S
TD-1057  
Shengliang Guan 已提交
3521
    int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
3522
  
H
hjxilinx 已提交
3523 3524
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
H
Haojun Liao 已提交
3525 3526
    // sql function list in selection clause.
    // Append the sqlExpr into exprList of pQueryInfo structure sequentially
3527
    if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
3528
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3529
    }
H
Haojun Liao 已提交
3530 3531 3532 3533 3534 3535 3536 3537

    // 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
3538
    uint64_t id = -1;
H
Haojun Liao 已提交
3539 3540 3541 3542 3543 3544
    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;
      }
3545 3546 3547

      if (i == 0) {
        id = p1->uid;
H
Haojun Liao 已提交
3548
      } else if (id != p1->uid) {
3549 3550
        return TSDB_CODE_TSC_INVALID_SQL;
      }
H
Haojun Liao 已提交
3551
    }
3552 3553

    *uid = id;
H
hzcheng 已提交
3554 3555 3556 3557 3558
  }

  return TSDB_CODE_SUCCESS;
}

3559
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3560 3561 3562 3563 3564
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
3565 3566 3567
  uint64_t uidLeft = 0;
  uint64_t uidRight = 0;

H
hzcheng 已提交
3568
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3569
    int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3570 3571 3572 3573
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3574
    int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type, &uidLeft);
H
hzcheng 已提交
3575 3576 3577 3578 3579 3580 3581
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3582
    int32_t ret = validateArithmeticSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3583 3584 3585 3586
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3587
    int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type, &uidRight);
H
hzcheng 已提交
3588 3589 3590
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
3591 3592

    // the expression not from the same table, return error
3593
    if (uidLeft != uidRight && uidLeft != 0 && uidRight != 0) {
3594 3595
      return TSDB_CODE_TSC_INVALID_SQL;
    }
H
hzcheng 已提交
3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607
  }

  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 已提交
3608 3609 3610
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3611 3612 3613
   *
   * However, columnA < 4+12 is valid
   */
B
Bomin Zhang 已提交
3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629
  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 已提交
3630 3631 3632 3633 3634 3635
    return false;
  }

  return true;
}

S
slguan 已提交
3636 3637 3638
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3639

S
slguan 已提交
3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664
  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 已提交
3665

S
slguan 已提交
3666 3667 3668 3669 3670
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3671
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684
  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) {
3685
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3686 3687 3688 3689 3690
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3691 3692
  if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3693
    return false;
H
hzcheng 已提交
3694 3695
  }

S
slguan 已提交
3696
  // todo extract function
H
hjxilinx 已提交
3697
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3698
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3699 3700
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3701
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3702
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3703 3704 3705
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3706
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3707 3708
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3709
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3710
    return false;
H
hzcheng 已提交
3711 3712
  }

S
slguan 已提交
3713
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3714
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3715
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
S
slguan 已提交
3716 3717
    return false;
  }
H
hzcheng 已提交
3718

S
slguan 已提交
3719 3720
  return true;
}
H
hzcheng 已提交
3721

S
slguan 已提交
3722 3723 3724 3725 3726 3727
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 已提交
3728 3729 3730
    }
  }

S
slguan 已提交
3731
  return false;
H
hzcheng 已提交
3732 3733
}

3734
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3735 3736
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3737
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3738
    }
H
hzcheng 已提交
3739

S
slguan 已提交
3740 3741 3742 3743
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3744

S
slguan 已提交
3745 3746
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3747

3748 3749
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                                     int32_t* type, int32_t parentOptr) {
3750
  const char* msg1 = "table query cannot use tags filter";
S
slguan 已提交
3751 3752 3753
  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 已提交
3754 3755 3756
  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";
3757 3758
  const char* msg8 = "wildcard string should be less than 20 characters";
  
S
slguan 已提交
3759 3760
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3761

S
slguan 已提交
3762 3763 3764
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3765 3766
  if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3767 3768
  }

H
Haojun Liao 已提交
3769
  assert(isExprDirectParentOfLeafNode(*pExpr));
S
slguan 已提交
3770

H
hjxilinx 已提交
3771
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3772
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3773 3774

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3775
    if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3776
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3777
    }
S
slguan 已提交
3778 3779 3780

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
H
hjxilinx 已提交
3781
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
S
slguan 已提交
3782 3783 3784 3785 3786 3787 3788 3789
      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 {
3790
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3791 3792 3793 3794
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3795 3796
  } 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 已提交
3797
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3798
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3799 3800 3801 3802 3803
    }

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

H
hjxilinx 已提交
3807
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3808 3809 3810

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

H
Haojun Liao 已提交
3815
    // in case of in operator, keep it in a seprate attribute
S
slguan 已提交
3816 3817
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3818
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
3819
      }
3820 3821
  
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
3822
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
3823
      }
S
slguan 已提交
3824 3825 3826 3827 3828 3829

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3830
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
3831 3832 3833 3834 3835
      }

      *type = TSQL_EXPR_TBNAME;
      *pExpr = NULL;
    } else {
H
Haojun Liao 已提交
3836
      if (pRight != NULL && pRight->nSQLOptr == TK_ID) {  // join on tag columns for stable query
3837
        if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3838
          return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3839 3840 3841
        }

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

3845 3846
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860
        *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
3861
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
3862 3863
    }

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

S
slguan 已提交
3868
  return ret;
H
hzcheng 已提交
3869 3870
}

3871 3872
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                        int32_t* type, int32_t parentOptr) {
H
hzcheng 已提交
3873 3874 3875 3876
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3879 3880 3881 3882
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3883
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3884 3885
  }

S
slguan 已提交
3886 3887
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3888

H
Haojun Liao 已提交
3889
  if (!isExprDirectParentOfLeafNode(*pExpr)) {
3890
    int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3891 3892 3893 3894
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3895
    ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3896 3897 3898
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3899

S
slguan 已提交
3900 3901 3902 3903 3904 3905
    /*
     *  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)) {
3906
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3907
      }
H
hzcheng 已提交
3908 3909
    }

S
slguan 已提交
3910 3911 3912
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3913

S
slguan 已提交
3914
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3915

3916
  return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3917
}
H
hzcheng 已提交
3918

S
slguan 已提交
3919
static void doCompactQueryExpr(tSQLExpr** pExpr) {
3920
  if (*pExpr == NULL || isExprDirectParentOfLeafNode(*pExpr)) {
S
slguan 已提交
3921 3922
    return;
  }
H
hzcheng 已提交
3923

S
slguan 已提交
3924 3925 3926
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3927

S
slguan 已提交
3928 3929 3930
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3931

S
slguan 已提交
3932 3933 3934 3935
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3936

S
slguan 已提交
3937 3938 3939
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3940

S
slguan 已提交
3941 3942 3943 3944
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3945

S
slguan 已提交
3946
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3947
  }
S
slguan 已提交
3948
}
H
hzcheng 已提交
3949

3950
static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
H
Haojun Liao 已提交
3951
  if (isExprDirectParentOfLeafNode(*pExpr)) {
S
slguan 已提交
3952 3953 3954
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3955
    if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3956
      return;
H
hzcheng 已提交
3957 3958
    }

S
slguan 已提交
3959 3960 3961 3962 3963 3964 3965 3966 3967 3968
    if (index.tableIndex != tableIndex) {
      return;
    }

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

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

3969 3970
    doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3971 3972 3973
  }
}

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

S
slguan 已提交
3977
  if (*pExpr != NULL) {
3978
    doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3979
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3980 3981
  }

S
slguan 已提交
3982
  return pResExpr;
H
hzcheng 已提交
3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997
}

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

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

S
slguan 已提交
4002 4003 4004 4005
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

4008
  STagCond* pTagCond = &pQueryInfo->tagCond;
4009
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
S
slguan 已提交
4010 4011 4012 4013

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
4014
    char* str = taosStringBuilderGetResult(sb, NULL);
4015
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
4016 4017 4018
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
4019
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
4020
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
4021

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

S
slguan 已提交
4024
  // remove the duplicated input table names
H
hzcheng 已提交
4025
  int32_t num = 0;
H
hjxilinx 已提交
4026 4027 4028
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
4029
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
4030 4031 4032 4033 4034 4035 4036 4037 4038

  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 已提交
4039
  char* name = extractDBName(pTableMetaInfo->name, db);
H
Haojun Liao 已提交
4040
  SStrToken dbToken = { .type = TK_STRING, .z = name, .n = (uint32_t)strlen(name) };
H
hjxilinx 已提交
4041
  
H
hzcheng 已提交
4042 4043
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
4044
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
4045
    }
H
hjxilinx 已提交
4046

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

4051
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
4052
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4053
      taosStringBuilderDestroy(&sb1);
S
TD-1848  
Shengliang Guan 已提交
4054
      tfree(segments);
H
hjxilinx 已提交
4055

4056
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4057 4058
      return ret;
    }
H
hjxilinx 已提交
4059

H
hjxilinx 已提交
4060
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
4061
  }
H
hjxilinx 已提交
4062

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

H
hjxilinx 已提交
4066
  taosStringBuilderDestroy(&sb1);
S
TD-1848  
Shengliang Guan 已提交
4067
  tfree(segments);
H
hzcheng 已提交
4068 4069 4070
  return TSDB_CODE_SUCCESS;
}

4071
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
4072 4073 4074 4075 4076 4077
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
4078

4079 4080
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
4081 4082
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
4083

4084
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098
          (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;
}

4099
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
4100 4101
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
4102 4103 4104 4105 4106

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

H
Haojun Liao 已提交
4107
  if (!isExprDirectParentOfLeafNode(pExpr)) {
S
slguan 已提交
4108
    if (pExpr->nSQLOptr == TK_OR) {
4109
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4110
    }
H
hzcheng 已提交
4111

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

4114
    return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
S
slguan 已提交
4115 4116
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
4117
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4118
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4119 4120
    }

H
hjxilinx 已提交
4121
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4122
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4123
    
S
slguan 已提交
4124 4125
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
4126 4127
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
4128
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
4129 4130 4131
    }

    // update the timestamp query range
H
hjxilinx 已提交
4132 4133
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
4134 4135
    }

H
hjxilinx 已提交
4136 4137
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
4138 4139 4140 4141 4142 4143
    }
  }

  return TSDB_CODE_SUCCESS;
}

4144
static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
4145 4146 4147 4148
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

4149 4150
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
4151 4152
      return TSDB_CODE_SUCCESS;
    } else {
4153
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
4154 4155 4156
    }
  }

H
hjxilinx 已提交
4157
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
4158
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // for stable join, tag columns
4159
                                                   // must be present for join
S
slguan 已提交
4160
    if (pCondExpr->pJoinExpr == NULL) {
4161
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4162 4163 4164 4165
    }
  }

  if (!pCondExpr->tsJoin) {
4166
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4167 4168
  }

S
slguan 已提交
4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193
  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);
  }
}

4194
static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
H
hjxilinx 已提交
4195
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
4196
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
Haojun Liao 已提交
4197
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hjxilinx 已提交
4198

4199
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
4200 4201
      tscError("%p: invalid column name (left)", pQueryInfo);
    }
H
hjxilinx 已提交
4202
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4203 4204
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4205 4206
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
  
4207
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
4208 4209
      tscError("%p: invalid column name (right)", pQueryInfo);
    }
H
hjxilinx 已提交
4210
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4211 4212
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4213
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
4214
  }
H
hjxilinx 已提交
4215
}
S
slguan 已提交
4216

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

4220 4221 4222 4223 4224
  if (pCondExpr->pTagCond == NULL) {
    return ret;
  }
  
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
4225
    tSQLExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
H
Haojun Liao 已提交
4226 4227 4228 4229
    if (p1 == NULL) {  // no query condition on this table
      continue;
    }

4230
    tExprNode* p = NULL;
4231 4232
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
H
Haojun Liao 已提交
4233
    ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL);
4234 4235 4236 4237 4238 4239 4240 4241 4242
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
4243
    
4244 4245
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
4246
    int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
4247 4248 4249 4250 4251 4252
    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 已提交
4253
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
4254 4255
    }
    
4256
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
4257 4258 4259 4260
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
4261 4262
    
    taosArrayDestroy(colList);
H
Haojun Liao 已提交
4263
    if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
Haojun Liao 已提交
4264 4265
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table");
    }
H
hjxilinx 已提交
4266
  }
H
hjxilinx 已提交
4267

4268
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
4269 4270
  return ret;
}
H
Haojun Liao 已提交
4271

4272
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
4273 4274 4275
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
4276

H
hjxilinx 已提交
4277
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
4278
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
4279

H
hjxilinx 已提交
4280
  int32_t ret = TSDB_CODE_SUCCESS;
S
slguan 已提交
4281

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

H
hjxilinx 已提交
4286
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
4287
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
S
slguan 已提交
4288 4289
  }

H
hjxilinx 已提交
4290
  int32_t type = 0;
4291
  if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4292 4293
    return ret;
  }
H
hjxilinx 已提交
4294

S
slguan 已提交
4295
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
4296

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

S
slguan 已提交
4300
  // 1. check if it is a join query
4301
  if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4302 4303
    return ret;
  }
H
hjxilinx 已提交
4304

S
slguan 已提交
4305
  // 2. get the query time range
4306
  if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4307 4308
    return ret;
  }
H
hjxilinx 已提交
4309

S
slguan 已提交
4310
  // 3. get the tag query condition
4311
  if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4312
    return ret;
S
slguan 已提交
4313
  }
H
hjxilinx 已提交
4314

S
slguan 已提交
4315
  // 4. get the table name query condition
4316
  if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4317 4318
    return ret;
  }
H
hjxilinx 已提交
4319

S
slguan 已提交
4320
  // 5. other column query condition
4321
  if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4322 4323
    return ret;
  }
H
hjxilinx 已提交
4324

S
slguan 已提交
4325
  // 6. join condition
4326
  if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4327
    return ret;
H
hzcheng 已提交
4328
  }
H
hjxilinx 已提交
4329

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

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

4336
  if (!validateFilterExpr(pQueryInfo)) {
4337
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
4338
  }
H
hjxilinx 已提交
4339

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

H
hjxilinx 已提交
4342
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
4343 4344 4345
  return ret;
}

H
hjxilinx 已提交
4346
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
4347 4348 4349 4350 4351
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
4352 4353
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
4354
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
4355 4356
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
4357
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4358
  }
H
hzcheng 已提交
4359 4360 4361 4362

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

S
slguan 已提交
4365
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
4366
    if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
4367
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4368 4369
        parsed = true;
      } else {
4370
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4371
      }
S
slguan 已提交
4372
    } else {
H
Haojun Liao 已提交
4373
      SStrToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
S
slguan 已提交
4374 4375 4376
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
4377
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4378
      }
H
hzcheng 已提交
4379 4380 4381 4382
    }
  } 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 已提交
4383
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398
     *
     * 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
     */
4399
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420

    /*
     * 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 已提交
4421
    win->ekey = val;
H
hzcheng 已提交
4422
  } else if (optr == TK_LT) {
H
hjxilinx 已提交
4423
    win->ekey = val - delta;
H
hzcheng 已提交
4424
  } else if (optr == TK_GT) {
H
hjxilinx 已提交
4425
    win->skey = val + delta;
H
hzcheng 已提交
4426
  } else if (optr == TK_GE) {
H
hjxilinx 已提交
4427
    win->skey = val;
H
hzcheng 已提交
4428
  } else if (optr == TK_EQ) {
H
hjxilinx 已提交
4429
    win->ekey = win->skey = val;
H
hzcheng 已提交
4430 4431 4432 4433
  }
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
4438 4439
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
B
Bomin Zhang 已提交
4440
    for (int32_t j = 0; j < (TSDB_COL_NAME_LEN - 1) && fieldName[j] != 0; ++j) {
S
slguan 已提交
4441 4442 4443 4444 4445
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
4446 4447
      }
    }
S
slguan 已提交
4448

H
hzcheng 已提交
4449 4450 4451 4452
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4453 4454 4455
  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 已提交
4456
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4457
        const char* msg = "duplicated column name in new table";
4458
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4459 4460 4461 4462 4463 4464 4465
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4466
int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
Haojun Liao 已提交
4467 4468
  SArray*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = taosArrayGet(pFillToken, 0);
H
hzcheng 已提交
4469 4470

  const int32_t START_INTERPO_COL_IDX = 1;
4471 4472 4473 4474

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

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4477
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4478
  }
H
hjxilinx 已提交
4479
  
H
Haojun Liao 已提交
4480
  size_t size = tscNumOfFields(pQueryInfo);
H
hjxilinx 已提交
4481
  
4482 4483 4484
  if (pQueryInfo->fillVal == NULL) {
    pQueryInfo->fillVal = calloc(size, sizeof(int64_t));
    if (pQueryInfo->fillVal == NULL) {
4485
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4486 4487 4488
    }
  }

H
hzcheng 已提交
4489
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4490
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4491
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4492
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4493
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
H
Haojun Liao 已提交
4494 4495
      TAOS_FIELD* pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
      setNull((char*)&pQueryInfo->fillVal[i], pField->type, pField->bytes);
H
hzcheng 已提交
4496 4497
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4498
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4499
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4500
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4501
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4502
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4503

H
Haojun Liao 已提交
4504 4505
    size_t num = taosArrayGetSize(pFillToken);
    if (num == 1) {
4506
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4507 4508 4509
    }

    int32_t startPos = 1;
S
Shengliang Guan 已提交
4510
    int32_t numOfFillVal = (int32_t)(num - 1);
H
hzcheng 已提交
4511 4512

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

H
hjxilinx 已提交
4516
      if (numOfFillVal > size) {
S
TD-1057  
Shengliang Guan 已提交
4517
        numOfFillVal = (int32_t)size;
H
hzcheng 已提交
4518 4519
      }
    } else {
S
Shengliang Guan 已提交
4520
      numOfFillVal = (int16_t)((num >  (int32_t)size) ? (int32_t)size : num);
H
hzcheng 已提交
4521 4522 4523 4524 4525
    }

    int32_t j = 1;

    for (int32_t i = startPos; i < numOfFillVal; ++i, ++j) {
H
Haojun Liao 已提交
4526
      TAOS_FIELD* pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hjxilinx 已提交
4527

H
Haojun Liao 已提交
4528 4529
      if (pField->type == TSDB_DATA_TYPE_BINARY || pField->type == TSDB_DATA_TYPE_NCHAR) {
        setVardataNull((char*) &pQueryInfo->fillVal[i], pField->type);
4530 4531
        continue;
      }
H
hjxilinx 已提交
4532

H
Haojun Liao 已提交
4533
      tVariant* p = taosArrayGet(pFillToken, j);
H
Haojun Liao 已提交
4534
      int32_t ret = tVariantDump(p, (char*)&pQueryInfo->fillVal[i], pField->type, true);
H
hzcheng 已提交
4535
      if (ret != TSDB_CODE_SUCCESS) {
4536
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4537 4538
      }
    }
H
hjxilinx 已提交
4539
    
H
Haojun Liao 已提交
4540 4541
    if ((num < size) || ((num - 1 < size) && (tscIsPointInterpQuery(pQueryInfo)))) {
      tVariantListItem* lastItem = taosArrayGetLast(pFillToken);
H
hzcheng 已提交
4542

H
hjxilinx 已提交
4543
      for (int32_t i = numOfFillVal; i < size; ++i) {
H
Haojun Liao 已提交
4544
        TAOS_FIELD* pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4545

H
Haojun Liao 已提交
4546 4547
        if (pField->type == TSDB_DATA_TYPE_BINARY || pField->type == TSDB_DATA_TYPE_NCHAR) {
          setVardataNull((char*) &pQueryInfo->fillVal[i], pField->type);
H
hjxilinx 已提交
4548
        } else {
H
Haojun Liao 已提交
4549
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pField->type, true);
H
hzcheng 已提交
4550 4551 4552 4553
        }
      }
    }
  } else {
4554
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4555 4556 4557 4558 4559
  }

  return TSDB_CODE_SUCCESS;
}

4560
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4561
  /* set default timestamp order information for all queries */
H
hjxilinx 已提交
4562
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4563

H
Haojun Liao 已提交
4564
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
4565 4566 4567 4568 4569
  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 已提交
4570

H
hjxilinx 已提交
4571
  /* for super table query, set default ascending order for group output */
weixin_48148422's avatar
weixin_48148422 已提交
4572
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
4573
    pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
H
hzcheng 已提交
4574 4575 4576
  }
}

4577
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4578 4579
  const char* msg0 = "only support order by primary timestamp";
  const char* msg1 = "invalid column name";
4580 4581
  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 已提交
4582

4583
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4584
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4585 4586 4587 4588 4589

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

H
Haojun Liao 已提交
4590
  SArray* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4591 4592 4593 4594 4595 4596 4597

  /*
   * 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 已提交
4598
  size_t size = taosArrayGetSize(pSortorder);
weixin_48148422's avatar
weixin_48148422 已提交
4599
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
Haojun Liao 已提交
4600
    if (size > 1) {
4601
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4602 4603
    }
  } else {
H
Haojun Liao 已提交
4604
    if (size > 2) {
4605
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4606 4607 4608 4609
    }
  }

  // handle the first part of order by
H
Haojun Liao 已提交
4610
  tVariant* pVar = taosArrayGet(pSortorder, 0);
H
hzcheng 已提交
4611 4612 4613 4614 4615 4616

  // 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 已提交
4617
  SStrToken    columnName = {pVar->nLen, pVar->nType, pVar->pz};
4618
  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
S
slguan 已提交
4619

weixin_48148422's avatar
weixin_48148422 已提交
4620
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4621 4622
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4623 4624 4625 4626
    }

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

H
hjxilinx 已提交
4628 4629
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4630
      
4631 4632
      // it is a tag column
      if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
4633
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4634
      }
4635 4636
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (relTagIndex == pColIndex->colIndex) {
H
hzcheng 已提交
4637 4638
        orderByTags = true;
      }
S
slguan 已提交
4639 4640
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4641 4642
    }

S
slguan 已提交
4643
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4644 4645 4646
      orderByTS = true;
    }

4647
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
4648
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4649 4650 4651 4652
    } else {
      assert(!(orderByTags && orderByTS));
    }

H
Haojun Liao 已提交
4653 4654
    size_t s = taosArrayGetSize(pSortorder);
    if (s == 1) {
H
hzcheng 已提交
4655
      if (orderByTags) {
H
hjxilinx 已提交
4656
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
Haojun Liao 已提交
4657 4658 4659

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

4665
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4666
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4667
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
4668
        }
4669

H
Haojun Liao 已提交
4670 4671
        tVariantListItem* p1 = taosArrayGet(pQuerySql->pSortOrder, 0);
        pQueryInfo->order.order = p1->sortOrder;
4672
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4673
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4674
      } else {
H
Haojun Liao 已提交
4675 4676 4677
        tVariantListItem* p1 = taosArrayGet(pQuerySql->pSortOrder, 0);

        pQueryInfo->order.order = p1->sortOrder;
4678
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
Haojun Liao 已提交
4679 4680 4681 4682 4683

        // orderby ts query on super table
        if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
          addPrimaryTsColIntoResult(pQueryInfo);
        }
H
hzcheng 已提交
4684 4685 4686
      }
    }

H
Haojun Liao 已提交
4687 4688
    if (s == 2) {
      tVariantListItem *pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
S
slguan 已提交
4689
      if (orderByTags) {
H
hjxilinx 已提交
4690
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
Haojun Liao 已提交
4691
        pQueryInfo->groupbyExpr.orderType = pItem->sortOrder;
S
slguan 已提交
4692
      } else {
H
Haojun Liao 已提交
4693
        pQueryInfo->order.order = pItem->sortOrder;
4694
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4695 4696
      }

H
Haojun Liao 已提交
4697 4698
      pItem = taosArrayGet(pQuerySql->pSortOrder, 1);
      tVariant* pVar2 = &pItem->pVar;
H
Haojun Liao 已提交
4699
      SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4700 4701
      if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4702 4703 4704
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4705
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4706
      } else {
H
Haojun Liao 已提交
4707 4708
        tVariantListItem* p1 = taosArrayGet(pSortorder, 1);
        pQueryInfo->order.order = p1->sortOrder;
4709
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4710 4711 4712 4713
      }
    }

  } else {  // meter query
4714 4715
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4716 4717
    }

4718
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
4719
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4720 4721
    }

4722
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4723
      /* order of top/bottom query in interval is not valid  */
4724
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4725
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4726

4727
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4728
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4729
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4730
      }
4731

H
Haojun Liao 已提交
4732 4733
      tVariantListItem* pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
      pQueryInfo->order.order = pItem->sortOrder;
4734
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4735 4736
      return TSDB_CODE_SUCCESS;
    }
4737

H
Haojun Liao 已提交
4738 4739
    tVariantListItem* pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
    pQueryInfo->order.order = pItem->sortOrder;
H
hzcheng 已提交
4740 4741 4742 4743 4744 4745
  }

  return TSDB_CODE_SUCCESS;
}

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

4748 4749 4750 4751 4752
  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 已提交
4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767
  
  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 已提交
4768 4769
  const char* msg19 = "invalid new tag name";

H
Haojun Liao 已提交
4770 4771
  int32_t code = TSDB_CODE_SUCCESS;

S
slguan 已提交
4772
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4773
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4774 4775
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4778
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4779
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
4780
  }
P
plum-lihui 已提交
4781

H
Haojun Liao 已提交
4782 4783 4784
  code = tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
H
hzcheng 已提交
4785 4786
  }

H
Haojun Liao 已提交
4787 4788 4789
  code = tscGetTableMeta(pSql, pTableMetaInfo);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
H
hzcheng 已提交
4790 4791
  }

H
hjxilinx 已提交
4792
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4793

4794 4795
  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 已提交
4796
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
4797
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4798
    }
weixin_48148422's avatar
weixin_48148422 已提交
4799
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) {
4800
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
4801
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4802
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4803
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
4804 4805
  }

4806
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
Haojun Liao 已提交
4807 4808
    SArray* pFieldList = pAlterSQL->pAddColumns;
    if (taosArrayGetSize(pFieldList) > 1) {
4809
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
4810 4811
    }

H
Haojun Liao 已提交
4812 4813
    TAOS_FIELD* p = taosArrayGet(pFieldList, 0);
    if (!validateOneTags(pCmd, p)) {
4814
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4815
    }
H
hjxilinx 已提交
4816
  
H
Haojun Liao 已提交
4817
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p);
4818
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
H
hjxilinx 已提交
4819
    if (tscGetNumOfTags(pTableMeta) == 1) {
4820
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
4821 4822 4823
    }

    // numOfTags == 1
H
Haojun Liao 已提交
4824
    if (taosArrayGetSize(pAlterSQL->varList) > 1) {
4825
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
hzcheng 已提交
4826 4827
    }

H
Haojun Liao 已提交
4828
    tVariantListItem* pItem = taosArrayGet(pAlterSQL->varList, 0);
B
Bomin Zhang 已提交
4829
    if (pItem->pVar.nLen >= TSDB_COL_NAME_LEN) {
4830
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
H
hzcheng 已提交
4831
    }
4832

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

4836
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4837
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4838 4839
    }

H
Haojun Liao 已提交
4840 4841
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
4842
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
H
Haojun Liao 已提交
4843
    } else if (index.columnIndex == numOfCols) {
4844
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
H
hzcheng 已提交
4845 4846
    }

4847 4848
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4849 4850 4851
  
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4852
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
Haojun Liao 已提交
4853 4854
    SArray* pVarList = pAlterSQL->varList;
    if (taosArrayGetSize(pVarList) > 2) {
4855
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4856 4857
    }

H
Haojun Liao 已提交
4858 4859
    tVariantListItem* pSrcItem = taosArrayGet(pAlterSQL->varList, 0);
    tVariantListItem* pDstItem = taosArrayGet(pAlterSQL->varList, 1);
4860 4861

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

4865
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4866
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
4867
    }
H
hzcheng 已提交
4868

S
slguan 已提交
4869 4870
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4871

H
Haojun Liao 已提交
4872
    SStrToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4873
    if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4874
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4875 4876
    }

H
Haojun Liao 已提交
4877
    SStrToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4878
    if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4879
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
H
hzcheng 已提交
4880 4881
    }

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

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

H
Haojun Liao 已提交
4889
    pItem = taosArrayGet(pVarList, 1);
H
hzcheng 已提交
4890
    memset(name, 0, tListLen(name));
H
Haojun Liao 已提交
4891 4892

    strncpy(name, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4893 4894
    f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4895 4896
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
    // Note: update can only be applied to table not super table.
4897 4898 4899
    // 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 已提交
4900 4901
    SArray* pVarList = pAlterSQL->varList;
    tVariantListItem* item = taosArrayGet(pVarList, 0);
4902
    int16_t       numOfTags = tscGetNumOfTags(pTableMeta);
H
hzcheng 已提交
4903

4904
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4905
    SStrToken    name = {.type = TK_STRING, .z = item->pVar.pz, .n = item->pVar.nLen};
4906
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4907
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4908 4909
    }

H
hjxilinx 已提交
4910
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4911
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12);
S
slguan 已提交
4912 4913
    }

H
Haojun Liao 已提交
4914
    tVariantListItem* pItem = taosArrayGet(pVarList, 1);
H
hjxilinx 已提交
4915
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
4916 4917
    pAlterSQL->tagData.data = calloc(1, pTagsSchema->bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE);

H
Haojun Liao 已提交
4918
    if (tVariantDump(&pItem->pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) {
4919
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg13);
H
hzcheng 已提交
4920
    }
4921
    
4922
    pAlterSQL->tagData.dataLen = pTagsSchema->bytes;
H
hzcheng 已提交
4923 4924

    // validate the length of binary
4925
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
H
Haojun Liao 已提交
4926
        varDataTLen(pAlterSQL->tagData.data) > pTagsSchema->bytes) {
4927
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg14);
H
hzcheng 已提交
4928
    }
4929 4930 4931 4932

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

4933 4934
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4935
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4936 4937
    }

4938
    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
4939
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
4940 4941
    pUpdateMsg->tid       = htonl(pTableMeta->id.tid);
    pUpdateMsg->uid       = htobe64(pTableMeta->id.uid);
H
Haojun Liao 已提交
4942
    pUpdateMsg->colId     = htons(pTagsSchema->colId);
H
Hongze Cheng 已提交
4943
    pUpdateMsg->type      = pTagsSchema->type;
H
Haojun Liao 已提交
4944 4945
    pUpdateMsg->bytes     = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion  = htons(pTableMeta->tversion);
4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962
    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 已提交
4963 4964
    pItem = taosArrayGet(pVarList, 1);
    tVariantDump(&pItem->pVar, pUpdateMsg->data + schemaLen, pTagsSchema->type, true);
4965 4966 4967 4968 4969
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
4970
      len = varDataTLen(pUpdateMsg->data + schemaLen);
4971 4972 4973 4974
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
4975
    int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen;
4976
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4977
    
4978
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
Haojun Liao 已提交
4979 4980
    SArray* pFieldList = pAlterSQL->pAddColumns;
    if (taosArrayGetSize(pFieldList) > 1) {
4981
      const char* msg = "only support add one column";
4982
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4983 4984
    }

H
Haojun Liao 已提交
4985 4986
    TAOS_FIELD* p = taosArrayGet(pFieldList, 0);
    if (!validateOneColumn(pCmd, p)) {
4987
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4988
    }
H
hjxilinx 已提交
4989
  
H
Haojun Liao 已提交
4990
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p);
4991
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
H
hjxilinx 已提交
4992
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
H
hjxilinx 已提交
4993
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15);
H
hzcheng 已提交
4994 4995
    }

H
Haojun Liao 已提交
4996 4997
    size_t size = taosArrayGetSize(pAlterSQL->varList);
    if (size > 1) {
H
hjxilinx 已提交
4998
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4999 5000
    }

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

5003
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
5004
    SStrToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
5005 5006
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
5007 5008
    }

5009
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
5010
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18);
5011
    }
H
hzcheng 已提交
5012

B
Bomin Zhang 已提交
5013 5014
    char name1[TSDB_COL_NAME_LEN] = {0};
    tstrncpy(name1, pItem->pVar.pz, sizeof(name1));
H
hjxilinx 已提交
5015 5016
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
5017 5018 5019 5020 5021
  }

  return TSDB_CODE_SUCCESS;
}

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

5026 5027 5028
  if (pQueryInfo->interval.interval != 0 && pQueryInfo->interval.interval < 10 &&
     pQueryInfo->interval.intervalUnit != 'n' &&
     pQueryInfo->interval.intervalUnit != 'y') {
5029
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
5030
  }
H
hjxilinx 已提交
5031
  
H
hjxilinx 已提交
5032
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5033
  for (int32_t i = 0; i < size; ++i) {
5034
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
5035
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
5036
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
5037 5038 5039 5040 5041 5042
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
5047
  // multi-output set/ todo refactor
H
hjxilinx 已提交
5048
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5049 5050
  
  for (int32_t k = 0; k < size; ++k) {
5051
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
5052

5053 5054 5055
    // 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 已提交
5056
      for (int32_t j = 0; j < size; ++j) {
5057
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
5058 5059 5060 5061 5062
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
5063

5064 5065 5066 5067
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
5068

5069
    if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
5070
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
5071 5072 5073
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
5074 5075

  if (isProjectionFunction) {
5076
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
5077 5078
  }

5079
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5080 5081 5082
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
5083 5084
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
5085 5086
} SDNodeDynConfOption;

H
Hui Li 已提交
5087

5088
int32_t validateEp(char* ep) {  
H
Hui Li 已提交
5089 5090 5091
  char buf[TSDB_EP_LEN + 1] = {0};
  tstrncpy(buf, ep, TSDB_EP_LEN);

5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102
  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 已提交
5103 5104
  }

5105
  return TSDB_CODE_SUCCESS;
H
Hui Li 已提交
5106 5107
}

H
hzcheng 已提交
5108 5109
int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
5110
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5111 5112
  }

5113 5114 5115 5116 5117 5118 5119
  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},
S
Shengliang Guan 已提交
5120
      {"debugFlag", 9},   {"monDebugFlag", 12},     {"vDebugFlag", 10}, {"mDebugFlag", 10},
5121 5122 5123
      {"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 已提交
5124
      {"cqDebugFlag", 11},
5125
  };
H
hzcheng 已提交
5126

H
Haojun Liao 已提交
5127
  SStrToken* pOptionToken = &pOptions->a[1];
H
hzcheng 已提交
5128 5129 5130

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
5131 5132
    for (int32_t i = 0; i < tokenLogEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
5133 5134 5135 5136
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
5137 5138
  } else if ((strncasecmp(cfgOptions[tokenBalance].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenBalance].len == pOptionToken->n)) {
H
Haojun Liao 已提交
5139
    SStrToken* pValToken = &pOptions->a[2];
S
Shengliang Guan 已提交
5140 5141
    int32_t vnodeId = 0;
    int32_t dnodeId = 0;
5142
    strdequote(pValToken->z);
S
Shengliang Guan 已提交
5143
    bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId);
5144 5145 5146 5147 5148 5149
    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 已提交
5150
    SStrToken* pValToken = &pOptions->a[2];
S
slguan 已提交
5151 5152
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
5153
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
S
slguan 已提交
5154 5155
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5156
  } else {
H
Haojun Liao 已提交
5157
    SStrToken* pValToken = &pOptions->a[2];
H
hzcheng 已提交
5158 5159

    int32_t val = strtol(pValToken->z, NULL, 10);
5160
    if (val < 0 || val > 256) {
H
hzcheng 已提交
5161
      /* options value is out of valid range */
5162
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5163 5164
    }

5165 5166
    for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
5167 5168 5169 5170 5171 5172 5173 5174

      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;
H
hzcheng 已提交
5176 5177
}

S
slguan 已提交
5178 5179
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
5180
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5181 5182
  }

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

H
Haojun Liao 已提交
5186
  SStrToken* pOptionToken = &pOptions->a[0];
S
slguan 已提交
5187 5188 5189 5190 5191 5192 5193 5194 5195 5196

  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 已提交
5197
    SStrToken* pValToken = &pOptions->a[1];
S
slguan 已提交
5198 5199 5200 5201

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
5202
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5203 5204 5205 5206 5207 5208 5209 5210 5211 5212
    }

    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;
      }
    }
  }
5213
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5214 5215
}

H
hzcheng 已提交
5216
int32_t validateColumnName(char* name) {
S
TD-1057  
Shengliang Guan 已提交
5217
  bool ret = isKeyWord(name, (int32_t)strlen(name));
H
hzcheng 已提交
5218
  if (ret) {
5219
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5220 5221
  }

H
Haojun Liao 已提交
5222
  SStrToken token = {.z = name};
H
hzcheng 已提交
5223 5224 5225
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
5226
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5227 5228 5229 5230
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
S
TD-1057  
Shengliang Guan 已提交
5231
    token.n = (uint32_t)strtrim(token.z);
H
hzcheng 已提交
5232 5233 5234

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
5235
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5236 5237 5238 5239 5240
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
5241
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5242 5243 5244 5245 5246 5247
    }
  }

  return TSDB_CODE_SUCCESS;
}

5248 5249
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
5250 5251 5252
    return true;
  }

H
hjxilinx 已提交
5253
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
5254 5255
}

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

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

H
hzcheng 已提交
5264
  // handle the limit offset value, validate the limit
5265
  pQueryInfo->limit = pQuerySql->limit;
5266
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
5267
  pQueryInfo->slimit = pQuerySql->slimit;
5268
  
5269
  tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
5270 5271
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
5272
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
5273
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
5274 5275
  }

5276
  if (pQueryInfo->limit.limit == 0) {
5277
    tscDebug("%p limit 0, no output result", pSql);
5278
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
5279
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5280 5281
  }

H
hjxilinx 已提交
5282
  // todo refactor
weixin_48148422's avatar
weixin_48148422 已提交
5283
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
5284
    if (!tscQueryTags(pQueryInfo)) {  // local handle the super table tag query
5285
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
5286
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
5287
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5288
        }
H
hjxilinx 已提交
5289

5290
        // for projection query on super table, all queries are subqueries
H
hjxilinx 已提交
5291 5292
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
            !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
5293
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
5294
        }
S
slguan 已提交
5295
      }
H
hzcheng 已提交
5296 5297
    }

5298
    if (pQueryInfo->slimit.limit == 0) {
5299
      tscDebug("%p slimit 0, no output result", pSql);
5300
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
5301 5302 5303 5304
      return TSDB_CODE_SUCCESS;
    }

    /*
5305 5306 5307 5308
     * 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 已提交
5309
     */
H
hjxilinx 已提交
5310
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
5311 5312 5313 5314
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
5315
    // No tables included. No results generated. Query results are empty.
5316
    if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
5317
      tscDebug("%p no table in super table, no output result", pSql);
5318
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
5319
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5320 5321 5322
    }

    // keep original limitation value in globalLimit
5323
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
H
Haojun Liao 已提交
5324
    pQueryInfo->prjOffset   = pQueryInfo->limit.offset;
H
Haojun Liao 已提交
5325
    pQueryInfo->vgroupLimit = -1;
H
hjxilinx 已提交
5326

5327 5328
    if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
      /*
5329 5330 5331 5332
       * the offset value should be removed during retrieve data from virtual node, since the
       * global order are done in client side, so the offset is applied at the client side
       * However, note that the maximum allowed number of result for each table should be less
       * than or equal to the value of limit.
5333 5334
       */
      if (pQueryInfo->limit.limit > 0) {
H
Haojun Liao 已提交
5335
        pQueryInfo->vgroupLimit = pQueryInfo->limit.limit + pQueryInfo->limit.offset;
5336 5337
        pQueryInfo->limit.limit = -1;
      }
H
hjxilinx 已提交
5338

5339 5340
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
5341
  } else {
5342
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
5343
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
5344
    }
H
hjxilinx 已提交
5345
  
H
hjxilinx 已提交
5346
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
5347 5348 5349
    
    bool hasTags = false;
    bool hasOtherFunc = false;
S
slguan 已提交
5350
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
5351
    for (int32_t i = 0; i < size; ++i) {
5352
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
5353 5354 5355 5356
      if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
        hasTags = true;
      } else {
        hasOtherFunc = true;
H
hzcheng 已提交
5357 5358
      }
    }
5359 5360
    
    if (hasTags && hasOtherFunc) {
5361
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5362
    }
H
hzcheng 已提交
5363 5364 5365 5366
  }

  return TSDB_CODE_SUCCESS;
}
5367

S
TD-1732  
Shengliang Guan 已提交
5368
static int32_t setKeepOption(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
hjxilinx 已提交
5369
  const char* msg = "invalid number of options";
H
hjxilinx 已提交
5370

5371 5372 5373
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
5374

H
Haojun Liao 已提交
5375
  SArray* pKeep = pCreateDb->keep;
H
hjxilinx 已提交
5376
  if (pKeep != NULL) {
H
Haojun Liao 已提交
5377 5378 5379 5380 5381 5382
    size_t s = taosArrayGetSize(pKeep);
    tVariantListItem* p0 = taosArrayGet(pKeep, 0);
    switch (s) {
      case 1: {
        pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64Key);
      }
5383 5384
        break;
      case 2: {
H
Haojun Liao 已提交
5385 5386 5387
        tVariantListItem* p1 = taosArrayGet(pKeep, 1);
        pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)p1->pVar.i64Key);
5388 5389 5390
        break;
      }
      case 3: {
H
Haojun Liao 已提交
5391 5392 5393 5394 5395 5396
        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);
5397 5398
        break;
      }
5399
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
5400 5401
    }
  }
H
hjxilinx 已提交
5402

H
hjxilinx 已提交
5403 5404
  return TSDB_CODE_SUCCESS;
}
5405

S
TD-1732  
Shengliang Guan 已提交
5406
static int32_t setTimePrecision(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDbInfo) {
H
hjxilinx 已提交
5407
  const char* msg = "invalid time precision";
H
hjxilinx 已提交
5408

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

H
Haojun Liao 已提交
5411
  SStrToken* pToken = &pCreateDbInfo->precision;
5412 5413
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
5414

5415 5416 5417 5418 5419
    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 已提交
5420
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
5421 5422
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
5423
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
5424 5425
    }
  }
H
hjxilinx 已提交
5426

H
hjxilinx 已提交
5427 5428
  return TSDB_CODE_SUCCESS;
}
5429

S
TD-1732  
Shengliang Guan 已提交
5430
static void setCreateDBOption(SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
Haojun Liao 已提交
5431
  pMsg->maxTables = htonl(-1);  // max tables can not be set anymore
H
hjxilinx 已提交
5432
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
5433
  pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
H
hjxilinx 已提交
5434
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
S
TD-1057  
Shengliang Guan 已提交
5435
  pMsg->commitTime = htonl((int32_t)pCreateDb->commitTime);
H
hjxilinx 已提交
5436 5437
  pMsg->minRowsPerFileBlock = htonl(pCreateDb->minRowsPerBlock);
  pMsg->maxRowsPerFileBlock = htonl(pCreateDb->maxRowsPerBlock);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5438
  pMsg->fsyncPeriod = htonl(pCreateDb->fsyncPeriod);
S
slguan 已提交
5439
  pMsg->compression = pCreateDb->compressionLevel;
H
hjxilinx 已提交
5440
  pMsg->walLevel = (char)pCreateDb->walLevel;
H
hjxilinx 已提交
5441
  pMsg->replications = pCreateDb->replica;
5442
  pMsg->quorum = pCreateDb->quorum;
5443
  pMsg->ignoreExist = pCreateDb->ignoreExists;
Y
yihaoDeng 已提交
5444
  pMsg->update = pCreateDb->update;
H
hjxilinx 已提交
5445 5446 5447
}

int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) {
S
TD-1732  
Shengliang Guan 已提交
5448
  SCreateDbMsg* pMsg = (SCreateDbMsg *)(pCmd->payload);
H
hjxilinx 已提交
5449
  setCreateDBOption(pMsg, pCreateDbSql);
H
hjxilinx 已提交
5450

H
hjxilinx 已提交
5451
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5452
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5453
  }
H
hjxilinx 已提交
5454

H
hjxilinx 已提交
5455
  if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5456
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5457
  }
H
hjxilinx 已提交
5458

H
hjxilinx 已提交
5459
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
5460
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5461
  }
H
hjxilinx 已提交
5462

5463
  return TSDB_CODE_SUCCESS;
H
huili 已提交
5464
}
S
slguan 已提交
5465

5466 5467
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
5468

5469 5470
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
H
Haojun Liao 已提交
5471 5472
    SSqlExpr* pExpr = NULL;

H
hjxilinx 已提交
5473
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
Haojun Liao 已提交
5474 5475 5476
    if (size > 0) {
      pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1);
    }
5477

H
Haojun Liao 已提交
5478
    if (pExpr == NULL || pExpr->functionId != TSDB_FUNC_TAG) {
H
Haojun Liao 已提交
5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490
      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;

H
Haojun Liao 已提交
5491
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(pQueryInfo), bytes, true);
S
slguan 已提交
5492 5493 5494 5495
      pExpr->colInfo.flag = TSDB_COL_TAG;

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

      int32_t relIndex = index.columnIndex;

5500
      pExpr->colInfo.colIndex = relIndex;
5501 5502
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
5503

5504
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
5505
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
5506 5507 5508 5509
    }
  }
}

H
hjxilinx 已提交
5510 5511 5512
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
5513
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
5514 5515 5516
  pExpr->numOfParams = 1;
}

5517
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
5518
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
H
hjxilinx 已提交
5519
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
5520

H
Haojun Liao 已提交
5521 5522 5523 5524
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

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

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

H
Haojun Liao 已提交
5528 5529 5530
  int32_t numOfFields = tscNumOfFields(pQueryInfo);
  SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfFields - 1);

H
Haojun Liao 已提交
5531
  doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
H
hjxilinx 已提交
5532
  pInfo->visible = false;
S
slguan 已提交
5533 5534
}

5535
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5536
  int32_t tagLength = 0;
H
hjxilinx 已提交
5537
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
5538 5539 5540 5541 5542

//todo is 0??
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);

H
hjxilinx 已提交
5543
  for (int32_t i = 0; i < size; ++i) {
5544
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5545 5546 5547 5548 5549 5550 5551 5552 5553
    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;
    }
  }

5554
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5555

H
hjxilinx 已提交
5556
  for (int32_t i = 0; i < size; ++i) {
5557
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
Haojun Liao 已提交
5558 5559
    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))) {
5560
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
S
TD-1057  
Shengliang Guan 已提交
5561
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64Key, &pExpr->resType,
5562
                        &pExpr->resBytes, &pExpr->interBytes, tagLength, isSTable);
S
slguan 已提交
5563 5564 5565 5566
    }
  }
}

H
Haojun Liao 已提交
5567
static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5568
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5569 5570
  
  for (int32_t i = 0; i < size; ++i) {
5571
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
Haojun Liao 已提交
5572

5573
    if (pExpr->functionId == TSDB_FUNC_PRJ && (!TSDB_COL_IS_UD_COL(pExpr->colInfo.flag) && (pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX))) {
H
hjxilinx 已提交
5574
      bool qualifiedCol = false;
5575
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5576 5577 5578
        SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
  
        if (pExpr->colInfo.colId == pColIndex->colId) {
H
hjxilinx 已提交
5579
          qualifiedCol = true;
H
hjxilinx 已提交
5580
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5581 5582 5583 5584
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
5585

H
Haojun Liao 已提交
5586 5587 5588 5589
      // it is not a tag column/tbname column/user-defined column, return error
      if (!qualifiedCol) {
        return TSDB_CODE_TSC_INVALID_SQL;
      }
H
hjxilinx 已提交
5590 5591
    }
  }
H
Haojun Liao 已提交
5592 5593

  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5594 5595
}

S
slguan 已提交
5596 5597
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
5598 5599
    SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j);
  
Y
TD-1230  
yihaoDeng 已提交
5600
    if (columnId == pColIndex->colId && TSDB_COL_IS_TAG(pColIndex->flag )) {
S
slguan 已提交
5601 5602 5603 5604 5605 5606 5607
      return true;
    }
  }

  return false;
}

5608
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5609 5610
  bool hasTagPrj = false;
  bool hasColumnPrj = false;
H
hjxilinx 已提交
5611
  
H
hjxilinx 已提交
5612
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5613
  for (int32_t i = 0; i < size; ++i) {
5614
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625
    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
5626
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5627 5628
  bool allInGroupby = true;

H
hjxilinx 已提交
5629 5630
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5631
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5632 5633 5634 5635
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5636
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5637 5638 5639 5640 5641 5642 5643 5644 5645
      allInGroupby = false;
      break;
    }
  }

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

5646
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5647
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5648 5649
  
  for (int32_t i = 0; i < size; ++i) {
5650
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662
    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.
 */
5663
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) {
S
slguan 已提交
5664
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5665
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5666

H
Haojun Liao 已提交
5667
  bool    tagTsColExists = false;
S
slguan 已提交
5668 5669 5670
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5671
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5672
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5673
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5674 5675
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
H
Haojun Liao 已提交
5676
      tagTsColExists = true;  // selectivity + ts/tag column
S
slguan 已提交
5677 5678 5679
      break;
    }
  }
H
hjxilinx 已提交
5680

H
hjxilinx 已提交
5681
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5682
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5683 5684
  
    int16_t functionId = pExpr->functionId;
5685
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5686
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5687
      continue;
S
slguan 已提交
5688
    }
H
hjxilinx 已提交
5689

H
hjxilinx 已提交
5690 5691 5692 5693 5694 5695
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5696

H
Haojun Liao 已提交
5697
  if (tagTsColExists) {  // check if the selectivity function exists
S
slguan 已提交
5698 5699
    // 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.
5700
    if (numOfAggregation > 0) {
5701
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5702 5703 5704 5705 5706 5707
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5708
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
H
Haojun Liao 已提交
5709 5710 5711 5712 5713
      int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
      }

S
slguan 已提交
5714 5715 5716 5717 5718
    } 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 已提交
5719
      for (int32_t i = 0; i < numOfExprs; ++i) {
H
Haojun Liao 已提交
5720 5721 5722
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
        int16_t functionId = pExpr->functionId;
        if (functionId == TSDB_FUNC_TAGPRJ || (aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == 0) {
S
slguan 已提交
5723 5724 5725
          continue;
        }

H
Haojun Liao 已提交
5726 5727 5728 5729
        if ((functionId == TSDB_FUNC_LAST_ROW) ||
             (functionId == TSDB_FUNC_LAST_DST && (pExpr->colInfo.flag & TSDB_COL_NULL) != 0)) {
          // do nothing
        } else {
5730
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5731 5732 5733
        }
      }

5734
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
H
Haojun Liao 已提交
5735 5736 5737 5738
      int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
      }
H
hjxilinx 已提交
5739 5740
    }
  } else {
5741
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5742
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5743
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5744
      }
H
hjxilinx 已提交
5745

H
hjxilinx 已提交
5746 5747
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5748
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
H
Haojun Liao 已提交
5749 5750 5751 5752
        int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
        if (code != TSDB_CODE_SUCCESS) {
          return code;
        }
H
hjxilinx 已提交
5753
      }
S
slguan 已提交
5754 5755 5756 5757 5758 5759
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

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

H
Haojun Liao 已提交
5765
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5766
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5767 5768 5769 5770
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5771
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5772
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5773
    int16_t colIndex = pColIndex->colIndex;
5774
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5775
      type  = s.type;
H
Haojun Liao 已提交
5776
      bytes = s.bytes;
H
Haojun Liao 已提交
5777
      name  = s.name;
S
slguan 已提交
5778
    } else {
5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789
      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 已提交
5790
    }
H
hjxilinx 已提交
5791 5792 5793
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5794
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5795
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
H
Haojun Liao 已提交
5796
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(pQueryInfo), bytes, true);
5797
      
B
Bomin Zhang 已提交
5798 5799
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5800
      
S
slguan 已提交
5801 5802 5803
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5804
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
S
TD-1057  
Shengliang Guan 已提交
5805
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5806 5807
    } else {
      // if this query is "group by" normal column, interval is not allowed
5808
      if (pQueryInfo->interval.interval > 0) {
5809
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5810 5811 5812
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5813
      for (int32_t j = 0; j < size; ++j) {
5814
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5815 5816 5817 5818 5819 5820 5821 5822 5823 5824
        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) {
5825
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5826 5827 5828 5829 5830 5831 5832
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5833
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5834
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5835
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5836
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5837
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5838 5839

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5840
  if (tscQueryTags(pQueryInfo)) {
5841
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) {
5842
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5843 5844 5845 5846 5847
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5848
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5849
    // check if all the tags prj columns belongs to the group by columns
5850 5851
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5852
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5853 5854 5855
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5856 5857
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5858
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5859 5860 5861 5862 5863 5864
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5865
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5866
        bool qualified = false;
5867
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5868
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5869 5870 5871 5872 5873 5874 5875
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5876
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5877 5878 5879 5880
        }
      }

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

5885
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5886
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5887 5888 5889
      }
    }

5890
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5891
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5892 5893 5894 5895 5896 5897
    }

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

H
hjxilinx 已提交
5902
    // projection query on super table does not compatible with "group by" syntax
5903
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5904
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5905
    }
H
hjxilinx 已提交
5906

H
hjxilinx 已提交
5907
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5908
  } else {
5909
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5910 5911
  }
}
5912
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5913 5914 5915
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5916

H
hjxilinx 已提交
5917 5918
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5919
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5920
  }
Y
yihaoDeng 已提交
5921
  bool server_status = false;
H
hjxilinx 已提交
5922 5923
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
Y
yihaoDeng 已提交
5924 5925 5926 5927 5928 5929 5930
    //handle 'select 1'
    if (pExpr->token.n == 1 && 0 == strncasecmp(pExpr->token.z, "1", 1)) {
      server_status = true; 
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } 
  } 
H
hjxilinx 已提交
5931
  // TODO redefine the function
Y
yihaoDeng 已提交
5932 5933 5934 5935 5936
   SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                            {"server_version()", 16},
                                            {"server_status()", 15},
                                            {"client_version()", 16},
                                            {"current_user()", 14}};
H
hjxilinx 已提交
5937

H
hjxilinx 已提交
5938
  int32_t index = -1;
Y
yihaoDeng 已提交
5939 5940 5941 5942 5943 5944 5945 5946 5947
  if (server_status == true) {
    index = 2;
  } else {
    for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
      if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
          functionsInfo[i].len == pExpr->operand.n) {
        index = i;
        break;
      }
H
hjxilinx 已提交
5948 5949
    }
  }
H
hjxilinx 已提交
5950 5951 5952

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5953
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5954
    case 1:
H
Haojun Liao 已提交
5955 5956 5957
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5958
    case 3:
H
Haojun Liao 已提交
5959
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5960
    case 4:
H
Haojun Liao 已提交
5961
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5962
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5963
  }
5964 5965 5966
  
  SColumnIndex ind = {0};
  SSqlExpr* pExpr1 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT,
H
Haojun Liao 已提交
5967
                                      tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize, getNewResColId(pQueryInfo), tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize, false);
5968 5969
  
  const char* name = (pExprList->a[0].aliasName != NULL)? pExprList->a[0].aliasName:functionsInfo[index].name;
B
Bomin Zhang 已提交
5970
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5971 5972
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5973
}
H
hjxilinx 已提交
5974 5975

// can only perform the parameters based on the macro definitation
S
TD-1732  
Shengliang Guan 已提交
5976
int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) {
H
hjxilinx 已提交
5977
  char msg[512] = {0};
H
hjxilinx 已提交
5978

H
hjxilinx 已提交
5979
  if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) {
S
TD-1388  
Shengliang Guan 已提交
5980
    snprintf(msg, tListLen(msg), "invalid db option walLevel: %d, only 1-2 allowed", pCreate->walLevel);
5981
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5982
  }
H
hjxilinx 已提交
5983

H
hjxilinx 已提交
5984
  if (pCreate->replications != -1 &&
5985
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5986
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5987
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5988
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5989
  }
H
hjxilinx 已提交
5990

5991 5992 5993 5994 5995 5996 5997
  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 已提交
5998
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5999
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
6000
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
6001
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
6002
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
6003
  }
H
hjxilinx 已提交
6004

H
hjxilinx 已提交
6005 6006 6007 6008
  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);
6009
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
6010
  }
H
hjxilinx 已提交
6011

H
hjxilinx 已提交
6012
  val = htonl(pCreate->maxTables);
S
slguan 已提交
6013
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
6014
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
6015
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
6016
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
6017
  }
H
hjxilinx 已提交
6018 6019 6020 6021

  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);
6022
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
6023
  }
H
hjxilinx 已提交
6024

H
hjxilinx 已提交
6025
  val = htonl(pCreate->commitTime);
S
slguan 已提交
6026
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
6027
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
6028
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
6029
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
6030
  }
H
hjxilinx 已提交
6031

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
6032 6033 6034 6035 6036 6037 6038
  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 已提交
6039
  if (pCreate->compression != -1 &&
S
slguan 已提交
6040
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
6041
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
6042
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
6043
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
6044
  }
H
hjxilinx 已提交
6045

H
hjxilinx 已提交
6046 6047
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
6048 6049

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

S
TD-1057  
Shengliang Guan 已提交
6053
  int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
6054
  if (size == 0) {
H
hjxilinx 已提交
6055 6056
    return;
  }
H
hjxilinx 已提交
6057

H
hjxilinx 已提交
6058
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
6059 6060

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

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

L
lihui 已提交
6067
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
6068 6069 6070
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
6071 6072 6073
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
6075
    if (i < size - 1) {
H
hjxilinx 已提交
6076 6077 6078
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
6079

H
hjxilinx 已提交
6080
  str[offset] = ']';
6081
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
6082
}
6083

6084
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
6085 6086
  const char* msg1 = "invalid table name";

6087 6088
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
6089
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
6090 6091 6092

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;

H
Haojun Liao 已提交
6093 6094
  SArray* pFieldList = pCreateTable->colInfo.pColumns;
  SArray* pTagList = pCreateTable->colInfo.pTagColumns;
6095 6096 6097 6098

  assert(pFieldList != NULL);

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

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
6102
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6103 6104
  }

H
Haojun Liao 已提交
6105 6106 6107
  int32_t code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql);
  if(code != TSDB_CODE_SUCCESS) {
    return code;
6108 6109 6110 6111
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
6112
    return TSDB_CODE_TSC_INVALID_SQL;
6113 6114 6115
  }

  int32_t col = 0;
H
Haojun Liao 已提交
6116 6117 6118
  size_t numOfFields = taosArrayGetSize(pFieldList);

  for (; col < numOfFields; ++col) {
H
Haojun Liao 已提交
6119
    TAOS_FIELD* p = taosArrayGet(pFieldList, col);
H
Haojun Liao 已提交
6120
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p);
6121 6122
  }

H
Haojun Liao 已提交
6123
  pCmd->numOfCols = (int16_t)numOfFields;
6124

H
hjxilinx 已提交
6125
  if (pTagList != NULL) {  // create super table[optional]
H
Haojun Liao 已提交
6126 6127
    size_t numOfTags = taosArrayGetSize(pTagList);
    for (int32_t i = 0; i < numOfTags; ++i) {
H
Haojun Liao 已提交
6128 6129
      TAOS_FIELD* p = taosArrayGet(pTagList, i);
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p);
6130 6131
    }

S
Shengliang Guan 已提交
6132
    pCmd->count =(int32_t) numOfTags;
6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146
  }

  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;
6147 6148 6149
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
6150 6151 6152
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
6153 6154 6155 6156

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

6157
  STableMetaInfo* pStableMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
6158 6159

  // super table name, create table by using dst
H
Haojun Liao 已提交
6160
  int32_t numOfTables = (int32_t) taosArrayGetSize(pCreateTable->childTableInfo);
6161 6162
  for(int32_t j = 0; j < numOfTables; ++j) {
    SCreatedTableInfo* pCreateTableInfo = taosArrayGet(pCreateTable->childTableInfo, j);
6163

6164 6165 6166 6167
    SStrToken* pToken = &pCreateTableInfo->stableName;
    if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
    }
6168

6169 6170 6171 6172
    int32_t code = tscSetTableFullName(pStableMetaInfo, pToken, pSql);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
6173

6174 6175 6176
    // get table meta from mnode
    tstrncpy(pCreateTableInfo->tagdata.name, pStableMetaInfo->name, tListLen(pCreateTableInfo->tagdata.name));
    SArray* pList = pCreateTableInfo->pTagVals;
6177

6178 6179 6180 6181
    code = tscGetTableMeta(pSql, pStableMetaInfo);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
6182

6183 6184 6185 6186
    size_t size = taosArrayGetSize(pList);
    if (tscGetNumOfTags(pStableMetaInfo->pTableMeta) != size) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
6187

6188 6189 6190
    // too long tag values will return invalid sql, not be truncated automatically
    SSchema  *pTagSchema = tscGetTableTagSchema(pStableMetaInfo->pTableMeta);
    STagData *pTag = &pCreateTableInfo->tagdata;
6191

6192 6193 6194 6195
    SKVRowBuilder kvRowBuilder = {0};
    if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
B
Bomin Zhang 已提交
6196

6197 6198 6199 6200
    int32_t ret = TSDB_CODE_SUCCESS;
    for (int32_t i = 0; i < size; ++i) {
      SSchema*          pSchema = &pTagSchema[i];
      tVariantListItem* pItem = taosArrayGet(pList, i);
H
Haojun Liao 已提交
6201

6202 6203 6204 6205 6206 6207
      char tagVal[TSDB_MAX_TAGS_LEN];
      if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
        if (pItem->pVar.nLen > pSchema->bytes) {
          tdDestroyKVRowBuilder(&kvRowBuilder);
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
        }
H
hjxilinx 已提交
6208
      }
H
Haojun Liao 已提交
6209

6210
      ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true);
H
Haojun Liao 已提交
6211

6212 6213 6214 6215 6216 6217 6218 6219 6220 6221
      // 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);
        }
      }

      if (ret != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
6222
        tdDestroyKVRowBuilder(&kvRowBuilder);
6223
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
Haojun Liao 已提交
6224 6225
      }

6226
      tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
6227 6228
    }

6229 6230 6231 6232 6233 6234 6235
    SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
    tdDestroyKVRowBuilder(&kvRowBuilder);
    if (row == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
    tdSortKVRowByColIdx(row);
    pTag->dataLen = kvRowLen(row);
H
Haojun Liao 已提交
6236

6237 6238 6239
    if (pTag->data == NULL) {
      pTag->data = malloc(pTag->dataLen);
    }
H
Haojun Liao 已提交
6240

6241 6242
    kvRowCpy(pTag->data, row);
    free(row);
6243

6244 6245 6246 6247
    // table name
    if (tscValidateName(&(pCreateTableInfo->name)) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
    }
B
Bomin Zhang 已提交
6248

6249 6250 6251 6252 6253
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
    ret = tscSetTableFullName(pTableMetaInfo, &pCreateTableInfo->name, pSql);
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
6254

6255
    pCreateTableInfo->fullname = strndup(pTableMetaInfo->name, TSDB_TABLE_FNAME_LEN);
6256 6257 6258 6259 6260 6261 6262 6263 6264 6265
  }

  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 已提交
6266 6267
  const char* msg6 = "from missing in subclause";
  
6268
  SSqlCmd*    pCmd = &pSql->cmd;
6269
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
6270 6271
  assert(pQueryInfo->numOfTables == 1);

6272
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
6273
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
6274 6275

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
6276
  SStrToken* pzTableName = &(pCreateTable->name);
6277 6278 6279
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
6280
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6281
  }
H
Haojun Liao 已提交
6282
  
H
Haojun Liao 已提交
6283 6284
  SArray* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
  if (pSrcMeterName == NULL || taosArrayGetSize(pSrcMeterName) == 0) {
H
Haojun Liao 已提交
6285 6286 6287
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
H
Haojun Liao 已提交
6288 6289
  tVariantListItem* p1 = taosArrayGet(pSrcMeterName, 0);
  SStrToken srcToken = {.z = p1->pVar.pz, .n = p1->pVar.nLen, .type = TK_STRING};
6290
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
6291
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6292 6293
  }

H
Haojun Liao 已提交
6294 6295 6296
  int32_t code = tscSetTableFullName(pTableMetaInfo, &srcToken, pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
6297 6298
  }

H
Haojun Liao 已提交
6299
  code = tscGetTableMeta(pSql, pTableMetaInfo);
6300 6301 6302 6303
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
6304
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
H
Haojun Liao 已提交
6305
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false) != TSDB_CODE_SUCCESS) {
6306
    return TSDB_CODE_TSC_INVALID_SQL;
6307 6308 6309
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
6310
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
6311
      return TSDB_CODE_TSC_INVALID_SQL;
6312 6313 6314 6315
    }
  }

  // set interval value
6316
  if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6317
    return TSDB_CODE_TSC_INVALID_SQL;
6318
  } else {
6319
    if ((pQueryInfo->interval.interval > 0) &&
6320
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6321
      return TSDB_CODE_TSC_INVALID_SQL;
6322 6323 6324 6325
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
6326 6327 6328
  code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
6329 6330 6331
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
6332
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
6333 6334
  }

6335
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
6336
    return TSDB_CODE_TSC_INVALID_SQL;
6337 6338
  }

H
hjxilinx 已提交
6339
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
6340

6341
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
6342
    return TSDB_CODE_TSC_INVALID_SQL;
6343 6344 6345 6346 6347 6348 6349
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
6350
    if (pQueryInfo->interval.interval == 0) {
6351
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
6352 6353
    }

H
Haojun Liao 已提交
6354
    tVariantListItem* pItem = taosArrayGet(pQuerySql->fillType, 0);
6355 6356 6357
    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))) {
6358
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
6359 6360 6361 6362 6363
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
6364
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
6365 6366 6367 6368
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
H
Haojun Liao 已提交
6369
  assert(pQuerySql != NULL && (pQuerySql->from == NULL || taosArrayGetSize(pQuerySql->from) > 0));
6370

H
Haojun Liao 已提交
6371 6372 6373 6374 6375 6376 6377 6378 6379
  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";
6380 6381

  int32_t code = TSDB_CODE_SUCCESS;
6382

6383
  SSqlCmd* pCmd = &pSql->cmd;
6384

6385
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
6386
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
6387
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
6388
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
6389
  }
H
hjxilinx 已提交
6390

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

6393 6394
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
6395
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407
  }

  /*
   * 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);
6408
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
6409 6410
  }

H
Haojun Liao 已提交
6411 6412
  size_t fromSize = taosArrayGetSize(pQuerySql->from);
  if (fromSize > TSDB_MAX_JOIN_TABLE_NUM * 2) {
6413
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
6414 6415
  }

6416
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
6417

H
Haojun Liao 已提交
6418
  if (fromSize > 4) {
H
Haojun Liao 已提交
6419 6420 6421
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

6422
  // set all query tables, which are maybe more than one.
H
Haojun Liao 已提交
6423 6424 6425
  for (int32_t i = 0; i < fromSize; ) {
    tVariantListItem* item = taosArrayGet(pQuerySql->from, i);
    tVariant* pTableItem = &item->pVar;
6426 6427

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
6428
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6429 6430 6431 6432
    }

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

H
Haojun Liao 已提交
6433
    SStrToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
6434
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
6435
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6436 6437
    }

H
Haojun Liao 已提交
6438
    if (pQueryInfo->numOfTables <= i/2) {  // more than one table
H
hjxilinx 已提交
6439
      tscAddEmptyMetaInfo(pQueryInfo);
6440 6441
    }

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

H
Haojun Liao 已提交
6444
    SStrToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
6445 6446 6447
    code = tscSetTableFullName(pTableMetaInfo1, &t, pSql);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
6448 6449
    }

6450
    tVariantListItem* p1 = taosArrayGet(pQuerySql->from, i + 1);
H
Haojun Liao 已提交
6451
    if (p1->pVar.nType != TSDB_DATA_TYPE_BINARY) {
H
Haojun Liao 已提交
6452 6453 6454
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

H
Haojun Liao 已提交
6455
    SStrToken aliasName = {.z = p1->pVar.pz, .n = p1->pVar.nLen, .type = TK_STRING};
H
Haojun Liao 已提交
6456 6457 6458 6459
    if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

6460
    // has no table alias name
H
Haojun Liao 已提交
6461
    if (memcmp(pTableItem->pz, p1->pVar.pz, p1->pVar.nLen) == 0) {
6462 6463
      extractTableName(pTableMetaInfo1->name, pTableMetaInfo1->aliasName);
    } else {
H
Haojun Liao 已提交
6464
      tstrncpy(pTableMetaInfo1->aliasName, p1->pVar.pz, sizeof(pTableMetaInfo1->aliasName));
6465
    }
H
Haojun Liao 已提交
6466 6467

    code = tscGetTableMeta(pSql, pTableMetaInfo1);
6468 6469 6470
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
H
Haojun Liao 已提交
6471 6472

    i += 2;
6473 6474
  }

H
Haojun Liao 已提交
6475
  assert(pQueryInfo->numOfTables == taosArrayGetSize(pQuerySql->from) / 2);
H
hjxilinx 已提交
6476
  bool isSTable = false;
H
hjxilinx 已提交
6477
  
weixin_48148422's avatar
weixin_48148422 已提交
6478
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
6479 6480 6481 6482 6483 6484 6485
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
6486 6487
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
6488
  }
6489

6490
  // parse the group by clause in the first place
6491
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
6492
    return TSDB_CODE_TSC_INVALID_SQL;
6493 6494
  }

6495 6496
  // set where info
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
Y
TD-1230  
yihaoDeng 已提交
6497

6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508
  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 已提交
6509
    if (taosArrayGetSize(pQuerySql->from) > 2) { // it is a join query, no wher clause is not allowed.
6510 6511
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "condition missing for join query ");
    }
Y
TD-1230  
yihaoDeng 已提交
6512
  }
6513

H
Haojun Liao 已提交
6514
  int32_t joinQuery = (pQuerySql->from != NULL && taosArrayGetSize(pQuerySql->from) > 2);
6515

H
Haojun Liao 已提交
6516
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery) != TSDB_CODE_SUCCESS) {
6517
    return TSDB_CODE_TSC_INVALID_SQL;
6518 6519
  }

H
Haojun Liao 已提交
6520 6521 6522 6523 6524
  // set order by info
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_TSC_INVALID_SQL;
  }

6525
  // set interval value
6526
  if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6527
    return TSDB_CODE_TSC_INVALID_SQL;
6528
  } else {
6529
    if ((pQueryInfo->interval.interval > 0) &&
6530
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6531
      return TSDB_CODE_TSC_INVALID_SQL;
6532 6533 6534 6535
    }
  }

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

  // no result due to invalid query time range
H
hjxilinx 已提交
6542
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6543
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6544 6545 6546
    return TSDB_CODE_SUCCESS;
  }

6547
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6548
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6549 6550 6551
  }

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

H
hjxilinx 已提交
6555
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6556
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6557 6558 6559
    }
  }

6560
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6561 6562 6563
    return code;
  }

6564
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6565 6566 6567
    return code;
  }

H
Haojun Liao 已提交
6568
  tscFieldInfoUpdateOffset(pQueryInfo);
6569

6570 6571 6572 6573 6574
  /*
   * 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) {
6575
    if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6576 6577
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6578

6579
    if (pQueryInfo->interval.interval > 0) {
H
Haojun Liao 已提交
6580 6581 6582 6583 6584
      bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER);
      if (initialWindows) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }

S
TD-1057  
Shengliang Guan 已提交
6585
      int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6586
      // number of result is not greater than 10,000,000
6587
      if ((timeRange == 0) || (timeRange / pQueryInfo->interval.interval) > MAX_INTERVAL_TIME_WINDOW) {
6588
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6589 6590
      }
    }
H
hjxilinx 已提交
6591

6592
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6593 6594 6595 6596
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6597 6598 6599

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

H
Haojun Liao 已提交
6601
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid) {
H
hjxilinx 已提交
6602 6603
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6604
  
6605
  if (pSqlExpr->pLeft != NULL) {
H
Haojun Liao 已提交
6606
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pQueryInfo, pCols, uid);
H
hjxilinx 已提交
6607 6608 6609 6610 6611
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6612
  if (pSqlExpr->pRight != NULL) {
H
Haojun Liao 已提交
6613
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid);
H
hjxilinx 已提交
6614 6615 6616 6617
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
H
Haojun Liao 已提交
6618 6619 6620 6621 6622

  if (pSqlExpr->pLeft == NULL && pSqlExpr->pRight == NULL && pSqlExpr->nSQLOptr == 0) {
    *pExpr = calloc(1, sizeof(tExprNode));
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
6623
  
6624
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6625
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6626
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6627
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6628 6629 6630
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6631
      return TSDB_CODE_SUCCESS;
6632
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6633
      // arithmetic expression on the results of aggregation functions
6634
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6635
      (*pExpr)->nodeType = TSQL_NODE_COL;
6636 6637 6638
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6639
      // set the input column data byte and type.
H
Haojun Liao 已提交
6640
      size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
6641 6642
      
      for (int32_t i = 0; i < size; ++i) {
H
Haojun Liao 已提交
6643
        SSqlExpr* p1 = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
6644 6645
        
        if (strcmp((*pExpr)->pSchema->name, p1->aliasName) == 0) {
H
Haojun Liao 已提交
6646
          (*pExpr)->pSchema->type  = (uint8_t)p1->resType;
H
hjxilinx 已提交
6647
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
Haojun Liao 已提交
6648
          (*pExpr)->pSchema->colId = p1->resColId;
H
Haojun Liao 已提交
6649 6650 6651 6652 6653

          if (uid != NULL) {
            *uid = p1->uid;
          }

H
hjxilinx 已提交
6654 6655 6656
          break;
        }
      }
6657
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
H
Haojun Liao 已提交
6658
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
6659
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6660 6661 6662
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
H
Haojun Liao 已提交
6663 6664 6665 6666

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

6667 6668 6669
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
H
Haojun Liao 已提交
6670

6671 6672
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6673 6674 6675
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6676
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6677 6678
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
H
Haojun Liao 已提交
6679 6680
        colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;

6681 6682
        taosArrayPush(pCols, &colIndex);
      }
6683
      
H
hjxilinx 已提交
6684
      return TSDB_CODE_SUCCESS;
6685
    } else {
H
Haojun Liao 已提交
6686
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression");
H
hjxilinx 已提交
6687 6688 6689
    }
    
  } else {
H
hjxilinx 已提交
6690
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6691 6692
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6693 6694 6695
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6696
    
H
Haojun Liao 已提交
6697
    SStrToken t = {.type = pSqlExpr->nSQLOptr};
H
Haojun Liao 已提交
6698
    (*pExpr)->_node.optr = convertOptr(&t);
6699
    
H
[td-32]  
hjxilinx 已提交
6700
    assert((*pExpr)->_node.optr != 0);
6701 6702

    // check for dividing by 0
H
[td-32]  
hjxilinx 已提交
6703
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6704 6705
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6706
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6707
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6708
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6709 6710 6711
        }
      }
    }
H
Hui Li 已提交
6712

6713
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6714
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
6715
      if (pRight != NULL && pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6716 6717 6718
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6719 6720
      }
    }
H
hjxilinx 已提交
6721 6722 6723
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6724
}
6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735

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