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

16
#include "os.h"
H
hzcheng 已提交
17 18 19 20 21
#include "taosmsg.h"

#include "tcache.h"
#include "tscUtil.h"
#include "tsclient.h"
H
hzcheng 已提交
22
#include "taosdef.h"
H
hzcheng 已提交
23

24
#include "qextbuffer.h"
H
hzcheng 已提交
25 26
#include "tscSecondaryMerge.h"
#include "tschemautil.h"
H
hjxilinx 已提交
27
#include "name.h"
H
hzcheng 已提交
28

H
hjxilinx 已提交
29 30
static void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, size_t valueLength);

H
hjxilinx 已提交
31
static int32_t getToStringLength(const char *pData, int32_t length, int32_t type) {
H
hzcheng 已提交
32 33 34 35 36 37 38 39 40
  char buf[512] = {0};

  int32_t len = 0;
  int32_t MAX_BOOL_TYPE_LENGTH = 5;  // max(strlen("true"), strlen("false"));
  switch (type) {
    case TSDB_DATA_TYPE_BINARY:
      return length;
    case TSDB_DATA_TYPE_NCHAR:
      return length;
S
slguan 已提交
41 42
    case TSDB_DATA_TYPE_DOUBLE: {
      double dv = 0;
L
lihui 已提交
43 44
      dv = GET_DOUBLE_VAL(pData);
      len = sprintf(buf, "%lf", dv);
S
slguan 已提交
45 46 47
      if (strncasecmp("nan", buf, 3) == 0) {
        len = 4;
      }
H
hjxilinx 已提交
48
    } break;
S
slguan 已提交
49 50
    case TSDB_DATA_TYPE_FLOAT: {
      float fv = 0;
L
lihui 已提交
51
      fv = GET_FLOAT_VAL(pData);
S
slguan 已提交
52 53 54 55
      len = sprintf(buf, "%f", fv);
      if (strncasecmp("nan", buf, 3) == 0) {
        len = 4;
      }
H
hjxilinx 已提交
56
    } break;
H
hzcheng 已提交
57 58
    case TSDB_DATA_TYPE_TIMESTAMP:
    case TSDB_DATA_TYPE_BIGINT:
H
hjxilinx 已提交
59
      len = sprintf(buf, "%" PRId64 "", *(int64_t *)pData);
H
hzcheng 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
      break;
    case TSDB_DATA_TYPE_BOOL:
      len = MAX_BOOL_TYPE_LENGTH;
      break;
    default:
      len = sprintf(buf, "%d", *(int32_t *)pData);
      break;
  };
  return len;
}

/*
 * we need to convert all data into string, so we need to sprintf all kinds of
 * non-string data into string, and record its length to get the right
 * maximum length. The length may be less or greater than its original binary length:
 * For example:
 * length((short) 1) == 1, less than sizeof(short)
 * length((uint64_t) 123456789011) > 12, greater than sizsof(uint64_t)
 */
static int32_t tscMaxLengthOfTagsFields(SSqlObj *pSql) {
H
hjxilinx 已提交
80
  STableMeta *pMeta = tscGetMeterMetaInfo(&pSql->cmd, 0, 0)->pTableMeta;
H
hzcheng 已提交
81

S
[TD-10]  
slguan 已提交
82 83
  if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
      pMeta->tableType == TSDB_STREAM_TABLE) {
H
hzcheng 已提交
84 85 86 87
    return 0;
  }

  char *   pTagValue = tsGetTagsValue(pMeta);
H
hjxilinx 已提交
88
  SSchema *pTagsSchema = tscGetTableTagSchema(pMeta);
H
hzcheng 已提交
89 90 91 92

  int32_t len = getToStringLength(pTagValue, pTagsSchema[0].bytes, pTagsSchema[0].type);

  pTagValue += pTagsSchema[0].bytes;
H
hjxilinx 已提交
93 94 95
  int32_t numOfTags = tscGetNumOfTags(pMeta);
  
  for (int32_t i = 1; i < numOfTags; ++i) {
H
hzcheng 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
    int32_t tLen = getToStringLength(pTagValue, pTagsSchema[i].bytes, pTagsSchema[i].type);
    if (len < tLen) {
      len = tLen;
    }

    pTagValue += pTagsSchema[i].bytes;
  }

  return len;
}

