TDengine/source/client/src/clientMain.c

1703 lines
48 KiB
C
Raw Normal View History

2022-03-29 07:24:25 +00:00
/*
* 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"
#include "clientInt.h"
2021-12-14 07:51:57 +00:00
#include "clientLog.h"
2022-04-20 13:36:55 +00:00
#include "clientStmt.h"
2022-06-21 05:50:33 +00:00
#include "functionMgt.h"
2022-03-29 07:24:25 +00:00
#include "os.h"
2021-12-21 09:18:39 +00:00
#include "query.h"
2022-04-20 13:36:55 +00:00
#include "scheduler.h"
2022-12-09 01:41:06 +00:00
#include "tdatablock.h"
#include "tglobal.h"
2022-03-29 07:24:25 +00:00
#include "tmsg.h"
#include "tref.h"
#include "trpc.h"
2022-02-23 12:39:21 +00:00
#include "version.h"
#define TSC_VAR_NOT_RELEASE 1
#define TSC_VAR_RELEASED 0
static int32_t sentinel = TSC_VAR_NOT_RELEASE;
2022-06-11 13:32:29 +00:00
static int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt);
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();
}
}
2022-03-29 07:24:25 +00:00
int ret = taos_options_imp(option, (const char *)arg);
atomic_store_32(&lock, 0);
return ret;
}
// this function may be called by user or system, or by both simultaneously.
void taos_cleanup(void) {
2022-07-13 12:25:16 +00:00
tscDebug("start to cleanup client environment");
if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
return;
}
2022-12-30 05:30:54 +00:00
tscStopCrashReport();
2021-12-24 15:39:55 +00:00
int32_t id = clientReqRefPool;
clientReqRefPool = -1;
taosCloseRef(id);
2022-07-13 12:25:16 +00:00
hbMgrCleanUp();
catalogDestroy();
schedulerDestroy();
2022-06-14 07:43:56 +00:00
fmFuncMgtDestroy();
qCleanupKeywordsTable();
nodesDestroyAllocatorSet();
2022-06-14 07:43:56 +00:00
id = clientConnRefPool;
clientConnRefPool = -1;
taosCloseRef(id);
2022-07-13 12:25:16 +00:00
rpcCleanup();
tscDebug("rpc cleanup");
2022-07-13 12:25:16 +00:00
cleanupTaskQueue();
2022-01-04 02:30:57 +00:00
2022-07-29 10:35:23 +00:00
taosConvDestroy();
2022-08-03 10:49:59 +00:00
2022-01-04 02:30:57 +00:00
tscInfo("all local resources released");
taosCleanupCfg();
taosCloseLog();
}
2022-06-29 12:57:15 +00:00
static setConfRet taos_set_config_imp(const char *config) {
setConfRet ret = {SET_CONF_RET_SUCC, {0}};
// TODO: need re-implementation
return ret;
}
2022-06-29 12:57:15 +00:00
setConfRet taos_set_config(const char *config) {
// TODO pthread_mutex_lock(&setConfMutex);
setConfRet ret = taos_set_config_imp(config);
2022-06-29 12:57:15 +00:00
// pthread_mutex_unlock(&setConfMutex);
return ret;
}
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
2022-02-23 07:02:17 +00:00
tscDebug("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
2021-12-17 03:22:31 +00:00
if (user == NULL) {
user = TSDB_DEFAULT_USER;
}
2021-12-17 03:22:31 +00:00
if (pass == NULL) {
pass = TSDB_DEFAULT_PASS;
}
2023-04-25 09:39:28 +00:00
2022-06-21 05:50:33 +00:00
STscObj *pObj = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY);
if (pObj) {
2022-06-27 01:50:42 +00:00
int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
*rid = pObj->id;
2022-07-02 09:00:57 +00:00
return (TAOS *)rid;
}
2022-06-21 05:50:33 +00:00
2022-06-17 12:21:41 +00:00
return NULL;
}
2023-04-19 06:47:06 +00:00
int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) {
2023-04-09 10:44:46 +00:00
if (taos == NULL) {
2023-04-18 11:58:02 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
2023-04-09 10:44:46 +00:00
}
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
if (NULL == pObj) {
2023-04-18 11:58:02 +00:00
terrno = TSDB_CODE_TSC_DISCONNECTED;
2023-04-09 10:44:46 +00:00
tscError("invalid parameter for %s", __func__);
2023-04-18 11:58:02 +00:00
return terrno;
2023-04-09 10:44:46 +00:00
}
2023-04-10 07:11:54 +00:00
switch (type) {
case TAOS_NOTIFY_PASSVER: {
2023-04-25 02:59:02 +00:00
taosThreadMutexLock(&pObj->mutex);
pObj->passInfo.fp = fp;
pObj->passInfo.param = param;
taosThreadMutexUnlock(&pObj->mutex);
2023-04-10 07:11:54 +00:00
break;
}
2023-04-18 11:58:02 +00:00
default: {
terrno = TSDB_CODE_INVALID_PARA;
releaseTscObj(*(int64_t *)taos);
return terrno;
}
2023-04-10 07:11:54 +00:00
}
2023-04-09 10:44:46 +00:00
2023-04-09 10:55:05 +00:00
releaseTscObj(*(int64_t *)taos);
2023-04-09 10:44:46 +00:00
return 0;
}
void taos_close_internal(void *taos) {
if (taos == NULL) {
return;
}
2021-12-14 07:08:06 +00:00
STscObj *pTscObj = (STscObj *)taos;
2022-06-27 01:50:42 +00:00
tscDebug("0x%" PRIx64 " try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
2022-06-27 01:50:42 +00:00
taosRemoveRef(clientConnRefPool, pTscObj->id);
}
void taos_close(TAOS *taos) {
2022-06-18 00:21:31 +00:00
if (taos == NULL) {
return;
}
2022-06-21 05:50:33 +00:00
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
if (NULL == pObj) {
2022-07-14 06:03:27 +00:00
taosMemoryFree(taos);
return;
}
2022-06-21 05:50:33 +00:00
taos_close_internal(pObj);
2022-06-21 05:50:33 +00:00
releaseTscObj(*(int64_t *)taos);
2022-06-17 12:21:41 +00:00
taosMemoryFree(taos);
}
2022-06-21 05:50:33 +00:00
int taos_errno(TAOS_RES *res) {
if (res == NULL || TD_RES_TMQ_META(res)) {
return terrno;
}
if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
return 0;
}
2022-12-02 14:24:35 +00:00
return ((SRequestObj *)res)->code;
}
const char *taos_errstr(TAOS_RES *res) {
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
2022-03-29 07:24:25 +00:00
return (const char *)tstrerror(terrno);
}
if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
return "success";
}
SRequestObj *pRequest = (SRequestObj *)res;
if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
return pRequest->msgBuf;
} else {
2022-12-02 14:24:35 +00:00
return (const char *)tstrerror(pRequest->code);
}
}
void taos_free_result(TAOS_RES *res) {
2022-04-18 05:22:47 +00:00
if (NULL == res) {
return;
}
2022-12-09 01:41:06 +00:00
tscDebug("taos free res %p", res);
2022-04-14 06:42:51 +00:00
if (TD_RES_QUERY(res)) {
SRequestObj *pRequest = (SRequestObj *)res;
2022-08-08 12:15:21 +00:00
tscDebug("0x%" PRIx64 " taos_free_result start to free query", pRequest->requestId);
2022-04-14 06:42:51 +00:00
destroyRequest(pRequest);
} else if (TD_RES_TMQ_METADATA(res)) {
2022-08-30 02:57:24 +00:00
SMqTaosxRspObj *pRsp = (SMqTaosxRspObj *)res;
2022-12-09 06:38:29 +00:00
taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
taosArrayDestroy(pRsp->rsp.blockDataLen);
taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
2023-05-04 08:15:14 +00:00
taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
2022-08-30 02:57:24 +00:00
// taosx
taosArrayDestroy(pRsp->rsp.createTableLen);
taosArrayDestroyP(pRsp->rsp.createTableReq, taosMemoryFree);
pRsp->resInfo.pRspMsg = NULL;
doFreeReqResultInfo(&pRsp->resInfo);
taosMemoryFree(pRsp);
2022-04-21 09:56:32 +00:00
} else if (TD_RES_TMQ(res)) {
SMqRspObj *pRsp = (SMqRspObj *)res;
2022-12-09 06:38:29 +00:00
taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
taosArrayDestroy(pRsp->rsp.blockDataLen);
taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
2023-05-04 08:15:14 +00:00
taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
2022-04-21 09:56:32 +00:00
pRsp->resInfo.pRspMsg = NULL;
doFreeReqResultInfo(&pRsp->resInfo);
taosMemoryFree(pRsp);
2022-06-21 05:50:33 +00:00
} else if (TD_RES_TMQ_META(res)) {
SMqMetaRspObj *pRspObj = (SMqMetaRspObj *)res;
taosMemoryFree(pRspObj->metaRsp.metaRsp);
taosMemoryFree(pRspObj);
2022-04-14 06:42:51 +00:00
}
2021-12-14 07:51:57 +00:00
}
2022-06-27 10:29:28 +00:00
void taos_kill_query(TAOS *taos) {
if (NULL == taos) {
return;
}
2022-07-02 09:00:57 +00:00
2022-07-04 08:10:59 +00:00
int64_t rid = *(int64_t *)taos;
2022-07-02 09:00:57 +00:00
STscObj *pTscObj = acquireTscObj(rid);
2022-10-14 05:26:10 +00:00
if (pTscObj) {
stopAllRequests(pTscObj->pRequests);
}
2022-06-27 10:29:28 +00:00
releaseTscObj(rid);
}
2022-03-29 07:24:25 +00:00
int taos_field_count(TAOS_RES *res) {
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
2021-12-17 03:22:31 +00:00
return 0;
}
2022-04-12 02:45:34 +00:00
SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2021-12-17 03:22:31 +00:00
return pResInfo->numOfCols;
}
2022-03-29 07:24:25 +00:00
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
2021-12-17 03:22:31 +00:00
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
2022-06-21 05:50:33 +00:00
if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res)) {
2021-12-17 03:22:31 +00:00
return NULL;
}
2022-04-12 02:45:34 +00:00
SReqResultInfo *pResInfo = tscGetCurResInfo(res);
return pResInfo->userFields;
2021-12-17 03:22:31 +00:00
}
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false); }
2022-11-03 12:08:30 +00:00
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
return taosQueryImplWithReqid(taos, sql, false, reqid);
}
2022-03-28 02:37:18 +00:00
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
if (res == NULL) {
return NULL;
}
2022-04-12 02:45:34 +00:00
if (TD_RES_QUERY(res)) {
SRequestObj *pRequest = (SRequestObj *)res;
if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
2022-06-16 13:06:04 +00:00
pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
2022-04-12 02:45:34 +00:00
return NULL;
}
2022-06-16 13:06:04 +00:00
return doAsyncFetchRows(pRequest, true, true);
} else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
2022-07-12 12:00:26 +00:00
SMqRspObj *msg = ((SMqRspObj *)res);
2022-04-20 13:36:55 +00:00
SReqResultInfo *pResultInfo;
if (msg->resIter == -1) {
pResultInfo = tmqGetNextResInfo(res, true);
} else {
pResultInfo = tmqGetCurResInfo(res);
}
2022-04-13 12:37:51 +00:00
if (pResultInfo->current < pResultInfo->numOfRows) {
2022-04-12 02:45:34 +00:00
doSetOneRowPtr(pResultInfo);
pResultInfo->current += 1;
2022-04-13 12:37:51 +00:00
return pResultInfo->row;
} else {
2022-04-20 13:36:55 +00:00
pResultInfo = tmqGetNextResInfo(res, true);
2023-03-03 02:20:52 +00:00
if (pResultInfo == NULL) {
return NULL;
}
2022-04-20 13:36:55 +00:00
doSetOneRowPtr(pResultInfo);
pResultInfo->current += 1;
return pResultInfo->row;
2022-04-12 02:45:34 +00:00
}
2022-06-23 07:46:42 +00:00
} else if (TD_RES_TMQ_META(res)) {
return NULL;
2022-04-12 02:45:34 +00:00
} else {
2022-04-15 04:09:27 +00:00
// assert to avoid un-initialization error
tscError("invalid result passed to taos_fetch_row");
return NULL;
2022-04-12 02:45:34 +00:00
}
}
2021-12-17 03:22:31 +00:00
2022-03-29 07:24:25 +00:00
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
2021-12-17 03:22:31 +00:00
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:
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_GEOMETRY: {
2022-03-29 07:24:25 +00:00
int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
2023-04-25 09:39:28 +00:00
if (ASSERT(charLen <= fields[i].bytes && charLen >= 0)) {
tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
}
2021-12-17 03:22:31 +00:00
} else {
2023-04-25 09:39:28 +00:00
if (ASSERT(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE && charLen >= 0)) {
tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
}
2021-12-17 03:22:31 +00:00
}
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;
}
}
2022-05-12 15:18:00 +00:00
str[len] = 0;
2021-12-17 03:22:31 +00:00
return len;
}
2021-12-17 03:48:23 +00:00
2022-03-29 07:24:25 +00:00
int *taos_fetch_lengths(TAOS_RES *res) {
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
2021-12-17 03:48:23 +00:00
return NULL;
}
2022-04-12 02:45:34 +00:00
SReqResultInfo *pResInfo = tscGetCurResInfo(res);
return pResInfo->length;
2021-12-17 03:48:23 +00:00
}
TAOS_ROW *taos_result_block(TAOS_RES *res) {
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
2022-04-02 10:25:57 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return NULL;
}
if (taos_is_update_query(res)) {
return NULL;
}
2022-04-12 02:45:34 +00:00
SReqResultInfo *pResInfo = tscGetCurResInfo(res);
return &pResInfo->row;
}
// todo intergrate with tDataTypes
2021-12-17 03:48:23 +00:00
const char *taos_data_type(int type) {
switch (type) {
2022-03-29 07:24:25 +00:00
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";
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
case TSDB_DATA_TYPE_GEOMETRY:
return "TSDB_DATA_TYPE_GEOMETRY";
case TSDB_DATA_TYPE_UTINYINT:
return "TSDB_DATA_TYPE_UTINYINT";
case TSDB_DATA_TYPE_USMALLINT:
return "TSDB_DATA_TYPE_USMALLINT";
case TSDB_DATA_TYPE_UINT:
return "TSDB_DATA_TYPE_UINT";
case TSDB_DATA_TYPE_UBIGINT:
return "TSDB_DATA_TYPE_UBIGINT";
case TSDB_DATA_TYPE_VARBINARY:
return "TSDB_DATA_TYPE_VARBINARY";
case TSDB_DATA_TYPE_DECIMAL:
return "TSDB_DATA_TYPE_DECIMAL";
case TSDB_DATA_TYPE_BLOB:
return "TSDB_DATA_TYPE_BLOB";
case TSDB_DATA_TYPE_MEDIUMBLOB:
return "TSDB_DATA_TYPE_MEDIUMBLOB";
2022-03-29 07:24:25 +00:00
default:
return "UNKNOWN";
2021-12-17 03:48:23 +00:00
}
}
const char *taos_get_client_info() { return version; }
// return int32_t
2022-01-04 09:16:32 +00:00
int taos_affected_rows(TAOS_RES *res) {
if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res)) {
2022-01-12 03:26:23 +00:00
return 0;
}
SRequestObj *pRequest = (SRequestObj *)res;
SReqResultInfo *pResInfo = &pRequest->body.resInfo;
return (int)pResInfo->numOfRows;
}
// return int64_t
2022-12-02 09:14:49 +00:00
int64_t taos_affected_rows64(TAOS_RES *res) {
if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res)) {
return 0;
}
2022-07-12 12:00:26 +00:00
SRequestObj *pRequest = (SRequestObj *)res;
2022-03-29 07:24:25 +00:00
SReqResultInfo *pResInfo = &pRequest->body.resInfo;
2022-01-12 03:26:23 +00:00
return pResInfo->numOfRows;
2022-01-04 09:16:32 +00:00
}
2022-04-02 10:25:57 +00:00
int taos_result_precision(TAOS_RES *res) {
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
2022-04-06 07:09:29 +00:00
return TSDB_TIME_PRECISION_MILLI;
}
2022-04-15 04:09:27 +00:00
2022-04-12 02:45:34 +00:00
if (TD_RES_QUERY(res)) {
SRequestObj *pRequest = (SRequestObj *)res;
return pRequest->body.resInfo.precision;
} else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
2022-04-12 02:45:34 +00:00
SReqResultInfo *info = tmqGetCurResInfo(res);
return info->precision;
}
return TSDB_TIME_PRECISION_MILLI;
2022-04-02 10:25:57 +00:00
}
int taos_select_db(TAOS *taos, const char *db) {
2022-06-21 05:50:33 +00:00
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
if (pObj == NULL) {
2022-06-21 05:50:33 +00:00
releaseTscObj(*(int64_t *)taos);
terrno = TSDB_CODE_TSC_DISCONNECTED;
return TSDB_CODE_TSC_DISCONNECTED;
}
if (db == NULL || strlen(db) == 0) {
2022-06-21 05:50:33 +00:00
releaseTscObj(*(int64_t *)taos);
terrno = TSDB_CODE_TSC_INVALID_INPUT;
return terrno;
}
char sql[256] = {0};
snprintf(sql, tListLen(sql), "use %s", db);
2022-03-29 07:24:25 +00:00
TAOS_RES *pRequest = taos_query(taos, sql);
int32_t code = taos_errno(pRequest);
taos_free_result(pRequest);
2022-06-21 05:50:33 +00:00
releaseTscObj(*(int64_t *)taos);
return code;
}
void taos_stop_query(TAOS_RES *res) {
if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res)) {
return;
}
2023-07-05 08:16:25 +00:00
stopAllQueries((SRequestObj *)res);
}
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
return true;
}
2022-04-12 02:45:34 +00:00
SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
return true;
}
2022-04-12 02:45:34 +00:00
SResultColumn *pCol = &pResultInfo->pCol[col];
if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
return (pCol->offset[row] == -1);
} else {
return colDataIsNull_f(pCol->nullbitmap, row);
}
}
2022-04-12 02:45:34 +00:00
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
2022-03-29 07:24:25 +00:00
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
2022-04-07 06:51:52 +00:00
int32_t numOfRows = 0;
2022-04-12 02:45:34 +00:00
/*int32_t code = */ taos_fetch_block_s(res, &numOfRows, rows);
2022-04-07 06:51:52 +00:00
return numOfRows;
}
2022-04-12 02:45:34 +00:00
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
2022-03-28 02:37:18 +00:00
return 0;
}
2022-04-12 02:45:34 +00:00
if (TD_RES_QUERY(res)) {
SRequestObj *pRequest = (SRequestObj *)res;
2022-03-28 02:37:18 +00:00
2022-04-12 02:45:34 +00:00
(*rows) = NULL;
(*numOfRows) = 0;
2022-04-07 06:51:52 +00:00
2022-04-12 02:45:34 +00:00
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;
}
2022-03-28 02:37:18 +00:00
doAsyncFetchRows(pRequest, false, true);
2022-03-28 02:37:18 +00:00
2022-04-12 02:45:34 +00:00
// TODO refactor
SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
pResultInfo->current = pResultInfo->numOfRows;
2022-03-28 02:37:18 +00:00
2022-04-12 02:45:34 +00:00
(*rows) = pResultInfo->row;
(*numOfRows) = pResultInfo->numOfRows;
return pRequest->code;
} else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
2022-04-20 13:36:55 +00:00
SReqResultInfo *pResultInfo = tmqGetNextResInfo(res, true);
2022-04-12 02:45:34 +00:00
if (pResultInfo == NULL) return -1;
2022-04-07 06:51:52 +00:00
2022-04-12 02:45:34 +00:00
pResultInfo->current = pResultInfo->numOfRows;
(*rows) = pResultInfo->row;
(*numOfRows) = pResultInfo->numOfRows;
2022-04-07 06:51:52 +00:00
return 0;
2022-04-12 02:45:34 +00:00
} else {
tscError("taos_fetch_block_s invalid res type");
2022-04-12 02:45:34 +00:00
return -1;
2022-04-07 06:51:52 +00:00
}
2022-04-12 02:45:34 +00:00
}
2022-04-07 06:51:52 +00:00
2022-04-12 02:45:34 +00:00
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
2023-03-22 08:08:16 +00:00
*numOfRows = 0;
*pData = NULL;
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
2022-04-07 06:51:52 +00:00
return 0;
}
2022-04-15 04:09:27 +00:00
if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
2022-04-20 13:36:55 +00:00
SReqResultInfo *pResultInfo = tmqGetNextResInfo(res, false);
2022-04-14 12:34:42 +00:00
if (pResultInfo == NULL) {
(*numOfRows) = 0;
return 0;
}
2022-04-07 06:51:52 +00:00
2022-04-12 02:45:34 +00:00
pResultInfo->current = pResultInfo->numOfRows;
(*numOfRows) = pResultInfo->numOfRows;
(*pData) = (void *)pResultInfo->pData;
return 0;
}
2022-04-12 02:45:34 +00:00
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;
2022-04-12 02:45:34 +00:00
}
doAsyncFetchRows(pRequest, false, false);
SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
pResultInfo->current = pResultInfo->numOfRows;
(*numOfRows) = pResultInfo->numOfRows;
(*pData) = (void *)pResultInfo->pData;
return 0;
}
2022-04-07 05:57:27 +00:00
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
2022-06-21 05:50:33 +00:00
if (res == NULL || TD_RES_TMQ_META(res)) {
2022-04-07 05:57:27 +00:00
return 0;
}
2022-04-12 02:45:34 +00:00
int32_t numOfFields = taos_num_fields(res);
2022-04-07 05:57:27 +00:00
if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
return 0;
}
2022-04-12 02:45:34 +00:00
SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2022-07-12 12:00:26 +00:00
TAOS_FIELD *pField = &pResInfo->userFields[columnIndex];
2022-04-07 05:57:27 +00:00
if (!IS_VAR_DATA_TYPE(pField->type)) {
return 0;
}
2022-04-12 02:45:34 +00:00
return pResInfo->pCol[columnIndex].offset;
2022-04-07 05:57:27 +00:00
}
int taos_validate_sql(TAOS *taos, const char *sql) {
TAOS_RES *pObj = taosQueryImpl(taos, sql, true);
2022-06-24 00:20:54 +00:00
int code = taos_errno(pObj);
2022-06-24 00:20:54 +00:00
taos_free_result(pObj);
return code;
}
void taos_reset_current_db(TAOS *taos) {
2022-06-21 05:50:33 +00:00
STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
if (pTscObj == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
2022-04-01 11:31:24 +00:00
return;
}
resetConnectDB(pTscObj);
2022-06-21 05:50:33 +00:00
releaseTscObj(*(int64_t *)taos);
}
const char *taos_get_server_info(TAOS *taos) {
2022-06-21 05:50:33 +00:00
STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
if (pTscObj == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
return NULL;
}
2022-06-21 05:50:33 +00:00
releaseTscObj(*(int64_t *)taos);
2022-06-24 07:18:40 +00:00
return pTscObj->sDetailVer;
}
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
if (pTscObj == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
return -1;
}
int code = TSDB_CODE_SUCCESS;
taosThreadMutexLock(&pTscObj->mutex);
2023-04-25 09:39:28 +00:00
if (database == NULL || len <= 0) {
if (required != NULL) *required = strlen(pTscObj->db) + 1;
terrno = TSDB_CODE_INVALID_PARA;
2023-01-12 15:57:06 +00:00
code = -1;
2023-04-25 09:39:28 +00:00
} else if (len < strlen(pTscObj->db) + 1) {
tstrncpy(database, pTscObj->db, len);
2023-04-25 09:39:28 +00:00
if (required) *required = strlen(pTscObj->db) + 1;
terrno = TSDB_CODE_INVALID_PARA;
code = -1;
2023-04-25 09:39:28 +00:00
} else {
strcpy(database, pTscObj->db);
code = 0;
}
taosThreadMutexUnlock(&pTscObj->mutex);
return code;
}
2022-08-08 07:49:31 +00:00
static void destoryTablesReq(void *p) {
STablesReq *pRes = (STablesReq *)p;
taosArrayDestroy(pRes->pTables);
}
static void destoryCatalogReq(SCatalogReq *pCatalogReq) {
if (NULL == pCatalogReq) {
return;
}
taosArrayDestroy(pCatalogReq->pDbVgroup);
taosArrayDestroy(pCatalogReq->pDbCfg);
taosArrayDestroy(pCatalogReq->pDbInfo);
if (pCatalogReq->cloned) {
taosArrayDestroy(pCatalogReq->pTableMeta);
taosArrayDestroy(pCatalogReq->pTableHash);
} else {
taosArrayDestroyEx(pCatalogReq->pTableMeta, destoryTablesReq);
taosArrayDestroyEx(pCatalogReq->pTableHash, destoryTablesReq);
}
taosArrayDestroy(pCatalogReq->pUdf);
taosArrayDestroy(pCatalogReq->pIndex);
taosArrayDestroy(pCatalogReq->pUser);
taosArrayDestroy(pCatalogReq->pTableIndex);
2022-11-14 06:38:51 +00:00
taosArrayDestroy(pCatalogReq->pTableCfg);
2023-04-25 09:39:28 +00:00
taosArrayDestroy(pCatalogReq->pTableTag);
taosMemoryFree(pCatalogReq);
}
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
if (NULL == pWrapper) {
return;
}
destoryCatalogReq(pWrapper->pCatalogReq);
qDestroyParseContext(pWrapper->pParseCtx);
2022-06-11 13:32:29 +00:00
taosMemoryFree(pWrapper);
}
2023-07-05 08:16:25 +00:00
void destroyCtxInRequest(SRequestObj *pRequest) {
schedulerFreeJob(&pRequest->body.queryJob, 0);
qDestroyQuery(pRequest->pQuery);
pRequest->pQuery = NULL;
destorySqlCallbackWrapper(pRequest->pWrapper);
pRequest->pWrapper = NULL;
}
2022-11-04 07:21:38 +00:00
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
SRequestObj *pRequest = pWrapper->pRequest;
SQuery *pQuery = pRequest->pQuery;
qDebug("0x%" PRIx64 " start to semantic analysis, reqId:0x%" PRIx64, pRequest->self, pRequest->requestId);
int64_t analyseStart = taosGetTimestampUs();
pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
2022-08-22 07:58:00 +00:00
if (TSDB_CODE_SUCCESS == code) {
code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
}
2023-07-05 08:16:25 +00:00
pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
2023-07-05 08:16:25 +00:00
handleQueryAnslyseRes(pWrapper, pResultMeta, code);
}
2023-07-05 08:16:25 +00:00
int32_t cloneCatalogReq(SCatalogReq **ppTarget, SCatalogReq *pSrc) {
int32_t code = TSDB_CODE_SUCCESS;
SCatalogReq *pTarget = taosMemoryCalloc(1, sizeof(SCatalogReq));
if (pTarget == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
} else {
pTarget->pDbVgroup = taosArrayDup(pSrc->pDbVgroup, NULL);
pTarget->pDbCfg = taosArrayDup(pSrc->pDbCfg, NULL);
pTarget->pDbInfo = taosArrayDup(pSrc->pDbInfo, NULL);
pTarget->pTableMeta = taosArrayDup(pSrc->pTableMeta, NULL);
pTarget->pTableHash = taosArrayDup(pSrc->pTableHash, NULL);
pTarget->pUdf = taosArrayDup(pSrc->pUdf, NULL);
pTarget->pIndex = taosArrayDup(pSrc->pIndex, NULL);
pTarget->pUser = taosArrayDup(pSrc->pUser, NULL);
pTarget->pTableIndex = taosArrayDup(pSrc->pTableIndex, NULL);
pTarget->pTableCfg = taosArrayDup(pSrc->pTableCfg, NULL);
pTarget->pTableTag = taosArrayDup(pSrc->pTableTag, NULL);
pTarget->qNodeRequired = pSrc->qNodeRequired;
pTarget->dNodeRequired = pSrc->dNodeRequired;
pTarget->svrVerRequired = pSrc->svrVerRequired;
pTarget->forceUpdate = pSrc->forceUpdate;
pTarget->cloned = true;
*ppTarget = pTarget;
}
return code;
}
2023-07-05 08:16:25 +00:00
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode *pRoot) {
SRequestObj *pNewRequest = NULL;
SSqlCallbackWrapper *pNewWrapper = NULL;
int32_t code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
if (code) {
handleQueryAnslyseRes(pWrapper, pResultMeta, code);
return;
}
2023-07-05 08:16:25 +00:00
pNewRequest->pQuery = (SQuery *)nodesMakeNode(QUERY_NODE_QUERY);
if (NULL == pNewRequest->pQuery) {
code = TSDB_CODE_OUT_OF_MEMORY;
} else {
pNewRequest->pQuery->pRoot = pRoot;
pRoot = NULL;
pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
}
if (TSDB_CODE_SUCCESS == code) {
code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
}
if (TSDB_CODE_SUCCESS == code) {
code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
}
doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
nodesDestroyNode(pRoot);
}
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
2023-07-05 08:16:25 +00:00
SRequestObj *pRequest = pWrapper->pRequest;
SQuery *pQuery = pRequest->pQuery;
if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
2023-07-05 08:16:25 +00:00
SNode *prevRoot = pQuery->pPrevRoot;
pQuery->pPrevRoot = NULL;
handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
return;
}
2023-07-05 08:16:25 +00:00
if (code == TSDB_CODE_SUCCESS) {
pRequest->stableQuery = pQuery->stableQuery;
2022-08-01 12:47:08 +00:00
if (pQuery->pRoot) {
2022-08-03 10:49:59 +00:00
pRequest->stmtType = pQuery->pRoot->type;
2022-08-01 12:47:08 +00:00
}
2022-06-06 09:29:43 +00:00
if (pQuery->haveResultSet) {
setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols);
setResPrecision(&pRequest->body.resInfo, pQuery->precision);
}
2022-06-06 09:29:43 +00:00
TSWAP(pRequest->dbList, (pQuery)->pDbList);
TSWAP(pRequest->tableList, (pQuery)->pTableList);
2022-07-27 03:12:31 +00:00
TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
2022-06-06 02:35:19 +00:00
launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
2022-06-06 09:29:43 +00:00
} else {
destorySqlCallbackWrapper(pWrapper);
pRequest->pWrapper = NULL;
2022-09-22 06:03:11 +00:00
qDestroyQuery(pRequest->pQuery);
pRequest->pQuery = NULL;
2022-06-06 09:29:43 +00:00
if (NEED_CLIENT_HANDLE_ERROR(code)) {
2022-06-11 13:32:29 +00:00
tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%" PRIx64,
pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
restartAsyncQuery(pRequest, code);
2022-06-06 09:29:43 +00:00
return;
}
2022-06-06 09:29:43 +00:00
// return to app directly
2022-06-11 13:32:29 +00:00
tscError("0x%" PRIx64 " error occurs, code:%s, return to user app, reqId:0x%" PRIx64, pRequest->self,
tstrerror(code), pRequest->requestId);
2022-06-06 09:29:43 +00:00
pRequest->code = code;
returnToUser(pRequest);
2022-06-06 09:29:43 +00:00
}
}
2022-11-04 07:21:38 +00:00
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
.requestId = pWrapper->pParseCtx->requestId,
.requestObjRefId = pWrapper->pParseCtx->requestRid,
.mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
&pWrapper->pRequest->body.queryJob);
}
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
int32_t code = TSDB_CODE_SUCCESS;
switch (pWrapper->pRequest->pQuery->execStage) {
case QUERY_EXEC_STAGE_PARSE: {
// continue parse after get metadata
code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
break;
}
case QUERY_EXEC_STAGE_ANALYSE: {
// analysis after get metadata
code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
break;
}
case QUERY_EXEC_STAGE_SCHEDULE: {
launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
break;
}
default:
break;
}
return code;
}
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
SRequestObj *pRequest = pWrapper->pRequest;
SQuery *pQuery = pRequest->pQuery;
pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
2022-12-09 01:41:06 +00:00
qDebug("0x%" PRIx64 " start to continue parse, reqId:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
tstrerror(code));
2022-11-04 07:21:38 +00:00
if (code == TSDB_CODE_SUCCESS) {
// pWrapper->pCatalogReq->forceUpdate = false;
2022-11-04 07:21:38 +00:00
code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
}
if (TSDB_CODE_SUCCESS == code) {
code = phaseAsyncQuery(pWrapper);
}
if (TSDB_CODE_SUCCESS != code) {
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pWrapper->pRequest->self, code,
tstrerror(code), pWrapper->pRequest->requestId);
destorySqlCallbackWrapper(pWrapper);
pRequest->pWrapper = NULL;
2022-11-04 07:21:38 +00:00
terrno = code;
2022-11-07 08:48:53 +00:00
pRequest->code = code;
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
2022-11-04 07:21:38 +00:00
}
}
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
if (TSDB_CODE_SUCCESS == code) {
code = phaseAsyncQuery(pWrapper);
}
if (TSDB_CODE_SUCCESS != code) {
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pWrapper->pRequest->self, code,
tstrerror(code), pWrapper->pRequest->requestId);
destorySqlCallbackWrapper(pWrapper);
pRequest->pWrapper = NULL;
2022-11-04 07:21:38 +00:00
terrno = code;
pRequest->code = code;
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
}
}
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
2022-07-12 12:00:26 +00:00
int64_t connId = *(int64_t *)taos;
2023-02-17 09:40:14 +00:00
tscDebug("taos_query_a start with sql:%s", sql);
taosAsyncQueryImpl(connId, sql, fp, param, false);
2023-02-17 09:40:14 +00:00
tscDebug("taos_query_a end with sql:%s", sql);
2022-06-06 09:29:43 +00:00
}
2022-05-11 03:02:58 +00:00
2022-11-03 12:08:30 +00:00
void taos_query_a_with_reqid(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, int64_t reqid) {
int64_t connId = *(int64_t *)taos;
taosAsyncQueryImplWithReqid(connId, sql, fp, param, false, reqid);
}
2022-06-11 13:32:29 +00:00
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt) {
2022-06-06 09:29:43 +00:00
const STscObj *pTscObj = pRequest->pTscObj;
*pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
if (*pCxt == NULL) {
return TSDB_CODE_OUT_OF_MEMORY;
}
2022-07-02 09:00:57 +00:00
**pCxt = (SParseContext){.requestId = pRequest->requestId,
.requestRid = pRequest->self,
.acctId = pTscObj->acctId,
.db = pRequest->pDb,
.topicQuery = false,
.pSql = pRequest->sqlstr,
.sqlLen = pRequest->sqlLen,
.pMsg = pRequest->msgBuf,
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
.pTransporter = pTscObj->pAppInfo->pTransporter,
.pStmtCb = NULL,
.pUser = pTscObj->user,
.isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
2022-08-24 09:36:10 +00:00
.enableSysInfo = pTscObj->sysInfo,
2022-07-02 09:00:57 +00:00
.async = true,
.svrVer = pTscObj->sVer,
.nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
.allocatorId = pRequest->allocatorRefId};
2022-06-06 09:29:43 +00:00
return TSDB_CODE_SUCCESS;
}
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
2023-07-05 08:16:25 +00:00
int32_t code = TSDB_CODE_SUCCESS;
STscObj *pTscObj = pRequest->pTscObj;
SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
if (pWrapper == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
} else {
pWrapper->pRequest = pRequest;
pRequest->pWrapper = pWrapper;
*ppWrapper = pWrapper;
2022-06-06 02:35:19 +00:00
}
if (TSDB_CODE_SUCCESS == code) {
code = createParseContext(pRequest, &pWrapper->pParseCtx);
2022-05-11 03:02:58 +00:00
}
if (TSDB_CODE_SUCCESS == code) {
pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
}
if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
int64_t syntaxStart = taosGetTimestampUs();
pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
if (pWrapper->pCatalogReq == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
} else {
pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
pWrapper->pCatalogReq->qNodeRequired = qnodeRequired(pRequest);
code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
}
pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
2022-08-01 12:47:08 +00:00
}
return code;
}
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
SSqlCallbackWrapper *pWrapper = NULL;
int32_t code = TSDB_CODE_SUCCESS;
if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
code = pRequest->prevCode;
terrno = code;
pRequest->code = code;
tscDebug("call sync query cb with code: %s", tstrerror(code));
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
return;
}
if (TSDB_CODE_SUCCESS == code) {
code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
}
if (TSDB_CODE_SUCCESS == code) {
pRequest->stmtType = pRequest->pQuery->pRoot->type;
2023-04-24 02:14:02 +00:00
code = phaseAsyncQuery(pWrapper);
2023-04-25 09:39:28 +00:00
}
2023-04-24 02:14:02 +00:00
if (TSDB_CODE_SUCCESS != code) {
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code, tstrerror(code),
pRequest->requestId);
destorySqlCallbackWrapper(pWrapper);
pRequest->pWrapper = NULL;
2022-12-09 02:06:07 +00:00
qDestroyQuery(pRequest->pQuery);
pRequest->pQuery = NULL;
if (NEED_CLIENT_HANDLE_ERROR(code)) {
tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%" PRIx64,
pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
refreshMeta(pRequest->pTscObj, pRequest);
pRequest->prevCode = code;
doAsyncQuery(pRequest, true);
return;
}
terrno = code;
pRequest->code = code;
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
}
}
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
2023-07-05 08:16:25 +00:00
int32_t reqIdx = 0;
SRequestObj *pReqList[16] = {NULL};
SRequestObj *pUserReq = NULL;
pReqList[0] = pRequest;
2023-07-05 08:16:25 +00:00
uint64_t tmpRefId = 0;
SRequestObj *pTmp = pRequest;
while (pTmp->relation.prevRefId) {
tmpRefId = pTmp->relation.prevRefId;
pTmp = acquireRequest(tmpRefId);
if (pTmp) {
pReqList[++reqIdx] = pTmp;
releaseRequest(tmpRefId);
} else {
2023-07-05 08:16:25 +00:00
tscError("0x%" PRIx64 ", prev req ref 0x%" PRIx64 " is not there, reqId:0x%" PRIx64, pTmp->self, tmpRefId,
pTmp->requestId);
break;
}
}
tmpRefId = pRequest->relation.nextRefId;
while (tmpRefId) {
pTmp = acquireRequest(tmpRefId);
if (pTmp) {
tmpRefId = pTmp->relation.nextRefId;
2023-07-05 08:16:25 +00:00
removeRequest(pTmp->self);
releaseRequest(pTmp->self);
} else {
tscError("0x%" PRIx64 " is not there", tmpRefId);
2023-07-05 08:16:25 +00:00
break;
}
}
for (int32_t i = reqIdx; i >= 0; i--) {
destroyCtxInRequest(pReqList[i]);
if (pReqList[i]->relation.userRefId == pReqList[i]->self || 0 == pReqList[i]->relation.userRefId) {
pUserReq = pReqList[i];
} else {
removeRequest(pReqList[i]->self);
}
}
if (pUserReq) {
pUserReq->prevCode = code;
memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
2022-06-06 02:35:19 +00:00
} else {
tscError("user req is missing");
return;
}
doAsyncQuery(pUserReq, true);
}
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
2023-04-25 09:39:28 +00:00
if (ASSERT(res != NULL && fp != NULL)) {
tscError("taos_fetch_rows_a invalid paras");
return;
}
2023-04-25 09:39:28 +00:00
if (ASSERT(TD_RES_QUERY(res))) {
tscError("taos_fetch_rows_a res is NULL");
return;
}
SRequestObj *pRequest = res;
taosAsyncFetchImpl(pRequest, fp, param);
2022-01-27 10:40:36 +00:00
}
2022-06-11 13:32:29 +00:00
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
2023-04-25 09:39:28 +00:00
if (ASSERT(res != NULL && fp != NULL)) {
tscError("taos_fetch_rows_a invalid paras");
return;
}
2023-04-25 09:39:28 +00:00
if (ASSERT(TD_RES_QUERY(res))) {
tscError("taos_fetch_rows_a res is NULL");
return;
}
2022-07-12 12:00:26 +00:00
SRequestObj *pRequest = res;
SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
// set the current block is all consumed
pResultInfo->convertUcs4 = false;
// it is a local executed query, no need to do async fetch
taos_fetch_rows_a(pRequest, fp, param);
}
2022-06-11 13:32:29 +00:00
const void *taos_get_raw_block(TAOS_RES *res) {
2023-04-25 09:39:28 +00:00
if (ASSERT(res != NULL)) {
tscError("taos_fetch_rows_a invalid paras");
return NULL;
}
2023-04-25 09:39:28 +00:00
if (ASSERT(TD_RES_QUERY(res))) {
tscError("taos_fetch_rows_a res is NULL");
return NULL;
}
2022-06-11 13:32:29 +00:00
SRequestObj *pRequest = res;
2022-06-10 01:48:56 +00:00
return pRequest->body.resInfo.pData;
}
2022-10-24 08:58:45 +00:00
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
if (NULL == taos) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
return terrno;
}
if (NULL == db || NULL == dbInfo) {
tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
terrno = TSDB_CODE_TSC_INVALID_INPUT;
return terrno;
}
2022-10-24 08:58:45 +00:00
int64_t connId = *(int64_t *)taos;
SRequestObj *pRequest = NULL;
char *sql = "taos_get_db_route_info";
2022-11-03 12:08:30 +00:00
int32_t code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
if (code != TSDB_CODE_SUCCESS) {
terrno = code;
return terrno;
}
2022-10-24 08:58:45 +00:00
STscObj *pTscObj = pRequest->pTscObj;
SCatalog *pCtg = NULL;
code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
if (code != TSDB_CODE_SUCCESS) {
goto _return;
}
SRequestConnInfo conn = {
.pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
char dbFName[TSDB_DB_FNAME_LEN] = {0};
snprintf(dbFName, sizeof(dbFName), "%d.%s", pTscObj->acctId, db);
2022-10-24 08:58:45 +00:00
code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
if (code) {
goto _return;
}
_return:
terrno = code;
destroyRequest(pRequest);
return code;
}
2022-10-24 08:58:45 +00:00
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
if (NULL == taos) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
return terrno;
}
if (NULL == db || NULL == table || NULL == vgId) {
tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
terrno = TSDB_CODE_TSC_INVALID_INPUT;
return terrno;
}
2022-10-24 08:58:45 +00:00
int64_t connId = *(int64_t *)taos;
SRequestObj *pRequest = NULL;
char *sql = "taos_get_table_vgId";
2022-11-03 12:08:30 +00:00
int32_t code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
if (code != TSDB_CODE_SUCCESS) {
return terrno;
}
pRequest->syncQuery = true;
2022-10-24 08:58:45 +00:00
STscObj *pTscObj = pRequest->pTscObj;
SCatalog *pCtg = NULL;
code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
if (code != TSDB_CODE_SUCCESS) {
goto _return;
}
SRequestConnInfo conn = {
.pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
SName tableName;
toName(pTscObj->acctId, db, table, &tableName);
SVgroupInfo vgInfo;
code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
if (code) {
goto _return;
}
*vgId = vgInfo.vgId;
_return:
terrno = code;
destroyRequest(pRequest);
return code;
}
2023-01-04 06:01:43 +00:00
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
if (NULL == taos) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
return terrno;
}
if (NULL == db || NULL == table || NULL == vgId || tableNum <= 0) {
tscError("invalid input param, db:%p, table:%p, vgId:%p, tbNum:%d", db, table, vgId, tableNum);
terrno = TSDB_CODE_TSC_INVALID_INPUT;
return terrno;
}
int64_t connId = *(int64_t *)taos;
SRequestObj *pRequest = NULL;
char *sql = "taos_get_table_vgId";
int32_t code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
if (code != TSDB_CODE_SUCCESS) {
return terrno;
}
pRequest->syncQuery = true;
STscObj *pTscObj = pRequest->pTscObj;
SCatalog *pCtg = NULL;
code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
if (code != TSDB_CODE_SUCCESS) {
goto _return;
}
SRequestConnInfo conn = {
.pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
if (code) {
goto _return;
}
_return:
terrno = code;
destroyRequest(pRequest);
return code;
}
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
2022-06-27 01:50:42 +00:00
if (NULL == taos) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
return terrno;
}
int64_t connId = *(int64_t *)taos;
2022-06-24 00:20:54 +00:00
const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024; // 12MB list
int32_t code = 0;
2022-07-12 12:00:26 +00:00
SRequestObj *pRequest = NULL;
SCatalogReq catalogReq = {0};
2022-06-24 00:20:54 +00:00
if (NULL == tableNameList) {
return TSDB_CODE_SUCCESS;
}
int32_t length = (int32_t)strlen(tableNameList);
if (0 == length) {
return TSDB_CODE_SUCCESS;
} else if (length > MAX_TABLE_NAME_LENGTH) {
tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
return TSDB_CODE_TSC_INVALID_OPERATION;
}
char *sql = "taos_load_table_info";
2022-11-03 12:08:30 +00:00
code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
if (code != TSDB_CODE_SUCCESS) {
terrno = code;
goto _return;
2022-06-24 00:20:54 +00:00
}
2023-05-08 07:47:10 +00:00
pRequest->syncQuery = true;
2022-07-12 12:00:26 +00:00
STscObj *pTscObj = pRequest->pTscObj;
2022-06-24 00:20:54 +00:00
code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta);
if (code) {
goto _return;
}
SCatalog *pCtg = NULL;
2022-06-24 00:20:54 +00:00
code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
if (code != TSDB_CODE_SUCCESS) {
goto _return;
}
SRequestConnInfo conn = {
.pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
2022-06-24 00:20:54 +00:00
conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
2022-07-26 01:48:43 +00:00
code = catalogAsyncGetAllMeta(pCtg, &conn, &catalogReq, syncCatalogFn, pRequest->body.param, NULL);
2022-06-24 00:20:54 +00:00
if (code) {
goto _return;
}
2022-07-12 12:00:26 +00:00
SSyncQueryParam *pParam = pRequest->body.param;
tsem_wait(&pParam->sem);
2022-06-24 00:20:54 +00:00
_return:
2023-05-08 06:22:41 +00:00
taosArrayDestroyEx(catalogReq.pTableMeta, destoryTablesReq);
2022-06-24 00:20:54 +00:00
destroyRequest(pRequest);
return code;
}
2022-03-29 07:24:25 +00:00
TAOS_STMT *taos_stmt_init(TAOS *taos) {
2022-06-21 05:50:33 +00:00
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
if (NULL == pObj) {
tscError("invalid parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_TSC_DISCONNECTED;
2022-04-13 09:52:26 +00:00
return NULL;
}
2022-11-03 12:08:30 +00:00
TAOS_STMT *pStmt = stmtInit(pObj, 0);
releaseTscObj(*(int64_t *)taos);
return pStmt;
}
TAOS_STMT *taos_stmt_init_with_reqid(TAOS *taos, int64_t reqid) {
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
if (NULL == pObj) {
tscError("invalid parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_TSC_DISCONNECTED;
return NULL;
}
TAOS_STMT *pStmt = stmtInit(pObj, reqid);
2022-06-21 05:50:33 +00:00
releaseTscObj(*(int64_t *)taos);
return pStmt;
}
2022-04-14 12:14:52 +00:00
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
if (stmt == NULL || sql == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-14 12:14:52 +00:00
return stmtPrepare(stmt, sql, length);
}
2022-04-25 12:03:28 +00:00
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
2022-04-15 12:10:51 +00:00
if (stmt == NULL || name == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-15 12:10:51 +00:00
int32_t code = stmtSetTbName(stmt, name);
if (code) {
return code;
}
if (tags) {
return stmtSetTbTags(stmt, tags);
}
return TSDB_CODE_SUCCESS;
}
2022-04-14 12:14:52 +00:00
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
if (stmt == NULL || name == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
2022-04-14 12:14:52 +00:00
return terrno;
2022-04-13 09:52:26 +00:00
}
2022-04-15 12:10:51 +00:00
return stmtSetTbName(stmt, name);
}
2022-05-31 13:03:47 +00:00
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);
}
int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name) { return taos_stmt_set_tbname(stmt, name); }
2022-04-21 07:33:07 +00:00
2022-06-11 13:32:29 +00:00
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
2022-05-31 13:03:47 +00:00
if (stmt == NULL || NULL == fieldNum) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-06-11 13:32:29 +00:00
2022-05-31 13:03:47 +00:00
return stmtGetTagFields(stmt, fieldNum, fields);
}
2022-06-11 13:32:29 +00:00
int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
2022-05-31 13:03:47 +00:00
if (stmt == NULL || NULL == fieldNum) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-06-11 13:32:29 +00:00
2022-05-31 13:03:47 +00:00
return stmtGetColFields(stmt, fieldNum, fields);
}
// let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields`
void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields) {
(void)stmt;
if (!fields) return;
taosMemoryFree(fields);
}
2022-04-25 12:03:28 +00:00
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
2022-04-14 12:14:52 +00:00
if (stmt == NULL || bind == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
2022-04-14 12:14:52 +00:00
return terrno;
2022-04-13 09:52:26 +00:00
}
2022-04-18 02:19:15 +00:00
if (bind->num > 1) {
tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-18 11:12:10 +00:00
return stmtBindBatch(stmt, bind, -1);
}
2022-04-25 12:03:28 +00:00
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
2022-04-13 09:52:26 +00:00
if (stmt == NULL || bind == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-14 12:14:52 +00:00
if (bind->num <= 0 || bind->num > INT16_MAX) {
tscError("invalid bind num %d", bind->num);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-25 12:03:28 +00:00
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;
}
2022-04-18 11:12:10 +00:00
return stmtBindBatch(stmt, bind, -1);
}
2022-04-25 12:03:28 +00:00
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
2022-04-18 11:12:10 +00:00
if (stmt == NULL || bind == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-20 10:27:00 +00:00
if (colIdx < 0) {
2022-04-18 11:12:10 +00:00
tscError("invalid bind column idx %d", colIdx);
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-25 12:03:28 +00:00
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;
}
2022-04-20 10:27:00 +00:00
return stmtBindBatch(stmt, bind, colIdx);
}
2022-04-14 12:14:52 +00:00
int taos_stmt_add_batch(TAOS_STMT *stmt) {
if (stmt == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-14 12:14:52 +00:00
return stmtAddBatch(stmt);
}
2022-04-14 12:14:52 +00:00
int taos_stmt_execute(TAOS_STMT *stmt) {
if (stmt == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-14 12:14:52 +00:00
return stmtExec(stmt);
}
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
2022-04-13 09:52:26 +00:00
if (stmt == NULL || insert == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
return stmtIsInsert(stmt, insert);
}
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
2022-04-13 09:52:26 +00:00
if (stmt == NULL || nums == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
return stmtGetParamNum(stmt, nums);
}
2022-05-31 13:03:47 +00:00
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);
}
2022-04-14 12:14:52 +00:00
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
2022-04-13 09:52:26 +00:00
if (stmt == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
2022-04-14 12:14:52 +00:00
return NULL;
2022-04-13 09:52:26 +00:00
}
2022-04-14 12:14:52 +00:00
return stmtUseResult(stmt);
}
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
2022-04-14 12:14:52 +00:00
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
2022-04-13 09:52:26 +00:00
if (stmt == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
2022-04-14 12:14:52 +00:00
return 0;
2022-04-13 09:52:26 +00:00
}
2022-04-14 12:14:52 +00:00
return stmtAffectedRows(stmt);
}
2022-04-25 12:03:28 +00:00
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);
}
2022-04-14 12:14:52 +00:00
int taos_stmt_close(TAOS_STMT *stmt) {
if (stmt == NULL) {
2022-04-13 11:57:21 +00:00
tscError("NULL parameter for %s", __FUNCTION__);
2022-04-13 09:52:26 +00:00
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
2022-04-14 12:14:52 +00:00
return stmtClose(stmt);
2022-04-13 09:52:26 +00:00
}