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

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

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

S
slguan 已提交
35 36 37 38 39 40 41 42
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"

// -1 is tbname column index, so here use the -2 as the initial value
#define COLUMN_INDEX_INITIAL_VAL (-2)
#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 已提交
43

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

49
static SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex);
H
hzcheng 已提交
50 51

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

H
hjxilinx 已提交
54
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name);
H
hzcheng 已提交
55 56 57 58 59
static void getCurrentDBName(SSqlObj* pSql, SSQLToken* pDBToken);
static bool hasSpecifyDB(SSQLToken* pTableName);
static bool validateTableColumnInfo(tFieldList* pFieldList, SSqlCmd* pCmd);
static bool validateTagParams(tFieldList* pTagsList, tFieldList* pFieldList, SSqlCmd* pCmd);

60
static int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQLToken* tableName, int32_t* len);
H
hzcheng 已提交
61

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

65
static int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult);
66
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
H
hjxilinx 已提交
67
                                 int8_t type, char* fieldName, SSqlExpr* pSqlExpr);
S
slguan 已提交
68
static int32_t changeFunctionID(int32_t optr, int16_t* functionId);
H
hjxilinx 已提交
69
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable);
H
hzcheng 已提交
70

71
static bool validateIpAddress(const char* ip, size_t size);
72
static bool hasUnsupportFunctionsForSTableQuery(SQueryInfo* pQueryInfo);
73 74
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo);
static void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo);
H
hzcheng 已提交
75

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

78
static int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
H
hjxilinx 已提交
79
static int32_t parseSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
H
hzcheng 已提交
80

81
static int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pItem);
H
hzcheng 已提交
82

83
static int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql);
84
static int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL);
S
slguan 已提交
85
static int32_t parseOrderbyClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema);
H
hzcheng 已提交
86

87
static int32_t tsRewriteFieldNameIfNecessary(SQueryInfo* pQueryInfo);
H
hzcheng 已提交
88
static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
89
static int32_t validateSqlFunctionInStreamSql(SQueryInfo* pQueryInfo);
S
slguan 已提交
90
static int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString);
91
static int32_t validateFunctionsInIntervalOrGroupbyQuery(SQueryInfo* pQueryInfo);
H
hjxilinx 已提交
92
static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
H
hzcheng 已提交
93
static int32_t validateDNodeConfig(tDCLSQL* pOptions);
S
slguan 已提交
94
static int32_t validateLocalConfig(tDCLSQL* pOptions);
H
hzcheng 已提交
95
static int32_t validateColumnName(char* name);
96
static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType);
S
slguan 已提交
97

H
hjxilinx 已提交
98
static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField);
99
static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo);
H
hjxilinx 已提交
100

101
static void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex);
S
slguan 已提交
102

103
static int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t index, SQuerySQL* pQuerySql, SSqlObj* pSql);
H
hjxilinx 已提交
104
static int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql);
105
static int32_t getColumnIndexByName(const SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
106
static int32_t getTableIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
S
slguan 已提交
107 108
static int32_t optrToString(tSQLExpr* pExpr, char** exprString);

H
hjxilinx 已提交
109
static int32_t getTableIndexImpl(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
110
static int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
111
static int32_t doLocalQueryProcess(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
112
static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate);
H
hjxilinx 已提交
113

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

116
static int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo);
117 118 119
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);
120
static int32_t exprTreeFromSqlExpr(tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols);
H
hjxilinx 已提交
121

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

130
static int setColumnFilterInfoForTimestamp(SQueryInfo* pQueryInfo, tVariant* pVar) {
S
slguan 已提交
131 132 133 134 135
  int64_t     time = 0;
  const char* msg = "invalid timestamp";

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

H
hjxilinx 已提交
138
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
139
  
S
slguan 已提交
140
  if (seg != NULL) {
H
hjxilinx 已提交
141
    if (taosParseTime(pVar->pz, &time, pVar->nLen, tinfo.precision) != TSDB_CODE_SUCCESS) {
142
      return invalidSqlErrMsg(pQueryInfo->msg, msg);
S
slguan 已提交
143 144
    }
  } else {
145
    if (tVariantDump(pVar, (char*)&time, TSDB_DATA_TYPE_BIGINT, true)) {
146
      return invalidSqlErrMsg(pQueryInfo->msg, msg);
S
slguan 已提交
147 148 149 150 151 152 153 154 155
    }
  }

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

  return TSDB_CODE_SUCCESS;
}

156 157 158 159 160 161
static int32_t handlePassword(SSqlCmd* pCmd, SSQLToken* pPwd) {
  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) {
162
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
163 164 165
  }

  strdequote(pPwd->z);
H
Haojun Liao 已提交
166
  pPwd->n = strtrim(pPwd->z);  // trim space before and after passwords
167 168

  if (pPwd->n <= 0) {
169
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
170 171
  }

B
Bomin Zhang 已提交
172
  if (pPwd->n >= TSDB_PASSWORD_LEN) {
173
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
174 175 176 177 178
  }

  return TSDB_CODE_SUCCESS;
}

H
hzcheng 已提交
179 180 181
// todo handle memory leak in error handle function
int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
  if (pInfo == NULL || pSql == NULL || pSql->signature != pSql) {
182
    return TSDB_CODE_TSC_APP_ERROR;
H
hzcheng 已提交
183 184
  }

185
  SSqlCmd*    pCmd = &(pSql->cmd);
186
  SQueryInfo* pQueryInfo = NULL;
H
hzcheng 已提交
187

188
  if (!pInfo->valid) {
189
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), pInfo->pzErrMsg);
H
hzcheng 已提交
190 191
  }

192
  int32_t code = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex, &pQueryInfo);
H
hjxilinx 已提交
193

H
hjxilinx 已提交
194 195 196 197
  STableMetaInfo* pTableMetaInfo = NULL;
  if (pQueryInfo->numOfTables == 0) {
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
  } else {
198
    pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
H
hjxilinx 已提交
199
  }
200

201 202 203 204 205 206 207 208
  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: {
209
      const char* msg2 = "invalid name";
210
      const char* msg3 = "param name too long";
H
hzcheng 已提交
211 212

      SSQLToken* pzName = &pInfo->pDCLInfo->a[0];
213
      if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (tscValidateName(pzName) != TSDB_CODE_SUCCESS)) {
214
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
215 216
      }

217 218
      if (pInfo->type == TSDB_SQL_DROP_DB) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
219

H
hjxilinx 已提交
220
        code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pzName, NULL, NULL);
H
hzcheng 已提交
221
        if (code != TSDB_CODE_SUCCESS) {
222
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
223 224
        }

225 226
      } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
        assert(pInfo->pDCLInfo->nTokens == 1);
H
hzcheng 已提交
227

H
Haojun Liao 已提交
228
        if (tscSetTableFullName(pTableMetaInfo, pzName, pSql) != TSDB_CODE_SUCCESS) {
229
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
230
        }
231
      } else if (pInfo->type == TSDB_SQL_DROP_DNODE) {
S
slguan 已提交
232
        pzName->n = strdequote(pzName->z);
H
hjxilinx 已提交
233
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
234
      } else {  // drop user
B
Bomin Zhang 已提交
235
        if (pzName->n >= TSDB_USER_LEN) {
236
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
237 238
        }

H
hjxilinx 已提交
239
        strncpy(pTableMetaInfo->name, pzName->z, pzName->n);
H
hzcheng 已提交
240 241
      }

242 243
      break;
    }
H
hzcheng 已提交
244

245 246 247
    case TSDB_SQL_USE_DB: {
      const char* msg = "invalid db name";
      SSQLToken*  pToken = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
248 249

      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
250
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
251 252
      }

H
hjxilinx 已提交
253
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pToken, NULL, NULL);
H
hzcheng 已提交
254
      if (ret != TSDB_CODE_SUCCESS) {
255
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
256 257 258 259 260
      }

      break;
    }

261 262
    case TSDB_SQL_RESET_CACHE: {
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
263 264
    }

265 266
    case TSDB_SQL_SHOW: {
      if (setShowInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
267
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
268 269
      }

270 271 272 273 274 275 276 277
      break;
    }

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

278
      SCreateDBInfo* pCreateDB = &(pInfo->pDCLInfo->dbOpt);
H
hzcheng 已提交
279
      if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) {
280
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
281 282
      }

H
hjxilinx 已提交
283
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname), NULL, NULL);
H
hzcheng 已提交
284
      if (ret != TSDB_CODE_SUCCESS) {
285
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
286 287
      }

H
hjxilinx 已提交
288
      if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
289
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
290 291 292 293 294
      }

      break;
    }

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

298
      if (pInfo->pDCLInfo->nTokens > 1) {
299
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
300 301
      }

302
      SSQLToken* pIpAddr = &pInfo->pDCLInfo->a[0];
S
slguan 已提交
303
      pIpAddr->n = strdequote(pIpAddr->z);
S
slguan 已提交
304 305 306
      break;
    }

307 308 309 310 311
    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 已提交
312

313 314
      SSQLToken* pName = &pInfo->pDCLInfo->user.user;
      SSQLToken* pPwd = &pInfo->pDCLInfo->user.passwd;
H
hzcheng 已提交
315

316
      if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
317
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
318 319
      }

B
Bomin Zhang 已提交
320
      if (pName->n >= TSDB_USER_LEN) {
321
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
322 323
      }

324
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
325
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
326 327 328
      }

      SCreateAcctSQL* pAcctOpt = &pInfo->pDCLInfo->acctOpt;
329
      if (pAcctOpt->stat.n > 0) {
H
hzcheng 已提交
330 331 332 333 334
        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 {
335
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
336 337
        }
      }
338

H
hzcheng 已提交
339 340 341
      break;
    }

342
    case TSDB_SQL_DESCRIBE_TABLE: {
S
slguan 已提交
343
      SSQLToken*  pToken = &pInfo->pDCLInfo->a[0];
344
      const char* msg2 = "table name is too long";
H
hjxilinx 已提交
345
      const char* msg1 = "invalid table name";
H
hzcheng 已提交
346

S
slguan 已提交
347
      if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
348
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
349
      }
S
slguan 已提交
350

H
Haojun Liao 已提交
351
      if (!tscValidateTableNameLength(pToken->n)) {
352
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
353 354
      }

H
Haojun Liao 已提交
355
      if (tscSetTableFullName(pTableMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
356
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
357 358
      }

H
hjxilinx 已提交
359
      return tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
360 361
    }

362
    case TSDB_SQL_CFG_DNODE: {
363
      const char* msg2 = "invalid configure options or values";
H
hzcheng 已提交
364

365 366
      /* validate the ip address */
      tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
367

368 369
      /* validate the parameter names and options */
      if (validateDNodeConfig(pDCL) != TSDB_CODE_SUCCESS) {
370
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
371 372
      }

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

S
slguan 已提交
375
      SCMCfgDnodeMsg* pCfg = (SCMCfgDnodeMsg*)pMsg;
guanshengliang's avatar
guanshengliang 已提交
376 377
      pDCL->a[0].n = strdequote(pDCL->a[0].z);
      
J
jtao1735 已提交
378
      strncpy(pCfg->ep, pDCL->a[0].z, pDCL->a[0].n);
H
hzcheng 已提交
379

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

382 383 384 385
      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 已提交
386

387 388
      break;
    }
H
hzcheng 已提交
389

390 391 392 393 394 395
    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 已提交
396

397
      pCmd->command = pInfo->type;
H
hjxilinx 已提交
398
      // tDCLSQL* pDCL = pInfo->pDCLInfo;
H
hzcheng 已提交
399

400 401 402
      SUserInfo* pUser = &pInfo->pDCLInfo->user;
      SSQLToken* pName = &pUser->user;
      SSQLToken* pPwd = &pUser->passwd;
H
hzcheng 已提交
403

B
Bomin Zhang 已提交
404
      if (pName->n >= TSDB_USER_LEN) {
405
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
406
      }
H
hzcheng 已提交
407

408
      if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
409
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
410
      }
H
hzcheng 已提交
411

412 413
      if (pCmd->command == TSDB_SQL_CREATE_USER) {
        if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
414
          return TSDB_CODE_TSC_INVALID_SQL;
415 416 417 418
        }
      } else {
        if (pUser->type == TSDB_ALTER_USER_PASSWD) {
          if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
419
            return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
420
          }
421
        } else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
L
lihui 已提交
422 423 424
          assert(pPwd->type == TSDB_DATA_TYPE_NULL);

          SSQLToken* pPrivilege = &pUser->privilege;
H
hzcheng 已提交
425

L
lihui 已提交
426
          if (strncasecmp(pPrivilege->z, "super", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
427
            pCmd->count = 1;
L
lihui 已提交
428
          } else if (strncasecmp(pPrivilege->z, "read", 4) == 0 && pPrivilege->n == 4) {
H
hzcheng 已提交
429
            pCmd->count = 2;
L
lihui 已提交
430
          } else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) {
H
hzcheng 已提交
431 432
            pCmd->count = 3;
          } else {
433
            return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
434 435
          }
        } else {
436
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
437 438
        }
      }
439

H
hzcheng 已提交
440 441
      break;
    }
442 443

    case TSDB_SQL_CFG_LOCAL: {
S
slguan 已提交
444 445 446 447 448
      tDCLSQL*    pDCL = pInfo->pDCLInfo;
      const char* msg = "invalid configure options or values";

      // validate the parameter names and options
      if (validateLocalConfig(pDCL) != TSDB_CODE_SUCCESS) {
449
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
S
slguan 已提交
450 451 452 453 454 455 456
      }

      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 已提交
457 458 459 460

      break;
    }

461 462
    case TSDB_SQL_CREATE_TABLE: {
      SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hzcheng 已提交
463

464
      if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
465
        if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
466
          return code;
H
hzcheng 已提交
467 468
        }

469
      } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) {
470
        assert(pCmd->numOfCols == 0);
471 472
        if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
473 474
        }

475 476 477
      } else if (pCreateTable->type == TSQL_CREATE_STREAM) {
        if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
          return code;
S
slguan 已提交
478
        }
H
hzcheng 已提交
479 480 481 482 483
      }

      break;
    }

484
    case TSDB_SQL_SELECT: {
485
      assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
486
      const char* msg1 = "columns in select clause not identical";
H
hjxilinx 已提交
487

488
      for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) {
489 490 491 492
        SQueryInfo* pqi = NULL;
        if ((code = tscGetQueryInfoDetailSafely(pCmd, i, &pqi)) != TSDB_CODE_SUCCESS) {
          return code;
        }
493 494 495 496
      }

      assert(pCmd->numOfClause == pInfo->subclauseInfo.numOfClause);
      for (int32_t i = 0; i < pInfo->subclauseInfo.numOfClause; ++i) {
497
        SQuerySQL* pQuerySql = pInfo->subclauseInfo.pClause[i];
498

499 500
        if ((code = doCheckForQuery(pSql, pQuerySql, i)) != TSDB_CODE_SUCCESS) {
          return code;
H
hzcheng 已提交
501
        }
H
hjxilinx 已提交
502

H
hjxilinx 已提交
503
        tscPrintSelectClause(pSql, i);
H
hzcheng 已提交
504
      }
H
hjxilinx 已提交
505

H
hjxilinx 已提交
506
      // set the command/global limit parameters from the first subclause to the sqlcmd object
507 508
      SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
      pCmd->command = pQueryInfo1->command;
H
hjxilinx 已提交
509

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

514 515 516
        int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
        if (ret != 0) {
          return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
517
        }
518
      }
519

520
      pCmd->parseFinished = 1;
521
      return TSDB_CODE_SUCCESS;  // do not build query message here
522
    }
H
hzcheng 已提交
523

524 525 526
    case TSDB_SQL_ALTER_TABLE: {
      if ((code = setAlterTableInfo(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
        return code;
H
hzcheng 已提交
527 528 529 530 531
      }

      break;
    }

532 533 534
    case TSDB_SQL_KILL_QUERY:
    case TSDB_SQL_KILL_STREAM:
    case TSDB_SQL_KILL_CONNECTION: {
535
      if ((code = setKillInfo(pSql, pInfo, pInfo->type)) != TSDB_CODE_SUCCESS) {
H
hzcheng 已提交
536 537 538 539 540 541 542
        return code;
      }

      break;
    }

    default:
543
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression");
H
hzcheng 已提交
544 545
  }

dengyihao's avatar
dengyihao 已提交
546
  pSql->cmd.parseFinished = 1;
547
  return tscBuildMsg[pCmd->command](pSql, pInfo);
H
hzcheng 已提交
548 549
}

S
slguan 已提交
550 551 552 553
/*
 * if the top/bottom exists, only tags columns, tbname column, and primary timestamp column
 * are available.
 */
554
static bool isTopBottomQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
555 556 557
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = 0; i < size; ++i) {
558
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
559 560 561 562

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

S
slguan 已提交
565
  return false;
H
hzcheng 已提交
566 567
}

568
int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
S
slguan 已提交
569 570
  const char* msg1 = "invalid query expression";
  const char* msg2 = "interval cannot be less than 10 ms";
571

H
hjxilinx 已提交
572
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
573
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
574
  
H
hjxilinx 已提交
575
  if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
H
hzcheng 已提交
576 577 578 579 580
    return TSDB_CODE_SUCCESS;
  }

  // interval is not null
  SSQLToken* t = &pQuerySql->interval;
581
  if (getTimestampInUsFromStr(t->z, t->n, &pQueryInfo->intervalTime) != TSDB_CODE_SUCCESS) {
582
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
583 584
  }

H
hjxilinx 已提交
585
  // if the unit of time window value is millisecond, change the value from microsecond
H
hjxilinx 已提交
586
  if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
587
    pQueryInfo->intervalTime = pQueryInfo->intervalTime / 1000;
H
hzcheng 已提交
588 589 590
  }

  /* parser has filter the illegal type, no need to check here */
H
hjxilinx 已提交
591
  pQueryInfo->slidingTimeUnit = pQuerySql->interval.z[pQuerySql->interval.n - 1];
H
hzcheng 已提交
592 593

  // interval cannot be less than 10 milliseconds
594
  if (pQueryInfo->intervalTime < tsMinIntervalTime) {
595
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
596 597 598
  }

  // for top/bottom + interval query, we do not add additional timestamp column in the front
599
  if (isTopBottomQuery(pQueryInfo)) {
H
hjxilinx 已提交
600
    if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
601
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
602
    }
H
hjxilinx 已提交
603

H
hzcheng 已提交
604 605 606
    return TSDB_CODE_SUCCESS;
  }

H
hjxilinx 已提交
607 608 609
  /*
   * check invalid SQL:
   * select count(tbname)/count(tag1)/count(tag2) from super_table_name interval(1d);
H
hjxilinx 已提交
610
   */
H
hjxilinx 已提交
611 612
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
613
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
614
    if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
615
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
616 617
    }
  }
H
hjxilinx 已提交
618

H
hjxilinx 已提交
619 620 621
  /*
   * check invalid SQL:
   * select tbname, tags_fields from super_table_name interval(1s)
H
hjxilinx 已提交
622
   */
H
hjxilinx 已提交
623
  if (tscQueryTags(pQueryInfo) && pQueryInfo->intervalTime > 0) {
H
hjxilinx 已提交
624 625
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
  }
S
slguan 已提交
626 627

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

  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
631
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
632
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
hjxilinx 已提交
633
    if (pTableMetaInfo->pTableMeta->uid == uid) {
S
slguan 已提交
634 635 636 637 638 639
      tableIndex = i;
      break;
    }
  }

  if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
640
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
641 642 643
  }

  SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
644 645
  SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
      TSDB_KEYSIZE, false);
H
hzcheng 已提交
646

S
slguan 已提交
647
  SColumnList ids = getColumnList(1, 0, PRIMARYKEY_TIMESTAMP_COL_INDEX);
648

H
hjxilinx 已提交
649 650
  int32_t ret =
      insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hjxilinx 已提交
651 652 653
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }
H
hjxilinx 已提交
654

H
hjxilinx 已提交
655
  if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
656
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
657
  }
H
hjxilinx 已提交
658

H
hjxilinx 已提交
659
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
660 661
}

H
hjxilinx 已提交
662
int32_t parseSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
663 664
  const char* msg0 = "sliding value too small";
  const char* msg1 = "sliding value no larger than the interval value";
H
hzcheng 已提交
665

H
hjxilinx 已提交
666
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
667
  SSQLToken*      pSliding = &pQuerySql->sliding;
H
hjxilinx 已提交
668
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
669 670

  if (pSliding->n != 0) {
H
hjxilinx 已提交
671
    getTimestampInUsFromStr(pSliding->z, pSliding->n, &pQueryInfo->slidingTime);
H
hjxilinx 已提交
672
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
673
      pQueryInfo->slidingTime /= 1000;
H
hzcheng 已提交
674 675
    }

H
hjxilinx 已提交
676
    if (pQueryInfo->slidingTime < tsMinSlidingTime) {
677
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
678 679
    }

H
hjxilinx 已提交
680
    if (pQueryInfo->slidingTime > pQueryInfo->intervalTime) {
681
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
682
    }
H
hjxilinx 已提交
683
  } else {
H
hjxilinx 已提交
684
    pQueryInfo->slidingTime = pQueryInfo->intervalTime;
H
hzcheng 已提交
685 686 687 688 689
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
690
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SSQLToken* pzTableName, SSqlObj* pSql) {
691
  const char* msg = "name too long";
H
hzcheng 已提交
692

693 694
  SSqlCmd* pCmd = &pSql->cmd;
  int32_t  code = TSDB_CODE_SUCCESS;
S
slguan 已提交
695

H
hjxilinx 已提交
696 697
  // backup the old name in pTableMetaInfo
  size_t size = strlen(pTableMetaInfo->name);
H
hjxilinx 已提交
698
  char*  oldName = NULL;
699
  if (size > 0) {
H
hjxilinx 已提交
700
    oldName = strdup(pTableMetaInfo->name);
701
  }
H
hjxilinx 已提交
702

H
hzcheng 已提交
703
  if (hasSpecifyDB(pzTableName)) {
704
    // db has been specified in sql string so we ignore current db path
H
hjxilinx 已提交
705
    code = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), NULL, pzTableName, NULL);
S
slguan 已提交
706
  } else {  // get current DB name first, then set it into path
H
hzcheng 已提交
707 708 709
    SSQLToken t = {0};
    getCurrentDBName(pSql, &t);

H
hjxilinx 已提交
710
    code = setObjFullName(pTableMetaInfo->name, NULL, &t, pzTableName, NULL);
H
hzcheng 已提交
711 712
  }

S
slguan 已提交
713
  if (code != TSDB_CODE_SUCCESS) {
714
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
715 716
  }

717 718 719 720
  if (code != TSDB_CODE_SUCCESS) {
    free(oldName);
    return code;
  }
H
hjxilinx 已提交
721

722 723 724 725 726
  /*
   * the old name exists and is not equalled to the new name. Release the metermeta/metricmeta
   * that are corresponding to the old name for the new table name.
   */
  if (size > 0) {
H
hjxilinx 已提交
727
    if (strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
728
      tscClearTableMetaInfo(pTableMetaInfo, false);
729 730
    }
  } else {
H
hjxilinx 已提交
731
    assert(pTableMetaInfo->pTableMeta == NULL);
732
  }
H
hjxilinx 已提交
733

734 735
  tfree(oldName);
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
736 737 738 739 740
}

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

741 742 743 744 745 746 747
  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 已提交
748 749 750

  // number of fields no less than 2
  if (pFieldList->nField <= 1 || pFieldList->nField > TSDB_MAX_COLUMNS) {
751
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
752 753 754 755 756
    return false;
  }

  // first column must be timestamp
  if (pFieldList->p[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
757
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
758 759 760 761 762 763 764 765 766 767
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
    nLen += pFieldList->p[i].bytes;
  }

  // max row length must be less than TSDB_MAX_BYTES_PER_ROW
  if (nLen > TSDB_MAX_BYTES_PER_ROW) {
768
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
769 770 771 772 773 774 775
    return false;
  }

  // field name must be unique
  for (int32_t i = 0; i < pFieldList->nField; ++i) {
    TAOS_FIELD* pField = &pFieldList->p[i];
    if (pField->type < TSDB_DATA_TYPE_BOOL || pField->type > TSDB_DATA_TYPE_NCHAR) {
776
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
777 778 779 780 781
      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))) {
782
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
783 784 785 786
      return false;
    }

    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
