tscLocal.c 33.6 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
#include "taosmsg.h"

H
hzcheng 已提交
19
#include "taosdef.h"
H
Haojun Liao 已提交
20 21
#include "tcache.h"
#include "tname.h"
S
slguan 已提交
22
#include "tscLog.h"
H
Haojun Liao 已提交
23
#include "tscUtil.h"
H
hzcheng 已提交
24
#include "tschemautil.h"
H
Haojun Liao 已提交
25
#include "tsclient.h"
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
#include "taos.h"
#include "tscSubquery.h"

#define STR_NOCASE_EQUAL(str1, len1, str2, len2) ((len1 == len2) && 0 == strncasecmp(str1, str2, len1)) 

typedef enum BuildType {
  SCREATE_BUILD_TABLE = 1, 
  SCREATE_BUILD_DB    = 2, 
} BuildType; 

typedef enum Stage {
  SCREATE_CALLBACK_QUERY    = 1,
  SCREATE_CALLBACK_RETRIEVE = 2,
} Stage;

// support 'show create table'   
typedef struct SCreateBuilder {
  char sTableName[TSDB_TABLE_FNAME_LEN];
  char buf[TSDB_TABLE_FNAME_LEN];
  SSqlObj *pParentSql; 
  SSqlObj *pInterSql;
  int32_t (*fp)(void *para, char* result);
  Stage callStage;
} SCreateBuilder; 
H
Haojun Liao 已提交
50
static void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, int16_t type, size_t valueLength);
H
hjxilinx 已提交
51

H
hjxilinx 已提交
52
static int32_t getToStringLength(const char *pData, int32_t length, int32_t type) {
H
hzcheng 已提交
53 54 55 56 57 58 59 60 61
  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 已提交
62 63
    case TSDB_DATA_TYPE_DOUBLE: {
      double dv = 0;
L
lihui 已提交
64 65
      dv = GET_DOUBLE_VAL(pData);
      len = sprintf(buf, "%lf", dv);
S
slguan 已提交
66 67 68
      if (strncasecmp("nan", buf, 3) == 0) {
        len = 4;
      }
H
hjxilinx 已提交
69
    } break;
S
slguan 已提交
70 71
    case TSDB_DATA_TYPE_FLOAT: {
      float fv = 0;
L
lihui 已提交
72
      fv = GET_FLOAT_VAL(pData);
S
slguan 已提交
73 74 75 76
      len = sprintf(buf, "%f", fv);
      if (strncasecmp("nan", buf, 3) == 0) {
        len = 4;
      }
H
hjxilinx 已提交
77
    } break;
H
hzcheng 已提交
78 79
    case TSDB_DATA_TYPE_TIMESTAMP:
    case TSDB_DATA_TYPE_BIGINT:
80
      len = sprintf(buf, "%" PRId64, *(int64_t *)pData);
H
hzcheng 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
      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) {
101
  STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->pTableMeta;
H
hzcheng 已提交
102

S
[TD-10]  
slguan 已提交
103 104
  if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
      pMeta->tableType == TSDB_STREAM_TABLE) {
H
hzcheng 已提交
105 106 107 108
    return 0;
  }

  char *   pTagValue = tsGetTagsValue(pMeta);
H
hjxilinx 已提交
109
  SSchema *pTagsSchema = tscGetTableTagSchema(pMeta);
H
hzcheng 已提交
110 111 112 113

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

  pTagValue += pTagsSchema[0].bytes;