static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
  SSqlRes *pRes = &pSql->res;

  // one column for each row
111 112
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  
H
hjxilinx 已提交
113
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
114
  STableMeta *    pMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
115 116 117 118 119 120 121

  /*
   * tagValueCnt is to denote the number of tags columns for meter, not metric. and is to show the column data.
   * for meter, which is created according to metric, the value of tagValueCnt is not 0, and the numOfTags must be 0.
   * for metric, the value of tagValueCnt must be 0, but the numOfTags is not 0
   */

H
hjxilinx 已提交
122 123
  int32_t numOfRows = tscGetNumOfColumns(pMeta);
  int32_t totalNumOfRows = numOfRows + tscGetNumOfTags(pMeta);
H
hzcheng 已提交
124

H
hjxilinx 已提交
125 126
  if (UTIL_METER_IS_SUPERTABLE(pTableMetaInfo)) {
    numOfRows = numOfRows + tscGetNumOfTags(pMeta);
H
hzcheng 已提交
127 128 129
  }

  tscInitResObjForLocalQuery(pSql, totalNumOfRows, rowLen);
H
hjxilinx 已提交
130
  SSchema *pSchema = tscGetTableSchema(pMeta);
H
hzcheng 已提交
131 132

  for (int32_t i = 0; i < numOfRows; ++i) {
133 134
    TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, 0);
    strncpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i, pSchema[i].name,
H
hzcheng 已提交
135 136 137 138
            TSDB_COL_NAME_LEN);

    char *type = tDataTypeDesc[pSchema[i].type].aName;

139 140
    pField = tscFieldInfoGetField(pQueryInfo, 1);
    strncpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i, type, pField->bytes);
H
hzcheng 已提交
141 142 143 144 145 146

    int32_t bytes = pSchema[i].bytes;
    if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
      bytes = bytes / TSDB_NCHAR_SIZE;
    }

147 148
    pField = tscFieldInfoGetField(pQueryInfo, 2);
    *(int32_t *)(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 2) * totalNumOfRows + pField->bytes * i) = bytes;
H
hzcheng 已提交
149

150
    pField = tscFieldInfoGetField(pQueryInfo, 3);
H
hjxilinx 已提交
151
    if (i >= tscGetNumOfColumns(pMeta) && tscGetNumOfTags(pMeta) != 0) {
152
      strncpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i, "tag",
H
hzcheng 已提交
153 154 155 156
              strlen("tag") + 1);
    }
  }

H
hjxilinx 已提交
157
  if (UTIL_METER_IS_SUPERTABLE(pTableMetaInfo)) {
H
hzcheng 已提交
158 159 160 161 162 163 164
    return 0;
  }

  // the following is handle display tags value for meters created according to metric
  char *pTagValue = tsGetTagsValue(pMeta);
  for (int32_t i = numOfRows; i < totalNumOfRows; ++i) {
    // field name
165 166
    TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, 0);
    strncpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i, pSchema[i].name,
H
hzcheng 已提交
167 168 169
            TSDB_COL_NAME_LEN);

    // type name
170
    pField = tscFieldInfoGetField(pQueryInfo, 1);
H
hzcheng 已提交
171
    char *type = tDataTypeDesc[pSchema[i].type].aName;
172
    strncpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i, type, pField->bytes);
H
hzcheng 已提交
173 174 175

    // type length
    int32_t bytes = pSchema[i].bytes;
176
    pField = tscFieldInfoGetField(pQueryInfo, 2);
H
hzcheng 已提交
177 178 179 180
    if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
      bytes = bytes / TSDB_NCHAR_SIZE;
    }

181
    *(int32_t *)(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 2) * totalNumOfRows + pField->bytes * i) = bytes;
H
hzcheng 已提交
182 183

    // tag value
184 185
    pField = tscFieldInfoGetField(pQueryInfo, 3);
    char *target = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