787
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
788 789 790 791
      return false;
    }

    if (has(pFieldList, i + 1, pFieldList->p[i].name) == true) {
792
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
793 794 795 796 797 798 799 800 801 802
      return false;
    }
  }

  return true;
}

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

803 804 805 806 807 808 809
  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 已提交
810 811 812

  // number of fields at least 1
  if (pTagsList->nField < 1 || pTagsList->nField > TSDB_MAX_TAGS) {
813
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
814 815 816 817 818 819 820 821 822 823
    return false;
  }

  int32_t nLen = 0;
  for (int32_t i = 0; i < pTagsList->nField; ++i) {
    nLen += pTagsList->p[i].bytes;
  }

  // max tag row length must be less than TSDB_MAX_TAGS_LEN
  if (nLen > TSDB_MAX_TAGS_LEN) {
824
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
825 826 827 828 829 830
    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) {
831
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
832 833 834 835 836 837 838
      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) {
839
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
840 841 842 843
      return false;
    }

    if (pTagsList->p[i].type < TSDB_DATA_TYPE_BOOL || pTagsList->p[i].type > TSDB_DATA_TYPE_NCHAR) {
844
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
845 846 847 848 849
      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)) {
850
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
H
hzcheng 已提交
851 852 853 854
      return false;
    }

    if (validateColumnName(pTagsList->p[i].name) != TSDB_CODE_SUCCESS) {
855
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
856 857 858 859
      return false;
    }

    if (has(pTagsList, i + 1, pTagsList->p[i].name) == true) {
860
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
861 862 863 864 865 866 867 868 869 870 871
      return false;
    }
  }

  return true;
}

/*
 * tags name /column name is truncated in sql.y
 */
bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
872 873 874 875 876 877
  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 已提交
878

879
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
880

881
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
882
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
883

H
hjxilinx 已提交
884 885 886
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
887
  // no more than 6 tags
H
hjxilinx 已提交
888
  if (numOfTags == TSDB_MAX_TAGS) {
H
hzcheng 已提交
889 890 891
    char msg[128] = {0};
    sprintf(msg, "tags no more than %d", TSDB_MAX_TAGS);

892
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hzcheng 已提交
893 894 895 896 897
    return false;
  }

  // no timestamp allowable
  if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) {
898
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
899 900 901
    return false;
  }

L
[#1236]  
lihui 已提交
902
  if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_NCHAR)) {
903
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
904 905 906
    return false;
  }

H
hjxilinx 已提交
907
  SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
908 909
  int32_t  nLen = 0;

H
hjxilinx 已提交
910
  for (int32_t i = 0; i < numOfTags; ++i) {
H
hzcheng 已提交
911 912 913 914 915
    nLen += pTagSchema[i].bytes;
  }

  // length less than TSDB_MAX_TASG_LEN
  if (nLen + pTagField->bytes > TSDB_MAX_TAGS_LEN) {
916
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
917 918 919 920 921
    return false;
  }

  // tags name can not be a keyword
  if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) {
922
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
923 924 925 926 927
    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) {
928
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
929 930 931 932
    return false;
  }

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

H
hjxilinx 已提交
935
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
936
    if (strncasecmp(pTagField->name, pSchema[i].name, sizeof(pTagField->name) - 1) == 0) {
937
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
938 939 940 941 942 943 944 945
      return false;
    }
  }

  return true;
}

bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
946 947 948 949 950 951
  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 已提交
952

953
  assert(pCmd->numOfClause == 1);
954
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
955 956 957 958 959
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  int32_t numOfTags = tscGetNumOfTags(pTableMeta);
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
H
hzcheng 已提交
960
  // no more max columns
H
hjxilinx 已提交
961
  if (numOfCols >= TSDB_MAX_COLUMNS || numOfTags + numOfCols >= TSDB_MAX_COLUMNS) {
962
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
963 964 965 966
    return false;
  }

  if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_NCHAR) {
967
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
H
hzcheng 已提交
968 969 970 971
    return false;
  }

  if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) {
972
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
973 974 975
    return false;
  }

H
hjxilinx 已提交
976
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
H
hzcheng 已提交
977 978
  int32_t  nLen = 0;

H
hjxilinx 已提交
979
  for (int32_t i = 0; i < numOfCols; ++i) {
H
hzcheng 已提交
980 981 982 983
    nLen += pSchema[i].bytes;
  }

  if (pColField->bytes <= 0) {
984
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
H
hzcheng 已提交
985 986 987 988 989
    return false;
  }

  // length less than TSDB_MAX_BYTES_PER_ROW
  if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) {
990
    invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
H
hzcheng 已提交
991 992 993 994
    return false;
  }

  // field name must be unique
H
hjxilinx 已提交
995
  for (int32_t i = 0; i < numOfTags + numOfCols; ++i) {
B
Bomin Zhang 已提交
996
    if (strncasecmp(pColField->name, pSchema[i].name, sizeof(pColField->name) - 1) == 0) {
997
      invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
998 999 1000 1001 1002 1003 1004 1005
      return false;
    }
  }

  return true;
}

/* is contained in pFieldList or not */
H
hjxilinx 已提交
1006
static bool has(tFieldList* pFieldList, int32_t startIdx, const char* name) {
H
hzcheng 已提交
1007
  for (int32_t j = startIdx; j < pFieldList->nField; ++j) {
B
Bomin Zhang 已提交
1008 1009
    TAOS_FIELD* field = pFieldList->p + j;
    if (strncasecmp(name, field->name, sizeof(field->name) - 1) == 0) return true;
H
hzcheng 已提交
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
  }

  return false;
}

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

static void getCurrentDBName(SSqlObj* pSql, SSQLToken* pDBToken) {
  pDBToken->z = pSql->pTscObj->db;
  pDBToken->n = strlen(pSql->pTscObj->db);
}

/* length limitation, strstr cannot be applied */
static bool hasSpecifyDB(SSQLToken* pTableName) {
  for (int32_t i = 0; i < pTableName->n; ++i) {
    if (pTableName->z[i] == TS_PATH_DELIMITER[0]) {
      return true;
    }
  }

  return false;
}

1033
int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQLToken* tableName, int32_t* xlen) {
H
hzcheng 已提交
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
  int32_t totalLen = 0;

  if (account != NULL) {
    int32_t len = strlen(account);
    strcpy(fullName, account);
    fullName[len] = TS_PATH_DELIMITER[0];
    totalLen += (len + 1);
  }

  /* db name is not specified, the tableName dose not include db name */
  if (pDB != NULL) {
B
Bomin Zhang 已提交
1045
    if (pDB->n >= TSDB_DB_NAME_LEN) {
1046
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
    }

    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 已提交
1059
      if (!tscValidateTableNameLength(tableName->n)) {
1060
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1061 1062 1063
      }
    } else {  // pDB == NULL, the db prefix name is specified in tableName
      /* the length limitation includes tablename + dbname + sep */
B
Bomin Zhang 已提交
1064
      if (tableName->n >= TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN) {
1065
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
      }
    }

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

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

S
slguan 已提交
1077
  if (totalLen < TSDB_TABLE_ID_LEN) {
S
slguan 已提交
1078 1079 1080
    fullName[totalLen] = 0;
  }

B
Bomin Zhang 已提交
1081
  return (totalLen < TSDB_TABLE_ID_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1082 1083
}

S
slguan 已提交
1084
static void extractColumnNameFromString(tSQLExprItem* pItem) {
H
hzcheng 已提交
1085
  if (pItem->pNode->nSQLOptr == TK_STRING) {
S
slguan 已提交
1086
    pItem->pNode->val.nLen = strdequote(pItem->pNode->val.pz);
H
hzcheng 已提交
1087 1088 1089 1090
    pItem->pNode->nSQLOptr = TK_ID;

    SSQLToken* pIdToken = &pItem->pNode->colInfo;
    pIdToken->type = TK_ID;
S
slguan 已提交
1091 1092
    pIdToken->z = pItem->pNode->val.pz;
    pIdToken->n = pItem->pNode->val.nLen;
H
hzcheng 已提交
1093 1094 1095
  }
}

1096
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) {
H
hzcheng 已提交
1097 1098
  assert(pSelection != NULL && pCmd != NULL);

1099
  const char* msg1 = "invalid column name, or illegal column type";
1100 1101
  const char* msg2 = "functions can not be mixed up";
  const char* msg3 = "not support query expression";
1102
  const char* msg4 = "columns from different table mixed up in arithmetic expression";
H
hjxilinx 已提交
1103
  const char* msg5 = "invalid function name";
H
hjxilinx 已提交
1104

1105
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
1106 1107 1108 1109 1110
  
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
H
hzcheng 已提交
1111
  for (int32_t i = 0; i < pSelection->nExpr; ++i) {
H
hjxilinx 已提交
1112
    int32_t outputIndex = tscSqlExprNumOfExprs(pQueryInfo);
H
hzcheng 已提交
1113 1114
    tSQLExprItem* pItem = &pSelection->a[i];

S
slguan 已提交
1115 1116 1117
    // project on all fields
    if (pItem->pNode->nSQLOptr == TK_ALL || pItem->pNode->nSQLOptr == TK_ID || pItem->pNode->nSQLOptr == TK_STRING) {
      // it is actually a function, but the function name is invalid
H
hzcheng 已提交
1118
      if (pItem->pNode->nSQLOptr == TK_ID && (pItem->pNode->colInfo.z == NULL && pItem->pNode->colInfo.n == 0)) {
H
hjxilinx 已提交
1119
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
1120 1121
      }

S
slguan 已提交
1122 1123
      // if the name of column is quoted, remove it and set the right information for later process
      extractColumnNameFromString(pItem);
H
hjxilinx 已提交
1124
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY);
S
slguan 已提交
1125 1126

      // select table_name1.field_name1, table_name2.field_name2  from table_name1, table_name2
1127
      if (addProjectionExprAndResultField(pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
1128
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1129
      }
1130
    } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_TBID) {
S
slguan 已提交
1131
      // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
H
hjxilinx 已提交
1132
      if (addExprAndResultField(pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
1133
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1134 1135 1136
      }

    } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
H
hjxilinx 已提交
1137
      // arithmetic function in select clause
1138
      SColumnList columnList = {0};
H
hjxilinx 已提交
1139 1140 1141
      int32_t     arithmeticType = NON_ARITHMEIC_EXPR;

      if (validateArithmeticSQLExpr(pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
1142
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1143
      }
1144 1145
      
      int32_t tableIndex = columnList.ids[0].tableIndex;
H
hzcheng 已提交
1146 1147
      char  arithmeticExprStr[1024] = {0};
      char* p = arithmeticExprStr;
H
hjxilinx 已提交
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
      
      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(pQueryInfo->msg, msg4);
          }
        }
  
        if (buildArithmeticExprString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
1160
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
1161 1162 1163 1164
        }
  
        // expr string is set as the parameter of function
        SColumnIndex index = {.tableIndex = tableIndex};
H
hjxilinx 已提交
1165
        SSqlExpr*    pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE,
1166
                                              sizeof(double), sizeof(double), false);
1167
        
H
hjxilinx 已提交
1168 1169
        /* todo alias name should use the original sql string */
        char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
B
Bomin Zhang 已提交
1170
        tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
1171 1172 1173 1174
        
        tExprNode* pNode = NULL;
        SArray* colList = taosArrayInit(10, sizeof(SColIndex));
        
H
hjxilinx 已提交
1175
        int32_t ret = exprTreeFromSqlExpr(&pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
1176 1177 1178 1179 1180
        if (ret != TSDB_CODE_SUCCESS) {
          tExprTreeDestroy(&pNode, NULL);
          return invalidSqlErrMsg(pQueryInfo->msg, "invalid arithmetic expression in select clause");
        }
        
1181 1182 1183 1184 1185 1186 1187 1188 1189
        SBufferWriter bw = tbufInitWriter(NULL, false);

        TRY(0) {
          exprTreeToBinary(&bw, pNode);
        } CATCH(code) {
          tbufCloseWriter(&bw);
          UNUSED(code);
          // TODO: other error handling
        } END_TRY
1190
        
1191 1192
        size_t len = tbufTell(&bw);
        char* c = tbufGetData(&bw, true);
1193 1194 1195 1196
        
        // set the serialized binary string as the parameter of arithmetic expression
        addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, len, index.tableIndex);
        
H
hjxilinx 已提交
1197
        insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
1198 1199 1200
        
        taosArrayDestroy(colList);
        tExprTreeDestroy(&pNode, NULL);
H
hzcheng 已提交
1201
      } else {
H
hjxilinx 已提交
1202 1203 1204
        columnList.num = 0;
        columnList.ids[0] = (SColumnIndex) {0, 0};
        
1205
        insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, "dummy_column", NULL);
H
hjxilinx 已提交
1206 1207
        
        int32_t slot = tscNumOfFields(pQueryInfo) - 1;
H
hjxilinx 已提交
1208
        SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);
H
hjxilinx 已提交
1209
        
H
hjxilinx 已提交
1210
        if (pInfo->pSqlExpr == NULL) {
1211
          SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));
H
hjxilinx 已提交
1212 1213
          
          // arithmetic expression always return result in the format of double float
1214 1215 1216
          pArithExprInfo->bytes = sizeof(double);
          pArithExprInfo->interBytes = sizeof(double);
          pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;
H
hjxilinx 已提交
1217

1218
          int32_t ret = exprTreeFromSqlExpr(&pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
H
hjxilinx 已提交
1219
          if (ret != TSDB_CODE_SUCCESS) {
1220
            tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
H
hjxilinx 已提交
1221 1222
            return invalidSqlErrMsg(pQueryInfo->msg, "invalid expression in select clause");
          }
1223
  
1224
          pInfo->pArithExprInfo = pArithExprInfo;
H
hjxilinx 已提交
1225
        }
H
hzcheng 已提交
1226 1227 1228 1229 1230 1231
      }
    } else {
      /*
       * not support such expression
       * e.g., select 12+5 from table_name
       */
1232
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1233 1234
    }

H
hjxilinx 已提交
1235
    if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
1236
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1237 1238 1239
    }
  }

1240 1241
  if (!functionCompatibleCheck(pQueryInfo)) {
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1242 1243
  }

1244
  if (isSTable) {
H
hzcheng 已提交
1245 1246 1247 1248
    /*
     * transfer sql functions that need secondary merge into another format
     * in dealing with metric queries such as: count/first/last
     */
H
hjxilinx 已提交
1249
    tscTansformSQLFuncForSTableQuery(pQueryInfo);
H
hzcheng 已提交
1250

1251
    if (hasUnsupportFunctionsForSTableQuery(pQueryInfo)) {
1252
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1253 1254 1255 1256 1257 1258
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1259 1260
int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
    int8_t type, char* fieldName, SSqlExpr* pSqlExpr) {
1261
  
S
slguan 已提交
1262
  for (int32_t i = 0; i < pIdList->num; ++i) {
1263 1264 1265 1266 1267 1268 1269 1270
    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;
    }
    
1271
    tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i]));
H
hzcheng 已提交
1272
  }
H
hjxilinx 已提交
1273 1274 1275 1276
  
  TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
  SFieldSupInfo* pInfo =tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
  pInfo->pSqlExpr = pSqlExpr;
H
hjxilinx 已提交
1277
  
H
hzcheng 已提交
1278 1279 1280
  return TSDB_CODE_SUCCESS;
}

1281
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex) {
H
hjxilinx 已提交
1282
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
1283 1284 1285
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
  
1286
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
H
hzcheng 已提交
1287

1288
  int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
1289 1290 1291 1292
  SColumnIndex index = {.tableIndex = tableIndex,};
  
  if (functionId == TSDB_FUNC_TAGPRJ) {
    index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta);
H
hjxilinx 已提交
1293 1294
  
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
1295 1296 1297 1298 1299 1300
  } else {
    index.columnIndex = colIndex;
  }
  
  return tscSqlExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes,
      pSchema->bytes, functionId == TSDB_FUNC_TAGPRJ);
H
hzcheng 已提交
1301 1302
}

1303 1304
static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSQLExprItem* pItem) {
  SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos, pIndex->columnIndex, pIndex->tableIndex);
H
hzcheng 已提交
1305

H
hjxilinx 已提交
1306
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
H
hjxilinx 已提交
1307 1308 1309
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
  
  SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
1310

S
slguan 已提交
1311
  char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName;
B
Bomin Zhang 已提交
1312
  tstrncpy(pExpr->aliasName, colName, sizeof(pExpr->aliasName));
H
hjxilinx 已提交
1313
  
S
slguan 已提交
1314 1315 1316
  SColumnList ids = {0};
  ids.num = 1;
  ids.ids[0] = *pIndex;
H
hzcheng 已提交
1317

H
hjxilinx 已提交
1318
  if (pIndex->columnIndex >= tscGetNumOfColumns(pTableMeta) || pIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1319 1320
    ids.num = 0;
  }
H
hzcheng 已提交
1321

H
hjxilinx 已提交
1322
  insertResultField(pQueryInfo, startPos, &ids, pExpr->resBytes, pExpr->resType, pExpr->aliasName, pExpr);
S
slguan 已提交
1323
}
H
hzcheng 已提交
1324

1325
void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
S
slguan 已提交
1326
                                  SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
H
hjxilinx 已提交
1327
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionId, pIndex, pColSchema->type,
1328
                                     pColSchema->bytes, pColSchema->bytes, flag);
H
hzcheng 已提交
1329

S
slguan 已提交
1330 1331 1332 1333
  SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
  if (TSDB_COL_IS_TAG(flag)) {
    ids.num = 0;
  }
H
hzcheng 已提交
1334

H
hjxilinx 已提交
1335
  insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr);
S
slguan 已提交
1336 1337

  pExpr->colInfo.flag = flag;
1338 1339
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
  
S
slguan 已提交
1340
  if (TSDB_COL_IS_TAG(flag)) {
H
hjxilinx 已提交
1341
    tscColumnListInsert(pTableMetaInfo->tagColList, pIndex);
S
slguan 已提交
1342 1343 1344
  }
}

1345
static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
H
hjxilinx 已提交
1346
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
1347 1348

  int32_t     numOfTotalColumns = 0;
H
hjxilinx 已提交
1349 1350
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1351

H
hjxilinx 已提交
1352
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
H
hjxilinx 已提交
1353
  
weixin_48148422's avatar
weixin_48148422 已提交
1354
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
1355
    numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags;
S
slguan 已提交
1356
  } else {
H
hjxilinx 已提交
1357
    numOfTotalColumns = tinfo.numOfColumns;
S
slguan 已提交
1358 1359 1360
  }

  for (int32_t j = 0; j < numOfTotalColumns; ++j) {
H
hjxilinx 已提交
1361
    SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos + j, j, pIndex->tableIndex);
B
Bomin Zhang 已提交
1362
    tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName));
S
slguan 已提交
1363 1364 1365 1366

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

H
hjxilinx 已提交
1369
    insertResultField(pQueryInfo, startPos + j, &ids, pSchema[j].bytes, pSchema[j].type, pSchema[j].name, pExpr);
S
slguan 已提交
1370 1371 1372 1373 1374
  }

  return numOfTotalColumns;
}

1375
int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pItem) {
S
slguan 已提交
1376
  const char* msg0 = "invalid column name";
H
hjxilinx 已提交
1377
  const char* msg1 = "tag for normal table query is not allowed";
H
hjxilinx 已提交
1378 1379
  
  int32_t startPos = tscSqlExprNumOfExprs(pQueryInfo);
S
slguan 已提交
1380 1381 1382

  if (pItem->pNode->nSQLOptr == TK_ALL) {  // project on all fields
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1383
    if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1384
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
1385 1386 1387 1388
    }

    // all meters columns are required
    if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) {  // all table columns are required.
1389
      for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
S
slguan 已提交
1390
        index.tableIndex = i;
1391
        int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1392
        startPos += inc;
H
hzcheng 已提交
1393 1394
      }
    } else {
1395
      doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos);
S
slguan 已提交
1396 1397 1398 1399
    }
  } else if (pItem->pNode->nSQLOptr == TK_ID) {  // simple column projection query
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;

1400
    if (getColumnIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1401
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
1402
    }
H
hzcheng 已提交
1403

S
slguan 已提交
1404
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
1405
      SSchema colSchema = tGetTableNameColumnSchema();
1406
      tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, true);
S
slguan 已提交
1407
    } else {
H
hjxilinx 已提交
1408
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1409
      STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
1410

weixin_48148422's avatar
weixin_48148422 已提交
1411
      if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
1412
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1413 1414
      }

1415
      addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
H
hzcheng 已提交
1416 1417
    }
  } else {
1418
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1419 1420 1421 1422 1423
  }

  return TSDB_CODE_SUCCESS;
}

S
slguan 已提交
1424
static int32_t setExprInfoForFunctions(SQueryInfo* pQueryInfo, SSchema* pSchema, int32_t functionID, char* aliasName,
S
slguan 已提交
1425
                                       int32_t resColIdx, SColumnIndex* pColIndex) {
H
hzcheng 已提交
1426 1427 1428
  int16_t type = 0;
  int16_t bytes = 0;

S
slguan 已提交
1429
  char        columnName[TSDB_COL_NAME_LEN] = {0};
1430
  const char* msg1 = "not support column types";
H
hzcheng 已提交
1431 1432

  if (functionID == TSDB_FUNC_SPREAD) {
S
slguan 已提交
1433 1434 1435
    if (pSchema[pColIndex->columnIndex].type == TSDB_DATA_TYPE_BINARY ||
        pSchema[pColIndex->columnIndex].type == TSDB_DATA_TYPE_NCHAR ||
        pSchema[pColIndex->columnIndex].type == TSDB_DATA_TYPE_BOOL) {
1436
      invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1437 1438 1439 1440 1441 1442
      return -1;
    } else {
      type = TSDB_DATA_TYPE_DOUBLE;
      bytes = tDataTypeDesc[type].nSize;
    }
  } else {
S
slguan 已提交
1443 1444
    type = pSchema[pColIndex->columnIndex].type;
    bytes = pSchema[pColIndex->columnIndex].bytes;
H
hzcheng 已提交
1445 1446 1447 1448 1449
  }

  if (aliasName != NULL) {
    strcpy(columnName, aliasName);
  } else {
B
Bomin Zhang 已提交
1450
    getRevisedName(columnName, functionID, sizeof(columnName) - 1, pSchema[pColIndex->columnIndex].name);
H
hzcheng 已提交
1451
  }
H
hjxilinx 已提交
1452
  
1453
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, bytes, false);
B
Bomin Zhang 已提交
1454
  tstrncpy(pExpr->aliasName, columnName, sizeof(pExpr->aliasName));
H
hjxilinx 已提交
1455
  
H
hjxilinx 已提交
1456
  // for all queries, the timestamp column needs to be loaded
S
slguan 已提交
1457
  SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1458
  tscColumnListInsert(pQueryInfo->colList, &index);
H
hzcheng 已提交
1459

S
slguan 已提交
1460
  SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
H
hjxilinx 已提交
1461
  insertResultField(pQueryInfo, resColIdx, &ids, bytes, type, columnName, pExpr);
H
hzcheng 已提交
1462 1463 1464 1465

  return TSDB_CODE_SUCCESS;
}

