tscUtil.c 68.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
#include "tscUtil.h"
#include "hash.h"
18
#include "os.h"
H
hjxilinx 已提交
19
#include "qast.h"
H
hzcheng 已提交
20 21 22 23 24 25
#include "taosmsg.h"
#include "tcache.h"
#include "tkey.h"
#include "tmd5.h"
#include "tscProfile.h"
#include "tscSecondaryMerge.h"
H
hjxilinx 已提交
26
#include "tscSubquery.h"
H
hzcheng 已提交
27 28 29
#include "tschemautil.h"
#include "tsclient.h"
#include "ttimer.h"
30
#include "ttokendef.h"
S
slguan 已提交
31
#include "tscLog.h"
H
hzcheng 已提交
32 33 34

/*
 * the detailed information regarding metric meta key is:
S
slguan 已提交
35 36
 * fullmetername + '.' + tagQueryCond + '.' + tableNameCond + '.' + joinCond +
 * '.' + relation + '.' + [tagId1, tagId2,...] + '.' + group_orderType
S
slguan 已提交
37
 *
S
slguan 已提交
38 39 40
 * if querycond/tablenameCond/joinCond is null, its format is:
 * fullmetername + '.' + '(nil)' + '.' + '(nil)' + relation + '.' + [tagId1,
 * tagId2,...] + '.' + group_orderType
H
hzcheng 已提交
41
 */
H
hjxilinx 已提交
42
void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) {
43
  int32_t         index = -1;
H
hjxilinx 已提交
44
  STableMetaInfo* pTableMetaInfo = tscGetMeterMetaInfoByUid(pQueryInfo, uid, &index);
H
hzcheng 已提交
45

S
slguan 已提交
46
  int32_t len = 0;
H
hzcheng 已提交
47
  char    tagIdBuf[128] = {0};
H
hjxilinx 已提交
48 49
  for (int32_t i = 0; i < pTableMetaInfo->numOfTags; ++i) {
    len += sprintf(&tagIdBuf[len], "%d,", pTableMetaInfo->tagColumnIndex[i]);
H
hzcheng 已提交
50 51
  }

52
  STagCond* pTagCond = &pQueryInfo->tagCond;
S
slguan 已提交
53
  assert(len < tListLen(tagIdBuf));
H
hzcheng 已提交
54

S
slguan 已提交
55 56
  const int32_t maxKeySize = TSDB_MAX_TAGS_LEN;  // allowed max key size

57
  SCond* cond = tsGetSTableQueryCond(pTagCond, uid);
S
slguan 已提交
58 59 60

  char join[512] = {0};
  if (pTagCond->joinInfo.hasJoin) {
S
slguan 已提交
61
    sprintf(join, "%s,%s", pTagCond->joinInfo.left.tableId, pTagCond->joinInfo.right.tableId);
S
slguan 已提交
62 63
  }

H
hjxilinx 已提交
64
  // estimate the buffer size
H
hjxilinx 已提交
65
  size_t tbnameCondLen = pTagCond->tbnameCond.cond != NULL ? strlen(pTagCond->tbnameCond.cond) : 0;
H
hjxilinx 已提交
66
  size_t redundantLen = 20;
H
hjxilinx 已提交
67

H
hjxilinx 已提交
68
  size_t bufSize = strlen(pTableMetaInfo->name) + tbnameCondLen + strlen(join) + strlen(tagIdBuf);
H
hjxilinx 已提交
69
  if (cond != NULL && cond->cond != NULL) {
H
hjxilinx 已提交
70 71
    bufSize += strlen(cond->cond);
  }
H
hjxilinx 已提交
72 73

  bufSize = (size_t)((bufSize + redundantLen) * 1.5);
H
hjxilinx 已提交
74 75
  char* tmp = calloc(1, bufSize);

H
hjxilinx 已提交
76
  int32_t keyLen = snprintf(tmp, bufSize, "%s,%s,%s,%d,%s,[%s],%d", pTableMetaInfo->name,
H
hjxilinx 已提交
77
                            ((cond != NULL && cond->cond != NULL) ? cond->cond : NULL), (tbnameCondLen > 0 ? pTagCond->tbnameCond.cond : NULL),
78
                            pTagCond->relType, join, tagIdBuf, pQueryInfo->groupbyExpr.orderType);
S
slguan 已提交
79

H
hjxilinx 已提交
80
  assert(keyLen <= bufSize);
S
slguan 已提交
81 82 83 84

  if (keyLen < maxKeySize) {
    strcpy(str, tmp);
  } else {  // using md5 to hash
H
hzcheng 已提交
85 86 87
    MD5_CTX ctx;
    MD5Init(&ctx);

H
hjxilinx 已提交
88
    MD5Update(&ctx, (uint8_t*)tmp, keyLen);
S
slguan 已提交
89 90 91 92 93 94 95
    char* pStr = base64_encode(ctx.digest, tListLen(ctx.digest));
    strcpy(str, pStr);
  }

  free(tmp);
}

96 97 98 99 100 101 102 103 104 105 106
SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) {
  if (pTagCond->pCond == NULL) {
    return NULL;
  }
  
  size_t size = taosArrayGetSize(pTagCond->pCond);
  for (int32_t i = 0; i < size; ++i) {
    SCond* pCond = taosArrayGet(pTagCond->pCond, i);
    
    if (uid == pCond->uid) {
      return pCond;
S
slguan 已提交
107 108 109 110 111 112
    }
  }

  return NULL;
}

113 114
void tsSetSTableQueryCond(STagCond* pTagCond, uint64_t uid, SBuffer* pBuf) {
  if (tbufTell(pBuf) == 0) {
S
slguan 已提交
115
    return;
H
hzcheng 已提交
116
  }
117 118 119 120 121 122 123 124 125 126 127 128 129 130
  
  SCond cond = {
    .uid = uid,
    .len = tbufTell(pBuf),
    .cond = NULL,
  };
  
  cond.cond = tbufGetData(pBuf, true);
  
  if (pTagCond->pCond == NULL) {
    pTagCond->pCond = taosArrayInit(3, sizeof(SCond));
  }
  
  taosArrayPush(pTagCond->pCond, &cond);
S
slguan 已提交
131 132
}

133
bool tscQueryOnSTable(SSqlCmd* pCmd) {
134 135 136
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  return ((pQueryInfo->type & TSDB_QUERY_TYPE_STABLE_QUERY) == TSDB_QUERY_TYPE_STABLE_QUERY) &&
S
slguan 已提交
137
         (pCmd->msgType == TSDB_MSG_TYPE_QUERY);
S
slguan 已提交
138 139
}

H
hjxilinx 已提交
140
bool tscQueryTags(SQueryInfo* pQueryInfo) {
141 142
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
    if (tscSqlExprGet(pQueryInfo, i)->functionId != TSDB_FUNC_TAGPRJ) {
S
slguan 已提交
143 144 145
      return false;
    }
  }
H
hzcheng 已提交
146

S
slguan 已提交
147
  return true;
H
hzcheng 已提交
148 149
}

S
slguan 已提交
150 151 152 153
bool tscIsSelectivityWithTagQuery(SSqlCmd* pCmd) {
  bool    hasTags = false;
  int32_t numOfSelectivity = 0;

154 155 156 157
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);

  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
    int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
S
slguan 已提交
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
    if (functId == TSDB_FUNC_TAG_DUMMY) {
      hasTags = true;
      continue;
    }

    if ((aAggs[functId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
      numOfSelectivity++;
    }
  }

  if (numOfSelectivity > 0 && hasTags) {
    return true;
  }

  return false;
}
H
hzcheng 已提交
174

S
slguan 已提交
175 176
void tscGetDBInfoFromMeterId(char* tableId, char* db) {
  char* st = strstr(tableId, TS_PATH_DELIMITER);
H
hzcheng 已提交
177 178 179
  if (st != NULL) {
    char* end = strstr(st + 1, TS_PATH_DELIMITER);
    if (end != NULL) {
S
slguan 已提交
180 181
      memcpy(db, tableId, (end - tableId));
      db[end - tableId] = 0;
H
hzcheng 已提交
182 183 184 185 186 187 188
      return;
    }
  }

  db[0] = 0;
}

S
slguan 已提交
189
SVnodeSidList* tscGetVnodeSidList(SSuperTableMeta* pMetricmeta, int32_t vnodeIdx) {
H
hjxilinx 已提交
190
#if 0
H
hzcheng 已提交
191 192 193 194 195
  if (pMetricmeta == NULL) {
    tscError("illegal metricmeta");
    return 0;
  }

S
slguan 已提交
196
  if (pMetricmeta->numOfVnodes == 0 || pMetricmeta->numOfTables == 0) {
H
hzcheng 已提交
197 198 199 200 201 202 203 204 205 206 207
    return 0;
  }

  if (vnodeIdx < 0 || vnodeIdx >= pMetricmeta->numOfVnodes) {
    int32_t vnodeRange = (pMetricmeta->numOfVnodes > 0) ? (pMetricmeta->numOfVnodes - 1) : 0;
    tscError("illegal vnodeIdx:%d, reset to 0, vnodeIdx range:%d-%d", vnodeIdx, 0, vnodeRange);

    vnodeIdx = 0;
  }

  return (SVnodeSidList*)(pMetricmeta->list[vnodeIdx] + (char*)pMetricmeta);
H
hjxilinx 已提交
208
#endif
209
  return NULL;
H
hzcheng 已提交
210 211
}

212
STableIdInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx) {
H
hzcheng 已提交
213 214 215 216 217 218 219 220 221 222 223
  if (pSidList == NULL) {
    tscError("illegal sidlist");
    return 0;
  }

  if (idx < 0 || idx >= pSidList->numOfSids) {
    int32_t sidRange = (pSidList->numOfSids > 0) ? (pSidList->numOfSids - 1) : 0;

    tscError("illegal sidIdx:%d, reset to 0, sidIdx range:%d-%d", idx, 0, sidRange);
    idx = 0;
  }
224 225 226
  
  assert(pSidList->pSidExtInfoList[idx] >= 0);
  
227
  return (STableIdInfo*)(pSidList->pSidExtInfoList[idx] + (char*)pSidList);
H
hzcheng 已提交
228 229
}

H
hjxilinx 已提交
230
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex) {
231 232 233
  if (pQueryInfo == NULL) {
    return false;
  }
234

H
hjxilinx 已提交
235
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
H
hjxilinx 已提交
236
  if (pTableMetaInfo == NULL) {
237 238 239 240
    return false;
  }
  
  // for select query super table, the metricmeta can not be null in any cases.
H
hjxilinx 已提交
241
  if (pQueryInfo->command == TSDB_SQL_SELECT && UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
242
//    assert(pTableMetaInfo->pMetricMeta != NULL);
243 244
  }
  
H
hjxilinx 已提交
245 246 247
//  if (pTableMetaInfo->pMetricMeta == NULL) {
//    return false;
//  }
H
hjxilinx 已提交
248 249 250
  
  if ((pQueryInfo->type & TSDB_QUERY_TYPE_FREE_RESOURCE) == TSDB_QUERY_TYPE_FREE_RESOURCE) {
    return false;
S
slguan 已提交
251 252
  }

253 254
  // for ordered projection query, iterate all qualified vnodes sequentially
  if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, tableIndex)) {
H
hzcheng 已提交
255 256 257
    return false;
  }

258
  if (((pQueryInfo->type & TSDB_QUERY_TYPE_STABLE_SUBQUERY) != TSDB_QUERY_TYPE_STABLE_SUBQUERY) &&
259
      pQueryInfo->command == TSDB_SQL_SELECT) {
H
hjxilinx 已提交
260
    return UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo);
H
hzcheng 已提交
261 262 263 264 265
  }

  return false;
}

266
bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) {
H
hjxilinx 已提交
267
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
268
  
H
hzcheng 已提交
269
  /*
270 271 272
   * In following cases, return false for non ordered project query on super table
   * 1. failed to get metermeta from server; 2. not a super table; 3. limitation is 0;
   * 4. show queries, instead of a select query
H
hzcheng 已提交
273
   */
H
hjxilinx 已提交
274
  if (pTableMetaInfo == NULL || !UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo) ||
275
      pQueryInfo->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pQueryInfo->exprsInfo.numOfExprs == 0) {
H
hzcheng 已提交
276 277
    return false;
  }
278
  
S
slguan 已提交
279
  // only query on tag, not a projection query
H
hjxilinx 已提交
280
  if (tscQueryTags(pQueryInfo)) {
S
slguan 已提交
281 282
    return false;
  }
283
  
H
hjxilinx 已提交
284
  // for project query, only the following two function is allowed
H
hjxilinx 已提交
285
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
286
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hjxilinx 已提交
287 288
    if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ && functionId != TSDB_FUNC_TAG &&
        functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_ARITHM) {
S
slguan 已提交
289
      return false;
H
hzcheng 已提交
290 291
    }
  }
292
  
S
slguan 已提交
293
  return true;
H
hzcheng 已提交
294 295
}

296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) {
  if (!tscIsProjectionQueryOnSTable(pQueryInfo, tableIndex)) {
    return false;
  }
  
  // order by column exists, not a non-ordered projection query
  return pQueryInfo->order.orderColId < 0;
}

bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) {
  if (!tscIsProjectionQueryOnSTable(pQueryInfo, tableIndex)) {
    return false;
  }
  
  // order by column exists, a non-ordered projection query
  return pQueryInfo->order.orderColId >= 0;
}

314 315 316
bool tscProjectionQueryOnTable(SQueryInfo* pQueryInfo) {
  for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
    int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
H
hjxilinx 已提交
317 318 319 320
    if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TS) {
      return false;
    }
  }
H
hjxilinx 已提交
321

H
hjxilinx 已提交
322 323 324
  return true;
}