H
hjxilinx 已提交
114 115 116
  int32_t numOfTags = tscGetNumOfTags(pMeta);
  
  for (int32_t i = 1; i < numOfTags; ++i) {
H
hzcheng 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
    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
132 133
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  
H
hjxilinx 已提交
134
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
135
  STableMeta *    pMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
136 137 138 139 140 141 142

  /*
   * 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 已提交
143 144
  int32_t numOfRows = tscGetNumOfColumns(pMeta);
  int32_t totalNumOfRows = numOfRows + tscGetNumOfTags(pMeta);
H
hzcheng 已提交
145

weixin_48148422's avatar
weixin_48148422 已提交
146
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
147
    numOfRows = numOfRows + tscGetNumOfTags(pMeta);
H
hzcheng 已提交
148 149 150
  }

  tscInitResObjForLocalQuery(pSql, totalNumOfRows, rowLen);
H
hjxilinx 已提交
151
  SSchema *pSchema = tscGetTableSchema(pMeta);
H
hzcheng 已提交
152 153

  for (int32_t i = 0; i < numOfRows; ++i) {
H
hjxilinx 已提交
154
    TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
H
hjxilinx 已提交
155
    char* dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i;
H
Hui Li 已提交
156
    STR_WITH_MAXSIZE_TO_VARSTR(dst, pSchema[i].name, pField->bytes);
H
hzcheng 已提交
157 158 159

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

H
hjxilinx 已提交
160
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
H
hjxilinx 已提交
161 162
    dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i;
    
H
Hui Li 已提交
163
    STR_WITH_MAXSIZE_TO_VARSTR(dst, type, pField->bytes);
H
hjxilinx 已提交
164
    
H
hzcheng 已提交
165
    int32_t bytes = pSchema[i].bytes;
H
hjxilinx 已提交
166 167 168 169 170 171
    if (pSchema[i].type == TSDB_DATA_TYPE_BINARY || pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
      bytes -= VARSTR_HEADER_SIZE;
      
      if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
        bytes = bytes / TSDB_NCHAR_SIZE;
      }
H
hzcheng 已提交
172 173
    }

H
hjxilinx 已提交
174
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 2);
175
    *(int32_t *)(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 2) * totalNumOfRows + pField->bytes * i) = bytes;
H
hzcheng 已提交
176

H
hjxilinx 已提交
177
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 3);
H
hjxilinx 已提交
178
    if (i >= tscGetNumOfColumns(pMeta) && tscGetNumOfTags(pMeta) != 0) {
179
      char* output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
sangshuduo's avatar
sangshuduo 已提交
180
      const char *src = "TAG";
H
Hui Li 已提交
181
      STR_WITH_MAXSIZE_TO_VARSTR(output, src, pField->bytes);
H
hzcheng 已提交
182 183 184
    }
  }

weixin_48148422's avatar
weixin_48148422 已提交
185
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
186 187 188 189 190 191 192
    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
H
hjxilinx 已提交
193
    TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
194
    char* output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i;
H
Hui Li 已提交
195
    STR_WITH_MAXSIZE_TO_VARSTR(output, pSchema[i].name, pField->bytes);
H
hzcheng 已提交
196 197

    // type name
H
hjxilinx 已提交
198
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
H
hzcheng 已提交
199
    char *type = tDataTypeDesc[pSchema[i].type].aName;
200 201 202
    
    output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i;
    STR_WITH_MAXSIZE_TO_VARSTR(output, type, pField->bytes);
H
hzcheng 已提交
203 204 205

    // type length
    int32_t bytes = pSchema[i].bytes;
H
hjxilinx 已提交
206
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 2);
L
liu0x54 已提交
207 208 209 210 211 212
    if (pSchema[i].type == TSDB_DATA_TYPE_BINARY || pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
      bytes -= VARSTR_HEADER_SIZE;
      
      if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
        bytes = bytes / TSDB_NCHAR_SIZE;
      }
H
hzcheng 已提交
213 214
    }

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

    // tag value
H
hjxilinx 已提交
218
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 3);
219
    char *target = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
sangshuduo's avatar
sangshuduo 已提交
220
    const char *src = "TAG";
H
Hui Li 已提交
221
    STR_WITH_MAXSIZE_TO_VARSTR(target, src, pField->bytes);
H
hzcheng 已提交
222 223 224 225 226 227 228

    pTagValue += pSchema[i].bytes;
  }

  return 0;
}

H
hjxilinx 已提交
229
static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, int32_t typeColLength,
H
hzcheng 已提交
230 231
                                               int32_t noteColLength) {
  int32_t  rowLen = 0;
H
hjxilinx 已提交
232 233 234
  SColumnIndex index = {0};
  
  pSql->cmd.numOfCols = numOfCols;
H
hzcheng 已提交
235

H
hjxilinx 已提交
236
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
237
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
hzcheng 已提交
238

B
Bomin Zhang 已提交
239 240
  TAOS_FIELD f = {.type = TSDB_DATA_TYPE_BINARY, .bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE};
  tstrncpy(f.name, "Field", sizeof(f.name));
H
hjxilinx 已提交
241 242
  
  SFieldSupInfo* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
hjxilinx 已提交
243
  pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
B
Bomin Zhang 已提交
244
      (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, (TSDB_COL_NAME_LEN - 1), false);
H
hjxilinx 已提交
245
  
B
Bomin Zhang 已提交
246
  rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE);
H
hzcheng 已提交
247

S
TD-1057  
Shengliang Guan 已提交
248
  f.bytes = (int16_t)(typeColLength + VARSTR_HEADER_SIZE);
H
hjxilinx 已提交
249
  f.type = TSDB_DATA_TYPE_BINARY;
B
Bomin Zhang 已提交
250
  tstrncpy(f.name, "Type", sizeof(f.name));
H
hjxilinx 已提交
251 252
  
  pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
S
TD-1057  
Shengliang Guan 已提交
253
  pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE),
254
      typeColLength, false);
H
hjxilinx 已提交
255
  
H
Hui Li 已提交
256
  rowLen += typeColLength + VARSTR_HEADER_SIZE;
H
hzcheng 已提交
257

H
hjxilinx 已提交
258 259
  f.bytes = sizeof(int32_t);
  f.type = TSDB_DATA_TYPE_INT;
B
Bomin Zhang 已提交
260
  tstrncpy(f.name, "Length", sizeof(f.name));
H
hjxilinx 已提交
261 262
  
  pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
263 264
  pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t),
      sizeof(int32_t), false);
H
hjxilinx 已提交
265
  
H
hzcheng 已提交
266 267
  rowLen += sizeof(int32_t);

S
TD-1057  
Shengliang Guan 已提交
268
  f.bytes = (int16_t)(noteColLength + VARSTR_HEADER_SIZE);
H
hjxilinx 已提交
269
  f.type = TSDB_DATA_TYPE_BINARY;
B
Bomin Zhang 已提交
270
  tstrncpy(f.name, "Note", sizeof(f.name));
H
hjxilinx 已提交
271
  
H
hjxilinx 已提交
272
  pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
S
TD-1057  
Shengliang Guan 已提交
273
  pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE),
274
      noteColLength, false);
H
hjxilinx 已提交
275
  
H
Hui Li 已提交
276
  rowLen += noteColLength + VARSTR_HEADER_SIZE;
H
hzcheng 已提交
277 278 279 280
  return rowLen;
}

static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
281 282
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  
H
hjxilinx 已提交
283
  assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL);
H
hzcheng 已提交
284

H
hjxilinx 已提交
285
  const int32_t NUM_OF_DESC_TABLE_COLUMNS = 4;
H
hzcheng 已提交
286 287 288
  const int32_t TYPE_COLUMN_LENGTH = 16;
  const int32_t NOTE_COLUMN_MIN_LENGTH = 8;

H
hjxilinx 已提交
289 290 291
  int32_t noteFieldLen = tscMaxLengthOfTagsFields(pSql);
  if (noteFieldLen == 0) {
    noteFieldLen = NOTE_COLUMN_MIN_LENGTH;
H
hzcheng 已提交
292 293
  }

H
hjxilinx 已提交
294
  int32_t rowLen = tscBuildTableSchemaResultFields(pSql, NUM_OF_DESC_TABLE_COLUMNS, TYPE_COLUMN_LENGTH, noteFieldLen);
H
hjxilinx 已提交
295
  tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
296 297
  return tscSetValueToResObj(pSql, rowLen);
}
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 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 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengths, int idx, char *result) {
  const char *val = row[idx];
  if (val == NULL) {
    sprintf(result, "%s", TSDB_DATA_NULL_STR);
    return -1;
  } 
  uint8_t type = fields[idx].type;
  int32_t length = lengths[idx]; 

  switch (type) {
    case TSDB_DATA_TYPE_BOOL: 
      sprintf(result, "%s", ((((int)(*((char *)val))) == 1) ? "true" : "false"));
      break;
    case TSDB_DATA_TYPE_TINYINT:
      sprintf(result, "%d", (int)(*((char *)val)));
      break;
    case TSDB_DATA_TYPE_SMALLINT: 
      sprintf(result, "%d", (int)(*((short *)val)));
      break;
    case TSDB_DATA_TYPE_INT:
      sprintf(result, "%d", *((int *)val));
      break;
    case TSDB_DATA_TYPE_BIGINT: 
      sprintf(result, "%"PRId64, *((int64_t *)val)); 
      break;
    case TSDB_DATA_TYPE_FLOAT:
      sprintf(result, "%f", GET_FLOAT_VAL(val)); 
      break;
    case TSDB_DATA_TYPE_DOUBLE:
      sprintf(result, "%f", GET_DOUBLE_VAL(val)); 
      break;
    case TSDB_DATA_TYPE_NCHAR:
    case TSDB_DATA_TYPE_BINARY:
      memcpy(result, val, length); 
      break;
    case TSDB_DATA_TYPE_TIMESTAMP:
      ///formatTimestamp(buf, *(int64_t*)val, TSDB_TIME_PRECISION_MICRO);
      //memcpy(result, val, strlen(buf));
      sprintf(result, "%"PRId64, *((int64_t *)val)); 
      break;
    default:
      break; 
  }
  return 0;
} 

void tscSCreateCallBack(void *param, TAOS_RES *tres, int code) {
  if (param == NULL || tres == NULL) {
    return;
  }  
  SCreateBuilder *builder = (SCreateBuilder *)(param);
  SSqlObj *pParentSql = builder->pParentSql;  
  SSqlObj *pSql = (SSqlObj *)tres; 

  SSqlRes *pRes = &pParentSql->res;
  pRes->code = taos_errno(pSql); 
  if (pRes->code != TSDB_CODE_SUCCESS) {
    taos_free_result(pSql);  
    free(builder);
    tscQueueAsyncRes(pParentSql);
    return;
  }

  if (builder->callStage == SCREATE_CALLBACK_QUERY) {
    taos_fetch_rows_a(tres, tscSCreateCallBack, param);    
    builder->callStage = SCREATE_CALLBACK_RETRIEVE;
  } else {
    char *result = calloc(1, TSDB_MAX_BINARY_LEN);
    pRes->code = builder->fp(builder, result);

    taos_free_result(pSql);  
    free(builder);
    free(result);

    if (pRes->code == TSDB_CODE_SUCCESS) {
      (*pParentSql->fp)(pParentSql->param, pParentSql, code);  
    } else {
      tscQueueAsyncRes(pParentSql);
    }
  }
}

TAOS_ROW tscFetchRow(void *param) {
  SCreateBuilder *builder = (SCreateBuilder *)param;
  if (builder == NULL) {
    return NULL;
  } 
  SSqlObj *pSql = builder->pInterSql;
  if (pSql == NULL || pSql->signature != pSql) {
    terrno = TSDB_CODE_TSC_DISCONNECTED;
    return NULL;
  }
  
  SSqlCmd *pCmd = &pSql->cmd;
  SSqlRes *pRes = &pSql->res;
  
  if (pRes->qhandle == 0 ||
      pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
      pCmd->command == TSDB_SQL_INSERT) {
    return NULL;
  }

  // set the sql object owner
  tscSetSqlOwner(pSql);

  // current data set are exhausted, fetch more data from node
  if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) &&
      (pCmd->command == TSDB_SQL_RETRIEVE ||
       pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE ||
       pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE ||
       pCmd->command == TSDB_SQL_FETCH ||
       pCmd->command == TSDB_SQL_SHOW ||
       pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
       pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE ||
       pCmd->command == TSDB_SQL_SELECT ||
       pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
       pCmd->command == TSDB_SQL_SERV_STATUS ||
       pCmd->command == TSDB_SQL_CURRENT_DB ||
       pCmd->command == TSDB_SQL_SERV_VERSION ||
       pCmd->command == TSDB_SQL_CLI_VERSION ||
       pCmd->command == TSDB_SQL_CURRENT_USER )) {
    taos_fetch_rows_a(pSql, tscSCreateCallBack, param);
    return NULL;
  }

  void* data = doSetResultRowData(pSql, true);

  tscClearSqlOwner(pSql);
  return data;
}
static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) {
  TAOS_ROW row = tscFetchRow(builder);
  SSqlObj* pSql = builder->pInterSql;

  if (row == NULL) {
   return TSDB_CODE_MND_INVALID_TABLE_NAME;
  }

  int32_t* lengths = taos_fetch_lengths(pSql);  
  int num_fields = taos_num_fields(pSql);
  TAOS_FIELD *fields = taos_fetch_fields(pSql);

  char buf[TSDB_COL_NAME_LEN + 16]; 
  for (int i = 0; i < num_fields; i++) {
    memset(buf, 0, sizeof(buf));
    int32_t ret = tscGetNthFieldResult(row, fields, lengths, i, buf);

    if (i == 0) {
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s", "(");
    } 
    if ((fields[i].type == TSDB_DATA_TYPE_NCHAR 
        || fields[i].type == TSDB_DATA_TYPE_BINARY 
        || fields[i].type == TSDB_DATA_TYPE_TIMESTAMP) && 0 == ret) {
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "\"%s\",", buf);
    } else {
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s,", buf);
    }
    if (i == num_fields - 1) {
      sprintf(result + strlen(result) - 1, "%s", ")");
    }
  }  

  if (0 == strlen(result)) {
   return TSDB_CODE_MND_INVALID_TABLE_NAME; 
  }
  return TSDB_CODE_SUCCESS;
}


// build 'show create table/database' result fields 
static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const char *ddl) {
  int32_t  rowLen = 0;
S
Shengliang Guan 已提交
470
  int16_t  ddlLen = (int16_t)strlen(ddl); 
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
  SColumnIndex index = {0};
  pSql->cmd.numOfCols = 2;

  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  pQueryInfo->order.order = TSDB_ORDER_ASC;

  TAOS_FIELD f; 
  if (type == SCREATE_BUILD_TABLE) {
    f.type  = TSDB_DATA_TYPE_BINARY;
    f.bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE;
    tstrncpy(f.name, "Table", sizeof(f.name));
  } else {
    f.type  = TSDB_DATA_TYPE_BINARY;
    f.bytes =  (TSDB_DB_NAME_LEN - 1) + VARSTR_HEADER_SIZE;
    tstrncpy(f.name, "Database", sizeof(f.name));
  } 

  SFieldSupInfo* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
  pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
      f.bytes, f.bytes - VARSTR_HEADER_SIZE, false);

  rowLen += f.bytes; 
H
hzcheng 已提交
493

494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
  f.bytes = (int16_t)(ddlLen + VARSTR_HEADER_SIZE);
  f.type = TSDB_DATA_TYPE_BINARY;
  if (type == SCREATE_BUILD_TABLE) {
    tstrncpy(f.name, "Create Table", sizeof(f.name));
  } else {
    tstrncpy(f.name, "Create Database", sizeof(f.name));
  }

  pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
  pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, 
      (int16_t)(ddlLen + VARSTR_HEADER_SIZE), ddlLen, false);

  rowLen += ddlLen + VARSTR_HEADER_SIZE;

  return rowLen;
}
static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) {
  SSqlRes *pRes = &pSql->res;

  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  int32_t numOfRows = 1;
  if (strlen(ddl) == 0) {
    
  }
  tscInitResObjForLocalQuery(pSql, numOfRows, rowLen);

  TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
  char* dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * numOfRows;
  STR_WITH_MAXSIZE_TO_VARSTR(dst, tableName, pField->bytes);

  pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
  dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * numOfRows;
  STR_WITH_MAXSIZE_TO_VARSTR(dst, ddl, pField->bytes);
  return 0;
}
static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) {
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); 
  int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result);

  tscFieldInfoUpdateOffset(pQueryInfo);
  return tscSCreateSetValueToResObj(pSql, rowLen, str, result);  
}
int32_t tscRebuildCreateTableStatement(void *param,char *result) {
  SCreateBuilder *builder = (SCreateBuilder *)param;
  int32_t code = TSDB_CODE_SUCCESS;

  char *buf = calloc(1,TSDB_MAX_BINARY_LEN);
  if (buf == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

  code = tscGetTableTagValue(builder, buf);
  if (code == TSDB_CODE_SUCCESS) {
    snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "CREATE TABLE %s USING %s TAGS %s", builder->buf, builder->sTableName, buf);
    code = tscSCreateBuildResult(builder->pParentSql, SCREATE_BUILD_TABLE, builder->buf, result);    
  }  
  free(buf);
  return code;
}

static int32_t tscGetDBInfo(SCreateBuilder *builder, char *result) {
  TAOS_ROW row = tscFetchRow(builder);
  if (row == NULL) {
   return TSDB_CODE_MND_DB_NOT_SELECTED; 
  }
  const char *showColumns[] = {"REPLICA", "QUORUM", "DAYS", "KEEP", "BLOCKS", NULL};

  SSqlObj *pSql = builder->pInterSql;
  TAOS_FIELD *fields = taos_fetch_fields(pSql);
  int num_fields = taos_num_fields(pSql);

  char buf[TSDB_DB_NAME_LEN + 64] = {0}; 
  do {
    int32_t* lengths = taos_fetch_lengths(pSql);  
    int32_t ret = tscGetNthFieldResult(row, fields, lengths, 0, buf);
    if (0 == ret && STR_NOCASE_EQUAL(buf, strlen(buf), builder->buf, strlen(builder->buf))) {
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "CREATE DATABASE %s", buf);  
      for (int i = 1; i < num_fields; i++) {
        for (int j = 0; showColumns[j] != NULL; j++) {
          if (STR_NOCASE_EQUAL(fields[i].name, strlen(fields[i].name), showColumns[j], strlen(showColumns[j]))) {
            memset(buf, 0, sizeof(buf));
            ret = tscGetNthFieldResult(row, fields, lengths, i, buf);
            if (ret == 0) {
              snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), " %s %s", showColumns[j], buf); 
            }
          }
        }
      }
      break;
    } 
    
    row = tscFetchRow(builder);
  } while (row != NULL);

  if (0 == strlen(result)) {
   return TSDB_CODE_MND_DB_NOT_SELECTED; 
  }

  return TSDB_CODE_SUCCESS;
}
int32_t tscRebuildCreateDBStatement(void *param,char *result) {
  SCreateBuilder *builder = (SCreateBuilder *)param;
  int32_t code = TSDB_CODE_SUCCESS;

  char *buf = calloc(1, TSDB_MAX_BINARY_LEN);
  if (buf == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  code = tscGetDBInfo(param, buf);  
  if (code == TSDB_CODE_SUCCESS) {
    code = tscSCreateBuildResult(builder->pParentSql, SCREATE_BUILD_DB, builder->buf, buf);    
  }
  free(buf);
  return code;
}

static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) {
  char *buf = (char *)malloc(TSDB_MAX_BINARY_LEN);
  if (buf == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY; 
  }
  buf[0] = 0;

  STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->pTableMeta; 
  if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
      pMeta->tableType == TSDB_STREAM_TABLE) {
    free(buf);
    return TSDB_CODE_TSC_INVALID_VALUE;
  } 

  SSchema *pTagsSchema = tscGetTableTagSchema(pMeta);  
  int32_t numOfTags = tscGetNumOfTags(pMeta);
  for (int32_t i = 0; i < numOfTags; i++) {
    if (i != numOfTags - 1) {
      snprintf(buf + strlen(buf), TSDB_MAX_BINARY_LEN - strlen(buf), "%s,", pTagsSchema[i].name);  
    } else {
      snprintf(buf + strlen(buf), TSDB_MAX_BINARY_LEN - strlen(buf), "%s", pTagsSchema[i].name);
    }
  }   

  *result = buf;
  return TSDB_CODE_SUCCESS;
}  
static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, char *ddl) {
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);

  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  STableMeta *    pMeta = pTableMetaInfo->pTableMeta;

  SSqlObj *pInterSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); 
  if (pInterSql == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }  

  SCreateBuilder *param = (SCreateBuilder *)malloc(sizeof(SCreateBuilder));    
  if (param == NULL) {
    free(pInterSql);
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

  char fullName[TSDB_TABLE_FNAME_LEN] = {0};
  extractDBName(pTableMetaInfo->name, fullName);
  extractTableName(pMeta->sTableId, param->sTableName);
  snprintf(fullName + strlen(fullName), TSDB_TABLE_FNAME_LEN - strlen(fullName),  ".%s", param->sTableName);
  extractTableName(pTableMetaInfo->name, param->buf);

  param->pParentSql = pSql;
  param->pInterSql  = pInterSql;
  param->fp         = tscRebuildCreateTableStatement;
  param->callStage  = SCREATE_CALLBACK_QUERY;

  char *query = (char *)calloc(1, TSDB_MAX_BINARY_LEN); 
  if (query == NULL) {
    free(param);
    free(pInterSql);
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

  char *columns = NULL;
  int32_t code = tscGetTableTagColumnName(pSql, &columns) ;
  if (code != TSDB_CODE_SUCCESS) {
    free(param); 
    free(pInterSql);
Y
fix bug  
yihaoDeng 已提交
677
    free(query);
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
    return code;
  }

  snprintf(query + strlen(query), TSDB_MAX_BINARY_LEN - strlen(query), "SELECT %s FROM %s WHERE TBNAME IN(\'%s\')", columns, fullName, param->buf);
  doAsyncQuery(pSql->pTscObj, pInterSql, tscSCreateCallBack, param, query, strlen(query));
  free(query);
  free(columns);

  return TSDB_CODE_TSC_ACTION_IN_PROGRESS; 
}
static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) {
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  STableMeta *    pMeta = pTableMetaInfo->pTableMeta;

  int32_t numOfRows = tscGetNumOfColumns(pMeta);
  SSchema *pSchema = tscGetTableSchema(pMeta);

  char *result = ddl;
  sprintf(result, "create table %s (", tableName);
  for (int32_t i = 0; i < numOfRows; ++i) {
    uint8_t type = pSchema[i].type;
    if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
Y
fix bug  
yihaoDeng 已提交
701
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s(%d),", pSchema[i].name,tDataTypeDesc[pSchema[i].type].aName,pSchema->bytes);
702
    } else {
Y
fix bug  
yihaoDeng 已提交
703
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s,", pSchema[i].name, tDataTypeDesc[pSchema[i].type].aName); 
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
    }
  }
  sprintf(result + strlen(result) - 1, "%s", ")");

  return TSDB_CODE_SUCCESS;
}
static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) {
  char *result = ddl;
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  STableMeta *    pMeta = pTableMetaInfo->pTableMeta;

  int32_t numOfRows = tscGetNumOfColumns(pMeta);
  int32_t totalRows = numOfRows + tscGetNumOfTags(pMeta);
  SSchema *pSchema = tscGetTableSchema(pMeta);

  sprintf(result, "create table %s (", tableName);
  for (int32_t i = 0; i < numOfRows; ++i) {
    uint8_t type = pSchema[i].type;
    if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
Y
fix bug  
yihaoDeng 已提交
724
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result),"%s %s(%d),", pSchema[i].name,tDataTypeDesc[pSchema[i].type].aName,pSchema->bytes);
725
    } else {
Y
fix bug  
yihaoDeng 已提交
726
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s,", pSchema[i].name, tDataTypeDesc[type].aName); 
727 728
    }
  }
Y
fix bug  
yihaoDeng 已提交
729
  snprintf(result + strlen(result) - 1, TSDB_MAX_BINARY_LEN - strlen(result), "%s %s", ")", "TAGS (");
730 731 732 733

  for (int32_t i = numOfRows; i < totalRows; i++) {
    uint8_t type = pSchema[i].type;
    if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
Y
fix bug  
yihaoDeng 已提交
734
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s(%d),", pSchema[i].name,tDataTypeDesc[pSchema[i].type].aName,pSchema->bytes);
735
    } else {
Y
fix bug  
yihaoDeng 已提交
736
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s,", pSchema[i].name, tDataTypeDesc[type].aName); 
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751
    }
  }
  sprintf(result + strlen(result) - 1, "%s", ")");

  return TSDB_CODE_SUCCESS;
}

static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  assert(pTableMetaInfo->pTableMeta != NULL);

  char tableName[TSDB_TABLE_NAME_LEN] = {0};
  extractTableName(pTableMetaInfo->name, tableName);

Y
fix bug  
yihaoDeng 已提交
752
  char *result = (char *)calloc(1, TSDB_MAX_BINARY_LEN);
753 754 755 756 757 758 759 760 761 762 763
  int32_t code = TSDB_CODE_SUCCESS;
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
    code = tscRebuildDDLForSuperTable(pSql, tableName, result);
  } else if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
    code = tscRebuildDDLForNormalTable(pSql, tableName, result);
  } else if (UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
    code = tscRebuildDDLForSubTable(pSql, tableName, result);
  } else {
    code = TSDB_CODE_TSC_INVALID_VALUE;
  }

Y
fix bug  
yihaoDeng 已提交
764 765 766 767 768
  if (code == TSDB_CODE_SUCCESS) {
    code = tscSCreateBuildResult(pSql, SCREATE_BUILD_TABLE, tableName, result);
  } 
  free(result);
  return code;
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
}

static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);

  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

  SSqlObj *pInterSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); 
  if (pInterSql == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }  

  SCreateBuilder *param = (SCreateBuilder *)malloc(sizeof(SCreateBuilder));    
  if (param == NULL) {
    free(pInterSql);
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
  extractTableName(pTableMetaInfo->name, param->buf);
  param->pParentSql = pSql;
  param->pInterSql  = pInterSql;
  param->fp         = tscRebuildCreateDBStatement;
  param->callStage  = SCREATE_CALLBACK_QUERY;
   
  const char *query = "show databases";
  doAsyncQuery(pSql->pTscObj, pInterSql, tscSCreateCallBack, param, query, strlen(query));
  return TSDB_CODE_TSC_ACTION_IN_PROGRESS;
}
H
Haojun Liao 已提交
796
static int32_t tscProcessCurrentUser(SSqlObj *pSql) {
797
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
798

H
hjxilinx 已提交
799
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
H
Haojun Liao 已提交
800 801
  pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY;
  pExpr->resType = TSDB_DATA_TYPE_BINARY;
802

H
Haojun Liao 已提交
803
  char* vx = calloc(1, pExpr->resBytes);
H
Haojun Liao 已提交
804 805 806 807
  if (vx == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

808 809
  size_t size = sizeof(pSql->pTscObj->user);
  STR_WITH_MAXSIZE_TO_VARSTR(vx, pSql->pTscObj->user, size);
810

H
Haojun Liao 已提交
811 812
  tscSetLocalQueryResult(pSql, vx, pExpr->aliasName, pExpr->resType, pExpr->resBytes);
  free(vx);
H
Haojun Liao 已提交
813 814

  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
815 816
}

H
Haojun Liao 已提交
817
static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
B
Bomin Zhang 已提交
818
  char db[TSDB_DB_NAME_LEN] = {0};
H
hjxilinx 已提交
819
  extractDBName(pSql->pTscObj->db, db);
820

821
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
822

H
hjxilinx 已提交
823
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
H
Haojun Liao 已提交
824
  pExpr->resType = TSDB_DATA_TYPE_BINARY;
825

H
Haojun Liao 已提交
826 827
  size_t t = strlen(db);
  pExpr->resBytes = TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE;
828

H
Haojun Liao 已提交
829
  char* vx = calloc(1, pExpr->resBytes);
H
Haojun Liao 已提交
830 831 832 833
  if (vx == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
Haojun Liao 已提交
834 835 836
  if (t == 0) {
    setVardataNull(vx, TSDB_DATA_TYPE_BINARY);
  } else {
S
TD-1057  
Shengliang Guan 已提交
837
    STR_WITH_SIZE_TO_VARSTR(vx, db, (VarDataLenT)t);
H
Haojun Liao 已提交
838
  }
839

H
Haojun Liao 已提交
840 841
  tscSetLocalQueryResult(pSql, vx, pExpr->aliasName, pExpr->resType, pExpr->resBytes);
  free(vx);
H
Haojun Liao 已提交
842 843

  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
844 845
}

H
Haojun Liao 已提交
846
static int32_t tscProcessServerVer(SSqlObj *pSql) {
H
hjxilinx 已提交
847
  const char* v = pSql->pTscObj->sversion;
848
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
849

H
hjxilinx 已提交
850
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
H
Haojun Liao 已提交
851
  pExpr->resType = TSDB_DATA_TYPE_BINARY;
852

H
Haojun Liao 已提交
853
  size_t t = strlen(v);
S
TD-1057  
Shengliang Guan 已提交
854
  pExpr->resBytes = (int16_t)(t + VARSTR_HEADER_SIZE);
855

H
Haojun Liao 已提交
856
  char* vx = calloc(1, pExpr->resBytes);
H
Haojun Liao 已提交
857 858
  if (vx == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
859

H
Haojun Liao 已提交
860 861
  }

S
TD-1057  
Shengliang Guan 已提交
862
  STR_WITH_SIZE_TO_VARSTR(vx, v, (VarDataLenT)t);
H
Haojun Liao 已提交
863
  tscSetLocalQueryResult(pSql, vx, pExpr->aliasName, pExpr->resType, pExpr->resBytes);
864

H
Haojun Liao 已提交
865 866
  free(vx);
  return TSDB_CODE_SUCCESS;
867

H
hjxilinx 已提交
868 869
}

H
Haojun Liao 已提交
870
static int32_t tscProcessClientVer(SSqlObj *pSql) {
871
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
872

H
hjxilinx 已提交
873
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
H
Haojun Liao 已提交
874
  pExpr->resType = TSDB_DATA_TYPE_BINARY;
875

H
Haojun Liao 已提交
876
  size_t t = strlen(version);
S
TD-1057  
Shengliang Guan 已提交
877
  pExpr->resBytes = (int16_t)(t + VARSTR_HEADER_SIZE);
878

H
Haojun Liao 已提交
879
  char* v = calloc(1, pExpr->resBytes);
H
Haojun Liao 已提交
880 881
  if (v == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
882

H
Haojun Liao 已提交
883 884
  }

S
TD-1057  
Shengliang Guan 已提交
885
  STR_WITH_SIZE_TO_VARSTR(v, version, (VarDataLenT)t);
H
Haojun Liao 已提交
886
  tscSetLocalQueryResult(pSql, v, pExpr->aliasName, pExpr->resType, pExpr->resBytes);
887

H
Haojun Liao 已提交
888 889
  free(v);
  return TSDB_CODE_SUCCESS;
890

H
hjxilinx 已提交
891 892
}

H
Haojun Liao 已提交
893
static int32_t tscProcessServStatus(SSqlObj *pSql) {
H
hjxilinx 已提交
894
  STscObj* pObj = pSql->pTscObj;
895

H
hjxilinx 已提交
896
  if (pObj->pHb != NULL) {
897 898
    if (pObj->pHb->res.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
      pSql->res.code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
H
Haojun Liao 已提交
899
      return pSql->res.code;
H
hjxilinx 已提交
900 901
    }
  } else {
902
    if (pSql->res.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
H
Haojun Liao 已提交
903
      return pSql->res.code;
H
hjxilinx 已提交
904 905
    }
  }
906

907
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
908

H
hjxilinx 已提交
909
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
H
Haojun Liao 已提交
910 911
  int32_t val = 1;
  tscSetLocalQueryResult(pSql, (char*) &val, pExpr->aliasName, TSDB_DATA_TYPE_INT, sizeof(int32_t));
H
Haojun Liao 已提交
912
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
913 914
}

H
Haojun Liao 已提交
915
void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, int16_t type, size_t valueLength) {
H
hjxilinx 已提交
916 917 918 919
  SSqlCmd *pCmd = &pSql->cmd;
  SSqlRes *pRes = &pSql->res;

  pCmd->numOfCols = 1;
920

921
  SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
922
  pQueryInfo->order.order = TSDB_ORDER_ASC;
923

H
hjxilinx 已提交
924
  tscFieldInfoClear(&pQueryInfo->fieldsInfo);
H
Haojun Liao 已提交
925 926
  pQueryInfo->fieldsInfo.pFields = taosArrayInit(1, sizeof(TAOS_FIELD));
  pQueryInfo->fieldsInfo.pSupportInfo = taosArrayInit(1, sizeof(SFieldSupInfo));
927

S
TD-1057  
Shengliang Guan 已提交
928
  TAOS_FIELD f = tscCreateField((int8_t)type, columnName, (int16_t)valueLength);
H
hjxilinx 已提交
929
  tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
930

S
TD-1057  
Shengliang Guan 已提交
931
  tscInitResObjForLocalQuery(pSql, 1, (int32_t)valueLength);
H
hjxilinx 已提交
932

H
hjxilinx 已提交
933 934
  TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
  SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, 0);
H
hjxilinx 已提交
935
  pInfo->pSqlExpr = taosArrayGetP(pQueryInfo->exprList, 0);
936

H
Haojun Liao 已提交
937
  memcpy(pRes->data, val, pField->bytes);
H
hjxilinx 已提交
938 939
}

H
hzcheng 已提交
940 941
int tscProcessLocalCmd(SSqlObj *pSql) {
  SSqlCmd *pCmd = &pSql->cmd;
H
Haojun Liao 已提交
942
  SSqlRes *pRes = &pSql->res;
H
hzcheng 已提交
943 944

  if (pCmd->command == TSDB_SQL_CFG_LOCAL) {
H
Haojun Liao 已提交
945
    pRes->code = (uint8_t)taosCfgDynamicOptions(pCmd->payload);
H
hzcheng 已提交
946
  } else if (pCmd->command == TSDB_SQL_DESCRIBE_TABLE) {
H
Haojun Liao 已提交
947
    pRes->code = (uint8_t)tscProcessDescribeTable(pSql);
H
hzcheng 已提交
948
  } else if (pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
S
slguan 已提交
949
    /*
H
hjxilinx 已提交
950 951
     * 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 已提交
952
     */
H
Haojun Liao 已提交
953 954
    pRes->qhandle = 0x1;
    pRes->numOfRows = 0;
955 956 957 958
  } else if (pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE) {
    pRes->code = tscProcessShowCreateTable(pSql); 
  } else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
    pRes->code = tscProcessShowCreateDatabase(pSql); 