H
hzcheng 已提交
186 187

    if (isNull(pTagValue, pSchema[i].type)) {
188
      sprintf(target, "%s", TSDB_DATA_NULL_STR);
H
hzcheng 已提交
189 190 191 192 193 194 195 196 197
    } else {
      switch (pSchema[i].type) {
        case TSDB_DATA_TYPE_BINARY:
          /* binary are not null-terminated string */
          strncpy(target, pTagValue, pSchema[i].bytes);
          break;
        case TSDB_DATA_TYPE_NCHAR:
          taosUcs4ToMbs(pTagValue, pSchema[i].bytes, target);
          break;
S
slguan 已提交
198 199
        case TSDB_DATA_TYPE_FLOAT: {
          float fv = 0;
L
lihui 已提交
200
          fv = GET_FLOAT_VAL(pTagValue);
S
slguan 已提交
201
          sprintf(target, "%f", fv);
H
hjxilinx 已提交
202
        } break;
S
slguan 已提交
203 204
        case TSDB_DATA_TYPE_DOUBLE: {
          double dv = 0;
L
lihui 已提交
205
          dv = GET_DOUBLE_VAL(pTagValue);
S
slguan 已提交
206
          sprintf(target, "%lf", dv);
H
hjxilinx 已提交
207
        } break;
H
hzcheng 已提交
208 209 210 211 212 213 214 215 216 217
        case TSDB_DATA_TYPE_TINYINT:
          sprintf(target, "%d", *(int8_t *)pTagValue);
          break;
        case TSDB_DATA_TYPE_SMALLINT:
          sprintf(target, "%d", *(int16_t *)pTagValue);
          break;
        case TSDB_DATA_TYPE_INT:
          sprintf(target, "%d", *(int32_t *)pTagValue);
          break;
        case TSDB_DATA_TYPE_BIGINT:
H
hjxilinx 已提交
218
          sprintf(target, "%" PRId64 "", *(int64_t *)pTagValue);
H
hzcheng 已提交
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
          break;
        case TSDB_DATA_TYPE_BOOL: {
          char *val = (*((int8_t *)pTagValue) == 0) ? "false" : "true";
          sprintf(target, "%s", val);
          break;
        }
        default:
          break;
      }
    }

    pTagValue += pSchema[i].bytes;
  }

  return 0;
}

static int32_t tscBuildMeterSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, int32_t typeColLength,
                                               int32_t noteColLength) {
  int32_t  rowLen = 0;
  SSqlCmd *pCmd = &pSql->cmd;
  pCmd->numOfCols = numOfCols;

242 243
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
  pQueryInfo->order.order = TSQL_SO_ASC;
H
hzcheng 已提交
244

245
  tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 0, TSDB_DATA_TYPE_BINARY, "Field", TSDB_COL_NAME_LEN);
H
hzcheng 已提交
246 247
  rowLen += TSDB_COL_NAME_LEN;

248
  tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 1, TSDB_DATA_TYPE_BINARY, "Type", typeColLength);
H
hzcheng 已提交
249 250
  rowLen += typeColLength;

251
  tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 2, TSDB_DATA_TYPE_INT, "Length", sizeof(int32_t));
H
hzcheng 已提交
252 253
  rowLen += sizeof(int32_t);

254
  tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 3, TSDB_DATA_TYPE_BINARY, "Note", noteColLength);
H
hzcheng 已提交
255
  rowLen += noteColLength;
H
hjxilinx 已提交
256 257 258 259 260 261 262
  
  //set the sqlexpr part
  SColumnIndex index = {0};
  pQueryInfo->fieldsInfo.pSqlExpr[0] = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, TSDB_COL_NAME_LEN, TSDB_COL_NAME_LEN);
  pQueryInfo->fieldsInfo.pSqlExpr[1] = tscSqlExprInsert(pQueryInfo, 1, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, typeColLength, typeColLength);
  pQueryInfo->fieldsInfo.pSqlExpr[2] = tscSqlExprInsert(pQueryInfo, 2, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), sizeof(int32_t));
  pQueryInfo->fieldsInfo.pSqlExpr[3] = tscSqlExprInsert(pQueryInfo, 3, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, noteColLength, noteColLength);
