tscSQLParser.c 227.5 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 _POSIX_C_SOURCE 200809L
H
hzcheng 已提交
20

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

192
  int32_t code = TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
193 194
  if (!pInfo->valid || terrno == TSDB_CODE_TSC_SQL_SYNTAX_ERROR) {
    terrno = TSDB_CODE_SUCCESS;  // clear the error number
Y
TD-934  
yihaoDeng 已提交
195
    return tscSQLSyntaxErrMsg(tscGetErrorMsgPayload(pCmd), NULL, pInfo->pzErrMsg);
H
hzcheng 已提交
196 197
  }

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

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

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

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

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

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

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

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

H
hjxilinx 已提交
249
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
250 251
      }

252 253
      break;
    }
H
hzcheng 已提交
254

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

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
260
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
261 262
      }

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

      break;
    }

271 272
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
273 274
    }

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

280 281 282 283 284 285 286 287
      break;
    }

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

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

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

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

      break;
    }

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

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

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

317 318 319 320 321
    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 已提交
322

H
Haojun Liao 已提交
323 324
      SStrToken* pName = &pInfo->pDCLInfo->user.user;
      SStrToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
325

326
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
327
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
328 329
      }

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

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

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

H
hzcheng 已提交
349 350 351
      break;
    }

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

S
slguan 已提交
357
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
358
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
359
      }
S
slguan 已提交
360

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

H
Haojun Liao 已提交
365
      // additional msg has been attached already
H
Haojun Liao 已提交
366 367 368
      code = tscSetTableFullName(pTableMetaInfo, pToken, pSql);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
369 370
      }

H
hjxilinx 已提交
371
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
372
    }
373 374 375 376
    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 已提交
377

378 379 380
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
      }
H
hzcheng 已提交
381

382 383 384 385
      if (!tscValidateTableNameLength(pToken->n)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
      }

H
Haojun Liao 已提交
386 387 388
      code = tscSetTableFullName(pTableMetaInfo, pToken, pSql);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
389
      }
H
Haojun Liao 已提交
390

391 392 393 394 395 396 397 398 399 400 401 402
      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 已提交
403 404 405

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

410 411
      /* validate the ip address */
      tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
412

413 414
      /* validate the parameter names and options */
      if (validateDNodeConfig(pDCL) != TSDB_CODE_SUCCESS) {
415
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
416 417
      }

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

S
TD-1732  
Shengliang Guan 已提交
420
      SCfgDnodeMsg* pCfg = (SCfgDnodeMsg*)pMsg;
guanshengliang's avatar
guanshengliang 已提交
421 422
      pDCL->a[0].n = strdequote(pDCL->a[0].z);
      
J
jtao1735 已提交
423
      strncpy(pCfg->ep, pDCL->a[0].z, pDCL->a[0].n);
H
hzcheng 已提交
424

H
Hui Li 已提交
425 426 427 428
      if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }

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

431 432 433 434
      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 已提交
435

436 437
      break;
    }
H
hzcheng 已提交
438

439 440 441 442 443 444
    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 已提交
445

446
      pCmd->command = pInfo->type;
H
hzcheng 已提交
447

448
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
H
Haojun Liao 已提交
449 450
      SStrToken* pName = &pUser->user;
      SStrToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
451

B
Bomin Zhang 已提交
452
      if (pName->n >= TSDB_USER_LEN) {
453
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
454
      }
H
hzcheng 已提交
455

456
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
457
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
458
      }
H
hzcheng 已提交
459

460 461
      if (pCmd->command == TSDB_SQL_CREATE_USER) {
        if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
462
          return TSDB_CODE_TSC_INVALID_SQL;
463 464 465 466
        }
      } else {
        if (pUser->type == TSDB_ALTER_USER_PASSWD) {
          if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
467
            return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
468
          }
469
        } else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
L
lihui 已提交
470 471
          assert(pPwd->type == TSDB_DATA_TYPE_NULL);

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

L
lihui 已提交
474
          if (strncasecmp(pPrivilege->z, "super", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
475
            pCmd->count = 1;
L
lihui 已提交
476
          } else if (strncasecmp(pPrivilege->z, "read", 4) == 0 && pPrivilege->n == 4) {
H
hzcheng 已提交
477
            pCmd->count = 2;
L
lihui 已提交
478
          } else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
479 480
            pCmd->count = 3;
          } else {
481
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
482 483
          }
        } else {
484
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
485 486
        }
      }
487

H
hzcheng 已提交
488 489
      break;
    }
490 491

    case TSDB_SQL_CFG_LOCAL: {
S
slguan 已提交
492 493 494 495 496
      tDCLSQL*    pDCL = pInfo->pDCLInfo;
      const char* msg = "invalid configure options or values";

      // validate the parameter names and options
      if (validateLocalConfig(pDCL) != TSDB_CODE_SUCCESS) {
497
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
498 499 500 501 502 503 504
      }

      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 已提交
505 506 507 508

      break;
    }

509 510
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
511

512
      if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
513
        if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
514
          return code;
H
hzcheng 已提交
515 516
        }

517
      } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) {
518
        assert(pCmd->numOfCols == 0);
519 520
        if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
521 522
        }

523 524 525
      } else if (pCreateTable->type == TSQL_CREATE_STREAM) {
        if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
S
slguan 已提交
526
        }
H
hzcheng 已提交
527 528 529 530 531
      }

      break;
    }

532
    case TSDB_SQL_SELECT: {
H
hjxilinx 已提交
533
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
534

535
      for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) {
536 537 538 539
        SQueryInfo* pqi = tscGetQueryInfoDetailSafely(pCmd, i);
        if (pqi == NULL) {
          pRes->code = terrno;
          return pRes->code;
540
        }
541 542 543
      }

      assert(pCmd->numOfClause == pInfo->subclauseInfo.numOfClause);
H
Haojun Liao 已提交
544
      for (int32_t i = pCmd->clauseIndex; i < pInfo->subclauseInfo.numOfClause; ++i) {
545
        SQuerySQL* pQuerySql = pInfo->subclauseInfo.pClause[i];
H
Haojun Liao 已提交
546
        tscTrace("%p start to parse %dth subclause, total:%d", pSql, i, pInfo->subclauseInfo.numOfClause);
547 548
        if ((code = doCheckForQuery(pSql, pQuerySql, i)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
549
        }
H
hjxilinx 已提交
550

H
hjxilinx 已提交
551
        tscPrintSelectClause(pSql, i);
H
Haojun Liao 已提交
552
        pCmd->clauseIndex += 1;
H
hzcheng 已提交
553
      }
H
hjxilinx 已提交
554

H
Haojun Liao 已提交
555 556
      // restore the clause index
      pCmd->clauseIndex = 0;
H
hjxilinx 已提交
557
      // set the command/global limit parameters from the first subclause to the sqlcmd object
558 559
      SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
      pCmd->command = pQueryInfo1->command;
H
hjxilinx 已提交
560

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

565 566 567
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
568
        }
569
      }
570

571
      pCmd->parseFinished = 1;
572
      return TSDB_CODE_SUCCESS;  // do not build query message here
573
    }
H
hzcheng 已提交
574

575 576 577
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
578 579 580 581 582
      }

      break;
    }

583 584 585
    case TSDB_SQL_KILL_QUERY:
    case TSDB_SQL_KILL_STREAM:
    case TSDB_SQL_KILL_CONNECTION: {
586
      if ((code = setKillInfo(pSql, pInfo, pInfo->type)) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
587 588 589 590 591 592 593
        return code;
      }

      break;
    }

    default:
594
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
595 596
  }

dengyihao's avatar
dengyihao 已提交
597
  pSql->cmd.parseFinished = 1;
598
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
599 600
}

S
slguan 已提交
601 602 603 604
/*
 * if the top/bottom exists, only tags columns, tbname column, and primary timestamp column
 * are available.
 */
605
static bool isTopBottomQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
606 607 608
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = 0; i < size; ++i) {
609
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
610 611 612 613

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

S
slguan 已提交
616
  return false;
H
hzcheng 已提交
617 618
}

619
int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
S
slguan 已提交
620 621
  const char* msg1 = "invalid query expression";
  const char* msg2 = "interval cannot be less than 10 ms";
622
  const char* msg3 = "sliding cannot be used without interval";
623

624 625
  SSqlCmd* pCmd = &pSql->cmd;

H
hjxilinx 已提交
626
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
627
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
628
  
H
hjxilinx 已提交
629
  if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
630 631 632
    if (pQuerySql->sliding.n > 0) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
633 634 635
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
636 637 638 639 640
  // 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 已提交
641
  // interval is not null
642
  SStrToken* t = &pQuerySql->interval;
643
  if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval, &pQueryInfo->interval.intervalUnit) != TSDB_CODE_SUCCESS) {
644
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
645 646
  }

647
  if (pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') {
B
Bomin Zhang 已提交
648 649
    // if the unit of time window value is millisecond, change the value from microsecond
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
650
      pQueryInfo->interval.interval = pQueryInfo->interval.interval / 1000;
B
Bomin Zhang 已提交
651
    }
H
hzcheng 已提交
652

B
Bomin Zhang 已提交
653
    // interval cannot be less than 10 milliseconds
654
    if (pQueryInfo->interval.interval < tsMinIntervalTime) {
B
Bomin Zhang 已提交
655 656
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }
H
hzcheng 已提交
657 658 659
  }

  // for top/bottom + interval query, we do not add additional timestamp column in the front
660
  if (isTopBottomQuery(pQueryInfo)) {
661 662 663 664
    if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_TSC_INVALID_SQL;
    }

665
    if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
666
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
667
    }
H
hjxilinx 已提交
668

H
hzcheng 已提交
669 670 671
    return TSDB_CODE_SUCCESS;
  }

H
hjxilinx 已提交
672 673 674
  /*
   * check invalid SQL:
   * select count(tbname)/count(tag1)/count(tag2) from super_table_name interval(1d);
H
hjxilinx 已提交
675
   */
H
hjxilinx 已提交
676 677
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
678
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
679
    if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
680
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
681 682
    }
  }
H
hjxilinx 已提交
683

H
hjxilinx 已提交
684 685 686
  /*
   * check invalid SQL:
   * select tbname, tags_fields from super_table_name interval(1s)
H
hjxilinx 已提交
687
   */
688
  if (tscQueryTags(pQueryInfo) && pQueryInfo->interval.interval > 0) {
689
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
690
  }
S
slguan 已提交
691 692

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

  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
696
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
697
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
698
    if (pTableMetaInfo->pTableMeta->id.uid == uid) {
S
slguan 已提交
699 700 701 702 703 704
      tableIndex = i;
      break;
    }
  }

  if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
705
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
706 707
  }

H
Haojun Liao 已提交
708 709
  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));
710

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

714 715 716 717
  if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_TSC_INVALID_SQL;
  }

718
  if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
719
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
720
  }
H
hjxilinx 已提交
721

H
hjxilinx 已提交
722
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
723 724
}

725
int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
726 727 728 729
  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'";

730 731 732
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);

733 734 735 736
  SStrToken* t = &pQuerySql->offset;
  if (t->n == 0) {
    pQueryInfo->interval.offsetUnit = pQueryInfo->interval.intervalUnit;
    pQueryInfo->interval.offset = 0;
737 738 739
    return TSDB_CODE_SUCCESS;
  }

740
  if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.offset, &pQueryInfo->interval.offsetUnit) != TSDB_CODE_SUCCESS) {
741
    return TSDB_CODE_TSC_INVALID_SQL;
742 743
  }

744
  if (pQueryInfo->interval.offset < 0) {
745 746 747
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }

748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
  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
771 772 773 774 775
  }

  return TSDB_CODE_SUCCESS;
}

776
int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
777 778
  const char* msg0 = "sliding value too small";
  const char* msg1 = "sliding value no larger than the interval value";
H
Haojun Liao 已提交
779
  const char* msg2 = "sliding value can not less than 1% of interval value";
780 781
  const char* msg3 = "does not support sliding when interval is natural month/year";
  const char* msg4 = "sliding not support yet in ordinary query";
H
Haojun Liao 已提交
782 783

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

H
hjxilinx 已提交
786
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
787
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
788

789
  SStrToken* pSliding = &pQuerySql->sliding;
B
Bomin Zhang 已提交
790
  if (pSliding->n == 0) {
791 792
    pQueryInfo->interval.slidingUnit = pQueryInfo->interval.intervalUnit;
    pQueryInfo->interval.sliding = pQueryInfo->interval.interval;
B
Bomin Zhang 已提交
793 794
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
795

796
  if (pQueryInfo->interval.intervalUnit == 'n' || pQueryInfo->interval.intervalUnit == 'y') {
B
Bomin Zhang 已提交
797 798
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
  }
H
hzcheng 已提交
799

800
  parseAbsoluteDuration(pSliding->z, pSliding->n, &pQueryInfo->interval.sliding);
B
Bomin Zhang 已提交
801
  if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
802
    pQueryInfo->interval.sliding /= 1000;
B
Bomin Zhang 已提交
803 804
  }

805
  if (pQueryInfo->interval.sliding < tsMinSlidingTime) {
B
Bomin Zhang 已提交
806 807 808
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
  }

809
  if (pQueryInfo->interval.sliding > pQueryInfo->interval.interval) {
B
Bomin Zhang 已提交
810
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
811 812
  }

813
  if ((pQueryInfo->interval.interval != 0) && (pQueryInfo->interval.interval/pQueryInfo->interval.sliding > INTERVAL_SLIDING_FACTOR)) {
H
Haojun Liao 已提交
814 815 816
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
  }

817 818 819 820
  if (pQueryInfo->interval.sliding != pQueryInfo->interval.interval && pSql->pStream == NULL) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
  }

H
hzcheng 已提交
821 822 823
  return TSDB_CODE_SUCCESS;
}

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

827 828
  SSqlCmd* pCmd = &pSql->cmd;
  int32_t  code = TSDB_CODE_SUCCESS;
S
slguan 已提交
829

H
hjxilinx 已提交
830
  // backup the old name in pTableMetaInfo
H
Haojun Liao 已提交
831 832
  char oldName[TSDB_TABLE_FNAME_LEN] = {0};
  tstrncpy(oldName, pTableMetaInfo->name, tListLen(oldName));
H
hjxilinx 已提交
833

H
Haojun Liao 已提交
834
  if (hasSpecifyDB(pzTableName)) { // db has been specified in sql string so we ignore current db path
H
hjxilinx 已提交
835
    code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), NULL, pzTableName, NULL);
H
Haojun Liao 已提交
836 837 838
    if (code != 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
    }
H
Haojun Liao 已提交
839
  } else {  // get current DB name first, and then set it into path
H
Haojun Liao 已提交
840
    SStrToken t = {0};
H
hzcheng 已提交
841
    getCurrentDBName(pSql, &t);
H
Haojun Liao 已提交
842
    if (t.n == 0) {  // current database not available or not specified
843
      code = TSDB_CODE_TSC_DB_NOT_SELECTED;
H
Haojun Liao 已提交
844 845 846 847 848
    } else {
      code = setObjFullName(pTableMetaInfo->name, NULL, &t, pzTableName, NULL);
      if (code != 0) {
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
      }
H
Haojun Liao 已提交
849
    }
H
hzcheng 已提交
850
  }
H
Haojun Liao 已提交
851

S
slguan 已提交
852
  if (code != TSDB_CODE_SUCCESS) {
853 854
    return code;
  }
H
hjxilinx 已提交
855

856
  /*
H
Haojun Liao 已提交
857
   * the old name exists and is not equalled to the new name. Release the table meta
858 859
   * that are corresponding to the old name for the new table name.
   */
H
Haojun Liao 已提交
860
  if (strlen(oldName) > 0 && strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
H
Haojun Liao 已提交
861
    tscClearTableMetaInfo(pTableMetaInfo, false);
862
  }
H
hjxilinx 已提交
863

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

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

870 871 872 873 874 875 876
  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 已提交
877 878 879

  // number of fields no less than 2
  if (pFieldList->nField <= 1 || pFieldList->nField > TSDB_MAX_COLUMNS) {
880
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
881 882 883 884 885
    return false;
  }

  // first column must be timestamp
  if (pFieldList->p[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
886
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
887 888 889 890 891
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
B
Bomin Zhang 已提交
892 893 894
    TAOS_FIELD* pField = &pFieldList->p[i];

    if (pField->bytes == 0) {
dengyihao's avatar
dengyihao 已提交
895 896 897
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
      return false;
    }
H
hzcheng 已提交
898 899

    if (pField->type < TSDB_DATA_TYPE_BOOL || pField->type > TSDB_DATA_TYPE_NCHAR) {
900
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
901 902 903 904 905
      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))) {
906
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
907 908 909 910
      return false;
    }

    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
911
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
912 913 914
      return false;
    }

B
Bomin Zhang 已提交
915
    // field name must be unique
H
hzcheng 已提交
916
    if (has(pFieldList, i + 1, pFieldList->p[i].name) == true) {
917
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
918 919
      return false;
    }
B
Bomin Zhang 已提交
920 921 922 923 924 925 926 927

    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 已提交
928 929 930 931 932 933 934 935
  }

  return true;
}

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

936 937 938 939 940 941 942
  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 已提交
