clientMain.c 21.2 KB
Newer Older
L
Liu Jicong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * 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/>.
 */

#include "catalog.h"
17
#include "clientInt.h"
18
#include "clientLog.h"
L
Liu Jicong 已提交
19
#include "clientStmt.h"
L
Liu Jicong 已提交
20
#include "os.h"
H
Haojun Liao 已提交
21
#include "query.h"
L
Liu Jicong 已提交
22
#include "scheduler.h"
23
#include "tglobal.h"
L
Liu Jicong 已提交
24 25 26
#include "tmsg.h"
#include "tref.h"
#include "trpc.h"
S
version  
Shengliang Guan 已提交
27
#include "version.h"
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

#define TSC_VAR_NOT_RELEASE 1
#define TSC_VAR_RELEASED    0

static int32_t sentinel = TSC_VAR_NOT_RELEASE;

int taos_options(TSDB_OPTION option, const void *arg, ...) {
  static int32_t lock = 0;

  for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
    if (i % 1000 == 0) {
      tscInfo("haven't acquire lock after spin %d times.", i);
      sched_yield();
    }
  }

L
Liu Jicong 已提交
44
  int ret = taos_options_imp(option, (const char *)arg);
45 46 47 48 49 50
  atomic_store_32(&lock, 0);
  return ret;
}

// this function may be called by user or system, or by both simultaneously.
void taos_cleanup(void) {
H
Haojun Liao 已提交
51
  tscInfo("start to cleanup client environment");
52 53 54 55 56

  if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
    return;
  }

H
Haojun Liao 已提交
57 58
  int32_t id = clientReqRefPool;
  clientReqRefPool = -1;
59 60
  taosCloseRef(id);

H
Haojun Liao 已提交
61
  cleanupTaskQueue();
62

63 64
  id = clientConnRefPool;
  clientConnRefPool = -1;
65 66
  taosCloseRef(id);

67 68
  hbMgrCleanUp();

D
dapan1121 已提交
69
  catalogDestroy();
D
dapan1121 已提交
70
  schedulerDestroy();
H
Haojun Liao 已提交
71

D
dapan1121 已提交
72 73
  rpcCleanup();

H
Haojun Liao 已提交
74
  tscInfo("all local resources released");
75
  taosCleanupCfg();
76
  taosCloseLog();
77 78
}

L
Liu Jicong 已提交
79
setConfRet taos_set_config(const char *config) {
80 81 82 83 84
  // TODO
  setConfRet ret = {SET_CONF_RET_SUCC, {0}};
  return ret;
}

85
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
S
Shengliang Guan 已提交
86
  tscDebug("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
H
Haojun Liao 已提交
87 88 89
  if (user == NULL) {
    user = TSDB_DEFAULT_USER;
  }
90

H
Haojun Liao 已提交
91 92 93
  if (pass == NULL) {
    pass = TSDB_DEFAULT_PASS;
  }
94

L
Liu Jicong 已提交
95
  return taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY);
96 97
}

L
Liu Jicong 已提交
98
void taos_close(TAOS *taos) {
99 100 101 102
  if (taos == NULL) {
    return;
  }

H
Haojun Liao 已提交
103
  STscObj *pTscObj = (STscObj *)taos;
L
Liu Jicong 已提交
104
  tscDebug("0x%" PRIx64 " try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
105

D
dapan1121 已提交
106
  taosRemoveRef(clientConnRefPool, pTscObj->id);
107 108
}

109 110 111 112 113
int taos_errno(TAOS_RES *tres) {
  if (tres == NULL) {
    return terrno;
  }

114 115 116 117
  if (TD_RES_TMQ(tres)) {
    return 0;
  }

L
Liu Jicong 已提交
118
  return ((SRequestObj *)tres)->code;
119 120
}

121
const char *taos_errstr(TAOS_RES *res) {
122
  if (res == NULL) {
L
Liu Jicong 已提交
123
    return (const char *)tstrerror(terrno);
124 125
  }

126 127 128 129 130
  if (TD_RES_TMQ(res)) {
    return "success";
  }

  SRequestObj *pRequest = (SRequestObj *)res;
131
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
132 133
    return pRequest->msgBuf;
  } else {
L
Liu Jicong 已提交
134
    return (const char *)tstrerror(pRequest->code);
135
  }
136 137 138
}