1466
int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult) {
H
hjxilinx 已提交
1467
  STableMetaInfo* pTableMetaInfo = NULL;
1468
  int32_t optr = pItem->pNode->nSQLOptr;
S
slguan 已提交
1469

1470
  const char* msg1 = "not support column types";
S
slguan 已提交
1471
  const char* msg2 = "invalid parameters";
1472
  const char* msg3 = "illegal column name";
S
slguan 已提交
1473
  const char* msg4 = "invalid table name";
1474
  const char* msg5 = "parameter is out of range [0, 100]";
S
slguan 已提交
1475
  const char* msg6 = "function applied to tags not allowed";
1476 1477
  const char* msg7 = "normal table can not apply this function";
  
H
hzcheng 已提交
1478 1479 1480 1481
  switch (optr) {
    case TK_COUNT: {
      if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
        /* more than one parameter for count() function */
1482
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1483 1484 1485 1486
      }

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1487
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1488 1489
      }

H
hjxilinx 已提交
1490
      SSqlExpr* pExpr = NULL;
S
slguan 已提交
1491
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
1492 1493 1494 1495

      if (pItem->pNode->pParam != NULL) {
        SSQLToken* pToken = &pItem->pNode->pParam->a[0].pNode->colInfo;
        if (pToken->z == NULL || pToken->n == 0) {
1496
          return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1497 1498
        }

S
slguan 已提交
1499 1500 1501 1502 1503 1504
        tSQLExprItem* pParamElem = &pItem->pNode->pParam->a[0];
        if (pParamElem->pNode->nSQLOptr == TK_ALL) {
          // select table.*
          // check if the table name is valid or not
          SSQLToken tmpToken = pParamElem->pNode->colInfo;

1505 1506
          if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
            return invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
1507 1508 1509 1510
          }

          index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
1511
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1512
        } else {
H
hjxilinx 已提交
1513
          // count the number of meters created according to the super table
1514
          if (getColumnIndexByName(pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1515
            return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
1516 1517
          }

H
hjxilinx 已提交
1518
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
S
slguan 已提交
1519 1520

          // count tag is equalled to count(tbname)
H
Haojun Liao 已提交
1521 1522
          bool isTag = false;
          if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
S
slguan 已提交
1523
            index.columnIndex = TSDB_TBNAME_COLUMN_INDEX;
H
Haojun Liao 已提交
1524
            isTag = true;
H
hzcheng 已提交
1525 1526
          }

S
slguan 已提交
1527
          int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
H
Haojun Liao 已提交
1528
          pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, isTag);
H
hzcheng 已提交
1529
        }
S
slguan 已提交
1530 1531 1532 1533
      } 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;
1534
        pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size, false);
H
hzcheng 已提交
1535
      }
H
hjxilinx 已提交
1536 1537
      
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1538
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1539
      
S
slguan 已提交
1540
      SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
H
hjxilinx 已提交
1541 1542 1543 1544 1545
      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) {
1546
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1547 1548
        }
      }
H
Haojun Liao 已提交
1549 1550 1551 1552 1553 1554 1555

      // the time stamp may be always needed
      if (index.tableIndex > 0 && index.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
        SColumnIndex tsCol = {.tableIndex = index.tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
        tscColumnListInsert(pQueryInfo->colList, &tsCol);
      }

S
slguan 已提交
1556
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1557 1558 1559
    }
    case TK_SUM:
    case TK_AVG:
L
lihui 已提交
1560 1561 1562 1563 1564 1565
    case TK_RATE:
    case TK_IRATE:
    case TK_SUM_RATE:
    case TK_SUM_IRATE:
    case TK_AVG_RATE:
    case TK_AVG_IRATE:
S
slguan 已提交
1566
    case TK_TWA:
H
hzcheng 已提交
1567 1568 1569 1570 1571 1572 1573 1574 1575
    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 */
1576
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1577 1578 1579 1580
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ALL && pParamElem->pNode->nSQLOptr != TK_ID) {
1581
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1582 1583
      }

S
slguan 已提交
1584
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1585
      if ((getColumnIndexByName(&pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) ||
1586
          index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
1587
        return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1588 1589 1590
      }

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

H
hjxilinx 已提交
1595
      if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1596
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1597 1598 1599 1600
      }

      int16_t resultType = 0;
      int16_t resultSize = 0;
1601
      int32_t intermediateResSize = 0;
H
hzcheng 已提交
1602 1603 1604

      int16_t functionID = 0;
      if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
1605
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1606 1607
      }

S
slguan 已提交
1608 1609
      if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
                            &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
1610
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1611
      }
H
hzcheng 已提交
1612

S
slguan 已提交
1613
      // set the first column ts for diff query
H
hzcheng 已提交
1614
      if (optr == TK_DIFF) {
1615
        colIndex += 1;
S
slguan 已提交
1616
        SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
H
hjxilinx 已提交
1617
        SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
1618
                         TSDB_KEYSIZE, false);
H
hzcheng 已提交
1619

S
slguan 已提交
1620
        SColumnList ids = getColumnList(1, 0, 0);
H
hjxilinx 已提交
1621
        insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].aName, pExpr);
H
hzcheng 已提交
1622 1623
      }

S
slguan 已提交
1624
      // functions can not be applied to tags
H
hjxilinx 已提交
1625
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1626
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
S
slguan 已提交
1627 1628
      }

1629
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, resultType, resultSize, resultSize, false);
H
hzcheng 已提交
1630 1631 1632 1633

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

S
slguan 已提交
1638
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES, 0);
H
hzcheng 已提交
1639 1640

        memset(val, 0, tListLen(val));
1641
        if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
1642
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1643 1644
        }

S
slguan 已提交
1645
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1646 1647
      }

S
slguan 已提交
1648 1649 1650
      SColumnList ids = {0};
      ids.num = 1;
      ids.ids[0] = index;
H
hjxilinx 已提交
1651 1652
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1653
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1654 1655 1656 1657 1658 1659
  
      if (finalResult) {
        int32_t numOfOutput = tscNumOfFields(pQueryInfo);
        insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, pExpr->resType, pExpr->aliasName, pExpr);
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1660
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1661 1662
        }
      }
1663 1664
  
      SColumnIndex tsCol = {.tableIndex = index.tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
1665
      tscColumnListInsert(pQueryInfo->colList, &tsCol);
1666
      
S
slguan 已提交
1667
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680
    }
    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;
      changeFunctionID(optr, &functionID);

      if (!requireAllFields) {
        if (pItem->pNode->pParam->nExpr < 1) {
1681
          return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1682 1683 1684 1685 1686 1687
        }

        /* 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) {
1688
            return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
1689 1690
          }

S
slguan 已提交
1691 1692 1693 1694 1695 1696
          SColumnIndex index = COLUMN_INDEX_INITIALIZER;

          if (pParamElem->pNode->nSQLOptr == TK_ALL) {
            // select table.*
            SSQLToken tmpToken = pParamElem->pNode->colInfo;

1697 1698
            if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
              return invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
1699 1700
            }

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

H
hjxilinx 已提交
1704
            for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
S
slguan 已提交
1705
              index.columnIndex = j;
1706
              if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex++, &index) != 0) {
1707
                return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1708 1709
              }
            }
H
hzcheng 已提交
1710

S
slguan 已提交
1711
          } else {
1712
            if (getColumnIndexByName(&pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1713
              return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
1714 1715
            }

H
hjxilinx 已提交
1716
            pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1717
            SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1718 1719

            // functions can not be applied to tags
H
hjxilinx 已提交
1720
            if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
1721
              return invalidSqlErrMsg(pQueryInfo->msg, msg6);
S
slguan 已提交
1722 1723
            }

1724
            if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i, &index) != 0) {
1725
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1726
            }
H
hzcheng 已提交
1727 1728
          }
        }
1729
        
S
slguan 已提交
1730 1731 1732 1733
        return TSDB_CODE_SUCCESS;
      } else {  // select * from xxx
        int32_t numOfFields = 0;

1734
        for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
H
hjxilinx 已提交
1735
          pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j);
H
hjxilinx 已提交
1736
          SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1737

H
hjxilinx 已提交
1738
          for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
S
slguan 已提交
1739
            SColumnIndex index = {.tableIndex = j, .columnIndex = i};
1740
            if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i + j, &index) !=
1741
                0) {
1742
              return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
1743
            }
H
hzcheng 已提交
1744
          }
S
slguan 已提交
1745

H
hjxilinx 已提交
1746
          numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1747 1748
        }

1749
        
S
slguan 已提交
1750
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1751 1752 1753 1754 1755 1756 1757 1758 1759
      }
    }
    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 */
1760
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1761 1762 1763 1764
      }

      tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
      if (pParamElem->pNode->nSQLOptr != TK_ID) {
1765
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1766
      }
H
hjxilinx 已提交
1767
      
S
slguan 已提交
1768
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
1769
      if (getColumnIndexByName(&pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
1770
        return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
1771 1772
      }

H
hjxilinx 已提交
1773
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
1774
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
1775 1776

      // functions can not be applied to tags
H
hjxilinx 已提交
1777
      if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
1778
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
H
hzcheng 已提交
1779 1780 1781
      }

      // 2. valid the column type
S
slguan 已提交
1782
      int16_t colType = pSchema[index.columnIndex].type;
H
hzcheng 已提交
1783
      if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
1784
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
1785 1786 1787 1788
      }

      // 3. valid the parameters
      if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
1789
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
1790 1791 1792 1793
      }

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

S
slguan 已提交
1794 1795
      int8_t  resultType = pSchema[index.columnIndex].type;
      int16_t resultSize = pSchema[index.columnIndex].bytes;
H
hzcheng 已提交
1796

H
hjxilinx 已提交
1797
      char    val[8] = {0};
H
hjxilinx 已提交
1798 1799
      SSqlExpr* pExpr = NULL;
      
H
hzcheng 已提交
1800
      if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
1801
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
H
hzcheng 已提交
1802

L
lihui 已提交
1803
        double dp = GET_DOUBLE_VAL(val);
S
slguan 已提交
1804
        if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
1805
          return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817
        }

        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) {
1818
          return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1819 1820
        }

1821
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1822
        addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
H
hzcheng 已提交
1823
      } else {
1824
        tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
1825 1826 1827

        int64_t nTop = *((int32_t*)val);
        if (nTop <= 0 || nTop > 100) {  // todo use macro
1828
          return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
1829 1830 1831 1832
        }

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

H
hzcheng 已提交
1836
        // set the first column ts for top/bottom query
S
slguan 已提交
1837
        SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
1838 1839
        pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
            TSDB_KEYSIZE, false);
S
slguan 已提交
1840 1841 1842

        const int32_t TS_COLUMN_INDEX = 0;
        SColumnList   ids = getColumnList(1, 0, TS_COLUMN_INDEX);
1843
        insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
H
hjxilinx 已提交
1844
                          aAggs[TSDB_FUNC_TS].aName, pExpr);
H
hzcheng 已提交
1845

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

1848
        pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
S
slguan 已提交
1849
        addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
H
hzcheng 已提交
1850
      }
H
hjxilinx 已提交
1851 1852
  
      memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
B
Bomin Zhang 已提交
1853
      getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
H
hjxilinx 已提交
1854
  
S
slguan 已提交
1855
      SColumnList ids = getColumnList(1, 0, index.columnIndex);
H
hjxilinx 已提交
1856
      if (finalResult) {
1857
        insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
H
hjxilinx 已提交
1858 1859
      } else {
        for (int32_t i = 0; i < ids.num; ++i) {
1860
          tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
H
hjxilinx 已提交
1861 1862
        }
      }
S
slguan 已提交
1863

1864 1865 1866 1867 1868
      return TSDB_CODE_SUCCESS;
    };
    
    case TK_TBID: {
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
1869
      if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889
        return invalidSqlErrMsg(pQueryInfo->msg, msg7);
      }
    
      // no parameters or more than one parameter for function
      if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 1) {
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
      }
      
      tSQLExpr* pParam = pItem->pNode->pParam->a[0].pNode;
    
      SColumnIndex index = COLUMN_INDEX_INITIALIZER;
      if (getColumnIndexByName(&pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
        return invalidSqlErrMsg(pQueryInfo->msg, msg3);
      }
    
      pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
      SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
  
      // functions can not be applied to normal columns
      int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
1890
      if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
1891 1892 1893
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
      }
    
1894 1895 1896
      if (index.columnIndex > 0) {
        index.columnIndex -= numOfCols;
      }
1897 1898
      
      // 2. valid the column type
1899 1900 1901 1902 1903 1904 1905 1906
      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) {
1907 1908 1909 1910 1911
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
      }

      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
1912 1913 1914
      
      SSchema s = {0};
      if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
1915
        s = tGetTableNameColumnSchema();
1916 1917 1918 1919
      } else {
        s = pTagSchema[index.columnIndex];
      }
      
1920 1921
      int16_t bytes = 0;
      int16_t type  = 0;
1922
      int32_t inter = 0;
1923 1924 1925 1926 1927 1928 1929 1930 1931 1932

      int32_t ret = getResultDataInfo(s.type, s.bytes, TSDB_FUNC_TID_TAG, 0, &type, &bytes, &inter, 0, 0);
      assert(ret == TSDB_CODE_SUCCESS);
      
      s.type  = type;
      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 已提交
1933
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
1934
    }
1935
    
H
hzcheng 已提交
1936
    default:
1937
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
1938
  }
1939
  
H
hzcheng 已提交
1940 1941
}

S
slguan 已提交
1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955
// todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
  assert(num == 1 && columnIndex >= -1 && tableIndex >= 0);

  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 已提交
1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968
void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength) {
  if (pItem->aliasName != NULL) {
    strncpy(resultFieldName, pItem->aliasName, nameLength);
  } else {
    int32_t len = (pItem->pNode->operand.n < nameLength) ? pItem->pNode->operand.n : nameLength;
    strncpy(resultFieldName, pItem->pNode->operand.z, len);
  }
}

void getRevisedName(char* resultFieldName, int32_t functionId, int32_t maxLen, char* columnName) {
  snprintf(resultFieldName, maxLen, "%s(%s)", aAggs[functionId].aName, columnName);
}

S
slguan 已提交
1969 1970 1971 1972 1973 1974 1975 1976 1977
static bool isTablenameToken(SSQLToken* token) {
  SSQLToken tmpToken = *token;
  SSQLToken tableToken = {0};

  extractTableNameFromToken(&tmpToken, &tableToken);

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

1978
static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SSQLToken* pToken) {
H
hjxilinx 已提交
1979
  STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index)->pTableMeta;
S
slguan 已提交
1980

H
hjxilinx 已提交
1981 1982
  int32_t  numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
S
slguan 已提交
1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998

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

  return columnIndex;
}

1999
int32_t doGetColumnIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
  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) {
2010 2011
      for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
        int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken);
S
slguan 已提交
2012 2013 2014

        if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
          if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
2015
            return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
2016 2017 2018 2019 2020 2021 2022
          } else {
            pIndex->tableIndex = i;
            pIndex->columnIndex = colIndex;
          }
        }
      }
    } else {  // table index is valid, get the column index
2023
      int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken);
S
slguan 已提交
2024 2025 2026 2027 2028 2029
      if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
        pIndex->columnIndex = colIndex;
      }
    }

    if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
2030
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
2031 2032 2033 2034 2035 2036
    }
  }

  if (COLUMN_INDEX_VALIDE(*pIndex)) {
    return TSDB_CODE_SUCCESS;
  } else {
2037
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2038 2039 2040
  }
}

H
hjxilinx 已提交
2041
int32_t getTableIndexImpl(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2042
  if (pTableToken->n == 0) {  // only one table and no table name prefix in column name
2043
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
2044 2045 2046 2047 2048 2049 2050
      pIndex->tableIndex = 0;
    }

    return TSDB_CODE_SUCCESS;
  }

  pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
B
Bomin Zhang 已提交
2051
  char tableName[TSDB_TABLE_ID_LEN] = {0};
S
slguan 已提交
2052

2053
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
2054
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
H
hjxilinx 已提交
2055
    extractTableName(pTableMetaInfo->name, tableName);
S
slguan 已提交
2056 2057 2058 2059 2060 2061 2062 2063

    if (strncasecmp(tableName, pTableToken->z, pTableToken->n) == 0 && strlen(tableName) == pTableToken->n) {
      pIndex->tableIndex = i;
      break;
    }
  }

  if (pIndex->tableIndex < 0) {
2064
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2065 2066 2067 2068 2069
  }

  return TSDB_CODE_SUCCESS;
}

2070
int32_t getTableIndexByName(SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
S
slguan 已提交
2071 2072 2073
  SSQLToken tableToken = {0};
  extractTableNameFromToken(pToken, &tableToken);

H
hjxilinx 已提交
2074
  if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2075
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2076 2077
  }

S
slguan 已提交
2078 2079
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
2080

2081
int32_t getColumnIndexByName(const SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
H
hjxilinx 已提交
2082
  if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
2083
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2084 2085
  }

S
slguan 已提交
2086 2087
  SSQLToken tmpToken = *pToken;

2088
  if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
2089
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2090 2091
  }

2092
  return doGetColumnIndexByName(&tmpToken, pQueryInfo, pIndex);
H
hzcheng 已提交
2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105
}

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 已提交
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123
    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 已提交
2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159
    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 已提交
2160 2161
    case TK_TWA:
      *functionId = TSDB_FUNC_TWA;
H
hzcheng 已提交
2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176
      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 已提交
2177
  SSqlCmd*        pCmd = &pSql->cmd;
2178
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
2179
  assert(pCmd->numOfClause == 1);
H
hjxilinx 已提交
2180

H
hzcheng 已提交
2181 2182
  pCmd->command = TSDB_SQL_SHOW;

2183
  const char* msg1 = "invalid name";
2184
  const char* msg2 = "pattern filter string too long";
2185 2186 2187 2188
  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 已提交
2189 2190 2191 2192 2193

  /*
   * database prefix in pInfo->pDCLInfo->a[0]
   * wildcard in like clause in pInfo->pDCLInfo->a[1]
   */
2194 2195 2196
  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 已提交
2197
    // db prefix in tagCond, show table conds in payload
2198 2199 2200
    SSQLToken* pDbPrefixToken = &pShowInfo->prefix;
    if (pDbPrefixToken->type != 0) {
      assert(pDbPrefixToken->n >= 0);
H
hzcheng 已提交
2201

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

2206
      if (pDbPrefixToken->n <= 0) {
2207
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
H
hzcheng 已提交
2208 2209
      }

2210
      if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
2211
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2212 2213
      }

H
hjxilinx 已提交
2214
      int32_t ret = setObjFullName(pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken, NULL, NULL);
H
hzcheng 已提交
2215
      if (ret != TSDB_CODE_SUCCESS) {
2216
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
H
hzcheng 已提交
2217
      }
2218
    }
H
hzcheng 已提交
2219

2220 2221 2222 2223
    // show table/stable like 'xxxx', set the like pattern for show tables
    SSQLToken* pPattern = &pShowInfo->pattern;
    if (pPattern->type != 0) {
      pPattern->n = strdequote(pPattern->z);
S
slguan 已提交
2224

2225
      if (pPattern->n <= 0) {
2226
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
2227
      }
H
hzcheng 已提交
2228

H
Haojun Liao 已提交
2229
      if (!tscValidateTableNameLength(pCmd->payloadLen)) {
2230
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
H
hzcheng 已提交
2231 2232
      }
    }
2233 2234
  } else if (showType == TSDB_MGMT_TABLE_VNODES) {
    if (pShowInfo->prefix.type == 0) {
2235
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode");
L
lihui 已提交
2236 2237
    }

L
lihui 已提交
2238
    // show vnodes may be ip addr of dnode in payload
2239
    SSQLToken* pDnodeIp = &pShowInfo->prefix;
B
Bomin Zhang 已提交
2240
    if (pDnodeIp->n >= TSDB_IPv4ADDR_LEN) {  // ip addr is too long
2241
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
2242
    }
L
lihui 已提交
2243

2244
    if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) {
2245
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
L
lihui 已提交
2246
    }
H
hzcheng 已提交
2247 2248 2249 2250 2251
  }

  return TSDB_CODE_SUCCESS;
}

2252 2253 2254 2255
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 已提交
2256

2257 2258
  SSqlCmd* pCmd = &pSql->cmd;
  pCmd->command = pInfo->type;
2259
  
2260 2261
  SSQLToken* idStr = &(pInfo->pDCLInfo->ip);
  if (idStr->n > TSDB_KILL_MSG_LEN) {
2262
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2263 2264
  }

2265
  strncpy(pCmd->payload, idStr->z, idStr->n);
2266

H
hzcheng 已提交
2267
  const char delim = ':';
2268 2269
  char* connIdStr = strtok(idStr->z, &delim);
  char* queryIdStr = strtok(NULL, &delim);
H
hzcheng 已提交
2270

2271 2272 2273 2274 2275
  int32_t connId = (int32_t)strtol(connIdStr, NULL, 10);
  if (connId <= 0) {
    memset(pCmd->payload, 0, strlen(pCmd->payload));
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
  }
2276

2277 2278 2279 2280 2281 2282
  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 已提交
2283
    memset(pCmd->payload, 0, strlen(pCmd->payload));
2284 2285 2286 2287 2288
    if (killType == TSDB_SQL_KILL_QUERY) {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
    } else {
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
    }
H
hzcheng 已提交
2289
  }
2290
  
H
hzcheng 已提交
2291 2292 2293
  return TSDB_CODE_SUCCESS;
}

2294 2295 2296 2297 2298 2299 2300 2301 2302
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);

  in_addr_t ipAddr = inet_addr(tmp);

  return ipAddr != INADDR_NONE;
H
hzcheng 已提交
2303 2304
}

H
hjxilinx 已提交
2305
int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2306
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
2307

weixin_48148422's avatar
weixin_48148422 已提交
2308
  if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2309
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2310 2311
  }

H
hjxilinx 已提交
2312
  assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0);
H
hzcheng 已提交
2313 2314 2315

  int16_t bytes = 0;
  int16_t type = 0;
2316
  int32_t interBytes = 0;
H
hjxilinx 已提交
2317 2318 2319
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t k = 0; k < size; ++k) {
2320
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, k);
S
slguan 已提交
2321 2322
    int16_t functionId = aAggs[pExpr->functionId].stableFuncId;

2323
    int32_t colIndex = pExpr->colInfo.colIndex;
H
hjxilinx 已提交
2324
    SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
H
hjxilinx 已提交
2325
    
S
slguan 已提交
2326
    if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
L
lihui 已提交
2327 2328
        (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
        (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
H
hjxilinx 已提交
2329
      if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, pExpr->param[0].i64Key, &type, &bytes,
2330
                            &interBytes, 0, true) != TSDB_CODE_SUCCESS) {
2331
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2332
      }
H
hzcheng 已提交
2333

2334
      tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
S
slguan 已提交
2335
      // todo refactor
2336
      pExpr->interBytes = interBytes;
H
hzcheng 已提交
2337 2338 2339
    }
  }

2340
  tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
S
slguan 已提交
2341
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2342 2343 2344
}

/* transfer the field-info back to original input format */
H
hjxilinx 已提交
2345
void tscRestoreSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
2346
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
2347
  if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
2348 2349
    return;
  }
H
hjxilinx 已提交
2350 2351 2352
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2353
    SSqlExpr*   pExpr = tscSqlExprGet(pQueryInfo, i);
2354
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
H
hjxilinx 已提交
2355
    
2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372
    // 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 已提交
2373 2374 2375
  }
}

2376
bool hasUnsupportFunctionsForSTableQuery(SQueryInfo* pQueryInfo) {
S
slguan 已提交
2377
  const char* msg1 = "TWA not allowed to apply to super table directly";
H
hjxilinx 已提交
2378
  const char* msg2 = "TWA only support group by tbname for super table query";
2379
  const char* msg3 = "function not support for super table query";
H
hjxilinx 已提交
2380

S
slguan 已提交
2381
  // filter sql function not supported by metric query yet.
H
hjxilinx 已提交
2382 2383
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
2384
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
2385
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_STABLE) == 0) {
2386
      invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
2387
      return true;
H
hzcheng 已提交
2388 2389 2390
    }
  }

2391 2392 2393
  if (tscIsTWAQuery(pQueryInfo)) {
    if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
      invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
2394 2395
      return true;
    }
H
hzcheng 已提交
2396

2397
    if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) {
2398
      invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
2399
      return true;
2400 2401 2402 2403 2404 2405
    } else {
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) {
        invalidSqlErrMsg(pQueryInfo->msg, msg2);
        return true;
      }
H
hzcheng 已提交
2406 2407
    }
  }
S
slguan 已提交
2408

H
hzcheng 已提交
2409 2410 2411
  return false;
}

2412
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
2413
  int32_t startIdx = 0;
H
hjxilinx 已提交
2414
  
H
hjxilinx 已提交
2415 2416
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
  int32_t functionID = pExpr->functionId;
S
slguan 已提交
2417 2418

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

2423
  int32_t factor = funcCompatDefList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
H
hzcheng 已提交
2424 2425 2426

  // diff function cannot be executed with other function
  // arithmetic function can be executed with other arithmetic functions
H
hjxilinx 已提交
2427 2428 2429
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
  for (int32_t i = startIdx + 1; i < size; ++i) {
H
hjxilinx 已提交
2430
    SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i);
2431

H
hjxilinx 已提交
2432
    int16_t functionId = pExpr1->functionId;
2433 2434 2435 2436
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
      continue;
    }