943 944 945

  // number of fields at least 1
  if (pTagsList->nField < 1 || pTagsList->nField > TSDB_MAX_TAGS) {
946
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
947 948 949 950 951
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
dengyihao's avatar
dengyihao 已提交
952 953 954 955
    if (pTagsList->p[i].bytes == 0) {
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
      return false;
    }
H
hzcheng 已提交
956 957 958 959 960
    nLen += pTagsList->p[i].bytes;
  }

  // max tag row length must be less than TSDB_MAX_TAGS_LEN
  if (nLen > TSDB_MAX_TAGS_LEN) {
961
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
962 963 964 965 966 967
    return false;
  }

  // field name must be unique
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
    if (has(pFieldList, 0, pTagsList->p[i].name) == true) {
968
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
969 970 971 972 973 974 975
      return false;
    }
  }

  /* timestamp in tag is not allowed */
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
    if (pTagsList->p[i].type == TSDB_DATA_TYPE_TIMESTAMP) {
976
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
977 978 979 980
      return false;
    }

    if (pTagsList->p[i].type < TSDB_DATA_TYPE_BOOL || pTagsList->p[i].type > TSDB_DATA_TYPE_NCHAR) {
981
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
982 983 984 985 986
      return false;
    }

    if ((pTagsList->p[i].type == TSDB_DATA_TYPE_BINARY && pTagsList->p[i].bytes <= 0) ||
        (pTagsList->p[i].type == TSDB_DATA_TYPE_NCHAR && pTagsList->p[i].bytes <= 0)) {
987
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
988 989 990 991
      return false;
    }

    if (validateColumnName(pTagsList->p[i].name) != TSDB_CODE_SUCCESS) {
992
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
993 994 995 996
      return false;
    }

    if (has(pTagsList, i + 1, pTagsList->p[i].name) == true) {
997
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
      return false;
    }
  }

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
1009 1010 1011 1012 1013 1014
  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 已提交
1015

1016
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
1017

1018
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
1019
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
1020

H
hjxilinx 已提交
1021 1022 1023
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
1024
  // no more than 6 tags
H
hjxilinx 已提交
1025
  if (numOfTags == TSDB_MAX_TAGS) {
H
hzcheng 已提交
1026 1027 1028
    char msg[128] = {0};
    sprintf(msg, "tags no more than %d", TSDB_MAX_TAGS);

1029
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
1030 1031 1032 1033 1034
    return false;
  }

  // no timestamp allowable
  if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) {
1035
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1036 1037 1038
    return false;
  }

L
[#1236]  
lihui 已提交
1039
  if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_NCHAR)) {
1040
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1041 1042 1043
    return false;
  }

H
hjxilinx 已提交
1044
  SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1045 1046
  int32_t  nLen = 0;

H
hjxilinx 已提交
1047
  for (int32_t i = 0; i < numOfTags; ++i) {
H
hzcheng 已提交
1048 1049 1050 1051 1052
    nLen += pTagSchema[i].bytes;
  }

  // length less than TSDB_MAX_TASG_LEN
  if (nLen + pTagField->bytes > TSDB_MAX_TAGS_LEN) {
1053
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1054 1055 1056 1057 1058
    return false;
  }

  // tags name can not be a keyword
  if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) {
1059
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
1060 1061 1062 1063 1064
    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) {
1065
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1066 1067 1068 1069
    return false;
  }

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

H
hjxilinx 已提交
1072
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
1073
    if (strncasecmp(pTagField->name, pSchema[i].name, sizeof(pTagField->name) - 1) == 0) {
1074
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1075 1076 1077 1078 1079 1080 1081 1082
      return false;
    }
  }

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
1083 1084 1085 1086 1087 1088
  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 已提交
1089

1090
  assert(pCmd->numOfClause == 1);
1091
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
1092 1093 1094 1095 1096
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
1097
  // no more max columns
H
hjxilinx 已提交
1098
  if (numOfCols >= TSDB_MAX_COLUMNS || numOfTags + numOfCols >= TSDB_MAX_COLUMNS) {
1099
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1100 1101 1102 1103
    return false;
  }

  if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_NCHAR) {
1104
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
1105 1106 1107 1108
    return false;
  }

  if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) {
1109
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1110 1111 1112
    return false;
  }

H
hjxilinx 已提交
1113
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
1114 1115
  int32_t  nLen = 0;

H
hjxilinx 已提交
1116
  for (int32_t i = 0; i < numOfCols; ++i) {
H
hzcheng 已提交
1117 1118 1119 1120
    nLen += pSchema[i].bytes;
  }

  if (pColField->bytes <= 0) {
1121
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
1122 1123 1124 1125 1126
    return false;
  }

  // length less than TSDB_MAX_BYTES_PER_ROW
  if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) {
1127
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1128 1129 1130 1131
    return false;
  }

  // field name must be unique
H
hjxilinx 已提交
1132
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
1133
    if (strncasecmp(pColField->name, pSchema[i].name, sizeof(pColField->name) - 1) == 0) {
1134
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1135 1136 1137 1138 1139 1140 1141 1142
      return false;
    }
  }

  return true;
}

/* is contained in pFieldList or not */
H
hjxilinx 已提交
1143
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name) {
H
hzcheng 已提交
1144
  for (int32_t j = startIdx; j < pFieldList->nField; ++j) {
B
Bomin Zhang 已提交
1145 1146
    TAOS_FIELD* field = pFieldList->p + j;
    if (strncasecmp(name, field->name, sizeof(field->name) - 1) == 0) return true;
H
hzcheng 已提交
1147 1148 1149 1150 1151 1152 1153
  }

  return false;
}

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

H
Haojun Liao 已提交
1154
static void getCurrentDBName(SSqlObj* pSql, SStrToken* pDBToken) {
H
hzcheng 已提交
1155
  pDBToken->z = pSql->pTscObj->db;
S
TD-1057  
Shengliang Guan 已提交
1156
  pDBToken->n = (uint32_t)strlen(pSql->pTscObj->db);
H
hzcheng 已提交
1157 1158 1159
}

/* length limitation, strstr cannot be applied */
H
Haojun Liao 已提交
1160
static bool hasSpecifyDB(SStrToken* pTableName) {
S
TD-1057  
Shengliang Guan 已提交
1161
  for (uint32_t i = 0; i < pTableName->n; ++i) {
H
hzcheng 已提交
1162 1163 1164 1165 1166 1167 1168 1169
    if (pTableName->z[i] == TS_PATH_DELIMITER[0]) {
      return true;
    }
  }

  return false;
}

H
Haojun Liao 已提交
1170
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1171 1172 1173
  int32_t totalLen = 0;

  if (account != NULL) {
S
TD-1057  
Shengliang Guan 已提交
1174
    int32_t len = (int32_t)strlen(account);
H
hzcheng 已提交
1175 1176 1177 1178 1179 1180 1181
    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 已提交
1182
    if (pDB->n >= TSDB_ACCT_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) {
1183
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195
    }

    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 已提交
1196
      if (!tscValidateTableNameLength(tableName->n)) {
1197
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1198 1199 1200
      }
    } else {  // pDB == NULL, the db prefix name is specified in tableName
      /* the length limitation includes tablename + dbname + sep */
B
Bomin Zhang 已提交
1201
      if (tableName->n >= TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN) {
1202
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212
      }
    }

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

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

H
Haojun Liao 已提交
1214
  if (totalLen < TSDB_TABLE_FNAME_LEN) {
S
slguan 已提交
1215 1216 1217
    fullName[totalLen] = 0;
  }

H
Haojun Liao 已提交
1218
  return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1219 1220
}

Y
TD-1688  
yihaoDeng 已提交
1221 1222 1223 1224
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
  tscColumnListInsert(pQueryInfo->colList, &tsCol);
}
1225
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
1226
  const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables";
1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257
  const char* msg2 = "invalid arithmetic expression in select clause";
  const char* msg3 = "tag columns can not be used in arithmetic expression";
  const char* msg4 = "columns from different table mixed up in arithmetic expression";

  // arithmetic function in select clause
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);

  SColumnList columnList = {0};
  int32_t     arithmeticType = NON_ARITHMEIC_EXPR;

  if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }

  int32_t tableIndex = columnList.ids[0].tableIndex;
  if (arithmeticType == NORMAL_ARITHMETIC) {
    pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;

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

    // expr string is set as the parameter of function
    SColumnIndex index = {.tableIndex = tableIndex};

    SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double),
                                       sizeof(double), false);

H
Haojun Liao 已提交
1258 1259 1260
    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);
1261 1262 1263 1264

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

H
Haojun Liao 已提交
1265
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo, colList, NULL);
1266
    if (ret != TSDB_CODE_SUCCESS) {
1267 1268
      taosArrayDestroy(colList);
      tExprTreeDestroy(&pNode, NULL);
1269 1270 1271 1272 1273 1274
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    }

    size_t numOfNode = taosArrayGetSize(colList);
    for(int32_t k = 0; k < numOfNode; ++k) {
      SColIndex* pIndex = taosArrayGet(colList, k);
1275 1276
      if (TSDB_COL_IS_TAG(pIndex->flag)) {
        tExprTreeDestroy(&pNode, NULL);
1277 1278
        taosArrayDestroy(colList);
        tExprTreeDestroy(&pNode, NULL);
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
        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 已提交
1293
    len = tbufTell(&bw);
H
Haojun Liao 已提交
1294
    char* c = tbufGetData(&bw, false);
1295 1296

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

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

H
Haojun Liao 已提交
1303
    tbufCloseWriter(&bw);
1304 1305 1306 1307 1308 1309
    taosArrayDestroy(colList);
    tExprTreeDestroy(&pNode, NULL);
  } else {
    columnList.num = 0;
    columnList.ids[0] = (SColumnIndex) {0, 0};

H
Haojun Liao 已提交
1310 1311 1312 1313 1314 1315 1316
    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 已提交
1317

H
Haojun Liao 已提交
1318
    insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, aliasName, NULL);
1319 1320

    int32_t slot = tscNumOfFields(pQueryInfo) - 1;
H
Haojun Liao 已提交
1321
    SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot);
1322 1323 1324 1325 1326

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

      // arithmetic expression always return result in the format of double float
H
Haojun Liao 已提交
1327
      pArithExprInfo->bytes      = sizeof(double);
1328
      pArithExprInfo->interBytes = sizeof(double);
H
Haojun Liao 已提交
1329
      pArithExprInfo->type       = TSDB_DATA_TYPE_DOUBLE;
1330

H
Haojun Liao 已提交
1331
      int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &pArithExprInfo->uid);
1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343
      if (ret != TSDB_CODE_SUCCESS) {
        tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
      }

      pInfo->pArithExprInfo = pArithExprInfo;
    }
  }

  return TSDB_CODE_SUCCESS;
}

1344

H
Haojun Liao 已提交
1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSQLExprItem* pItem) {
  SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos, pIndex->columnIndex, pIndex->tableIndex);

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

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

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

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

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

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

H
Haojun Liao 已提交
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387
static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) {
  // primary timestamp column has been added already
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
    if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
      return;
    }
  }

  SColumnIndex index = {0};

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

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

H
Haojun Liao 已提交
1388
  SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols);
H
Haojun Liao 已提交
1389 1390 1391 1392 1393
  pSupInfo->visible = false;

  pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
}

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

1397 1398
  const char* msg2 = "functions can not be mixed up";
  const char* msg3 = "not support query expression";
H
hjxilinx 已提交
1399
  const char* msg5 = "invalid function name";
H
hjxilinx 已提交
1400

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

1403 1404 1405
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
H
Haojun Liao 已提交
1406

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

S
slguan 已提交
1411
    // project on all fields
H
Haojun Liao 已提交
1412 1413
    int32_t optr = pItem->pNode->nSQLOptr;

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

S
slguan 已提交
1420
      // select table_name1.field_name1, table_name2.field_name2  from table_name1, table_name2
1421
      if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
1422
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1423
      }
1424
    } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_TBID) {
S
slguan 已提交
1425
      // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
1426
      if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
1427
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1428 1429 1430
      }

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
1431 1432 1433
      int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
1434 1435
      }
    } else {
1436
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1437 1438
    }

H
hjxilinx 已提交
1439
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1440
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1441 1442 1443
    }
  }

1444 1445 1446
  // 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 已提交
1447
    addPrimaryTsColIntoResult(pQueryInfo);
1448 1449
  }

H
Haojun Liao 已提交
1450
  if (!functionCompatibleCheck(pQueryInfo, joinQuery)) {
1451
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1452 1453
  }

H
Haojun Liao 已提交
1454 1455
  /*
   * transfer sql functions that need secondary merge into another format
1456
   * in dealing with super table queries such as: count/first/last
H
Haojun Liao 已提交
1457
   */
1458
  if (isSTable) {
H
hjxilinx 已提交
1459
    tscTansformSQLFuncForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1460

1461
    if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
1462
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1463 1464 1465 1466 1467 1468
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1469 1470
int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
    int8_t type, char* fieldName, SSqlExpr* pSqlExpr) {
1471
  
S
slguan 已提交
1472
  for (int32_t i = 0; i < pIdList->num; ++i) {
1473 1474 1475 1476 1477 1478 1479 1480
    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;
    }
    
1481
    tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i]));
H
hzcheng 已提交
1482
  }
H
hjxilinx 已提交
1483 1484
  
  TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
H
Haojun Liao 已提交
1485
  SInternalField* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
H
hjxilinx 已提交
1486
  pInfo->pSqlExpr = pSqlExpr;
H
hjxilinx 已提交
1487
  
H
hzcheng 已提交
1488 1489 1490
  return TSDB_CODE_SUCCESS;
}

1491
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1492
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1493 1494 1495
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
1496
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
H
hzcheng 已提交
1497

1498
  int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
1499 1500 1501 1502
  SColumnIndex index = {.tableIndex = tableIndex,};
  
  if (functionId == TSDB_FUNC_TAGPRJ) {
    index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta);
H
hjxilinx 已提交
1503 1504
  
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
1505 1506 1507 1508 1509 1510
  } else {
    index.columnIndex = colIndex;
  }
  
  return tscSqlExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes,
      pSchema->bytes, functionId == TSDB_FUNC_TAGPRJ);
H
hzcheng 已提交
1511 1512
}

H
Haojun Liao 已提交
1513
SSqlExpr* tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1514
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
H
Haojun Liao 已提交
1515
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
H
Haojun Liao 已提交
1516
                                     pColSchema->bytes, pColSchema->bytes, TSDB_COL_IS_TAG(flag));
H
Haojun Liao 已提交
1517
  tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName));
H
hzcheng 已提交
1518

S
slguan 已提交
1519 1520 1521 1522
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1523

H
hjxilinx 已提交
1524
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1525 1526

  pExpr->colInfo.flag = flag;
1527 1528
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  
S
slguan 已提交
1529
  if (TSDB_COL_IS_TAG(flag)) {
H
hjxilinx 已提交
1530
    tscColumnListInsert(pTableMetaInfo->tagColList, pIndex);
S
slguan 已提交
1531
  }
H
Haojun Liao 已提交
1532 1533

  return pExpr;
S
slguan 已提交
1534 1535
}

1536
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1537
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1538 1539

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1540 1541
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1542

H
hjxilinx 已提交
1543
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1544
  
weixin_48148422's avatar
weixin_48148422 已提交
1545
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1546
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1547
  } else {
H
hjxilinx 已提交
1548
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1549 1550 1551
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
hjxilinx 已提交
1552
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex);
B
Bomin Zhang 已提交
1553
    tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName));
S
slguan 已提交
1554 1555 1556 1557

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

H
hjxilinx 已提交
1560
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1561 1562 1563 1564 1565
  }

  return numOfTotalColumns;
}

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

1570
  int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
Haojun Liao 已提交
1571 1572 1573 1574 1575
  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 已提交
1576
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1577
    if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1578
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
1579 1580 1581 1582
    }

    // all meters columns are required
    if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) {  // all table columns are required.
1583
      for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
S
slguan 已提交
1584
        index.tableIndex = i;
1585
        int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1586
        startPos += inc;
H
hzcheng 已提交
1587 1588
      }
    } else {
1589
      doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1590
    }
H
Haojun Liao 已提交
1591 1592 1593

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

H
Haojun Liao 已提交
1597
    // user-specified constant value as a new result column
1598 1599
    index.columnIndex = (pQueryInfo->udColumnId--);
    index.tableIndex = 0;
H
hzcheng 已提交
1600

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

1605 1606 1607 1608 1609
    // 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 已提交
1610

1611 1612 1613
    if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
    }
H
Haojun Liao 已提交
1614

1615 1616 1617 1618 1619 1620
    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 已提交
1621

1622 1623
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1624 1625
      }

1626
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
Haojun Liao 已提交
1627
      pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
H
hzcheng 已提交
1628
    }
H
Haojun Liao 已提交
1629

1630 1631
    // add the primary timestamp column even though it is not required by user
    tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
H
hzcheng 已提交
1632
  } else {
1633
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1634 1635 1636 1637 1638
  }

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
1643 1644
  int16_t type = 0;
  int16_t bytes = 0;
Y
TD-1230  
yihaoDeng 已提交
1645
  int32_t functionID = cvtFunc.execFuncId;
