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

H
hzcheng 已提交
19
#include "taosdef.h"
H
Haojun Liao 已提交
20
#include "tname.h"
S
slguan 已提交
21
#include "tscLog.h"
H
Haojun Liao 已提交
22
#include "tscUtil.h"
H
Haojun Liao 已提交
23
#include "qTableMeta.h"
H
Haojun Liao 已提交
24
#include "tsclient.h"
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
#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;
48 49
} 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
hzcheng 已提交
52 53 54 55
static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
  SSqlRes *pRes = &pSql->res;

  // one column for each row
H
Haojun Liao 已提交
56
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
57
  
H
hjxilinx 已提交
58
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
H
hjxilinx 已提交
59
  STableMeta *    pMeta = pTableMetaInfo->pTableMeta;
H
hzcheng 已提交
60 61 62 63 64 65 66

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

weixin_48148422's avatar
weixin_48148422 已提交
70
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hjxilinx 已提交
71
    numOfRows = numOfRows + tscGetNumOfTags(pMeta);
H
hzcheng 已提交
72 73
  }

H
Haojun Liao 已提交
74 75 76
  pSql->res.pMerger = tscInitResObjForLocalQuery(totalNumOfRows, rowLen, pSql->self);
  tscInitResForMerge(&pSql->res);

H
hjxilinx 已提交
77
  SSchema *pSchema = tscGetTableSchema(pMeta);
H
hzcheng 已提交
78 79

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

H
Haojun Liao 已提交
84
    char *type = tDataTypes[pSchema[i].type].name;
H
hzcheng 已提交
85

H
hjxilinx 已提交
86
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
H
hjxilinx 已提交
87
    dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i;
H
Hui Li 已提交
88
    STR_WITH_MAXSIZE_TO_VARSTR(dst, type, pField->bytes);
wmmhello's avatar
wmmhello 已提交
89

H
hzcheng 已提交
90
    int32_t bytes = pSchema[i].bytes;
91
    if (pSchema[i].type == TSDB_DATA_TYPE_BINARY){
92 93
      bytes -= VARSTR_HEADER_SIZE;
    }
wmmhello's avatar
wmmhello 已提交
94
    else if(pSchema[i].type == TSDB_DATA_TYPE_NCHAR || pSchema[i].type == TSDB_DATA_TYPE_JSON) {
H
hjxilinx 已提交
95
      bytes -= VARSTR_HEADER_SIZE;
96
      bytes = bytes / TSDB_NCHAR_SIZE;
H
hzcheng 已提交
97 98
    }

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

H
hjxilinx 已提交
102
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 3);
H
hjxilinx 已提交
103
    if (i >= tscGetNumOfColumns(pMeta) && tscGetNumOfTags(pMeta) != 0) {
104
      char* output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
sangshuduo's avatar
sangshuduo 已提交
105
      const char *src = "TAG";
H
Hui Li 已提交
106
      STR_WITH_MAXSIZE_TO_VARSTR(output, src, pField->bytes);
H
hzcheng 已提交
107 108 109
    }
  }

weixin_48148422's avatar
weixin_48148422 已提交
110
  if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
H
hzcheng 已提交
111 112 113
    return 0;
  }

H
Haojun Liao 已提交
114
  // the following is handle display tags for table created according to super table
H
hzcheng 已提交
115 116
  for (int32_t i = numOfRows; i < totalNumOfRows; ++i) {
    // field name
H
hjxilinx 已提交
117
    TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
118
    char* output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i;
H
Hui Li 已提交
119
    STR_WITH_MAXSIZE_TO_VARSTR(output, pSchema[i].name, pField->bytes);
H
hzcheng 已提交
120 121

    // type name
H
hjxilinx 已提交
122
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
H
Haojun Liao 已提交
123
    char *type = tDataTypes[pSchema[i].type].name;
124 125 126
    
    output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i;
    STR_WITH_MAXSIZE_TO_VARSTR(output, type, pField->bytes);
H
hzcheng 已提交
127 128 129

    // type length
    int32_t bytes = pSchema[i].bytes;
H
hjxilinx 已提交
130
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 2);
L
liu0x54 已提交
131 132 133 134 135 136
    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 已提交
137 138
    }

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

    // tag value
H
hjxilinx 已提交
142
    pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 3);
143
    char *target = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