H
hjxilinx 已提交
2437
    if (functionId == TSDB_FUNC_PRJ && pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
2438 2439 2440 2441
      continue;
    }

    if (funcCompatDefList[functionId] != factor) {
H
hzcheng 已提交
2442 2443 2444 2445 2446 2447 2448
      return false;
    }
  }

  return true;
}

2449
void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex) {
2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464
//  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
//
//  // update tags column index for expression
//  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
//  for (int32_t i = 0; i < size; ++i) {
//    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
//
//    if (!TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {  // not tags, continue
//      continue;
//    }
//
//    // not belongs to this table
//    if (pExpr->uid != pTableMetaInfo->pTableMeta->uid) {
//      continue;
//    }
H
hzcheng 已提交
2465

2466 2467 2468 2469 2470 2471 2472
//    for (int32_t j = 0; j < pTableMetaInfo->numOfTags; ++j) {
//      if (pExpr->colInfo.colIndex == pTableMetaInfo->tagColumnIndex[j]) {
//        pExpr->colInfo.colIndex = j;
//        break;
//      }
//    }
//  }
H
hjxilinx 已提交
2473

H
hjxilinx 已提交
2474
  // update join condition tag column index
2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498
//  SJoinInfo* pJoinInfo = &pQueryInfo->tagCond.joinInfo;
//  if (!pJoinInfo->hasJoin) {  // not join query
//    return;
//  }
//
//  assert(pJoinInfo->left.uid != pJoinInfo->right.uid);
//
//  // the join condition expression node belongs to this table(super table)
//  assert(0);
//  if (pTableMetaInfo->pTableMeta->uid == pJoinInfo->left.uid) {
//    for (int32_t i = 0; i < pTableMetaInfo->numOfTags; ++i) {
//      if (pJoinInfo->left.tagCol == pTableMetaInfo->tagColumnIndex[i]) {
//        pJoinInfo->left.tagCol = i;
//      }
//    }
//  }
//
//  if (pTableMetaInfo->pTableMeta->uid == pJoinInfo->right.uid) {
//    for (int32_t i = 0; i < pTableMetaInfo->numOfTags; ++i) {
//      if (pJoinInfo->right.tagCol == pTableMetaInfo->tagColumnIndex[i]) {
//        pJoinInfo->right.tagCol = i;
//      }
//    }
//  }
H
hzcheng 已提交
2499 2500
}

2501
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
2502 2503
  const char* msg1 = "too many columns in group by clause";
  const char* msg2 = "invalid column name in group by clause";
H
hjxilinx 已提交
2504
  const char* msg3 = "group by columns must belong to one table";
S
slguan 已提交
2505 2506 2507
  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 已提交
2508

2509
  // todo : handle two tables situation
H
hjxilinx 已提交
2510
  STableMetaInfo* pTableMetaInfo = NULL;
H
hzcheng 已提交
2511 2512 2513 2514 2515

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

2516 2517 2518 2519
  if (pQueryInfo->colList == NULL) {
    pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
  }
  
2520
  pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
H
hzcheng 已提交
2521
  if (pList->nExpr > TSDB_MAX_TAGS) {
2522
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
2523 2524
  }

H
hjxilinx 已提交
2525
  STableMeta* pTableMeta = NULL;
S
slguan 已提交
2526
  SSchema*    pSchema = NULL;
H
hjxilinx 已提交
2527
  SSchema     s = tscGetTbnameColumnSchema();
H
hzcheng 已提交
2528

S
slguan 已提交
2529
  int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
2530
  
H
hzcheng 已提交
2531 2532 2533 2534
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tVariant* pVar = &pList->a[i].pVar;
    SSQLToken token = {pVar->nLen, pVar->nType, pVar->pz};

S
slguan 已提交
2535
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
2536
    if (getColumnIndexByName(&token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
2537
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
2538
    }
H
hzcheng 已提交
2539

S
slguan 已提交
2540
    if (tableIndex != index.tableIndex && tableIndex >= 0) {
2541
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
2542 2543
    }

S
slguan 已提交
2544
    tableIndex = index.tableIndex;
H
hzcheng 已提交
2545

H
hjxilinx 已提交
2546
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
2547
    pTableMeta = pTableMetaInfo->pTableMeta;
2548 2549
  
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
S
slguan 已提交
2550 2551 2552
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      pSchema = &s;
    } else {
H
hjxilinx 已提交
2553
      pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
S
slguan 已提交
2554
    }
H
hzcheng 已提交
2555

S
slguan 已提交
2556
    bool groupTag = false;
2557
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
S
slguan 已提交
2558
      groupTag = true;
H
hzcheng 已提交
2559
    }
2560 2561 2562 2563 2564 2565
  
    SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
    if (pGroupExpr->columnInfo == NULL) {
      pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
    }
    
S
slguan 已提交
2566
    if (groupTag) {
weixin_48148422's avatar
weixin_48148422 已提交
2567
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
2568
        return invalidSqlErrMsg(pQueryInfo->msg, msg9);
S
slguan 已提交
2569 2570
      }

2571 2572 2573 2574
      int32_t relIndex = index.columnIndex;
      if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
        relIndex -= numOfCols;
      }
S
slguan 已提交
2575

H
hjxilinx 已提交
2576
      SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
2577
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
H
hjxilinx 已提交
2578 2579 2580
      
      index.columnIndex = relIndex;
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
2581 2582
    } else {
      // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
2583
      if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
2584
        return invalidSqlErrMsg(pQueryInfo->msg, msg8);
S
slguan 已提交
2585 2586
      }

2587
      tscColumnListInsert(pQueryInfo->colList, &index);
2588 2589 2590 2591 2592
      
      SColIndex colIndex = {
          .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId,
      };
      taosArrayPush(pGroupExpr->columnInfo, &colIndex);
2593
      pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
S
slguan 已提交
2594 2595

      if (i == 0 && pList->nExpr > 1) {
2596
        return invalidSqlErrMsg(pQueryInfo->msg, msg7);
S
slguan 已提交
2597
      }
H
hzcheng 已提交
2598 2599 2600
    }
  }

2601
  pQueryInfo->groupbyExpr.tableIndex = tableIndex;
S
slguan 已提交
2602

H
hzcheng 已提交
2603 2604 2605
  return TSDB_CODE_SUCCESS;
}

2606 2607
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
  if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
2608
    tscFieldInfoUpdateOffsetForInterResult(pQueryInfo);
H
hzcheng 已提交
2609
  } else {
H
hjxilinx 已提交
2610
    tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
2611 2612 2613
  }
}

2614
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
S
slguan 已提交
2615 2616 2617
  if (pColumn == NULL) {
    return NULL;
  }
2618

S
slguan 已提交
2619
  int32_t size = pColumn->numOfFilters + 1;
L
lihui 已提交
2620
  char*   tmp = (char*)realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size));
S
slguan 已提交
2621 2622
  if (tmp != NULL) {
    pColumn->filterInfo = (SColumnFilterInfo*)tmp;
2623 2624
  }

S
slguan 已提交
2625
  pColumn->numOfFilters++;
2626

S
slguan 已提交
2627 2628 2629 2630
  SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1];
  memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo));

  return pColFilterInfo;
2631 2632
}

2633 2634
static int32_t doExtractColumnFilterInfo(SQueryInfo* pQueryInfo, SColumnFilterInfo* pColumnFilter,
                                         SColumnIndex* columnIndex, tSQLExpr* pExpr) {
S
slguan 已提交
2635
  const char* msg = "not supported filter condition";
H
hzcheng 已提交
2636

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

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

S
slguan 已提交
2642
  int16_t colType = pSchema->type;
2643
  if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
H
hzcheng 已提交
2644 2645 2646
    colType = TSDB_DATA_TYPE_BIGINT;
  } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
    colType = TSDB_DATA_TYPE_DOUBLE;
2647
  } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
2648
    int retVal = setColumnFilterInfoForTimestamp(pQueryInfo, &pRight->val);
2649 2650 2651
    if (TSDB_CODE_SUCCESS != retVal) {
      return retVal;
    }
H
hzcheng 已提交
2652 2653 2654
  }

  if (pExpr->nSQLOptr == TK_LE || pExpr->nSQLOptr == TK_LT) {
2655
    tVariantDump(&pRight->val, (char*)&pColumnFilter->upperBndd, colType, false);
S
slguan 已提交
2656
  } else {  // TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
H
hzcheng 已提交
2657
    if (colType == TSDB_DATA_TYPE_BINARY) {
S
slguan 已提交
2658 2659
      pColumnFilter->pz = (int64_t)calloc(1, pRight->val.nLen + 1);
      pColumnFilter->len = pRight->val.nLen;
H
hzcheng 已提交
2660

2661
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2662 2663 2664 2665
    } 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);

2666
      tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
S
slguan 已提交
2667 2668 2669

      size_t len = wcslen((wchar_t*)pColumnFilter->pz);
      pColumnFilter->len = len * TSDB_NCHAR_SIZE;
H
hzcheng 已提交
2670
    } else {
2671
      tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
H
hzcheng 已提交
2672 2673 2674 2675 2676
    }
  }

  switch (pExpr->nSQLOptr) {
    case TK_LE:
S
slguan 已提交
2677
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
H
hzcheng 已提交
2678 2679
      break;
    case TK_LT:
S
slguan 已提交
2680
      pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
H
hzcheng 已提交
2681 2682
      break;
    case TK_GT:
2683
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
H
hzcheng 已提交
2684 2685
      break;
    case TK_GE:
2686
      pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
H
hzcheng 已提交
2687 2688
      break;
    case TK_EQ:
S
slguan 已提交
2689
      pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
H
hzcheng 已提交
2690 2691
      break;
    case TK_NE:
S
slguan 已提交
2692
      pColumnFilter->lowerRelOptr = TSDB_RELATION_NOT_EQUAL;
H
hzcheng 已提交
2693 2694
      break;
    case TK_LIKE:
S
slguan 已提交
2695
      pColumnFilter->lowerRelOptr = TSDB_RELATION_LIKE;
H
hzcheng 已提交
2696
      break;
S
slguan 已提交
2697
    default:
2698
      return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
2699
  }
S
slguan 已提交
2700

2701
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2702 2703
}

S
slguan 已提交
2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717
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 已提交
2718

H
hjxilinx 已提交
2719
static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
S
slguan 已提交
2720 2721

static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
H
hzcheng 已提交
2722
  if (pExpr->nSQLOptr == TK_ID) {  // column name
S
slguan 已提交
2723 2724
    strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
    *str += pExpr->colInfo.n;
H
hzcheng 已提交
2725 2726

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

H
hjxilinx 已提交
2729 2730 2731 2732 2733 2734 2735
  } 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 已提交
2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754
    assert(false);
  }

  return TSDB_CODE_SUCCESS;
}

static bool isExprLeafNode(tSQLExpr* pExpr) {
  return (pExpr->pRight == NULL && pExpr->pLeft == NULL) &&
         (pExpr->nSQLOptr == TK_ID || (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_NCHAR) ||
          pExpr->nSQLOptr == TK_SET);
}

static bool isExprDirectParentOfLeaftNode(tSQLExpr* pExpr) {
  return (pExpr->pLeft != NULL && pExpr->pRight != NULL) &&
         (isExprLeafNode(pExpr->pLeft) && isExprLeafNode(pExpr->pRight));
}

static int32_t tSQLExprLeafToString(tSQLExpr* pExpr, bool addParentheses, char** output) {
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
2755
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2756 2757
  }

S
slguan 已提交
2758 2759 2760 2761 2762 2763 2764 2765 2766 2767
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

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

  tSQLExprNodeToString(pLeft, output);
  if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
2768
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2769 2770 2771 2772 2773 2774 2775 2776 2777
  }

  tSQLExprNodeToString(pRight, output);

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

H
hzcheng 已提交
2778 2779 2780 2781
  return TSDB_CODE_SUCCESS;
}

static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
S
slguan 已提交
2782 2783 2784 2785
  const char* le = "<=";
  const char* ge = ">=";
  const char* ne = "<>";
  const char* likeOptr = "LIKE";
H
hzcheng 已提交
2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833

  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:
2834
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2835 2836 2837 2838 2839 2840 2841
  }

  *exprString += 1;

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2842
static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hzcheng 已提交
2843 2844
  tSQLExprList* pList = pExpr->pParam;
  if (pList->nExpr <= 0) {
2845
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2846 2847
  }

S
slguan 已提交
2848
  if (pList->nExpr > 0) {
H
hjxilinx 已提交
2849
    taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
S
slguan 已提交
2850 2851
  }

H
hzcheng 已提交
2852 2853
  for (int32_t i = 0; i < pList->nExpr; ++i) {
    tSQLExpr* pSub = pList->a[i].pNode;
H
hjxilinx 已提交
2854
    taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
S
slguan 已提交
2855 2856

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

H
Haojun Liao 已提交
2860
    if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
2861
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2862 2863 2864 2865 2866 2867
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
2868
static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
H
hjxilinx 已提交
2869 2870
  taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
  taosStringBuilderAppendString(sb, pExpr->val.pz);
S
slguan 已提交
2871 2872

  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2873 2874
}

S
slguan 已提交
2875 2876 2877 2878 2879 2880
enum {
  TSQL_EXPR_TS = 0,
  TSQL_EXPR_TAG = 1,
  TSQL_EXPR_COLUMN = 2,
  TSQL_EXPR_TBNAME = 3,
};
H
hzcheng 已提交
2881

2882
static int32_t extractColumnFilterInfo(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, tSQLExpr* pExpr, int32_t sqlOptr) {
H
hjxilinx 已提交
2883
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
S
slguan 已提交
2884

H
hjxilinx 已提交
2885 2886
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
  SSchema*    pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
H
hzcheng 已提交
2887

S
slguan 已提交
2888 2889 2890
  const char* msg1 = "non binary column not support like operator";
  const char* msg2 = "binary column not support this operator";

H
hjxilinx 已提交
2891
  SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
S
slguan 已提交
2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908
  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];
    }
  } else if (sqlOptr == TK_OR) {
    // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
    pColFilter = addColumnFilterInfo(pColumn);
  } else {  // error;
2909
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
2910 2911
  }

2912
  pColFilter->filterstr =
S
slguan 已提交
2913 2914
      ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);

2915
  if (pColFilter->filterstr) {
S
slguan 已提交
2916
    if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE && pExpr->nSQLOptr != TK_LIKE) {
2917
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
2918
    }
S
slguan 已提交
2919 2920
  } else {
    if (pExpr->nSQLOptr == TK_LIKE) {
2921
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
2922
    }
S
slguan 已提交
2923 2924 2925
  }

  pColumn->colIndex = *pIndex;
2926
  return doExtractColumnFilterInfo(pQueryInfo, pColFilter, pIndex, pExpr);
S
slguan 已提交
2927 2928
}

2929
static void relToString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2930 2931 2932 2933 2934
  assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);

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

2935
  //    if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
S
slguan 已提交
2936 2937 2938 2939 2940 2941 2942 2943 2944
  if (pExpr->nSQLOptr == TK_AND) {
    strcpy(*str, and);
    *str += strlen(and);
  } else {
    strcpy(*str, or);
    *str += strlen(or);
  }
}

2945
UNUSED_FUNC
2946
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
S
slguan 已提交
2947 2948 2949 2950 2951 2952 2953
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

2955
    int32_t ret = getTagCondString(pExpr->pLeft, str);
H
hzcheng 已提交
2956
    if (ret != TSDB_CODE_SUCCESS) {
S
slguan 已提交
2957
      return ret;
H
hzcheng 已提交
2958
    }
S
slguan 已提交
2959

2960
    relToString(pExpr, str);
S
slguan 已提交
2961

2962
    ret = getTagCondString(pExpr->pRight, str);
S
slguan 已提交
2963 2964 2965 2966

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

H
hzcheng 已提交
2967 2968 2969
    return ret;
  }

S
slguan 已提交
2970 2971 2972
  return tSQLExprLeafToString(pExpr, true, str);
}

2973
static int32_t getTablenameCond(SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
S
slguan 已提交
2974 2975 2976 2977
  const char* msg0 = "invalid table name list";

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

S
slguan 已提交
2980 2981
  tSQLExpr* pLeft = pTableCond->pLeft;
  tSQLExpr* pRight = pTableCond->pRight;
H
hzcheng 已提交
2982

S
slguan 已提交
2983
  if (!isTablenameToken(&pLeft->colInfo)) {
2984
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
2985 2986
  }

S
slguan 已提交
2987
  int32_t ret = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
2988

S
slguan 已提交
2989
  if (pTableCond->nSQLOptr == TK_IN) {
H
hjxilinx 已提交
2990
    ret = tablenameListToString(pRight, sb);
S
slguan 已提交
2991
  } else if (pTableCond->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
2992
    ret = tablenameCondToString(pRight, sb);
S
slguan 已提交
2993
  }
H
hzcheng 已提交
2994

S
slguan 已提交
2995
  if (ret != TSDB_CODE_SUCCESS) {
2996
    invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
2997
  }
H
hzcheng 已提交
2998

S
slguan 已提交
2999 3000 3001
  return ret;
}

3002
static int32_t getColumnQueryCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
S
slguan 已提交
3003 3004 3005 3006 3007
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  if (!isExprDirectParentOfLeaftNode(pExpr)) {  // internal node
3008
    int32_t ret = getColumnQueryCondInfo(pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
S
slguan 已提交
3009 3010 3011 3012
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3013
    return getColumnQueryCondInfo(pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
S
slguan 已提交
3014 3015
  } else {  // handle leaf node
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3016
    if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3017
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3018
    }
S
slguan 已提交
3019

3020
    return extractColumnFilterInfo(pQueryInfo, &index, pExpr, relOptr);
H
hzcheng 已提交
3021
  }
S
slguan 已提交
3022
}
H
hzcheng 已提交
3023

3024
static int32_t getJoinCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
3025
  const char* msg = "invalid join query condition";
H
hzcheng 已提交
3026

S
slguan 已提交
3027 3028 3029
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3030

S
slguan 已提交
3031
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
3032
    return invalidSqlErrMsg(pQueryInfo->msg, msg);
S
slguan 已提交
3033 3034
  }

3035
  STagCond*  pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
3036 3037 3038 3039
  SJoinNode* pLeft = &pTagCond->joinInfo.left;
  SJoinNode* pRight = &pTagCond->joinInfo.right;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3040
  if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3041
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3042 3043
  }

H
hjxilinx 已提交
3044
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3045
  int16_t         tagColIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3046

H
hjxilinx 已提交
3047
  pLeft->uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
3048
  pLeft->tagCol = tagColIndex;
H
hjxilinx 已提交
3049
  strcpy(pLeft->tableId, pTableMetaInfo->name);
S
slguan 已提交
3050 3051

  index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
3052
  if (getColumnIndexByName(&pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3053
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3054 3055
  }

H
hjxilinx 已提交
3056
  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3057
  tagColIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3058

H
hjxilinx 已提交
3059
  pRight->uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
3060
  pRight->tagCol = tagColIndex;
H
hjxilinx 已提交
3061
  strcpy(pRight->tableId, pTableMetaInfo->name);
S
slguan 已提交
3062 3063

  pTagCond->joinInfo.hasJoin = true;
H
hzcheng 已提交
3064 3065 3066 3067
  return TSDB_CODE_SUCCESS;
}

// todo error handle / such as and /or mixed with +/-/*/
S
slguan 已提交
3068
int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
H
hzcheng 已提交
3069 3070 3071
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3072
  *(*exprString)++ = '(';
H
hzcheng 已提交
3073 3074

  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
S
slguan 已提交
3075
    buildArithmeticExprString(pLeft, exprString);
H
hzcheng 已提交
3076
  } else {
S
slguan 已提交
3077
    int32_t ret = tSQLExprNodeToString(pLeft, exprString);
H
hzcheng 已提交
3078
    if (ret != TSDB_CODE_SUCCESS) {
3079
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3080 3081 3082 3083 3084 3085
    }
  }

  optrToString(pExpr, exprString);

  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
S
slguan 已提交
3086
    buildArithmeticExprString(pRight, exprString);
H
hzcheng 已提交
3087
  } else {
S
slguan 已提交
3088
    int32_t ret = tSQLExprNodeToString(pRight, exprString);
H
hzcheng 已提交
3089
    if (ret != TSDB_CODE_SUCCESS) {
3090
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3091 3092 3093
    }
  }

H
hjxilinx 已提交
3094
  *(*exprString)++ = ')';
H
hzcheng 已提交
3095 3096 3097 3098

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3099
static int32_t validateSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3100
  if (pExpr->nSQLOptr == TK_ID) {
H
hjxilinx 已提交
3101 3102 3103
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = NORMAL_ARITHMETIC;
    } else if (*type == AGG_ARIGHTMEIC) {
3104
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3105
    }
L
lihui 已提交
3106

H
hjxilinx 已提交
3107 3108
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
    if (getColumnIndexByName(&pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3109
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3110 3111 3112
    }

    // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
H
hjxilinx 已提交
3113
    STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
H
hjxilinx 已提交
3114 3115
    SSchema*    pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
    
H
hjxilinx 已提交
3116 3117
    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)) {
3118
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3119 3120 3121
    }

    pList->ids[pList->num++] = index;
H
hzcheng 已提交
3122
  } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
3123
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3124 3125 3126 3127
  } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
    if (*type == NON_ARITHMEIC_EXPR) {
      *type = AGG_ARIGHTMEIC;
    } else if (*type == NORMAL_ARITHMETIC) {
3128
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3129 3130
    }

H
hjxilinx 已提交
3131 3132
    int32_t outputIndex = tscSqlExprNumOfExprs(pQueryInfo);
  
H
hjxilinx 已提交
3133 3134 3135 3136
    tSQLExprItem item = {.pNode = pExpr, .aliasName = NULL};
  
    // sql function in selection clause, append sql function info in pSqlCmd structure sequentially
    if (addExprAndResultField(pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
3137
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
3138
    }
H
hzcheng 已提交
3139 3140 3141 3142 3143
  }

  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3144
static int32_t validateArithmeticSQLExpr(tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
H
hzcheng 已提交
3145 3146 3147 3148 3149 3150
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  tSQLExpr* pLeft = pExpr->pLeft;
  if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
H
hjxilinx 已提交
3151
    int32_t ret = validateArithmeticSQLExpr(pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3152 3153 3154 3155
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
H
hjxilinx 已提交
3156
    int32_t ret = validateSQLExpr(pLeft, pQueryInfo, pList, type);
H
hzcheng 已提交
3157 3158 3159 3160 3161 3162 3163
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  tSQLExpr* pRight = pExpr->pRight;
  if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
H
hjxilinx 已提交
3164
    int32_t ret = validateArithmeticSQLExpr(pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3165 3166 3167 3168
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  } else {
H
hjxilinx 已提交
3169
    int32_t ret = validateSQLExpr(pRight, pQueryInfo, pList, type);
H
hzcheng 已提交
3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }

  return TSDB_CODE_SUCCESS;
}

static bool isValidExpr(tSQLExpr* pLeft, tSQLExpr* pRight, int32_t optr) {
  if (pLeft == NULL || (pRight == NULL && optr != TK_IN)) {
    return false;
  }

  /*
   * filter illegal expression in where clause:
S
slguan 已提交
3185 3186 3187
   * 1. count(*) > 12
   * 2. sum(columnA) > sum(columnB)
   * 3. 4 < 5,  'ABC'>'abc'
H
hzcheng 已提交
3188 3189 3190
   *
   * However, columnA < 4+12 is valid
   */
L
lihui 已提交
3191 3192
  if ((pLeft->nSQLOptr >= TK_COUNT && pLeft->nSQLOptr <= TK_AVG_IRATE) ||
      (pRight->nSQLOptr >= TK_COUNT && pRight->nSQLOptr <= TK_AVG_IRATE) ||
H
hzcheng 已提交
3193 3194 3195 3196 3197 3198 3199 3200
      (pLeft->nSQLOptr >= TK_BOOL && pLeft->nSQLOptr <= TK_BINARY && pRight->nSQLOptr >= TK_BOOL &&
       pRight->nSQLOptr <= TK_BINARY)) {
    return false;
  }

  return true;
}

S
slguan 已提交
3201 3202 3203
static void exchangeExpr(tSQLExpr* pExpr) {
  tSQLExpr* pLeft = pExpr->pLeft;
  tSQLExpr* pRight = pExpr->pRight;
H
hzcheng 已提交
3204

S
slguan 已提交
3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229
  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 已提交
3230

S
slguan 已提交
3231 3232 3233 3234 3235
    pExpr->nSQLOptr = optr;
    SWAP(pExpr->pLeft, pExpr->pRight, void*);
  }
}