H
hzcheng 已提交
1646 1647

  if (functionID == TSDB_FUNC_SPREAD) {
1648
    int32_t t1 = pSchema->type;
1649
    if (t1 == TSDB_DATA_TYPE_BINARY || t1 == TSDB_DATA_TYPE_NCHAR || t1 == TSDB_DATA_TYPE_BOOL) {
1650
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1651 1652 1653 1654 1655 1656
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
1657 1658
    type = pSchema->type;
    bytes = pSchema->bytes;
H
hzcheng 已提交
1659
  }
Y
TD-1230  
yihaoDeng 已提交
1660
  
1661
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, bytes, false);
1662
  tstrncpy(pExpr->aliasName, name, tListLen(pExpr->aliasName));
1663

Y
TD-1230  
yihaoDeng 已提交
1664 1665 1666 1667
  if (cvtFunc.originFuncId == TSDB_FUNC_LAST_ROW && cvtFunc.originFuncId != functionID) {
    pExpr->colInfo.flag |= TSDB_COL_NULL;
  }

1668 1669 1670 1671 1672 1673
  // 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 已提交
1674
  
H
hjxilinx 已提交
1675
  // for all queries, the timestamp column needs to be loaded
S
slguan 已提交
1676
  SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1677
  tscColumnListInsert(pQueryInfo->colList, &index);
H
hzcheng 已提交
1678

H
Haojun Liao 已提交
1679
  // if it is not in the final result, do not add it
S
slguan 已提交
1680
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
H
Haojun Liao 已提交
1681
  if (finalResult) {
1682
    insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, pExpr->aliasName, pExpr);
H
Haojun Liao 已提交
1683 1684 1685
  } else {
    tscColumnListInsert(pQueryInfo->colList, &(ids.ids[0]));
  }
H
hzcheng 已提交
1686 1687 1688 1689

  return TSDB_CODE_SUCCESS;
}

1690 1691 1692 1693 1694 1695 1696 1697
void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrToken* pToken) {
  if (pItem->aliasName != NULL) {
    tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN);
  } else {
    char uname[TSDB_COL_NAME_LEN] = {0};
    int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN);
    tstrncpy(uname, pToken->z, len);

H
Haojun Liao 已提交
1698 1699 1700 1701 1702 1703
    int32_t size = TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].aName) + 2 + 1;
    char tmp[TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].aName) + 2 + 1] = {0};

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

    tstrncpy(name, tmp, TSDB_COL_NAME_LEN);
1704 1705 1706
  }
}

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

1711
  const char* msg1 = "not support column types";
S
slguan 已提交
1712
  const char* msg2 = "invalid parameters";
1713
  const char* msg3 = "illegal column name";
S
slguan 已提交
1714
  const char* msg4 = "invalid table name";
1715
  const char* msg5 = "parameter is out of range [0, 100]";
S
slguan 已提交
1716
  const char* msg6 = "function applied to tags not allowed";
1717
  const char* msg7 = "normal table can not apply this function";
H
Haojun Liao 已提交
1718
  const char* msg8 = "multi-columns selection does not support alias column name";
B
Bomin Zhang 已提交
1719
  const char* msg9 = "invalid function";
H
Haojun Liao 已提交
1720

H
hzcheng 已提交
1721 1722 1723
  switch (optr) {
    case TK_COUNT: {
        /* more than one parameter for count() function */
H
Haojun Liao 已提交
1724
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
1725
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1726 1727 1728 1729
      }

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

H
hjxilinx 已提交
1733
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1734
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1735 1736

      if (pItem->pNode->pParam != NULL) {
S
slguan 已提交
1737
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
Y
TD-1370  
yihaoDeng 已提交
1738
        SStrToken* pToken = &pParamElem->pNode->colInfo;
S
TD-1530  
Shengliang Guan 已提交
1739
        int16_t sqlOptr = pParamElem->pNode->nSQLOptr;
Y
TD-1370  
yihaoDeng 已提交
1740 1741 1742 1743 1744
        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 已提交
1745 1746
          // select table.*
          // check if the table name is valid or not
H
Haojun Liao 已提交
1747
          SStrToken tmpToken = pParamElem->pNode->colInfo;
S
slguan 已提交
1748

1749
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1750
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1751 1752 1753 1754
          }

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
1755
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
Y
TD-1370  
yihaoDeng 已提交
1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770
        } else if (sqlOptr == TK_INTEGER) { // select count(1) from table1
          char buf[8] = {0};  
          int64_t val = -1;
          tVariant* pVariant = &pParamElem->pNode->val;
          if (pVariant->nType == TSDB_DATA_TYPE_BIGINT) {
            tVariantDump(pVariant, buf, TSDB_DATA_TYPE_BIGINT, true);
            val = GET_INT64_VAL(buf); 
          }
          if (val == 1) {
            index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
            int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
            pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
          } else {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
          }
H
hzcheng 已提交
1771
        } else {
H
hjxilinx 已提交
1772
          // count the number of meters created according to the super table
1773 1774
          if (getColumnIndexByName(pCmd, pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1775 1776
          }

H
hjxilinx 已提交
1777
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1778 1779

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1780 1781
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1782
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1783
            isTag = true;
H
hzcheng 已提交
1784 1785
          }

S
slguan 已提交
1786
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1787
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1788
        }
S
slguan 已提交
1789 1790 1791
      } 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;
1792
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1793
      }
H
Haojun Liao 已提交
1794 1795 1796

      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);

H
hjxilinx 已提交
1797
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1798
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1799
      
S
slguan 已提交
1800
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1801 1802 1803 1804 1805
      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) {
1806
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1807 1808
        }
      }
H
Haojun Liao 已提交
1809 1810

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

S
slguan 已提交
1815
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1816 1817 1818
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1819 1820 1821 1822 1823 1824
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1825
    case TK_TWA:
H
hzcheng 已提交
1826 1827 1828 1829 1830 1831 1832 1833 1834
    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 */
1835
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
1836 1837 1838 1839
      }

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

S
slguan 已提交
1843
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
Y
yihaoDeng 已提交
1844
      if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
1845
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1846
      }
Y
yihaoDeng 已提交
1847 1848 1849
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
H
hzcheng 已提交
1850 1851

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

H
hjxilinx 已提交
1856
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1857
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
1858 1859 1860 1861
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
1862
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1863 1864 1865

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1866
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1867 1868
      }

S
slguan 已提交
1869 1870
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
1871
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1872
      }
H
hzcheng 已提交
1873

S
slguan 已提交
1874
      // set the first column ts for diff query
H
hzcheng 已提交
1875
      if (optr == TK_DIFF) {
1876
        colIndex += 1;
S
slguan 已提交
1877
        SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
H
hjxilinx 已提交
1878
        SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
1879
                         TSDB_KEYSIZE, false);
H
hzcheng 已提交
1880

S
slguan 已提交
1881
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1882
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1883 1884
      }

S
slguan 已提交
1885
      // functions can not be applied to tags
H
hjxilinx 已提交
1886
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1887
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
1888 1889
      }

1890
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, resultSize, false);
H
hzcheng 已提交
1891 1892 1893 1894

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

S
slguan 已提交
1899
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1900 1901

        memset(val, 0, tListLen(val));
1902
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1903
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1904 1905
        }

S
slguan 已提交
1906
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1907 1908
      }

S
slguan 已提交
1909 1910 1911
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1912 1913
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1914
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1915 1916 1917
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
S
TD-1057  
Shengliang Guan 已提交
1918
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, (int32_t)pExpr->resType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
1919 1920
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1921
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1922 1923
        }
      }
H
Haojun Liao 已提交
1924 1925

      tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
S
slguan 已提交
1926
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1927 1928 1929 1930 1931 1932 1933 1934 1935
    }
    case TK_FIRST:
    case TK_LAST:
    case TK_SPREAD:
    case TK_LAST_ROW:
    case TK_INTERP: {
      bool requireAllFields = (pItem->pNode->pParam == NULL);

      int16_t functionID = 0;
B
Bomin Zhang 已提交
1936
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1937
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
B
Bomin Zhang 已提交
1938
      }
1939 1940

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

H
hzcheng 已提交
1946 1947
      if (!requireAllFields) {
        if (pItem->pNode->pParam->nExpr < 1) {
1948
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1949 1950
        }

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

H
hzcheng 已提交
1955 1956 1957 1958
        /* 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) {
1959
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
1960 1961
          }

S
slguan 已提交
1962 1963
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

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

1967
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1968
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
1969 1970
            }

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

1974
            char name[TSDB_COL_NAME_LEN] = {0};
H
hjxilinx 已提交
1975
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
1976
              index.columnIndex = j;
S
Shengliang Guan 已提交
1977
              SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
1978 1979 1980
              setResultColName(name, pItem, cvtFunc.originFuncId, &t);

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

S
slguan 已提交
1985
          } else {
1986 1987
            if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
1988 1989
            }

H
hjxilinx 已提交
1990
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1991 1992

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

1997 1998 1999 2000 2001 2002
            char name[TSDB_COL_NAME_LEN] = {0};

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

            if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
2003
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2004
            }
2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020

            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 已提交
2021 2022
          }
        }
2023
        
S
slguan 已提交
2024 2025 2026 2027
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

H
Haojun Liao 已提交
2028
        // multicolumn selection does not support alias name
H
Haojun Liao 已提交
2029
        if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
2030
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
Haojun Liao 已提交
2031 2032
        }

2033
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
2034
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
2035
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
2036

H
hjxilinx 已提交
2037
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
2038
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
2039 2040

            char name[TSDB_COL_NAME_LEN] = {0};
S
Shengliang Guan 已提交
2041
            SStrToken t = {.z = pSchema->name, .n = (uint32_t)strnlen(pSchema->name, TSDB_COL_NAME_LEN)};
2042 2043 2044
            setResultColName(name, pItem, cvtFunc.originFuncId, &t);

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

            colIndex++;
H
hzcheng 已提交
2049
          }
S
slguan 已提交
2050

H
hjxilinx 已提交
2051
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
2052 2053
        }

2054
        
S
slguan 已提交
2055
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2056 2057 2058 2059 2060 2061 2062 2063 2064
      }
    }
    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 */
2065
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2066 2067 2068 2069
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
2070
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2071
      }
H
hjxilinx 已提交
2072
      
S
slguan 已提交
2073
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2074 2075
      if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2076
      }
Y
yihaoDeng 已提交
2077 2078 2079 2080
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }
      
H
hjxilinx 已提交
2081
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2082
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
2083 2084

      // functions can not be applied to tags
H
hjxilinx 已提交
2085
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
2086
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
2087 2088 2089
      }

      // 2. valid the column type
S
slguan 已提交
2090
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
2091
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
2092
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2093 2094 2095 2096
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
2097
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2098 2099 2100 2101
      }

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

S
slguan 已提交
2102 2103
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
2104

H
hjxilinx 已提交
2105
      char    val[8] = {0};
H
hjxilinx 已提交
2106 2107
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
2108
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
2109
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
2110

L
lihui 已提交
2111
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
2112
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
2113
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125
        }

        resultSize = sizeof(double);
        resultType = TSDB_DATA_TYPE_DOUBLE;

        /*
         * sql function transformation
         * for dp = 0, it is actually min,
         * for dp = 100, it is max,
         */
        int16_t functionId = 0;
        if (changeFunctionID(optr, &functionId) != TSDB_CODE_SUCCESS) {
2126
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2127
        }
dengyihao's avatar
dengyihao 已提交
2128 2129
        tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
        colIndex += 1;  // the first column is ts
H
hzcheng 已提交
2130

2131
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
2132
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
2133
      } else {
2134
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
2135

H
Haojun Liao 已提交
2136
        int64_t nTop = GET_INT32_VAL(val);
H
hzcheng 已提交
2137
        if (nTop <= 0 || nTop > 100) {  // todo use macro
2138
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2139 2140 2141 2142
        }

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

H
Haojun Liao 已提交
2146
        // todo REFACTOR
H
hzcheng 已提交
2147
        // set the first column ts for top/bottom query
S
slguan 已提交
2148
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
2149 2150
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
            TSDB_KEYSIZE, false);
H
Haojun Liao 已提交
2151
        tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
S
slguan 已提交
2152

H
Haojun Liao 已提交
2153
        const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
2154
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
2155
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
2156
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
2157

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

2160
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
2161
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
2162
      }
H
hjxilinx 已提交
2163 2164
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
2165
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
2166
  
S
slguan 已提交
2167
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
2168
      if (finalResult) {
2169
        insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
2170 2171
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
2172
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
2173 2174
        }
      }
S
slguan 已提交
2175

2176 2177 2178 2179 2180
      return TSDB_CODE_SUCCESS;
    };
    
    case TK_TBID: {
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2181
      if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
2182
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
2183 2184 2185 2186
      }
    
      // no parameters or more than one parameter for function
      if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 1) {
2187
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2188 2189 2190 2191 2192
      }
      
      tSQLExpr* pParam = pItem->pNode->pParam->a[0].pNode;
    
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2193 2194
      if (getColumnIndexByName(pCmd, &pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2195 2196 2197 2198 2199 2200 2201
      }
    
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
  
      // functions can not be applied to normal columns
      int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
2202
      if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
2203
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2204 2205
      }
    
2206 2207 2208
      if (index.columnIndex > 0) {
        index.columnIndex -= numOfCols;
      }
2209 2210
      
      // 2. valid the column type
2211 2212 2213 2214 2215 2216 2217 2218
      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) {
2219
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
2220 2221 2222 2223
      }

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
2224 2225 2226
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
2227
        s = tGetTableNameColumnSchema();
2228 2229 2230 2231
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
2232 2233
      int16_t bytes = 0;
      int16_t type  = 0;
2234
      int32_t inter = 0;
2235 2236 2237 2238

      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 已提交
2239
      s.type = (uint8_t)type;
2240 2241 2242 2243 2244
      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 已提交
2245
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2246
    }
2247
    
H
hzcheng 已提交
2248
    default:
2249
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2250
  }
2251
  
H
hzcheng 已提交
2252 2253
}

S
slguan 已提交
2254 2255
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
2256
  assert(num == 1 && tableIndex >= 0);
S
slguan 已提交
2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267

  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 已提交
2268 2269 2270 2271
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
S
TD-1057  
Shengliang Guan 已提交
2272
    int32_t len = ((int32_t)pItem->pNode->operand.n < nameLength) ? (int32_t)pItem->pNode->operand.n : nameLength;
H
hzcheng 已提交
2273 2274 2275 2276
    strncpy(resultFieldName, pItem->pNode->operand.z, len);
  }
}

H
Haojun Liao 已提交
2277 2278 2279
static bool isTablenameToken(SStrToken* token) {
  SStrToken tmpToken = *token;
  SStrToken tableToken = {0};
S
slguan 已提交
2280 2281 2282 2283 2284 2285

  extractTableNameFromToken(&tmpToken, &tableToken);

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

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

H
hjxilinx 已提交
2289 2290
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
2291 2292 2293 2294 2295 2296 2297 2298 2299 2300

  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 已提交
2301
      break;
S
slguan 已提交
2302 2303 2304 2305 2306 2307
    }
  }

  return columnIndex;
}

H
Haojun Liao 已提交
2308
int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2309 2310 2311 2312 2313 2314 2315 2316 2317 2318
  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) {
2319 2320
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2321 2322 2323

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2324
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
2325 2326 2327 2328 2329 2330 2331
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2332
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2333 2334 2335 2336 2337 2338
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2339
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2340 2341 2342 2343 2344 2345
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2346
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2347 2348 2349
  }
}

H
Haojun Liao 已提交
2350
int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2351
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2352
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2353 2354 2355 2356 2357 2358 2359
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
2360
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2361
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
Haojun Liao 已提交
2362 2363
    char* name = pTableMetaInfo->aliasName;
    if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
S
slguan 已提交
2364 2365 2366 2367 2368 2369
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
2370
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2371 2372 2373 2374 2375
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
2376 2377
int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
  SStrToken tableToken = {0};
S
slguan 已提交
2378 2379
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2380
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2381
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2382 2383
  }

S
slguan 已提交
2384 2385
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2386

H
Haojun Liao 已提交
2387
int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2388
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2389
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2390 2391
  }

H
Haojun Liao 已提交
2392
  SStrToken tmpToken = *pToken;
S
slguan 已提交
2393

2394
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2395
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2396 2397
  }

2398
  return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411
}

int32_t changeFunctionID(int32_t optr, int16_t* functionId) {
  switch (optr) {
    case TK_COUNT:
      *functionId = TSDB_FUNC_COUNT;
      break;
    case TK_SUM:
      *functionId = TSDB_FUNC_SUM;
      break;
    case TK_AVG:
      *functionId = TSDB_FUNC_AVG;
      break;
L
lihui 已提交
2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429
    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 已提交
2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465
    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 已提交
2466 2467
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482
      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 已提交
2483
  SSqlCmd*        pCmd = &pSql->cmd;
2484
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2485
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2486

H
hzcheng 已提交
2487 2488
  pCmd->command = TSDB_SQL_SHOW;

2489
  const char* msg1 = "invalid name";
2490
  const char* msg2 = "pattern filter string too long";
2491 2492 2493 2494
  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 已提交
2495 2496 2497 2498 2499

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2500 2501 2502
  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 已提交
2503
    // db prefix in tagCond, show table conds in payload
H
Haojun Liao 已提交
2504
    SStrToken* pDbPrefixToken = &pShowInfo->prefix;
2505
    if (pDbPrefixToken->type != 0) {
H
hzcheng 已提交
2506

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

2511
      if (pDbPrefixToken->n <= 0) {
2512
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2513 2514
      }

2515
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2516
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2517 2518
      }

H
hjxilinx 已提交
2519
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2520
      if (ret != TSDB_CODE_SUCCESS) {
2521
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2522
      }
2523
    }
H
hzcheng 已提交
2524

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

2530
      if (pPattern->n <= 0) {
2531
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2532
      }
H
hzcheng 已提交
2533

H
Haojun Liao 已提交
2534
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2535
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2536 2537
      }
    }