325 326 327
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) {
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
H
hzcheng 已提交
328 329 330 331
    if (pExpr == NULL) {
      return false;
    }

S
slguan 已提交
332
    int32_t functionId = pExpr->functionId;
H
hzcheng 已提交
333 334 335 336 337 338 339 340 341 342 343
    if (functionId == TSDB_FUNC_TAG) {
      continue;
    }

    if (functionId != TSDB_FUNC_INTERP) {
      return false;
    }
  }
  return true;
}

344 345 346
bool tscIsTWAQuery(SQueryInfo* pQueryInfo) {
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
347 348 349 350 351 352 353 354 355 356 357
    if (pExpr == NULL) {
      continue;
    }

    int32_t functionId = pExpr->functionId;
    if (functionId == TSDB_FUNC_TWA) {
      return true;
    }
  }

  return false;
H
hzcheng 已提交
358 359
}

360 361
void tscClearInterpInfo(SQueryInfo* pQueryInfo) {
  if (!tscIsPointInterpQuery(pQueryInfo)) {
H
hzcheng 已提交
362 363 364
    return;
  }

365
  pQueryInfo->interpoType = TSDB_INTERPO_NONE;
366
  tfree(pQueryInfo->defaultVal);
H
hzcheng 已提交
367 368
}

369
int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
H
hzcheng 已提交
370
  if (pRes->tsrow == NULL) {
371
    int32_t numOfOutputCols = pQueryInfo->fieldsInfo.numOfOutputCols;
H
hjxilinx 已提交
372
    pRes->numOfCols = numOfOutputCols;
373
  
H
hjxilinx 已提交
374 375
    pRes->tsrow = calloc(POINTER_BYTES, numOfOutputCols);
    pRes->buffer = calloc(POINTER_BYTES, numOfOutputCols);
376 377
  
    // not enough memory
H
hjxilinx 已提交
378
    if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) {
379 380 381
      tfree(pRes->tsrow);
      tfree(pRes->buffer);
    
H
hzcheng 已提交
382 383 384 385 386 387 388 389 390
      pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
      return pRes->code;
    }
  }

  return TSDB_CODE_SUCCESS;
}

void tscDestroyResPointerInfo(SSqlRes* pRes) {
391 392
  if (pRes->buffer != NULL) {
    // free all buffers containing the multibyte string
H
hjxilinx 已提交
393
    for (int i = 0; i < pRes->numOfCols; i++) {
H
hzcheng 已提交
394 395
      tfree(pRes->buffer[i]);
    }
396
    
H
hjxilinx 已提交
397
    pRes->numOfCols = 0;
H
hzcheng 已提交
398
  }
399 400
  
  tfree(pRes->pRsp);
H
hzcheng 已提交
401
  tfree(pRes->tsrow);
402 403 404 405 406 407
  
  tfree(pRes->pGroupRec);
  tfree(pRes->pColumnIndex);
  tfree(pRes->buffer);
  
  pRes->data = NULL;  // pRes->data points to the buffer of pRsp, no need to free
H
hzcheng 已提交
408 409
}

410 411
void tscResetSqlCmdObj(SSqlCmd* pCmd) {
  pCmd->command   = 0;
412
  pCmd->numOfCols = 0;
413 414 415 416 417 418 419
  pCmd->count     = 0;
  pCmd->curSql    = NULL;
  pCmd->msgType   = 0;
  pCmd->parseFinished = 0;
  
  taosHashCleanup(pCmd->pTableList);
  pCmd->pTableList= NULL;
420
  
S
slguan 已提交
421
  pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
422
  tscFreeSubqueryInfo(pCmd);
H
hzcheng 已提交
423 424
}

425 426 427
/*
 * this function must not change the pRes->code value, since it may be used later.
 */
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
void tscFreeResData(SSqlObj* pSql) {
  SSqlRes* pRes = &pSql->res;
  
  pRes->row = 0;
  
  pRes->rspType = 0;
  pRes->rspLen = 0;
  pRes->row = 0;
  
  pRes->numOfRows = 0;
  pRes->numOfTotal = 0;
  pRes->numOfTotalInCurrentClause = 0;
  
  pRes->numOfGroups = 0;
  pRes->precision = 0;
  pRes->qhandle = 0;
  
  pRes->offset = 0;
  pRes->useconds = 0;
  
  tscDestroyLocalReducer(pSql);
  
  tscDestroyResPointerInfo(pRes);
}

weixin_48148422's avatar
weixin_48148422 已提交
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
void tscFreeSqlResult(SSqlObj* pSql) {
  tfree(pSql->res.pRsp);
  pSql->res.row = 0;
  pSql->res.numOfRows = 0;
  pSql->res.numOfTotal = 0;

  pSql->res.numOfGroups = 0;
  tfree(pSql->res.pGroupRec);

  tscDestroyLocalReducer(pSql);

  tscDestroyResPointerInfo(&pSql->res);
  tfree(pSql->res.pColumnIndex);
}

H
hzcheng 已提交
468
void tscFreeSqlObjPartial(SSqlObj* pSql) {
S
slguan 已提交
469 470 471
  if (pSql == NULL || pSql->signature != pSql) {
    return;
  }
H
hzcheng 已提交
472 473 474 475 476

  SSqlCmd* pCmd = &pSql->cmd;
  STscObj* pObj = pSql->pTscObj;

  int32_t cmd = pCmd->command;
S
slguan 已提交
477 478
  if (cmd < TSDB_SQL_INSERT || cmd == TSDB_SQL_RETRIEVE_METRIC || cmd == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
      cmd == TSDB_SQL_METRIC_JOIN_RETRIEVE) {
H
hzcheng 已提交
479 480
    tscRemoveFromSqlList(pSql);
  }
481
  
H
hzcheng 已提交
482 483 484 485
  // pSql->sqlstr will be used by tscBuildQueryStreamDesc
  pthread_mutex_lock(&pObj->mutex);
  tfree(pSql->sqlstr);
  pthread_mutex_unlock(&pObj->mutex);
486
  
weixin_48148422's avatar
weixin_48148422 已提交
487
  tscFreeSqlResult(pSql);
H
hzcheng 已提交
488
  tfree(pSql->pSubs);
H
[TD-98]  
hjxilinx 已提交
489
  
490
  pSql->freed = 0;
H
[TD-98]  
hjxilinx 已提交
491 492
  pSql->numOfSubs = 0;
  
493
  tscResetSqlCmdObj(pCmd);
494
  
495
  tscTrace("%p partially free sqlObj completed", pSql);
H
hzcheng 已提交
496 497 498 499 500 501 502 503 504 505
}

void tscFreeSqlObj(SSqlObj* pSql) {
  if (pSql == NULL || pSql->signature != pSql) return;

  tscTrace("%p start to free sql object", pSql);
  tscFreeSqlObjPartial(pSql);

  pSql->signature = NULL;
  pSql->fp = NULL;
506
  
H
hzcheng 已提交
507 508
  SSqlCmd* pCmd = &pSql->cmd;

S
slguan 已提交
509
  memset(pCmd->payload, 0, (size_t)pCmd->allocSize);
H
hzcheng 已提交
510 511 512 513 514 515
  tfree(pCmd->payload);

  pCmd->allocSize = 0;
  free(pSql);
}

S
slguan 已提交
516 517
void tscDestroyDataBlock(STableDataBlocks* pDataBlock) {
  if (pDataBlock == NULL) {
H
hzcheng 已提交
518 519 520
    return;
  }

S
slguan 已提交
521
  tfree(pDataBlock->pData);
S
slguan 已提交
522
  tfree(pDataBlock->params);
H
hjxilinx 已提交
523

H
hjxilinx 已提交
524
  // free the refcount for metermeta
H
hjxilinx 已提交
525
  taosCacheRelease(tscCacheHandle, (void**)&(pDataBlock->pTableMeta), false);
S
slguan 已提交
526
  tfree(pDataBlock);
H
hzcheng 已提交
527 528
}

529 530
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, short bytes,
                                   uint32_t offset) {
S
slguan 已提交
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
  uint32_t needed = pDataBlock->numOfParams + 1;
  if (needed > pDataBlock->numOfAllocedParams) {
    needed *= 2;
    void* tmp = realloc(pDataBlock->params, needed * sizeof(SParamInfo));
    if (tmp == NULL) {
      return NULL;
    }
    pDataBlock->params = (SParamInfo*)tmp;
    pDataBlock->numOfAllocedParams = needed;
  }

  SParamInfo* param = pDataBlock->params + pDataBlock->numOfParams;
  param->idx = -1;
  param->type = type;
  param->timePrec = timePrec;
  param->bytes = bytes;
  param->offset = offset;

  ++pDataBlock->numOfParams;
  return param;
}

H
hzcheng 已提交
553 554 555 556
SDataBlockList* tscCreateBlockArrayList() {
  const int32_t DEFAULT_INITIAL_NUM_OF_BLOCK = 16;

  SDataBlockList* pDataBlockArrayList = calloc(1, sizeof(SDataBlockList));
S
slguan 已提交
557 558 559
  if (pDataBlockArrayList == NULL) {
    return NULL;
  }
H
hzcheng 已提交
560 561
  pDataBlockArrayList->nAlloc = DEFAULT_INITIAL_NUM_OF_BLOCK;
  pDataBlockArrayList->pData = calloc(1, POINTER_BYTES * pDataBlockArrayList->nAlloc);
S
slguan 已提交
562 563 564 565
  if (pDataBlockArrayList->pData == NULL) {
    free(pDataBlockArrayList);
    return NULL;
  }
H
hzcheng 已提交
566 567 568 569

  return pDataBlockArrayList;
}

570
void tscAppendDataBlock(SDataBlockList* pList, STableDataBlocks* pBlocks) {
S
slguan 已提交
571
  if (pList->nSize >= pList->nAlloc) {
H
hjxilinx 已提交
572 573
    pList->nAlloc = (pList->nAlloc) << 1U;
    pList->pData = realloc(pList->pData, POINTER_BYTES * (size_t)pList->nAlloc);
S
slguan 已提交
574 575

    // reset allocated memory
H
hjxilinx 已提交
576
    memset(pList->pData + pList->nSize, 0, POINTER_BYTES * (pList->nAlloc - pList->nSize));
S
slguan 已提交
577 578 579 580 581
  }

  pList->pData[pList->nSize++] = pBlocks;
}

S
slguan 已提交
582 583 584
void* tscDestroyBlockArrayList(SDataBlockList* pList) {
  if (pList == NULL) {
    return NULL;
H
hzcheng 已提交
585 586
  }

S
slguan 已提交
587 588
  for (int32_t i = 0; i < pList->nSize; i++) {
    tscDestroyDataBlock(pList->pData[i]);
H
hzcheng 已提交
589 590
  }

S
slguan 已提交
591 592 593 594
  tfree(pList->pData);
  tfree(pList);

  return NULL;
H
hzcheng 已提交
595 596
}

S
slguan 已提交
597
int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
H
hjxilinx 已提交
598
  SSqlCmd* pCmd = &pSql->cmd;
H
hjxilinx 已提交
599
  assert(pDataBlock->pTableMeta != NULL);
H
hjxilinx 已提交
600

S
slguan 已提交
601
  pCmd->numOfTablesInSubmit = pDataBlock->numOfTables;
602

603
  assert(pCmd->numOfClause == 1);
604
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
H
hjxilinx 已提交
605

606
  // set the correct table meta object, the table meta has been locked in pDataBlocks, so it must be in the cache
H
hjxilinx 已提交
607 608 609
  if (pTableMetaInfo->pTableMeta != pDataBlock->pTableMeta) {
    strcpy(pTableMetaInfo->name, pDataBlock->tableId);
    taosCacheRelease(tscCacheHandle, (void**)&(pTableMetaInfo->pTableMeta), false);
610

H
hjxilinx 已提交
611
    pTableMetaInfo->pTableMeta = taosCacheTransfer(tscCacheHandle, (void**)&pDataBlock->pTableMeta);
H
hjxilinx 已提交
612
  } else {
H
hjxilinx 已提交
613
    assert(strncmp(pTableMetaInfo->name, pDataBlock->tableId, tListLen(pDataBlock->tableId)) == 0);
H
hjxilinx 已提交
614
  }
H
hjxilinx 已提交
615

616 617
  /*
   * the submit message consists of : [RPC header|message body|digest]
618
   * the dataBlock only includes the RPC Header buffer and actual submit message body, space for digest needs
619 620
   * additional space.
   */
S
slguan 已提交
621
  int ret = tscAllocPayload(pCmd, pDataBlock->nAllocSize + 100);
H
hjxilinx 已提交
622 623 624
  if (TSDB_CODE_SUCCESS != ret) {
    return ret;
  }
H
hjxilinx 已提交
625

H
hzcheng 已提交
626
  memcpy(pCmd->payload, pDataBlock->pData, pDataBlock->nAllocSize);
H
hjxilinx 已提交
627

628 629 630 631
  /*
   * the payloadLen should be actual message body size
   * the old value of payloadLen is the allocated payload size
   */
632
  pCmd->payloadLen = pDataBlock->nAllocSize - tsRpcHeadSize;
H
hjxilinx 已提交
633

H
hjxilinx 已提交
634
  assert(pCmd->allocSize >= pCmd->payloadLen + tsRpcHeadSize + 100 && pCmd->payloadLen > 0);
H
hjxilinx 已提交
635
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
636 637 638 639 640
}

void tscFreeUnusedDataBlocks(SDataBlockList* pList) {
  /* release additional memory consumption */
  for (int32_t i = 0; i < pList->nSize; ++i) {
S
slguan 已提交
641 642 643
    STableDataBlocks* pDataBlock = pList->pData[i];
    pDataBlock->pData = realloc(pDataBlock->pData, pDataBlock->size);
    pDataBlock->nAllocSize = (uint32_t)pDataBlock->size;
H
hzcheng 已提交
644 645 646
  }
}