3236
static bool validateJoinExprNode(SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
S
slguan 已提交
3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249
  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) {
3250
    invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
3251 3252 3253 3254 3255
    return false;
  }

  SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER;

3256
  if (getColumnIndexByName(&pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) {
3257
    invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3258
    return false;
H
hzcheng 已提交
3259 3260
  }

S
slguan 已提交
3261
  // todo extract function
H
hjxilinx 已提交
3262
  STableMetaInfo* pLeftMeterMeta = tscGetMetaInfo(pQueryInfo, pLeftIndex->tableIndex);
H
hjxilinx 已提交
3263
  SSchema*        pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta);
S
slguan 已提交
3264 3265
  int16_t         leftType = pLeftSchema[pLeftIndex->columnIndex].type;

H
hjxilinx 已提交
3266
  STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex);
H
hjxilinx 已提交
3267
  SSchema*        pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta);
S
slguan 已提交
3268 3269 3270
  int16_t         rightType = pRightSchema[rightIndex.columnIndex].type;

  if (leftType != rightType) {
3271
    invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
3272 3273
    return false;
  } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) {
3274
    invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
3275
    return false;
H
hzcheng 已提交
3276 3277
  }

S
slguan 已提交
3278
  // table to table/ super table to super table are allowed
weixin_48148422's avatar
weixin_48148422 已提交
3279
  if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) {
3280
    invalidSqlErrMsg(pQueryInfo->msg, msg5);
S
slguan 已提交
3281 3282
    return false;
  }
H
hzcheng 已提交
3283

S
slguan 已提交
3284 3285
  return true;
}
H
hzcheng 已提交
3286

S
slguan 已提交
3287 3288 3289 3290 3291 3292
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 已提交
3293 3294 3295
    }
  }

S
slguan 已提交
3296
  return false;
H
hzcheng 已提交
3297 3298
}

3299
static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
S
slguan 已提交
3300 3301
  if (*parent != NULL) {
    if (parentOptr == TK_OR && msg != NULL) {
3302
      return invalidSqlErrMsg(msgBuf, msg);
S
slguan 已提交
3303
    }
H
hzcheng 已提交
3304

S
slguan 已提交
3305 3306 3307 3308
    *parent = tSQLExprCreate((*parent), pExpr, parentOptr);
  } else {
    *parent = pExpr;
  }
H
hzcheng 已提交
3309

S
slguan 已提交
3310 3311
  return TSDB_CODE_SUCCESS;
}
H
hzcheng 已提交
3312

3313
static int32_t handleExprInQueryCond(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr, int32_t* type,
S
slguan 已提交
3314
                                     int32_t parentOptr) {
3315
  const char* msg1 = "table query cannot use tags filter";
S
slguan 已提交
3316 3317 3318
  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 已提交
3319 3320 3321
  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";
3322 3323
  const char* msg8 = "wildcard string should be less than 20 characters";
  
S
slguan 已提交
3324 3325
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;
H
hzcheng 已提交
3326

S
slguan 已提交
3327 3328 3329
  int32_t ret = TSDB_CODE_SUCCESS;

  SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3330
  if (getColumnIndexByName(&pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3331
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
3332 3333
  }

S
slguan 已提交
3334 3335
  assert(isExprDirectParentOfLeaftNode(*pExpr));

H
hjxilinx 已提交
3336
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3337
  STableMeta*     pTableMeta = pTableMetaInfo->pTableMeta;
S
slguan 已提交
3338 3339

  if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {  // query on time range
3340
    if (!validateJoinExprNode(pQueryInfo, *pExpr, &index)) {
3341
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3342
    }
S
slguan 已提交
3343 3344 3345

    // set join query condition
    if (pRight->nSQLOptr == TK_ID) {  // no need to keep the timestamp join condition
H
hjxilinx 已提交
3346
      TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
S
slguan 已提交
3347 3348 3349 3350 3351 3352 3353 3354
      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 {
3355
      ret = setExprToCond(&pCondExpr->pTimewindow, *pExpr, msg3, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3356 3357 3358 3359
    }

    *pExpr = NULL;  // remove this expression
    *type = TSQL_EXPR_TS;
3360 3361
  } 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 已提交
3362
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
3363
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3364 3365 3366 3367 3368
    }

    // check for like expression
    if ((*pExpr)->nSQLOptr == TK_LIKE) {
      if (pRight->val.nLen > TSDB_PATTERN_STRING_MAX_LEN) {
3369
        return invalidSqlErrMsg(pQueryInfo->msg, msg8);
S
slguan 已提交
3370 3371
      }

H
hjxilinx 已提交
3372
      SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
3373 3374 3375

      if ((!isTablenameToken(&pLeft->colInfo)) && pSchema[index.columnIndex].type != TSDB_DATA_TYPE_BINARY &&
          pSchema[index.columnIndex].type != TSDB_DATA_TYPE_NCHAR) {
3376
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
3377 3378 3379 3380 3381 3382
      }
    }

    // in case of in operator, keep it in a seperate attribute
    if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      if (!validTableNameOptr(*pExpr)) {
3383
        return invalidSqlErrMsg(pQueryInfo->msg, msg7);
S
slguan 已提交
3384
      }
3385 3386 3387 3388
  
      if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
      }
S
slguan 已提交
3389 3390 3391 3392 3393 3394

      if (pCondExpr->pTableCond == NULL) {
        pCondExpr->pTableCond = *pExpr;
        pCondExpr->relType = parentOptr;
        pCondExpr->tableCondIndex = index.tableIndex;
      } else {
3395
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
S
slguan 已提交
3396 3397 3398 3399 3400 3401
      }

      *type = TSQL_EXPR_TBNAME;
      *pExpr = NULL;
    } else {
      if (pRight->nSQLOptr == TK_ID) {  // join on tag columns for stable query
3402
        if (!validateJoinExprNode(pQueryInfo, *pExpr, &index)) {
3403
          return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3404 3405 3406
        }

        if (pCondExpr->pJoinExpr != NULL) {
3407
          return invalidSqlErrMsg(pQueryInfo->msg, msg4);
S
slguan 已提交
3408 3409
        }

3410 3411
        pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
        ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
S
slguan 已提交
3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425
        *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
3426
      return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
3427 3428
    }

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

S
slguan 已提交
3433
  return ret;
H
hzcheng 已提交
3434 3435
}

3436 3437
int32_t getQueryCondExpr(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr, int32_t* type,
                         int32_t parentOptr) {
H
hzcheng 已提交
3438 3439 3440 3441
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

S
slguan 已提交
3444 3445 3446 3447
  tSQLExpr* pLeft = (*pExpr)->pLeft;
  tSQLExpr* pRight = (*pExpr)->pRight;

  if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
3448
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3449 3450
  }

S
slguan 已提交
3451 3452
  int32_t leftType = -1;
  int32_t rightType = -1;
H
hzcheng 已提交
3453

S
slguan 已提交
3454
  if (!isExprDirectParentOfLeaftNode(*pExpr)) {
3455
    int32_t ret = getQueryCondExpr(pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
H
hzcheng 已提交
3456 3457 3458 3459
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

3460
    ret = getQueryCondExpr(pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
S
slguan 已提交
3461 3462 3463
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
H
hzcheng 已提交
3464

S
slguan 已提交
3465 3466 3467 3468 3469 3470
    /*
     *  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)) {
3471
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3472
      }
H
hzcheng 已提交
3473 3474
    }

S
slguan 已提交
3475 3476 3477
    *type = rightType;
    return TSDB_CODE_SUCCESS;
  }
H
hzcheng 已提交
3478

S
slguan 已提交
3479
  exchangeExpr(*pExpr);
H
hzcheng 已提交
3480

3481
  return handleExprInQueryCond(pQueryInfo, pExpr, pCondExpr, type, parentOptr);
S
slguan 已提交
3482
}
H
hzcheng 已提交
3483

S
slguan 已提交
3484 3485 3486 3487
static void doCompactQueryExpr(tSQLExpr** pExpr) {
  if (*pExpr == NULL || isExprDirectParentOfLeaftNode(*pExpr)) {
    return;
  }
H
hzcheng 已提交
3488

S
slguan 已提交
3489 3490 3491
  if ((*pExpr)->pLeft) {
    doCompactQueryExpr(&(*pExpr)->pLeft);
  }
H
hzcheng 已提交
3492

S
slguan 已提交
3493 3494 3495
  if ((*pExpr)->pRight) {
    doCompactQueryExpr(&(*pExpr)->pRight);
  }
H
hzcheng 已提交
3496

S
slguan 已提交
3497 3498 3499 3500
  if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
      ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
    tSQLExprNodeDestroy(*pExpr);
    *pExpr = NULL;
H
hzcheng 已提交
3501

S
slguan 已提交
3502 3503 3504
  } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pRight;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3505

S
slguan 已提交
3506 3507 3508 3509
    (*pExpr) = tmpPtr;
  } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
    tSQLExpr* tmpPtr = (*pExpr)->pLeft;
    tSQLExprNodeDestroy(*pExpr);
H
hzcheng 已提交
3510

S
slguan 已提交
3511
    (*pExpr) = tmpPtr;
H
hzcheng 已提交
3512
  }
S
slguan 已提交
3513
}
H
hzcheng 已提交
3514

3515
static void doExtractExprForSTable(tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
S
slguan 已提交
3516 3517 3518 3519
  if (isExprDirectParentOfLeaftNode(*pExpr)) {
    tSQLExpr* pLeft = (*pExpr)->pLeft;

    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3520
    if (getColumnIndexByName(&pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3521
      return;
H
hzcheng 已提交
3522 3523
    }

S
slguan 已提交
3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536
    if (index.tableIndex != tableIndex) {
      return;
    }

    SSQLToken t = {0};
    extractTableNameFromToken(&pLeft->colInfo, &t);

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

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

3537 3538
    doExtractExprForSTable(&(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
    doExtractExprForSTable(&(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
S
slguan 已提交
3539 3540 3541
  }
}

3542
static tSQLExpr* extractExprForSTable(tSQLExpr** pExpr, SQueryInfo* pQueryInfo, int32_t tableIndex) {
S
slguan 已提交
3543
  tSQLExpr* pResExpr = NULL;
H
hzcheng 已提交
3544

S
slguan 已提交
3545
  if (*pExpr != NULL) {
3546
    doExtractExprForSTable(pExpr, pQueryInfo, &pResExpr, tableIndex);
S
slguan 已提交
3547
    doCompactQueryExpr(&pResExpr);
H
hzcheng 已提交
3548 3549
  }

S
slguan 已提交
3550
  return pResExpr;
H
hzcheng 已提交
3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565
}

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

3566
static int32_t setTableCondForSTableQuery(SQueryInfo* pQueryInfo, const char* account, tSQLExpr* pExpr,
3567
                                          int16_t tableCondIndex, SStringBuilder* sb) {
3568
  const char* msg = "table name too long";
H
hzcheng 已提交
3569

S
slguan 已提交
3570 3571 3572 3573
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }

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

3576
  STagCond* pTagCond = &pQueryInfo->tagCond;
H
hjxilinx 已提交
3577
  pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->uid;
S
slguan 已提交
3578 3579 3580 3581

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

  if (pExpr->nSQLOptr == TK_LIKE) {
H
hjxilinx 已提交
3582
    char* str = taosStringBuilderGetResult(sb, NULL);
3583
    pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
S
slguan 已提交
3584 3585 3586
    return TSDB_CODE_SUCCESS;
  }

S
Shuduo Sang 已提交
3587
  SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
H
hjxilinx 已提交
3588
  taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
H
hzcheng 已提交
3589

S
slguan 已提交
3590
  char db[TSDB_TABLE_ID_LEN] = {0};
H
hzcheng 已提交
3591

S
slguan 已提交
3592
  // remove the duplicated input table names
H
hzcheng 已提交
3593
  int32_t num = 0;
H
hjxilinx 已提交
3594 3595 3596
  char*   tableNameString = taosStringBuilderGetResult(sb, NULL);

  char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
H
hjxilinx 已提交
3597
  qsort(segments, num, POINTER_BYTES, tableNameCompar);
H
hzcheng 已提交
3598 3599 3600 3601 3602 3603 3604 3605 3606

  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 已提交
3607 3608 3609
  char* name = extractDBName(pTableMetaInfo->name, db);
  SSQLToken dbToken = {.type = TK_STRING, .z = name, .n = strlen(name)};
  
H
hzcheng 已提交
3610 3611
  for (int32_t i = 0; i < num; ++i) {
    if (i >= 1) {
H
hjxilinx 已提交
3612
      taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
H
hzcheng 已提交
3613
    }
H
hjxilinx 已提交
3614

B
Bomin Zhang 已提交
3615
    char      idBuf[TSDB_TABLE_ID_LEN] = {0};
S
slguan 已提交
3616
    int32_t   xlen = strlen(segments[i]);
H
hzcheng 已提交
3617 3618
    SSQLToken t = {.z = segments[i], .n = xlen, .type = TK_STRING};

3619
    int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
H
hzcheng 已提交
3620
    if (ret != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3621
      taosStringBuilderDestroy(&sb1);
H
hzcheng 已提交
3622
      tfree(segments);
H
hjxilinx 已提交
3623

3624
      invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
3625 3626
      return ret;
    }
H
hjxilinx 已提交
3627

H
hjxilinx 已提交
3628
    taosStringBuilderAppendString(&sb1, idBuf);
H
hzcheng 已提交
3629
  }
H
hjxilinx 已提交
3630

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

H
hjxilinx 已提交
3634
  taosStringBuilderDestroy(&sb1);
H
hzcheng 已提交
3635 3636 3637 3638
  tfree(segments);
  return TSDB_CODE_SUCCESS;
}

3639
static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
3640 3641 3642 3643 3644 3645
  SArray* pColList = pQueryInfo->colList;
  
  size_t num = taosArrayGetSize(pColList);
  
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColList, i);
3646

3647 3648
    for (int32_t j = 0; j < pCol->numOfFilters; ++j) {
      SColumnFilterInfo* pColFilter = &pCol->filterInfo[j];
S
slguan 已提交
3649 3650
      int32_t            lowerOptr = pColFilter->lowerRelOptr;
      int32_t            upperOptr = pColFilter->upperRelOptr;
3651

3652
      if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666
          (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;
}

3667
static int32_t getTimeRangeFromExpr(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
S
slguan 已提交
3668 3669
  const char* msg0 = "invalid timestamp";
  const char* msg1 = "only one time stamp window allowed";
H
hzcheng 已提交
3670 3671 3672 3673 3674

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

S
slguan 已提交
3675 3676
  if (!isExprDirectParentOfLeaftNode(pExpr)) {
    if (pExpr->nSQLOptr == TK_OR) {
3677
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3678
    }
H
hzcheng 已提交
3679

3680
    getTimeRangeFromExpr(pQueryInfo, pExpr->pLeft);
S
slguan 已提交
3681

3682
    return getTimeRangeFromExpr(pQueryInfo, pExpr->pRight);
S
slguan 已提交
3683 3684
  } else {
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
3685
    if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
3686
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3687 3688
    }

H
hjxilinx 已提交
3689
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3690
    STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3691
    
S
slguan 已提交
3692 3693
    tSQLExpr* pRight = pExpr->pRight;

H
hjxilinx 已提交
3694 3695
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
    if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
3696
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
3697 3698 3699
    }

    // update the timestamp query range
H
hjxilinx 已提交
3700 3701
    if (pQueryInfo->window.skey < win.skey) {
      pQueryInfo->window.skey = win.skey;
S
slguan 已提交
3702 3703
    }

H
hjxilinx 已提交
3704 3705
    if (pQueryInfo->window.ekey > win.ekey) {
      pQueryInfo->window.ekey = win.ekey;
S
slguan 已提交
3706 3707 3708 3709 3710 3711
    }
  }

  return TSDB_CODE_SUCCESS;
}

3712
static int32_t validateJoinExpr(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
S
slguan 已提交
3713 3714 3715 3716
  const char* msg1 = "super table join requires tags column";
  const char* msg2 = "timestamp join condition missing";
  const char* msg3 = "condition missing for join query";

3717 3718
  if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
    if (pQueryInfo->numOfTables == 1) {
S
slguan 已提交
3719 3720
      return TSDB_CODE_SUCCESS;
    } else {
3721
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
S
slguan 已提交
3722 3723 3724
    }
  }

H
hjxilinx 已提交
3725
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
3726
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // for stable join, tag columns
3727
                                                   // must be present for join
S
slguan 已提交
3728
    if (pCondExpr->pJoinExpr == NULL) {
3729
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3730 3731 3732 3733
    }
  }

  if (!pCondExpr->tsJoin) {
3734
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
3735 3736
  }

S
slguan 已提交
3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761
  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);
  }
}

3762
static void doAddJoinTagsColumnsIntoTagList(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
H
hjxilinx 已提交
3763
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
weixin_48148422's avatar
weixin_48148422 已提交
3764
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
S
slguan 已提交
3765
    SColumnIndex index = {0};
H
hjxilinx 已提交
3766

3767
    getColumnIndexByName(&pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index);
H
hjxilinx 已提交
3768
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3769 3770
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3771 3772
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
  
3773
    getColumnIndexByName(&pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index);
H
hjxilinx 已提交
3774
    pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
H
hjxilinx 已提交
3775 3776
  
    index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
3777
    tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
3778
  }
H
hjxilinx 已提交
3779
}
S
slguan 已提交
3780

3781
static int32_t getTagQueryCondExpr(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSQLExpr** pExpr) {
H
hjxilinx 已提交
3782
  int32_t ret = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
3783

3784 3785 3786 3787 3788 3789 3790
  if (pCondExpr->pTagCond == NULL) {
    return ret;
  }
  
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
    tSQLExpr* p1 = extractExprForSTable(pExpr, pQueryInfo, i);
    tExprNode* p = NULL;
3791 3792 3793
  
    SArray* colList = taosArrayInit(10, sizeof(SColIndex));
    ret = exprTreeFromSqlExpr(&p, p1, NULL, pQueryInfo, colList);
3794 3795 3796 3797 3798 3799 3800 3801 3802
    SBufferWriter bw = tbufInitWriter(NULL, false);

    TRY(0) {
      exprTreeToBinary(&bw, p);
    } CATCH(code) {
      tbufCloseWriter(&bw);
      UNUSED(code);
      // TODO: more error handling
    } END_TRY
3803
    
3804 3805 3806 3807 3808 3809 3810 3811 3812
    // add to source column list
    STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
    int64_t uid = pTableMetaInfo->pTableMeta->uid;
    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 已提交
3813
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
3814 3815
    }
    
3816
    tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
3817 3818 3819 3820
    doCompactQueryExpr(pExpr);
    
    tSQLExprDestroy(p1);
    tExprTreeDestroy(&p, NULL);
3821 3822
    
    taosArrayDestroy(colList);
H
hjxilinx 已提交
3823
  }
H
hjxilinx 已提交
3824

3825
  pCondExpr->pTagCond = NULL;
S
slguan 已提交
3826 3827
  return ret;
}
3828
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
H
hjxilinx 已提交
3829 3830 3831
  if (pExpr == NULL) {
    return TSDB_CODE_SUCCESS;
  }
H
hjxilinx 已提交
3832

H
hjxilinx 已提交
3833
  const char* msg1 = "invalid expression";
H
hjxilinx 已提交
3834
  const char* msg2 = "invalid filter expression";
H
hjxilinx 已提交
3835

H
hjxilinx 已提交
3836
  int32_t ret = TSDB_CODE_SUCCESS;
3837
  pQueryInfo->window = TSWINDOW_INITIALIZER;
S
slguan 已提交
3838

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

H
hjxilinx 已提交
3843
  if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
3844
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
3845 3846
  }

H
hjxilinx 已提交
3847
  int32_t type = 0;
3848
  if ((ret = getQueryCondExpr(pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3849 3850
    return ret;
  }
H
hjxilinx 已提交
3851

S
slguan 已提交
3852
  doCompactQueryExpr(pExpr);
H
hjxilinx 已提交
3853

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

S
slguan 已提交
3857
  // 1. check if it is a join query
3858
  if ((ret = validateJoinExpr(pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3859 3860
    return ret;
  }
H
hjxilinx 已提交
3861

S
slguan 已提交
3862
  // 2. get the query time range
3863
  if ((ret = getTimeRangeFromExpr(pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3864 3865
    return ret;
  }
H
hjxilinx 已提交
3866

S
slguan 已提交
3867
  // 3. get the tag query condition
3868
  if ((ret = getTagQueryCondExpr(pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
3869
    return ret;
S
slguan 已提交
3870
  }
H
hjxilinx 已提交
3871

S
slguan 已提交
3872
  // 4. get the table name query condition
3873
  if ((ret = getTablenameCond(pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3874 3875
    return ret;
  }
H
hjxilinx 已提交
3876

S
slguan 已提交
3877
  // 5. other column query condition
3878
  if ((ret = getColumnQueryCondInfo(pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3879 3880
    return ret;
  }
H
hjxilinx 已提交
3881

S
slguan 已提交
3882
  // 6. join condition
3883
  if ((ret = getJoinCondInfo(pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
S
slguan 已提交
3884
    return ret;
H
hzcheng 已提交
3885
  }
H
hjxilinx 已提交
3886

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

3890
  ret = setTableCondForSTableQuery(pQueryInfo, getAccountId(pSql), condExpr.pTableCond, condExpr.tableCondIndex, &sb);
H
hjxilinx 已提交
3891
  taosStringBuilderDestroy(&sb);
H
hjxilinx 已提交
3892

3893
  if (!validateFilterExpr(pQueryInfo)) {
H
hjxilinx 已提交
3894
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
3895
  }
H
hjxilinx 已提交
3896

3897
  doAddJoinTagsColumnsIntoTagList(pQueryInfo, &condExpr);
H
hjxilinx 已提交
3898

H
hjxilinx 已提交
3899
  cleanQueryExpr(&condExpr);
H
hzcheng 已提交
3900 3901 3902
  return ret;
}

H
hjxilinx 已提交
3903
int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
S
slguan 已提交
3904 3905 3906 3907 3908
  // this is join condition, do nothing
  if (pRight->nSQLOptr == TK_ID) {
    return TSDB_CODE_SUCCESS;
  }

S
slguan 已提交
3909 3910
  /*
   * filter primary ts filter expression like:
S
slguan 已提交
3911
   * where ts in ('2015-12-12 4:8:12')
S
slguan 已提交
3912 3913
   */
  if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
3914
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3915
  }
H
hzcheng 已提交
3916 3917 3918 3919

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

S
slguan 已提交
3922
    char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
H
hzcheng 已提交
3923 3924 3925 3926
    if (seg != NULL) {
      if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO) == TSDB_CODE_SUCCESS) {
        parsed = true;
      } else {
3927
        return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
3928
      }
S
slguan 已提交
3929 3930 3931 3932 3933
    } else {
      SSQLToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
      int32_t   len = tSQLGetToken(pRight->val.pz, &token.type);

      if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
3934
        return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
3935
      }
H
hzcheng 已提交
3936 3937 3938 3939
    }
  } 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 已提交
3940
     * need the time precision in metermeta to transfer the value in MICROSECOND
H
hzcheng 已提交
3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955
     *
     * 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
     */
3956
    tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