2538 2539
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2540
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2541 2542
    }

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

2549
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2550
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2551
    }
H
hzcheng 已提交
2552 2553 2554 2555 2556
  }

  return TSDB_CODE_SUCCESS;
}

2557 2558 2559 2560
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 已提交
2561

2562 2563
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2564
  
H
Haojun Liao 已提交
2565
  SStrToken* idStr = &(pInfo->pDCLInfo->ip);
2566
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2567
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2568 2569
  }

2570
  strncpy(pCmd->payload, idStr->z, idStr->n);
2571

H
hzcheng 已提交
2572
  const char delim = ':';
2573 2574
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2575

2576 2577 2578 2579 2580
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2581

2582 2583 2584 2585 2586 2587
  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 已提交
2588
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2589 2590 2591 2592 2593
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2594
  }
2595
  
H
hzcheng 已提交
2596 2597 2598
  return TSDB_CODE_SUCCESS;
}

2599 2600 2601 2602 2603 2604
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);

2605
  in_addr_t epAddr = taosInetAddr(tmp);
2606

2607
  return epAddr != INADDR_NONE;
H
hzcheng 已提交
2608 2609
}

H
hjxilinx 已提交
2610
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2611
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2612

weixin_48148422's avatar
weixin_48148422 已提交
2613
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2614
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2615 2616
  }

H
hjxilinx 已提交
2617
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2618 2619 2620

  int16_t bytes = 0;
  int16_t type = 0;
2621
  int32_t interBytes = 0;
H
hjxilinx 已提交
2622 2623 2624
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2625
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2626 2627
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

2628
    int32_t colIndex = pExpr->colInfo.colIndex;
H
hjxilinx 已提交
2629
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2630
    
S
slguan 已提交
2631
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2632 2633
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
S
TD-1057  
Shengliang Guan 已提交
2634
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64Key, &type, &bytes,
2635
                            &interBytes, 0, true) != TSDB_CODE_SUCCESS) {
2636
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2637
      }
H
hzcheng 已提交
2638

2639
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2640
      // todo refactor
2641
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2642 2643 2644
    }
  }

2645
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2646
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2647 2648 2649
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2650
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2651
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2652
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2653 2654
    return;
  }
H
hjxilinx 已提交
2655 2656 2657
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2658
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2659
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2660
    
2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677
    // 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 已提交
2678 2679 2680
  }
}

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

S
slguan 已提交
2686
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2687 2688
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2689
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
2690
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
2691
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
2692
      return true;
H
hzcheng 已提交
2693 2694 2695
    }
  }

2696 2697
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
2698
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
2699 2700
      return true;
    }
H
hzcheng 已提交
2701

2702
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2703
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2704
      return true;
2705 2706 2707
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
2708
        invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
2709 2710
        return true;
      }
H
hzcheng 已提交
2711 2712
    }
  }
S
slguan 已提交
2713

H
hzcheng 已提交
2714 2715 2716
  return false;
}

H
Haojun Liao 已提交
2717
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
H
hzcheng 已提交
2718
  int32_t startIdx = 0;
H
hjxilinx 已提交
2719
  
H
hjxilinx 已提交
2720 2721
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2722 2723

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

H
Haojun Liao 已提交
2728
  int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2729 2730 2731

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2732 2733 2734
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2735
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2736

H
hjxilinx 已提交
2737
    int16_t functionId = pExpr1->functionId;
2738 2739 2740 2741
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
Haojun Liao 已提交
2742
    if (functionId == TSDB_FUNC_PRJ && (pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->colInfo.flag))) {
S
slguan 已提交
2743 2744 2745
      continue;
    }

H
Haojun Liao 已提交
2746
    if (functionCompatList[functionId] != factor) {
H
hzcheng 已提交
2747 2748
      return false;
    }
H
Haojun Liao 已提交
2749 2750 2751 2752

    if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
      return false;
    }
H
hzcheng 已提交
2753 2754 2755 2756 2757
  }

  return true;
}

2758
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2759 2760
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
2761
  const char* msg3 = "columns from one table allowed as group by columns";
2762
  const char* msg4 = "join query does not support group by";
S
slguan 已提交
2763 2764 2765
  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 已提交
2766

2767
  // todo : handle two tables situation
H
hjxilinx 已提交
2768
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2769 2770 2771 2772 2773

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

2774 2775 2776 2777
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
2778
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2779
  if (pList->nExpr > TSDB_MAX_TAGS) {
2780
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2781 2782
  }

2783 2784 2785 2786
  if (pQueryInfo->numOfTables > 1) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
  }

H
hjxilinx 已提交
2787
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2788
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2789
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2790

S
slguan 已提交
2791
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
2792
  
H
hzcheng 已提交
2793 2794
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tVariant* pVar = &pList->a[i].pVar;
H
Haojun Liao 已提交
2795
    SStrToken token = {pVar->nLen, pVar->nType, pVar->pz};
H
hzcheng 已提交
2796

S
slguan 已提交
2797
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2798 2799
    if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
2800
    }
H
hzcheng 已提交
2801

2802 2803 2804 2805 2806
    if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
      tableIndex = index.tableIndex;
    } else if (tableIndex != index.tableIndex) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2807

H
hjxilinx 已提交
2808
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2809
    pTableMeta = pTableMetaInfo->pTableMeta;
2810 2811
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2812 2813 2814
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2815
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2816
    }
H
hzcheng 已提交
2817

S
slguan 已提交
2818
    bool groupTag = false;
2819
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2820
      groupTag = true;
H
hzcheng 已提交
2821
    }
2822 2823 2824 2825 2826 2827
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2828
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2829
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2830
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
S
slguan 已提交
2831 2832
      }

2833 2834 2835 2836
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2837

H
hjxilinx 已提交
2838
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2839
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2840 2841 2842
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2843 2844
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
H
Haojun Liao 已提交
2845
      if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) {
2846
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
S
slguan 已提交
2847 2848
      }

2849
      tscColumnListInsert(pQueryInfo->colList, &index);
2850
      
2851
      SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
2852
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2853
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2854 2855

      if (i == 0 && pList->nExpr > 1) {
2856
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
2857
      }
H
hzcheng 已提交
2858 2859 2860
    }
  }

2861
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
H
hzcheng 已提交
2862 2863 2864
  return TSDB_CODE_SUCCESS;
}

2865 2866
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2867
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2868
  } else {
H
hjxilinx 已提交
2869
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2870 2871 2872
  }
}

2873
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2874 2875 2876
  if (pColumn == NULL) {
    return NULL;
  }
2877

S
slguan 已提交
2878
  int32_t size = pColumn->numOfFilters + 1;
2879 2880

  char* tmp = (char*) realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2881 2882
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2883 2884
  } else {
    return NULL;
2885 2886
  }

S
slguan 已提交
2887
  pColumn->numOfFilters++;
2888

S
slguan 已提交
2889 2890 2891 2892
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2893 2894
}

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

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

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

S
slguan 已提交
2904
  int16_t colType = pSchema->type;
2905
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2906 2907 2908
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2909
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2910
    int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
2911 2912 2913
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2914 2915
  }

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

B
Bomin Zhang 已提交
2920 2921 2922 2923 2924
  // 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 已提交
2925

B
Bomin Zhang 已提交
2926 2927 2928 2929 2930 2931
  } 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 已提交
2932

B
Bomin Zhang 已提交
2933 2934
  } else {
    retVal = tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
2935 2936
  }

B
Bomin Zhang 已提交
2937 2938 2939 2940
  if (retVal != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
  } 

H
hzcheng 已提交
2941 2942
  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
2943
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
2944 2945
      break;
    case TK_LT:
S
slguan 已提交
2946
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
2947 2948
      break;
    case TK_GT:
2949
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
2950 2951
      break;
    case TK_GE:
2952
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
2953 2954
      break;
    case TK_EQ:
S
slguan 已提交
2955
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
2956 2957
      break;
    case TK_NE:
S
slguan 已提交
2958
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
2959 2960
      break;
    case TK_LIKE:
S
slguan 已提交
2961
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
2962
      break;
H
Haojun Liao 已提交
2963 2964 2965 2966 2967 2968
    case TK_ISNULL:
      pColumnFilter->lowerRelOptr = TSDB_RELATION_ISNULL;
      break;
    case TK_NOTNULL:
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOTNULL;
      break;
S
slguan 已提交
2969
    default:
2970
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
2971
  }
S
slguan 已提交
2972

2973
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2974 2975
}

S
slguan 已提交
2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989
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 已提交
2990

H
hjxilinx 已提交
2991
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
2992 2993

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2994
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2995 2996
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2997 2998

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

H
hjxilinx 已提交
3001 3002 3003 3004 3005 3006 3007
  } 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 已提交
3008 3009 3010 3011 3012 3013
    assert(false);
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
3014
// pExpr->nSQLOptr == 0 while handling "is null" query
S
slguan 已提交
3015 3016
static bool isExprLeafNode(tSQLExpr* pExpr) {
  return (pExpr->pRight == NULL && pExpr->pLeft == NULL) &&
H
Haojun Liao 已提交
3017
         (pExpr->nSQLOptr == 0 || pExpr->nSQLOptr == TK_ID || (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_NCHAR) || pExpr->nSQLOptr == TK_SET);
S
slguan 已提交
3018 3019
}

H
Haojun Liao 已提交
3020
static bool isExprDirectParentOfLeafNode(tSQLExpr* pExpr) {
S
slguan 已提交
3021 3022 3023 3024 3025
  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 已提交
3026
  if (!isExprDirectParentOfLeafNode(pExpr)) {
3027
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3028 3029
  }

S
slguan 已提交
3030 3031 3032 3033 3034 3035 3036 3037 3038 3039
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
3040
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3041 3042 3043 3044 3045 3046 3047 3048 3049
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
3050 3051 3052 3053
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
3054 3055 3056 3057
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105

  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:
3106
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3107 3108 3109 3110 3111 3112 3113
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3114
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
3115 3116
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
3117
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3118 3119
  }

S
slguan 已提交
3120
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
3121
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
3122 3123
  }

H
hzcheng 已提交
3124 3125
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
3126
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
3127 3128

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

H
Haojun Liao 已提交
3132
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
3133
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3134 3135 3136 3137 3138 3139
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3140
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
3141 3142
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
3143 3144

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3145 3146
}

S
slguan 已提交
3147 3148 3149 3150 3151 3152
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
3153

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

H
hjxilinx 已提交
3157 3158
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
3159

S
slguan 已提交
3160
  const char* msg1 = "non binary column not support like operator";
H
Hui Li 已提交
3161 3162
  const char* msg2 = "binary column not support this operator";  
  const char* msg3 = "bool column not support this operator";
S
slguan 已提交
3163

H
hjxilinx 已提交
3164
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177
  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];
    }
3178 3179 3180 3181

    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3182 3183 3184
  } else if (sqlOptr == TK_OR) {
    // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
    pColFilter = addColumnFilterInfo(pColumn);
3185 3186 3187
    if (pColFilter == NULL) {
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }
S
slguan 已提交
3188
  } else {  // error;
3189
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3190 3191
  }

3192
  pColFilter->filterstr =
S
slguan 已提交
3193 3194
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

3195
  if (pColFilter->filterstr) {
S
slguan 已提交
3196
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
3197
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3198
    }
S
slguan 已提交
3199 3200
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
3201
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
3202
    }
H
Hui Li 已提交
3203 3204 3205
    
    if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
      if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
3206
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Hui Li 已提交
3207 3208
      }
    }
S
slguan 已提交
3209 3210 3211
  }

  pColumn->colIndex = *pIndex;
3212
  return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
3213 3214
}

3215
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3216 3217 3218 3219 3220
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

3221
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
3222 3223 3224 3225 3226 3227 3228 3229 3230
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

3231
UNUSED_FUNC
3232
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
3233 3234 3235 3236
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
3237
  if (!isExprDirectParentOfLeafNode(pExpr)) {
S
slguan 已提交
3238 3239
    *(*str) = '(';
    *str += 1;
H
hzcheng 已提交
3240

3241
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
3242
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3243
      return ret;
H
hzcheng 已提交
3244
    }
S
slguan 已提交
3245

3246
    relToString(pExpr, str);
S
slguan 已提交
3247

3248
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
3249 3250 3251 3252

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

H
hzcheng 已提交
3253 3254 3255
    return ret;
  }

S
slguan 已提交
3256 3257 3258
  return tSQLExprLeafToString(pExpr, true, str);
}

3259
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
3260 3261 3262 3263
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
3266 3267
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
3268

S
slguan 已提交
3269
  if (!isTablenameToken(&pLeft->colInfo)) {
3270
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3271 3272
  }

S
slguan 已提交
3273
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
3274

S
slguan 已提交
3275
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
3276
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
3277
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3278
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
3279
  }
H
hzcheng 已提交
3280

S
slguan 已提交
3281
  if (ret != TSDB_CODE_SUCCESS) {
3282
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
3283
  }
H
hzcheng 已提交
3284

S
slguan 已提交
3285 3286 3287
  return ret;
}

3288
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3289 3290 3291 3292
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
3293
  if (!isExprDirectParentOfLeafNode(pExpr)) {  // internal node
3294
    int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3295 3296 3297 3298
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3299
    return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3300 3301
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3302
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3303
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3304
    }
S
slguan 已提交
3305

3306
    return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3307
  }
S
slguan 已提交
3308
}
H
hzcheng 已提交
3309

3310
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
H
Haojun Liao 已提交
3311 3312 3313
  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 已提交
3314

S
slguan 已提交
3315 3316 3317
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3318

H
Haojun Liao 已提交
3319
  if (!isExprDirectParentOfLeafNode(pExpr)) {
3320
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3321 3322
  }

3323
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3324 3325 3326 3327
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3328 3329
  if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3330 3331
  }

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

3335
  pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3336
  pLeft->tagColId = pTagSchema1->colId;
H
hjxilinx 已提交
3337
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3338 3339

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3340 3341
  if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3342 3343
  }

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

3347
  pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
H
Haojun Liao 已提交
3348
  pRight->tagColId = pTagSchema2->colId;
H
hjxilinx 已提交
3349
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3350

H
Haojun Liao 已提交
3351
  if (pTagSchema1->type != pTagSchema2->type) {
3352
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
Haojun Liao 已提交
3353 3354
  }

S
slguan 已提交
3355
  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3356 3357 3358 3359
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
3364
  *(*exprString)++ = '(';
H
hzcheng 已提交
3365 3366

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3367
    doArithmeticExprToString(pLeft, exprString);
H
hzcheng 已提交
3368
  } else {
S
slguan 已提交
3369
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3370
    if (ret != TSDB_CODE_SUCCESS) {
3371
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3372 3373 3374 3375 3376 3377
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3378
    doArithmeticExprToString(pRight, exprString);
H
hzcheng 已提交
3379
  } else {
S
slguan 已提交
3380
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3381
    if (ret != TSDB_CODE_SUCCESS) {
3382
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3383 3384 3385
    }
  }

H
hjxilinx 已提交
3386
  *(*exprString)++ = ')';
H
hzcheng 已提交
3387 3388 3389 3390

  return TSDB_CODE_SUCCESS;
}

3391 3392
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList,
    int32_t* type, uint64_t* uid) {
H
hzcheng 已提交
3393
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3394 3395 3396
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
3397
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3398
    }
L
lihui 已提交
3399

H
hjxilinx 已提交
3400
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3401
    if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3402
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3403 3404 3405
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3406
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3407 3408
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3409 3410
    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)) {
3411
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3412 3413 3414
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3415
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
3416
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3417 3418 3419 3420
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
3421
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3422 3423
    }

S
TD-1057  
Shengliang Guan 已提交
3424
    int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
3425
  
H
hjxilinx 已提交
3426 3427
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
H
Haojun Liao 已提交
3428 3429
    // sql function list in selection clause.
    // Append the sqlExpr into exprList of pQueryInfo structure sequentially
3430
    if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
3431
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3432
    }
H
Haojun Liao 已提交
3433 3434 3435 3436 3437 3438 3439 3440

    // 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
3441
    uint64_t id = -1;
H
Haojun Liao 已提交
3442 3443 3444 3445 3446 3447
    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;
      }
3448 3449 3450 3451 3452 3453

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

    *uid = id;
H
hzcheng 已提交
3457 3458 3459 3460 3461
  }

  return TSDB_CODE_SUCCESS;
}

3462
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3463 3464 3465 3466 3467
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
3468 3469 3470
  uint64_t uidLeft = 0;
  uint64_t uidRight = 0;

H
hzcheng 已提交
3471
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
3472
    int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3473 3474 3475 3476
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3477
    int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type, &uidLeft);