H
hjxilinx 已提交
647 648 649 650 651 652
/**
 * create the in-memory buffer for each table to keep the submitted data block
 * @param initialSize
 * @param rowSize
 * @param startOffset
 * @param name
H
hjxilinx 已提交
653
 * @param dataBlocks
H
hjxilinx 已提交
654 655
 * @return
 */
H
hjxilinx 已提交
656
int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, const char* name,
H
hjxilinx 已提交
657
                           STableMeta* pTableMeta, STableDataBlocks** dataBlocks) {
H
hjxilinx 已提交
658
  STableDataBlocks* dataBuf = (STableDataBlocks*)calloc(1, sizeof(STableDataBlocks));
H
hjxilinx 已提交
659 660 661 662 663 664
  if (dataBuf == NULL) {
    tscError("failed to allocated memory, reason:%s", strerror(errno));
    return TSDB_CODE_CLI_OUT_OF_MEMORY;
  }

  dataBuf->nAllocSize = (uint32_t)initialSize;
L
[#1102]  
lihui 已提交
665
  dataBuf->headerSize = startOffset; // the header size will always be the startOffset value, reserved for the subumit block header
H
hjxilinx 已提交
666 667 668 669
  if (dataBuf->nAllocSize <= dataBuf->headerSize) {
    dataBuf->nAllocSize = dataBuf->headerSize*2;
  }
  
H
hjxilinx 已提交
670 671 672
  dataBuf->pData = calloc(1, dataBuf->nAllocSize);
  dataBuf->ordered = true;
  dataBuf->prevTS = INT64_MIN;
S
slguan 已提交
673 674 675

  dataBuf->rowSize = rowSize;
  dataBuf->size = startOffset;
S
slguan 已提交
676 677
  dataBuf->tsSource = -1;

S
slguan 已提交
678
  strncpy(dataBuf->tableId, name, TSDB_TABLE_ID_LEN);
H
hjxilinx 已提交
679 680

  /*
681
   * The table meta may be released since the table meta cache are completed clean by other thread
682 683
   * due to operation such as drop database. So here we add the reference count directly instead of invoke
   * taosGetDataFromCache, which may return NULL value.
H
hjxilinx 已提交
684
   */
H
hjxilinx 已提交
685 686
  dataBuf->pTableMeta = taosCacheAcquireByData(tscCacheHandle, pTableMeta);
  assert(initialSize > 0 && pTableMeta != NULL && dataBuf->pTableMeta != NULL);
687

688 689
  *dataBlocks = dataBuf;
  return TSDB_CODE_SUCCESS;
S
slguan 已提交
690 691
}

H
hjxilinx 已提交
692
int32_t tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList, int64_t id, int32_t size,
H
hjxilinx 已提交
693
                                int32_t startOffset, int32_t rowSize, const char* tableId, STableMeta* pTableMeta,
H
hjxilinx 已提交
694 695
                                STableDataBlocks** dataBlocks) {
  *dataBlocks = NULL;
S
slguan 已提交
696

H
hjxilinx 已提交
697
  STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pHashList, (const char*)&id, sizeof(id));
S
slguan 已提交
698
  if (t1 != NULL) {
H
hjxilinx 已提交
699
    *dataBlocks = *t1;
S
slguan 已提交
700 701
  }

H
hjxilinx 已提交
702
  if (*dataBlocks == NULL) {
H
hjxilinx 已提交
703
    int32_t ret = tscCreateDataBlock((size_t)size, rowSize, startOffset, tableId, pTableMeta, dataBlocks);
H
hjxilinx 已提交
704 705 706 707
    if (ret != TSDB_CODE_SUCCESS) {
      return ret;
    }

H
hjxilinx 已提交
708
    taosHashPut(pHashList, (const char*)&id, sizeof(int64_t), (char*)dataBlocks, POINTER_BYTES);
H
hjxilinx 已提交
709
    tscAppendDataBlock(pDataBlockList, *dataBlocks);
S
slguan 已提交
710 711
  }

H
hjxilinx 已提交
712
  return TSDB_CODE_SUCCESS;
S
slguan 已提交
713 714
}

715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
static void trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock) {
  int32_t firstPartLen = 0;
  
  STableMeta* pTableMeta = pTableDataBlock->pTableMeta;
  STableComInfo tinfo = tscGetTableInfo(pTableMeta);
  SSchema* pSchema = tscGetTableSchema(pTableMeta);
  
  memcpy(pDataBlock, pTableDataBlock->pData, sizeof(SSubmitBlk));
  pDataBlock += sizeof(SSubmitBlk);
  
  int32_t total = sizeof(int32_t)*2;
  for(int32_t i = 0; i < tinfo.numOfColumns; ++i) {
    switch (pSchema[i].type) {
      case TSDB_DATA_TYPE_NCHAR:
      case TSDB_DATA_TYPE_BINARY: {
        assert(0);  // not support binary yet
        firstPartLen += sizeof(int32_t);break;
      }
      default:
        firstPartLen += tDataTypeDesc[pSchema[i].type].nSize;
        total += tDataTypeDesc[pSchema[i].type].nSize;
    }
  }
  
  char* p = pTableDataBlock->pData + sizeof(SSubmitBlk);
  
H
hjxilinx 已提交
741
  SSubmitBlk* pBlock = (SSubmitBlk*) pTableDataBlock->pData;
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
  int32_t rows = htons(pBlock->numOfRows);
  
  for(int32_t i = 0; i < rows; ++i) {
    *(int32_t*) pDataBlock = total;
    pDataBlock += sizeof(int32_t);
    
    *(int32_t*) pDataBlock = firstPartLen;
    pDataBlock += sizeof(int32_t);
    
    memcpy(pDataBlock, p, pTableDataBlock->rowSize);
    
    p += pTableDataBlock->rowSize;
    pDataBlock += pTableDataBlock->rowSize;
  }
}

S
slguan 已提交
758 759 760
int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockList) {
  SSqlCmd* pCmd = &pSql->cmd;

H
hjxilinx 已提交
761
  void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false);
S
slguan 已提交
762 763 764 765
  SDataBlockList* pVnodeDataBlockList = tscCreateBlockArrayList();

  for (int32_t i = 0; i < pTableDataBlockList->nSize; ++i) {
    STableDataBlocks* pOneTableBlock = pTableDataBlockList->pData[i];
S
slguan 已提交
766

H
hjxilinx 已提交
767
    STableDataBlocks* dataBuf = NULL;
H
hjxilinx 已提交
768 769 770
    
    int32_t ret =
        tscGetDataBlockFromList(pVnodeDataBlockHashList, pVnodeDataBlockList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE,
H
hjxilinx 已提交
771
                                tsInsertHeadSize, 0, pOneTableBlock->tableId, pOneTableBlock->pTableMeta, &dataBuf);
H
hjxilinx 已提交
772
    if (ret != TSDB_CODE_SUCCESS) {
773
      tscError("%p failed to prepare the data block buffer for merging table data, code:%d", pSql, ret);
H
hjxilinx 已提交
774
      taosHashCleanup(pVnodeDataBlockHashList);
775
      tscDestroyBlockArrayList(pVnodeDataBlockList);
H
hjxilinx 已提交
776 777
      return ret;
    }
S
slguan 已提交
778

779
    int64_t destSize = dataBuf->size + pOneTableBlock->size + pOneTableBlock->size*sizeof(int32_t)*2;
S
slguan 已提交
780 781 782 783 784 785 786 787 788
    if (dataBuf->nAllocSize < destSize) {
      while (dataBuf->nAllocSize < destSize) {
        dataBuf->nAllocSize = dataBuf->nAllocSize * 1.5;
      }

      char* tmp = realloc(dataBuf->pData, dataBuf->nAllocSize);
      if (tmp != NULL) {
        dataBuf->pData = tmp;
        memset(dataBuf->pData + dataBuf->size, 0, dataBuf->nAllocSize - dataBuf->size);
789
      } else {  // failed to allocate memory, free already allocated memory and return error code
S
slguan 已提交
790 791
        tscError("%p failed to allocate memory for merging submit block, size:%d", pSql, dataBuf->nAllocSize);

H
hjxilinx 已提交
792
        taosHashCleanup(pVnodeDataBlockHashList);
S
slguan 已提交
793
        tscDestroyBlockArrayList(pVnodeDataBlockList);
794
        tfree(dataBuf->pData);
S
slguan 已提交
795 796

        return TSDB_CODE_CLI_OUT_OF_MEMORY;
S
slguan 已提交
797 798 799
      }
    }

800
    SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
S
slguan 已提交
801
    sortRemoveDuplicates(pOneTableBlock);
S
slguan 已提交
802

803
    char* e = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1);
L
lihui 已提交
804
    
805 806
    tscTrace("%p tableId:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->tableId,
        pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(e));
S
slguan 已提交
807

808 809 810
    int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + sizeof(int32_t) * 2);
    
    pBlocks->tid = htonl(pBlocks->tid);
S
slguan 已提交
811 812 813
    pBlocks->uid = htobe64(pBlocks->uid);
    pBlocks->sversion = htonl(pBlocks->sversion);
    pBlocks->numOfRows = htons(pBlocks->numOfRows);
814 815 816 817 818 819
    
    pBlocks->len = htonl(len);
    
    // erase the empty space reserved for binary data
    trimDataBlock(dataBuf->pData + dataBuf->size, pOneTableBlock);
    dataBuf->size += (len + sizeof(SSubmitBlk));
S
slguan 已提交
820
    dataBuf->numOfTables += 1;
S
slguan 已提交
821 822 823 824 825 826 827 828
  }

  tscDestroyBlockArrayList(pTableDataBlockList);

  // free the table data blocks;
  pCmd->pDataBlocks = pVnodeDataBlockList;

  tscFreeUnusedDataBlocks(pCmd->pDataBlocks);
H
hjxilinx 已提交
829
  taosHashCleanup(pVnodeDataBlockHashList);
S
slguan 已提交
830 831

  return TSDB_CODE_SUCCESS;
S
slguan 已提交
832 833
}

H
hzcheng 已提交
834 835 836
void tscCloseTscObj(STscObj* pObj) {
  pObj->signature = NULL;
  SSqlObj* pSql = pObj->pSql;
837
  if (pSql) {
H
hjxilinx 已提交
838
    terrno = pSql->res.code;
839 840
  }
  
H
hzcheng 已提交
841 842 843
  taosTmrStopA(&(pObj->pTimer));
  tscFreeSqlObj(pSql);

844
  sem_destroy(&pSql->rspSem);
H
hzcheng 已提交
845
  pthread_mutex_destroy(&pObj->mutex);
846
  
H
hzcheng 已提交
847 848 849 850 851
  tscTrace("%p DB connection is closed", pObj);
  tfree(pObj);
}

bool tscIsInsertOrImportData(char* sqlstr) {
852 853 854 855 856 857 858 859
  int32_t index = 0;

  do {
    SSQLToken t0 = tStrGetToken(sqlstr, &index, false, 0, NULL);
    if (t0.type != TK_LP) {
      return t0.type == TK_INSERT || t0.type == TK_IMPORT;
    }
  } while (1);
H
hzcheng 已提交
860 861
}

S
slguan 已提交
862
int tscAllocPayload(SSqlCmd* pCmd, int size) {
H
hzcheng 已提交
863 864 865 866 867
  assert(size > 0);

  if (pCmd->payload == NULL) {
    assert(pCmd->allocSize == 0);

868
    pCmd->payload = (char*)calloc(1, size);
H
hzcheng 已提交
869 870 871 872
    if (pCmd->payload == NULL) return TSDB_CODE_CLI_OUT_OF_MEMORY;
    pCmd->allocSize = size;
  } else {
    if (pCmd->allocSize < size) {
873
      char* b = realloc(pCmd->payload, size);
S
slguan 已提交
874 875
      if (b == NULL) return TSDB_CODE_CLI_OUT_OF_MEMORY;
      pCmd->payload = b;
H
hzcheng 已提交
876 877
      pCmd->allocSize = size;
    }
878
    
H
hjxilinx 已提交
879
    memset(pCmd->payload, 0, pCmd->allocSize);
H
hzcheng 已提交
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
  }

  assert(pCmd->allocSize >= size);
  return TSDB_CODE_SUCCESS;
}

static void ensureSpace(SFieldInfo* pFieldInfo, int32_t size) {
  if (size > pFieldInfo->numOfAlloc) {
    int32_t oldSize = pFieldInfo->numOfAlloc;

    int32_t newSize = (oldSize <= 0) ? 8 : (oldSize << 1);
    while (newSize < size) {
      newSize = (newSize << 1);
    }

    if (newSize > TSDB_MAX_COLUMNS) {
      newSize = TSDB_MAX_COLUMNS;
    }

    int32_t inc = newSize - oldSize;

    pFieldInfo->pFields = realloc(pFieldInfo->pFields, newSize * sizeof(TAOS_FIELD));
    memset(&pFieldInfo->pFields[oldSize], 0, inc * sizeof(TAOS_FIELD));

H
hjxilinx 已提交
904 905
//    pFieldInfo->pOffset = realloc(pFieldInfo->pOffset, newSize * sizeof(int16_t));
//    memset(&pFieldInfo->pOffset[oldSize], 0, inc * sizeof(int16_t));
H
hzcheng 已提交
906

S
slguan 已提交
907
    pFieldInfo->pVisibleCols = realloc(pFieldInfo->pVisibleCols, newSize * sizeof(bool));
H
hjxilinx 已提交
908
    memset(&pFieldInfo->pVisibleCols[oldSize], 0, inc * sizeof(bool));
S
slguan 已提交
909

H
hjxilinx 已提交
910 911 912 913 914 915
    pFieldInfo->pSqlExpr = realloc(pFieldInfo->pSqlExpr, POINTER_BYTES*newSize);
    pFieldInfo->pExpr = realloc(pFieldInfo->pExpr, POINTER_BYTES*newSize);
  
    memset(&pFieldInfo->pSqlExpr[oldSize], 0, inc * POINTER_BYTES);
    memset(&pFieldInfo->pExpr[oldSize], 0, inc * POINTER_BYTES);
  
H
hzcheng 已提交
916 917 918 919 920 921 922 923
    pFieldInfo->numOfAlloc = newSize;
  }
}