H
hzcheng 已提交
3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977

    /*
     * 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 已提交
3978
    win->ekey = val;
H
hzcheng 已提交
3979
  } else if (optr == TK_LT) {
H
hjxilinx 已提交
3980
    win->ekey = val - delta;
H
hzcheng 已提交
3981
  } else if (optr == TK_GT) {
H
hjxilinx 已提交
3982
    win->skey = val + delta;
H
hzcheng 已提交
3983
  } else if (optr == TK_GE) {
H
hjxilinx 已提交
3984
    win->skey = val;
H
hzcheng 已提交
3985
  } else if (optr == TK_EQ) {
H
hjxilinx 已提交
3986
    win->ekey = win->skey = val;
H
hzcheng 已提交
3987 3988 3989 3990
  }
  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
3991
// todo error !!!!
3992
int32_t tsRewriteFieldNameIfNecessary(SQueryInfo* pQueryInfo) {
S
slguan 已提交
3993 3994
  const char rep[] = {'(', ')', '*', ',', '.', '/', '\\', '+', '-', '%', ' '};

H
hjxilinx 已提交
3995 3996
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
    char* fieldName = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i)->name;
B
Bomin Zhang 已提交
3997
    for (int32_t j = 0; j < (TSDB_COL_NAME_LEN - 1) && fieldName[j] != 0; ++j) {
S
slguan 已提交
3998 3999 4000 4001 4002
      for (int32_t k = 0; k < tListLen(rep); ++k) {
        if (fieldName[j] == rep[k]) {
          fieldName[j] = '_';
          break;
        }
H
hzcheng 已提交
4003 4004
      }
    }
S
slguan 已提交
4005

H
hzcheng 已提交
4006 4007 4008 4009
    fieldName[TSDB_COL_NAME_LEN - 1] = 0;
  }

  // the column name may be identical, here check again
H
hjxilinx 已提交
4010 4011 4012
  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 已提交
4013
      if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) {
4014
        const char* msg = "duplicated column name in new table";
4015
        return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
4016 4017 4018 4019 4020 4021 4022
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

4023
int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
H
hzcheng 已提交
4024 4025 4026 4027
  tVariantList*     pFillToken = pQuerySQL->fillType;
  tVariantListItem* pItem = &pFillToken->a[0];

  const int32_t START_INTERPO_COL_IDX = 1;
4028 4029 4030 4031

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

  if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
4034
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4035
  }
H
hjxilinx 已提交
4036 4037 4038
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
4039 4040 4041
  if (pQueryInfo->fillVal == NULL) {
    pQueryInfo->fillVal = calloc(size, sizeof(int64_t));
    if (pQueryInfo->fillVal == NULL) {
4042
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4043 4044 4045
    }
  }

H
hzcheng 已提交
4046
  if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
4047
    pQueryInfo->fillType = TSDB_FILL_NONE;
H
hzcheng 已提交
4048
  } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
4049
    pQueryInfo->fillType = TSDB_FILL_NULL;
H
hjxilinx 已提交
4050 4051
    for (int32_t i = START_INTERPO_COL_IDX; i < size; ++i) {
      TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
4052 4053 4054 4055 4056
      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 已提交
4057 4058
    }
  } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
4059
    pQueryInfo->fillType = TSDB_FILL_PREV;
H
hzcheng 已提交
4060
  } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
4061
    pQueryInfo->fillType = TSDB_FILL_LINEAR;
H
hzcheng 已提交
4062
  } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
4063
    pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
H
hzcheng 已提交
4064 4065

    if (pFillToken->nExpr == 1) {
4066
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4067 4068 4069 4070 4071 4072
    }

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

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

H
hjxilinx 已提交
4076 4077
      if (numOfFillVal > size) {
        numOfFillVal = size;
H
hzcheng 已提交
4078 4079
      }
    } else {
H
hjxilinx 已提交
4080
      numOfFillVal = (pFillToken->nExpr > size) ? size : pFillToken->nExpr;
H
hzcheng 已提交
4081 4082 4083 4084 4085
    }

    int32_t j = 1;

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

4088
      if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4089
        setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
4090 4091
        continue;
      }
H
hjxilinx 已提交
4092

4093
      int32_t ret = tVariantDump(&pFillToken->a[j].pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4094
      if (ret != TSDB_CODE_SUCCESS) {
4095
        return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
4096 4097
      }
    }
H
hjxilinx 已提交
4098
    
4099
    if ((pFillToken->nExpr < size) || ((pFillToken->nExpr - 1 < size) && (tscIsPointInterpQuery(pQueryInfo)))) {
H
hzcheng 已提交
4100 4101
      tVariantListItem* lastItem = &pFillToken->a[pFillToken->nExpr - 1];

H
hjxilinx 已提交
4102 4103
      for (int32_t i = numOfFillVal; i < size; ++i) {
        TAOS_FIELD* pFields = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
H
hzcheng 已提交
4104 4105

        if (pFields->type == TSDB_DATA_TYPE_BINARY || pFields->type == TSDB_DATA_TYPE_NCHAR) {
4106
          setVardataNull((char*) &pQueryInfo->fillVal[i], pFields->type);
H
hjxilinx 已提交
4107
        } else {
4108
          tVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pFields->type, true);
H
hzcheng 已提交
4109 4110 4111 4112
        }
      }
    }
  } else {
4113
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4114 4115 4116 4117 4118
  }

  return TSDB_CODE_SUCCESS;
}

4119
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
4120
  /* set default timestamp order information for all queries */
4121
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
hjxilinx 已提交
4122
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4123

4124
  if (isTopBottomQuery(pQueryInfo)) {
4125
    pQueryInfo->order.order = TSDB_ORDER_ASC;
4126
    pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4127
  } else {
4128
    pQueryInfo->order.orderColId = -1;
H
hzcheng 已提交
4129 4130
  }

H
hjxilinx 已提交
4131
  /* for super table query, set default ascending order for group output */
weixin_48148422's avatar
weixin_48148422 已提交
4132
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
4133
    pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
H
hzcheng 已提交
4134 4135 4136
  }
}

S
slguan 已提交
4137
int32_t parseOrderbyClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
S
slguan 已提交
4138 4139 4140 4141
  const char* msg0 = "only support order by primary timestamp";
  const char* msg1 = "invalid column name";
  const char* msg2 = "only support order by primary timestamp and queried column";
  const char* msg3 = "only support order by primary timestamp and first tag in groupby clause";
H
hzcheng 已提交
4142

4143
  setDefaultOrderInfo(pQueryInfo);
H
hjxilinx 已提交
4144
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4145 4146 4147 4148 4149 4150

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

  tVariantList* pSortorder = pQuerySql->pSortOrder;
S
slguan 已提交
4151 4152 4153 4154 4155 4156 4157

  /*
   * 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 已提交
4158
  if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
4159
    if (pSortorder->nExpr > 1) {
4160
      return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
4161 4162 4163
    }
  } else {
    if (pSortorder->nExpr > 2) {
4164
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175
    }
  }

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

S
slguan 已提交
4176 4177 4178
  SSQLToken    columnName = {pVar->nLen, pVar->nType, pVar->pz};
  SColumnIndex index = {0};

weixin_48148422's avatar
weixin_48148422 已提交
4179
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {  // super table query
4180
    if (getColumnIndexByName(&columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4181
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
4182 4183 4184 4185
    }

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

H
hjxilinx 已提交
4187 4188
    if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
      int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4189
      
4190 4191 4192 4193
      // it is a tag column
      if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
      }
4194 4195
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      if (relTagIndex == pColIndex->colIndex) {
H
hzcheng 已提交
4196 4197
        orderByTags = true;
      }
S
slguan 已提交
4198 4199
    } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
      orderByTags = true;
H
hzcheng 已提交
4200 4201
    }

S
slguan 已提交
4202
    if (PRIMARYKEY_TIMESTAMP_COL_INDEX == index.columnIndex) {
H
hzcheng 已提交
4203 4204 4205
      orderByTS = true;
    }

4206 4207
    if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4208 4209 4210 4211 4212 4213
    } else {
      assert(!(orderByTags && orderByTS));
    }

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

4221
        pExpr = tscSqlExprGet(pQueryInfo, 1);
4222
        if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4223
          return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
4224
        }
4225

4226 4227
        pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
        pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
S
slguan 已提交
4228
        return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4229
      } else {
4230 4231
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4232 4233 4234 4235
      }
    }

    if (pSortorder->nExpr == 2) {
S
slguan 已提交
4236
      if (orderByTags) {
H
hjxilinx 已提交
4237
        pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
4238
        pQueryInfo->groupbyExpr.orderType = pQuerySql->pSortOrder->a[0].sortOrder;
S
slguan 已提交
4239
      } else {
4240 4241
        pQueryInfo->order.order = pSortorder->a[0].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
S
slguan 已提交
4242 4243
      }

H
hzcheng 已提交
4244 4245
      tVariant* pVar2 = &pSortorder->a[1].pVar;
      SSQLToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
4246
      if (getColumnIndexByName(&cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4247
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
4248 4249 4250
      }

      if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4251
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4252
      } else {
4253 4254
        pQueryInfo->order.order = pSortorder->a[1].sortOrder;
        pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
H
hzcheng 已提交
4255 4256 4257 4258
      }
    }

  } else {  // meter query
4259
    if (getColumnIndexByName(&columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4260
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4261 4262
    }

4263 4264
    if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4265 4266
    }

4267
    if (isTopBottomQuery(pQueryInfo)) {
H
hzcheng 已提交
4268
      /* order of top/bottom query in interval is not valid  */
4269
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4270
      assert(pExpr->functionId == TSDB_FUNC_TS);
H
hzcheng 已提交
4271

4272
      pExpr = tscSqlExprGet(pQueryInfo, 1);
4273
      if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
4274
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4275
      }
4276

4277 4278
      pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
      pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
H
hzcheng 已提交
4279 4280
      return TSDB_CODE_SUCCESS;
    }
4281

4282
    pQueryInfo->order.order = pQuerySql->pSortOrder->a[0].sortOrder;
H
hzcheng 已提交
4283 4284 4285 4286 4287 4288
  }

  return TSDB_CODE_SUCCESS;
}

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

4291 4292 4293 4294 4295 4296
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";
  const char* msg3 = "manipulation of tag available for super table";
  const char* msg4 = "set tag value only available for table";
  const char* msg5 = "only support add one tag";
  const char* msg6 = "column can only be modified by super table";
H
hjxilinx 已提交
4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312
  
  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";
  
S
slguan 已提交
4313
  SSqlCmd*        pCmd = &pSql->cmd;
H
hzcheng 已提交
4314
  SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
4315 4316
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

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

4319
  if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) {
4320
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
4321
  }
P
plum-lihui 已提交
4322

H
Haojun Liao 已提交
4323
  if (tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql) != TSDB_CODE_SUCCESS) {
4324
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hzcheng 已提交
4325 4326
  }

H
hjxilinx 已提交
4327
  int32_t ret = tscGetTableMeta(pSql, pTableMetaInfo);
H
hzcheng 已提交
4328 4329 4330 4331
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

H
hjxilinx 已提交
4332
  STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
4333

4334 4335
  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 已提交
4336
    if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
4337
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hzcheng 已提交
4338
    }
weixin_48148422's avatar
weixin_48148422 已提交
4339
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) {
4340
    return invalidSqlErrMsg(pQueryInfo->msg, msg4);
4341
  } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) &&
4342
             UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
4343
    return invalidSqlErrMsg(pQueryInfo->msg, msg6);
H
hzcheng 已提交
4344 4345
  }

4346
  if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
H
hzcheng 已提交
4347 4348
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4349
      return invalidSqlErrMsg(pQueryInfo->msg, msg5);
H
hzcheng 已提交
4350 4351 4352
    }

    if (!validateOneTags(pCmd, &pFieldList->p[0])) {
4353
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4354
    }
H
hjxilinx 已提交
4355 4356
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4357
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
H
hjxilinx 已提交
4358
    if (tscGetNumOfTags(pTableMeta) == 1) {
H
hjxilinx 已提交
4359
      return invalidSqlErrMsg(pQueryInfo->msg, msg7);
H
hzcheng 已提交
4360 4361 4362 4363
    }

    // numOfTags == 1
    if (pAlterSQL->varList->nExpr > 1) {
H
hjxilinx 已提交
4364
      return invalidSqlErrMsg(pQueryInfo->msg, msg8);
H
hzcheng 已提交
4365 4366 4367
    }

    tVariantListItem* pItem = &pAlterSQL->varList->a[0];
B
Bomin Zhang 已提交
4368
    if (pItem->pVar.nLen >= TSDB_COL_NAME_LEN) {
H
hjxilinx 已提交
4369
      return invalidSqlErrMsg(pQueryInfo->msg, msg9);
H
hzcheng 已提交
4370
    }
4371

4372
    SColumnIndex index = COLUMN_INDEX_INITIALIZER;
4373 4374
    SSQLToken    name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen, .type = TK_STRING};

4375
    if (getColumnIndexByName(&name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
4376
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4377 4378
    }

H
Haojun Liao 已提交
4379 4380
    int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
    if (index.columnIndex < numOfCols) {
H
hjxilinx 已提交
4381
      return invalidSqlErrMsg(pQueryInfo->msg, msg10);
H
Haojun Liao 已提交
4382
    } else if (index.columnIndex == numOfCols) {
H
hjxilinx 已提交
4383
      return invalidSqlErrMsg(pQueryInfo->msg, msg11);
H
hzcheng 已提交
4384 4385
    }

4386 4387
    char name1[128] = {0};
    strncpy(name1, pItem->pVar.pz, pItem->pVar.nLen);
H
hjxilinx 已提交
4388 4389 4390
  
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4391
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
H
hzcheng 已提交
4392 4393
    tVariantList* pVarList = pAlterSQL->varList;
    if (pVarList->nExpr > 2) {
4394
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4395 4396
    }

4397 4398 4399 4400
    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) {
H
hjxilinx 已提交
4401
      return invalidSqlErrMsg(pQueryInfo->msg, msg9);
H
hzcheng 已提交
4402 4403
    }

4404
    if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
H
hjxilinx 已提交
4405
      return invalidSqlErrMsg(pQueryInfo->msg, msg10);
4406
    }
H
hzcheng 已提交
4407

S
slguan 已提交
4408 4409
    SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER;
    SColumnIndex destIndex = COLUMN_INDEX_INITIALIZER;
H
hzcheng 已提交
4410

S
slguan 已提交
4411
    SSQLToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
4412
    if (getColumnIndexByName(&srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
4413
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4414 4415
    }

S
slguan 已提交
4416
    SSQLToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
4417
    if (getColumnIndexByName(&destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
4418
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4419 4420
    }

B
Bomin Zhang 已提交
4421
    char name[TSDB_COL_NAME_LEN] = {0};
H
hzcheng 已提交
4422
    strncpy(name, pVarList->a[0].pVar.pz, pVarList->a[0].pVar.nLen);
H
hjxilinx 已提交
4423 4424
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4425 4426 4427

    memset(name, 0, tListLen(name));
    strncpy(name, pVarList->a[1].pVar.pz, pVarList->a[1].pVar.nLen);
H
hjxilinx 已提交
4428 4429
    f = tscCreateField(TSDB_DATA_TYPE_INT, name, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
4430 4431
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
    // Note: update can only be applied to table not super table.
4432 4433 4434
    // the following is used to handle tags value for table created according to super table
    pCmd->command = TSDB_SQL_UPDATE_TAGS_VAL;
    
H
hzcheng 已提交
4435 4436 4437
    tVariantList* pVarList = pAlterSQL->varList;
    tVariant*     pTagName = &pVarList->a[0].pVar;

4438 4439
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
    SSQLToken    name = {.type = TK_STRING, .z = pTagName->pz, .n = pTagName->nLen};
4440
    if (getColumnIndexByName(&name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
4441
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4442 4443
    }

H
hjxilinx 已提交
4444
    if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) {
H
hjxilinx 已提交
4445
      return invalidSqlErrMsg(pQueryInfo->msg, msg12);
S
slguan 已提交
4446 4447
    }

H
hjxilinx 已提交
4448
    SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex);
4449
    if (tVariantDump(&pVarList->a[1].pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4450
      return invalidSqlErrMsg(pQueryInfo->msg, msg13);
H
hzcheng 已提交
4451
    }
4452
    
4453
    pAlterSQL->tagData.dataLen = pTagsSchema->bytes;
H
hzcheng 已提交
4454 4455

    // validate the length of binary
4456
    if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) &&
4457
        (pVarList->a[1].pVar.nLen + VARSTR_HEADER_SIZE) > pTagsSchema->bytes) {
H
hjxilinx 已提交
4458
      return invalidSqlErrMsg(pQueryInfo->msg, msg14);
H
hzcheng 已提交
4459
    }
H
hjxilinx 已提交
4460
  
4461 4462 4463
    int32_t size = sizeof(SUpdateTableTagValMsg) + pTagsSchema->bytes + TSDB_EXTRA_PAYLOAD_SIZE;
    if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
      tscError("%p failed to malloc for alter table msg", pSql);
4464
      return TSDB_CODE_TSC_OUT_OF_MEMORY;
4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488
    }

    SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) (pCmd->payload + tsRpcHeadSize);
    pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
    pUpdateMsg->tid = htonl(pTableMeta->sid);
    pUpdateMsg->uid = htobe64(pTableMeta->uid);
    pUpdateMsg->colId = htons(pTagsSchema->colId);
    pUpdateMsg->type  = htons(pTagsSchema->type);
    pUpdateMsg->bytes = htons(pTagsSchema->bytes);
    pUpdateMsg->tversion = htons(pTableMeta->tversion);
    
    tVariantDump(&pVarList->a[1].pVar, pUpdateMsg->data, pTagsSchema->type, true);
    
    int32_t len = 0;
    if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
      len = tDataTypeDesc[pTagsSchema->type].nSize;
    } else {
      len = varDataLen(pUpdateMsg->data);
    }
    
    pUpdateMsg->tagValLen = htonl(len);  // length may be changed after dump data
    
    int32_t total = sizeof(SUpdateTableTagValMsg) + len;
    pUpdateMsg->head.contLen = htonl(total);
H
hjxilinx 已提交
4489
    
4490
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
H
hzcheng 已提交
4491 4492
    tFieldList* pFieldList = pAlterSQL->pAddColumns;
    if (pFieldList->nField > 1) {
4493
      const char* msg = "only support add one column";
4494
      return invalidSqlErrMsg(pQueryInfo->msg, msg);
H
hzcheng 已提交
4495 4496 4497
    }

    if (!validateOneColumn(pCmd, &pFieldList->p[0])) {
4498
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4499
    }
H
hjxilinx 已提交
4500 4501
  
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[0]);
4502
  } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
H
hjxilinx 已提交
4503
    if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) {  //
H
hjxilinx 已提交
4504
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15);
H
hzcheng 已提交
4505 4506 4507
    }

    if (pAlterSQL->varList->nExpr > 1) {
H
hjxilinx 已提交
4508
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16);
H
hzcheng 已提交
4509 4510 4511 4512
    }

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

4513 4514
    SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
    SSQLToken    name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen};
4515
    if (getColumnIndexByName(&name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
4516
      return invalidSqlErrMsg(pQueryInfo->msg, msg17);
H
hzcheng 已提交
4517 4518
    }

4519
    if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
H
hjxilinx 已提交
4520
      return invalidSqlErrMsg(pQueryInfo->msg, msg18);
4521
    }
H
hzcheng 已提交
4522

B
Bomin Zhang 已提交
4523 4524
    char name1[TSDB_COL_NAME_LEN] = {0};
    tstrncpy(name1, pItem->pVar.pz, sizeof(name1));
H
hjxilinx 已提交
4525 4526
    TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypeDesc[TSDB_DATA_TYPE_INT].nSize);
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hzcheng 已提交
4527 4528 4529 4530 4531
  }

  return TSDB_CODE_SUCCESS;
}

4532
int32_t validateSqlFunctionInStreamSql(SQueryInfo* pQueryInfo) {
4533 4534
  const char* msg0 = "sample interval can not be less than 10ms.";
  const char* msg1 = "functions not allowed in select clause";
H
hzcheng 已提交
4535

4536
  if (pQueryInfo->intervalTime != 0 && pQueryInfo->intervalTime < 10) {
4537
    return invalidSqlErrMsg(pQueryInfo->msg, msg0);
H
hzcheng 已提交
4538
  }
H
hjxilinx 已提交
4539
  
H
hjxilinx 已提交
4540
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4541
  for (int32_t i = 0; i < size; ++i) {
4542
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hzcheng 已提交
4543
    if (!IS_STREAM_QUERY_VALID(aAggs[functId].nStatus)) {
4544
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4545 4546 4547 4548 4549 4550
    }
  }

  return TSDB_CODE_SUCCESS;
}

4551
int32_t validateFunctionsInIntervalOrGroupbyQuery(SQueryInfo* pQueryInfo) {
S
slguan 已提交
4552
  bool        isProjectionFunction = false;
4553
  const char* msg1 = "column projection is not compatible with interval";
H
hjxilinx 已提交
4554

H
hzcheng 已提交
4555
  // multi-output set/ todo refactor
H
hjxilinx 已提交
4556
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4557 4558
  
  for (int32_t k = 0; k < size; ++k) {
4559
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
H
hjxilinx 已提交
4560

4561 4562 4563
    // 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 已提交
4564
      for (int32_t j = 0; j < size; ++j) {
4565
        SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j);
4566 4567 4568 4569 4570
        if ((aAggs[pEx->functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) {
          hasSelectivity = true;
          break;
        }
      }
H
hjxilinx 已提交
4571

4572 4573 4574 4575
      if (hasSelectivity) {
        continue;
      }
    }
H
hjxilinx 已提交
4576

S
slguan 已提交
4577
    if (pExpr->functionId == TSDB_FUNC_PRJ || pExpr->functionId == TSDB_FUNC_DIFF ||
H
hjxilinx 已提交
4578
        pExpr->functionId == TSDB_FUNC_ARITHM) {
H
hzcheng 已提交
4579 4580 4581
      isProjectionFunction = true;
    }
  }
S
slguan 已提交
4582 4583

  if (isProjectionFunction) {
4584
    invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4585 4586
  }

4587
  return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4588 4589 4590
}

typedef struct SDNodeDynConfOption {
H
hjxilinx 已提交
4591 4592
  char*   name;  // command name
  int32_t len;   // name string length
H
hzcheng 已提交
4593 4594 4595 4596
} SDNodeDynConfOption;

int32_t validateDNodeConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 2 || pOptions->nTokens > 3) {
4597
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4598 4599
  }

4600 4601 4602 4603 4604 4605 4606
  const int DNODE_DYNAMIC_CFG_OPTIONS_SIZE = 17;
  const SDNodeDynConfOption DNODE_DYNAMIC_CFG_OPTIONS[] = {
      {"resetLog", 8},       {"resetQueryCache", 15},  {"debugFlag", 9},     {"mDebugFlag", 10},
      {"dDebugFlag", 10},    {"sdbDebugFlag", 12},     {"vDebugFlag", 10},   {"cDebugFlag", 10},
      {"httpDebugFlag", 13}, {"monitorDebugFlag", 16}, {"rpcDebugFlag", 12}, {"uDebugFlag", 10},
      {"tmrDebugFlag", 12},  {"qDebugflag", 10},       {"sDebugflag", 10},   {"tsdbDebugFlag", 13},
      {"monitor", 7}};
H
hzcheng 已提交
4607 4608 4609 4610 4611 4612

  SSQLToken* pOptionToken = &pOptions->a[1];

  if (pOptions->nTokens == 2) {
    // reset log and reset query cache does not need value
    for (int32_t i = 0; i < 2; ++i) {
H
hjxilinx 已提交
4613
      const SDNodeDynConfOption* pOption = &DNODE_DYNAMIC_CFG_OPTIONS[i];
H
hzcheng 已提交
4614 4615 4616 4617
      if ((strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0) && (pOption->len == pOptionToken->n)) {
        return TSDB_CODE_SUCCESS;
      }
    }
4618 4619
  } else if ((strncasecmp(DNODE_DYNAMIC_CFG_OPTIONS[DNODE_DYNAMIC_CFG_OPTIONS_SIZE - 1].name, pOptionToken->z, pOptionToken->n) == 0) &&
             (DNODE_DYNAMIC_CFG_OPTIONS[DNODE_DYNAMIC_CFG_OPTIONS_SIZE - 1].len == pOptionToken->n)) {
S
slguan 已提交
4620 4621 4622
    SSQLToken* pValToken = &pOptions->a[2];
    int32_t    val = strtol(pValToken->z, NULL, 10);
    if (val != 0 && val != 1) {
4623
      return TSDB_CODE_TSC_INVALID_SQL;  // options value is invalid
S
slguan 已提交
4624 4625
    }
    return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4626 4627 4628 4629 4630 4631
  } else {
    SSQLToken* pValToken = &pOptions->a[2];

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      /* options value is out of valid range */
4632
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4633 4634
    }

4635
    for (int32_t i = 2; i < DNODE_DYNAMIC_CFG_OPTIONS_SIZE - 1; ++i) {
H
hjxilinx 已提交
4636
      const SDNodeDynConfOption* pOption = &DNODE_DYNAMIC_CFG_OPTIONS[i];
H
hzcheng 已提交
4637 4638 4639 4640 4641 4642 4643 4644

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

4645
  return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4646 4647
}

