Merge pull request #9134 from taosdata/feature/3.0_liaohj
Feature/3.0 liaohj
This commit is contained in:
commit
a1bfc9ff9e
|
@ -0,0 +1,9 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.209.3/containers/cpp/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Debian / Ubuntu version (use Debian 11/9, Ubuntu 18.04/21.04 on local arm64/Apple Silicon): debian-11, debian-10, debian-9, ubuntu-21.04, ubuntu-20.04, ubuntu-18.04
|
||||
ARG VARIANT="bullseye"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT}
|
||||
|
||||
# [Optional] Uncomment this section to install additional packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
|
@ -0,0 +1,32 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.209.3/containers/cpp
|
||||
{
|
||||
"name": "C++",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
// Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-11, debian-10, debian-9, ubuntu-21.04, ubuntu-20.04, ubuntu-18.04
|
||||
// Use Debian 11, Debian 9, Ubuntu 18.04 or Ubuntu 21.04 on local arm64/Apple Silicon
|
||||
"args": { "VARIANT": "ubuntu-21.04" }
|
||||
},
|
||||
"runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools",
|
||||
"ms-vscode.cmake-tools",
|
||||
"austin.code-gnu-global",
|
||||
"visualstudioexptteam.vscodeintel"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "gcc -v",
|
||||
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode"
|
||||
}
|
|
@ -39,7 +39,7 @@ typedef void **TAOS_ROW;
|
|||
#define TSDB_DATA_TYPE_BIGINT 5 // 8 bytes
|
||||
#define TSDB_DATA_TYPE_FLOAT 6 // 4 bytes
|
||||
#define TSDB_DATA_TYPE_DOUBLE 7 // 8 bytes
|
||||
#define TSDB_DATA_TYPE_BINARY 8 // string
|
||||
#define TSDB_DATA_TYPE_BINARY 8 // string, alias for varchar
|
||||
#define TSDB_DATA_TYPE_TIMESTAMP 9 // 8 bytes
|
||||
#define TSDB_DATA_TYPE_NCHAR 10 // unicode string
|
||||
#define TSDB_DATA_TYPE_UTINYINT 11 // 1 byte
|
||||
|
@ -47,10 +47,10 @@ typedef void **TAOS_ROW;
|
|||
#define TSDB_DATA_TYPE_UINT 13 // 4 bytes
|
||||
#define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes
|
||||
#define TSDB_DATA_TYPE_VARCHAR 15 // string
|
||||
#define TSDB_DATA_TYPE_JSON 16 // json
|
||||
#define TSDB_DATA_TYPE_DECIMAL 17 // decimal
|
||||
#define TSDB_DATA_TYPE_BLOB 18 // binary string
|
||||
#define TSDB_DATA_TYPE_LONGBLOB 19 // long binary string
|
||||
#define TSDB_DATA_TYPE_VARBINARY 16 // binary
|
||||
#define TSDB_DATA_TYPE_JSON 17 // json
|
||||
#define TSDB_DATA_TYPE_DECIMAL 18 // decimal
|
||||
#define TSDB_DATA_TYPE_BLOB 19 // binary
|
||||
|
||||
typedef enum {
|
||||
TSDB_OPTION_LOCALE,
|
||||
|
@ -61,6 +61,23 @@ typedef enum {
|
|||
TSDB_MAX_OPTIONS
|
||||
} TSDB_OPTION;
|
||||
|
||||
typedef enum {
|
||||
TSDB_SML_UNKNOWN_PROTOCOL = 0,
|
||||
TSDB_SML_LINE_PROTOCOL = 1,
|
||||
TSDB_SML_TELNET_PROTOCOL = 2,
|
||||
TSDB_SML_JSON_PROTOCOL = 3,
|
||||
} TSDB_SML_PROTOCOL_TYPE;
|
||||
|
||||
typedef enum {
|
||||
TSDB_SML_TIMESTAMP_NOT_CONFIGURED = 0,
|
||||
TSDB_SML_TIMESTAMP_HOURS,
|
||||
TSDB_SML_TIMESTAMP_MINUTES,
|
||||
TSDB_SML_TIMESTAMP_SECONDS,
|
||||
TSDB_SML_TIMESTAMP_MILLI_SECONDS,
|
||||
TSDB_SML_TIMESTAMP_MICRO_SECONDS,
|
||||
TSDB_SML_TIMESTAMP_NANO_SECONDS,
|
||||
} TSDB_SML_TIMESTAMP_TYPE;
|
||||
|
||||
typedef struct taosField {
|
||||
char name[65];
|
||||
uint8_t type;
|
||||
|
@ -136,37 +153,36 @@ DLL_EXPORT int taos_stmt_close(TAOS_STMT *stmt);
|
|||
DLL_EXPORT char * taos_stmt_errstr(TAOS_STMT *stmt);
|
||||
|
||||
DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql);
|
||||
DLL_EXPORT TAOS_RES *taos_query_l(TAOS *taos, const char *sql, size_t sqlLen);
|
||||
|
||||
DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_result_precision(TAOS_RES *res); // get the time precision of result
|
||||
DLL_EXPORT int taos_result_precision(TAOS_RES *res); // get the time precision of result
|
||||
DLL_EXPORT void taos_free_result(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_field_count(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_num_fields(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_affected_rows(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_field_count(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_num_fields(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_affected_rows(TAOS_RES *res);
|
||||
|
||||
DLL_EXPORT TAOS_FIELD *taos_fetch_fields(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_select_db(TAOS *taos, const char *db);
|
||||
DLL_EXPORT int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields);
|
||||
DLL_EXPORT int taos_select_db(TAOS *taos, const char *db);
|
||||
DLL_EXPORT int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields);
|
||||
DLL_EXPORT void taos_stop_query(TAOS_RES *res);
|
||||
DLL_EXPORT bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col);
|
||||
DLL_EXPORT int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows);
|
||||
DLL_EXPORT int taos_validate_sql(TAOS *taos, const char *sql);
|
||||
DLL_EXPORT int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows);
|
||||
DLL_EXPORT int taos_validate_sql(TAOS *taos, const char *sql);
|
||||
|
||||
DLL_EXPORT int* taos_fetch_lengths(TAOS_RES *res);
|
||||
|
||||
// TAOS_RES *taos_list_tables(TAOS *mysql, const char *wild);
|
||||
// TAOS_RES *taos_list_dbs(TAOS *mysql, const char *wild);
|
||||
|
||||
// TODO: the return value should be `const`
|
||||
DLL_EXPORT const char *taos_get_server_info(TAOS *taos);
|
||||
DLL_EXPORT const char *taos_get_client_info();
|
||||
DLL_EXPORT const char *taos_errstr(TAOS_RES *tres);
|
||||
|
||||
DLL_EXPORT int taos_errno(TAOS_RES *tres);
|
||||
DLL_EXPORT const char *taos_errstr(TAOS_RES *tres);
|
||||
DLL_EXPORT int taos_errno(TAOS_RES *tres);
|
||||
|
||||
DLL_EXPORT void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param);
|
||||
DLL_EXPORT void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param);
|
||||
|
||||
typedef void (*TAOS_SUBSCRIBE_CALLBACK)(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code);
|
||||
DLL_EXPORT TAOS_SUB *taos_subscribe(TAOS* taos, int restart, const char* topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp, void *param, int interval);
|
||||
typedef void (*__taos_sub_fn_t)(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code);
|
||||
DLL_EXPORT TAOS_SUB *taos_subscribe(TAOS* taos, int restart, const char* topic, const char *sql, __taos_sub_fn_t fp, void *param, int interval);
|
||||
DLL_EXPORT TAOS_RES *taos_consume(TAOS_SUB *tsub);
|
||||
DLL_EXPORT void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress);
|
||||
|
||||
|
@ -175,8 +191,7 @@ DLL_EXPORT TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sql, void (*fp)
|
|||
DLL_EXPORT void taos_close_stream(TAOS_STREAM *tstr);
|
||||
|
||||
DLL_EXPORT int taos_load_table_info(TAOS *taos, const char* tableNameList);
|
||||
|
||||
DLL_EXPORT int taos_insert_lines(TAOS* taos, char* lines[], int numLines);
|
||||
DLL_EXPORT TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int protocol, int precision);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -406,8 +406,10 @@ typedef struct {
|
|||
} SDropUserMsg, SDropAcctMsg;
|
||||
|
||||
typedef struct {
|
||||
int8_t type;
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
int8_t superUser; // denote if it is a super user or not
|
||||
int32_t reserve[8];
|
||||
} SCreateUserMsg, SAlterUserMsg;
|
||||
|
||||
|
@ -831,7 +833,7 @@ typedef struct {
|
|||
} SVgroupsMsg, SVgroupsInfo;
|
||||
|
||||
typedef struct {
|
||||
char tbFname[TSDB_TABLE_FNAME_LEN]; // table id
|
||||
char tbFname[TSDB_TABLE_FNAME_LEN]; // table full name
|
||||
char stbFname[TSDB_TABLE_FNAME_LEN];
|
||||
int32_t numOfTags;
|
||||
int32_t numOfColumns;
|
||||
|
@ -866,7 +868,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
char db[TSDB_FULL_DB_NAME_LEN];
|
||||
int32_t vgVersion;
|
||||
int32_t vgNum;
|
||||
int32_t vgNum;
|
||||
int8_t hashMethod;
|
||||
SVgroupInfo vgroupInfo[];
|
||||
} SUseDbRsp;
|
||||
|
|
|
@ -153,7 +153,7 @@ typedef struct SParseContext {
|
|||
* @param msg extended error message if exists.
|
||||
* @return error code
|
||||
*/
|
||||
int32_t qParseQuerySql(const char* pStr, size_t length, struct SQueryStmtInfo** pQueryInfo, int64_t id, char* msg, int32_t msgLen);
|
||||
int32_t qParseQuerySql(const char* pStr, size_t length, int64_t id, int32_t* type, void** pOutput, int32_t* outputLen, char* msg, int32_t msgLen);
|
||||
|
||||
typedef enum {
|
||||
PAYLOAD_TYPE_KV = 0,
|
||||
|
|
|
@ -196,6 +196,7 @@ do { \
|
|||
|
||||
#define TSDB_AUTH_LEN 16
|
||||
#define TSDB_PASSWORD_LEN 32
|
||||
#define TSDB_USET_PASSWORD_LEN 129
|
||||
#define TSDB_VERSION_LEN 12
|
||||
#define TSDB_LABEL_LEN 8
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ target_link_libraries(
|
|||
taos
|
||||
PRIVATE common
|
||||
INTERFACE api
|
||||
PRIVATE os util common transport parser
|
||||
PRIVATE os util common transport parser catalog function
|
||||
)
|
||||
|
||||
ADD_SUBDIRECTORY(test)
|
|
@ -20,14 +20,15 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <common.h>
|
||||
#include "taos.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tdef.h"
|
||||
#include "tep.h"
|
||||
#include "thash.h"
|
||||
#include "tlist.h"
|
||||
#include "trpc.h"
|
||||
#include "tdef.h"
|
||||
#include "tmsgtype.h"
|
||||
#include "tep.h"
|
||||
#include "trpc.h"
|
||||
|
||||
typedef struct SQueryExecMetric {
|
||||
int64_t start; // start timestamp
|
||||
|
@ -86,12 +87,22 @@ typedef struct STscObj {
|
|||
SAppInstInfo *pAppInfo;
|
||||
} STscObj;
|
||||
|
||||
typedef struct SClientResultInfo {
|
||||
SSDataBlock *pData;
|
||||
TAOS_FIELD *resultFields;
|
||||
int32_t current;
|
||||
} SClientResultInfo;
|
||||
|
||||
typedef struct SReqBody {
|
||||
tsem_t rspSem; // not used now
|
||||
void* fp;
|
||||
void* param;
|
||||
int32_t paramLen;
|
||||
SClientResultInfo* pResInfo;
|
||||
} SRequestBody;
|
||||
|
||||
#define ERROR_MSG_BUF_DEFAULT_SIZE 512
|
||||
|
||||
typedef struct SRequestObj {
|
||||
uint64_t requestId;
|
||||
int32_t type; // request type
|
||||
|
@ -118,7 +129,7 @@ extern int32_t tscReqRef;
|
|||
extern void *tscQhandle;
|
||||
extern int32_t tscConnRef;
|
||||
|
||||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SRequestObj *pRequest, SRequestMsgBody *pMsg);
|
||||
extern int (*buildRequestMsgFp[TSDB_SQL_MAX])(SRequestObj *pRequest, SRequestMsgBody *pMsgBody);
|
||||
extern int (*handleRequestRspFp[TSDB_SQL_MAX])(SRequestObj *pRequest, const char* pMsg, int32_t msgLen);
|
||||
|
||||
int taos_init();
|
||||
|
@ -129,8 +140,6 @@ void destroyTscObj(void*pObj);
|
|||
void* createRequest(STscObj* pObj, __taos_async_fn_t fp, void* param, int32_t type);
|
||||
void destroyRequest(SRequestObj* pRequest);
|
||||
|
||||
TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, const char *auth, const char *db, uint16_t port);
|
||||
|
||||
void taos_init_imp(void);
|
||||
int taos_options_imp(TSDB_OPTION option, const char *str);
|
||||
|
||||
|
@ -139,6 +148,11 @@ void* openTransporter(const char *user, const char *auth);
|
|||
void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet);
|
||||
void initMsgHandleFp();
|
||||
|
||||
TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, const char *auth, const char *db, uint16_t port);
|
||||
TAOS_RES *taos_query_l(TAOS *taos, const char *sql, size_t sqlLen);
|
||||
|
||||
void* doFetchRow(SRequestObj* pRequest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_TSCLOG_H
|
||||
#define TDENGINE_TSCLOG_H
|
||||
#ifndef TDENGINE_CLIENTLOG_H
|
||||
#define TDENGINE_CLIENTLOG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* 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 "os.h"
|
||||
#include "tdef.h"
|
||||
#include "tglobal.h"
|
||||
#include "clientInt.h"
|
||||
#include "tscLog.h"
|
||||
|
||||
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
|
||||
int32_t p = (port != 0)? port:tsServerPort;
|
||||
|
||||
tscDebug("try to connect to %s:%u, user:%s db:%s", ip, p, user, db);
|
||||
if (user == NULL) {
|
||||
user = TSDB_DEFAULT_USER;
|
||||
}
|
||||
|
||||
if (pass == NULL) {
|
||||
pass = TSDB_DEFAULT_PASS;
|
||||
}
|
||||
|
||||
return taos_connect_internal(ip, user, pass, NULL, db, p);
|
||||
}
|
||||
|
||||
TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port) {
|
||||
tscDebug("try to connect to %s:%u by auth, user:%s db:%s", ip, port, user, db);
|
||||
if (user == NULL) {
|
||||
user = TSDB_DEFAULT_USER;
|
||||
}
|
||||
|
||||
if (auth == NULL) {
|
||||
tscError("No auth info is given, failed to connect to server");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return taos_connect_internal(ip, user, NULL, auth, db, port);
|
||||
}
|
||||
|
||||
TAOS *taos_connect_l(const char *ip, int ipLen, const char *user, int userLen, const char *pass, int passLen, const char *db, int dbLen, uint16_t port) {
|
||||
char ipStr[TSDB_EP_LEN] = {0};
|
||||
char dbStr[TSDB_DB_NAME_LEN] = {0};
|
||||
char userStr[TSDB_USER_LEN] = {0};
|
||||
char passStr[TSDB_PASSWORD_LEN] = {0};
|
||||
|
||||
strncpy(ipStr, ip, MIN(TSDB_EP_LEN - 1, ipLen));
|
||||
strncpy(userStr, user, MIN(TSDB_USER_LEN - 1, userLen));
|
||||
strncpy(passStr, pass, MIN(TSDB_PASSWORD_LEN - 1, passLen));
|
||||
strncpy(dbStr, db, MIN(TSDB_DB_NAME_LEN - 1, dbLen));
|
||||
return taos_connect(ipStr, userStr, passStr, dbStr, port);
|
||||
}
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
#include <tpagedfile.h>
|
||||
|
||||
#include "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "tdef.h"
|
||||
#include "tep.h"
|
||||
#include "tglobal.h"
|
||||
#include "tmsgtype.h"
|
||||
#include "tnote.h"
|
||||
#include "tpagedfile.h"
|
||||
#include "tref.h"
|
||||
#include "tscLog.h"
|
||||
#include "parser.h"
|
||||
|
||||
static int32_t initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSet);
|
||||
static int32_t buildConnectMsg(SRequestObj *pRequest, SRequestMsgBody* pMsgBody);
|
||||
|
@ -109,6 +112,71 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass,
|
|||
return taosConnectImpl(ip, user, &secretEncrypt[0], db, port, NULL, NULL, pInst);
|
||||
}
|
||||
|
||||
TAOS_RES *taos_query_l(TAOS *taos, const char *sql, size_t sqlLen) {
|
||||
STscObj *pTscObj = (STscObj *)taos;
|
||||
if (sqlLen > (size_t) tsMaxSQLStringLen) {
|
||||
tscError("sql string exceeds max length:%d", tsMaxSQLStringLen);
|
||||
terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nPrintTsc("%s", sql)
|
||||
|
||||
SRequestObj* pRequest = createRequest(pTscObj, NULL, NULL, TSDB_SQL_SELECT);
|
||||
if (pRequest == NULL) {
|
||||
tscError("failed to malloc sqlObj");
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pRequest->sqlstr = malloc(sqlLen + 1);
|
||||
if (pRequest->sqlstr == NULL) {
|
||||
tscError("0x%"PRIx64" failed to prepare sql string buffer", pRequest->self);
|
||||
|
||||
pRequest->msgBuf = strdup("failed to prepare sql string buffer");
|
||||
terrno = pRequest->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pRequest;
|
||||
}
|
||||
|
||||
strntolower(pRequest->sqlstr, sql, (int32_t)sqlLen);
|
||||
pRequest->sqlstr[sqlLen] = 0;
|
||||
|
||||
tscDebugL("0x%"PRIx64" SQL: %s", pRequest->requestId, pRequest->sqlstr);
|
||||
|
||||
int32_t code = 0;
|
||||
if (qIsInsertSql(pRequest->sqlstr, sqlLen)) {
|
||||
// todo add
|
||||
} else {
|
||||
int32_t type = 0;
|
||||
void* output = NULL;
|
||||
int32_t outputLen = 0;
|
||||
code = qParseQuerySql(pRequest->sqlstr, sqlLen, pRequest->requestId, &type, &output, &outputLen, pRequest->msgBuf, ERROR_MSG_BUF_DEFAULT_SIZE);
|
||||
if (type == TSDB_SQL_CREATE_USER || type == TSDB_SQL_SHOW) {
|
||||
pRequest->type = type;
|
||||
pRequest->body.param = output;
|
||||
pRequest->body.paramLen = outputLen;
|
||||
|
||||
SRequestMsgBody body = {0};
|
||||
buildRequestMsgFp[type](pRequest, &body);
|
||||
|
||||
int64_t transporterId = 0;
|
||||
sendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &body, &transporterId);
|
||||
|
||||
tsem_wait(&pRequest->body.rspSem);
|
||||
destroyConnectMsg(&body);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pRequest->code = code;
|
||||
return pRequest;
|
||||
}
|
||||
|
||||
return pRequest;
|
||||
}
|
||||
|
||||
int initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSet) {
|
||||
pEpSet->version = 0;
|
||||
|
||||
|
@ -272,8 +340,8 @@ void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
|
|||
pMsg->code = (*handleRequestRspFp[pRequest->type])(pRequest, pMsg->pCont, pMsg->contLen);
|
||||
}
|
||||
} else {
|
||||
tscError("0x%" PRIx64 " SQL cmd:%s, code:%s rspLen:%d", pRequest->requestId, taosMsg[pMsg->msgType],
|
||||
tstrerror(pMsg->code), pMsg->contLen);
|
||||
tscError("0x%" PRIx64 " SQL cmd:%s, code:%s rspLen:%d, elapsed time:%"PRId64" ms", pRequest->requestId, taosMsg[pMsg->msgType],
|
||||
tstrerror(pMsg->code), pMsg->contLen, pRequest->metric.rsp - pRequest->metric.start);
|
||||
}
|
||||
|
||||
taosReleaseRef(tscReqRef, requestRefId);
|
||||
|
@ -281,3 +349,47 @@ void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
|
|||
|
||||
sem_post(&pRequest->body.rspSem);
|
||||
}
|
||||
|
||||
TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port) {
|
||||
tscDebug("try to connect to %s:%u by auth, user:%s db:%s", ip, port, user, db);
|
||||
if (user == NULL) {
|
||||
user = TSDB_DEFAULT_USER;
|
||||
}
|
||||
|
||||
if (auth == NULL) {
|
||||
tscError("No auth info is given, failed to connect to server");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return taos_connect_internal(ip, user, NULL, auth, db, port);
|
||||
}
|
||||
|
||||
TAOS *taos_connect_l(const char *ip, int ipLen, const char *user, int userLen, const char *pass, int passLen, const char *db, int dbLen, uint16_t port) {
|
||||
char ipStr[TSDB_EP_LEN] = {0};
|
||||
char dbStr[TSDB_DB_NAME_LEN] = {0};
|
||||
char userStr[TSDB_USER_LEN] = {0};
|
||||
char passStr[TSDB_PASSWORD_LEN] = {0};
|
||||
|
||||
strncpy(ipStr, ip, MIN(TSDB_EP_LEN - 1, ipLen));
|
||||
strncpy(userStr, user, MIN(TSDB_USER_LEN - 1, userLen));
|
||||
strncpy(passStr, pass, MIN(TSDB_PASSWORD_LEN - 1, passLen));
|
||||
strncpy(dbStr, db, MIN(TSDB_DB_NAME_LEN - 1, dbLen));
|
||||
return taos_connect(ipStr, userStr, passStr, dbStr, port);
|
||||
}
|
||||
|
||||
void* doFetchRow(SRequestObj* pRequest) {
|
||||
assert(pRequest != NULL);
|
||||
SClientResultInfo* pResultInfo = pRequest->body.pResInfo;
|
||||
|
||||
if (pResultInfo == NULL || pResultInfo->current >= pResultInfo->pData->info.rows) {
|
||||
if (pResultInfo == NULL) {
|
||||
pRequest->body.pResInfo = calloc(1, sizeof(SClientResultInfo));
|
||||
// pRequest->body.pResInfo.
|
||||
}
|
||||
// current data set are exhausted, fetch more result from node
|
||||
// if (pRes->row >= pRes->numOfRows && needToFetchNewBlock(pSql)) {
|
||||
// taos_fetch_rows_a(res, waitForRetrieveRsp, pSql->pTscObj);
|
||||
// tsem_wait(&pSql->rspSem);
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#include "clientInt.h"
|
||||
#include "trpc.h"
|
||||
#include "clientLog.h"
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcache.h"
|
||||
|
@ -7,7 +7,7 @@
|
|||
#include "tglobal.h"
|
||||
#include "tnote.h"
|
||||
#include "tref.h"
|
||||
#include "tscLog.h"
|
||||
#include "trpc.h"
|
||||
#include "tsched.h"
|
||||
#include "ttime.h"
|
||||
#include "ttimezone.h"
|
||||
|
@ -16,9 +16,6 @@
|
|||
#define TSC_VAR_RELEASED 0
|
||||
|
||||
static int32_t sentinel = TSC_VAR_NOT_RELEASE;
|
||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||
|
||||
extern int32_t tscInitRes;
|
||||
|
||||
int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
||||
static int32_t lock = 0;
|
||||
|
@ -36,11 +33,6 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int taos_init() {
|
||||
pthread_once(&tscinit, taos_init_imp);
|
||||
return tscInitRes;
|
||||
}
|
||||
|
||||
// this function may be called by user or system, or by both simultaneously.
|
||||
void taos_cleanup(void) {
|
||||
tscDebug("start to cleanup client environment");
|
||||
|
@ -65,6 +57,21 @@ void taos_cleanup(void) {
|
|||
taosCloseLog();
|
||||
}
|
||||
|
||||
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
|
||||
int32_t p = (port != 0)? port:tsServerPort;
|
||||
|
||||
tscDebug("try to connect to %s:%u, user:%s db:%s", ip, p, user, db);
|
||||
if (user == NULL) {
|
||||
user = TSDB_DEFAULT_USER;
|
||||
}
|
||||
|
||||
if (pass == NULL) {
|
||||
pass = TSDB_DEFAULT_PASS;
|
||||
}
|
||||
|
||||
return taos_connect_internal(ip, user, pass, NULL, db, p);
|
||||
}
|
||||
|
||||
void taos_close(TAOS* taos) {
|
||||
if (taos == NULL) {
|
||||
return;
|
||||
|
@ -76,10 +83,51 @@ void taos_close(TAOS* taos) {
|
|||
taosRemoveRef(tscConnRef, pTscObj->id);
|
||||
}
|
||||
|
||||
const char *taos_errstr(TAOS_RES *res) {
|
||||
int taos_errno(TAOS_RES *tres) {
|
||||
if (tres == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
return ((SRequestObj*) tres)->code;
|
||||
}
|
||||
|
||||
const char *taos_errstr(TAOS_RES *res) {
|
||||
SRequestObj *pRequest = (SRequestObj *) res;
|
||||
|
||||
if (pRequest == NULL) {
|
||||
return (const char*) tstrerror(terrno);
|
||||
}
|
||||
|
||||
if (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR) {
|
||||
return pRequest->msgBuf;
|
||||
} else {
|
||||
return (const char*)tstrerror(pRequest->code);
|
||||
}
|
||||
}
|
||||
|
||||
void taos_free_result(TAOS_RES *res) {
|
||||
SRequestObj* pRequest = (SRequestObj*) res;
|
||||
destroyRequest(pRequest);
|
||||
}
|
||||
|
||||
}
|
||||
TAOS_RES *taos_query(TAOS *taos, const char *sql) {
|
||||
if (taos == NULL || sql == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return taos_query_l(taos, sql, strlen(sql));
|
||||
}
|
||||
|
||||
TAOS_ROW taos_fetch_row(TAOS_RES *pRes) {
|
||||
if (pRes == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SRequestObj *pRequest = (SRequestObj *) pRes;
|
||||
if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
|
||||
pRequest->type == TSDB_SQL_INSERT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return doFetchRow(pRequest);
|
||||
}
|
|
@ -13,11 +13,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include <catalog.h>
|
||||
#include "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "os.h"
|
||||
#include "tmsgtype.h"
|
||||
#include "trpc.h"
|
||||
#include "tscLog.h"
|
||||
|
||||
int (*buildRequestMsgFp[TSDB_SQL_MAX])(SRequestObj *pRequest, SRequestMsgBody *pMsgBody) = {0};
|
||||
int (*handleRequestRspFp[TSDB_SQL_MAX])(SRequestObj *pRequest, const char* pMsg, int32_t msgLen);
|
||||
|
@ -3091,6 +3092,36 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
|
|||
|
||||
#endif
|
||||
|
||||
int32_t buildConnectMsg(SRequestObj *pRequest, SRequestMsgBody* pMsgBody) {
|
||||
pMsgBody->msgType = TSDB_MSG_TYPE_CONNECT;
|
||||
pMsgBody->msgLen = sizeof(SConnectMsg);
|
||||
pMsgBody->requestObjRefId = pRequest->self;
|
||||
|
||||
SConnectMsg *pConnect = calloc(1, sizeof(SConnectMsg));
|
||||
if (pConnect == NULL) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO refactor full_name
|
||||
char *db; // ugly code to move the space
|
||||
|
||||
STscObj *pObj = pRequest->pTscObj;
|
||||
pthread_mutex_lock(&pObj->mutex);
|
||||
db = strstr(pObj->db, TS_PATH_DELIMITER);
|
||||
|
||||
db = (db == NULL) ? pObj->db : db + 1;
|
||||
tstrncpy(pConnect->db, db, sizeof(pConnect->db));
|
||||
pthread_mutex_unlock(&pObj->mutex);
|
||||
|
||||
pConnect->pid = htonl(appInfo.pid);
|
||||
pConnect->startTime = htobe64(appInfo.startTime);
|
||||
tstrncpy(pConnect->app, appInfo.appName, tListLen(pConnect->app));
|
||||
|
||||
pMsgBody->pData = pConnect;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int processConnectRsp(SRequestObj *pRequest, const char* pMsg, int32_t msgLen) {
|
||||
STscObj *pTscObj = pRequest->pTscObj;
|
||||
|
||||
|
@ -3099,6 +3130,11 @@ int processConnectRsp(SRequestObj *pRequest, const char* pMsg, int32_t msgLen) {
|
|||
pConnect->connId = htonl(pConnect->connId);
|
||||
pConnect->clusterId = htonl(pConnect->clusterId);
|
||||
|
||||
assert(pConnect->epSet.numOfEps > 0);
|
||||
for(int32_t i = 0; i < pConnect->epSet.numOfEps; ++i) {
|
||||
pConnect->epSet.port[i] = htons(pConnect->epSet.port[i]);
|
||||
}
|
||||
|
||||
// TODO refactor
|
||||
pthread_mutex_lock(&pTscObj->mutex);
|
||||
char temp[TSDB_TABLE_FNAME_LEN * 2] = {0};
|
||||
|
@ -3108,13 +3144,12 @@ int processConnectRsp(SRequestObj *pRequest, const char* pMsg, int32_t msgLen) {
|
|||
tstrncpy(pTscObj->db, temp, sizeof(pTscObj->db));
|
||||
pthread_mutex_unlock(&pTscObj->mutex);
|
||||
|
||||
assert(pConnect->epSet.numOfEps > 0);
|
||||
if (!isEpsetEqual(&pTscObj->pAppInfo->mgmtEp.epSet, &pConnect->epSet)) {
|
||||
updateEpSet_s(&pTscObj->pAppInfo->mgmtEp, &pConnect->epSet);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pConnect->epSet.numOfEps; ++i) {
|
||||
tscDebug("0x%" PRIx64 " epSet.fqdn[%d]: %s, connObj:0x%"PRIx64, pRequest->requestId, i, pConnect->epSet.fqdn[i], pTscObj->id);
|
||||
tscDebug("0x%" PRIx64 " epSet.fqdn[%d]:%s port:%d, connObj:0x%"PRIx64, pRequest->requestId, i, pConnect->epSet.fqdn[i], pConnect->epSet.port[i], pTscObj->id);
|
||||
}
|
||||
|
||||
pTscObj->connId = pConnect->connId;
|
||||
|
@ -3124,10 +3159,81 @@ int processConnectRsp(SRequestObj *pRequest, const char* pMsg, int32_t msgLen) {
|
|||
atomic_add_fetch_64(&pTscObj->pAppInfo->numOfConns, 1);
|
||||
|
||||
tscDebug("0x%" PRIx64 " clusterId:%d, totalConn:%"PRId64, pRequest->requestId, pConnect->clusterId, pTscObj->pAppInfo->numOfConns);
|
||||
// createHbObj(pTscObj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t buildCreateUserMsg(SRequestObj *pRequest, SRequestMsgBody* pMsgBody) {
|
||||
pMsgBody->msgType = TSDB_MSG_TYPE_CREATE_USER;
|
||||
pMsgBody->msgLen = sizeof(SCreateUserMsg);
|
||||
pMsgBody->requestObjRefId = pRequest->self;
|
||||
pMsgBody->pData = pRequest->body.param;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t buildShowMsg(SRequestObj* pRequest, SRequestMsgBody* pMsgBody) {
|
||||
pMsgBody->msgType = TSDB_MSG_TYPE_SHOW;
|
||||
pMsgBody->msgLen = pRequest->body.paramLen;
|
||||
pMsgBody->requestObjRefId = pRequest->self;
|
||||
pMsgBody->pData = pRequest->body.param;
|
||||
}
|
||||
|
||||
STableMeta* createTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) {
|
||||
assert(pTableMetaMsg != NULL && pTableMetaMsg->numOfColumns >= 2);
|
||||
|
||||
size_t schemaSize = (pTableMetaMsg->numOfColumns + pTableMetaMsg->numOfTags) * sizeof(SSchema);
|
||||
STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + schemaSize);
|
||||
|
||||
pTableMeta->tableType = pTableMetaMsg->tableType;
|
||||
pTableMeta->vgId = pTableMetaMsg->vgroup.vgId;
|
||||
pTableMeta->suid = pTableMetaMsg->suid;
|
||||
pTableMeta->uid = pTableMetaMsg->tuid;
|
||||
|
||||
pTableMeta->tableInfo = (STableComInfo) {
|
||||
.numOfTags = pTableMetaMsg->numOfTags,
|
||||
.precision = pTableMetaMsg->precision,
|
||||
.numOfColumns = pTableMetaMsg->numOfColumns,
|
||||
};
|
||||
|
||||
pTableMeta->sversion = pTableMetaMsg->sversion;
|
||||
pTableMeta->tversion = pTableMetaMsg->tversion;
|
||||
|
||||
memcpy(pTableMeta->schema, pTableMetaMsg->pSchema, schemaSize);
|
||||
|
||||
int32_t numOfTotalCols = pTableMeta->tableInfo.numOfColumns;
|
||||
for(int32_t i = 0; i < numOfTotalCols; ++i) {
|
||||
pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes;
|
||||
}
|
||||
|
||||
return pTableMeta;
|
||||
}
|
||||
|
||||
int32_t processShowRsp(SRequestObj *pRequest, const char* pMsg, int32_t msgLen) {
|
||||
SShowRsp* pShow = (SShowRsp *)pMsg;
|
||||
pShow->showId = htonl(pShow->showId);
|
||||
|
||||
STableMetaMsg *pMetaMsg = &(pShow->tableMeta);
|
||||
pMetaMsg->numOfColumns = htonl(pMetaMsg->numOfColumns);
|
||||
|
||||
SSchema* pSchema = pMetaMsg->pSchema;
|
||||
pMetaMsg->tuid = htobe64(pMetaMsg->tuid);
|
||||
for (int i = 0; i < pMetaMsg->numOfColumns; ++i) {
|
||||
pSchema->bytes = htons(pSchema->bytes);
|
||||
pSchema++;
|
||||
}
|
||||
|
||||
STableMeta* pTableMeta = createTableMetaFromMsg(pMetaMsg);
|
||||
SSchema *pTableSchema = pTableMeta->schema;
|
||||
|
||||
TAOS_FIELD* pFields = calloc(1, pTableMeta->tableInfo.numOfColumns);
|
||||
for (int16_t i = 0; i < pTableMeta->tableInfo.numOfColumns; ++i, ++pSchema) {
|
||||
tstrncpy(pFields[i].name, pTableSchema[i].name, tListLen(pFields[i].name));
|
||||
pFields[i].type = pTableSchema[i].type;
|
||||
pFields[i].bytes = pTableSchema[i].bytes;
|
||||
}
|
||||
|
||||
// pRequest->body.resultFields = pFields;
|
||||
// pRequest->body.numOfFields = pTableMeta->tableInfo.numOfColumns;
|
||||
|
||||
// launch a timer to send heartbeat to maintain the connection and send status to mnode
|
||||
// taosTmrReset(tscProcessActivityTimer, tsShellActivityTimer * 500, (void *)pTscObj->rid, tscTmr, &pTscObj->pTimer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3207,6 +3313,12 @@ void initMsgHandleFp() {
|
|||
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp;
|
||||
#endif
|
||||
|
||||
// buildRequestMsgFp[TSDB_SQL_CONNECT] = tscBuildConnectMsg;
|
||||
buildRequestMsgFp[TSDB_SQL_CONNECT] = buildConnectMsg;
|
||||
handleRequestRspFp[TSDB_SQL_CONNECT] = processConnectRsp;
|
||||
|
||||
buildRequestMsgFp[TSDB_SQL_CREATE_USER] = buildCreateUserMsg;
|
||||
|
||||
buildRequestMsgFp[TSDB_SQL_SHOW] = buildShowMsg;
|
||||
handleRequestRspFp[TSDB_SQL_SHOW] = processShowRsp;
|
||||
|
||||
}
|
|
@ -13,6 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcache.h"
|
||||
|
@ -20,12 +22,10 @@
|
|||
#include "tglobal.h"
|
||||
#include "tnote.h"
|
||||
#include "tref.h"
|
||||
#include "tscLog.h"
|
||||
#include "trpc.h"
|
||||
#include "tsched.h"
|
||||
#include "ttime.h"
|
||||
#include "trpc.h"
|
||||
#include "ttimezone.h"
|
||||
#include "clientInt.h"
|
||||
|
||||
#define TSC_VAR_NOT_RELEASE 1
|
||||
#define TSC_VAR_RELEASED 0
|
||||
|
@ -35,6 +35,7 @@ int32_t tscReqRef = -1;
|
|||
int32_t tscConnRef = -1;
|
||||
void *tscQhandle = NULL;
|
||||
|
||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||
int32_t tsNumOfThreads = 1;
|
||||
volatile int32_t tscInitRes = 0;
|
||||
|
||||
|
@ -64,7 +65,7 @@ static void deregisterRequest(SRequestObj* pRequest) {
|
|||
SInstanceActivity* pActivity = &pTscObj->pAppInfo->summary;
|
||||
|
||||
int32_t currentInst = atomic_sub_fetch_32(&pActivity->currentRequests, 1);
|
||||
int32_t num = atomic_sub_fetch_32(&pTscObj->numOfReqs, 1);
|
||||
int32_t num = atomic_sub_fetch_32(&pTscObj->numOfReqs, 1);
|
||||
|
||||
tscDebug("0x%"PRIx64" free Request from connObj: 0x%"PRIx64", current:%d, app current:%d", pRequest->self, pTscObj->id, num, currentInst);
|
||||
taosReleaseRef(tscConnRef, pTscObj->id);
|
||||
|
@ -172,6 +173,7 @@ void* createRequest(STscObj* pObj, __taos_async_fn_t fp, void* param, int32_t ty
|
|||
pRequest->pTscObj = pObj;
|
||||
pRequest->body.fp = fp;
|
||||
pRequest->body.param = param;
|
||||
pRequest->msgBuf = calloc(1, ERROR_MSG_BUF_DEFAULT_SIZE);
|
||||
tsem_init(&pRequest->body.rspSem, 0, 0);
|
||||
|
||||
registerRequest(pRequest);
|
||||
|
@ -250,6 +252,11 @@ void taos_init_imp(void) {
|
|||
tscDebug("client is initialized successfully");
|
||||
}
|
||||
|
||||
int taos_init() {
|
||||
pthread_once(&tscinit, taos_init_imp);
|
||||
return tscInitRes;
|
||||
}
|
||||
|
||||
int taos_options_imp(TSDB_OPTION option, const char *str) {
|
||||
SGlobalCfg *cfg = NULL;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <taoserror.h>
|
||||
#include <iostream>
|
||||
#include "tglobal.h"
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
|
@ -36,5 +37,16 @@ TEST(testCase, driverInit_Test) {
|
|||
TAOS* pConn = taos_connect("ubuntu", "root", "taosdata", NULL, 0);
|
||||
assert(pConn != NULL);
|
||||
|
||||
// TAOS_RES* pRes = taos_query(pConn, "create user abc pass 'abc'");
|
||||
// if (taos_errno(pRes) != TSDB_CODE_SUCCESS) {
|
||||
// printf("failed to create user, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
//
|
||||
// taos_free_result(pRes);
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "show users");
|
||||
TAOS_ROW pRow = taos_fetch_row(pRes);
|
||||
assert(pRow != NULL);
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
|
@ -431,7 +431,7 @@ static int32_t mndGetUserMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *p
|
|||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
pMeta->numOfColumns = htonl(cols);
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
pShow->offset[0] = 0;
|
||||
|
|
|
@ -53,6 +53,15 @@ void clearAllTableMetaInfo(SQueryStmtInfo* pQueryInfo, bool removeMeta, uint64_t
|
|||
*/
|
||||
int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQueryStmtInfo* pQueryInfo, int64_t id, char* msg, int32_t msgLen);
|
||||
|
||||
/**
|
||||
* validate the ddl ast, and convert the ast to the corresponding message format
|
||||
* @param pSqlInfo
|
||||
* @param output
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, int64_t id, void** output, int32_t* outputLen, int32_t* type, char* msgBuf, int32_t msgBufLen);
|
||||
|
||||
/**
|
||||
* Evaluate the numeric and timestamp arithmetic expression in the WHERE clause.
|
||||
* @param pNode
|
||||
|
|
|
@ -45,6 +45,8 @@ int32_t getNumOfFields(SFieldInfo* pFieldInfo);
|
|||
SInternalField* getInternalField(SFieldInfo* pFieldInfo, int32_t index);
|
||||
|
||||
int32_t parserValidateIdToken(SToken* pToken);
|
||||
int32_t parserValidatePassword(SToken* pToken, SMsgBuf* pMsgBuf);
|
||||
|
||||
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
|
||||
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr);
|
||||
|
||||
|
@ -63,6 +65,8 @@ int32_t getExprFunctionId(SExprInfo *pExprInfo);
|
|||
|
||||
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
||||
|
||||
bool isDclSqlStatement(SSqlInfo* pSqlInfo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <function.h>
|
||||
#include "astGenerator.h"
|
||||
#include "function.h"
|
||||
#include "parserInt.h"
|
||||
|
@ -23,6 +22,7 @@
|
|||
#include "tglobal.h"
|
||||
#include "tmsgtype.h"
|
||||
#include "ttime.h"
|
||||
#include "astToMsg.h"
|
||||
|
||||
#define TSQL_TBNAME_L "tbname"
|
||||
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"
|
||||
|
@ -3636,11 +3636,14 @@ int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf)
|
|||
}
|
||||
|
||||
int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQueryStmtInfo* pQueryInfo, int64_t id, char* msgBuf, int32_t msgBufLen) {
|
||||
//1. if it is a query, get the meta info and continue.
|
||||
assert(pCatalog != NULL && pInfo != NULL);
|
||||
int32_t code = 0;
|
||||
#if 0
|
||||
|
||||
SMsgBuf m = {.buf = msgBuf, .len = msgBufLen};
|
||||
SMsgBuf *pMsgBuf = &m;
|
||||
|
||||
switch (pInfo->type) {
|
||||
#if 0
|
||||
case TSDB_SQL_DROP_TABLE:
|
||||
case TSDB_SQL_DROP_USER:
|
||||
case TSDB_SQL_DROP_ACCT:
|
||||
|
@ -3651,14 +3654,14 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
|
||||
SToken* pzName = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||
if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (parserValidateIdToken(pzName) != TSDB_CODE_SUCCESS)) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg2);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
if (pInfo->type == TSDB_SQL_DROP_DB) {
|
||||
assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1);
|
||||
code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg2);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
} else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
|
||||
|
@ -3675,7 +3678,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
strncpy(pCmd->payload, pzName->z, pzName->n);
|
||||
} else { // drop user/account
|
||||
if (pzName->n >= TSDB_USER_LEN) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg3);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
strncpy(pCmd->payload, pzName->z, pzName->n);
|
||||
|
@ -3689,12 +3692,12 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||
|
||||
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg);
|
||||
}
|
||||
|
||||
int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -3729,19 +3732,19 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
|
||||
SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt);
|
||||
if (pCreateDB->dbname.n >= TSDB_DB_NAME_LEN) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg2);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
char buf[TSDB_DB_NAME_LEN] = {0};
|
||||
SToken token = taosTokenDup(&pCreateDB->dbname, buf, tListLen(buf));
|
||||
|
||||
if (tscValidateName(&token) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg1);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &token);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg2);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3755,7 +3758,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
const char* msg = "invalid host name (ip address)";
|
||||
|
||||
if (taosArrayGetSize(pInfo->pMiscInfo->a) > 1) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg);
|
||||
}
|
||||
|
||||
SToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||
|
@ -3779,11 +3782,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
}
|
||||
|
||||
if (pName->n >= TSDB_USER_LEN) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg3);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg2);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
SCreateAcctInfo* pAcctOpt = &pInfo->pMiscInfo->acctOpt;
|
||||
|
@ -3793,7 +3796,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
} else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) {
|
||||
} else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) {
|
||||
} else {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg1);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3805,7 +3808,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
|
||||
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg1);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
// additional msg has been attached already
|
||||
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
|
||||
|
@ -3821,7 +3824,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
|
||||
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg1);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
|
||||
|
@ -3836,11 +3839,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
|
||||
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg1);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
if (pToken->n > TSDB_DB_NAME_LEN) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg1);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
return tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken);
|
||||
}
|
||||
|
@ -3853,7 +3856,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
|
||||
/* validate the parameter names and options */
|
||||
if (validateDNodeConfig(pMiscInfo) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg2);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
char* pMsg = pCmd->payload;
|
||||
|
@ -3867,7 +3870,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
strncpy(pCfg->ep, t0->z, t0->n);
|
||||
|
||||
if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg3);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
strncpy(pCfg->config, t1->z, t1->n);
|
||||
|
@ -3882,65 +3885,13 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
break;
|
||||
}
|
||||
|
||||
case TSDB_SQL_CREATE_USER:
|
||||
case TSDB_SQL_ALTER_USER: {
|
||||
const char* msg2 = "invalid user/account name";
|
||||
const char* msg3 = "name too long";
|
||||
const char* msg5 = "invalid user rights";
|
||||
const char* msg7 = "not support options";
|
||||
|
||||
pCmd->command = pInfo->type;
|
||||
|
||||
SUserInfo* pUser = &pInfo->pMiscInfo->user;
|
||||
SToken* pName = &pUser->user;
|
||||
SToken* pPwd = &pUser->passwd;
|
||||
|
||||
if (pName->n >= TSDB_USER_LEN) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
if (pCmd->command == TSDB_SQL_CREATE_USER) {
|
||||
if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
} else {
|
||||
if (pUser->type == TSDB_ALTER_USER_PASSWD) {
|
||||
if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
} else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
|
||||
assert(pPwd->type == TSDB_DATA_TYPE_NULL);
|
||||
|
||||
SToken* pPrivilege = &pUser->privilege;
|
||||
|
||||
if (strncasecmp(pPrivilege->z, "super", 5) == 0 && pPrivilege->n == 5) {
|
||||
pCmd->count = 1;
|
||||
} else if (strncasecmp(pPrivilege->z, "read", 4) == 0 && pPrivilege->n == 4) {
|
||||
pCmd->count = 2;
|
||||
} else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) {
|
||||
pCmd->count = 3;
|
||||
} else {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg5);
|
||||
}
|
||||
} else {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg7);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_SQL_CFG_LOCAL: {
|
||||
SMiscInfo *pMiscInfo = pInfo->pMiscInfo;
|
||||
const char *msg = "invalid configure options or values";
|
||||
|
||||
// validate the parameter names and options
|
||||
if (validateLocalConfig(pMiscInfo) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg);
|
||||
}
|
||||
|
||||
int32_t numOfToken = (int32_t) taosArrayGetSize(pMiscInfo->a);
|
||||
|
@ -3995,7 +3946,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
tscTrace("0x%"PRIx64" start to parse the %dth subclause, total:%"PRIzu, pSql->self, i, size);
|
||||
|
||||
if (size > 1 && pSqlNode->from && pSqlNode->from->type == SQL_FROM_NODE_SUBQUERY) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg1);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
// normalizeSqlNode(pSqlNode); // normalize the column name in each function
|
||||
|
@ -4061,21 +4012,22 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1);
|
||||
code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg1);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_SQL_COMPACT_VNODE:{
|
||||
const char* msg = "invalid compact";
|
||||
if (setCompactVnodeInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
|
||||
return setInvalidOperatorMsg(pMsgBuf, msg);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return setInvalidOperatorMsg(pMsgBuf, "not support sql expression");
|
||||
return buildInvalidOperationMsg(pMsgBuf, "not support sql expression");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
SCatalogReq req = {0};
|
||||
SMetaData data = {0};
|
||||
|
@ -4114,5 +4066,159 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
}
|
||||
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
// todo remove it
|
||||
static int32_t setShowInfo(struct SSqlInfo* pInfo, void** output, int32_t* msgLen, SMsgBuf* pMsgBuf) {
|
||||
const char* msg1 = "invalid name";
|
||||
const char* msg2 = "wildcard string should be less than %d characters";
|
||||
const char* msg3 = "database name too long";
|
||||
const char* msg4 = "pattern is invalid";
|
||||
const char* msg5 = "database name is empty";
|
||||
const char* msg6 = "pattern string is empty";
|
||||
|
||||
/*
|
||||
* database prefix in pInfo->pMiscInfo->a[0]
|
||||
* wildcard in like clause in pInfo->pMiscInfo->a[1]
|
||||
*/
|
||||
SShowInfo* pShowInfo = &pInfo->pMiscInfo->showOpt;
|
||||
int16_t showType = pShowInfo->showType;
|
||||
if (showType == TSDB_MGMT_TABLE_TABLE || showType == TSDB_MGMT_TABLE_VGROUP) {
|
||||
SToken* pDbPrefixToken = &pShowInfo->prefix;
|
||||
if (pDbPrefixToken->type != 0) {
|
||||
if (pDbPrefixToken->n >= TSDB_DB_NAME_LEN) { // db name is too long
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
if (pDbPrefixToken->n <= 0) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg5);
|
||||
}
|
||||
|
||||
if (parserValidateIdToken(pDbPrefixToken) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
// int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pRequest->pTsc), pDbPrefixToken);
|
||||
// if (ret != TSDB_CODE_SUCCESS) {
|
||||
// return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
// }
|
||||
}
|
||||
|
||||
// show table/stable like 'xxxx', set the like pattern for show tables
|
||||
SToken* pPattern = &pShowInfo->pattern;
|
||||
if (pPattern->type != 0) {
|
||||
if (pPattern->type == TK_ID && pPattern->z[0] == TS_ESCAPE_CHAR) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg4);
|
||||
}
|
||||
|
||||
pPattern->n = strdequote(pPattern->z);
|
||||
if (pPattern->n <= 0) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg6);
|
||||
}
|
||||
|
||||
if (pPattern->n > tsMaxWildCardsLen) {
|
||||
char tmp[64] = {0};
|
||||
sprintf(tmp, msg2, tsMaxWildCardsLen);
|
||||
return buildInvalidOperationMsg(pMsgBuf, tmp);
|
||||
}
|
||||
}
|
||||
} else if (showType == TSDB_MGMT_TABLE_VNODES) {
|
||||
if (pShowInfo->prefix.type == 0) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, "No specified dnode ep");
|
||||
}
|
||||
|
||||
if (pShowInfo->prefix.type == TK_STRING) {
|
||||
pShowInfo->prefix.n = strdequote(pShowInfo->prefix.z);
|
||||
}
|
||||
}
|
||||
|
||||
SShowMsg* pShowMsg = calloc(1, sizeof(SShowMsg));
|
||||
pShowMsg->type = pShowInfo->showType;
|
||||
|
||||
if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) {
|
||||
SToken* pPattern = &pShowInfo->pattern;
|
||||
if (pPattern->type > 0) { // only show tables support wildcard query
|
||||
strncpy(pShowMsg->payload, pPattern->z, pPattern->n);
|
||||
pShowMsg->payloadLen = htons(pPattern->n);
|
||||
}
|
||||
} else {
|
||||
SToken* pEpAddr = &pShowInfo->prefix;
|
||||
assert(pEpAddr->n > 0 && pEpAddr->type > 0);
|
||||
|
||||
strncpy(pShowMsg->payload, pEpAddr->z, pEpAddr->n);
|
||||
pShowMsg->payloadLen = htons(pEpAddr->n);
|
||||
}
|
||||
|
||||
*output = pShowMsg;
|
||||
*msgLen = sizeof(SShowMsg) + htons(pShowMsg->payloadLen);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, int64_t id, void** output, int32_t* outputLen, int32_t* type, char* msgBuf, int32_t msgBufLen) {
|
||||
int32_t code = 0;
|
||||
|
||||
SMsgBuf m = {.buf = msgBuf, .len = msgBufLen};
|
||||
SMsgBuf *pMsgBuf = &m;
|
||||
|
||||
*type = pInfo->type;
|
||||
|
||||
switch (pInfo->type) {
|
||||
case TSDB_SQL_CREATE_USER:
|
||||
case TSDB_SQL_ALTER_USER: {
|
||||
const char* msg1 = "not support options";
|
||||
const char* msg2 = "invalid user/account name";
|
||||
const char* msg3 = "name too long";
|
||||
const char* msg4 = "invalid user rights";
|
||||
|
||||
SUserInfo* pUser = &pInfo->pMiscInfo->user;
|
||||
SToken* pName = &pUser->user;
|
||||
SToken* pPwd = &pUser->passwd;
|
||||
|
||||
if (pName->n >= TSDB_USER_LEN) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
if (parserValidateIdToken(pName) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
if (pInfo->type == TSDB_SQL_CREATE_USER) {
|
||||
if (parserValidatePassword(pPwd, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
} else {
|
||||
if (pUser->type == TSDB_ALTER_USER_PASSWD) {
|
||||
if (parserValidatePassword(pPwd, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
} else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
|
||||
assert(pPwd->type == TSDB_DATA_TYPE_NULL);
|
||||
|
||||
SToken* pPrivilege = &pUser->privilege;
|
||||
if (strncasecmp(pPrivilege->z, "super", 5) == 0 && pPrivilege->n == 5) {
|
||||
// pCmd->count = 1;
|
||||
} else if (strncasecmp(pPrivilege->z, "normal", 4) == 0 && pPrivilege->n == 4) {
|
||||
// pCmd->count = 2;
|
||||
} else {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg4);
|
||||
}
|
||||
} else {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
}
|
||||
|
||||
*output = buildUserManipulationMsg(pInfo, id, msgBuf, msgBufLen);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_SQL_SHOW: {
|
||||
code = setShowInfo(pInfo, output, outputLen, pMsgBuf);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -31,25 +31,35 @@ bool qIsInsertSql(const char* pStr, size_t length) {
|
|||
} while (1);
|
||||
}
|
||||
|
||||
int32_t qParseQuerySql(const char* pStr, size_t length, struct SQueryStmtInfo** pQueryInfo, int64_t id, char* msg, int32_t msgLen) {
|
||||
*pQueryInfo = calloc(1, sizeof(SQueryStmtInfo));
|
||||
if (*pQueryInfo == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY; // set correct error code.
|
||||
int32_t qParseQuerySql(const char* pStr, size_t length, int64_t id, int32_t *type, void** pOutput, int32_t* outputLen, char* msg, int32_t msgLen) {
|
||||
SQueryStmtInfo* pQueryInfo = calloc(1, sizeof(SQueryStmtInfo));
|
||||
if (pQueryInfo == NULL) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; // set correct error code.
|
||||
return terrno;
|
||||
}
|
||||
|
||||
SSqlInfo info = doGenerateAST(pStr);
|
||||
if (!info.valid) {
|
||||
strncpy(msg, info.msg, msgLen);
|
||||
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||
terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
struct SCatalog* pCatalog = NULL;
|
||||
int32_t code = catalogGetHandle(NULL, &pCatalog);
|
||||
if (code) {
|
||||
return code;
|
||||
if (isDclSqlStatement(&info)) {
|
||||
int32_t code = qParserValidateDclSqlNode(&info, id, pOutput, outputLen, type, msg, msgLen);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
// do nothing
|
||||
}
|
||||
} else {
|
||||
struct SCatalog* pCatalog = NULL;
|
||||
int32_t code = catalogGetHandle(NULL, &pCatalog);
|
||||
code = qParserValidateSqlNode(pCatalog, &info, pQueryInfo, id, msg, msgLen);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
*pOutput = pQueryInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return qParserValidateSqlNode(pCatalog, &info, *pQueryInfo, id, msg, msgLen);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qParseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
* 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 "parserUtil.h"
|
||||
|
||||
|
||||
#include "taosmsg.h"
|
||||
#include "parser.h"
|
||||
|
@ -22,6 +22,8 @@
|
|||
#include "thash.h"
|
||||
#include "tbuffer.h"
|
||||
#include "parserInt.h"
|
||||
#include "parserUtil.h"
|
||||
#include "tmsgtype.h"
|
||||
#include "queryInfoUtil.h"
|
||||
#include "function.h"
|
||||
|
||||
|
@ -97,12 +99,35 @@ int32_t parserValidateIdToken(SToken* pToken) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t parserValidatePassword(SToken* pToken, SMsgBuf* pMsgBuf) {
|
||||
const char* msg1 = "password can not be empty";
|
||||
const char* msg2 = "name or password too long";
|
||||
const char* msg3 = "password needs single quote marks enclosed";
|
||||
|
||||
if (pToken->type != TK_STRING) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
strdequote(pToken->z);
|
||||
|
||||
pToken->n = (uint32_t)strtrim(pToken->z); // trim space before and after passwords
|
||||
if (pToken->n <= 0) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
if (pToken->n >= TSDB_USET_PASSWORD_LEN) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t buildInvalidOperationMsg(SMsgBuf* pBuf, const char* msg) {
|
||||
strncpy(pBuf->buf, msg, pBuf->len);
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr) {
|
||||
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr) {
|
||||
const char* msgFormat1 = "syntax error near \'%s\'";
|
||||
const char* msgFormat2 = "syntax error near \'%s\' (%s)";
|
||||
const char* msgFormat3 = "%s";
|
||||
|
@ -584,21 +609,6 @@ int32_t getNumOfFields(SFieldInfo* pFieldInfo) {
|
|||
return pFieldInfo->numOfOutput;
|
||||
}
|
||||
|
||||
int32_t getFirstInvisibleFieldPos(SQueryStmtInfo* pQueryInfo) {
|
||||
if (pQueryInfo->fieldsInfo.numOfOutput <= 0 || pQueryInfo->fieldsInfo.internalField == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||
SInternalField* pField = taosArrayGet(pQueryInfo->fieldsInfo.internalField, i);
|
||||
if (!pField->visible) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return pQueryInfo->fieldsInfo.numOfOutput;
|
||||
}
|
||||
|
||||
SInternalField* appendFieldInfo(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) {
|
||||
assert(pFieldInfo != NULL);
|
||||
pFieldInfo->numOfOutput++;
|
||||
|
@ -1583,6 +1593,10 @@ uint32_t convertRelationalOperator(SToken *pToken) {
|
|||
}
|
||||
}
|
||||
|
||||
bool isDclSqlStatement(SSqlInfo* pSqlInfo) {
|
||||
return (pSqlInfo->type != TSDB_SQL_SELECT);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t tscCreateQueryFromQueryInfo(SQueryStmtInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr) {
|
||||
memset(pQueryAttr, 0, sizeof(SQueryAttr));
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "taos.h"
|
||||
#include "tdef.h"
|
||||
#include "tvariant.h"
|
||||
#include "parserUtil.h"
|
||||
|
||||
namespace {
|
||||
void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_t colId) {
|
||||
|
@ -700,5 +701,47 @@ TEST(testCase, function_Test6) {
|
|||
|
||||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
}
|
||||
|
||||
TEST(testCase, show_user_Test) {
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
char sql1[] = "show users";
|
||||
SSqlInfo info1 = doGenerateAST(sql1);
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
void* output = NULL;
|
||||
int32_t type = 0;
|
||||
int32_t len = 0;
|
||||
int32_t code = qParserValidateDclSqlNode(&info1, 1, &output, &len, &type, msg, buf.len);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
// convert the show command to be the select query
|
||||
// select name, privilege, create_time, account from information_schema.users;
|
||||
}
|
||||
|
||||
TEST(testCase, create_user_Test) {
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
char sql[] = {"create user abc pass 'abc'"};
|
||||
|
||||
SSqlInfo info1 = doGenerateAST(sql);
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
ASSERT_EQ(isDclSqlStatement(&info1), true);
|
||||
|
||||
void* output = NULL;
|
||||
int32_t type = 0;
|
||||
int32_t len = 0;
|
||||
int32_t code = qParserValidateDclSqlNode(&info1, 1, &output, &len, &type, msg, buf.len);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
destroySqlInfo(&info1);
|
||||
}
|
Loading…
Reference in New Issue