sangshuduo's avatar
sangshuduo 已提交
144
    const char *src = "TAG";
H
Hui Li 已提交
145
    STR_WITH_MAXSIZE_TO_VARSTR(target, src, pField->bytes);
H
hzcheng 已提交
146 147 148 149 150
  }

  return 0;
}

H
hjxilinx 已提交
151
static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, int32_t typeColLength,
H
hzcheng 已提交
152 153
                                               int32_t noteColLength) {
  int32_t  rowLen = 0;
H
hjxilinx 已提交
154 155 156
  SColumnIndex index = {0};
  
  pSql->cmd.numOfCols = numOfCols;
H
hzcheng 已提交
157

H
Haojun Liao 已提交
158
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
159
  pQueryInfo->order.order = TSDB_ORDER_ASC;
H
hzcheng 已提交
160

B
Bomin Zhang 已提交
161 162
  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 已提交
163
  
H
Haojun Liao 已提交
164
  SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
Haojun Liao 已提交
165
  pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
H
Haojun Liao 已提交
166
      (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false);
H
hjxilinx 已提交
167
  
B
Bomin Zhang 已提交
168
  rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE);
H
hzcheng 已提交
169

S
TD-1057  
Shengliang Guan 已提交
170
  f.bytes = (int16_t)(typeColLength + VARSTR_HEADER_SIZE);
H
hjxilinx 已提交
171
  f.type = TSDB_DATA_TYPE_BINARY;
B
Bomin Zhang 已提交
172
  tstrncpy(f.name, "Type", sizeof(f.name));
H
hjxilinx 已提交
173 174
  
  pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
Haojun Liao 已提交
175
  pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE),
H
Haojun Liao 已提交
176
      -1000, typeColLength, false);
H
hjxilinx 已提交
177
  
H
Hui Li 已提交
178
  rowLen += typeColLength + VARSTR_HEADER_SIZE;
H
hzcheng 已提交
179

H
hjxilinx 已提交
180 181
  f.bytes = sizeof(int32_t);
  f.type = TSDB_DATA_TYPE_INT;
B
Bomin Zhang 已提交
182
  tstrncpy(f.name, "Length", sizeof(f.name));
H
hjxilinx 已提交
183 184
  
  pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
Haojun Liao 已提交
185
  pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t),
H
Haojun Liao 已提交
186
      -1000, sizeof(int32_t), false);
H
hjxilinx 已提交
187
  
H
hzcheng 已提交
188 189
  rowLen += sizeof(int32_t);

S
TD-1057  
Shengliang Guan 已提交
190
  f.bytes = (int16_t)(noteColLength + VARSTR_HEADER_SIZE);
H
hjxilinx 已提交
191
  f.type = TSDB_DATA_TYPE_BINARY;
B
Bomin Zhang 已提交
192
  tstrncpy(f.name, "Note", sizeof(f.name));
H
hjxilinx 已提交
193
  
H
hjxilinx 已提交
194
  pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
Haojun Liao 已提交
195
  pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE),
H
Haojun Liao 已提交
196
      -1000, noteColLength, false);
H
hjxilinx 已提交
197
  
H
Hui Li 已提交
198
  rowLen += noteColLength + VARSTR_HEADER_SIZE;
H
hzcheng 已提交
199 200 201 202
  return rowLen;
}

static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
H
Haojun Liao 已提交
203
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
204
  
H
hjxilinx 已提交
205
  assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL);
H
hzcheng 已提交
206

H
hjxilinx 已提交
207
  const int32_t NUM_OF_DESC_TABLE_COLUMNS = 4;
208
  const int32_t TYPE_COLUMN_LENGTH = 20;
H
hzcheng 已提交
209 210
  const int32_t NOTE_COLUMN_MIN_LENGTH = 8;

211
  int32_t noteFieldLen = NOTE_COLUMN_MIN_LENGTH;
H
hzcheng 已提交
212

H
hjxilinx 已提交
213
  int32_t rowLen = tscBuildTableSchemaResultFields(pSql, NUM_OF_DESC_TABLE_COLUMNS, TYPE_COLUMN_LENGTH, noteFieldLen);
H
hjxilinx 已提交
214
  tscFieldInfoUpdateOffset(pQueryInfo);