H
hzcheng 已提交
3478 3479 3480 3481 3482 3483 3484
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
3485
    int32_t ret = validateArithmeticSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3486 3487 3488 3489
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
3490
    int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type, &uidRight);
H
hzcheng 已提交
3491 3492 3493
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
3494 3495

    // the expression not from the same table, return error
3496
    if (uidLeft != uidRight && uidLeft != 0 && uidRight != 0) {
3497 3498
      return TSDB_CODE_TSC_INVALID_SQL;
    }
H
hzcheng 已提交
3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510
  }

  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 已提交
3511 3512 3513
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3514 3515 3516
   *
   * However, columnA < 4+12 is valid
   */
B
Bomin Zhang 已提交
3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532
  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 已提交
3533 3534 3535 3536 3537 3538
    return false;
  }

  return true;
}

S
slguan 已提交
3539 3540 3541
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3542

S
slguan 已提交
3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567
  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 已提交
3568

S
slguan 已提交
3569 3570 3571 3572 3573
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3574
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587
  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) {
3588
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
3589 3590 3591 3592 3593
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3594 3595
  if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3596
    return false;
H
hzcheng 已提交
3597 3598
  }

S
slguan 已提交
3599
  // todo extract function
H
hjxilinx 已提交
3600
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3601
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3602 3603
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3604
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3605
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3606 3607 3608
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3609
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
3610 3611
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3612
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
3613
    return false;
H
hzcheng 已提交
3614 3615
  }

S
slguan 已提交
3616
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3617
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3618
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
S
slguan 已提交
3619 3620
    return false;
  }
H
hzcheng 已提交
3621

S
slguan 已提交
3622 3623
  return true;
}
H
hzcheng 已提交
3624

S
slguan 已提交
3625 3626 3627 3628 3629 3630
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 已提交
3631 3632 3633
    }
  }

S
slguan 已提交
3634
  return false;
H
hzcheng 已提交
3635 3636
}

3637
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3638 3639
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3640
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3641
    }
H
hzcheng 已提交
3642

S
slguan 已提交
3643 3644 3645 3646
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3647

S
slguan 已提交
3648 3649
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3650

3651 3652
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                                     int32_t* type, int32_t parentOptr) {
3653
  const char* msg1 = "table query cannot use tags filter";
S
slguan 已提交
3654 3655 3656
  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 已提交
3657 3658 3659
  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";
3660 3661
  const char* msg8 = "wildcard string should be less than 20 characters";
  
S
slguan 已提交
3662 3663
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3664

S
slguan 已提交
3665 3666 3667
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3668 3669
  if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
3670 3671
  }

H
Haojun Liao 已提交
3672
  assert(isExprDirectParentOfLeafNode(*pExpr));
S
slguan 已提交
3673

H
hjxilinx 已提交
3674
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3675
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3676 3677

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3678
    if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3679
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3680
    }
S
slguan 已提交
3681 3682 3683

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
H
hjxilinx 已提交
3684
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
S
slguan 已提交
3685 3686 3687 3688 3689 3690 3691 3692
      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 {
3693
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3694 3695 3696 3697
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3698 3699
  } 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 已提交
3700
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3701
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3702 3703 3704 3705 3706
    }

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

H
hjxilinx 已提交
3710
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3711 3712 3713

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

H
Haojun Liao 已提交
3718
    // in case of in operator, keep it in a seprate attribute
S
slguan 已提交
3719 3720
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3721
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
S
slguan 已提交
3722
      }
3723 3724
  
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
3725
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
3726
      }
S
slguan 已提交
3727 3728 3729 3730 3731 3732

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3733
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
S
slguan 已提交
3734 3735 3736 3737 3738
      }

      *type = TSQL_EXPR_TBNAME;
      *pExpr = NULL;
    } else {
H
Haojun Liao 已提交
3739
      if (pRight != NULL && pRight->nSQLOptr == TK_ID) {  // join on tag columns for stable query
3740
        if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
3741
          return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3742 3743 3744
        }

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

3748 3749
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763
        *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
3764
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
3765 3766
    }

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

S
slguan 已提交
3771
  return ret;
H
hzcheng 已提交
3772 3773
}

3774 3775
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
                        int32_t* type, int32_t parentOptr) {
H
hzcheng 已提交
3776 3777 3778 3779
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3782 3783 3784 3785
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3786
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3787 3788
  }

S
slguan 已提交
3789 3790
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3791

H
Haojun Liao 已提交
3792
  if (!isExprDirectParentOfLeafNode(*pExpr)) {
3793
    int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3794 3795 3796 3797
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3798
    ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3799 3800 3801
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3802

S
slguan 已提交
3803 3804 3805 3806 3807 3808
    /*
     *  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)) {
3809
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
3810
      }
H
hzcheng 已提交
3811 3812
    }

S
slguan 已提交
3813 3814 3815
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3816

S
slguan 已提交
3817
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3818

3819
  return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3820
}
H
hzcheng 已提交
3821

S
slguan 已提交
3822
static void doCompactQueryExpr(tSQLExpr** pExpr) {
3823
  if (*pExpr == NULL || isExprDirectParentOfLeafNode(*pExpr)) {
S
slguan 已提交
3824 3825
    return;
  }
H
hzcheng 已提交
3826

S
slguan 已提交
3827 3828 3829
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3830

S
slguan 已提交
3831 3832 3833
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3834

S
slguan 已提交
3835 3836 3837 3838
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3839

S
slguan 已提交
3840 3841 3842
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3843

S
slguan 已提交
3844 3845 3846 3847
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3848

S
slguan 已提交
3849
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3850
  }
S
slguan 已提交
3851
}
H
hzcheng 已提交
3852

3853
static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
H
Haojun Liao 已提交
3854
  if (isExprDirectParentOfLeafNode(*pExpr)) {
S
slguan 已提交
3855 3856 3857
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3858
    if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3859
      return;
H
hzcheng 已提交
3860 3861
    }

S
slguan 已提交
3862 3863 3864 3865
    if (index.tableIndex != tableIndex) {
      return;
    }

H
Haojun Liao 已提交
3866
    SStrToken t = {0};
S
slguan 已提交
3867 3868 3869 3870 3871 3872 3873 3874
    extractTableNameFromToken(&pLeft->colInfo, &t);

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

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

3875 3876
    doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3877 3878 3879
  }
}

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

S
slguan 已提交
3883
  if (*pExpr != NULL) {
3884
    doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3885
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3886 3887
  }

S
slguan 已提交
3888
  return pResExpr;
H
hzcheng 已提交
3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903
}

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

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

S
slguan 已提交
3908 3909 3910 3911
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3914
  STagCond* pTagCond = &pQueryInfo->tagCond;
3915
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
S
slguan 已提交
3916 3917 3918 3919

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3920
    char* str = taosStringBuilderGetResult(sb, NULL);
3921
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3922 3923 3924
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
3925
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
3926
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3927

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

S
slguan 已提交
3930
  // remove the duplicated input table names
H
hzcheng 已提交
3931
  int32_t num = 0;
H
hjxilinx 已提交
3932 3933 3934
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3935
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3936 3937 3938 3939 3940 3941 3942 3943 3944

  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 已提交
3945
  char* name = extractDBName(pTableMetaInfo->name, db);
H
Haojun Liao 已提交
3946
  SStrToken dbToken = { .type = TK_STRING, .z = name, .n = (uint32_t)strlen(name) };
H
hjxilinx 已提交
3947
  
H
hzcheng 已提交
3948 3949
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3950
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3951
    }
H
hjxilinx 已提交
3952

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

3957
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3958
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3959
      taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3960
      taosTFree(segments);
H
hjxilinx 已提交
3961

3962
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
3963 3964
      return ret;
    }
H
hjxilinx 已提交
3965

H
hjxilinx 已提交
3966
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3967
  }
H
hjxilinx 已提交
3968

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

H
hjxilinx 已提交
3972
  taosStringBuilderDestroy(&sb1);
S
Shengliang Guan 已提交
3973
  taosTFree(segments);
H
hzcheng 已提交
3974 3975 3976
  return TSDB_CODE_SUCCESS;
}

3977
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
3978 3979 3980 3981 3982 3983
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
3984

3985 3986
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
3987 3988
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
3989

3990
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004
          (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;
}

4005
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
4006 4007
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
4008 4009 4010 4011 4012

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

H
Haojun Liao 已提交
4013
  if (!isExprDirectParentOfLeafNode(pExpr)) {
S
slguan 已提交
4014
    if (pExpr->nSQLOptr == TK_OR) {
4015
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4016
    }
H
hzcheng 已提交
4017

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

4020
    return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
S
slguan 已提交
4021 4022
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
4023
    if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4024
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4025 4026
    }

H
hjxilinx 已提交
4027
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4028
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4029
    
S
slguan 已提交
4030 4031
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
4032 4033
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
4034
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
4035 4036 4037
    }

    // update the timestamp query range
H
hjxilinx 已提交
4038 4039
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
4040 4041
    }

H
hjxilinx 已提交
4042 4043
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
4044 4045 4046 4047 4048 4049
    }
  }

  return TSDB_CODE_SUCCESS;
}

4050
static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
4051 4052 4053 4054
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

4055 4056
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
4057 4058
      return TSDB_CODE_SUCCESS;
    } else {
4059
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
4060 4061 4062
    }
  }

H
hjxilinx 已提交
4063
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
4064
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // for stable join, tag columns
4065
                                                   // must be present for join
S
slguan 已提交
4066
    if (pCondExpr->pJoinExpr == NULL) {
4067
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4068 4069 4070 4071
    }
  }

  if (!pCondExpr->tsJoin) {
4072
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4073 4074
  }

S
slguan 已提交
4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099
  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);
  }
}

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

4105
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
4106 4107
      tscError("%p: invalid column name (left)", pQueryInfo);
    }
H
hjxilinx 已提交
4108
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4109 4110
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4111 4112
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
  
4113
    if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
4114 4115
      tscError("%p: invalid column name (right)", pQueryInfo);
    }
H
hjxilinx 已提交
4116
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
4117 4118
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
4119
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
4120
  }
H
hjxilinx 已提交
4121
}
S
slguan 已提交
4122

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

4126 4127 4128 4129 4130
  if (pCondExpr->pTagCond == NULL) {
    return ret;
  }
  
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
4131
    tSQLExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
H
Haojun Liao 已提交
4132 4133 4134 4135
    if (p1 == NULL) {  // no query condition on this table
      continue;
    }

4136
    tExprNode* p = NULL;
4137 4138
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
H
Haojun Liao 已提交
4139
    ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL);
4140 4141 4142 4143 4144 4145 4146 4147 4148
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
4149
    
4150 4151
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
4152
    int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
4153 4154 4155 4156 4157 4158
    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 已提交
4159
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
4160 4161
    }
    
4162
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
4163 4164 4165 4166
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
4167 4168
    
    taosArrayDestroy(colList);
H
hjxilinx 已提交
4169
  }
H
hjxilinx 已提交
4170

4171
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
4172 4173
  return ret;
}
4174
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
4175 4176 4177
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
4178

H
hjxilinx 已提交
4179
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
4180
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
4181

H
hjxilinx 已提交
4182
  int32_t ret = TSDB_CODE_SUCCESS;
S
slguan 已提交
4183

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

H
hjxilinx 已提交
4188
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
4189
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
S
slguan 已提交
4190 4191
  }

H
hjxilinx 已提交
4192
  int32_t type = 0;
4193
  if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4194 4195
    return ret;
  }
H
hjxilinx 已提交
4196

S
slguan 已提交
4197
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
4198

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

S
slguan 已提交
4202
  // 1. check if it is a join query
4203
  if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4204 4205
    return ret;
  }
H
hjxilinx 已提交
4206

S
slguan 已提交
4207
  // 2. get the query time range
4208
  if ((ret = getTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4209 4210
    return ret;
  }
H
hjxilinx 已提交
4211

S
slguan 已提交
4212
  // 3. get the tag query condition
4213
  if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4214
    return ret;
S
slguan 已提交
4215
  }
H
hjxilinx 已提交
4216

S
slguan 已提交
4217
  // 4. get the table name query condition
4218
  if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4219 4220
    return ret;
  }
H
hjxilinx 已提交
4221

S
slguan 已提交
4222
  // 5. other column query condition
4223
  if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4224 4225
    return ret;
  }
H
hjxilinx 已提交
4226

S
slguan 已提交
4227
  // 6. join condition
4228
  if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
4229
    return ret;
H
hzcheng 已提交
4230
  }
H
hjxilinx 已提交
4231

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

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

4238
  if (!validateFilterExpr(pQueryInfo)) {
4239
    return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
4240
  }
H
hjxilinx 已提交
4241

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

H
hjxilinx 已提交
4244
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
4245 4246 4247
  return ret;
}

H
hjxilinx 已提交
4248
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
4249 4250 4251 4252 4253
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
4254 4255
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
4256
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
4257 4258
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
4259
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4260
  }
H
hzcheng 已提交
4261 4262 4263 4264

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

S
slguan 已提交
4267
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
4268
    if (seg != NULL) {
dengyihao's avatar
dengyihao 已提交
4269
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
4270 4271
        parsed = true;
      } else {
4272
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4273
      }
S
slguan 已提交
4274
    } else {
H
Haojun Liao 已提交
4275
      SStrToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
S
slguan 已提交
4276 4277 4278
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
4279
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4280
      }
H
hzcheng 已提交
4281 4282 4283 4284
    }
  } 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 已提交
4285
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300
     *
     * 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
     */
4301
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322

    /*
     * 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 已提交
4323
    win->ekey = val;
H
hzcheng 已提交
4324
  } else if (optr == TK_LT) {
H
hjxilinx 已提交
4325
    win->ekey = val - delta;
H
hzcheng 已提交
4326
  } else if (optr == TK_GT) {
H
hjxilinx 已提交
4327
    win->skey = val + delta;
H
hzcheng 已提交
4328
  } else if (optr == TK_GE) {
H
hjxilinx 已提交
4329
    win->skey = val;
H
hzcheng 已提交
4330
  } else if (optr == TK_EQ) {
H
hjxilinx 已提交
4331
    win->ekey = win->skey = val;
H
hzcheng 已提交
4332 4333 4334 4335
  }
  return TSDB_CODE_SUCCESS;
}

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

H
hjxilinx 已提交
4340 4341
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
B
Bomin Zhang 已提交
4342
    for (int32_t j = 0; j < (TSDB_COL_NAME_LEN - 1) && fieldName[j] != 0; ++j) {
S
slguan 已提交
4343 4344 4345 4346 4347
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
4348 4349
      }
    }
S
slguan 已提交
4350

H
hzcheng 已提交
4351 4352 4353 4354
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4355 4356 4357
  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 已提交
4358
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4359
        const char* msg = "duplicated column name in new table";
4360
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4361 4362 4363 4364 4365 4366 4367
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4368
int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
4369 4370 4371 4372
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
4373 4374 4375 4376

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

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4379
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4380
  }
H
hjxilinx 已提交
4381 4382 4383
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
4384 4385 4386
  if (pQueryInfo->fillVal == NULL) {
    pQueryInfo->fillVal = calloc(size, sizeof(int64_t));
    if (pQueryInfo->fillVal == NULL) {
4387
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4388 4389 4390
    }
  }

H
hzcheng 已提交
4391
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4392
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4393
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4394
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4395 4396
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
4397 4398 4399 4400 4401
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
      } else {
        setNull((char*)&pQueryInfo->fillVal[i], pFields->type, pFields->bytes);
      };
H
hzcheng 已提交
4402 4403
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4404
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4405
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4406
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4407
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4408
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4409 4410

    if (pFillToken->nExpr == 1) {
4411
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4412 4413 4414 4415 4416 4417
    }

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

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

H
hjxilinx 已提交
4421
      if (numOfFillVal > size) {
S
TD-1057  
Shengliang Guan 已提交
4422
        numOfFillVal = (int32_t)size;
H
hzcheng 已提交
4423 4424
      }
    } else {
S
TD-1057  
Shengliang Guan 已提交
4425
      numOfFillVal = (pFillToken->nExpr >  (int32_t)size) ? (int32_t)size : pFillToken->nExpr;
H
hzcheng 已提交
4426 4427 4428 4429 4430
    }

    int32_t j = 1;

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

4433
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4434
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
4435 4436
        continue;
      }
H
hjxilinx 已提交
4437

4438
      int32_t ret = tVariantDump(&pFillToken->a[j].pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4439
      if (ret != TSDB_CODE_SUCCESS) {
4440
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4441 4442
      }
    }
H
hjxilinx 已提交
4443
    
4444
    if ((pFillToken->nExpr < size) || ((pFillToken->nExpr - 1 < size) && (tscIsPointInterpQuery(pQueryInfo)))) {
H
hzcheng 已提交
4445 4446
      tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1];

H
hjxilinx 已提交
4447 4448
      for (int32_t i = numOfFillVal; i < size; ++i) {
        TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4449 4450

        if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4451
          setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
H
hjxilinx 已提交
4452
        } else {
4453
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4454 4455 4456 4457
        }
      }
    }
  } else {
4458
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4459 4460 4461 4462 4463
  }

  return TSDB_CODE_SUCCESS;
}

4464
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4465
  /* set default timestamp order information for all queries */
H
hjxilinx 已提交
4466
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4467

H
Haojun Liao 已提交
4468
  pQueryInfo->order.order = TSDB_ORDER_ASC;
4469 4470
  if (isTopBottomQuery(pQueryInfo)) {
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
Haojun Liao 已提交
4471 4472
  } 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 已提交
4473 4474
  }