void taos_free_result(TAOS_RES *res) {
D
stmt  
dapan1121 已提交
139 140 141
  if (NULL == res) {
    return;
  }
142

L
Liu Jicong 已提交
143 144 145
  if (TD_RES_QUERY(res)) {
    SRequestObj *pRequest = (SRequestObj *)res;
    destroyRequest(pRequest);
L
Liu Jicong 已提交
146 147 148 149 150 151
  } else if (TD_RES_TMQ(res)) {
    SMqRspObj *pRsp = (SMqRspObj *)res;
    if (pRsp->rsp.blockData) taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
    if (pRsp->rsp.blockDataLen) taosArrayDestroy(pRsp->rsp.blockDataLen);
    if (pRsp->rsp.blockTags) taosArrayDestroy(pRsp->rsp.blockTags);
    if (pRsp->rsp.blockTagSchema) taosArrayDestroy(pRsp->rsp.blockTagSchema);
L
Liu Jicong 已提交
152 153
    if (pRsp->rsp.withTbName) taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
    if (pRsp->rsp.withSchema) taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
L
Liu Jicong 已提交
154 155
    pRsp->resInfo.pRspMsg = NULL;
    doFreeReqResultInfo(&pRsp->resInfo);
L
Liu Jicong 已提交
156
  }
157 158
}

L
Liu Jicong 已提交
159
int taos_field_count(TAOS_RES *res) {
H
Haojun Liao 已提交
160 161 162 163
  if (res == NULL) {
    return 0;
  }

L
Liu Jicong 已提交
164
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
H
Haojun Liao 已提交
165 166 167
  return pResInfo->numOfCols;
}

L
Liu Jicong 已提交
168
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
H
Haojun Liao 已提交
169 170 171 172 173 174

TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
  if (taos_num_fields(res) == 0) {
    return NULL;
  }

L
Liu Jicong 已提交
175
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
176
  return pResInfo->userFields;
H
Haojun Liao 已提交
177 178
}

179 180 181 182 183
TAOS_RES *taos_query(TAOS *taos, const char *sql) {
  if (taos == NULL || sql == NULL) {
    return NULL;
  }

L
Liu Jicong 已提交
184
  return taos_query_l(taos, sql, (int32_t)strlen(sql));
185
}
186

187 188
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
  if (res == NULL) {
189 190 191
    return NULL;
  }

L
Liu Jicong 已提交
192 193 194 195 196 197 198
  if (TD_RES_QUERY(res)) {
    SRequestObj *pRequest = (SRequestObj *)res;
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
      return NULL;
    }

199
    return doFetchRows(pRequest, true, true);
L
Liu Jicong 已提交
200 201

  } else if (TD_RES_TMQ(res)) {
L
Liu Jicong 已提交
202 203 204 205 206 207 208
    SMqRspObj      *msg = ((SMqRspObj *)res);
    SReqResultInfo *pResultInfo;
    if (msg->resIter == -1) {
      pResultInfo = tmqGetNextResInfo(res, true);
    } else {
      pResultInfo = tmqGetCurResInfo(res);
    }
L
Liu Jicong 已提交
209
    if (pResultInfo->current < pResultInfo->numOfRows) {
L
Liu Jicong 已提交
210 211
      doSetOneRowPtr(pResultInfo);
      pResultInfo->current += 1;
L
Liu Jicong 已提交
212 213
      return pResultInfo->row;
    } else {
L
Liu Jicong 已提交
214 215 216 217 218
      pResultInfo = tmqGetNextResInfo(res, true);
      if (pResultInfo == NULL) return NULL;
      doSetOneRowPtr(pResultInfo);
      pResultInfo->current += 1;
      return pResultInfo->row;
L
Liu Jicong 已提交
219 220
    }
  } else {
221
    // assert to avoid un-initialization error
L
Liu Jicong 已提交
222 223 224
    ASSERT(0);
  }
  return NULL;
225
}
H
Haojun Liao 已提交
226