H
hzcheng 已提交
263 264 265 266 267

  return rowLen;
}

static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
268 269
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  
H
hjxilinx 已提交
270
  assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL);
H
hzcheng 已提交
271 272 273 274 275 276 277 278 279 280 281 282

  const int32_t NUM_OF_DESCRIBE_TABLE_COLUMNS = 4;
  const int32_t TYPE_COLUMN_LENGTH = 16;
  const int32_t NOTE_COLUMN_MIN_LENGTH = 8;

  int32_t note_field_length = tscMaxLengthOfTagsFields(pSql);
  if (note_field_length == 0) {
    note_field_length = NOTE_COLUMN_MIN_LENGTH;
  }

  int32_t rowLen =
      tscBuildMeterSchemaResultFields(pSql, NUM_OF_DESCRIBE_TABLE_COLUMNS, TYPE_COLUMN_LENGTH, note_field_length);
283
  tscFieldInfoCalOffset(pQueryInfo);
H
hzcheng 已提交
284 285 286 287 288 289 290
  return tscSetValueToResObj(pSql, rowLen);
}

// todo add order support
static int tscBuildMetricTagProjectionResult(SSqlObj *pSql) {
  // the result structure has been completed in sql parse, so we
  // only need to reorganize the results in the column format
S
slguan 已提交
291 292
  SSqlCmd *       pCmd = &pSql->cmd;
  SSqlRes *       pRes = &pSql->res;
293 294
  SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
  
H
hjxilinx 已提交
295
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hzcheng 已提交
296

H
hjxilinx 已提交
297 298
  SSuperTableMeta *pMetricMeta = pTableMetaInfo->pMetricMeta;
  SSchema *    pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
H
hzcheng 已提交
299 300

  int32_t vOffset[TSDB_MAX_COLUMNS] = {0};
S
slguan 已提交
301

H
hjxilinx 已提交
302 303
  for (int32_t f = 1; f < pTableMetaInfo->numOfTags; ++f) {
    int16_t tagColumnIndex = pTableMetaInfo->tagColumnIndex[f - 1];
H
hzcheng 已提交
304
    if (tagColumnIndex == -1) {
S
slguan 已提交
305
      vOffset[f] = vOffset[f - 1] + TSDB_TABLE_NAME_LEN;
H
hzcheng 已提交
306 307 308 309 310
    } else {
      vOffset[f] = vOffset[f - 1] + pSchema[tagColumnIndex].bytes;
    }
  }

S
slguan 已提交
311
  int32_t totalNumOfResults = pMetricMeta->numOfTables;
312
  int32_t rowLen = tscGetResRowLength(pQueryInfo);
H
hzcheng 已提交
313 314 315 316 317 318 319 320

  tscInitResObjForLocalQuery(pSql, totalNumOfResults, rowLen);

  int32_t rowIdx = 0;
  for (int32_t i = 0; i < pMetricMeta->numOfVnodes; ++i) {
    SVnodeSidList *pSidList = (SVnodeSidList *)((char *)pMetricMeta + pMetricMeta->list[i]);

    for (int32_t j = 0; j < pSidList->numOfSids; ++j) {
S
slguan 已提交
321
      STableSidExtInfo *pSidExt = tscGetMeterSidInfo(pSidList, j);
322 323 324
      
      for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
        SColIndexEx *pColIndex = &tscSqlExprGet(pQueryInfo, k)->colInfo;
S
slguan 已提交
325
        int16_t      offsetId = pColIndex->colIdx;
H
hzcheng 已提交
326

S
slguan 已提交
327
        assert((pColIndex->flag & TSDB_COL_TAG) != 0);
H
hzcheng 已提交
328 329

        char *      val = pSidExt->tags + vOffset[offsetId];
330
        TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, k);
H
hzcheng 已提交
331

332
        memcpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, k) * totalNumOfResults + pField->bytes * rowIdx, val,
H
hzcheng 已提交
333 334 335 336 337 338 339 340 341 342 343 344 345
               (size_t)pField->bytes);
      }
      rowIdx++;
    }
  }

  return 0;
}