H
hzcheng 已提交
215 216
  return tscSetValueToResObj(pSql, rowLen);
}
217
static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengths, int idx, char *result) {
wmmhello's avatar
wmmhello 已提交
218
  const char *val = (const char*)row[idx];
219 220 221 222 223
  if (val == NULL) {
    sprintf(result, "%s", TSDB_DATA_NULL_STR);
    return -1;
  } 
  uint8_t type = fields[idx].type;
wmmhello's avatar
wmmhello 已提交
224
  int32_t length = lengths[idx];
wmmhello's avatar
wmmhello 已提交
225

226 227
  switch (type) {
    case TSDB_DATA_TYPE_BOOL: 
S
TD-1530  
Shengliang Guan 已提交
228
      sprintf(result, "%s", ((((int32_t)(*((char *)val))) == 1) ? "true" : "false"));
229 230
      break;
    case TSDB_DATA_TYPE_TINYINT:
S
TD-1530  
Shengliang Guan 已提交
231
      sprintf(result, "%d", *((int8_t *)val));
232 233
      break;
    case TSDB_DATA_TYPE_SMALLINT: 
S
TD-1530  
Shengliang Guan 已提交
234
      sprintf(result, "%d", *((int16_t *)val));
235 236
      break;
    case TSDB_DATA_TYPE_INT:
S
TD-1530  
Shengliang Guan 已提交
237
      sprintf(result, "%d", *((int32_t *)val));
238 239 240 241 242 243 244 245 246 247 248 249
      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:
wmmhello's avatar
wmmhello 已提交
250
    case TSDB_DATA_TYPE_JSON:
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
      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);
H
Haojun Liao 已提交
277
    tscAsyncResultOnError(pParentSql);
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
    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 {
H
Haojun Liao 已提交
295
      tscAsyncResultOnError(pParentSql);
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
    }
  }
}

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;
  
H
Haojun Liao 已提交
314
  if (pRes->qId == 0 ||
315 316 317 318 319 320 321 322 323 324 325
      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 ||
326
       pCmd->command == TSDB_SQL_RETRIEVE_GLOBALMERGE ||
327 328 329 330
       pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE ||
       pCmd->command == TSDB_SQL_FETCH ||
       pCmd->command == TSDB_SQL_SHOW ||
       pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
331
       pCmd->command == TSDB_SQL_SHOW_CREATE_STABLE ||
332 333 334 335 336 337 338 339 340 341 342 343
       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;
  }

344
  void* data = doSetResultRowData(pSql);
345 346 347 348 349 350 351 352 353

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

  if (row == NULL) {
354
   return TSDB_CODE_TSC_INVALID_TABLE_NAME;
355 356 357 358 359 360 361
  }

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

  for (int i = 0; i < num_fields; i++) {
X
xywang 已提交
362 363 364 365 366 367
    char *buf = calloc(1, lengths[i] + 1);
    if (buf == NULL) {
        return TSDB_CODE_TSC_OUT_OF_MEMORY;
    }

    memset(buf, 0, lengths[i] + 1);
368 369 370 371 372 373 374 375 376 377 378 379
    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);
    }
X
xywang 已提交
380 381 382

    free(buf);

383 384 385
    if (i == num_fields - 1) {
      sprintf(result + strlen(result) - 1, "%s", ")");
    }
X
xywang 已提交
386
  }
387 388

  if (0 == strlen(result)) {
389
   return TSDB_CODE_TSC_INVALID_TABLE_NAME;
390 391 392 393 394 395 396 397
  }
  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 已提交
398
  int16_t  ddlLen = (int16_t)strlen(ddl); 
399 400 401
  SColumnIndex index = {0};
  pSql->cmd.numOfCols = 2;

H
Haojun Liao 已提交
402
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
403 404 405 406 407
  pQueryInfo->order.order = TSDB_ORDER_ASC;

  TAOS_FIELD f; 
  if (type == SCREATE_BUILD_TABLE) {
    f.type  = TSDB_DATA_TYPE_BINARY;
D
dapan1121 已提交
408
    f.bytes = (TSDB_TABLE_NAME_LEN - 1) + VARSTR_HEADER_SIZE;
409 410 411 412 413 414 415
    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));
  } 

H
Haojun Liao 已提交
416
  SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
H
Haojun Liao 已提交
417
  pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false);
418 419

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

421 422 423 424 425 426 427 428 429
  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);