H
hjxilinx 已提交
4475
  /* for super table query, set default ascending order for group output */
weixin_48148422's avatar
weixin_48148422 已提交
4476
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
4477
    pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
H
hzcheng 已提交
4478 4479 4480
  }
}

4481
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4482 4483
  const char* msg0 = "only support order by primary timestamp";
  const char* msg1 = "invalid column name";
4484 4485
  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 已提交
4486

4487
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4488
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4489 4490 4491 4492 4493 4494

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

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4495 4496 4497 4498 4499 4500 4501

  /*
   * for table query, there is only one or none order option is allowed, which is the
   * ts or values(top/bottom) order is supported.
   *
   * for super table query, the order option must be less than 3.
   */
weixin_48148422's avatar
weixin_48148422 已提交
4502
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4503
    if (pSortorder->nExpr > 1) {
4504
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4505 4506 4507
    }
  } else {
    if (pSortorder->nExpr > 2) {
4508
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519
    }
  }

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

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

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

weixin_48148422's avatar
weixin_48148422 已提交
4523
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4524 4525
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4526 4527 4528 4529
    }

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

H
hjxilinx 已提交
4531 4532
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4533
      
4534 4535
      // it is a tag column
      if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
4536
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
4537
      }
4538 4539
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (relTagIndex == pColIndex->colIndex) {
H
hzcheng 已提交
4540 4541
        orderByTags = true;
      }
S
slguan 已提交
4542 4543
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4544 4545
    }

S
slguan 已提交
4546
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4547 4548 4549
      orderByTS = true;
    }

4550
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
4551
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4552 4553 4554 4555 4556 4557
    } else {
      assert(!(orderByTags && orderByTS));
    }

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

4565
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4566
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4567
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
4568
        }
4569

4570 4571
        pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4572
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4573
      } else {
4574 4575
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
Haojun Liao 已提交
4576 4577 4578 4579 4580

        // orderby ts query on super table
        if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
          addPrimaryTsColIntoResult(pQueryInfo);
        }
H
hzcheng 已提交
4581 4582 4583 4584
      }
    }

    if (pSortorder->nExpr == 2) {
S
slguan 已提交
4585
      if (orderByTags) {
H
hjxilinx 已提交
4586
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4587
        pQueryInfo->groupbyExpr.orderType = pQuerySql->pSortOrder->a[0].sortOrder;
S
slguan 已提交
4588
      } else {
4589 4590
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4591 4592
      }

H
hzcheng 已提交
4593
      tVariant* pVar2 = &pSortorder->a[1].pVar;
H
Haojun Liao 已提交
4594
      SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4595 4596
      if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
4597 4598 4599
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4600
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4601
      } else {
4602 4603
        pQueryInfo->order.order = pSortorder->a[1].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4604 4605 4606 4607
      }
    }

  } else {  // meter query
4608 4609
    if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4610 4611
    }

4612
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
4613
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4614 4615
    }

4616
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4617
      /* order of top/bottom query in interval is not valid  */
4618
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4619
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4620

4621
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4622
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4623
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
4624
      }
4625

4626 4627
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4628 4629
      return TSDB_CODE_SUCCESS;
    }
4630

4631
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4632 4633 4634 4635 4636 4637
  }

  return TSDB_CODE_SUCCESS;
}

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

4640 4641 4642 4643 4644
  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 已提交
4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659
  
  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 已提交
4660 4661
  const char* msg19 = "invalid new tag name";

H
Haojun Liao 已提交
4662 4663
  int32_t code = TSDB_CODE_SUCCESS;

S
slguan 已提交
4664
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4665
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4666 4667
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4670
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4671
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
4672
  }
P
plum-lihui 已提交
4673

H
Haojun Liao 已提交
4674 4675 4676
  code = tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
H
hzcheng 已提交
4677 4678
  }

H
Haojun Liao 已提交
4679 4680 4681
  code = tscGetTableMeta(pSql, pTableMetaInfo);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
H
hzcheng 已提交
4682 4683
  }

H
hjxilinx 已提交
4684
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4685

4686 4687
  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 已提交
4688
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
4689
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
4690
    }
weixin_48148422's avatar
weixin_48148422 已提交
4691
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) {
4692
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
4693
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4694
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4695
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
4696 4697
  }

4698
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
hzcheng 已提交
4699 4700
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4701
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
4702 4703 4704
    }

    if (!validateOneTags(pCmd, &pFieldList->p[0])) {
4705
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4706
    }
H
hjxilinx 已提交
4707 4708
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4709
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
H
hjxilinx 已提交
4710
    if (tscGetNumOfTags(pTableMeta) == 1) {
4711
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
4712 4713 4714 4715
    }

    // numOfTags == 1
    if (pAlterSQL->varList->nExpr > 1) {
4716
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
H
hzcheng 已提交
4717 4718 4719
    }

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

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

4727
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4728
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4729 4730
    }

H
Haojun Liao 已提交
4731 4732
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
4733
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
H
Haojun Liao 已提交
4734
    } else if (index.columnIndex == numOfCols) {
4735
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
H
hzcheng 已提交
4736 4737
    }

4738 4739
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4740 4741 4742
  
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4743
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
hzcheng 已提交
4744 4745
    tVariantList* pVarList = pAlterSQL->varList;
    if (pVarList->nExpr > 2) {
4746
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4747 4748
    }

4749 4750 4751 4752
    tVariantListItem* pSrcItem = &pAlterSQL->varList->a[0];
    tVariantListItem* pDstItem = &pAlterSQL->varList->a[1];

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

4756
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4757
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
4758
    }
H
hzcheng 已提交
4759

S
slguan 已提交
4760 4761
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4762

H
Haojun Liao 已提交
4763
    SStrToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4764
    if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4765
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4766 4767
    }

H
Haojun Liao 已提交
4768
    SStrToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4769
    if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4770
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
H
hzcheng 已提交
4771 4772
    }

B
Bomin Zhang 已提交
4773
    char name[TSDB_COL_NAME_LEN] = {0};
H
hzcheng 已提交
4774
    strncpy(name, pVarList->a[0].pVar.pz, pVarList->a[0].pVar.nLen);
H
hjxilinx 已提交
4775 4776
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4777 4778 4779

    memset(name, 0, tListLen(name));
    strncpy(name, pVarList->a[1].pVar.pz, pVarList->a[1].pVar.nLen);
H
hjxilinx 已提交
4780 4781
    f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4782 4783
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
    // Note: update can only be applied to table not super table.
4784 4785 4786
    // the following is used to handle tags value for table created according to super table
    pCmd->command = TSDB_SQL_UPDATE_TAGS_VAL;
    
H
hzcheng 已提交
4787 4788
    tVariantList* pVarList = pAlterSQL->varList;
    tVariant*     pTagName = &pVarList->a[0].pVar;
4789
    int16_t       numOfTags = tscGetNumOfTags(pTableMeta);
H
hzcheng 已提交
4790

4791
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4792
    SStrToken    name = {.type = TK_STRING, .z = pTagName->pz, .n = pTagName->nLen};
4793
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4794
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4795 4796
    }

H
hjxilinx 已提交
4797
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
4798
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12);
S
slguan 已提交
4799 4800
    }

H
hjxilinx 已提交
4801
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
4802
    if (tVariantDump(&pVarList->a[1].pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) {
4803
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg13);
H
hzcheng 已提交
4804
    }
4805
    
4806
    pAlterSQL->tagData.dataLen = pTagsSchema->bytes;
H
hzcheng 已提交
4807 4808

    // validate the length of binary
4809
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
H
Haojun Liao 已提交
4810
        varDataTLen(pAlterSQL->tagData.data) > pTagsSchema->bytes) {
4811
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg14);
H
hzcheng 已提交
4812
    }
4813 4814 4815 4816

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

4817 4818
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4819
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4820 4821
    }

4822
    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
4823
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
4824 4825
    pUpdateMsg->tid       = htonl(pTableMeta->id.tid);
    pUpdateMsg->uid       = htobe64(pTableMeta->id.uid);
H
Haojun Liao 已提交
4826
    pUpdateMsg->colId     = htons(pTagsSchema->colId);
H
Hongze Cheng 已提交
4827
    pUpdateMsg->type      = pTagsSchema->type;
H
Haojun Liao 已提交
4828 4829
    pUpdateMsg->bytes     = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion  = htons(pTableMeta->tversion);
4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847
    pUpdateMsg->numOfTags = htons(numOfTags);
    pUpdateMsg->schemaLen = htonl(schemaLen);

    // the schema is located after the msg body, then followed by true tag value
    char* d = pUpdateMsg->data;
    SSchema* pTagCols = tscGetTableTagSchema(pTableMeta);
    for (int i = 0; i < numOfTags; ++i) {
      STColumn* pCol = (STColumn*) d;
      pCol->colId = htons(pTagCols[i].colId);
      pCol->bytes = htons(pTagCols[i].bytes);
      pCol->type  = pTagCols[i].type;
      pCol->offset = 0;

      d += sizeof(STColumn);
    }

    // copy the tag value to msg body
    tVariantDump(&pVarList->a[1].pVar, pUpdateMsg->data + schemaLen, pTagsSchema->type, true);
4848 4849 4850 4851 4852
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
4853
      len = varDataTLen(pUpdateMsg->data + schemaLen);
4854 4855 4856 4857
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
4858
    int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen;
4859
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4860
    
4861
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
hzcheng 已提交
4862 4863
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4864
      const char* msg = "only support add one column";
4865
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
4866 4867 4868
    }

    if (!validateOneColumn(pCmd, &pFieldList->p[0])) {
4869
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4870
    }
H
hjxilinx 已提交
4871 4872
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4873
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
H
hjxilinx 已提交
4874
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
H
hjxilinx 已提交
4875
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15);
H
hzcheng 已提交
4876 4877 4878
    }

    if (pAlterSQL->varList->nExpr > 1) {
H
hjxilinx 已提交
4879
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4880 4881 4882 4883
    }

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

4884
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
H
Haojun Liao 已提交
4885
    SStrToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4886 4887
    if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
H
hzcheng 已提交
4888 4889
    }

4890
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4891
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18);
4892
    }
H
hzcheng 已提交
4893

B
Bomin Zhang 已提交
4894 4895
    char name1[TSDB_COL_NAME_LEN] = {0};
    tstrncpy(name1, pItem->pVar.pz, sizeof(name1));
H
hjxilinx 已提交
4896 4897
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4898 4899 4900 4901 4902
  }

  return TSDB_CODE_SUCCESS;
}

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

4907 4908 4909
  if (pQueryInfo->interval.interval != 0 && pQueryInfo->interval.interval < 10 &&
     pQueryInfo->interval.intervalUnit != 'n' &&
     pQueryInfo->interval.intervalUnit != 'y') {
4910
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
H
hzcheng 已提交
4911
  }
H
hjxilinx 已提交
4912
  
H
hjxilinx 已提交
4913
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4914
  for (int32_t i = 0; i < size; ++i) {
4915
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
4916
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
4917
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4918 4919 4920 4921 4922 4923
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

H
hzcheng 已提交
4928
  // multi-output set/ todo refactor
H
hjxilinx 已提交
4929
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4930 4931
  
  for (int32_t k = 0; k < size; ++k) {
4932
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
4933

4934 4935 4936
    // 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 已提交
4937
      for (int32_t j = 0; j < size; ++j) {
4938
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
4939 4940 4941 4942 4943
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
4944

4945 4946 4947 4948
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4949

4950
    if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4951
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4952 4953 4954
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4955 4956

  if (isProjectionFunction) {
4957
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
4958 4959
  }

4960
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4961 4962 4963
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4964 4965
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4966 4967
} SDNodeDynConfOption;

H
Hui Li 已提交
4968

4969
int32_t validateEp(char* ep) {  
H
Hui Li 已提交
4970 4971 4972
  char buf[TSDB_EP_LEN + 1] = {0};
  tstrncpy(buf, ep, TSDB_EP_LEN);

4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983
  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 已提交
4984 4985
  }

4986
  return TSDB_CODE_SUCCESS;
H
Hui Li 已提交
4987 4988
}

H
hzcheng 已提交
4989 4990
int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
4991
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4992 4993
  }

4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004
  const int tokenLogEnd = 2;
  const int tokenBalance = 2;
  const int tokenMonitor = 3;
  const int tokenDebugFlag = 4;
  const int tokenDebugFlagEnd = 20;
  const SDNodeDynConfOption cfgOptions[] = {
      {"resetLog", 8},    {"resetQueryCache", 15},  {"balance", 7},     {"monitor", 7},
      {"debugFlag", 9},   {"monitorDebugFlag", 16}, {"vDebugFlag", 10}, {"mDebugFlag", 10},
      {"cDebugFlag", 10}, {"httpDebugFlag", 13},    {"qDebugflag", 10}, {"sdbDebugFlag", 12},
      {"uDebugFlag", 10}, {"tsdbDebugFlag", 13},    {"sDebugflag", 10}, {"rpcDebugFlag", 12},
      {"dDebugFlag", 10}, {"mqttDebugFlag", 13},    {"wDebugFlag", 10}, {"tmrDebugFlag", 12},
S
TD-1520  
Shengliang Guan 已提交
5005
      {"cqDebugFlag", 11},
5006
  };
H
hzcheng 已提交
5007

H
Haojun Liao 已提交
5008
  SStrToken* pOptionToken = &pOptions->a[1];
H
hzcheng 已提交
5009 5010 5011

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
5012 5013
    for (int32_t i = 0; i < tokenLogEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
5014 5015 5016 5017
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
5018 5019
  } else if ((strncasecmp(cfgOptions[tokenBalance].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (cfgOptions[tokenBalance].len == pOptionToken->n)) {
H
Haojun Liao 已提交
5020
    SStrToken* pValToken = &pOptions->a[2];
S
Shengliang Guan 已提交
5021 5022
    int32_t vnodeId = 0;
    int32_t dnodeId = 0;
5023
    strdequote(pValToken->z);
S
Shengliang Guan 已提交
5024
    bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId);
5025 5026 5027 5028 5029 5030
    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 已提交
5031
    SStrToken* pValToken = &pOptions->a[2];
S
slguan 已提交
5032 5033
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
5034
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
S
slguan 已提交
5035 5036
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5037
  } else {
H
Haojun Liao 已提交
5038
    SStrToken* pValToken = &pOptions->a[2];
H
hzcheng 已提交
5039 5040

    int32_t val = strtol(pValToken->z, NULL, 10);
5041
    if (val < 0 || val > 256) {
H
hzcheng 已提交
5042
      /* options value is out of valid range */
5043
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5044 5045
    }

5046 5047
    for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) {
      const SDNodeDynConfOption* pOption = &cfgOptions[i];
H
hzcheng 已提交
5048 5049 5050 5051 5052 5053 5054 5055

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

5056
  return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5057 5058
}

S
slguan 已提交
5059 5060
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
5061
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5062 5063
  }

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

H
Haojun Liao 已提交
5067
  SStrToken* pOptionToken = &pOptions->a[0];
S
slguan 已提交
5068 5069 5070 5071 5072 5073 5074 5075 5076 5077

  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 已提交
5078
    SStrToken* pValToken = &pOptions->a[1];
S
slguan 已提交
5079 5080 5081 5082

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
5083
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5084 5085 5086 5087 5088 5089 5090 5091 5092 5093
    }

    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;
      }
    }
  }
5094
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5095 5096
}

H
hzcheng 已提交
5097
int32_t validateColumnName(char* name) {
S
TD-1057  
Shengliang Guan 已提交
5098
  bool ret = isKeyWord(name, (int32_t)strlen(name));
H
hzcheng 已提交
5099
  if (ret) {
5100
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5101 5102
  }

H
Haojun Liao 已提交
5103
  SStrToken token = {.z = name};
H
hzcheng 已提交
5104 5105 5106
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
5107
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5108 5109 5110 5111
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
S
TD-1057  
Shengliang Guan 已提交
5112
    token.n = (uint32_t)strtrim(token.z);
H
hzcheng 已提交
5113 5114 5115

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
5116
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5117 5118 5119 5120 5121
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
5122
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
5123 5124 5125 5126 5127 5128
    }
  }

  return TSDB_CODE_SUCCESS;
}

5129 5130
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
5131 5132 5133
    return true;
  }

H
hjxilinx 已提交
5134
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
5135 5136
}

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

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

H
hzcheng 已提交
5145
  // handle the limit offset value, validate the limit
5146
  pQueryInfo->limit = pQuerySql->limit;
5147
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
5148
  pQueryInfo->slimit = pQuerySql->slimit;
5149
  
5150
  tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
5151 5152
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
5153
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
5154
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
S
slguan 已提交
5155 5156
  }

5157
  if (pQueryInfo->limit.limit == 0) {
5158
    tscDebug("%p limit 0, no output result", pSql);
5159
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
5160
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5161 5162
  }

H
hjxilinx 已提交
5163
  // todo refactor
