[td-11818] support create user/show user parser.
This commit is contained in:
parent
77ff634df8
commit
6386917287
|
@ -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"
|
||||
}
|
|
@ -393,8 +393,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
|
||||
} SCreateUserMsg, SAlterUserMsg;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -151,7 +151,7 @@ typedef struct SParseContext {
|
|||
* @param msg extended error message if exists.
|
||||
* @return error code
|
||||
*/
|
||||
struct SQueryStmtInfo* qParseQuerySql(const char* pStr, size_t length, 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, char* msg, int32_t msgLen);
|
||||
|
||||
typedef enum {
|
||||
PAYLOAD_TYPE_KV = 0,
|
||||
|
|
|
@ -194,6 +194,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
|
||||
|
||||
|
|
|
@ -120,7 +120,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();
|
||||
|
|
|
@ -1,64 +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 "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "tglobal.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,5 +1,4 @@
|
|||
|
||||
#include <parser.h>
|
||||
#include "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "tdef.h"
|
||||
|
@ -9,6 +8,7 @@
|
|||
#include "tnote.h"
|
||||
#include "tpagedfile.h"
|
||||
#include "tref.h"
|
||||
#include "parser.h"
|
||||
|
||||
static int32_t initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSet);
|
||||
static int32_t buildConnectMsg(SRequestObj *pRequest, SRequestMsgBody* pMsgBody);
|
||||
|
@ -113,7 +113,7 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass,
|
|||
}
|
||||
|
||||
TAOS_RES *taos_query_l(TAOS *taos, const char *sql, size_t sqlLen) {
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
STscObj *pTscObj = (STscObj *)taos;
|
||||
if (sqlLen > (size_t) tsMaxSQLStringLen) {
|
||||
tscError("sql string exceeds max length:%d", tsMaxSQLStringLen);
|
||||
terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
|
||||
|
@ -122,7 +122,7 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, size_t sqlLen) {
|
|||
|
||||
nPrintTsc("%s", sql)
|
||||
|
||||
SRequestObj* pRequest = createRequest(pObj, NULL, NULL, TSDB_SQL_SELECT);
|
||||
SRequestObj* pRequest = createRequest(pTscObj, NULL, NULL, TSDB_SQL_SELECT);
|
||||
if (pRequest == NULL) {
|
||||
tscError("failed to malloc sqlObj");
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -143,25 +143,36 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, size_t sqlLen) {
|
|||
|
||||
tscDebugL("0x%"PRIx64" SQL: %s", pRequest->requestId, pRequest->sqlstr);
|
||||
|
||||
int32_t code = 0;//tsParseSql(pSql, true);
|
||||
int32_t code = 0;
|
||||
if (qIsInsertSql(pRequest->sqlstr, sqlLen)) {
|
||||
// qParseInsertSql();
|
||||
// todo add
|
||||
} else {
|
||||
SQueryStmtInfo *pQueryInfo = qParseQuerySql(pRequest->sqlstr, sqlLen, pRequest->requestId, pRequest->msgBuf, ERROR_MSG_BUF_DEFAULT_SIZE);
|
||||
assert(pQueryInfo != NULL);
|
||||
int32_t type = 0;
|
||||
void* output = NULL;
|
||||
|
||||
code = qParseQuerySql(pRequest->sqlstr, sqlLen, pRequest->requestId, &type, &output, pRequest->msgBuf, ERROR_MSG_BUF_DEFAULT_SIZE);
|
||||
if (type == TSDB_SQL_CREATE_USER || type == TSDB_SQL_SHOW) {
|
||||
pRequest->type = type;
|
||||
pRequest->body.param = output;
|
||||
|
||||
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;
|
||||
// tscAsyncResultOnError(pSql);
|
||||
// taosReleaseRef(tscReqRef, p->self);
|
||||
return NULL;
|
||||
return pRequest;
|
||||
}
|
||||
|
||||
// executeQuery(pSql, pQueryInfo);
|
||||
// doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen);
|
||||
|
||||
tsem_wait(&pRequest->body.rspSem);
|
||||
return pRequest;
|
||||
}
|
||||
|
||||
|
@ -328,8 +339,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);
|
||||
|
@ -337,3 +348,30 @@ 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);
|
||||
}
|
|
@ -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,12 +83,31 @@ 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) {
|
||||
|
|
|
@ -3091,6 +3091,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 +3129,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 +3143,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 +3158,14 @@ 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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3207,6 +3245,10 @@ 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;
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
@ -251,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,6 +37,14 @@ TEST(testCase, driverInit_Test) {
|
|||
TAOS* pConn = taos_connect("ubuntu", "root", "taosdata", NULL, 0);
|
||||
assert(pConn != NULL);
|
||||
|
||||
taos_query(pConn, "create user abc pass 'abc'");
|
||||
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);
|
||||
|
||||
pRes = taos_query(pConn, "show users");
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
|
@ -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 qParserValidateDdlSqlNode(SSqlInfo* pInfo, int64_t id, void** output, 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 isDdlSql(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
|
||||
|
||||
|
||||
SMetaReq req = {0};
|
||||
SMetaData data = {0};
|
||||
|
@ -4116,3 +4068,66 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t qParserValidateDdlSqlNode(SSqlInfo* pInfo, int64_t id, void** output, 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;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -31,27 +31,35 @@ bool qIsInsertSql(const char* pStr, size_t length) {
|
|||
} while (1);
|
||||
}
|
||||
|
||||
SQueryStmtInfo* qParseQuerySql(const char* pStr, size_t length, 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, 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 NULL;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
SSqlInfo info = doGenerateAST(pStr);
|
||||
if (!info.valid) {
|
||||
strncpy(msg, info.msg, msgLen);
|
||||
terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||
return NULL;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
if (isDdlSql(&info)) {
|
||||
int32_t code = qParserValidateDdlSqlNode(&info, id, pOutput, type, msg, msgLen);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
// do nothing
|
||||
}
|
||||
} else {
|
||||
struct SCatalog* pCatalog = getCatalogHandle(NULL);
|
||||
|
||||
int32_t code = qParserValidateSqlNode(pCatalog, &info, pQueryInfo, id, msg, msgLen);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
return pQueryInfo;
|
||||
*pOutput = pQueryInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qParseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "parserUtil.h"
|
||||
#include <tmsgtype.h>
|
||||
|
||||
#include "taosmsg.h"
|
||||
#include "parser.h"
|
||||
|
@ -97,6 +98,29 @@ 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;
|
||||
|
@ -584,21 +608,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++;
|
||||
|
@ -1623,6 +1632,10 @@ uint32_t convertRelationalOperator(SToken *pToken) {
|
|||
}
|
||||
}
|
||||
|
||||
bool isDdlSql(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) {
|
||||
|
@ -702,3 +703,47 @@ TEST(testCase, function_Test6) {
|
|||
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);
|
||||
|
||||
// convert the show command to be the select query
|
||||
// select name, privilege, create_time, account from information_schema.users;
|
||||
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
// setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
// ASSERT_NE(ret, 0);
|
||||
}
|
||||
|
||||
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(isDdlSql(&info1), true);
|
||||
|
||||
void* output = NULL;
|
||||
int32_t type = 0;
|
||||
|
||||
int32_t code = qParserValidateDdlSqlNode(&info1, 1, &output, &type, msg, buf.len);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
destroySqlInfo(&info1);
|
||||
}
|
Loading…
Reference in New Issue