H
Haojun Liao 已提交
430
  pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
H
Haojun Liao 已提交
431
      (int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false);
432 433 434 435 436 437 438 439

  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;

H
Haojun Liao 已提交
440
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
441 442 443 444
  int32_t numOfRows = 1;
  if (strlen(ddl) == 0) {
    
  }
H
Haojun Liao 已提交
445 446
  pSql->res.pMerger = tscInitResObjForLocalQuery(numOfRows, rowLen, pSql->self);
  tscInitResForMerge(&pSql->res);
447 448 449 450 451 452 453 454 455 456 457

  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) {
H
Haojun Liao 已提交
458
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
  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) {
W
wpan 已提交
475
    snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "CREATE TABLE `%s` USING `%s` TAGS %s", builder->buf, builder->sTableName, buf);
476 477 478 479 480 481 482 483 484
    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) {
485
   return TSDB_CODE_TSC_DB_NOT_SELECTED;
486 487 488 489 490 491 492 493 494
  }
  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 {
495
    memset(buf, 0, sizeof(buf));
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
    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)) {
518
   return TSDB_CODE_TSC_DB_NOT_SELECTED;
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
  }

  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;

H
Haojun Liao 已提交
546
  STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0)->pTableMeta;
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
  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) {
H
Haojun Liao 已提交
567
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582

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

S
Shengliang Guan 已提交
583
  char fullName[TSDB_TABLE_FNAME_LEN * 2] = {0};
W
wpan 已提交
584
  char tblName[TSDB_TABLE_NAME_LEN + 1] = {0};
585 586
  tNameGetDbName(&pTableMetaInfo->name, fullName);

587
  extractTableName(pMeta->sTableName, param->sTableName);
W
wpan 已提交
588
  snprintf(fullName + strlen(fullName), TSDB_TABLE_FNAME_LEN - strlen(fullName),  ".`%s`", param->sTableName);
589 590

  strncpy(param->buf, tNameGetTableName(&pTableMetaInfo->name), TSDB_TABLE_NAME_LEN);
W
wpan 已提交
591
  tableNameToStr(tblName, param->buf, '\'');
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609

  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 已提交
610
    free(query);
611 612 613
    return code;
  }

W
wpan 已提交
614
  snprintf(query + strlen(query), TSDB_MAX_BINARY_LEN - strlen(query), "SELECT %s FROM %s WHERE TBNAME IN(\'%s\')", columns, fullName, tblName);
615 616 617 618 619 620
  doAsyncQuery(pSql->pTscObj, pInterSql, tscSCreateCallBack, param, query, strlen(query));
  free(query);
  free(columns);

  return TSDB_CODE_TSC_ACTION_IN_PROGRESS; 
}
621

622
static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) {
H
Haojun Liao 已提交
623
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
624 625 626 627 628 629 630
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  STableMeta *    pMeta = pTableMetaInfo->pTableMeta;

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

  char *result = ddl;
W
wpan 已提交
631
  sprintf(result, "create table `%s` (", tableName);
632 633 634
  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) {
635 636 637 638
      int32_t bytes = pSchema[i].bytes - VARSTR_HEADER_SIZE;
      if (type == TSDB_DATA_TYPE_NCHAR) {
        bytes =  bytes/TSDB_NCHAR_SIZE;
      }
H
Haojun Liao 已提交
639
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s(%d),", pSchema[i].name, tDataTypes[pSchema[i].type].name, bytes);
640
    } else {
H
Haojun Liao 已提交
641
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s,", pSchema[i].name, tDataTypes[pSchema[i].type].name);
642 643 644 645 646 647 648 649
    }
  }
  sprintf(result + strlen(result) - 1, "%s", ")");

  return TSDB_CODE_SUCCESS;
}
static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) {
  char *result = ddl;
H
Haojun Liao 已提交
650
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
651 652 653 654 655 656 657
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  STableMeta *    pMeta = pTableMetaInfo->pTableMeta;

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

W
wpan 已提交
658
  sprintf(result, "create table `%s` (", tableName);
659 660 661
  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) {
662 663 664 665
      int32_t bytes = pSchema[i].bytes - VARSTR_HEADER_SIZE;
      if (type == TSDB_DATA_TYPE_NCHAR) {
        bytes =  bytes/TSDB_NCHAR_SIZE;
      }
H
Haojun Liao 已提交
666
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result),"%s %s(%d),", pSchema[i].name,tDataTypes[pSchema[i].type].name, bytes);
667
    } else {
H
Haojun Liao 已提交
668
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s,", pSchema[i].name, tDataTypes[type].name);
669 670
    }
  }