static int tscBuildMetricTagSqlFunctionResult(SSqlObj *pSql) {
  SSqlCmd *pCmd = &pSql->cmd;
  SSqlRes *pRes = &pSql->res;

346 347
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
  
H
hjxilinx 已提交
348
  SSuperTableMeta *pMetricMeta = tscGetMetaInfo(pQueryInfo, 0)->pMetricMeta;
H
hzcheng 已提交
349
  int32_t      totalNumOfResults = 1;  // count function only produce one result
350
  int32_t      rowLen = tscGetResRowLength(pQueryInfo);
H
hzcheng 已提交
351 352 353 354 355

  tscInitResObjForLocalQuery(pSql, totalNumOfResults, rowLen);

  int32_t rowIdx = 0;
  for (int32_t i = 0; i < totalNumOfResults; ++i) {
356 357
    for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
      SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
H
hzcheng 已提交
358

S
slguan 已提交
359
      if (pExpr->colInfo.colIdx == -1 && pExpr->functionId == TSDB_FUNC_COUNT) {
360
        TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, k);
H
hzcheng 已提交
361

362
        memcpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, i) * totalNumOfResults + pField->bytes * rowIdx,
S
slguan 已提交
363
               &pMetricMeta->numOfTables, sizeof(pMetricMeta->numOfTables));
H
hzcheng 已提交
364 365 366 367 368 369 370 371 372 373 374 375 376
      } else {
        tscError("not support operations");
        continue;
      }
    }
    rowIdx++;
  }

  return 0;
}

static int tscProcessQueryTags(SSqlObj *pSql) {
  SSqlCmd *pCmd = &pSql->cmd;
377 378 379
  
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
  
H
hjxilinx 已提交
380
  STableMeta *pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
H
hjxilinx 已提交
381
  if (pTableMeta == NULL || tscGetNumOfTags(pTableMeta) == 0 || tscGetNumOfColumns(pTableMeta) == 0) {
H
hzcheng 已提交
382 383 384 385 386
    strcpy(pCmd->payload, "invalid table");
    pSql->res.code = TSDB_CODE_INVALID_TABLE;
    return pSql->res.code;
  }

387
  SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, 0);
S
slguan 已提交
388
  if (pExpr->functionId == TSDB_FUNC_COUNT) {
H
hzcheng 已提交
389 390 391 392 393 394
    return tscBuildMetricTagSqlFunctionResult(pSql);
  } else {
    return tscBuildMetricTagProjectionResult(pSql);
  }
}

H
hjxilinx 已提交
395
static void tscProcessCurrentUser(SSqlObj *pSql) {
396 397 398
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
H
hjxilinx 已提交
399 400 401 402 403 404 405 406 407 408 409 410
  tscSetLocalQueryResult(pSql, pSql->pTscObj->user, pExpr->aliasName, TSDB_USER_LEN);
}

static void tscProcessCurrentDB(SSqlObj *pSql) {
  char db[TSDB_DB_NAME_LEN + 1] = {0};
  extractDBName(pSql->pTscObj->db, db);
  
  // no use db is invoked before.
  if (strlen(db) == 0) {
    setNull(db, TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN);
  }
  
411 412 413
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
H
hjxilinx 已提交
414 415 416 417 418
  tscSetLocalQueryResult(pSql, db, pExpr->aliasName, TSDB_DB_NAME_LEN);
}

static void tscProcessServerVer(SSqlObj *pSql) {
  const char* v = pSql->pTscObj->sversion;
419
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
H
hjxilinx 已提交
420
  
421
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
H
hjxilinx 已提交
422 423 424 425
  tscSetLocalQueryResult(pSql, v, pExpr->aliasName, tListLen(pSql->pTscObj->sversion));
}

static void tscProcessClientVer(SSqlObj *pSql) {
426 427 428
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
H
hjxilinx 已提交
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
  tscSetLocalQueryResult(pSql, version, pExpr->aliasName, strlen(version));
}