weixin_48148422's avatar
weixin_48148422 已提交
5164
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
5165
    if (!tscQueryTags(pQueryInfo)) {  // local handle the super table tag query
5166
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
5167
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
5168
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5169
        }
H
hjxilinx 已提交
5170

5171
        // for projection query on super table, all queries are subqueries
H
hjxilinx 已提交
5172 5173
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
            !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
5174
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
5175
        }
S
slguan 已提交
5176
      }
H
hzcheng 已提交
5177 5178
    }

5179
    if (pQueryInfo->slimit.limit == 0) {
5180
      tscDebug("%p slimit 0, no output result", pSql);
5181
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
5182 5183 5184 5185
      return TSDB_CODE_SUCCESS;
    }

    /*
5186 5187 5188 5189
     * 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 已提交
5190
     */
H
hjxilinx 已提交
5191
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
5192 5193 5194 5195
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
5196
    // No tables included. No results generated. Query results are empty.
5197
    if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
5198
      tscDebug("%p no table in super table, no output result", pSql);
5199
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
5200
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
5201 5202 5203
    }

    // keep original limitation value in globalLimit
5204
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
5205
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
5206

5207 5208 5209 5210 5211 5212 5213 5214 5215
    if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
      /*
       * the limitation/offset value should be removed during retrieve data from virtual node,
       * since the global order are done in client side, so the limitation should also
       * be done at the client side.
       */
      if (pQueryInfo->limit.limit > 0) {
        pQueryInfo->limit.limit = -1;
      }
H
hjxilinx 已提交
5216

5217 5218
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
5219
  } else {
5220
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
5221
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
5222
    }
H
hjxilinx 已提交
5223
  
H
hjxilinx 已提交
5224
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
5225 5226 5227
    
    bool hasTags = false;
    bool hasOtherFunc = false;
S
slguan 已提交
5228
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
5229
    for (int32_t i = 0; i < size; ++i) {
5230
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
5231 5232 5233 5234
      if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
        hasTags = true;
      } else {
        hasOtherFunc = true;
H
hzcheng 已提交
5235 5236
      }
    }
5237 5238
    
    if (hasTags && hasOtherFunc) {
5239
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5240
    }
H
hzcheng 已提交
5241 5242 5243 5244
  }

  return TSDB_CODE_SUCCESS;
}
5245

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

5249 5250 5251
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
5252

H
hjxilinx 已提交
5253 5254 5255
  tVariantList* pKeep = pCreateDb->keep;
  if (pKeep != NULL) {
    switch (pKeep->nExpr) {
S
slguan 已提交
5256
      case 1:
S
TD-1057  
Shengliang Guan 已提交
5257
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
5258 5259
        break;
      case 2: {
S
TD-1057  
Shengliang Guan 已提交
5260 5261
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)pKeep->a[1].pVar.i64Key);
5262 5263 5264
        break;
      }
      case 3: {
S
TD-1057  
Shengliang Guan 已提交
5265 5266 5267
        pMsg->daysToKeep = htonl((int32_t)pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl((int32_t)pKeep->a[1].pVar.i64Key);
        pMsg->daysToKeep2 = htonl((int32_t)pKeep->a[2].pVar.i64Key);
5268 5269
        break;
      }
5270
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
5271 5272
    }
  }
H
hjxilinx 已提交
5273

H
hjxilinx 已提交
5274 5275
  return TSDB_CODE_SUCCESS;
}
5276

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

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

H
Haojun Liao 已提交
5282
  SStrToken* pToken = &pCreateDbInfo->precision;
5283 5284
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
5285

5286 5287 5288 5289 5290
    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 已提交
5291
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
5292 5293
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
5294
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
5295 5296
    }
  }
H
hjxilinx 已提交
5297

H
hjxilinx 已提交
5298 5299
  return TSDB_CODE_SUCCESS;
}
5300

S
TD-1732  
Shengliang Guan 已提交
5301
static void setCreateDBOption(SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
Haojun Liao 已提交
5302
  pMsg->maxTables = htonl(-1);  // max tables can not be set anymore
H
hjxilinx 已提交
5303
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
5304
  pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
H
hjxilinx 已提交
5305
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
S
TD-1057  
Shengliang Guan 已提交
5306
  pMsg->commitTime = htonl((int32_t)pCreateDb->commitTime);
H
hjxilinx 已提交
5307 5308
  pMsg->minRowsPerFileBlock = htonl(pCreateDb->minRowsPerBlock);
  pMsg->maxRowsPerFileBlock = htonl(pCreateDb->maxRowsPerBlock);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5309
  pMsg->fsyncPeriod = htonl(pCreateDb->fsyncPeriod);
S
slguan 已提交
5310
  pMsg->compression = pCreateDb->compressionLevel;
H
hjxilinx 已提交
5311
  pMsg->walLevel = (char)pCreateDb->walLevel;
H
hjxilinx 已提交
5312
  pMsg->replications = pCreateDb->replica;
5313
  pMsg->quorum = pCreateDb->quorum;
5314
  pMsg->ignoreExist = pCreateDb->ignoreExists;
Y
yihaoDeng 已提交
5315
  pMsg->update = pCreateDb->update;
H
hjxilinx 已提交
5316 5317 5318
}

int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) {
S
TD-1732  
Shengliang Guan 已提交
5319
  SCreateDbMsg* pMsg = (SCreateDbMsg *)(pCmd->payload);
H
hjxilinx 已提交
5320
  setCreateDBOption(pMsg, pCreateDbSql);
H
hjxilinx 已提交
5321

H
hjxilinx 已提交
5322
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5323
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5324
  }
H
hjxilinx 已提交
5325

H
hjxilinx 已提交
5326
  if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
5327
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5328
  }
H
hjxilinx 已提交
5329

H
hjxilinx 已提交
5330
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
5331
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
5332
  }
H
hjxilinx 已提交
5333

5334
  return TSDB_CODE_SUCCESS;
H
huili 已提交
5335
}
S
slguan 已提交
5336

5337 5338
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
5339

5340 5341
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
H
Haojun Liao 已提交
5342 5343
    SSqlExpr* pExpr = NULL;

H
hjxilinx 已提交
5344
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
Haojun Liao 已提交
5345 5346 5347
    if (size > 0) {
      pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1);
    }
5348

H
Haojun Liao 已提交
5349
    if (pExpr == NULL || pExpr->functionId != TSDB_FUNC_TAG) {
H
Haojun Liao 已提交
5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360
      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;
S
slguan 已提交
5361

5362
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
S
slguan 已提交
5363 5364 5365 5366
      pExpr->colInfo.flag = TSDB_COL_TAG;

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

      int32_t relIndex = index.columnIndex;

5371
      pExpr->colInfo.colIndex = relIndex;
5372 5373
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
5374

5375
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
5376
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
5377 5378 5379 5380
    }
  }
}

H
hjxilinx 已提交
5381 5382 5383
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
5384
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
5385 5386 5387
  pExpr->numOfParams = 1;
}

5388
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
5389
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
H
hjxilinx 已提交
5390
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
5391

H
Haojun Liao 已提交
5392 5393 5394 5395
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

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

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

H
Haojun Liao 已提交
5399
  SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, (int32_t)size);
H
Haojun Liao 已提交
5400
  doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
H
hjxilinx 已提交
5401
  pInfo->visible = false;
S
slguan 已提交
5402 5403
}

5404
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5405
  int32_t tagLength = 0;
H
hjxilinx 已提交
5406
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
5407 5408 5409 5410 5411

//todo is 0??
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);

H
hjxilinx 已提交
5412
  for (int32_t i = 0; i < size; ++i) {
5413
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5414 5415 5416 5417 5418 5419 5420 5421 5422
    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;
    }
  }

5423
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5424

H
hjxilinx 已提交
5425
  for (int32_t i = 0; i < size; ++i) {
5426
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
Haojun Liao 已提交
5427 5428
    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))) {
5429
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
S
TD-1057  
Shengliang Guan 已提交
5430
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64Key, &pExpr->resType,
5431
                        &pExpr->resBytes, &pExpr->interBytes, tagLength, isSTable);
S
slguan 已提交
5432 5433 5434 5435
    }
  }
}

H
Haojun Liao 已提交
5436
static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5437
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5438 5439
  
  for (int32_t i = 0; i < size; ++i) {
5440
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
Haojun Liao 已提交
5441

5442
    if (pExpr->functionId == TSDB_FUNC_PRJ && (!TSDB_COL_IS_UD_COL(pExpr->colInfo.flag) && (pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX))) {
H
hjxilinx 已提交
5443
      bool qualifiedCol = false;
5444
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5445 5446 5447
        SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
  
        if (pExpr->colInfo.colId == pColIndex->colId) {
H
hjxilinx 已提交
5448
          qualifiedCol = true;
H
hjxilinx 已提交
5449
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5450 5451 5452 5453
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
5454

H
Haojun Liao 已提交
5455 5456 5457 5458
      // it is not a tag column/tbname column/user-defined column, return error
      if (!qualifiedCol) {
        return TSDB_CODE_TSC_INVALID_SQL;
      }
H
hjxilinx 已提交
5459 5460
    }
  }
H
Haojun Liao 已提交
5461 5462

  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5463 5464
}

S
slguan 已提交
5465 5466
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
5467 5468
    SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j);
  
Y
TD-1230  
yihaoDeng 已提交
5469
    if (columnId == pColIndex->colId && TSDB_COL_IS_TAG(pColIndex->flag )) {
S
slguan 已提交
5470 5471 5472 5473 5474 5475 5476
      return true;
    }
  }

  return false;
}

5477
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5478 5479
  bool hasTagPrj = false;
  bool hasColumnPrj = false;
H
hjxilinx 已提交
5480
  
H
hjxilinx 已提交
5481
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5482
  for (int32_t i = 0; i < size; ++i) {
5483
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494
    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
5495
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5496 5497
  bool allInGroupby = true;

H
hjxilinx 已提交
5498 5499
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5500
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5501 5502 5503 5504
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5505
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5506 5507 5508 5509 5510 5511 5512 5513 5514
      allInGroupby = false;
      break;
    }
  }

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

5515
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5516
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5517 5518
  
  for (int32_t i = 0; i < size; ++i) {
5519
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531
    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.
 */
5532
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) {
S
slguan 已提交
5533
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5534
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5535

H
Haojun Liao 已提交
5536
  bool    tagTsColExists = false;
S
slguan 已提交
5537 5538 5539
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5540
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5541
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5542
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5543 5544
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
H
Haojun Liao 已提交
5545
      tagTsColExists = true;  // selectivity + ts/tag column
S
slguan 已提交
5546 5547 5548
      break;
    }
  }
H
hjxilinx 已提交
5549

H
hjxilinx 已提交
5550
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5551
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5552 5553
  
    int16_t functionId = pExpr->functionId;
5554
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5555
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5556
      continue;
S
slguan 已提交
5557
    }
H
hjxilinx 已提交
5558

H
hjxilinx 已提交
5559 5560 5561 5562 5563 5564
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5565

H
Haojun Liao 已提交
5566
  if (tagTsColExists) {  // check if the selectivity function exists
S
slguan 已提交
5567 5568
    // 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.
5569
    if (numOfAggregation > 0) {
5570
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5571 5572 5573 5574 5575 5576
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5577
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
H
Haojun Liao 已提交
5578 5579 5580 5581 5582
      int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
      }

S
slguan 已提交
5583 5584 5585 5586 5587
    } 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 已提交
5588
      for (int32_t i = 0; i < numOfExprs; ++i) {
H
Haojun Liao 已提交
5589 5590 5591
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
        int16_t functionId = pExpr->functionId;
        if (functionId == TSDB_FUNC_TAGPRJ || (aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == 0) {
S
slguan 已提交
5592 5593 5594
          continue;
        }

H
Haojun Liao 已提交
5595 5596 5597 5598
        if ((functionId == TSDB_FUNC_LAST_ROW) ||
             (functionId == TSDB_FUNC_LAST_DST && (pExpr->colInfo.flag & TSDB_COL_NULL) != 0)) {
          // do nothing
        } else {
5599
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5600 5601 5602
        }
      }

5603
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
H
Haojun Liao 已提交
5604 5605 5606 5607
      int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
      if (code != TSDB_CODE_SUCCESS) {
        return code;
      }
H
hjxilinx 已提交
5608 5609
    }
  } else {
5610
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5611
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
5612
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hjxilinx 已提交
5613
      }
H
hjxilinx 已提交
5614

H
hjxilinx 已提交
5615 5616
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5617
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
H
Haojun Liao 已提交
5618 5619 5620 5621
        int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo);
        if (code != TSDB_CODE_SUCCESS) {
          return code;
        }
H
hjxilinx 已提交
5622
      }
S
slguan 已提交
5623 5624 5625 5626 5627 5628
    }
  }

  return TSDB_CODE_SUCCESS;
}

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

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

H
Haojun Liao 已提交
5634
  SSchema s = tGetTableNameColumnSchema();
H
hjxilinx 已提交
5635
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5636 5637 5638 5639
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5640
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5641
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
5642
    int16_t colIndex = pColIndex->colIndex;
5643
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5644
      type  = s.type;
H
Haojun Liao 已提交
5645
      bytes = s.bytes;
H
Haojun Liao 已提交
5646
      name  = s.name;
S
slguan 已提交
5647
    } else {
5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658
      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 已提交
5659
    }
H
hjxilinx 已提交
5660 5661 5662
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5663
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5664
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5665
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5666
      
B
Bomin Zhang 已提交
5667 5668
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5669
      
S
slguan 已提交
5670 5671 5672
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5673
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
S
TD-1057  
Shengliang Guan 已提交
5674
      insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
S
slguan 已提交
5675 5676
    } else {
      // if this query is "group by" normal column, interval is not allowed
5677
      if (pQueryInfo->interval.interval > 0) {
5678
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5679 5680 5681
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5682
      for (int32_t j = 0; j < size; ++j) {
5683
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5684 5685 5686 5687 5688 5689 5690 5691 5692 5693
        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) {
5694
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5695 5696 5697 5698 5699 5700 5701
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5702
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5703
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5704
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5705
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5706
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5707 5708

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5709
  if (tscQueryTags(pQueryInfo)) {
5710
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) {
5711
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5712 5713 5714 5715 5716
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5717
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5718
    // check if all the tags prj columns belongs to the group by columns
5719 5720
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
5721
      return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo);
S
slguan 已提交
5722 5723 5724
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5725 5726
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5727
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5728 5729 5730 5731 5732 5733
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5734
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5735
        bool qualified = false;
5736
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5737
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5738 5739 5740 5741 5742 5743 5744
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5745
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
S
slguan 已提交
5746 5747 5748 5749
        }
      }

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

5754
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5755
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
S
slguan 已提交
5756 5757 5758
      }
    }

5759
    if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) {
5760
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5761 5762 5763 5764 5765 5766
    }

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

H
hjxilinx 已提交
5771
    // projection query on super table does not compatible with "group by" syntax
5772
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5773
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5774
    }
H
hjxilinx 已提交
5775

H
hjxilinx 已提交
5776
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5777
  } else {
5778
    return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
S
slguan 已提交
5779 5780
  }
}
5781
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5782 5783 5784
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5785

H
hjxilinx 已提交
5786 5787
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5788
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hjxilinx 已提交
5789
  }
H
hjxilinx 已提交
5790

H
hjxilinx 已提交
5791 5792
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5793
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hjxilinx 已提交
5794
  }
H
hjxilinx 已提交
5795

H
hjxilinx 已提交
5796
  // TODO redefine the function
H
hjxilinx 已提交
5797 5798 5799 5800 5801 5802
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5803
  int32_t index = -1;
H
hjxilinx 已提交
5804
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5805
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5806
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5807 5808 5809 5810
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5811 5812 5813

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5814
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5815
    case 1:
H
Haojun Liao 已提交
5816 5817 5818
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5819
    case 3:
H
Haojun Liao 已提交
5820
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5821
    case 4:
H
Haojun Liao 已提交
5822
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5823
    default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); }
H
hjxilinx 已提交
5824
  }
5825 5826 5827 5828 5829 5830
  
  SColumnIndex ind = {0};
  SSqlExpr* pExpr1 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT,
                                      tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize, false);
  
  const char* name = (pExprList->a[0].aliasName != NULL)? pExprList->a[0].aliasName:functionsInfo[index].name;
B
Bomin Zhang 已提交
5831
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5832 5833
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5834
}
H
hjxilinx 已提交
5835 5836

// can only perform the parameters based on the macro definitation
S
TD-1732  
Shengliang Guan 已提交
5837
int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) {
H
hjxilinx 已提交
5838
  char msg[512] = {0};
H
hjxilinx 已提交
5839

H
hjxilinx 已提交
5840
  if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) {
S
TD-1388  
Shengliang Guan 已提交
5841
    snprintf(msg, tListLen(msg), "invalid db option walLevel: %d, only 1-2 allowed", pCreate->walLevel);
5842
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5843
  }
H
hjxilinx 已提交
5844

H
hjxilinx 已提交
5845
  if (pCreate->replications != -1 &&
5846
      (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) {
H
hjxilinx 已提交
5847
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
5848
             TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
5849
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5850
  }
H
hjxilinx 已提交
5851

5852 5853 5854 5855 5856 5857 5858
  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 已提交
5859
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5860
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5861
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5862
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5863
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5864
  }