S
slguan 已提交
4648 4649
int32_t validateLocalConfig(tDCLSQL* pOptions) {
  if (pOptions->nTokens < 1 || pOptions->nTokens > 2) {
4650
    return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4651 4652
  }

H
hjxilinx 已提交
4653 4654
  SDNodeDynConfOption LOCAL_DYNAMIC_CFG_OPTIONS[6] = {{"resetLog", 8},    {"rpcDebugFlag", 12}, {"tmrDebugFlag", 12},
                                                      {"cDebugFlag", 10}, {"uDebugFlag", 10},   {"debugFlag", 9}};
S
slguan 已提交
4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671

  SSQLToken* pOptionToken = &pOptions->a[0];

  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 {
    SSQLToken* pValToken = &pOptions->a[1];

    int32_t val = strtol(pValToken->z, NULL, 10);
    if (val < 131 || val > 199) {
      // options value is out of valid range
4672
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4673 4674 4675 4676 4677 4678 4679 4680 4681 4682
    }

    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;
      }
    }
  }
4683
  return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
4684 4685
}

H
hzcheng 已提交
4686 4687 4688
int32_t validateColumnName(char* name) {
  bool ret = isKeyWord(name, strlen(name));
  if (ret) {
4689
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4690 4691
  }

S
slguan 已提交
4692
  SSQLToken token = {.z = name};
H
hzcheng 已提交
4693 4694 4695
  token.n = tSQLGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
4696
    return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4697 4698 4699 4700
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
H
Haojun Liao 已提交
4701
    token.n = strtrim(token.z);
H
hzcheng 已提交
4702 4703 4704

    int32_t k = tSQLGetToken(token.z, &token.type);
    if (k != token.n) {
4705
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4706 4707 4708 4709 4710
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
4711
      return TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
4712 4713 4714 4715 4716 4717
    }
  }

  return TSDB_CODE_SUCCESS;
}

4718 4719
bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
4720 4721 4722
    return true;
  }

H
hjxilinx 已提交
4723
  return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
H
hzcheng 已提交
4724 4725
}

4726
int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* pQuerySql, SSqlObj* pSql) {
H
hjxilinx 已提交
4727
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
4728

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

H
hzcheng 已提交
4734
  // handle the limit offset value, validate the limit
4735
  pQueryInfo->limit = pQuerySql->limit;
4736
  pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4737
  pQueryInfo->slimit = pQuerySql->slimit;
4738 4739 4740 4741
  
  tscTrace("%p limit:%d, offset:%" PRId64 " slimit:%d, soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
      pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
  
4742
  if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
4743
    return invalidSqlErrMsg(pQueryInfo->msg, msg0);
S
slguan 已提交
4744 4745
  }

4746
  if (pQueryInfo->limit.limit == 0) {
S
slguan 已提交
4747
    tscTrace("%p limit 0, no output result", pSql);
4748
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4749
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
4750 4751
  }

H
hjxilinx 已提交
4752
  // todo refactor
weixin_48148422's avatar
weixin_48148422 已提交
4753
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
4754
    if (!tscQueryTags(pQueryInfo)) {  // local handle the super table tag query
4755
      if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
H
hjxilinx 已提交
4756 4757 4758
        if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
          return invalidSqlErrMsg(pQueryInfo->msg, msg3);
        }
H
hjxilinx 已提交
4759

4760
        // for projection query on super table, all queries are subqueries
H
hjxilinx 已提交
4761 4762
        if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
            !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
4763
          pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
4764
        }
S
slguan 已提交
4765
      }
H
hzcheng 已提交
4766 4767
    }

4768
    if (pQueryInfo->slimit.limit == 0) {
4769
      tscTrace("%p slimit 0, no output result", pSql);
4770
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hzcheng 已提交
4771 4772 4773 4774
      return TSDB_CODE_SUCCESS;
    }

    /*
4775 4776 4777 4778
     * 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 已提交
4779
     */
H
hjxilinx 已提交
4780
    int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex);
H
hzcheng 已提交
4781 4782 4783 4784
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }

S
slguan 已提交
4785
    // No tables included. No results generated. Query results are empty.
4786 4787
    if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
      tscTrace("%p no table in super table, no output result", pSql);
4788
      pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
H
hjxilinx 已提交
4789
      return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
4790 4791 4792
    }

    // keep original limitation value in globalLimit
4793
    pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
4794
    pQueryInfo->prjOffset = pQueryInfo->limit.offset;
H
hjxilinx 已提交
4795

4796 4797 4798 4799 4800 4801 4802 4803 4804
    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 已提交
4805

4806 4807
      pQueryInfo->limit.offset = 0;
    }
H
hzcheng 已提交
4808
  } else {
4809 4810
    if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hzcheng 已提交
4811
    }
H
hjxilinx 已提交
4812
  
H
hjxilinx 已提交
4813
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
4814 4815 4816
    
    bool hasTags = false;
    bool hasOtherFunc = false;
S
slguan 已提交
4817
    // filter the query functions operating on "tbname" column that are not supported by normal columns.
H
hjxilinx 已提交
4818
    for (int32_t i = 0; i < size; ++i) {
4819
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
4820 4821 4822 4823
      if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
        hasTags = true;
      } else {
        hasOtherFunc = true;
H
hzcheng 已提交
4824 4825
      }
    }
4826 4827 4828 4829
    
    if (hasTags && hasOtherFunc) {
      return invalidSqlErrMsg(pQueryInfo->msg, msg2);
    }
H
hzcheng 已提交
4830 4831 4832 4833
  }

  return TSDB_CODE_SUCCESS;
}
4834

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

4838 4839 4840
  pMsg->daysToKeep = htonl(-1);
  pMsg->daysToKeep1 = htonl(-1);
  pMsg->daysToKeep2 = htonl(-1);
H
hjxilinx 已提交
4841

H
hjxilinx 已提交
4842 4843 4844
  tVariantList* pKeep = pCreateDb->keep;
  if (pKeep != NULL) {
    switch (pKeep->nExpr) {
S
slguan 已提交
4845
      case 1:
H
hjxilinx 已提交
4846
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
4847 4848
        break;
      case 2: {
H
hjxilinx 已提交
4849 4850
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl(pKeep->a[1].pVar.i64Key);
4851 4852 4853
        break;
      }
      case 3: {
H
hjxilinx 已提交
4854 4855 4856
        pMsg->daysToKeep = htonl(pKeep->a[0].pVar.i64Key);
        pMsg->daysToKeep1 = htonl(pKeep->a[1].pVar.i64Key);
        pMsg->daysToKeep2 = htonl(pKeep->a[2].pVar.i64Key);
4857 4858
        break;
      }
4859
      default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
4860 4861
    }
  }
H
hjxilinx 已提交
4862

H
hjxilinx 已提交
4863 4864
  return TSDB_CODE_SUCCESS;
}
4865

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

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

H
hjxilinx 已提交
4871
  SSQLToken* pToken = &pCreateDbInfo->precision;
4872 4873
  if (pToken->n > 0) {
    pToken->n = strdequote(pToken->z);
H
hjxilinx 已提交
4874

4875 4876 4877 4878 4879
    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 已提交
4880
               strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) {
4881 4882
      pMsg->precision = TSDB_TIME_PRECISION_MICRO;
    } else {
4883
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
4884 4885
    }
  }
H
hjxilinx 已提交
4886

H
hjxilinx 已提交
4887 4888
  return TSDB_CODE_SUCCESS;
}
4889

4890
static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
H
hjxilinx 已提交
4891 4892
  pMsg->maxTables = htonl(pCreateDb->maxTablesPerVnode);
  pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
4893
  pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
H
hjxilinx 已提交
4894
  pMsg->daysPerFile = htonl(pCreateDb->daysPerFile);
S
slguan 已提交
4895
  pMsg->commitTime = htonl(pCreateDb->commitTime);
H
hjxilinx 已提交
4896 4897
  pMsg->minRowsPerFileBlock = htonl(pCreateDb->minRowsPerBlock);
  pMsg->maxRowsPerFileBlock = htonl(pCreateDb->maxRowsPerBlock);
S
slguan 已提交
4898
  pMsg->compression = pCreateDb->compressionLevel;
H
hjxilinx 已提交
4899
  pMsg->walLevel = (char)pCreateDb->walLevel;
H
hjxilinx 已提交
4900
  pMsg->replications = pCreateDb->replica;
4901
  pMsg->ignoreExist = pCreateDb->ignoreExists;
H
hjxilinx 已提交
4902 4903 4904
}

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

H
hjxilinx 已提交
4908
  if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
4909
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
4910
  }
H
hjxilinx 已提交
4911

H
hjxilinx 已提交
4912
  if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
4913
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
4914
  }
H
hjxilinx 已提交
4915

H
hjxilinx 已提交
4916
  if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) {
4917
    return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
4918
  }
H
hjxilinx 已提交
4919

4920
  return TSDB_CODE_SUCCESS;
H
huili 已提交
4921
}
S
slguan 已提交
4922

4923
void tscAddTimestampColumn(SQueryInfo* pQueryInfo, int16_t functionId, int16_t tableIndex) {
S
slguan 已提交
4924 4925
  // the first column not timestamp column, add it
  SSqlExpr* pExpr = NULL;
H
hjxilinx 已提交
4926
  if (tscSqlExprNumOfExprs(pQueryInfo) > 0) {
4927
    pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
4928 4929 4930 4931 4932
  }

  if (pExpr == NULL || pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX || pExpr->functionId != functionId) {
    SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};

H
hjxilinx 已提交
4933
    pExpr = tscSqlExprInsert(pQueryInfo, 0, functionId, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE, false);
S
slguan 已提交
4934 4935 4936 4937 4938
    pExpr->colInfo.flag = TSDB_COL_NORMAL;

    // NOTE: tag column does not add to source column list
    SColumnList ids = getColumnList(1, tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX);

H
hjxilinx 已提交
4939
    insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, "ts", pExpr);
S
slguan 已提交
4940 4941 4942
  }
}

4943 4944
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
  SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
4945

4946 4947
  if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
H
hjxilinx 已提交
4948
    size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
4949 4950
  
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, size - 1);
4951

S
slguan 已提交
4952
    if (pExpr->functionId != TSDB_FUNC_TAG) {
H
hjxilinx 已提交
4953
      STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
4954
      int16_t         columnInfo = tscGetJoinTagColIndexByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid);
4955
      SColumnIndex    index = {.tableIndex = 0, .columnIndex = columnInfo};
H
hjxilinx 已提交
4956
      SSchema*        pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
4957 4958 4959 4960

      int16_t type = pSchema[index.columnIndex].type;
      int16_t bytes = pSchema[index.columnIndex].bytes;
      char*   name = pSchema[index.columnIndex].name;
H
hjxilinx 已提交
4961
  
4962
      pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
S
slguan 已提交
4963 4964 4965 4966
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
      SColumnList ids = {0};
H
hjxilinx 已提交
4967
      insertResultField(pQueryInfo, size, &ids, bytes, type, name, pExpr);
S
slguan 已提交
4968 4969 4970

      int32_t relIndex = index.columnIndex;

4971
      pExpr->colInfo.colIndex = relIndex;
4972 4973
      SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
      pColIndex->colIndex = relIndex;
S
slguan 已提交
4974

4975
      index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex};
H
hjxilinx 已提交
4976
      tscColumnListInsert(pTableMetaInfo->tagColList, &index);
S
slguan 已提交
4977 4978 4979 4980
    }
  }
}

H
hjxilinx 已提交
4981 4982 4983
// limit the output to be 1 for each state value
static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
  int32_t outputRow = 1;
H
hjxilinx 已提交
4984
  tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT);
H
hjxilinx 已提交
4985 4986 4987
  pExpr->numOfParams = 1;
}

4988
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
4989 4990 4991
  SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
  int32_t index = pColIndex->colIndex;
  
H
hjxilinx 已提交
4992
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
S
slguan 已提交
4993

H
hjxilinx 已提交
4994
  SSchema*     pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index);
S
slguan 已提交
4995
  SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = index};
H
hjxilinx 已提交
4996 4997
  
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
4998 4999
  SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_PRJ, &colIndex, pSchema->type, pSchema->bytes,
      pSchema->bytes, false);
S
slguan 已提交
5000 5001

  pExpr->colInfo.flag = TSDB_COL_NORMAL;
H
hjxilinx 已提交
5002
  doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5003

S
slguan 已提交
5004 5005 5006 5007 5008
  // NOTE: tag column does not add to source column list
  SColumnList list = {0};
  list.num = 1;
  list.ids[0] = colIndex;

5009
  insertResultField(pQueryInfo, size, &list, pSchema->bytes, pSchema->type, pSchema->name, pExpr);
H
hjxilinx 已提交
5010 5011
  SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, size - 1);
  pInfo->visible = false;
S
slguan 已提交
5012 5013
}

5014
static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5015
  int32_t tagLength = 0;
H
hjxilinx 已提交
5016
  
H
hjxilinx 已提交
5017
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5018 5019
  
  for (int32_t i = 0; i < size; ++i) {
5020
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5021 5022 5023 5024 5025 5026 5027 5028 5029
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ || pExpr->functionId == TSDB_FUNC_TAG) {
      pExpr->functionId = TSDB_FUNC_TAG_DUMMY;
      tagLength += pExpr->resBytes;
    } else if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
      pExpr->functionId = TSDB_FUNC_TS_DUMMY;
      tagLength += pExpr->resBytes;
    }
  }

H
hjxilinx 已提交
5030
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5031
  SSchema*        pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5032

H
hjxilinx 已提交
5033
  for (int32_t i = 0; i < size; ++i) {
5034
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5035
    if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) {
5036
      SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
S
slguan 已提交
5037
      getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, pExpr->param[0].i64Key, &pExpr->resType,
5038
                        &pExpr->resBytes, &pExpr->interBytes, tagLength, true);
S
slguan 已提交
5039 5040 5041 5042
    }
  }
}

5043
static void doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5044
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5045 5046
  
  for (int32_t i = 0; i < size; ++i) {
5047
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hjxilinx 已提交
5048 5049
    if (pExpr->functionId == TSDB_FUNC_PRJ) {
      bool qualifiedCol = false;
5050
      for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5051 5052 5053
        SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
  
        if (pExpr->colInfo.colId == pColIndex->colId) {
H
hjxilinx 已提交
5054
          qualifiedCol = true;
H
hjxilinx 已提交
5055
          doLimitOutputNormalColOfGroupby(pExpr);
H
hjxilinx 已提交
5056 5057 5058 5059
          pExpr->numOfParams = 1;
          break;
        }
      }
H
hjxilinx 已提交
5060

H
hjxilinx 已提交
5061 5062 5063 5064 5065
      assert(qualifiedCol);
    }
  }
}

S
slguan 已提交
5066 5067
static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) {
  for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
5068 5069 5070
    SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j);
  
    if (columnId == pColIndex->colId && pColIndex->flag == TSDB_COL_TAG) {
S
slguan 已提交
5071 5072 5073 5074 5075 5076 5077
      return true;
    }
  }

  return false;
}

5078
static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5079 5080
  bool hasTagPrj = false;
  bool hasColumnPrj = false;
H
hjxilinx 已提交
5081
  
H
hjxilinx 已提交
5082
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5083
  for (int32_t i = 0; i < size; ++i) {
5084
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095
    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
5096
static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5097 5098
  bool allInGroupby = true;

H
hjxilinx 已提交
5099 5100
  size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  for (int32_t i = 0; i < size; ++i) {
5101
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5102 5103 5104 5105
    if (pExpr->functionId != TSDB_FUNC_TAGPRJ) {
      continue;
    }

5106
    if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) {
S
slguan 已提交
5107 5108 5109 5110 5111 5112 5113 5114 5115
      allInGroupby = false;
      break;
    }
  }

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

5116
static void updateTagPrjFunction(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
5117
  size_t size = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5118 5119
  
  for (int32_t i = 0; i < size; ++i) {
5120
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132
    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.
 */
5133
static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5134
  const char* msg1 = "only one selectivity function allowed in presence of tags function";
H
hjxilinx 已提交
5135
  const char* msg3 = "aggregation function should not be mixed up with projection";
H
hjxilinx 已提交
5136

S
slguan 已提交
5137 5138 5139 5140
  bool    tagColExists = false;
  int16_t numOfSelectivity = 0;
  int16_t numOfAggregation = 0;

H
hjxilinx 已提交
5141
  size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
H
hjxilinx 已提交
5142
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5143
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
S
slguan 已提交
5144 5145 5146 5147 5148 5149
    if (pExpr->functionId == TSDB_FUNC_TAGPRJ ||
        (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
      tagColExists = true;
      break;
    }
  }
H
hjxilinx 已提交
5150

H
hjxilinx 已提交
5151
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
hjxilinx 已提交
5152
    SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
H
hjxilinx 已提交
5153 5154
  
    int16_t functionId = pExpr->functionId;
5155
    if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS ||
H
hjxilinx 已提交
5156
        functionId == TSDB_FUNC_ARITHM) {
H
hjxilinx 已提交
5157
      continue;
S
slguan 已提交
5158
    }
H
hjxilinx 已提交
5159

H
hjxilinx 已提交
5160 5161 5162 5163 5164 5165
    if ((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    } else {
      numOfAggregation++;
    }
  }
H
hjxilinx 已提交
5166

H
hjxilinx 已提交
5167
  if (tagColExists) {  // check if the selectivity function exists
S
slguan 已提交
5168 5169
    // 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.
5170
    if (numOfAggregation > 0) {
5171
      return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5172 5173 5174 5175 5176 5177
    }

    /*
     *  if numOfSelectivity equals to 0, it is a super table projection query
     */
    if (numOfSelectivity == 1) {
5178 5179
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
S
slguan 已提交
5180 5181 5182 5183 5184
    } 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 已提交
5185 5186
      for (int32_t i = 0; i < numOfExprs; ++i) {
        
5187
        int16_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
5188 5189 5190 5191 5192
        if (functionId == TSDB_FUNC_TAGPRJ) {
          continue;
        }

        if (((aAggs[functionId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) && (functionId != TSDB_FUNC_LAST_ROW)) {
5193
          return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5194 5195 5196
        }
      }

5197 5198
      doUpdateSqlFunctionForTagPrj(pQueryInfo);
      doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5199 5200
    }
  } else {
5201
    if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) {
5202 5203
      if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
        return invalidSqlErrMsg(pQueryInfo->msg, msg3);
H
hjxilinx 已提交
5204
      }
H
hjxilinx 已提交
5205

H
hjxilinx 已提交
5206 5207
      if (numOfAggregation > 0 || numOfSelectivity > 0) {
        // clear the projection type flag
5208 5209
        pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY);
        doUpdateSqlFunctionForColPrj(pQueryInfo);
H
hjxilinx 已提交
5210
      }
S
slguan 已提交
5211 5212 5213 5214 5215 5216
    }
  }

  return TSDB_CODE_SUCCESS;
}

5217
static int32_t doAddGroupbyColumnsOnDemand(SQueryInfo* pQueryInfo) {
S
slguan 已提交
5218 5219
  const char* msg2 = "interval not allowed in group by normal column";

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

H
hjxilinx 已提交
5222
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
S
slguan 已提交
5223 5224 5225 5226
  int16_t  bytes = 0;
  int16_t  type = 0;
  char*    name = NULL;

5227
  for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
5228 5229
    SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
  
5230
    int16_t colIndex = pColIndex->colIndex;
5231
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
H
Haojun Liao 已提交
5232
      SSchema s = tGetTableNameColumnSchema();
H
Haojun Liao 已提交
5233
      type  = s.type;
H
Haojun Liao 已提交
5234
      bytes = s.bytes;
H
Haojun Liao 已提交
5235
      name  = s.name;
S
slguan 已提交
5236
    } else {
5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247
      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 已提交
5248
    }
H
hjxilinx 已提交
5249 5250 5251
  
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
  
S
slguan 已提交
5252
    if (TSDB_COL_IS_TAG(pColIndex->flag)) {
5253
      SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex};
5254
      SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
5255
      
B
Bomin Zhang 已提交
5256 5257
      memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName));
      tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
5258
      
S
slguan 已提交
5259 5260 5261
      pExpr->colInfo.flag = TSDB_COL_TAG;

      // NOTE: tag column does not add to source column list
5262
      SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
5263
      insertResultField(pQueryInfo, size, &ids, bytes, type, name, pExpr);
S
slguan 已提交
5264 5265
    } else {
      // if this query is "group by" normal column, interval is not allowed
5266
      if (pQueryInfo->intervalTime > 0) {
5267
        return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
5268 5269 5270
      }

      bool hasGroupColumn = false;
H
hjxilinx 已提交
5271
      for (int32_t j = 0; j < size; ++j) {
5272
        SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j);
S
slguan 已提交
5273 5274 5275 5276 5277 5278 5279 5280 5281 5282
        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) {
5283
        doAddGroupColumnForSubquery(pQueryInfo, i);
S
slguan 已提交
5284 5285 5286 5287 5288 5289 5290
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

5291
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
S
slguan 已提交
5292
  const char* msg1 = "functions/columns not allowed in group by query";
H
hjxilinx 已提交
5293
  const char* msg2 = "projection query on columns not allowed";
S
slguan 已提交
5294
  const char* msg3 = "group by not allowed on projection query";
H
hjxilinx 已提交
5295
  const char* msg4 = "retrieve tags not compatible with group by or interval query";
S
slguan 已提交
5296 5297

  // only retrieve tags, group by is not supportted
H
hjxilinx 已提交
5298
  if (tscQueryTags(pQueryInfo)) {
5299
    if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->intervalTime > 0) {
5300
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
S
slguan 已提交
5301 5302 5303 5304 5305
    } else {
      return TSDB_CODE_SUCCESS;
    }
  }

5306
  if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
S
slguan 已提交
5307
    // check if all the tags prj columns belongs to the group by columns
5308 5309 5310
    if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) {
      updateTagPrjFunction(pQueryInfo);
      return doAddGroupbyColumnsOnDemand(pQueryInfo);
S
slguan 已提交
5311 5312 5313
    }

    // check all query functions in selection clause, multi-output functions are not allowed
H
hjxilinx 已提交
5314 5315
    size_t size = tscSqlExprNumOfExprs(pQueryInfo);
    for (int32_t i = 0; i < size; ++i) {
5316
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
5317 5318 5319 5320 5321 5322
      int32_t   functId = pExpr->functionId;

      /*
       * group by normal columns.
       * Check if the column projection is identical to the group by column or not
       */
5323
      if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
S
slguan 已提交
5324
        bool qualified = false;
5325
        for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
5326
          SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
S
slguan 已提交
5327 5328 5329 5330 5331 5332 5333
          if (pColIndex->colId == pExpr->colInfo.colId) {
            qualified = true;
            break;
          }
        }

        if (!qualified) {
5334
          return invalidSqlErrMsg(pQueryInfo->msg, msg2);
S
slguan 已提交
5335 5336 5337 5338
        }
      }

      if (IS_MULTIOUTPUT(aAggs[functId].nStatus) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM &&
H
hjxilinx 已提交
5339
          functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) {
5340
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5341 5342
      }

5343
      if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
5344
        return invalidSqlErrMsg(pQueryInfo->msg, msg1);
S
slguan 已提交
5345 5346 5347
      }
    }

5348
    if (checkUpdateTagPrjFunctions(pQueryInfo) != TSDB_CODE_SUCCESS) {
5349
      return TSDB_CODE_TSC_INVALID_SQL;
S
slguan 已提交
5350 5351 5352 5353 5354 5355
    }

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

H
hjxilinx 已提交
5360
    // projection query on super table does not compatible with "group by" syntax
5361
    if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
5362
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
S
slguan 已提交
5363
    }
H
hjxilinx 已提交
5364

H
hjxilinx 已提交
5365
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
5366
  } else {
5367
    return checkUpdateTagPrjFunctions(pQueryInfo);
S
slguan 已提交
5368 5369
  }
}
H
hjxilinx 已提交
5370