static void tscProcessServStatus(SSqlObj *pSql) {
  STscObj* pObj = pSql->pTscObj;
  
  if (pObj->pHb != NULL) {
    if (pObj->pHb->res.code == TSDB_CODE_NETWORK_UNAVAIL) {
      pSql->res.code = TSDB_CODE_NETWORK_UNAVAIL;
      return;
    }
  } else {
    if (pSql->res.code == TSDB_CODE_NETWORK_UNAVAIL) {
      return;
    }
  }
  
446 447 448
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  
  SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
H
hjxilinx 已提交
449 450 451 452 453 454 455 456
  tscSetLocalQueryResult(pSql, "1", pExpr->aliasName, 2);
}

void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, size_t valueLength) {
  SSqlCmd *pCmd = &pSql->cmd;
  SSqlRes *pRes = &pSql->res;

  pCmd->numOfCols = 1;
457 458
  
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
459
  pQueryInfo->order.order = TSQL_SO_ASC;
460 461 462
  
  tscClearFieldInfo(&pQueryInfo->fieldsInfo);
  
463
  tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 0, TSDB_DATA_TYPE_BINARY, columnName, valueLength);
H
hjxilinx 已提交
464 465
  tscInitResObjForLocalQuery(pSql, 1, valueLength);

466
  TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, 0);
H
hjxilinx 已提交
467 468
  pQueryInfo->fieldsInfo.pSqlExpr[0] = pQueryInfo->exprsInfo.pExprs[0];
  
H
hjxilinx 已提交
469 470 471
  strncpy(pRes->data, val, pField->bytes);
}

H
hzcheng 已提交
472 473 474 475 476 477 478 479 480 481
int tscProcessLocalCmd(SSqlObj *pSql) {
  SSqlCmd *pCmd = &pSql->cmd;

  if (pCmd->command == TSDB_SQL_CFG_LOCAL) {
    pSql->res.code = (uint8_t)tsCfgDynamicOptions(pCmd->payload);
  } else if (pCmd->command == TSDB_SQL_DESCRIBE_TABLE) {
    pSql->res.code = (uint8_t)tscProcessDescribeTable(pSql);
  } else if (pCmd->command == TSDB_SQL_RETRIEVE_TAGS) {
    pSql->res.code = (uint8_t)tscProcessQueryTags(pSql);
  } else if (pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
S
slguan 已提交
482
    /*
H
hjxilinx 已提交
483 484
     * set the qhandle to be 1 in order to pass the qhandle check, and to call partial release function to
     * free allocated resources and remove the SqlObj from sql query linked list
S
slguan 已提交
485
     */
H
hjxilinx 已提交
486
    pSql->res.qhandle = 0x1;
H
hzcheng 已提交
487 488
    pSql->res.numOfRows = 0;
  } else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
489
    taosCacheEmpty(tscCacheHandle);
H
hjxilinx 已提交
490 491 492 493 494 495 496 497 498 499
  } else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
    tscProcessServerVer(pSql);
  } else if (pCmd->command == TSDB_SQL_CLI_VERSION) {
    tscProcessClientVer(pSql);
  } else if (pCmd->command == TSDB_SQL_CURRENT_USER) {
    tscProcessCurrentUser(pSql);
  } else if (pCmd->command == TSDB_SQL_CURRENT_DB) {
    tscProcessCurrentDB(pSql);
  } else if (pCmd->command == TSDB_SQL_SERV_STATUS) {
    tscProcessServStatus(pSql);
H
hzcheng 已提交
500 501 502 503 504
  } else {
    pSql->res.code = TSDB_CODE_INVALID_SQL;
    tscError("%p not support command:%d", pSql, pCmd->command);
  }

S
slguan 已提交
505
  // keep the code in local variable in order to avoid invalid read in case of async query
H
hzcheng 已提交
506 507 508 509 510 511 512 513 514 515 516 517
  int32_t code = pSql->res.code;

  if (pSql->fp != NULL) {  // callback function
    if (code == 0) {
      (*pSql->fp)(pSql->param, pSql, 0);
    } else {
      tscQueueAsyncRes(pSql);
    }
  }

  return code;
}