H
hjxilinx 已提交
5865

H
hjxilinx 已提交
5866 5867 5868 5869
  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);
5870
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5871
  }
H
hjxilinx 已提交
5872

H
hjxilinx 已提交
5873
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5874
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5875
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5876
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5877
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5878
  }
H
hjxilinx 已提交
5879 5880 5881 5882

  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);
5883
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5884
  }
H
hjxilinx 已提交
5885

H
hjxilinx 已提交
5886
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5887
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5888
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5889
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5890
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5891
  }
H
hjxilinx 已提交
5892

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
5893 5894 5895 5896 5897 5898 5899
  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 已提交
5900
  if (pCreate->compression != -1 &&
S
slguan 已提交
5901
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5902
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5903
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5904
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5905
  }
H
hjxilinx 已提交
5906

H
hjxilinx 已提交
5907 5908
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5909 5910

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

S
TD-1057  
Shengliang Guan 已提交
5914
  int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
H
hjxilinx 已提交
5915
  if (size == 0) {
H
hjxilinx 已提交
5916 5917
    return;
  }
H
hjxilinx 已提交
5918

H
hjxilinx 已提交
5919
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5920 5921

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

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

L
lihui 已提交
5928
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5929 5930 5931
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5932 5933 5934
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
5936
    if (i < size - 1) {
H
hjxilinx 已提交
5937 5938 5939
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5940

H
hjxilinx 已提交
5941
  str[offset] = ']';
5942
  tscDebug("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5943
}
5944

5945
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5946 5947
  const char* msg1 = "invalid table name";

5948 5949
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5950
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5951 5952 5953 5954 5955 5956 5957 5958 5959

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;

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

  assert(pFieldList != NULL);

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

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5963
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5964 5965
  }

H
Haojun Liao 已提交
5966 5967 5968
  int32_t code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql);
  if(code != TSDB_CODE_SUCCESS) {
    return code;
5969 5970 5971 5972
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
5973
    return TSDB_CODE_TSC_INVALID_SQL;
5974 5975 5976 5977
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
H
hjxilinx 已提交
5978
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[col]);
5979 5980 5981 5982
  }

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

H
hjxilinx 已提交
5983
  if (pTagList != NULL) {  // create super table[optional]
5984
    for (int32_t i = 0; i < pTagList->nField; ++i) {
H
hjxilinx 已提交
5985
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pTagList->p[i]);
5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002
    }

    pCmd->count = pTagList->nField;
  }

  return TSDB_CODE_SUCCESS;
}

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

  SSqlCmd* pCmd = &pSql->cmd;

  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
6003 6004 6005
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
6006 6007 6008
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
6009 6010 6011 6012

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

H
hjxilinx 已提交
6013
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
6014 6015

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

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
6019
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6020 6021
  }

H
Haojun Liao 已提交
6022 6023 6024
  int32_t code = tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
6025 6026 6027
  }

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

H
Haojun Liao 已提交
6031
  code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
6032 6033 6034 6035
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
6036
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
6037
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
6038 6039 6040
  }

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

6043
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
B
Bomin Zhang 已提交
6044 6045 6046 6047 6048
  SKVRowBuilder kvRowBuilder = {0};
  if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
hjxilinx 已提交
6049
  int32_t ret = TSDB_CODE_SUCCESS;
6050
  for (int32_t i = 0; i < pList->nExpr; ++i) {
H
Haojun Liao 已提交
6051 6052 6053
    SSchema* pSchema = &pTagSchema[i];
    
    char tagVal[TSDB_MAX_TAGS_LEN];
B
Bomin Zhang 已提交
6054
    if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
H
Haojun Liao 已提交
6055
      if (pList->a[i].pVar.nLen > pSchema->bytes) {
B
Bomin Zhang 已提交
6056
        tdDestroyKVRowBuilder(&kvRowBuilder);
H
hjxilinx 已提交
6057 6058 6059
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
H
Haojun Liao 已提交
6060

B
Bomin Zhang 已提交
6061
    ret = tVariantDump(&(pList->a[i].pVar), tagVal, pSchema->type, true);
H
Haojun Liao 已提交
6062 6063 6064 6065 6066 6067 6068 6069 6070 6071

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

6072
    if (ret != TSDB_CODE_SUCCESS) {
B
Bomin Zhang 已提交
6073
      tdDestroyKVRowBuilder(&kvRowBuilder);
6074
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
6075 6076
    }

H
Haojun Liao 已提交
6077 6078


B
Bomin Zhang 已提交
6079
    tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
6080 6081
  }

B
Bomin Zhang 已提交
6082
  SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
B
Bomin Zhang 已提交
6083 6084 6085 6086 6087
  tdDestroyKVRowBuilder(&kvRowBuilder);
  if (row == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  tdSortKVRowByColIdx(row);
B
Bomin Zhang 已提交
6088
  pTag->dataLen = kvRowLen(row);
B
Bomin Zhang 已提交
6089
  kvRowCpy(pTag->data, row);
B
Bomin Zhang 已提交
6090 6091
  free(row);

6092 6093
  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
6094
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6095 6096
  }

H
hjxilinx 已提交
6097
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
6098
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
  const char* msg1 = "invalid table name";
  const char* msg3 = "fill only available for interval query";
  const char* msg4 = "fill option not supported in stream computing";
  const char* msg5 = "sql too long";  // todo ADD support
H
Haojun Liao 已提交
6111 6112
  const char* msg6 = "from missing in subclause";
  
6113
  SSqlCmd*    pCmd = &pSql->cmd;
6114
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
6115 6116
  assert(pQueryInfo->numOfTables == 1);

6117
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
6118
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
6119 6120

  // if sql specifies db, use it, otherwise use default db
H
Haojun Liao 已提交
6121
  SStrToken* pzTableName = &(pCreateTable->name);
6122 6123 6124
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
6125
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6126
  }
H
Haojun Liao 已提交
6127
  
6128
  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
H
Haojun Liao 已提交
6129 6130 6131 6132 6133
  if (pSrcMeterName == NULL || pSrcMeterName->nExpr == 0) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
  tVariant* pVar = &pSrcMeterName->a[0].pVar;
H
Haojun Liao 已提交
6134
  SStrToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
6135
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
6136
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
6137 6138
  }

H
Haojun Liao 已提交
6139 6140 6141
  int32_t code = tscSetTableFullName(pTableMetaInfo, &srcToken, pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
6142 6143
  }

H
Haojun Liao 已提交
6144
  code = tscGetTableMeta(pSql, pTableMetaInfo);
6145 6146 6147 6148
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
6149
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
H
Haojun Liao 已提交
6150
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false) != TSDB_CODE_SUCCESS) {
6151
    return TSDB_CODE_TSC_INVALID_SQL;
6152 6153 6154
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
6155
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
6156
      return TSDB_CODE_TSC_INVALID_SQL;
6157 6158 6159 6160
    }
  }

  // set interval value
6161
  if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6162
    return TSDB_CODE_TSC_INVALID_SQL;
6163
  } else {
6164
    if ((pQueryInfo->interval.interval > 0) &&
6165
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6166
      return TSDB_CODE_TSC_INVALID_SQL;
6167 6168 6169 6170
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
6171 6172 6173
  code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql);
  if (code != TSDB_CODE_SUCCESS) {
    return code;
6174 6175 6176
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
6177
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
6178 6179
  }

6180
  if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
6181
    return TSDB_CODE_TSC_INVALID_SQL;
6182 6183
  }

H
hjxilinx 已提交
6184
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
6185

6186
  if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
6187
    return TSDB_CODE_TSC_INVALID_SQL;
6188 6189 6190 6191 6192 6193 6194
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
6195
    if (pQueryInfo->interval.interval == 0) {
6196
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
6197 6198 6199 6200 6201 6202
    }

    tVariantListItem* pItem = &pQuerySql->fillType->a[0];
    if (pItem->pVar.nType == TSDB_DATA_TYPE_BINARY) {
      if (!((strncmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) ||
            (strncmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4))) {
6203
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
6204 6205 6206 6207 6208
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
6209
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
6210 6211 6212 6213 6214 6215
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
  assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0));

H
Haojun Liao 已提交
6216 6217 6218 6219 6220 6221 6222 6223 6224
  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";
6225 6226

  int32_t code = TSDB_CODE_SUCCESS;
6227

6228
  SSqlCmd* pCmd = &pSql->cmd;
6229

6230
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
6231
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
6232
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
6233
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
6234
  }
H
hjxilinx 已提交
6235

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

6238 6239
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
6240
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252
  }

  /*
   * 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);
6253
    return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
6254 6255
  }

H
Haojun Liao 已提交
6256
  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM * 2) {
6257
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
6258 6259
  }

6260
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
6261

H
Haojun Liao 已提交
6262
  if (pQuerySql->from->nExpr > 4) {
H
Haojun Liao 已提交
6263 6264 6265
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
  }

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

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
6271
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6272 6273 6274 6275
    }

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

H
Haojun Liao 已提交
6276
    SStrToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
6277
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
6278
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
6279 6280
    }

H
Haojun Liao 已提交
6281
    if (pQueryInfo->numOfTables <= i/2) {  // more than one table
H
hjxilinx 已提交
6282
      tscAddEmptyMetaInfo(pQueryInfo);
6283 6284
    }

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

H
Haojun Liao 已提交
6287
    SStrToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
6288 6289 6290
    code = tscSetTableFullName(pTableMetaInfo1, &t, pSql);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
6291 6292
    }

H
Haojun Liao 已提交
6293
    tVariant* pTableItem1 = &pQuerySql->from->a[i + 1].pVar;
H
Haojun Liao 已提交
6294 6295 6296 6297
    if (pTableItem1->nType != TSDB_DATA_TYPE_BINARY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

H
Haojun Liao 已提交
6298
    SStrToken aliasName = {.z = pTableItem1->pz, .n = pTableItem1->nLen, .type = TK_STRING};
H
Haojun Liao 已提交
6299 6300 6301 6302
    if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
    }

6303 6304 6305 6306 6307 6308
    // has no table alias name
    if (memcmp(pTableItem->pz, pTableItem1->pz, pTableItem1->nLen) == 0) {
      extractTableName(pTableMetaInfo1->name, pTableMetaInfo1->aliasName);
    } else {
      tstrncpy(pTableMetaInfo1->aliasName, pTableItem1->pz, sizeof(pTableMetaInfo1->aliasName));
    }
H
Haojun Liao 已提交
6309 6310

    code = tscGetTableMeta(pSql, pTableMetaInfo1);
6311 6312 6313
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
H
Haojun Liao 已提交
6314 6315

    i += 2;
6316 6317
  }

H
Haojun Liao 已提交
6318
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr / 2);
H
hjxilinx 已提交
6319
  bool isSTable = false;
H
hjxilinx 已提交
6320
  
weixin_48148422's avatar
weixin_48148422 已提交
6321
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
6322 6323 6324 6325 6326 6327 6328
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
6329 6330
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
6331
  }
6332

6333
  // parse the group by clause in the first place
6334
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
6335
    return TSDB_CODE_TSC_INVALID_SQL;
6336 6337
  }

6338 6339
  // set where info
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
Y
TD-1230  
yihaoDeng 已提交
6340

6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354
  if (pQuerySql->pWhere != NULL) {
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_TSC_INVALID_SQL;
    }

    pQuerySql->pWhere = NULL;
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
      pQueryInfo->window.skey = pQueryInfo->window.skey / 1000;
      pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000;
    }
  } else {  // set the time rang
    if (pQuerySql->from->nExpr > 2) { // it is a join query, no wher clause is not allowed.
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "condition missing for join query ");
    }
Y
TD-1230  
yihaoDeng 已提交
6355
  }
6356 6357 6358

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

H
Haojun Liao 已提交
6359
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery) != TSDB_CODE_SUCCESS) {
6360
    return TSDB_CODE_TSC_INVALID_SQL;
6361 6362
  }

H
Haojun Liao 已提交
6363 6364 6365 6366 6367
  // set order by info
  if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_TSC_INVALID_SQL;
  }

6368
  // set interval value
6369
  if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
6370
    return TSDB_CODE_TSC_INVALID_SQL;
6371
  } else {
6372
    if ((pQueryInfo->interval.interval > 0) &&
6373
        (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
6374
      return TSDB_CODE_TSC_INVALID_SQL;
6375 6376 6377 6378
    }
  }

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

  // no result due to invalid query time range
H
hjxilinx 已提交
6385
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
6386
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
6387 6388 6389
    return TSDB_CODE_SUCCESS;
  }

6390
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
6391
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
6392 6393 6394
  }

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

H
hjxilinx 已提交
6398
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
6399
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6400 6401 6402
    }
  }

6403
  if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
6404 6405 6406
    return code;
  }

6407
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
6408 6409 6410
    return code;
  }

6411
  setColumnOffsetValueInResultset(pQueryInfo);
6412

6413 6414 6415 6416 6417
  /*
   * 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) {
6418
    if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
6419 6420
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
6421

6422
    if (pQueryInfo->interval.interval > 0 && pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') {
H
Haojun Liao 已提交
6423 6424 6425 6426 6427
      bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER);
      if (initialWindows) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
      }

S
TD-1057  
Shengliang Guan 已提交
6428
      int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
6429
      // number of result is not greater than 10,000,000
6430
      if ((timeRange == 0) || (timeRange / pQueryInfo->interval.interval) > MAX_INTERVAL_TIME_WINDOW) {
6431
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
6432 6433
      }
    }
H
hjxilinx 已提交
6434

6435
    int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
6436 6437 6438 6439
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
6440 6441 6442

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

H
Haojun Liao 已提交
6444
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid) {
H
hjxilinx 已提交
6445 6446
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
6447
  
6448
  if (pSqlExpr->pLeft != NULL) {
H
Haojun Liao 已提交
6449
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pQueryInfo, pCols, uid);
H
hjxilinx 已提交
6450 6451 6452 6453 6454
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
6455
  if (pSqlExpr->pRight != NULL) {
H
Haojun Liao 已提交
6456
    int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid);
H
hjxilinx 已提交
6457 6458 6459 6460
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
H
Haojun Liao 已提交
6461 6462 6463 6464 6465

  if (pSqlExpr->pLeft == NULL && pSqlExpr->pRight == NULL && pSqlExpr->nSQLOptr == 0) {
    *pExpr = calloc(1, sizeof(tExprNode));
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
6466
  
6467
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
6468
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
6469
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6470
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
6471 6472 6473
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
6474
      return TSDB_CODE_SUCCESS;
6475
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
6476
      // arithmetic expression on the results of aggregation functions
6477
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
6478
      (*pExpr)->nodeType = TSQL_NODE_COL;
6479 6480 6481
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
6482
      // set the input column data byte and type.
H
Haojun Liao 已提交
6483
      size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
6484 6485
      
      for (int32_t i = 0; i < size; ++i) {
H
Haojun Liao 已提交
6486
        SSqlExpr* p1 = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
6487 6488
        
        if (strcmp((*pExpr)->pSchema->name, p1->aliasName) == 0) {
H
Haojun Liao 已提交
6489
          (*pExpr)->pSchema->type  = (uint8_t)p1->resType;
H
hjxilinx 已提交
6490
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
Haojun Liao 已提交
6491 6492 6493 6494 6495

          if (uid != NULL) {
            *uid = p1->uid;
          }

H
hjxilinx 已提交
6496 6497 6498
          break;
        }
      }
6499
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6500
      SColumnIndex index = {0};
6501
      int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
6502 6503 6504
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
H
Haojun Liao 已提交
6505 6506 6507 6508

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

6509 6510 6511
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
H
Haojun Liao 已提交
6512

6513 6514
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6515 6516 6517
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6518
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6519 6520
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
H
Haojun Liao 已提交
6521 6522
        colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;

6523 6524
        taosArrayPush(pCols, &colIndex);
      }
6525
      
H
hjxilinx 已提交
6526
      return TSDB_CODE_SUCCESS;
6527
    } else {
6528
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6529 6530 6531
    }
    
  } else {
H
hjxilinx 已提交
6532
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6533 6534
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6535 6536 6537
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6538
    
H
Haojun Liao 已提交
6539
    SStrToken t = {.type = pSqlExpr->nSQLOptr};
H
[td-32]  
hjxilinx 已提交
6540
    (*pExpr)->_node.optr = getBinaryExprOptr(&t);
6541
    
H
[td-32]  
hjxilinx 已提交
6542
    assert((*pExpr)->_node.optr != 0);
6543 6544

    // check for dividing by 0
H
[td-32]  
hjxilinx 已提交
6545
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6546 6547
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6548
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6549
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6550
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6551 6552 6553
        }
      }
    }
H
Hui Li 已提交
6554

6555
    // NOTE: binary|nchar data allows the >|< type filter
H
Hui Li 已提交
6556
    if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
6557
      if (pRight != NULL && pRight->nodeType == TSQL_NODE_VALUE) {
B
Bomin Zhang 已提交
6558 6559 6560
        if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
          return TSDB_CODE_TSC_INVALID_SQL;
        }
H
Hui Li 已提交
6561 6562
      }
    }
H
hjxilinx 已提交
6563 6564 6565
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6566
}
6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577

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