5371
int32_t doLocalQueryProcess(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
H
hjxilinx 已提交
5372 5373 5374
  const char* msg1 = "only one expression allowed";
  const char* msg2 = "invalid expression in select clause";
  const char* msg3 = "invalid function";
H
hjxilinx 已提交
5375

H
hjxilinx 已提交
5376 5377
  tSQLExprList* pExprList = pQuerySql->pSelection;
  if (pExprList->nExpr != 1) {
5378
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
H
hjxilinx 已提交
5379
  }
H
hjxilinx 已提交
5380

H
hjxilinx 已提交
5381 5382
  tSQLExpr* pExpr = pExprList->a[0].pNode;
  if (pExpr->operand.z == NULL) {
5383
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
H
hjxilinx 已提交
5384
  }
H
hjxilinx 已提交
5385

H
hjxilinx 已提交
5386
  // TODO redefine the function
H
hjxilinx 已提交
5387 5388 5389 5390 5391 5392
  SDNodeDynConfOption functionsInfo[5] = {{"database()", 10},
                                          {"server_version()", 16},
                                          {"server_status()", 15},
                                          {"client_version()", 16},
                                          {"current_user()", 14}};

H
hjxilinx 已提交
5393
  int32_t index = -1;
H
hjxilinx 已提交
5394
  for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
H
hjxilinx 已提交
5395
    if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
H
hjxilinx 已提交
5396
        functionsInfo[i].len == pExpr->operand.n) {
H
hjxilinx 已提交
5397 5398 5399 5400
      index = i;
      break;
    }
  }
H
hjxilinx 已提交
5401 5402 5403

  switch (index) {
    case 0:
H
Haojun Liao 已提交
5404
      pQueryInfo->command = TSDB_SQL_CURRENT_DB;break;
H
hjxilinx 已提交
5405
    case 1:
H
Haojun Liao 已提交
5406 5407 5408
      pQueryInfo->command = TSDB_SQL_SERV_VERSION;break;
      case 2:
      pQueryInfo->command = TSDB_SQL_SERV_STATUS;break;
H
hjxilinx 已提交
5409
    case 3:
H
Haojun Liao 已提交
5410
      pQueryInfo->command = TSDB_SQL_CLI_VERSION;break;
H
hjxilinx 已提交
5411
    case 4:
H
Haojun Liao 已提交
5412
      pQueryInfo->command = TSDB_SQL_CURRENT_USER;break;
5413
    default: { return invalidSqlErrMsg(pQueryInfo->msg, msg3); }
H
hjxilinx 已提交
5414
  }
5415 5416 5417 5418 5419 5420
  
  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 已提交
5421
  tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
H
Haojun Liao 已提交
5422 5423
  
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
5424
}
H
hjxilinx 已提交
5425 5426

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

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

H
hjxilinx 已提交
5435
  if (pCreate->replications != -1 &&
S
slguan 已提交
5436
      (pCreate->replications < TSDB_MIN_REPLICA_NUM || pCreate->replications > TSDB_MAX_REPLICA_NUM)) {
H
hjxilinx 已提交
5437
    snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications,
S
slguan 已提交
5438
             TSDB_MIN_REPLICA_NUM, TSDB_MAX_REPLICA_NUM);
5439
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5440
  }
H
hjxilinx 已提交
5441

H
hjxilinx 已提交
5442
  int32_t val = htonl(pCreate->daysPerFile);
S
slguan 已提交
5443
  if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) {
H
hjxilinx 已提交
5444
    snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val,
S
slguan 已提交
5445
             TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE);
5446
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5447
  }
H
hjxilinx 已提交
5448

H
hjxilinx 已提交
5449 5450 5451 5452
  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);
5453
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5454
  }
H
hjxilinx 已提交
5455

H
hjxilinx 已提交
5456
  val = htonl(pCreate->maxTables);
S
slguan 已提交
5457
  if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) {
H
hjxilinx 已提交
5458
    snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val,
S
slguan 已提交
5459
             TSDB_MIN_TABLES, TSDB_MAX_TABLES);
5460
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5461
  }
H
hjxilinx 已提交
5462 5463 5464 5465

  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);
5466
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5467
  }
H
hjxilinx 已提交
5468

H
hjxilinx 已提交
5469
  val = htonl(pCreate->commitTime);
S
slguan 已提交
5470
  if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) {
H
hjxilinx 已提交
5471
    snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val,
S
slguan 已提交
5472
             TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME);
5473
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5474
  }
H
hjxilinx 已提交
5475

H
hjxilinx 已提交
5476
  if (pCreate->compression != -1 &&
S
slguan 已提交
5477
      (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) {
H
hjxilinx 已提交
5478
    snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression,
S
slguan 已提交
5479
             TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL);
5480
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
H
hjxilinx 已提交
5481
  }
H
hjxilinx 已提交
5482

H
hjxilinx 已提交
5483 5484
  return TSDB_CODE_SUCCESS;
}
H
hjxilinx 已提交
5485 5486

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

H
hjxilinx 已提交
5490 5491
  int32_t size = tscSqlExprNumOfExprs(pQueryInfo);
  if (size == 0) {
H
hjxilinx 已提交
5492 5493
    return;
  }
H
hjxilinx 已提交
5494

H
hjxilinx 已提交
5495
  int32_t totalBufSize = 1024;
H
hjxilinx 已提交
5496 5497

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

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

L
lihui 已提交
5504
    char    tmpBuf[1024] = {0};
H
hjxilinx 已提交
5505 5506 5507
    int32_t tmpLen = 0;
    tmpLen =
        sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
L
lihui 已提交
5508 5509 5510
    if (tmpLen + offset > totalBufSize) break;

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

H
hjxilinx 已提交
5512
    if (i < size - 1) {
H
hjxilinx 已提交
5513 5514 5515
      str[offset++] = ',';
    }
  }
H
hjxilinx 已提交
5516

H
hjxilinx 已提交
5517
  str[offset] = ']';
H
hjxilinx 已提交
5518
  tscTrace("%p select clause:%s", pSql, str);
H
hjxilinx 已提交
5519
}
5520

5521
int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) {
5522 5523 5524
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";

5525 5526
  SSqlCmd*        pCmd = &pSql->cmd;
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
H
hjxilinx 已提交
5527
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539

  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
  SSQLToken* pzTableName = &(pCreateTable->name);

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5540
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5541 5542
  }

H
Haojun Liao 已提交
5543
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5544
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
5545 5546 5547 5548
  }

  if (!validateTableColumnInfo(pFieldList, pCmd) ||
      (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) {
5549
    return TSDB_CODE_TSC_INVALID_SQL;
5550 5551 5552 5553
  }

  int32_t col = 0;
  for (; col < pFieldList->nField; ++col) {
H
hjxilinx 已提交
5554
    tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pFieldList->p[col]);
5555 5556 5557 5558
  }

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

H
hjxilinx 已提交
5559
  if (pTagList != NULL) {  // create super table[optional]
5560
    for (int32_t i = 0; i < pTagList->nField; ++i) {
H
hjxilinx 已提交
5561
      tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &pTagList->p[i]);
5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578
    }

    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;
5579 5580 5581
  SQueryInfo*      pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  // two table: the first one is for current table, and the secondary is for the super table.
5582 5583 5584
  if (pQueryInfo->numOfTables < 2) {
    tscAddEmptyMetaInfo(pQueryInfo);
  }
5585 5586 5587 5588

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

H
hjxilinx 已提交
5589
  STableMetaInfo* pStableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
5590 5591 5592 5593 5594

  // super table name, create table by using dst
  SSQLToken* pToken = &(pCreateTable->usingInfo.stableName);

  if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
5595
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5596 5597
  }

H
Haojun Liao 已提交
5598
  if (tscSetTableFullName(pStableMeterMetaInfo, pToken, pSql) != TSDB_CODE_SUCCESS) {
5599
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5600 5601 5602
  }

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

H
hjxilinx 已提交
5606
  int32_t code = tscGetTableMeta(pSql, pStableMeterMetaInfo);
5607 5608 5609 5610
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

H
hjxilinx 已提交
5611
  if (tscGetNumOfTags(pStableMeterMetaInfo->pTableMeta) != pList->nExpr) {
5612
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
5613 5614 5615
  }

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

5618 5619
  STagData* pTag = &pCreateTable->usingInfo.tagdata;
  char* tagVal = pTag->data;
H
hjxilinx 已提交
5620 5621
  int32_t ret = TSDB_CODE_SUCCESS;
  
5622
  for (int32_t i = 0; i < pList->nExpr; ++i) {
H
hjxilinx 已提交
5623 5624 5625 5626 5627 5628 5629
    if (pTagSchema[i].type == TSDB_DATA_TYPE_BINARY || pTagSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
      // validate the length of binary
      if (pList->a[i].pVar.nLen + VARSTR_HEADER_SIZE > pTagSchema[i].bytes) {
        return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
      }
    }
    
5630
    ret = tVariantDump(&(pList->a[i].pVar), tagVal, pTagSchema[i].type, true);
5631
    if (ret != TSDB_CODE_SUCCESS) {
5632
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
5633 5634 5635 5636 5637 5638 5639
    }

    tagVal += pTagSchema[i].bytes;
  }

  // table name
  if (tscValidateName(&pInfo->pCreateTableInfo->name) != TSDB_CODE_SUCCESS) {
5640
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5641 5642
  }

H
hjxilinx 已提交
5643
  STableMetaInfo* pTableMeterMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
H
Haojun Liao 已提交
5644
  ret = tscSetTableFullName(pTableMeterMetaInfo, &pInfo->pCreateTableInfo->name, pSql);
5645 5646 5647 5648
  if (ret != TSDB_CODE_SUCCESS) {
    return ret;
  }

5649
  pTag->dataLen = tagVal - pTag->data;
5650 5651 5652 5653 5654 5655 5656 5657 5658
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
  const char* msg1 = "invalid table name";
  const char* msg2 = "table name too long";
  const char* msg3 = "fill only available for interval query";
  const char* msg4 = "fill option not supported in stream computing";
  const char* msg5 = "sql too long";  // todo ADD support
H
Haojun Liao 已提交
5659 5660
  const char* msg6 = "from missing in subclause";
  
5661
  SSqlCmd*    pCmd = &pSql->cmd;
5662
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
5663 5664
  assert(pQueryInfo->numOfTables == 1);

5665
  SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
H
hjxilinx 已提交
5666
  STableMetaInfo*  pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
5667 5668 5669 5670 5671 5672

  // if sql specifies db, use it, otherwise use default db
  SSQLToken* pzTableName = &(pCreateTable->name);
  SQuerySQL* pQuerySql = pCreateTable->pSelect;

  if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
5673
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5674
  }
H
Haojun Liao 已提交
5675
  
5676
  tVariantList* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
H
Haojun Liao 已提交
5677 5678 5679 5680 5681
  if (pSrcMeterName == NULL || pSrcMeterName->nExpr == 0) {
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
  }
  
  tVariant* pVar = &pSrcMeterName->a[0].pVar;
5682 5683
  SSQLToken srcToken = {.z = pVar->pz, .n = pVar->nLen, .type = TK_STRING};
  if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
5684
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
5685 5686
  }

H
Haojun Liao 已提交
5687
  if (tscSetTableFullName(pTableMetaInfo, &srcToken, pSql) != TSDB_CODE_SUCCESS) {
5688
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
5689 5690
  }

H
hjxilinx 已提交
5691
  int32_t code = tscGetTableMeta(pSql, pTableMetaInfo);
5692 5693 5694 5695
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

weixin_48148422's avatar
weixin_48148422 已提交
5696
  bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
5697
  if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5698
    return TSDB_CODE_TSC_INVALID_SQL;
5699 5700 5701
  }

  if (pQuerySql->pWhere != NULL) {  // query condition in stream computing
5702
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5703
      return TSDB_CODE_TSC_INVALID_SQL;
5704 5705 5706 5707
    }
  }

  // set interval value
5708
  if (parseIntervalClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5709
    return TSDB_CODE_TSC_INVALID_SQL;
5710
  } else {
5711
    if ((pQueryInfo->intervalTime > 0) &&
5712
        (validateFunctionsInIntervalOrGroupbyQuery(pQueryInfo) != TSDB_CODE_SUCCESS)) {
5713
      return TSDB_CODE_TSC_INVALID_SQL;
5714 5715 5716 5717
    }
  }

  // set the created table[stream] name
H
Haojun Liao 已提交
5718
  if (tscSetTableFullName(pTableMetaInfo, pzTableName, pSql) != TSDB_CODE_SUCCESS) {
5719
    return invalidSqlErrMsg(pQueryInfo->msg, msg1);
5720 5721 5722
  }

  if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
5723
    return invalidSqlErrMsg(pQueryInfo->msg, msg5);
5724 5725
  }

5726
  if (tsRewriteFieldNameIfNecessary(pQueryInfo) != TSDB_CODE_SUCCESS) {
5727
    return TSDB_CODE_TSC_INVALID_SQL;
5728 5729
  }

H
hjxilinx 已提交
5730
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5731

5732
  if (validateSqlFunctionInStreamSql(pQueryInfo) != TSDB_CODE_SUCCESS) {
5733
    return TSDB_CODE_TSC_INVALID_SQL;
5734 5735 5736 5737 5738 5739 5740
  }

  /*
   * check if fill operation is available, the fill operation is parsed and executed during query execution,
   * not here.
   */
  if (pQuerySql->fillType != NULL) {
5741
    if (pQueryInfo->intervalTime == 0) {
5742
      return invalidSqlErrMsg(pQueryInfo->msg, msg3);
5743 5744 5745 5746 5747 5748
    }

    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))) {
5749
        return invalidSqlErrMsg(pQueryInfo->msg, msg4);
5750 5751 5752 5753 5754
      }
    }
  }

  // set the number of stream table columns
H
hjxilinx 已提交
5755
  pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771
  return TSDB_CODE_SUCCESS;
}

int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
  assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0));

  const char* msg0 = "invalid table name";
  const char* msg1 = "table name too long";
  const char* msg2 = "point interpolation query needs timestamp";
  const char* msg5 = "fill only available for interval query";
  const char* msg6 = "start(end) time of query range required or time range too large";
  const char* msg7 = "illegal number of tables in from clause";
  const char* msg8 = "too many columns in selection clause";
  const char* msg9 = "TWA query requires both the start and end time";

  int32_t code = TSDB_CODE_SUCCESS;
5772

5773
  SSqlCmd* pCmd = &pSql->cmd;
5774

5775
  SQueryInfo*     pQueryInfo = tscGetQueryInfoDetail(pCmd, index);
H
hjxilinx 已提交
5776
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
5777
  if (pTableMetaInfo == NULL) {
H
hjxilinx 已提交
5778
    pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
5779
  }
H
hjxilinx 已提交
5780

5781 5782
  // too many result columns not support order by in query
  if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
5783
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795
  }

  /*
   * 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);
5796
    return doLocalQueryProcess(pQueryInfo, pQuerySql);
5797 5798 5799
  }

  if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM) {
5800
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
5801 5802
  }

5803
  pQueryInfo->command = TSDB_SQL_SELECT;
H
hjxilinx 已提交
5804

5805 5806 5807 5808 5809
  // set all query tables, which are maybe more than one.
  for (int32_t i = 0; i < pQuerySql->from->nExpr; ++i) {
    tVariant* pTableItem = &pQuerySql->from->a[i].pVar;

    if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
5810
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5811 5812 5813 5814 5815 5816
    }

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

    SSQLToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
    if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) {
5817
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
5818 5819
    }

5820
    if (pQueryInfo->numOfTables <= i) {  // more than one table
H
hjxilinx 已提交
5821
      tscAddEmptyMetaInfo(pQueryInfo);
5822 5823
    }

H
hjxilinx 已提交
5824
    STableMetaInfo* pMeterInfo1 = tscGetMetaInfo(pQueryInfo, i);
5825

5826
    SSQLToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
H
Haojun Liao 已提交
5827
    if (tscSetTableFullName(pMeterInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
5828
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
5829 5830
    }

H
hjxilinx 已提交
5831
    code = tscGetTableMeta(pSql, pMeterInfo1);
5832 5833 5834 5835 5836
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

5837
  assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr);
H
hjxilinx 已提交
5838
  bool isSTable = false;
H
hjxilinx 已提交
5839
  
weixin_48148422's avatar
weixin_48148422 已提交
5840
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
5841 5842 5843 5844 5845 5846 5847
    isSTable = true;
    code = tscGetSTableVgroupInfo(pSql, index);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
    
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY);
5848 5849
  } else {
    TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
H
hjxilinx 已提交
5850
  }
5851

5852
  // parse the group by clause in the first place
5853
  if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
5854
    return TSDB_CODE_TSC_INVALID_SQL;
5855 5856
  }

5857
  if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable) != TSDB_CODE_SUCCESS) {
5858
    return TSDB_CODE_TSC_INVALID_SQL;
5859 5860 5861
  }

  // set interval value
5862
  if (parseIntervalClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
5863
    return TSDB_CODE_TSC_INVALID_SQL;
5864
  } else {
5865
    if ((pQueryInfo->intervalTime > 0) &&
5866
        (validateFunctionsInIntervalOrGroupbyQuery(pQueryInfo) != TSDB_CODE_SUCCESS)) {
5867
      return TSDB_CODE_TSC_INVALID_SQL;
5868 5869 5870 5871
    }
  }

  // set order by info
H
hjxilinx 已提交
5872
  if (parseOrderbyClause(pQueryInfo, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
5873
    return TSDB_CODE_TSC_INVALID_SQL;
5874 5875 5876
  }

  // set where info
H
hjxilinx 已提交
5877
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
5878
  
5879
  if (pQuerySql->pWhere != NULL) {
5880
    if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
5881
      return TSDB_CODE_TSC_INVALID_SQL;
5882 5883 5884
    }

    pQuerySql->pWhere = NULL;
H
hjxilinx 已提交
5885
    if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
H
hjxilinx 已提交
5886 5887
      pQueryInfo->window.skey = pQueryInfo->window.skey / 1000;
      pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000;
5888 5889
    }
  } else {  // set the time rang
5890
    pQueryInfo->window.skey = TSKEY_INITIAL_VAL;
H
hjxilinx 已提交
5891
    pQueryInfo->window.ekey = INT64_MAX;
5892 5893 5894
  }

  // user does not specified the query time window, twa is not allowed in such case.
H
hjxilinx 已提交
5895 5896
  if ((pQueryInfo->window.skey == 0 || pQueryInfo->window.ekey == INT64_MAX ||
       (pQueryInfo->window.ekey == INT64_MAX / 1000 && tinfo.precision == TSDB_TIME_PRECISION_MILLI)) && tscIsTWAQuery(pQueryInfo)) {
5897
    return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
5898 5899 5900
  }

  // no result due to invalid query time range
H
hjxilinx 已提交
5901
  if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
5902
    pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
5903 5904 5905
    return TSDB_CODE_SUCCESS;
  }

5906 5907
  if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
    return invalidSqlErrMsg(pQueryInfo->msg, msg2);
5908 5909 5910
  }

  // in case of join query, time range is required.
5911
  if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
H
hjxilinx 已提交
5912
    int64_t timeRange = labs(pQueryInfo->window.skey - pQueryInfo->window.ekey);
5913

H
hjxilinx 已提交
5914
    if (timeRange == 0 && pQueryInfo->window.skey == 0) {
5915
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
5916 5917 5918
    }
  }

5919
  if ((code = parseLimitClause(pQueryInfo, index, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
5920 5921 5922
    return code;
  }

5923
  if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
5924 5925 5926
    return code;
  }

5927
  setColumnOffsetValueInResultset(pQueryInfo);
5928

5929 5930
  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
    updateTagColumnIndex(pQueryInfo, i);
5931
  }
H
hjxilinx 已提交
5932

5933 5934 5935 5936 5937
  /*
   * 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) {
5938
    if (pQueryInfo->intervalTime == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
5939 5940
      return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
    }
H
hjxilinx 已提交
5941

5942
    if (pQueryInfo->intervalTime > 0) {
H
hjxilinx 已提交
5943
      int64_t timeRange = labs(pQueryInfo->window.skey - pQueryInfo->window.ekey);
5944
      // number of result is not greater than 10,000,000
5945
      if ((timeRange == 0) || (timeRange / pQueryInfo->intervalTime) > MAX_RETRIEVE_ROWS_IN_INTERVAL_QUERY) {
5946 5947 5948
        return invalidSqlErrMsg(pQueryInfo->msg, msg6);
      }
    }
H
hjxilinx 已提交
5949

5950 5951 5952 5953 5954
    int32_t ret = parseFillClause(pQueryInfo, pQuerySql);
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
5955 5956 5957

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

5959
int32_t exprTreeFromSqlExpr(tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols) {
H
hjxilinx 已提交
5960 5961
  tExprNode* pLeft = NULL;
  tExprNode* pRight= NULL;
H
hjxilinx 已提交
5962
  
5963 5964
  if (pSqlExpr->pLeft != NULL) {
    int32_t ret = exprTreeFromSqlExpr(&pLeft, pSqlExpr->pLeft, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
5965 5966 5967 5968 5969
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
5970 5971
  if (pSqlExpr->pRight != NULL) {
    int32_t ret = exprTreeFromSqlExpr(&pRight, pSqlExpr->pRight, pExprInfo, pQueryInfo, pCols);
H
hjxilinx 已提交
5972 5973 5974 5975 5976
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }
  }
  
5977
  if (pSqlExpr->pLeft == NULL) {
H
hjxilinx 已提交
5978
    if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
5979
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
5980
      (*pExpr)->nodeType = TSQL_NODE_VALUE;
5981 5982 5983
      (*pExpr)->pVal = calloc(1, sizeof(tVariant));
      
      tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
5984
      return TSDB_CODE_SUCCESS;
5985
    } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
5986
      // arithmetic expression on the results of aggregation functions
5987
      *pExpr = calloc(1, sizeof(tExprNode));
H
hjxilinx 已提交
5988
      (*pExpr)->nodeType = TSQL_NODE_COL;
5989 5990 5991
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
      
H
hjxilinx 已提交
5992
      // set the input column data byte and type.
H
hjxilinx 已提交
5993 5994 5995 5996 5997 5998 5999 6000
      size_t size = taosArrayGetSize(pExprInfo);
      
      for (int32_t i = 0; i < size; ++i) {
        SSqlExpr* p1 = taosArrayGetP(pExprInfo, i);
        
        if (strcmp((*pExpr)->pSchema->name, p1->aliasName) == 0) {
          (*pExpr)->pSchema->type = p1->resType;
          (*pExpr)->pSchema->bytes = p1->resBytes;
H
hjxilinx 已提交
6001 6002 6003
          break;
        }
      }
6004
    } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017
      SColumnIndex index = {0};
      int32_t ret = getColumnIndexByName(&pSqlExpr->colInfo, pQueryInfo, &index);
      if (ret != TSDB_CODE_SUCCESS) {
        return ret;
      }
  
      *pExpr = calloc(1, sizeof(tExprNode));
      (*pExpr)->nodeType = TSQL_NODE_COL;
      (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
      
      STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
      SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
      *(*pExpr)->pSchema = *pSchema;
6018 6019 6020
  
      if (pCols != NULL) {  // record the involved columns
        SColIndex colIndex = {0};
B
Bomin Zhang 已提交
6021
        tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
6022 6023 6024 6025 6026
        colIndex.colId = pSchema->colId;
        colIndex.colIndex = index.columnIndex;
        
        taosArrayPush(pCols, &colIndex);
      }
6027
      
H
hjxilinx 已提交
6028
      return TSDB_CODE_SUCCESS;
6029
    } else {
6030
      return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6031 6032 6033
    }
    
  } else {
H
hjxilinx 已提交
6034
    *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
6035 6036
    (*pExpr)->nodeType = TSQL_NODE_EXPR;
    
H
[td-32]  
hjxilinx 已提交
6037 6038 6039
    (*pExpr)->_node.hasPK = false;
    (*pExpr)->_node.pLeft = pLeft;
    (*pExpr)->_node.pRight = pRight;
6040 6041
    
    SSQLToken t = {.type = pSqlExpr->nSQLOptr};
H
[td-32]  
hjxilinx 已提交
6042
    (*pExpr)->_node.optr = getBinaryExprOptr(&t);
6043
    
H
[td-32]  
hjxilinx 已提交
6044
    assert((*pExpr)->_node.optr != 0);
H
hjxilinx 已提交
6045
    
H
[td-32]  
hjxilinx 已提交
6046
    if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
H
hjxilinx 已提交
6047 6048
      if (pRight->nodeType == TSQL_NODE_VALUE) {
        if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
6049
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6050
        } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
6051
          return TSDB_CODE_TSC_INVALID_SQL;
H
hjxilinx 已提交
6052 6053 6054 6055 6056 6057
        }
      }
    }
  }
  
  return TSDB_CODE_SUCCESS;
L
[#1197]  
lihui 已提交
6058
}