static void evic(SFieldInfo* pFieldInfo, int32_t index) {
  if (index < pFieldInfo->numOfOutputCols) {
    memmove(&pFieldInfo->pFields[index + 1], &pFieldInfo->pFields[index],
            sizeof(pFieldInfo->pFields[0]) * (pFieldInfo->numOfOutputCols - index));
H
hjxilinx 已提交
924 925 926 927 928 929 930 931 932
    
    memmove(&pFieldInfo->pVisibleCols[index + 1], &pFieldInfo->pVisibleCols[index],
            sizeof(pFieldInfo->pVisibleCols[0]) * (pFieldInfo->numOfOutputCols - index));
    
    memmove(&pFieldInfo->pSqlExpr[index + 1], &pFieldInfo->pSqlExpr[index],
            sizeof(pFieldInfo->pSqlExpr[0]) * (pFieldInfo->numOfOutputCols - index));
  
    memmove(&pFieldInfo->pExpr[index + 1], &pFieldInfo->pExpr[index],
            sizeof(pFieldInfo->pExpr[0]) * (pFieldInfo->numOfOutputCols - index));
H
hzcheng 已提交
933 934 935
  }
}

H
hjxilinx 已提交
936
static void setValueImpl(TAOS_FIELD* pField, int8_t type, const char* name, int16_t bytes) {
H
hzcheng 已提交
937 938 939 940 941
  pField->type = type;
  strncpy(pField->name, name, TSDB_COL_NAME_LEN);
  pField->bytes = bytes;
}

S
slguan 已提交
942
void tscFieldInfoSetValFromSchema(SFieldInfo* pFieldInfo, int32_t index, SSchema* pSchema) {
H
hzcheng 已提交
943 944 945 946 947 948 949 950 951 952 953 954 955
  ensureSpace(pFieldInfo, pFieldInfo->numOfOutputCols + 1);
  evic(pFieldInfo, index);

  TAOS_FIELD* pField = &pFieldInfo->pFields[index];
  setValueImpl(pField, pSchema->type, pSchema->name, pSchema->bytes);
  pFieldInfo->numOfOutputCols++;
}

void tscFieldInfoSetValFromField(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* pField) {
  ensureSpace(pFieldInfo, pFieldInfo->numOfOutputCols + 1);
  evic(pFieldInfo, index);

  memcpy(&pFieldInfo->pFields[index], pField, sizeof(TAOS_FIELD));
S
slguan 已提交
956
  pFieldInfo->pVisibleCols[index] = true;
H
hzcheng 已提交
957 958 959
  pFieldInfo->numOfOutputCols++;
}

S
slguan 已提交
960
void tscFieldInfoUpdateVisible(SFieldInfo* pFieldInfo, int32_t index, bool visible) {
weixin_48148422's avatar
weixin_48148422 已提交
961
  if (index < 0 || index >= pFieldInfo->numOfOutputCols) {
S
slguan 已提交
962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
    return;
  }

  bool oldVisible = pFieldInfo->pVisibleCols[index];
  pFieldInfo->pVisibleCols[index] = visible;

  if (oldVisible != visible) {
    if (!visible) {
      pFieldInfo->numOfHiddenCols += 1;
    } else {
      if (pFieldInfo->numOfHiddenCols > 0) {
        pFieldInfo->numOfHiddenCols -= 1;
      }
    }
  }
}

H
hjxilinx 已提交
979
void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, const char* name, int16_t bytes) {
H
hzcheng 已提交
980 981 982 983 984
  ensureSpace(pFieldInfo, pFieldInfo->numOfOutputCols + 1);
  evic(pFieldInfo, index);

  TAOS_FIELD* pField = &pFieldInfo->pFields[index];
  setValueImpl(pField, type, name, bytes);
S
slguan 已提交
985 986

  pFieldInfo->pVisibleCols[index] = true;
H
hzcheng 已提交
987 988 989
  pFieldInfo->numOfOutputCols++;
}

H
hjxilinx 已提交
990 991 992 993 994 995 996 997 998
void tscFieldInfoSetExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlExpr* pExpr) {
  assert(index >= 0 && index < pFieldInfo->numOfOutputCols);
  pFieldInfo->pSqlExpr[index] = pExpr;
}

void tscFieldInfoSetBinExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlFunctionExpr* pExpr) {
  assert(index >= 0 && index < pFieldInfo->numOfOutputCols);
  pFieldInfo->pExpr[index] = pExpr;
}
H
hzcheng 已提交
999

H
hjxilinx 已提交
1000 1001
void tscFieldInfoCalOffset(SQueryInfo* pQueryInfo) {
  SSqlExprInfo* pExprInfo = &pQueryInfo->exprsInfo;
H
hjxilinx 已提交
1002
  pExprInfo->pExprs[0]->offset = 0;
H
hjxilinx 已提交
1003 1004
  
  for (int32_t i = 1; i < pExprInfo->numOfExprs; ++i) {
H
hjxilinx 已提交
1005
    pExprInfo->pExprs[i]->offset = pExprInfo->pExprs[i - 1]->offset + pExprInfo->pExprs[i - 1]->resBytes;
H
hzcheng 已提交
1006 1007 1008
  }
}

1009
void tscFieldInfoUpdateOffsetForInterResult(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
1010 1011
  SSqlExprInfo* pExprInfo = &pQueryInfo->exprsInfo;
  if (pExprInfo->numOfExprs == 0) {
H
hzcheng 已提交
1012 1013
    return;
  }
H
hjxilinx 已提交
1014
  
H
hjxilinx 已提交
1015
  pExprInfo->pExprs[0]->offset = 0;
H
hjxilinx 已提交
1016 1017
  
  for (int32_t i = 1; i < pExprInfo->numOfExprs; ++i) {
H
hjxilinx 已提交
1018
    pExprInfo->pExprs[i]->offset = pExprInfo->pExprs[i - 1]->offset + pExprInfo->pExprs[i - 1]->resBytes;
H
hzcheng 已提交
1019 1020 1021
  }
}

S
slguan 已提交
1022
void tscFieldInfoCopy(SFieldInfo* src, SFieldInfo* dst, const int32_t* indexList, int32_t size) {
H
hzcheng 已提交
1023 1024 1025 1026
  if (src == NULL) {
    return;
  }

S
slguan 已提交
1027 1028
  if (size <= 0) {
    *dst = *src;
1029
    tscFieldInfoCopyAll(dst, src);
S
slguan 已提交
1030 1031 1032 1033
  } else {  // only copy the required column
    for (int32_t i = 0; i < size; ++i) {
      assert(indexList[i] >= 0 && indexList[i] <= src->numOfOutputCols);
      tscFieldInfoSetValFromField(dst, i, &src->pFields[indexList[i]]);
H
hjxilinx 已提交
1034 1035
      dst->pVisibleCols[i] = src->pVisibleCols[indexList[i]];
      dst->pSqlExpr[i] = src->pSqlExpr[indexList[i]];
S
slguan 已提交
1036 1037 1038 1039
    }
  }
}

1040
void tscFieldInfoCopyAll(SFieldInfo* dst, SFieldInfo* src) {
H
hzcheng 已提交
1041 1042 1043
  *dst = *src;

  dst->pFields = malloc(sizeof(TAOS_FIELD) * dst->numOfAlloc);
S
slguan 已提交
1044
  dst->pVisibleCols = malloc(sizeof(bool) * dst->numOfAlloc);
H
hjxilinx 已提交
1045
  dst->pSqlExpr = malloc(POINTER_BYTES * dst->numOfAlloc);
H
hjxilinx 已提交
1046
  dst->pExpr = malloc(POINTER_BYTES * dst->numOfAlloc);
H
hzcheng 已提交
1047 1048

  memcpy(dst->pFields, src->pFields, sizeof(TAOS_FIELD) * dst->numOfOutputCols);
S
slguan 已提交
1049
  memcpy(dst->pVisibleCols, src->pVisibleCols, sizeof(bool) * dst->numOfOutputCols);
H
hjxilinx 已提交
1050
  memcpy(dst->pSqlExpr, src->pSqlExpr, POINTER_BYTES * dst->numOfOutputCols);
H
hjxilinx 已提交
1051
  memcpy(dst->pExpr, src->pExpr, POINTER_BYTES * dst->numOfOutputCols);
H
hzcheng 已提交
1052 1053
}

1054 1055
TAOS_FIELD* tscFieldInfoGetField(SQueryInfo* pQueryInfo, int32_t index) {
  if (index >= pQueryInfo->fieldsInfo.numOfOutputCols) {
H
hzcheng 已提交
1056 1057 1058
    return NULL;
  }

1059
  return &pQueryInfo->fieldsInfo.pFields[index];
1060 1061
}

1062
int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutputCols; }
H
hzcheng 已提交
1063

1064
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
H
hjxilinx 已提交
1065
  if (index >= pQueryInfo->exprsInfo.numOfExprs) {
H
hzcheng 已提交
1066 1067 1068
    return 0;
  }

H
hjxilinx 已提交
1069
  return pQueryInfo->exprsInfo.pExprs[index]->offset;
H
hzcheng 已提交
1070 1071
}

1072 1073
int32_t tscFieldInfoCompare(SFieldInfo* pFieldInfo1, SFieldInfo* pFieldInfo2) {
  assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL);
1074

1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
  if (pFieldInfo1->numOfOutputCols != pFieldInfo2->numOfOutputCols) {
    return pFieldInfo1->numOfOutputCols - pFieldInfo2->numOfOutputCols;
  }

  for (int32_t i = 0; i < pFieldInfo1->numOfOutputCols; ++i) {
    TAOS_FIELD* pField1 = &pFieldInfo1->pFields[i];
    TAOS_FIELD* pField2 = &pFieldInfo2->pFields[i];

    if (pField1->type != pField2->type || pField1->bytes != pField2->bytes ||
        strcasecmp(pField1->name, pField2->name) != 0) {
      return 1;
    }
  }

  return 0;
}

1092
int32_t tscGetResRowLength(SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
1093
  if (pQueryInfo->exprsInfo.numOfExprs <= 0) {
H
hzcheng 已提交
1094 1095
    return 0;
  }
H
hjxilinx 已提交
1096 1097 1098
  
  int32_t size = 0;
  for(int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
H
hjxilinx 已提交
1099
    size += pQueryInfo->exprsInfo.pExprs[i]->resBytes;
H
hjxilinx 已提交
1100 1101 1102
  }
  
  return size;
H
hzcheng 已提交
1103 1104
}

S
slguan 已提交
1105 1106
void tscClearFieldInfo(SFieldInfo* pFieldInfo) {
  if (pFieldInfo == NULL) {
H
hzcheng 已提交
1107 1108 1109
    return;
  }

S
slguan 已提交
1110 1111
  tfree(pFieldInfo->pFields);
  tfree(pFieldInfo->pVisibleCols);
H
hjxilinx 已提交
1112 1113 1114 1115
  tfree(pFieldInfo->pSqlExpr);
  
  for(int32_t i = 0; i < pFieldInfo->numOfOutputCols; ++i) {
    if (pFieldInfo->pExpr[i] != NULL) {
1116
      tExprTreeDestroy(&pFieldInfo->pExpr[i]->binExprInfo.pBinExpr, NULL);
1117
      tfree(pFieldInfo->pExpr[i]->binExprInfo.pReqColumns);
H
hjxilinx 已提交
1118 1119 1120 1121 1122
      tfree(pFieldInfo->pExpr[i]);
    }
  }
  
  tfree(pFieldInfo->pExpr);
S
slguan 已提交
1123
  memset(pFieldInfo, 0, sizeof(SFieldInfo));
H
hzcheng 已提交
1124 1125 1126 1127
}

static void _exprCheckSpace(SSqlExprInfo* pExprInfo, int32_t size) {
  if (size > pExprInfo->numOfAlloc) {
1128
    uint32_t oldSize = pExprInfo->numOfAlloc;
H
hzcheng 已提交
1129

1130
    uint32_t newSize = (oldSize <= 0) ? 8 : (oldSize << 1U);
H
hzcheng 已提交
1131
    while (newSize < size) {
1132
      newSize = (newSize << 1U);
H
hzcheng 已提交
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
    }

    if (newSize > TSDB_MAX_COLUMNS) {
      newSize = TSDB_MAX_COLUMNS;
    }

    int32_t inc = newSize - oldSize;

    pExprInfo->pExprs = realloc(pExprInfo->pExprs, newSize * sizeof(SSqlExpr));
    memset(&pExprInfo->pExprs[oldSize], 0, inc * sizeof(SSqlExpr));

    pExprInfo->numOfAlloc = newSize;
  }
}

static void _exprEvic(SSqlExprInfo* pExprInfo, int32_t index) {
  if (index < pExprInfo->numOfExprs) {
    memmove(&pExprInfo->pExprs[index + 1], &pExprInfo->pExprs[index],
            sizeof(pExprInfo->pExprs[0]) * (pExprInfo->numOfExprs - index));
  }
}