Y
fix bug  
yihaoDeng 已提交
671
  snprintf(result + strlen(result) - 1, TSDB_MAX_BINARY_LEN - strlen(result), "%s %s", ")", "TAGS (");
672 673 674 675

  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) {
676 677 678 679
      int32_t bytes = pSchema[i].bytes - VARSTR_HEADER_SIZE;
      if (type == TSDB_DATA_TYPE_NCHAR) {
        bytes =  bytes/TSDB_NCHAR_SIZE;
      }
H
Haojun Liao 已提交
680
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s(%d),", pSchema[i].name,tDataTypes[pSchema[i].type].name, bytes);
681
    } else {
H
Haojun Liao 已提交
682
      snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s %s,", pSchema[i].name, tDataTypes[type].name);
683 684 685 686 687 688 689 690
    }
  }
  sprintf(result + strlen(result) - 1, "%s", ")");

  return TSDB_CODE_SUCCESS;
}

static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
H
Haojun Liao 已提交
691
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
692 693 694
  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
  assert(pTableMetaInfo->pTableMeta != NULL);

695
  const char* tableName = tNameGetTableName(&pTableMetaInfo->name);
696 697 698
  if (pSql->cmd.command == TSDB_SQL_SHOW_CREATE_STABLE && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))  {
    return TSDB_CODE_TSC_INVALID_VALUE;
  }
699

Y
fix bug  
yihaoDeng 已提交
700
  char *result = (char *)calloc(1, TSDB_MAX_BINARY_LEN);
701 702 703 704 705 706 707 708 709 710 711
  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 已提交
712 713 714 715 716
  if (code == TSDB_CODE_SUCCESS) {
    code = tscSCreateBuildResult(pSql, SCREATE_BUILD_TABLE, tableName, result);
  } 
  free(result);
  return code;
717 718 719
}

static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
H
Haojun Liao 已提交
720
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
721 722 723 724 725 726 727 728

  STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);

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

Y
yihaoDeng 已提交
729
  SCreateBuilder *param = (SCreateBuilder *)calloc(1, sizeof(SCreateBuilder));    
730 731 732 733
  if (param == NULL) {
    free(pInterSql);
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }
Y
yihaoDeng 已提交
734
  tNameGetDbName(&pTableMetaInfo->name, param->buf);
735

736 737 738 739 740 741 742 743 744
  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 已提交
745
static int32_t tscProcessCurrentUser(SSqlObj *pSql) {
H
Haojun Liao 已提交
746
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
747

H
hjxilinx 已提交
748
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
H
Haojun Liao 已提交
749 750
  pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY;
  pExpr->resType = TSDB_DATA_TYPE_BINARY;
751

H
Haojun Liao 已提交
752
  char* vx = calloc(1, pExpr->resBytes);
H
Haojun Liao 已提交
753 754 755 756
  if (vx == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

757 758
  size_t size = sizeof(pSql->pTscObj->user);
  STR_WITH_MAXSIZE_TO_VARSTR(vx, pSql->pTscObj->user, size);
759

H
Haojun Liao 已提交
760 761
  tscSetLocalQueryResult(pSql, vx, pExpr->aliasName, pExpr->resType, pExpr->resBytes);
  free(vx);
H
Haojun Liao 已提交
762 763

  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
764 765
}

H
Haojun Liao 已提交
766
static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
B
Bomin Zhang 已提交
767
  char db[TSDB_DB_NAME_LEN] = {0};
D
dapan1121 已提交
768 769

  pthread_mutex_lock(&pSql->pTscObj->mutex);
H
hjxilinx 已提交
770
  extractDBName(pSql->pTscObj->db, db);
D
dapan1121 已提交
771
  pthread_mutex_unlock(&pSql->pTscObj->mutex);
772

H
Haojun Liao 已提交
773
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
774

H
hjxilinx 已提交
775
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
H
Haojun Liao 已提交
776
  pExpr->resType = TSDB_DATA_TYPE_BINARY;
777

H
Haojun Liao 已提交
778 779
  size_t t = strlen(db);
  pExpr->resBytes = TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE;
780

H
Haojun Liao 已提交
781
  char* vx = calloc(1, pExpr->resBytes);
H
Haojun Liao 已提交
782 783 784 785
  if (vx == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
  }

H
Haojun Liao 已提交
786 787 788
  if (t == 0) {
    setVardataNull(vx, TSDB_DATA_TYPE_BINARY);
  } else {
S
TD-1057  
Shengliang Guan 已提交
789
    STR_WITH_SIZE_TO_VARSTR(vx, db, (VarDataLenT)t);
H
Haojun Liao 已提交
790
  }
791

H
Haojun Liao 已提交
792 793
  tscSetLocalQueryResult(pSql, vx, pExpr->aliasName, pExpr->resType, pExpr->resBytes);
  free(vx);
H
Haojun Liao 已提交
794 795

  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
796 797
}