L
Liu Jicong 已提交
227
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
H
Haojun Liao 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 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 277 278 279 280 281 282 283 284 285
  int32_t len = 0;
  for (int i = 0; i < num_fields; ++i) {
    if (i > 0) {
      str[len++] = ' ';
    }

    if (row[i] == NULL) {
      len += sprintf(str + len, "%s", TSDB_DATA_NULL_STR);
      continue;
    }

    switch (fields[i].type) {
      case TSDB_DATA_TYPE_TINYINT:
        len += sprintf(str + len, "%d", *((int8_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_UTINYINT:
        len += sprintf(str + len, "%u", *((uint8_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_SMALLINT:
        len += sprintf(str + len, "%d", *((int16_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_USMALLINT:
        len += sprintf(str + len, "%u", *((uint16_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_INT:
        len += sprintf(str + len, "%d", *((int32_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_UINT:
        len += sprintf(str + len, "%u", *((uint32_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_BIGINT:
        len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_UBIGINT:
        len += sprintf(str + len, "%" PRIu64, *((uint64_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_FLOAT: {
        float fv = 0;
        fv = GET_FLOAT_VAL(row[i]);
        len += sprintf(str + len, "%f", fv);
      } break;

      case TSDB_DATA_TYPE_DOUBLE: {
        double dv = 0;
        dv = GET_DOUBLE_VAL(row[i]);
        len += sprintf(str + len, "%lf", dv);
      } break;

      case TSDB_DATA_TYPE_BINARY:
      case TSDB_DATA_TYPE_NCHAR: {
L
Liu Jicong 已提交
286
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
H
Haojun Liao 已提交
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
        if (fields[i].type == TSDB_DATA_TYPE_BINARY) {
          assert(charLen <= fields[i].bytes && charLen >= 0);
        } else {
          assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE && charLen >= 0);
        }

        memcpy(str + len, row[i], charLen);
        len += charLen;
      } break;

      case TSDB_DATA_TYPE_TIMESTAMP:
        len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i]));
        break;

      case TSDB_DATA_TYPE_BOOL:
        len += sprintf(str + len, "%d", *((int8_t *)row[i]));
      default:
        break;
    }
  }
L
Liu Jicong 已提交
307
  str[len] = 0;
H
Haojun Liao 已提交
308 309 310

  return len;
}
311

L
Liu Jicong 已提交
312
int *taos_fetch_lengths(TAOS_RES *res) {
313 314 315 316
  if (res == NULL) {
    return NULL;
  }

L
Liu Jicong 已提交
317 318
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
  return pResInfo->length;
319 320
}

321
TAOS_ROW *taos_result_block(TAOS_RES *res) {
L
Liu Jicong 已提交
322
  if (res == NULL) {
323 324 325 326 327 328 329 330
    terrno = TSDB_CODE_INVALID_PARA;
    return NULL;
  }

  if (taos_is_update_query(res)) {
    return NULL;
  }

L
Liu Jicong 已提交
331 332
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
  return &pResInfo->row;
333 334
}

335
// todo intergrate with tDataTypes
336 337
const char *taos_data_type(int type) {
  switch (type) {
L
Liu Jicong 已提交
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
    case TSDB_DATA_TYPE_NULL:
      return "TSDB_DATA_TYPE_NULL";
    case TSDB_DATA_TYPE_BOOL:
      return "TSDB_DATA_TYPE_BOOL";
    case TSDB_DATA_TYPE_TINYINT:
      return "TSDB_DATA_TYPE_TINYINT";
    case TSDB_DATA_TYPE_SMALLINT:
      return "TSDB_DATA_TYPE_SMALLINT";
    case TSDB_DATA_TYPE_INT:
      return "TSDB_DATA_TYPE_INT";
    case TSDB_DATA_TYPE_BIGINT:
      return "TSDB_DATA_TYPE_BIGINT";
    case TSDB_DATA_TYPE_FLOAT:
      return "TSDB_DATA_TYPE_FLOAT";
    case TSDB_DATA_TYPE_DOUBLE:
      return "TSDB_DATA_TYPE_DOUBLE";
    case TSDB_DATA_TYPE_VARCHAR:
      return "TSDB_DATA_TYPE_VARCHAR";
      //    case TSDB_DATA_TYPE_BINARY:          return "TSDB_DATA_TYPE_VARCHAR";
    case TSDB_DATA_TYPE_TIMESTAMP:
      return "TSDB_DATA_TYPE_TIMESTAMP";
    case TSDB_DATA_TYPE_NCHAR:
      return "TSDB_DATA_TYPE_NCHAR";
    case TSDB_DATA_TYPE_JSON:
      return "TSDB_DATA_TYPE_JSON";
    default:
      return "UNKNOWN";
365 366
  }
}
367 368 369

const char *taos_get_client_info() { return version; }

X
Xiaoyu Wang 已提交
370
int taos_affected_rows(TAOS_RES *res) {
L
Liu Jicong 已提交
371
  if (res == NULL || TD_RES_TMQ(res)) {
H
Haojun Liao 已提交
372 373 374
    return 0;
  }

L
Liu Jicong 已提交
375 376
  SRequestObj    *pRequest = (SRequestObj *)res;
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
H
Haojun Liao 已提交
377
  return pResInfo->numOfRows;
X
Xiaoyu Wang 已提交
378
}
379

380
int taos_result_precision(TAOS_RES *res) {
L
Liu Jicong 已提交
381
  if (res == NULL) {
H
Haojun Liao 已提交
382 383
    return TSDB_TIME_PRECISION_MILLI;
  }
384

L
Liu Jicong 已提交
385 386 387 388 389 390 391 392
  if (TD_RES_QUERY(res)) {
    SRequestObj *pRequest = (SRequestObj *)res;
    return pRequest->body.resInfo.precision;
  } else if (TD_RES_TMQ(res)) {
    SReqResultInfo *info = tmqGetCurResInfo(res);
    return info->precision;
  }
  return TSDB_TIME_PRECISION_MILLI;
393
}
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409

int taos_select_db(TAOS *taos, const char *db) {
  STscObj *pObj = (STscObj *)taos;
  if (pObj == NULL) {
    terrno = TSDB_CODE_TSC_DISCONNECTED;
    return TSDB_CODE_TSC_DISCONNECTED;
  }

  if (db == NULL || strlen(db) == 0) {
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
    return terrno;
  }

  char sql[256] = {0};
  snprintf(sql, tListLen(sql), "use %s", db);

L
Liu Jicong 已提交
410 411
  TAOS_RES *pRequest = taos_query(taos, sql);
  int32_t   code = taos_errno(pRequest);
412 413 414 415 416 417 418 419 420 421

  taos_free_result(pRequest);
  return code;
}

void taos_stop_query(TAOS_RES *res) {
  if (res == NULL) {
    return;
  }

L
Liu Jicong 已提交
422 423
  SRequestObj *pRequest = (SRequestObj *)res;
  int32_t      numOfFields = taos_num_fields(pRequest);
424 425 426 427 428 429

  // It is not a query, no need to stop.
  if (numOfFields == 0) {
    return;
  }

D
dapan1121 已提交
430
  schedulerFreeJob(pRequest->body.queryJob);
431 432 433
}

bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
L
Liu Jicong 已提交
434
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
435 436 437 438
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
    return true;
  }

L
Liu Jicong 已提交
439
  SResultColumn *pCol = &pResultInfo->pCol[col];
440 441 442 443 444
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
    return (pCol->offset[row] == -1);
  } else {
    return colDataIsNull_f(pCol->nullbitmap, row);
  }
445 446
}

L
Liu Jicong 已提交
447
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
448

L
Liu Jicong 已提交
449
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
H
Haojun Liao 已提交
450
  int32_t numOfRows = 0;
L
Liu Jicong 已提交
451
  /*int32_t code = */ taos_fetch_block_s(res, &numOfRows, rows);
H
Haojun Liao 已提交
452 453 454
  return numOfRows;
}

L
Liu Jicong 已提交
455 456
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
  if (res == NULL) {
457 458
    return 0;
  }
L
Liu Jicong 已提交
459 460
  if (TD_RES_QUERY(res)) {
    SRequestObj *pRequest = (SRequestObj *)res;
461

L
Liu Jicong 已提交
462 463
    (*rows) = NULL;
    (*numOfRows) = 0;
H
Haojun Liao 已提交
464

L
Liu Jicong 已提交
465 466 467 468
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
      return 0;
    }
469

470
    doFetchRows(pRequest, false, true);
471

L
Liu Jicong 已提交
472 473 474
    // TODO refactor
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
    pResultInfo->current = pResultInfo->numOfRows;
475

L
Liu Jicong 已提交
476 477 478 479
    (*rows) = pResultInfo->row;
    (*numOfRows) = pResultInfo->numOfRows;
    return pRequest->code;
  } else if (TD_RES_TMQ(res)) {
L
Liu Jicong 已提交
480
    SReqResultInfo *pResultInfo = tmqGetNextResInfo(res, true);
L
Liu Jicong 已提交
481
    if (pResultInfo == NULL) return -1;
H
Haojun Liao 已提交
482

L
Liu Jicong 已提交
483 484 485
    pResultInfo->current = pResultInfo->numOfRows;
    (*rows) = pResultInfo->row;
    (*numOfRows) = pResultInfo->numOfRows;
H
Haojun Liao 已提交
486
    return 0;
L
Liu Jicong 已提交
487 488 489
  } else {
    ASSERT(0);
    return -1;
H
Haojun Liao 已提交
490
  }
L
Liu Jicong 已提交
491
}
H
Haojun Liao 已提交
492

L
Liu Jicong 已提交
493 494
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
  if (res == NULL) {
H
Haojun Liao 已提交
495 496
    return 0;
  }
497

498
  if (TD_RES_TMQ(res)) {
L
Liu Jicong 已提交
499
    SReqResultInfo *pResultInfo = tmqGetNextResInfo(res, false);
L
Liu Jicong 已提交
500 501 502 503
    if (pResultInfo == NULL) {
      (*numOfRows) = 0;
      return 0;
    }
H
Haojun Liao 已提交
504

L
Liu Jicong 已提交
505 506 507 508
    pResultInfo->current = pResultInfo->numOfRows;
    (*numOfRows) = pResultInfo->numOfRows;
    (*pData) = (void *)pResultInfo->pData;
    return 0;
509
  }
L
Liu Jicong 已提交
510

511 512 513 514 515
  SRequestObj *pRequest = (SRequestObj *)res;

  if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
      pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
    return 0;
L
Liu Jicong 已提交
516
  }
517 518 519 520 521 522 523 524 525 526

  doFetchRows(pRequest, false, false);

  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;

  pResultInfo->current = pResultInfo->numOfRows;
  (*numOfRows) = pResultInfo->numOfRows;
  (*pData) = (void *)pResultInfo->pData;

  return 0;
527 528
}

H
Haojun Liao 已提交
529
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
L
Liu Jicong 已提交
530
  if (res == NULL) {
H
Haojun Liao 已提交
531 532 533
    return 0;
  }

L
Liu Jicong 已提交
534
  int32_t numOfFields = taos_num_fields(res);
H
Haojun Liao 已提交
535 536 537 538
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
    return 0;
  }

L
Liu Jicong 已提交
539 540
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
H
Haojun Liao 已提交
541 542 543 544
  if (!IS_VAR_DATA_TYPE(pField->type)) {
    return 0;
  }

L
Liu Jicong 已提交
545
  return pResInfo->pCol[columnIndex].offset;
H
Haojun Liao 已提交
546 547
}

L
Liu Jicong 已提交
548
int taos_validate_sql(TAOS *taos, const char *sql) { return true; }
549

550
void taos_reset_current_db(TAOS *taos) {
H
Haojun Liao 已提交
551 552 553 554 555
  if (taos == NULL) {
    return;
  }

  resetConnectDB(taos);
556 557
}

558 559 560 561 562
const char *taos_get_server_info(TAOS *taos) {
  if (taos == NULL) {
    return NULL;
  }

L
Liu Jicong 已提交
563
  STscObj *pTscObj = (STscObj *)taos;
564 565 566 567
  return pTscObj->ver;
}

void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
568 569 570 571 572 573 574 575 576
  if (taos == NULL || sql == NULL) {
    fp(param, NULL, TSDB_CODE_INVALID_PARA);
    return;
  }

  SRequestObj* pRequest = NULL;
  int32_t      retryNum = 0;
  int32_t      code = 0;

577 578
  size_t sqlLen = strlen(sql);

579
  while (retryNum++ < REQUEST_MAX_TRY_TIMES) {
580
    pRequest = launchQuery(taos, sql, sqlLen);
581 582 583 584 585 586 587 588 589 590 591 592 593 594
    if (pRequest == NULL || TSDB_CODE_SUCCESS == pRequest->code || !NEED_CLIENT_HANDLE_ERROR(pRequest->code)) {
      break;
    }

    code = refreshMeta(taos, pRequest);
    if (code) {
      pRequest->code = code;
      break;
    }

    destroyRequest(pRequest);
  }

  fp(param, pRequest, code);
595 596 597 598
}

void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
  // TODO
L
Liu Jicong 已提交
599
}
600

L
Liu Jicong 已提交
601 602 603 604
TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char *topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp,
                         void *param, int interval) {
  // TODO
  return NULL;
605 606 607
}

TAOS_RES *taos_consume(TAOS_SUB *tsub) {
L
Liu Jicong 已提交
608 609
  // TODO
  return NULL;
610 611 612
}

void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress) {
L
Liu Jicong 已提交
613
  // TODO
614 615
}

616 617 618 619 620
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
  // TODO
  return -1;
}

L
Liu Jicong 已提交
621
TAOS_STMT *taos_stmt_init(TAOS *taos) {
D
stmt  
dapan1121 已提交
622
  if (taos == NULL) {
D
stmt  
dapan1121 已提交
623
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
624 625 626 627 628
    terrno = TSDB_CODE_INVALID_PARA;
    return NULL;
  }

  return stmtInit(taos);
629 630
}

D
stmt  
dapan1121 已提交
631 632
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
  if (stmt == NULL || sql == NULL) {
D
stmt  
dapan1121 已提交
633
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
634 635 636 637
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
stmt  
dapan1121 已提交
638
  return stmtPrepare(stmt, sql, length);
639 640
}

D
dapan1121 已提交
641
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
D
stmt  
dapan1121 已提交
642
  if (stmt == NULL || name == NULL) {
D
stmt  
dapan1121 已提交
643
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
644 645 646 647
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
stmt  
dapan1121 已提交
648 649 650 651 652 653 654 655 656 657
  int32_t code = stmtSetTbName(stmt, name);
  if (code) {
    return code;
  }

  if (tags) {
    return stmtSetTbTags(stmt, tags);
  }

  return TSDB_CODE_SUCCESS;
658 659
}

D
stmt  
dapan1121 已提交
660 661
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
  if (stmt == NULL || name == NULL) {
D
stmt  
dapan1121 已提交
662
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
663
    terrno = TSDB_CODE_INVALID_PARA;
D
stmt  
dapan1121 已提交
664
    return terrno;
D
stmt  
dapan1121 已提交
665 666
  }

D
stmt  
dapan1121 已提交
667
  return stmtSetTbName(stmt, name);
668 669
}