1155 1156
SSqlExpr* tscSqlExprInsertEmpty(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId) {
  SSqlExprInfo* pExprInfo = &pQueryInfo->exprsInfo;
H
hjxilinx 已提交
1157

H
hjxilinx 已提交
1158 1159
  _exprCheckSpace(pExprInfo, pExprInfo->numOfExprs + 1);
  _exprEvic(pExprInfo, index);
H
hjxilinx 已提交
1160 1161
  
  SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr));
H
hjxilinx 已提交
1162
  pExpr->functionId = functionId;
H
hjxilinx 已提交
1163
  
H
hjxilinx 已提交
1164
  pExprInfo->numOfExprs++;
H
hjxilinx 已提交
1165
  pExprInfo->pExprs[index] = pExpr;
H
hjxilinx 已提交
1166 1167 1168
  return pExpr;
}

1169 1170
SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex,
                           int16_t type, int16_t size, int16_t interSize) {
H
hjxilinx 已提交
1171
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pColIndex->tableIndex);
S
slguan 已提交
1172

1173
  SSqlExprInfo* pExprInfo = &pQueryInfo->exprsInfo;
H
hzcheng 已提交
1174 1175 1176 1177

  _exprCheckSpace(pExprInfo, pExprInfo->numOfExprs + 1);
  _exprEvic(pExprInfo, index);

H
hjxilinx 已提交
1178 1179 1180
  SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr));
  pExprInfo->pExprs[index] = pExpr;
  
S
slguan 已提交
1181
  pExpr->functionId = functionId;
1182
  
H
hjxilinx 已提交
1183
  int16_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
1184
  
S
slguan 已提交
1185 1186 1187 1188
  // set the correct column index
  if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
    pExpr->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX;
  } else {
H
hjxilinx 已提交
1189
    SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex);
S
slguan 已提交
1190 1191 1192 1193 1194 1195
    pExpr->colInfo.colId = pSchema->colId;
  }

  // tag columns require the column index revised.
  if (pColIndex->columnIndex >= numOfCols) {
    pExpr->colInfo.flag = TSDB_COL_TAG;
H
hzcheng 已提交
1196
  } else {
S
slguan 已提交
1197 1198 1199 1200 1201
    if (pColIndex->columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
      pExpr->colInfo.flag = TSDB_COL_NORMAL;
    } else {
      pExpr->colInfo.flag = TSDB_COL_TAG;
    }
H
hzcheng 已提交
1202 1203
  }

1204
  pExpr->colInfo.colIndex = pColIndex->columnIndex;
H
hzcheng 已提交
1205 1206
  pExpr->resType = type;
  pExpr->resBytes = size;
S
slguan 已提交
1207
  pExpr->interResBytes = interSize;
H
hjxilinx 已提交
1208
  pExpr->uid = pTableMetaInfo->pTableMeta->uid;
H
hzcheng 已提交
1209 1210 1211 1212 1213

  pExprInfo->numOfExprs++;
  return pExpr;
}

1214 1215
SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex,
                           int16_t type, int16_t size) {
H
hjxilinx 已提交
1216
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
1217
  SSqlExprInfo*   pExprInfo = &pQueryInfo->exprsInfo;
H
hzcheng 已提交
1218 1219 1220 1221
  if (index > pExprInfo->numOfExprs) {
    return NULL;
  }

H
hjxilinx 已提交
1222
  SSqlExpr* pExpr = pExprInfo->pExprs[index];
H
hzcheng 已提交
1223

S
slguan 已提交
1224
  pExpr->functionId = functionId;
H
hzcheng 已提交
1225

1226
  pExpr->colInfo.colIndex = srcColumnIndex;
H
hjxilinx 已提交
1227
  pExpr->colInfo.colId = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, srcColumnIndex)->colId;
H
hzcheng 已提交
1228 1229 1230 1231 1232 1233 1234

  pExpr->resType = type;
  pExpr->resBytes = size;

  return pExpr;
}

H
hjxilinx 已提交
1235 1236 1237 1238
int32_t  tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo) {
  return pQueryInfo->exprsInfo.numOfExprs;
}

S
slguan 已提交
1239
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes, int16_t tableIndex) {
H
hzcheng 已提交
1240 1241 1242 1243 1244 1245
  if (pExpr == NULL || argument == NULL || bytes == 0) {
    return;
  }

  // set parameter value
  // transfer to tVariant from byte data/no ascii data
S
slguan 已提交
1246
  tVariantCreateFromBinary(&pExpr->param[pExpr->numOfParams], argument, bytes, type);
H
hzcheng 已提交
1247 1248 1249 1250 1251

  pExpr->numOfParams += 1;
  assert(pExpr->numOfParams <= 3);
}

1252 1253
SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index) {
  if (pQueryInfo->exprsInfo.numOfExprs <= index) {
H
hzcheng 已提交
1254 1255 1256
    return NULL;
  }

H
hjxilinx 已提交
1257
  return pQueryInfo->exprsInfo.pExprs[index];
H
hzcheng 已提交
1258 1259
}

H
hjxilinx 已提交
1260 1261 1262 1263 1264 1265 1266 1267 1268
void* tscSqlExprDestroy(SSqlExpr* pExpr) {
  if (pExpr == NULL) {
    return NULL;
  }
  
  for(int32_t i = 0; i < tListLen(pExpr->param); ++i) {
    tVariantDestroy(&pExpr->param[i]);
  }
  
H
hjxilinx 已提交
1269 1270
  tfree(pExpr);
  
H
hjxilinx 已提交
1271
  return NULL;
H
hzcheng 已提交
1272 1273
}

H
hjxilinx 已提交
1274 1275 1276 1277 1278 1279 1280 1281
/*
 * NOTE: Does not release SSqlExprInfo here.
 */
void tscSqlExprInfoDestroy(SSqlExprInfo* pExprInfo) {
  if (pExprInfo->numOfAlloc == 0) {
    return;
  }
  
H
hjxilinx 已提交
1282 1283
  for(int32_t i = 0; i < pExprInfo->numOfExprs; ++i) {
    tscSqlExprDestroy(pExprInfo->pExprs[i]);
H
hjxilinx 已提交
1284 1285 1286 1287 1288 1289 1290 1291
  }
  
  tfree(pExprInfo->pExprs);
  
  pExprInfo->numOfAlloc = 0;
  pExprInfo->numOfExprs = 0;
}

H
hjxilinx 已提交
1292
void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t tableuid, bool deepcopy) {
1293
  if (src == NULL || src->numOfExprs == 0) {
H
hzcheng 已提交
1294 1295 1296 1297 1298
    return;
  }

  *dst = *src;

H
hjxilinx 已提交
1299 1300
  dst->pExprs = calloc(dst->numOfAlloc, POINTER_BYTES);
  
S
slguan 已提交
1301 1302
  int16_t num = 0;
  for (int32_t i = 0; i < src->numOfExprs; ++i) {
H
hjxilinx 已提交
1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
    if (src->pExprs[i]->uid == tableuid) {
      
      if (deepcopy) {
        dst->pExprs[num] = calloc(1, sizeof(SSqlExpr));
        *dst->pExprs[num] = *src->pExprs[i];
      } else {
        dst->pExprs[num] = src->pExprs[i];
      }
      
      num++;
S
slguan 已提交
1313 1314
    }
  }
H
hzcheng 已提交
1315

S
slguan 已提交
1316
  dst->numOfExprs = num;
H
hjxilinx 已提交
1317 1318 1319 1320 1321 1322
  
  if (deepcopy) {
    for (int32_t i = 0; i < dst->numOfExprs; ++i) {
      for (int32_t j = 0; j < src->pExprs[i]->numOfParams; ++j) {
        tVariantAssign(&dst->pExprs[i]->param[j], &src->pExprs[i]->param[j]);
      }
H
hzcheng 已提交
1323 1324 1325 1326
    }
  }
}

1327
SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) {
S
slguan 已提交
1328 1329
  // ignore the tbname column to be inserted into source list
  if (pColIndex->columnIndex < 0) {
H
hzcheng 已提交
1330 1331
    return NULL;
  }
1332 1333
  
  size_t numOfCols = taosArrayGetSize(pColumnList);
S
slguan 已提交
1334 1335
  int16_t col = pColIndex->columnIndex;

H
hzcheng 已提交
1336
  int32_t i = 0;
1337 1338 1339
  while (i < numOfCols) {
    SColumn* pCol = taosArrayGetP(pColumnList, i);
    if (pCol->colIndex.columnIndex < col) {
S
slguan 已提交
1340
      i++;
1341
    } else if (pCol->colIndex.tableIndex < pColIndex->tableIndex) {
S
slguan 已提交
1342 1343 1344 1345
      i++;
    } else {
      break;
    }
H
hzcheng 已提交
1346 1347
  }

1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361
  if (i >= numOfCols || numOfCols == 0) {
    SColumn* b = calloc(1, sizeof(SColumn));
    b->colIndex = *pColIndex;
    
    taosArrayInsert(pColumnList, i, &b);
  } else {
    SColumn* pCol = taosArrayGetP(pColumnList, i);
  
    if (i < numOfCols && (pCol->colIndex.columnIndex > col || pCol->colIndex.tableIndex != pColIndex->tableIndex)) {
      SColumn* b = calloc(1, sizeof(SColumn));
      b->colIndex = *pColIndex;
      
      taosArrayInsert(pColumnList, i, &b);
    }
H
hzcheng 已提交
1362 1363
  }

1364
  return taosArrayGetP(pColumnList, i);
H
hzcheng 已提交
1365 1366
}

1367 1368 1369 1370 1371 1372 1373
SColumnFilterInfo* tscFilterInfoClone(const SColumnFilterInfo* src, int32_t numOfFilters) {
  SColumnFilterInfo* pFilter = NULL;
  if (numOfFilters > 0) {
    pFilter = calloc(1, numOfFilters * sizeof(SColumnFilterInfo));
  } else {
    assert(src == NULL);
    return NULL;
S
slguan 已提交
1374
  }
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
  
  memcpy(pFilter, src, sizeof(SColumnFilterInfo) * numOfFilters);
  for (int32_t j = 0; j < numOfFilters; ++j) {
    if (pFilter[j].filterstr) {
      size_t len = (size_t) pFilter[j].len + 1;
  
      char*  pTmp   = calloc(1, len);
      pFilter[j].pz = (int64_t) pTmp;
      
      memcpy((char*)pFilter[j].pz, (char*)src->pz, (size_t)len);
    }
S
slguan 已提交
1386
  }
1387 1388 1389 1390 1391
  
  assert(src->filterstr == 0 || src->filterstr == 1);
  assert(!(src->lowerRelOptr == TSDB_RELATION_INVALID && src->upperRelOptr == TSDB_RELATION_INVALID));
  
  return pFilter;
S
slguan 已提交
1392 1393
}

1394 1395 1396 1397
static void destroyFilterInfo(SColumnFilterInfo* pFilterInfo, int32_t numOfFilters) {
  for(int32_t i = 0; i < numOfFilters; ++i) {
    if (pFilterInfo[i].filterstr) {
      tfree(pFilterInfo[i].pz);
S
slguan 已提交
1398 1399
    }
  }
1400 1401
  
  tfree(pFilterInfo);
S
slguan 已提交
1402 1403
}

1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421
SColumn* tscColumnClone(const SColumn* src) {
  assert(src != NULL);
  
  SColumn* dst = calloc(1, sizeof(SColumn));
  
  dst->colIndex     = src->colIndex;
  dst->numOfFilters = src->numOfFilters;
  dst->filterInfo   = tscFilterInfoClone(src->filterInfo, src->numOfFilters);
  
  return dst;
}

static void tscColumnDestroy(SColumn* pCol) {
  destroyFilterInfo(pCol->filterInfo, pCol->numOfFilters);
  free(pCol);
}

void tscColumnListAssign(SArray* dst, const SArray* src, int16_t tableIndex) {
H
hzcheng 已提交
1422 1423 1424
  if (src == NULL) {
    return;
  }
1425 1426 1427 1428
  
  size_t num = taosArrayGetSize(src);
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(src, i);
H
hzcheng 已提交
1429

1430 1431 1432
    if (pCol->colIndex.tableIndex == tableIndex || tableIndex < 0) {
      SColumn* p = tscColumnClone(pCol);
      taosArrayPush(dst, &p);
S
slguan 已提交
1433 1434
    }
  }
H
hzcheng 已提交
1435 1436
}

1437
void tscColumnListDestroy(SArray* pColumnBaseInfo) {
S
slguan 已提交
1438 1439 1440 1441
  if (pColumnBaseInfo == NULL) {
    return;
  }

1442 1443 1444 1445
  size_t num = taosArrayGetSize(pColumnBaseInfo);
  for (int32_t i = 0; i < num; ++i) {
    SColumn* pCol = taosArrayGetP(pColumnBaseInfo, i);
    tscColumnDestroy(pCol);
S
slguan 已提交
1446 1447
  }

1448
  taosArrayDestroy(pColumnBaseInfo);
1449
}
H
hzcheng 已提交
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465

/*
 * 1. normal name, not a keyword or number
 * 2. name with quote
 * 3. string with only one delimiter '.'.
 *
 * only_one_part
 * 'only_one_part'
 * first_part.second_part
 * first_part.'second_part'
 * 'first_part'.second_part
 * 'first_part'.'second_part'
 * 'first_part.second_part'
 *
 */
static int32_t validateQuoteToken(SSQLToken* pToken) {
H
huili 已提交
1466
  pToken->n = strdequote(pToken->z);
H
hzcheng 已提交
1467 1468 1469 1470
  strtrim(pToken->z);
  pToken->n = (uint32_t)strlen(pToken->z);

  int32_t k = tSQLGetToken(pToken->z, &pToken->type);
1471

H
huili 已提交
1472 1473
  if (pToken->type == TK_STRING) {
    return tscValidateName(pToken);
S
slguan 已提交
1474
  }
H
hzcheng 已提交
1475

H
huili 已提交
1476 1477 1478
  if (k != pToken->n || pToken->type != TK_ID) {
    return TSDB_CODE_INVALID_SQL;
  }
H
hzcheng 已提交
1479 1480 1481 1482 1483 1484 1485 1486
  return TSDB_CODE_SUCCESS;
}