H
Haojun Liao 已提交
798
static int32_t tscProcessServerVer(SSqlObj *pSql) {
H
hjxilinx 已提交
799
  const char* v = pSql->pTscObj->sversion;
H
Haojun Liao 已提交
800
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
801

H
hjxilinx 已提交
802
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
H
Haojun Liao 已提交
803
  pExpr->resType = TSDB_DATA_TYPE_BINARY;
804

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

H
Haojun Liao 已提交
808
  char* vx = calloc(1, pExpr->resBytes);
H
Haojun Liao 已提交
809 810
  if (vx == NULL) {
    return TSDB_CODE_TSC_OUT_OF_MEMORY;
811

H
Haojun Liao 已提交
812 813
  }

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

H
Haojun Liao 已提交
817 818
  free(vx);
  return TSDB_CODE_SUCCESS;
819

H
hjxilinx 已提交
820 821
}

H
Haojun Liao 已提交
822
static int32_t tscProcessClientVer(SSqlObj *pSql) {
H
Haojun Liao 已提交
823
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
824

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

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

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

H
Haojun Liao 已提交
835 836
  }

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

H
Haojun Liao 已提交
840 841
  free(v);
  return TSDB_CODE_SUCCESS;
842

H
hjxilinx 已提交
843 844
}

845 846 847
// TODO add test cases.
static int32_t checkForOnlineNode(SSqlObj* pSql) {
  int32_t* data = pSql->res.length;
848 849 850
  if (data == NULL) {
    return TSDB_CODE_SUCCESS;
  }
851 852 853 854 855 856

  int32_t total  = data[0];
  int32_t online = data[1];
  return (online < total)? TSDB_CODE_RPC_NETWORK_UNAVAIL:TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
857
static int32_t tscProcessServStatus(SSqlObj *pSql) {
H
hjxilinx 已提交
858
  STscObj* pObj = pSql->pTscObj;
859

860 861
  SSqlObj* pHb = (SSqlObj*)taosAcquireRef(tscObjRef, pObj->hbrid);
  if (pHb != NULL) {
862
    pSql->res.code = pHb->res.code;
H
hjxilinx 已提交
863
  }
864

865
  if (pSql->res.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
866
    taosReleaseRef(tscObjRef, pObj->hbrid);
867 868 869
    return pSql->res.code;
  }

870 871
  if (pHb != NULL) {
    pSql->res.code = checkForOnlineNode(pHb);
872
    taosReleaseRef(tscObjRef, pObj->hbrid);
873 874
  }

875 876 877
  if (pSql->res.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
    return pSql->res.code;
  }
878

H
Haojun Liao 已提交
879
  SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
H
hjxilinx 已提交
880
  SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
881

H
Haojun Liao 已提交
882 883
  int32_t val = 1;
  tscSetLocalQueryResult(pSql, (char*) &val, pExpr->aliasName, TSDB_DATA_TYPE_INT, sizeof(int32_t));
H
Haojun Liao 已提交
884
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
885 886
}

H
Haojun Liao 已提交
887
void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, int16_t type, size_t valueLength) {
H
hjxilinx 已提交
888 889 890 891
  SSqlCmd *pCmd = &pSql->cmd;
  SSqlRes *pRes = &pSql->res;

  pCmd->numOfCols = 1;
892

H
Haojun Liao 已提交
893
  SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
894
  pQueryInfo->order.order = TSDB_ORDER_ASC;
895

H
hjxilinx 已提交
896
  tscFieldInfoClear(&pQueryInfo->fieldsInfo);
H
Haojun Liao 已提交
897
  pQueryInfo->fieldsInfo.internalField = taosArrayInit(1, sizeof(SInternalField));
898

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

H
Haojun Liao 已提交
902 903
  pSql->res.pMerger = tscInitResObjForLocalQuery(1, (int32_t)valueLength, pSql->self);
  tscInitResForMerge(&pSql->res);
H
hjxilinx 已提交
904

H
Haojun Liao 已提交
905
  SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, 0);