H
hzcheng 已提交
959
  } else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
H
Haojun Liao 已提交
960
    taosCacheEmpty(tscMetaCache);
H
Haojun Liao 已提交
961
    pRes->code = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
962
  } else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
H
Haojun Liao 已提交
963
    pRes->code = tscProcessServerVer(pSql);
H
hjxilinx 已提交
964
  } else if (pCmd->command == TSDB_SQL_CLI_VERSION) {
H
Haojun Liao 已提交
965
    pRes->code = tscProcessClientVer(pSql);
H
hjxilinx 已提交
966
  } else if (pCmd->command == TSDB_SQL_CURRENT_USER) {
H
Haojun Liao 已提交
967
    pRes->code = tscProcessCurrentUser(pSql);
H
hjxilinx 已提交
968
  } else if (pCmd->command == TSDB_SQL_CURRENT_DB) {
H
Haojun Liao 已提交
969
    pRes->code = tscProcessCurrentDB(pSql);
H
hjxilinx 已提交
970
  } else if (pCmd->command == TSDB_SQL_SERV_STATUS) {
H
Haojun Liao 已提交
971
    pRes->code = tscProcessServStatus(pSql);
H
hzcheng 已提交
972
  } else {
H
Haojun Liao 已提交
973
    pRes->code = TSDB_CODE_TSC_INVALID_SQL;
H
hzcheng 已提交
974 975 976
    tscError("%p not support command:%d", pSql, pCmd->command);
  }

S
slguan 已提交
977
  // keep the code in local variable in order to avoid invalid read in case of async query
978

H
Haojun Liao 已提交
979
  int32_t code = pRes->code;
980
  if (code == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
981
    (*pSql->fp)(pSql->param, pSql, code);
982
  } else if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS){
983 984
  } else {
    tscQueueAsyncRes(pSql);
H
hzcheng 已提交
985 986 987
  }
  return code;
}