int32_t tscValidateName(SSQLToken* pToken) {
  if (pToken->type != TK_STRING && pToken->type != TK_ID) {
    return TSDB_CODE_INVALID_SQL;
  }

S
slguan 已提交
1487
  char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
H
hzcheng 已提交
1488 1489
  if (sep == NULL) {  // single part
    if (pToken->type == TK_STRING) {
H
huili 已提交
1490 1491 1492
      pToken->n = strdequote(pToken->z);
      strtrim(pToken->z);
      pToken->n = (uint32_t)strlen(pToken->z);
S
slguan 已提交
1493 1494 1495 1496

      int len = tSQLGetToken(pToken->z, &pToken->type);

      // single token, validate it
1497
      if (len == pToken->n) {
H
huili 已提交
1498
        return validateQuoteToken(pToken);
S
slguan 已提交
1499
      } else {
1500 1501 1502 1503
        sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
        if (sep == NULL) {
          return TSDB_CODE_INVALID_SQL;
        }
S
slguan 已提交
1504

H
huili 已提交
1505
        return tscValidateName(pToken);
1506
      }
H
hzcheng 已提交
1507 1508 1509 1510 1511 1512 1513 1514 1515
    } else {
      if (isNumber(pToken)) {
        return TSDB_CODE_INVALID_SQL;
      }
    }
  } else {  // two part
    int32_t oldLen = pToken->n;
    char*   pStr = pToken->z;

H
huili 已提交
1516 1517
    if (pToken->type == TK_SPACE) {
      strtrim(pToken->z);
S
slguan 已提交
1518
      pToken->n = (uint32_t)strlen(pToken->z);
H
huili 已提交
1519 1520
    }

H
hzcheng 已提交
1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548
    pToken->n = tSQLGetToken(pToken->z, &pToken->type);
    if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) {
      return TSDB_CODE_INVALID_SQL;
    }

    if (pToken->type != TK_STRING && pToken->type != TK_ID) {
      return TSDB_CODE_INVALID_SQL;
    }

    if (pToken->type == TK_STRING && validateQuoteToken(pToken) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_INVALID_SQL;
    }

    int32_t firstPartLen = pToken->n;

    pToken->z = sep + 1;
    pToken->n = oldLen - (sep - pStr) - 1;
    int32_t len = tSQLGetToken(pToken->z, &pToken->type);
    if (len != pToken->n || (pToken->type != TK_STRING && pToken->type != TK_ID)) {
      return TSDB_CODE_INVALID_SQL;
    }

    if (pToken->type == TK_STRING && validateQuoteToken(pToken) != TSDB_CODE_SUCCESS) {
      return TSDB_CODE_INVALID_SQL;
    }

    // re-build the whole name string
    if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) {
H
hjxilinx 已提交
1549
      // first part do not have quote do nothing
H
hzcheng 已提交
1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570
    } else {
      pStr[firstPartLen] = TS_PATH_DELIMITER[0];
      memmove(&pStr[firstPartLen + 1], pToken->z, pToken->n);
      pStr[firstPartLen + sizeof(TS_PATH_DELIMITER[0]) + pToken->n] = 0;
    }
    pToken->n += (firstPartLen + sizeof(TS_PATH_DELIMITER[0]));
    pToken->z = pStr;
  }

  return TSDB_CODE_SUCCESS;
}

void tscIncStreamExecutionCount(void* pStream) {
  if (pStream == NULL) {
    return;
  }

  SSqlStream* ps = (SSqlStream*)pStream;
  ps->num += 1;
}

H
hjxilinx 已提交
1571 1572
bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId) {
  if (pTableMetaInfo->pTableMeta == NULL) {
H
hzcheng 已提交
1573 1574 1575
    return false;
  }

H
hjxilinx 已提交
1576
  if (colId == -1 && UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
H
hzcheng 已提交
1577 1578 1579
    return true;
  }

H
hjxilinx 已提交
1580
  SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
1581
  STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
H
hjxilinx 已提交
1582 1583
  
  int32_t  numOfTotal = tinfo.numOfTags + tinfo.numOfColumns;
H
hzcheng 已提交
1584 1585 1586 1587 1588 1589 1590 1591 1592 1593

  for (int32_t i = 0; i < numOfTotal; ++i) {
    if (pSchema[i].colId == colId) {
      return true;
    }
  }

  return false;
}

S
slguan 已提交
1594 1595
void tscTagCondCopy(STagCond* dest, const STagCond* src) {
  memset(dest, 0, sizeof(STagCond));
H
hjxilinx 已提交
1596

H
hjxilinx 已提交
1597 1598 1599
  if (src->tbnameCond.cond != NULL) {
    dest->tbnameCond.cond = strdup(src->tbnameCond.cond);
  }
S
slguan 已提交
1600 1601 1602 1603

  dest->tbnameCond.uid = src->tbnameCond.uid;

  memcpy(&dest->joinInfo, &src->joinInfo, sizeof(SJoinInfo));
1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623
  dest->relType = src->relType;
  
  if (src->pCond == NULL) {
    return;
  }
  
  size_t s = taosArrayGetSize(src->pCond);
  dest->pCond = taosArrayInit(s, sizeof(SCond));
  
  for (int32_t i = 0; i < s; ++i) {
    SCond* pCond = taosArrayGet(src->pCond, i);
    
    SCond c = {0};
    c.len = pCond->len;
    c.uid = pCond->uid;
    
    if (pCond->len > 0) {
      assert(pCond->cond != NULL);
      c.cond = malloc(c.len);
      memcpy(c.cond, pCond->cond, c.len);
H
hjxilinx 已提交
1624
    }
1625 1626
    
    taosArrayPush(dest->pCond, &c);
H
hzcheng 已提交
1627 1628 1629
  }
}

1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640
void tscTagCondRelease(STagCond* pTagCond) {
  free(pTagCond->tbnameCond.cond);
  
  if (pTagCond->pCond != NULL) {
    size_t s = taosArrayGetSize(pTagCond->pCond);
    for (int32_t i = 0; i < s; ++i) {
      SCond* p = taosArrayGet(pTagCond->pCond, i);
      tfree(p->cond);
    }
  
    taosArrayDestroy(pTagCond->pCond);
H
hzcheng 已提交
1641 1642
  }

1643
  memset(pTagCond, 0, sizeof(STagCond));
H
hzcheng 已提交
1644 1645
}

1646
void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) {
H
hjxilinx 已提交
1647
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
1648
  SSchema*        pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
1649

1650 1651
  for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
    SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
1652
    pColInfo[i].functionId = pExpr->functionId;
H
hzcheng 已提交
1653

S
slguan 已提交
1654
    if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
H
hjxilinx 已提交
1655
      SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
1656
      int16_t  actualTagIndex = pTableMetaInfo->tagColumnIndex[pExpr->colInfo.colIndex];
H
hzcheng 已提交
1657 1658 1659

      pColInfo[i].type = (actualTagIndex != -1) ? pTagSchema[actualTagIndex].type : TSDB_DATA_TYPE_BINARY;
    } else {
1660
      pColInfo[i].type = pSchema[pExpr->colInfo.colIndex].type;
H
hzcheng 已提交
1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672
    }
  }
}

void tscSetFreeHeatBeat(STscObj* pObj) {
  if (pObj == NULL || pObj->signature != pObj || pObj->pHb == NULL) {
    return;
  }

  SSqlObj* pHeatBeat = pObj->pHb;
  assert(pHeatBeat == pHeatBeat->signature);

S
slguan 已提交
1673
  // to denote the heart-beat timer close connection and free all allocated resources
1674 1675
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pHeatBeat->cmd, 0);
  pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE;
H
hzcheng 已提交
1676 1677 1678 1679
}

bool tscShouldFreeHeatBeat(SSqlObj* pHb) {
  assert(pHb == pHb->signature);
1680 1681 1682

  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pHb->cmd, 0);
  return pQueryInfo->type == TSDB_QUERY_TYPE_FREE_RESOURCE;
H
hzcheng 已提交
1683 1684 1685
}

void tscCleanSqlCmd(SSqlCmd* pCmd) {
1686 1687
  pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
  tscFreeSubqueryInfo(pCmd);
H
hzcheng 已提交
1688

S
slguan 已提交
1689 1690
  uint32_t allocSize = pCmd->allocSize;
  char*    allocPtr = pCmd->payload;
H
hzcheng 已提交
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715

  memset(pCmd, 0, sizeof(SSqlCmd));

  // restore values
  pCmd->allocSize = allocSize;
  pCmd->payload = allocPtr;
}

/*
 * the following three kinds of SqlObj should not be freed
 * 1. SqlObj for stream computing
 * 2. main SqlObj
 * 3. heartbeat SqlObj
 *
 * If res code is error and SqlObj does not belong to above types, it should be
 * automatically freed for async query, ignoring that connection should be kept.
 *
 * If connection need to be recycled, the SqlObj also should be freed.
 */
bool tscShouldFreeAsyncSqlObj(SSqlObj* pSql) {
  if (pSql == NULL || pSql->signature != pSql || pSql->fp == NULL) {
    return false;
  }

  STscObj* pTscObj = pSql->pTscObj;
1716
  if (pSql->pStream != NULL || pTscObj->pHb == pSql || pTscObj->pSql == pSql) {
H
hzcheng 已提交
1717 1718 1719 1720
    return false;
  }

  int32_t command = pSql->cmd.command;
1721
  if (command == TSDB_SQL_CONNECT || command == TSDB_SQL_INSERT) {
1722
    return true;
H
hzcheng 已提交
1723 1724 1725 1726 1727 1728
  } else {
    return tscKeepConn[command] == 0 ||
           (pSql->res.code != TSDB_CODE_ACTION_IN_PROGRESS && pSql->res.code != TSDB_CODE_SUCCESS);
  }
}

1729 1730 1731
/**
 *
 * @param pCmd
1732
 * @param clauseIndex denote the index of the union sub clause, usually are 0, if no union query exists.
1733 1734 1735
 * @param tableIndex  denote the table index for join query, where more than one table exists
 * @return
 */
1736
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd* pCmd, int32_t clauseIndex, int32_t tableIndex) {
1737
  if (pCmd == NULL || pCmd->numOfClause == 0) {
S
slguan 已提交
1738 1739 1740
    return NULL;
  }

1741
  assert(clauseIndex >= 0 && clauseIndex < pCmd->numOfClause);
1742

1743
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
H
hjxilinx 已提交
1744
  return tscGetMetaInfo(pQueryInfo, tableIndex);
S
slguan 已提交
1745 1746
}

H
hjxilinx 已提交
1747
STableMetaInfo* tscGetMetaInfo(SQueryInfo* pQueryInfo, int32_t tableIndex) {
H
hjxilinx 已提交
1748
  assert(pQueryInfo != NULL);
1749

H
hjxilinx 已提交
1750
  if (pQueryInfo->pTableMetaInfo == NULL) {
1751 1752 1753 1754
    assert(pQueryInfo->numOfTables == 0);
    return NULL;
  }

H
hjxilinx 已提交
1755
  assert(tableIndex >= 0 && tableIndex <= pQueryInfo->numOfTables && pQueryInfo->pTableMetaInfo != NULL);
1756

H
hjxilinx 已提交
1757
  return pQueryInfo->pTableMetaInfo[tableIndex];
1758 1759 1760
}

SQueryInfo* tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex) {
1761
  assert(pCmd != NULL && subClauseIndex >= 0 && subClauseIndex < TSDB_MAX_UNION_CLAUSE);
1762

1763
  if (pCmd->pQueryInfo == NULL || subClauseIndex >= pCmd->numOfClause) {
1764 1765 1766 1767 1768 1769
    return NULL;
  }

  return pCmd->pQueryInfo[subClauseIndex];
}

1770
int32_t tscGetQueryInfoDetailSafely(SSqlCmd* pCmd, int32_t subClauseIndex, SQueryInfo** pQueryInfo) {
1771
  int32_t ret = TSDB_CODE_SUCCESS;
1772

1773
  *pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
1774

1775 1776 1777 1778
  while ((*pQueryInfo) == NULL) {
    if ((ret = tscAddSubqueryInfo(pCmd)) != TSDB_CODE_SUCCESS) {
      return ret;
    }
1779

1780 1781
    (*pQueryInfo) = tscGetQueryInfoDetail(pCmd, subClauseIndex);
  }
1782

1783 1784 1785
  return TSDB_CODE_SUCCESS;
}

H
hjxilinx 已提交
1786
STableMetaInfo* tscGetMeterMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, int32_t* index) {
S
slguan 已提交
1787
  int32_t k = -1;
1788 1789

  for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
H
hjxilinx 已提交
1790
    if (pQueryInfo->pTableMetaInfo[i]->pTableMeta->uid == uid) {
S
slguan 已提交
1791 1792 1793 1794 1795 1796 1797 1798 1799
      k = i;
      break;
    }
  }

  if (index != NULL) {
    *index = k;
  }

H
hjxilinx 已提交
1800
  assert(k != -1);
H
hjxilinx 已提交
1801
  return tscGetMetaInfo(pQueryInfo, k);
S
slguan 已提交
1802 1803
}