D
dapan1121 已提交
670 671 672 673 674 675 676 677 678 679 680
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
  if (stmt == NULL || tags == NULL) {
    tscError("NULL parameter for %s", __FUNCTION__);
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

  return stmtSetTbTags(stmt, tags);
}


681
int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name) { return taos_stmt_set_tbname(stmt, name); }
D
dapan1121 已提交
682

D
dapan1121 已提交
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int* fieldNum, TAOS_FIELD_E** fields) {
  if (stmt == NULL || NULL == fieldNum) {
    tscError("NULL parameter for %s", __FUNCTION__);
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }
  
  return stmtGetTagFields(stmt, fieldNum, fields);
}

int taos_stmt_get_col_fields(TAOS_STMT *stmt, int* fieldNum, TAOS_FIELD_E** fields) {
  if (stmt == NULL || NULL == fieldNum) {
    tscError("NULL parameter for %s", __FUNCTION__);
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }
  
  return stmtGetColFields(stmt, fieldNum, fields);
}

D
dapan1121 已提交
703
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
D
stmt  
dapan1121 已提交
704
  if (stmt == NULL || bind == NULL) {
D
stmt  
dapan1121 已提交
705
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
706
    terrno = TSDB_CODE_INVALID_PARA;
D
stmt  
dapan1121 已提交
707
    return terrno;
D
stmt  
dapan1121 已提交
708
  }