H
Haojun Liao 已提交
906
  pInfo->pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
907

H
Haojun Liao 已提交
908
  memcpy(pRes->data, val, pInfo->field.bytes);
H
hjxilinx 已提交
909 910
}

H
hzcheng 已提交
911 912
int tscProcessLocalCmd(SSqlObj *pSql) {
  SSqlCmd *pCmd = &pSql->cmd;
H
Haojun Liao 已提交
913
  SSqlRes *pRes = &pSql->res;
H
hzcheng 已提交
914 915

  if (pCmd->command == TSDB_SQL_CFG_LOCAL) {
Y
TD-2568  
yihaoDeng 已提交
916 917 918 919 920 921
    if (taosCfgDynamicOptions(pCmd->payload)) {
       pRes->code = TSDB_CODE_SUCCESS;
    } else {
       pRes->code = TSDB_CODE_COM_INVALID_CFG_MSG; 
    } 
    pRes->numOfRows = 0;
H
hzcheng 已提交
922
  } else if (pCmd->command == TSDB_SQL_DESCRIBE_TABLE) {
H
Haojun Liao 已提交
923
    pRes->code = (uint8_t)tscProcessDescribeTable(pSql);
H
hzcheng 已提交
924
  } else if (pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
S
slguan 已提交
925
    /*
H
hjxilinx 已提交
926 927
     * 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 已提交
928
     */
H
Haojun Liao 已提交
929
    pRes->qId = 0x1;
H
Haojun Liao 已提交
930
    pRes->numOfRows = 0;
931
  } else if (pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE || pCmd->command == TSDB_SQL_SHOW_CREATE_STABLE) {
932 933 934
    pRes->code = tscProcessShowCreateTable(pSql); 
  } else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
    pRes->code = tscProcessShowCreateDatabase(pSql); 
H
hzcheng 已提交
935
  } else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
936 937
    taosHashClear(UTIL_GET_TABLEMETA(pSql));
    taosCacheEmpty(UTIL_GET_VGROUPLIST(pSql));
H
Haojun Liao 已提交
938
    pRes->code = TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
939
  } else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
H
Haojun Liao 已提交
940
    pRes->code = tscProcessServerVer(pSql);
H
hjxilinx 已提交
941
  } else if (pCmd->command == TSDB_SQL_CLI_VERSION) {
H
Haojun Liao 已提交
942
    pRes->code = tscProcessClientVer(pSql);
H
hjxilinx 已提交
943
  } else if (pCmd->command == TSDB_SQL_CURRENT_USER) {
H
Haojun Liao 已提交
944
    pRes->code = tscProcessCurrentUser(pSql);
H
hjxilinx 已提交
945
  } else if (pCmd->command == TSDB_SQL_CURRENT_DB) {
H
Haojun Liao 已提交
946
    pRes->code = tscProcessCurrentDB(pSql);
H
hjxilinx 已提交
947
  } else if (pCmd->command == TSDB_SQL_SERV_STATUS) {
H
Haojun Liao 已提交
948
    pRes->code = tscProcessServStatus(pSql);
H
hzcheng 已提交
949
  } else {
950
    pRes->code = TSDB_CODE_TSC_INVALID_OPERATION;
D
dapan1121 已提交
951
    tscError("0x%"PRIx64" not support command:%d", pSql->self, pCmd->command);
H
hzcheng 已提交
952 953
  }

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

H
Haojun Liao 已提交
956
  int32_t code = pRes->code;
957
  if (code == TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
958
    (*pSql->fp)(pSql->param, pSql, code);
959
  } else if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS){
960
  } else {
H
Haojun Liao 已提交
961
    tscAsyncResultOnError(pSql);
H
hzcheng 已提交
962 963 964
  }
  return code;
}