1804
int32_t tscAddSubqueryInfo(SSqlCmd* pCmd) {
1805
  assert(pCmd != NULL);
1806 1807 1808

  size_t s = pCmd->numOfClause + 1;
  char*  tmp = realloc(pCmd->pQueryInfo, s * POINTER_BYTES);
1809 1810 1811
  if (tmp == NULL) {
    return TSDB_CODE_CLI_OUT_OF_MEMORY;
  }
1812 1813 1814 1815 1816 1817 1818

  pCmd->pQueryInfo = (SQueryInfo**)tmp;

  SQueryInfo* pQueryInfo = calloc(1, sizeof(SQueryInfo));
  pQueryInfo->msg = pCmd->payload;  // pointer to the parent error message buffer

  pCmd->pQueryInfo[pCmd->numOfClause++] = pQueryInfo;
1819 1820 1821
  return TSDB_CODE_SUCCESS;
}

1822
static void doClearSubqueryInfo(SQueryInfo* pQueryInfo) {
1823 1824
  tscTagCondRelease(&pQueryInfo->tagCond);
  tscClearFieldInfo(&pQueryInfo->fieldsInfo);
1825

H
hjxilinx 已提交
1826
  tscSqlExprInfoDestroy(&pQueryInfo->exprsInfo);
1827
  memset(&pQueryInfo->exprsInfo, 0, sizeof(pQueryInfo->exprsInfo));
1828

1829
  tscColumnListDestroy(pQueryInfo->colList);
1830
  memset(&pQueryInfo->colList, 0, sizeof(pQueryInfo->colList));
1831

1832
  pQueryInfo->tsBuf = tsBufDestory(pQueryInfo->tsBuf);
1833

1834
  tfree(pQueryInfo->defaultVal);
1835
}
1836

1837
void tscClearSubqueryInfo(SSqlCmd* pCmd) {
1838
  for (int32_t i = 0; i < pCmd->numOfClause; ++i) {
1839 1840
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);
    doClearSubqueryInfo(pQueryInfo);
1841
  }
1842 1843 1844 1845 1846 1847 1848 1849
}

void tscFreeSubqueryInfo(SSqlCmd* pCmd) {
  if (pCmd == NULL || pCmd->numOfClause == 0) {
    return;
  }

  for (int32_t i = 0; i < pCmd->numOfClause; ++i) {
1850 1851 1852
    char* addr = (char*)pCmd - offsetof(SSqlObj, cmd);
    SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);

1853
    doClearSubqueryInfo(pQueryInfo);
1854
    tscRemoveAllMeterMetaInfo(pQueryInfo, (const char*)addr, false);
1855
    tfree(pQueryInfo);
1856
  }
1857

1858 1859 1860 1861
  pCmd->numOfClause = 0;
  tfree(pCmd->pQueryInfo);
}

1862
STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta,
1863
                                    SVgroupsInfo* vgroupList, int16_t numOfTags, int16_t* tags) {
H
hjxilinx 已提交
1864
  void* pAlloc = realloc(pQueryInfo->pTableMetaInfo, (pQueryInfo->numOfTables + 1) * POINTER_BYTES);
S
slguan 已提交
1865 1866 1867 1868
  if (pAlloc == NULL) {
    return NULL;
  }

H
hjxilinx 已提交
1869 1870
  pQueryInfo->pTableMetaInfo = pAlloc;
  pQueryInfo->pTableMetaInfo[pQueryInfo->numOfTables] = calloc(1, sizeof(STableMetaInfo));
S
slguan 已提交
1871

H
hjxilinx 已提交
1872
  STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[pQueryInfo->numOfTables];
H
hjxilinx 已提交
1873
  assert(pTableMetaInfo != NULL);
S
slguan 已提交
1874 1875

  if (name != NULL) {
S
slguan 已提交
1876
    assert(strlen(name) <= TSDB_TABLE_ID_LEN);
H
hjxilinx 已提交
1877
    strcpy(pTableMetaInfo->name, name);
S
slguan 已提交
1878 1879
  }

H
hjxilinx 已提交
1880 1881
  pTableMetaInfo->pTableMeta = pTableMeta;
  pTableMetaInfo->numOfTags = numOfTags;
1882 1883
  
  if (vgroupList != NULL) {
H
hjxilinx 已提交
1884 1885 1886
    assert(vgroupList->numOfVgroups == 1);  // todo fix me
    
    size_t size = sizeof(SVgroupsInfo) + sizeof(SCMVgroupInfo) * vgroupList->numOfVgroups;
1887 1888 1889
    
    pTableMetaInfo->vgroupList = malloc(size);
    memcpy(pTableMetaInfo->vgroupList, vgroupList, size);
1890
  }
S
slguan 已提交
1891 1892

  if (tags != NULL) {
H
hjxilinx 已提交
1893
    memcpy(pTableMetaInfo->tagColumnIndex, tags, sizeof(pTableMetaInfo->tagColumnIndex[0]) * numOfTags);
S
slguan 已提交
1894 1895
  }

1896
  pQueryInfo->numOfTables += 1;
H
hjxilinx 已提交
1897
  return pTableMetaInfo;
S
slguan 已提交
1898 1899
}

H
hjxilinx 已提交
1900
STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo* pQueryInfo) {
1901
  return tscAddTableMetaInfo(pQueryInfo, NULL, NULL, NULL, 0, NULL);
1902
}
S
slguan 已提交
1903

1904
void doRemoveTableMetaInfo(SQueryInfo* pQueryInfo, int32_t index, bool removeFromCache) {
1905
  if (index < 0 || index >= pQueryInfo->numOfTables) {
S
slguan 已提交
1906 1907 1908
    return;
  }

H
hjxilinx 已提交
1909
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index);
S
slguan 已提交
1910

H
hjxilinx 已提交
1911 1912
  tscClearMeterMetaInfo(pTableMetaInfo, removeFromCache);
  free(pTableMetaInfo);
S
slguan 已提交
1913

1914
  int32_t after = pQueryInfo->numOfTables - index - 1;
S
slguan 已提交
1915
  if (after > 0) {
H
hjxilinx 已提交
1916
    memmove(&pQueryInfo->pTableMetaInfo[index], &pQueryInfo->pTableMetaInfo[index + 1], after * POINTER_BYTES);
S
slguan 已提交
1917 1918
  }

1919
  pQueryInfo->numOfTables -= 1;
S
slguan 已提交
1920 1921
}

1922
void tscRemoveAllMeterMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache) {
1923
  tscTrace("%p deref the table meta in cache, numOfTables:%d", address, pQueryInfo->numOfTables);
S
slguan 已提交
1924

1925 1926
  int32_t index = pQueryInfo->numOfTables;
  while (index >= 0) {
1927
    doRemoveTableMetaInfo(pQueryInfo, --index, removeFromCache);
S
slguan 已提交
1928 1929
  }

H
hjxilinx 已提交
1930
  tfree(pQueryInfo->pTableMetaInfo);
S
slguan 已提交
1931 1932
}

H
hjxilinx 已提交
1933 1934
void tscClearMeterMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache) {
  if (pTableMetaInfo == NULL) {
S
slguan 已提交
1935 1936 1937
    return;
  }

H
hjxilinx 已提交
1938
  taosCacheRelease(tscCacheHandle, (void**)&(pTableMetaInfo->pTableMeta), removeFromCache);
1939
  tfree(pTableMetaInfo->vgroupList);
H
hjxilinx 已提交
1940
//  taosCacheRelease(tscCacheHandle, (void**)&(pTableMetaInfo->pMetricMeta), removeFromCache);
S
slguan 已提交
1941 1942 1943
}

void tscResetForNextRetrieve(SSqlRes* pRes) {
H
hjxilinx 已提交
1944 1945 1946
  if (pRes == NULL) {
    return;
  }
1947

S
slguan 已提交
1948 1949 1950 1951
  pRes->row = 0;
  pRes->numOfRows = 0;
}

1952
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void* param, int32_t cmd, SSqlObj* pPrevSql) {
1953
  SSqlCmd* pCmd = &pSql->cmd;
S
slguan 已提交
1954 1955
  SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj));
  if (pNew == NULL) {
1956
    tscError("%p new subquery failed, tableIndex:%d", pSql, tableIndex);
S
slguan 已提交
1957 1958
    return NULL;
  }
1959 1960
  
  STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, tableIndex);
S
slguan 已提交
1961 1962 1963 1964 1965 1966

  pNew->pTscObj = pSql->pTscObj;
  pNew->signature = pNew;

  pNew->sqlstr = strdup(pSql->sqlstr);
  if (pNew->sqlstr == NULL) {
H
hjxilinx 已提交
1967
    tscError("%p new subquery failed, tableIndex:%d, vgroupIndex:%d", pSql, tableIndex, pTableMetaInfo->vgroupIndex);
S
slguan 已提交
1968 1969 1970 1971 1972

    free(pNew);
    return NULL;
  }

1973 1974 1975 1976 1977 1978
  SSqlCmd* pnCmd = &pNew->cmd;
  memcpy(pnCmd, pCmd, sizeof(SSqlCmd));
  
  pnCmd->command = cmd;
  pnCmd->payload = NULL;
  pnCmd->allocSize = 0;
S
slguan 已提交
1979

1980 1981 1982 1983
  pnCmd->pQueryInfo = NULL;
  pnCmd->numOfClause = 0;
  pnCmd->clauseIndex = 0;
  pnCmd->pDataBlocks = NULL;
1984

1985
  if (tscAddSubqueryInfo(pnCmd) != TSDB_CODE_SUCCESS) {
1986 1987 1988
    tscFreeSqlObj(pNew);
    return NULL;
  }
1989

1990
  SQueryInfo* pNewQueryInfo = tscGetQueryInfoDetail(pnCmd, 0);
1991
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
1992 1993 1994 1995 1996

  memcpy(pNewQueryInfo, pQueryInfo, sizeof(SQueryInfo));

  memset(&pNewQueryInfo->colList, 0, sizeof(pNewQueryInfo->colList));
  memset(&pNewQueryInfo->fieldsInfo, 0, sizeof(SFieldInfo));
1997

H
hjxilinx 已提交
1998
  pNewQueryInfo->pTableMetaInfo = NULL;
1999
  pNewQueryInfo->defaultVal = NULL;
2000 2001 2002 2003
  pNewQueryInfo->numOfTables = 0;
  pNewQueryInfo->tsBuf = NULL;

  tscTagCondCopy(&pNewQueryInfo->tagCond, &pQueryInfo->tagCond);
2004

2005 2006 2007 2008
  if (pQueryInfo->interpoType != TSDB_INTERPO_NONE) {
    pNewQueryInfo->defaultVal = malloc(pQueryInfo->fieldsInfo.numOfOutputCols * sizeof(int64_t));
    memcpy(pNewQueryInfo->defaultVal, pQueryInfo->defaultVal, pQueryInfo->fieldsInfo.numOfOutputCols * sizeof(int64_t));
  }
2009

2010
  if (tscAllocPayload(pnCmd, TSDB_DEFAULT_PAYLOAD_SIZE) != TSDB_CODE_SUCCESS) {
H
hjxilinx 已提交
2011
    tscError("%p new subquery failed, tableIndex:%d, vgroupIndex:%d", pSql, tableIndex, pTableMetaInfo->vgroupIndex);
S
slguan 已提交
2012 2013 2014 2015
    tscFreeSqlObj(pNew);
    return NULL;
  }

2016
  tscColumnListAssign(pNewQueryInfo->colList, pQueryInfo->colList, (int16_t)tableIndex);
2017

S
slguan 已提交
2018 2019
  // set the correct query type
  if (pPrevSql != NULL) {
2020
    SQueryInfo* pPrevQueryInfo = tscGetQueryInfoDetail(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex);
2021
    pNewQueryInfo->type = pPrevQueryInfo->type;
S
slguan 已提交
2022
  } else {
2023
    pNewQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;  // it must be the subquery
S
slguan 已提交
2024 2025
  }

H
hjxilinx 已提交
2026
  uint64_t uid = pTableMetaInfo->pTableMeta->uid;
H
hjxilinx 已提交
2027
  tscSqlExprCopy(&pNewQueryInfo->exprsInfo, &pQueryInfo->exprsInfo, uid, true);
S
slguan 已提交
2028

2029
  int32_t numOfOutputCols = pNewQueryInfo->exprsInfo.numOfExprs;
S
slguan 已提交
2030 2031 2032

  if (numOfOutputCols > 0) {
    int32_t* indexList = calloc(1, numOfOutputCols * sizeof(int32_t));
2033 2034
    for (int32_t i = 0, j = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
      SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
S
slguan 已提交
2035 2036 2037 2038 2039
      if (pExpr->uid == uid) {
        indexList[j++] = i;
      }
    }

2040
    tscFieldInfoCopy(&pQueryInfo->fieldsInfo, &pNewQueryInfo->fieldsInfo, indexList, numOfOutputCols);
S
slguan 已提交
2041
    free(indexList);
H
hjxilinx 已提交
2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054
  
    //     make sure the the sqlExpr for each fields is correct
// todo handle the agg arithmetic expression
    for(int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutputCols; ++f) {
      char* name = pNewQueryInfo->fieldsInfo.pFields[f].name;
      for(int32_t k1 = 0; k1 < pNewQueryInfo->exprsInfo.numOfExprs; ++k1) {
        SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1);
        if (strcmp(name, pExpr1->aliasName) == 0) {
          pNewQueryInfo->fieldsInfo.pSqlExpr[f] = pExpr1;
        }
      }
    }
    
2055
    tscFieldInfoUpdateOffsetForInterResult(pNewQueryInfo);
S
slguan 已提交
2056 2057 2058 2059
  }

  pNew->fp = fp;
  pNew->param = param;
H
hjxilinx 已提交
2060

S
slguan 已提交
2061
  char key[TSDB_MAX_TAGS_LEN + 1] = {0};