709

D
stmt  
dapan1121 已提交
710 711 712 713 714
  if (bind->num > 1) {
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }
715

D
stmt  
dapan1121 已提交
716
  return stmtBindBatch(stmt, bind, -1);
717 718
}

D
dapan1121 已提交
719
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
D
stmt  
dapan1121 已提交
720
  if (stmt == NULL || bind == NULL) {
D
stmt  
dapan1121 已提交
721
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
722 723 724 725
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
stmt  
dapan1121 已提交
726 727
  if (bind->num <= 0 || bind->num > INT16_MAX) {
    tscError("invalid bind num %d", bind->num);
D
stmt  
dapan1121 已提交
728 729 730 731
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
dapan1121 已提交
732 733 734 735 736 737 738 739
  int32_t insert = 0;
  stmtIsInsert(stmt, &insert);
  if (0 == insert && bind->num > 1) {
    tscError("only one row data allowed for query");
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
stmt  
dapan1121 已提交
740
  return stmtBindBatch(stmt, bind, -1);
741 742
}

D
dapan1121 已提交
743
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
D
stmt  
dapan1121 已提交
744
  if (stmt == NULL || bind == NULL) {
D
stmt  
dapan1121 已提交
745
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
746 747 748 749
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
stmt  
dapan1121 已提交
750
  if (colIdx < 0) {
D
stmt  
dapan1121 已提交
751 752 753 754
    tscError("invalid bind column idx %d", colIdx);
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }
D
dapan1121 已提交
755 756 757 758 759 760 761 762

  int32_t insert = 0;
  stmtIsInsert(stmt, &insert);
  if (0 == insert && bind->num > 1) {
    tscError("only one row data allowed for query");
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }
763

D
stmt  
dapan1121 已提交
764
  return stmtBindBatch(stmt, bind, colIdx);
765 766
}

D
stmt  
dapan1121 已提交
767 768
int taos_stmt_add_batch(TAOS_STMT *stmt) {
  if (stmt == NULL) {
D
stmt  
dapan1121 已提交
769
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
770 771 772 773
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
stmt  
dapan1121 已提交
774
  return stmtAddBatch(stmt);
775 776
}

D
stmt  
dapan1121 已提交
777 778
int taos_stmt_execute(TAOS_STMT *stmt) {
  if (stmt == NULL) {
D
stmt  
dapan1121 已提交
779
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
780 781 782 783
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
stmt  
dapan1121 已提交
784
  return stmtExec(stmt);
785 786
}

787
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
D
stmt  
dapan1121 已提交
788
  if (stmt == NULL || insert == NULL) {
D
stmt  
dapan1121 已提交
789
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
790 791 792 793 794
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

  return stmtIsInsert(stmt, insert);
795 796
}

797
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
D
stmt  
dapan1121 已提交
798
  if (stmt == NULL || nums == NULL) {
D
stmt  
dapan1121 已提交
799
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
800 801 802 803 804
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

  return stmtGetParamNum(stmt, nums);
805 806
}

D
dapan1121 已提交
807 808 809 810 811 812 813 814 815 816
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
    tscError("invalid parameter for %s", __FUNCTION__);
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

  return stmtGetParam(stmt, idx, type, bytes);
}

D
stmt  
dapan1121 已提交
817
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
D
stmt  
dapan1121 已提交
818
  if (stmt == NULL) {
D
stmt  
dapan1121 已提交
819
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
820
    terrno = TSDB_CODE_INVALID_PARA;
D
stmt  
dapan1121 已提交
821
    return NULL;
D
stmt  
dapan1121 已提交
822 823
  }

D
stmt  
dapan1121 已提交
824
  return stmtUseResult(stmt);
825 826
}

827
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
828

D
stmt  
dapan1121 已提交
829
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
D
stmt  
dapan1121 已提交
830
  if (stmt == NULL) {
D
stmt  
dapan1121 已提交
831
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
832
    terrno = TSDB_CODE_INVALID_PARA;
D
stmt  
dapan1121 已提交
833
    return 0;
D
stmt  
dapan1121 已提交
834 835
  }

D
stmt  
dapan1121 已提交
836
  return stmtAffectedRows(stmt);
837 838
}

D
dapan1121 已提交
839 840 841 842 843 844 845 846 847 848
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
  if (stmt == NULL) {
    tscError("NULL parameter for %s", __FUNCTION__);
    terrno = TSDB_CODE_INVALID_PARA;
    return 0;
  }

  return stmtAffectedRowsOnce(stmt);
}

D
stmt  
dapan1121 已提交
849 850
int taos_stmt_close(TAOS_STMT *stmt) {
  if (stmt == NULL) {
D
stmt  
dapan1121 已提交
851
    tscError("NULL parameter for %s", __FUNCTION__);
D
stmt  
dapan1121 已提交
852 853 854 855
    terrno = TSDB_CODE_INVALID_PARA;
    return terrno;
  }

D
stmt  
dapan1121 已提交
856
  return stmtClose(stmt);
D
stmt  
dapan1121 已提交
857 858
}