2062 2063 2064
  if (cmd == TSDB_SQL_SELECT) {
    tscGetMetricMetaCacheKey(pQueryInfo, key, uid);
  }
H
hjxilinx 已提交
2065

H
hjxilinx 已提交
2066
#ifdef _DEBUG_VIEW
2067
  tscTrace("the metricmeta key is:%s", key);
H
hjxilinx 已提交
2068
#endif
H
hjxilinx 已提交
2069

2070
  char* name = pTableMetaInfo->name;
H
hjxilinx 已提交
2071
  STableMetaInfo* pFinalInfo = NULL;
S
slguan 已提交
2072 2073

  if (pPrevSql == NULL) {
2074
    STableMeta* pTableMeta = taosCacheAcquireByName(tscCacheHandle, name);
S
slguan 已提交
2075

2076
    pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pTableMeta, pTableMetaInfo->vgroupList, pTableMetaInfo->numOfTags,
H
hjxilinx 已提交
2077
                                     pTableMetaInfo->tagColumnIndex);
2078 2079
  } else {  // transfer the ownership of pTableMeta to the newly create sql object.
    STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex, 0);
2080

2081 2082 2083 2084 2085 2086
    STableMeta*  pPrevTableMeta = taosCacheTransfer(tscCacheHandle, (void**)&pPrevInfo->pTableMeta);
    SVgroupsInfo* pVgroupsInfo = pPrevInfo->vgroupList;
    pPrevInfo->vgroupList = NULL;
    
    pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pPrevTableMeta, pVgroupsInfo, pTableMetaInfo->numOfTags,
                                     pTableMetaInfo->tagColumnIndex);
S
slguan 已提交
2087 2088
  }

H
hjxilinx 已提交
2089
  assert(pFinalInfo->pTableMeta != NULL && pNewQueryInfo->numOfTables == 1);
H
hjxilinx 已提交
2090
  if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
2091
    assert(pFinalInfo->vgroupList != NULL);
S
slguan 已提交
2092
  }
H
hjxilinx 已提交
2093
  
2094
  if (cmd == TSDB_SQL_SELECT) {
2095 2096
    size_t size = taosArrayGetSize(pNewQueryInfo->colList);
    
2097 2098 2099
    tscTrace(
        "%p new subquery: %p, tableIndex:%d, vnodeIdx:%d, type:%d, exprInfo:%d, colList:%d,"
        "fieldInfo:%d, name:%s, qrang:%" PRId64 " - %" PRId64 " order:%d, limit:%" PRId64,
H
hjxilinx 已提交
2100
        pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, pNewQueryInfo->exprsInfo.numOfExprs,
2101
        size, pNewQueryInfo->fieldsInfo.numOfOutputCols, pFinalInfo->name, pNewQueryInfo->stime,
2102 2103 2104 2105
        pNewQueryInfo->etime, pNewQueryInfo->order.order, pNewQueryInfo->limit.limit);
    
    tscPrintSelectClause(pNew, 0);
  } else {
H
hjxilinx 已提交
2106
    tscTrace("%p new sub insertion: %p, vnodeIdx:%d", pSql, pNew, pTableMetaInfo->vgroupIndex);
2107
  }
2108

S
slguan 已提交
2109 2110 2111
  return pNew;
}

H
hzcheng 已提交
2112 2113
void tscDoQuery(SSqlObj* pSql) {
  SSqlCmd* pCmd = &pSql->cmd;
H
hjxilinx 已提交
2114
  
2115
  pSql->res.code = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
2116
  
H
hzcheng 已提交
2117 2118 2119 2120 2121 2122 2123
  if (pCmd->command > TSDB_SQL_LOCAL) {
    tscProcessLocalCmd(pSql);
  } else {
    if (pCmd->command == TSDB_SQL_SELECT) {
      tscAddIntoSqlList(pSql);
    }

2124 2125
    if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) {
      tscProcessMultiVnodesInsertFromFile(pSql);
H
hzcheng 已提交
2126
    } else {
S
slguan 已提交
2127
      // pSql may be released in this function if it is a async insertion.
H
hzcheng 已提交
2128
      tscProcessSql(pSql);
S
slguan 已提交
2129
    }
H
hzcheng 已提交
2130 2131
  }
}
S
slguan 已提交
2132

H
hjxilinx 已提交
2133
int16_t tscGetJoinTagColIndexByUid(STagCond* pTagCond, uint64_t uid) {
S
slguan 已提交
2134 2135 2136 2137 2138 2139
  if (pTagCond->joinInfo.left.uid == uid) {
    return pTagCond->joinInfo.left.tagCol;
  } else {
    return pTagCond->joinInfo.right.tagCol;
  }
}
2140 2141 2142

bool tscIsUpdateQuery(STscObj* pObj) {
  if (pObj == NULL || pObj->signature != pObj) {
H
hjxilinx 已提交
2143
    terrno = TSDB_CODE_DISCONNECTED;
2144 2145 2146
    return TSDB_CODE_DISCONNECTED;
  }

H
hjxilinx 已提交
2147 2148
  SSqlCmd* pCmd = &pObj->pSql->cmd;
  return ((pCmd->command >= TSDB_SQL_INSERT && pCmd->command <= TSDB_SQL_DROP_DNODE) ||
H
hjxilinx 已提交
2149 2150 2151
          TSDB_SQL_USE_DB == pCmd->command)
             ? 1
             : 0;
H
hjxilinx 已提交
2152
}
2153

H
hjxilinx 已提交
2154 2155 2156 2157 2158
int32_t tscInvalidSQLErrMsg(char* msg, const char* additionalInfo, const char* sql) {
  const char* msgFormat1 = "invalid SQL: %s";
  const char* msgFormat2 = "invalid SQL: syntax error near \"%s\" (%s)";
  const char* msgFormat3 = "invalid SQL: syntax error near \"%s\"";

H
hjxilinx 已提交
2159
  const int32_t BACKWARD_CHAR_STEP = 0;
H
hjxilinx 已提交
2160

H
hjxilinx 已提交
2161 2162 2163 2164 2165
  if (sql == NULL) {
    assert(additionalInfo != NULL);
    sprintf(msg, msgFormat1, additionalInfo);
    return TSDB_CODE_INVALID_SQL;
  }
H
hjxilinx 已提交
2166 2167

  char buf[64] = {0};  // only extract part of sql string
H
hjxilinx 已提交
2168
  strncpy(buf, (sql - BACKWARD_CHAR_STEP), tListLen(buf) - 1);
H
hjxilinx 已提交
2169

H
hjxilinx 已提交
2170 2171 2172
  if (additionalInfo != NULL) {
    sprintf(msg, msgFormat2, buf, additionalInfo);
  } else {
H
hjxilinx 已提交
2173
    sprintf(msg, msgFormat3, buf);  // no additional information for invalid sql error
H
hjxilinx 已提交
2174
  }
H
hjxilinx 已提交
2175

H
hjxilinx 已提交
2176
  return TSDB_CODE_INVALID_SQL;
2177
}
H
hjxilinx 已提交
2178

H
hjxilinx 已提交
2179 2180 2181
bool tscHasReachLimitation(SQueryInfo* pQueryInfo, SSqlRes* pRes) {
  assert(pQueryInfo != NULL && pQueryInfo->clauseLimit != 0);
  return (pQueryInfo->clauseLimit > 0 && pRes->numOfTotalInCurrentClause >= pQueryInfo->clauseLimit);
H
hjxilinx 已提交
2182
}
2183 2184

char* tscGetErrorMsgPayload(SSqlCmd* pCmd) { return pCmd->payload; }
2185 2186 2187 2188 2189

/**
 *  If current vnode query does not return results anymore (pRes->numOfRows == 0), try the next vnode if exists,
 *  in case of multi-vnode super table projection query and the result does not reach the limitation.
 */
2190
bool hasMoreVnodesToTry(SSqlObj* pSql) {
2191 2192
//  SSqlCmd* pCmd = &pSql->cmd;
//  SSqlRes* pRes = &pSql->res;
2193

2194
//  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
2195
  
2196
//  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
2197
//  if (!UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo) || (pTableMetaInfo->pMetricMeta == NULL)) {
2198
    return false;
H
hjxilinx 已提交
2199
//  }
2200
  
H
hjxilinx 已提交
2201 2202
//  int32_t totalVnode = pTableMetaInfo->pMetricMeta->numOfVnodes;
//  return pRes->numOfRows == 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
H
hjxilinx 已提交
2203
//         (!tscHasReachLimitation(pQueryInfo, pRes)) && (pTableMetaInfo->vgroupIndex < totalVnode - 1);
2204 2205
}

2206 2207 2208 2209 2210 2211
void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) {
  SSqlCmd* pCmd = &pSql->cmd;
  SSqlRes* pRes = &pSql->res;

  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);

2212 2213 2214 2215
  /*
   * no result returned from the current virtual node anymore, try the next vnode if exists
   * if case of: multi-vnode super table projection query
   */
2216
  assert(pRes->numOfRows == 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && !tscHasReachLimitation(pQueryInfo, pRes));
2217

H
hjxilinx 已提交
2218
  STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
2219 2220
  int32_t totalVnode = 0;
//  int32_t         totalVnode = pTableMetaInfo->pMetricMeta->numOfVnodes;
2221

H
hjxilinx 已提交
2222
  while (++pTableMetaInfo->vgroupIndex < totalVnode) {
2223
    tscTrace("%p current vnode:%d exhausted, try next:%d. total vnode:%d. current numOfRes:%d", pSql,
H
hjxilinx 已提交
2224
             pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVnode, pRes->numOfTotalInCurrentClause);
2225

2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237
    /*
     * update the limit and offset value for the query on the next vnode,
     * according to current retrieval results
     *
     * NOTE:
     * if the pRes->offset is larger than 0, the start returned position has not reached yet.
     * Therefore, the pRes->numOfRows, as well as pRes->numOfTotalInCurrentClause, must be 0.
     * The pRes->offset value will be updated by virtual node, during query execution.
     */
    if (pQueryInfo->clauseLimit >= 0) {
      pQueryInfo->limit.limit = pQueryInfo->clauseLimit - pRes->numOfTotalInCurrentClause;
    }
2238

2239
    pQueryInfo->limit.offset = pRes->offset;
2240

2241 2242
    assert((pRes->offset >= 0 && pRes->numOfRows == 0) || (pRes->offset == 0 && pRes->numOfRows >= 0));
    tscTrace("%p new query to next vnode, vnode index:%d, limit:%" PRId64 ", offset:%" PRId64 ", glimit:%" PRId64, pSql,
H
hjxilinx 已提交
2243
             pTableMetaInfo->vgroupIndex, pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->clauseLimit);
2244

2245 2246 2247 2248 2249 2250 2251 2252
    /*
     * For project query with super table join, the numOfSub is equalled to the number of all subqueries.
     * Therefore, we need to reset the value of numOfSubs to be 0.
     *
     * For super table join with projection query, if anyone of the subquery is exhausted, the query completed.
     */
    pSql->numOfSubs = 0;
    pCmd->command = TSDB_SQL_SELECT;
2253

2254
    tscResetForNextRetrieve(pRes);
2255

2256 2257
    // in case of async query, set the callback function
    void* fp1 = pSql->fp;
2258
    pSql->fp = fp;
2259

2260
    if (fp1 != NULL) {
2261
      assert(fp != NULL);
2262
    }
2263

2264
    int32_t ret = tscProcessSql(pSql);  // todo check for failure
2265

2266
    // in case of async query, return now
2267 2268 2269
    if (fp != NULL) {
      return;
    }
2270

2271 2272 2273 2274
    if (ret != TSDB_CODE_SUCCESS) {
      pSql->res.code = ret;
      return;
    }
2275

2276 2277 2278
    // retrieve data
    assert(pCmd->command == TSDB_SQL_SELECT);
    pCmd->command = TSDB_SQL_FETCH;
2279

2280 2281 2282 2283
    if ((ret = tscProcessSql(pSql)) != TSDB_CODE_SUCCESS) {
      pSql->res.code = ret;
      return;
    }
2284

2285 2286 2287 2288 2289
    // if the result from current virtual node are empty, try next if exists. otherwise, return the results.
    if (pRes->numOfRows > 0) {
      break;
    }
  }
2290

2291 2292 2293 2294
  if (pRes->numOfRows == 0) {
    tscTrace("%p all vnodes exhausted, prj query completed. total res:%d", pSql, totalVnode, pRes->numOfTotal);
  }
}
2295 2296 2297 2298 2299 2300 2301 2302

void tscTryQueryNextClause(SSqlObj* pSql, void (*queryFp)()) {
  SSqlCmd* pCmd = &pSql->cmd;
  SSqlRes* pRes = &pSql->res;

  // current subclause is completed, try the next subclause
  assert(pCmd->clauseIndex < pCmd->numOfClause - 1);

H
hjxilinx 已提交
2303
  pCmd->clauseIndex++;
2304 2305 2306 2307
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);

  pSql->cmd.command = pQueryInfo->command;

2308 2309 2310 2311 2312 2313
  //backup the total number of result first
  int64_t num = pRes->numOfTotal + pRes->numOfTotalInCurrentClause;
  tscFreeResData(pSql);
  
  pRes->numOfTotal = num;
  
2314
  tfree(pSql->pSubs);
2315 2316
  pSql->numOfSubs = 0;
  
2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328
  if (pSql->fp != NULL) {
    pSql->fp = queryFp;
    assert(queryFp != NULL);
  }

  tscTrace("%p try data in the next subclause:%d, total subclause:%d", pSql, pCmd->clauseIndex, pCmd->numOfClause);
  if (pCmd->command > TSDB_SQL_LOCAL) {
    tscProcessLocalCmd(pSql);
  } else {
    tscProcessSql(pSql);
  }
}