提交 5e918eaa 编写于 作者: B Benguang Zhao

Merge 2.6 to FIX/TD-19011-2.6

......@@ -336,6 +336,7 @@ typedef struct STscObj {
char user[TSDB_USER_LEN];
char pass[TSDB_PASS_LEN];
char acctId[TSDB_ACCT_ID_LEN];
char tags[TSDB_TAGS_LEN];
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
char sversion[TSDB_VERSION_LEN];
char clusterId[TSDB_CLUSTER_ID_LEN];
......
......@@ -34,6 +34,320 @@ static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOf
*/
static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows);
// like select * from st1 , st2 where ... format
static inline int32_t likeBlanksCommaBlans(char * str) {
char *p = str;
int32_t cnt1 = 0; // ' ' count
int32_t cnt2 = 0; // ',' count
while (*p != 0) {
if(*p == ' ')
cnt1++;
else if(*p == ',')
cnt2++;
else
return cnt2 == 0 ? 0 : cnt1 + cnt2;
p++;
}
return 0;
}
// return tbname start , put tbname end to args pe
static char *searchTBName(char *from_end, char **pend) {
char *p = from_end;
// remove pre blanks
while(*p == ' ') {
++p;
}
char *tbname = p;
if(*p == 0)
return NULL;
// goto next blank
while(1) {
p++;
if(*p == ' ') {
// if following not have , this is end
// format like select * from stb1 , stb2 , stb3 where ...
int32_t len = likeBlanksCommaBlans(p);
if(len > 0) {
p += len;
continue;
}
// tbname is end
if(pend)
*pend = p;
return tbname;
} else if(*p == ';' || *p == 0) {
// sql end flag '\0' or ';' end
if(pend)
*pend = p;
return tbname;
}
}
return NULL;
}
// return names min pointer
static inline char *searchEndPart(char *tbname_end) {
char* names[] = {
" group ",
" order ",
" interval(",
" interval (",
" session(",
" session (",
" state_window(",
" state_window (",
" slimit ",
" slimit(",
" limit ",
" limit(",
" sliding ",
" fill(",
" fill ("
" >>",
";"
};
int32_t count = sizeof(names)/sizeof(char *);
char * p = NULL;
for(int32_t i = 0; i < count; i++) {
char * p1 = strstr(tbname_end, names[i]);
if (p1) {
if (p == NULL || p1 < p)
p = p1;
}
}
if(p == NULL) {
// move string end
p = tbname_end + strlen(tbname_end);
}
return p;
}
// get brackets context and set context to pend
static inline char *bracketsString(char *select, char **pend){
char *p = select;
int32_t cnt = 0;
while (*p) {
if(*p == '(') {
// left bracket
cnt++;
} else if(*p == ')') {
// right bracket
cnt--;
}
if(cnt < 0) {
// this is end
if(pend)
*pend = p;
// copy str to new
int len = p - 1 - select;
if(len == 0)
return NULL;
len += 1; // string end
char *str = (char *)malloc(len);
strncpy(str, select, len);
str[len] = 0;
return str;
}
++p;
}
return NULL;
}
//
// return new malloc buffer, NULL is need not insert or failed tags example is 'tags=3'
// sql part :
// select * from st where age=1 order by ts;
// ------------- --- ----------- -----------
// select part tbname part condition part end part
//
static inline char *insertTags(char *sql, char *tags) {
char *p = sql;
// remove pre blanks
while(*p == ' ') {
++p;
}
// filter not query sql
if(strncmp(p, "select ", 7) != 0) {
return NULL;
}
// specail check
char *from = strstr(p, " from ");
char *block = strstr(p, " _block_dist() ");
if (from == NULL || block != NULL) {
return NULL;
}
char *select = strstr(p + 7, "select "); // sub select sql
char *union_all = strstr(p + 7, " union all ");
// need append tags filter
int32_t bufLen = strlen(sql) + 1 + TSDB_TAGS_LEN;
char *buf = malloc(bufLen);
memset(buf, 0, bufLen);
// case1 if have sub select, tags only append to sub select sql
if(select && union_all) {
// union all like select * from t1 union all select * from t2 union all select * from ....
size_t len = strlen(sql) + 10;
// part1
char *part1 = (char *)malloc(len);
memset(part1, 0, len);
strncpy(part1, p, union_all - p);
char *p1 = insertTags(part1, tags);
free(part1);
if(p1 == NULL) {
free(buf);
return NULL;
}
// part2
char *part2 = union_all + sizeof(" union all ") - 1;
char *p2 = insertTags(part2, tags);
if(p2 == NULL) {
free(buf);
free(p1);
return NULL;
}
// combine p1 + union all + p2
len = strlen(p1) + strlen(p2) + 32;
char *all = (char *)malloc(len);
strcpy(all, p1);
strcat(all, " union all ");
strcat(all, p2);
free(p1);
free(p2);
free(buf);
return all;
}
else if(select) {
char *part1_end = select - 1;
char *part2 = NULL;
char *part3_start = 0;
char *sub_sql = bracketsString(select, &part3_start);
if (sub_sql == NULL) {
// unknown format, can not insert tags
tscError("TAGS found sub select sql but can not parse brackets format. select=%s sql=%s", select, sql);
free(buf);
return NULL;
}
// nest call
part2 = insertTags(sub_sql, tags);
free(sub_sql);
if (part2 == NULL) {
// unknown format, can not insert tags
tscError("TAGS insertTags sub select sql failed. subsql=%s sql=%s", sub_sql, sql);
free(buf);
return NULL;
}
// new string is part1 + part2 + part 3
strncpy(buf, p, part1_end - p + 1);
strcat(buf, part2);
strcat(buf, part3_start);
// return ok 1
// like select * from (select * from st where age>1) where age == 2;
// after-> select * from (select * from st where (tags=3) and (age>1) ) where age == 2;
return buf;
}
char *tbname_end = NULL;
char *tbname = searchTBName(from + sizeof(" from ") - 1, &tbname_end);
if(tbname == NULL || tbname_end == NULL) {
// unexpect string format
free(buf);
return NULL;
}
// condition part
char *where = strstr(tbname_end, " where ");
char *end_part = searchEndPart(tbname_end);
if(end_part == NULL) {
// invalid sql
free(buf);
return NULL;
}
// case2 no condition part
if(where == NULL) {
strncpy(buf, p, end_part - p);
strcat(buf, " where ");
strcat(buf, tags);
strcat(buf, end_part);
// return ok 2
// like select * from st order by ts;
// after-> select * from st where tags=3 order by ts;
return buf;
}
// case3 found condition part
char *cond_part = where + sizeof("where ");
strncpy(buf, p, cond_part - p); // where before part(include where )
strcat(buf, "(");
int32_t cond_len = end_part - cond_part;
// cat cond part
strncat(buf, cond_part, cond_len);
strcat(buf, ") and (");
// cat tags part
strcat(buf, tags);
strcat(buf, ")");
// cat end part
strcat(buf, end_part);
// return ok 3
// like select * from st where age=1 order by ts;
// after-> select * from st where (age=1) and (tags=3) order by ts;
return buf;
}
// if return true success, false is not append privilege sql
bool appendTagsFilter(SSqlObj* pSql) {
// valid tags
STscObj * pTscObj = pSql->pTscObj;
if(pTscObj->tags[0] == 0) {
tscDebug("TAGS 0x%" PRIx64 " tags empty. user=%s", pSql->self, pTscObj->user);
return false;
}
char * p = insertTags(pSql->sqlstr, pTscObj->tags);
if(p == NULL) {
return false;
}
// replace new
char * old = pSql->sqlstr;
pSql->sqlstr = p;
tscDebug("TAGS 0x%" PRIx64 " replace sqlstr ok. old=%s new=%s tags=%s", pSql->self, old, p, pTscObj->tags);
free(old);
return true;
}
void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* param, const char* sqlstr, size_t sqlLen) {
SSqlCmd* pCmd = &pSql->cmd;
......@@ -58,6 +372,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
strntolower(pSql->sqlstr, sqlstr, (int32_t)sqlLen);
appendTagsFilter(pSql);
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
pCmd->resColumnId = TSDB_RES_COL_ID;
......
......@@ -862,6 +862,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
const char* msg3 = "name too long";
const char* msg5 = "invalid user rights";
const char* msg7 = "not support options";
const char* msg8 = "tags filter length must over 3 bytes.";
pCmd->command = pInfo->type;
......@@ -900,7 +901,11 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
} else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
} else {
} else if (pUser->type == TSDB_ALTER_USER_TAGS) {
SStrToken* pTags = &pUser->tags;
if(pTags->n < 4)
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8);
} else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
}
}
......@@ -10471,6 +10476,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
const char* msg7 = "derivative/twa/rate/irate/diff/tail/stateCount/stateDuration requires timestamp column exists in subquery";
const char* msg8 = "condition missing for join query";
const char* msg9 = "not support 3 level select";
const char* msg10 = "limit user forbid query normal or child table, you can query from stable.";
int32_t code = TSDB_CODE_SUCCESS;
SSqlCmd* pCmd = &pSql->cmd;
......@@ -10655,6 +10661,11 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
// if have tags, only support query on super table
if( !isSTable && pSql->pTscObj->tags[0] !=0) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg10);
}
int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY;
TSDB_QUERY_SET_TYPE(pQueryInfo->type, type);
......
......@@ -330,7 +330,7 @@ void checkBrokenQueries(STscObj *pTscObj) {
SSqlObj *pSql = pTscObj->sqlList;
while (pSql) {
// avoid sqlobj may not be correctly removed from sql list
if (pSql->sqlstr == NULL) {
if (pSql->sqlstr == NULL || pSql->signature != pSql) {
pSql = pSql->next;
continue;
}
......@@ -1475,11 +1475,15 @@ int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pAlterMsg->privilege = (char)pCmd->count;
} else if (pUser->type == TSDB_ALTER_USER_PASSWD) {
strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n);
} else if (pUser->type == TSDB_ALTER_USER_TAGS) {
// copy tags
strncpy(pAlterMsg->tags, pUser->tags.z, pUser->tags.n);
} else { // create user password info
strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n);
strncpy(pAlterMsg->tags, pUser->tags.z, pUser->tags.n);
}
if (pUser->type == TSDB_ALTER_USER_PASSWD || pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
if (pUser->type == TSDB_ALTER_USER_PASSWD || pUser->type == TSDB_ALTER_USER_PRIVILEGES || pUser->type == TSDB_ALTER_USER_TAGS) {
pCmd->msgType = TSDB_MSG_TYPE_CM_ALTER_USER;
} else {
pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_USER;
......@@ -2866,7 +2870,11 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
pObj->writeAuth = pConnect->writeAuth;
pObj->superAuth = pConnect->superAuth;
pObj->connId = htonl(pConnect->connId);
tstrncpy(pObj->clusterId, pConnect->clusterId, sizeof(pObj->clusterId));
tstrncpy(pObj->clusterId, pConnect->clusterId, sizeof(pObj->clusterId));
if (pConnect->tags[0] != 0) {
strcpy(pObj->tags, pConnect->tags);
tscInfo("TAGS client received . user=%s tags=%s", pObj->user, pObj->tags);
}
createHbObj(pObj);
......
......@@ -2168,7 +2168,9 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
int32_t code = TSDB_CODE_SUCCESS;
code = doReInitSubState(pSql, pQueryInfo->numOfTables);
assert (code == TSDB_CODE_SUCCESS && "Out of memory");
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
SJoinSupporter *pSupporter = tscCreateJoinSupporter(pSql, i);
......@@ -2226,16 +2228,23 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
}
void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs) {
assert(numOfSubs <= pSql->subState.numOfSub && numOfSubs >= 0);
pthread_mutex_lock(&pSql->subState.mutex);
if (numOfSubs > pSql->subState.numOfSub || numOfSubs <= 0 || pSql->subState.numOfSub <= 0) {
goto _out;
}
for(int32_t i = 0; i < numOfSubs; ++i) {
SSqlObj* pSub = pSql->pSubs[i];
assert(pSub != NULL);
pSql->pSubs[i] = NULL;
if (!pSub) continue;
tscFreeRetrieveSup(&pSub->param);
taos_free_result(pSub);
}
_out:
pthread_mutex_unlock(&pSql->subState.mutex);
}
void tscLockByThread(int64_t *lockedBy) {
......@@ -3349,12 +3358,12 @@ static bool needRetryInsert(SSqlObj* pParentObj, int32_t numOfSub) {
}
static void doFreeInsertSupporter(SSqlObj* pSqlObj) {
assert(pSqlObj != NULL && pSqlObj->subState.numOfSub > 0);
pthread_mutex_lock(&pSqlObj->subState.mutex);
for(int32_t i = 0; i < pSqlObj->subState.numOfSub; ++i) {
SSqlObj* pSql = pSqlObj->pSubs[i];
tfree(pSql->param);
}
pthread_mutex_unlock(&pSqlObj->subState.mutex);
}
static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) {
......
......@@ -89,6 +89,9 @@ extern const int32_t TYPE_BYTES[16];
#define TSDB_PASS_LEN 16
#define SHELL_MAX_PASSWORD_LEN 20
// user set query tags max len
#define TSDB_TAGS_LEN 256
#define TSDB_TRUE 1
#define TSDB_FALSE 0
#define TSDB_OK 0
......
......@@ -185,6 +185,7 @@ enum _mgmt_table {
#define TSDB_ALTER_USER_PASSWD 0x1
#define TSDB_ALTER_USER_PRIVILEGES 0x2
#define TSDB_ALTER_USER_TAGS 0x4
#define TSDB_KILL_MSG_LEN 30
......@@ -362,6 +363,7 @@ typedef struct {
char acctId[TSDB_ACCT_ID_LEN];
char serverVersion[TSDB_VERSION_LEN];
char clusterId[TSDB_CLUSTER_ID_LEN];
char tags[TSDB_TAGS_LEN];
int8_t writeAuth;
int8_t superAuth;
int8_t reserved1;
......@@ -400,6 +402,7 @@ typedef struct {
int8_t extend;
char user[TSDB_USER_LEN];
char pass[TSDB_PASS_LEN];
char tags[TSDB_TAGS_LEN];
int8_t privilege;
int8_t flag;
} SCreateUserMsg, SAlterUserMsg;
......
......@@ -100,42 +100,42 @@
#define TK_ALTER 82
#define TK_PASS 83
#define TK_PRIVILEGE 84
#define TK_LOCAL 85
#define TK_COMPACT 86
#define TK_LP 87
#define TK_RP 88
#define TK_IF 89
#define TK_EXISTS 90
#define TK_AS 91
#define TK_OUTPUTTYPE 92
#define TK_AGGREGATE 93
#define TK_BUFSIZE 94
#define TK_PPS 95
#define TK_TSERIES 96
#define TK_DBS 97
#define TK_STORAGE 98
#define TK_QTIME 99
#define TK_CONNS 100
#define TK_STATE 101
#define TK_COMMA 102
#define TK_KEEP 103
#define TK_CACHE 104
#define TK_REPLICA 105
#define TK_QUORUM 106
#define TK_DAYS 107
#define TK_MINROWS 108
#define TK_MAXROWS 109
#define TK_BLOCKS 110
#define TK_CTIME 111
#define TK_WAL 112
#define TK_FSYNC 113
#define TK_COMP 114
#define TK_PRECISION 115
#define TK_UPDATE 116
#define TK_CACHELAST 117
#define TK_PARTITIONS 118
#define TK_UNSIGNED 119
#define TK_TAGS 120
#define TK_TAGS 85
#define TK_LOCAL 86
#define TK_COMPACT 87
#define TK_LP 88
#define TK_RP 89
#define TK_IF 90
#define TK_EXISTS 91
#define TK_AS 92
#define TK_OUTPUTTYPE 93
#define TK_AGGREGATE 94
#define TK_BUFSIZE 95
#define TK_PPS 96
#define TK_TSERIES 97
#define TK_DBS 98
#define TK_STORAGE 99
#define TK_QTIME 100
#define TK_CONNS 101
#define TK_STATE 102
#define TK_COMMA 103
#define TK_KEEP 104
#define TK_CACHE 105
#define TK_REPLICA 106
#define TK_QUORUM 107
#define TK_DAYS 108
#define TK_MINROWS 109
#define TK_MAXROWS 110
#define TK_BLOCKS 111
#define TK_CTIME 112
#define TK_WAL 113
#define TK_FSYNC 114
#define TK_COMP 115
#define TK_PRECISION 116
#define TK_UPDATE 117
#define TK_CACHELAST 118
#define TK_PARTITIONS 119
#define TK_UNSIGNED 120
#define TK_USING 121
#define TK_TO 122
#define TK_SPLIT 123
......@@ -222,6 +222,7 @@
#define TK_VALUES 204
#define TK_FILE 205
#define TK_SPACE 300
#define TK_COMMENT 301
#define TK_ILLEGAL 302
......
......@@ -74,6 +74,7 @@ SWords shellCommands[] = {
{"alter local tmrDebugFlag 143;", 0, 0, NULL},
{"alter topic", 0, 0, NULL},
{"alter user <user_name> pass", 0, 0, NULL},
{"alter user <user_name> tags", 0, 0, NULL},
{"alter user <user_name> privilege read", 0, 0, NULL},
{"alter user <user_name> privilege write", 0, 0, NULL},
{"create table <anyword> using <stb_name> tags(", 0, 0, NULL},
......@@ -82,7 +83,7 @@ SWords shellCommands[] = {
{"create dnode ", 0, 0, NULL},
{"create topic", 0, 0, NULL},
{"create function ", 0, 0, NULL},
{"create user <anyword> pass", 0, 0, NULL},
{"create user <anyword> pass <anyword> tags", 0, 0, NULL},
{"compact vnode in", 0, 0, NULL},
{"describe <all_table>", 0, 0, NULL},
#ifdef TD_ENTERPRISE
......@@ -124,7 +125,7 @@ SWords shellCommands[] = {
{"show variables;", 0, 0, NULL},
{"show vgroups;", 0, 0, NULL},
{"insert into <tb_name> values(", 0, 0, NULL},
{"insert into <tb_name> using <stb_name> tags(", 0, 0, NULL},
{"insert into <tb_name> using <stb_name> tags( <anyword> ) values(", 0, 0, NULL},
{"use <db_name>", 0, 0, NULL},
{"quit", 0, 0, NULL}
};
......@@ -359,7 +360,8 @@ void showHelp() {
alter local resetlog; \n\
alter local DebugFlag 143; \n\
alter topic <topic_name>\n\
alter user <user_name> pass\n\
alter user <user_name> pass <password>;\n\
alter user <user_name> tags <privileges>;\n\
alter user <user_name> privilege read ;\n\
alter user <user_name> privilege write ;\n\
----- C ----- \n\
......@@ -370,6 +372,7 @@ void showHelp() {
create topic <top_name>\n\
create function <function_name>\n\
create user <user_name> pass <password>;\n\
create user <user_name> pass <password> tags <privileges>;\n\
compact vnode in (vgid,vgid,vgid);\n\
----- D ----- \n\
describe <all_table> ;\n\
......
Subproject commit 9f4c01ec83b93b2385816134071aa5e702a24079
Subproject commit e7270c90fd1888842a45d47700040d3f86ebaf5f
......@@ -202,6 +202,20 @@ typedef struct SDbObj {
pthread_mutex_t mutex;
} SDbObj;
// old tags
typedef struct SUserObjOld {
char user[TSDB_USER_LEN];
char pass[TSDB_KEY_LEN];
char acct[TSDB_USER_LEN];
int64_t createdTime;
int8_t superAuth;
int8_t writeAuth;
int8_t reserved[10];
int8_t updateEnd[4];
int32_t refCount;
struct SAcctObj * pAcct;
} SUserObjOld;
typedef struct SUserObj {
char user[TSDB_USER_LEN];
char pass[TSDB_KEY_LEN];
......@@ -210,6 +224,7 @@ typedef struct SUserObj {
int8_t superAuth;
int8_t writeAuth;
int8_t reserved[10];
char tags[TSDB_TAGS_LEN];
int8_t updateEnd[4];
int32_t refCount;
struct SAcctObj * pAcct;
......
......@@ -30,7 +30,7 @@ void mnodeIncUserRef(SUserObj *pUser);
void mnodeDecUserRef(SUserObj *pUser);
SUserObj *mnodeGetUserFromConn(void *pConn);
char * mnodeGetUserFromMsg(void *pMnodeMsg);
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg);
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, char* tags, void *pMsg);
void mnodeDropAllUsers(SAcctObj *pAcct);
int32_t mnodeCompactUsers();
......
......@@ -343,6 +343,9 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
memcpy(pConnectRsp->serverVersion, version, TSDB_VERSION_LEN);
pConnectRsp->writeAuth = pUser->writeAuth;
pConnectRsp->superAuth = pUser->superAuth;
strcpy(pConnectRsp->tags, pUser->tags);
if(pUser->tags[0])
mInfo("TAGS server response to client. user=%s tags=%s", pUser->user, pUser->tags);
mnodeGetMnodeEpSetForShell(&pConnectRsp->epSet, false);
......
......@@ -132,9 +132,9 @@ static int32_t mnodeUserActionRestored() {
if (numOfRows <= 0 && dnodeIsFirstDeploy()) {
mInfo("dnode first deploy, create root user");
SAcctObj *pAcct = mnodeGetAcct(TSDB_DEFAULT_USER);
mnodeCreateUser(pAcct, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS, NULL);
mnodeCreateUser(pAcct, "monitor", tsInternalPass, NULL);
mnodeCreateUser(pAcct, "_"TSDB_DEFAULT_USER, tsInternalPass, NULL);
mnodeCreateUser(pAcct, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS, NULL, NULL);
mnodeCreateUser(pAcct, "monitor", tsInternalPass, NULL, NULL);
mnodeCreateUser(pAcct, "_"TSDB_DEFAULT_USER, tsInternalPass, NULL, NULL);
mnodeDecAcctRef(pAcct);
}
......@@ -229,7 +229,7 @@ static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) {
return code;
}
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) {
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, char *tags, void *pMsg) {
int32_t code = acctCheck(pAcct, ACCT_GRANT_USER);
if (code != TSDB_CODE_SUCCESS) {
return code;
......@@ -259,6 +259,10 @@ int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) {
tstrncpy(pUser->user, name, TSDB_USER_LEN);
taosEncryptPass((uint8_t*) pass, strlen(pass), pUser->pass);
strcpy(pUser->acct, pAcct->user);
if (tags) {
strcpy(pUser->tags, tags);
}
pUser->createdTime = taosGetTimestampMs();
pUser->superAuth = 0;
pUser->writeAuth = 1;
......@@ -336,6 +340,14 @@ static int32_t mnodeGetUserMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
// tags
pShow->bytes[cols] = TSDB_USER_LEN + VARSTR_HEADER_SIZE;
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
strcpy(pSchema[cols].name, "tags");
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
pMeta->numOfColumns = htons(cols);
strcpy(pMeta->tableFname, "show users");
pShow->numOfColumns = cols;
......@@ -417,6 +429,11 @@ static int32_t mnodeRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, voi
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->acct, pShow->bytes[cols]);
cols++;
// tags
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->tags, pShow->bytes[cols]);
cols++;
numOfRows++;
mnodeDecUserRef(pUser);
}
......@@ -450,7 +467,7 @@ static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) {
if (pOperUser->superAuth) {
SCreateUserMsg *pCreate = pMsg->rpcMsg.pCont;
return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pMsg);
return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pCreate->tags, pMsg);
} else {
mError("user:%s, no rights to create user", pOperUser->user);
return TSDB_CODE_MND_NO_RIGHTS;
......@@ -536,6 +553,36 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
mError("user:%s, no rights to alter user", pOperUser->user);
code = TSDB_CODE_MND_NO_RIGHTS;
}
// ALTER TAGS
} else if ((pAlter->flag & TSDB_ALTER_USER_TAGS) != 0) {
// check has right
bool hasRight = false;
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
hasRight = false;
} else if (strcmp(pUser->user, pUser->acct) == 0) {
hasRight = false;
} else if (strcmp(pOperUser->user, TSDB_DEFAULT_USER) == 0) {
hasRight = true;
} else if (strcmp(pUser->user, pOperUser->user) == 0) {
hasRight = false;
} else if (pOperUser->superAuth) {
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
hasRight = false;
} else if (strcmp(pOperUser->acct, pUser->acct) != 0) {
hasRight = false;
} else {
hasRight = true;
}
}
// set tags new values
if (hasRight) {
strcpy(pUser->tags, pAlter->tags);
code = mnodeUpdateUser(pUser, pMsg);
} else {
mError("user:%s, no rights to alter user tags", pOperUser->user);
code = TSDB_CODE_MND_NO_RIGHTS;
}
} else {
mError("user:%s, no rights to alter user", pOperUser->user);
code = TSDB_CODE_MND_NO_RIGHTS;
......
......@@ -92,6 +92,7 @@ typedef struct SResultRow {
char *key; // start key of current result row
SHashObj *uniqueHash; // for unique function
SHashObj *modeHash; // for unique function
int32_t groupIndex; // index in group result
} SResultRow;
typedef struct SResultRowCell {
......
......@@ -235,6 +235,7 @@ typedef struct SShowInfo {
typedef struct SUserInfo {
SStrToken user;
SStrToken passwd;
SStrToken tags; // format like tag1,tag2,tag3 ... splite with ','
SStrToken privilege;
int16_t type;
} SUserInfo;
......@@ -358,9 +359,9 @@ void setShowOptions(SSqlInfo *pInfo, int32_t type, SStrToken* prefix, SStrToken*
void setCreateDbInfo(SSqlInfo *pInfo, int32_t type, SStrToken *pToken, SCreateDbInfo *pDB, SStrToken *pIgExists);
void setCreateAcctSql(SSqlInfo *pInfo, int32_t type, SStrToken *pName, SStrToken *pPwd, SCreateAcctInfo *pAcctInfo);
void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd);
void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd, SStrToken *pTags);
void setKillSql(SSqlInfo *pInfo, int32_t type, SStrToken *ip);
void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* pPwd, SStrToken *pPrivilege);
void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* pPwd, SStrToken *pPrivilege, SStrToken *pTags);
void setCompactVnodeSql(SSqlInfo *pInfo, int32_t type, SArray *pParam);
......
......@@ -161,8 +161,9 @@ cmd ::= DESC ids(X) cpxName(Y). {
setDCLSqlElems(pInfo, TSDB_SQL_DESCRIBE_TABLE, 1, &X);
}
/////////////////////////////////THE ALTER STATEMENT////////////////////////////////////////
cmd ::= ALTER USER ids(X) PASS ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PASSWD, &X, &Y, NULL); }
cmd ::= ALTER USER ids(X) PRIVILEGE ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PRIVILEGES, &X, NULL, &Y);}
cmd ::= ALTER USER ids(X) PASS ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PASSWD, &X, &Y, NULL, NULL);}
cmd ::= ALTER USER ids(X) PRIVILEGE ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PRIVILEGES, &X, NULL, &Y, NULL);}
cmd ::= ALTER USER ids(X) TAGS ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_TAGS, &X, NULL, NULL, &Y);}
cmd ::= ALTER DNODE ids(X) ids(Y). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_DNODE, 2, &X, &Y); }
cmd ::= ALTER DNODE ids(X) ids(Y) ids(Z). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_DNODE, 3, &X, &Y, &Z); }
cmd ::= ALTER LOCAL ids(X). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_LOCAL, 1, &X); }
......@@ -201,7 +202,8 @@ cmd ::= CREATE DATABASE ifnotexists(Z) ids(X) db_optr(Y). { setCreateDbInfo(pIn
cmd ::= CREATE TOPIC ifnotexists(Z) ids(X) topic_optr(Y). { setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &X, &Y, &Z);}
cmd ::= CREATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B). { setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &X, &Y, &Z, &B, 1);}
cmd ::= CREATE AGGREGATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B). { setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &X, &Y, &Z, &B, 2);}
cmd ::= CREATE USER ids(X) PASS ids(Y). { setCreateUserSql(pInfo, &X, &Y);}
cmd ::= CREATE USER ids(X) PASS ids(Y). { setCreateUserSql(pInfo, &X, &Y, NULL);}
cmd ::= CREATE USER ids(X) PASS ids(Y) TAGS ids(Z). { setCreateUserSql(pInfo, &X, &Y, &Z);}
bufsize(Y) ::= . { Y.n = 0; }
bufsize(Y) ::= BUFSIZE INTEGER(X). { Y = X; }
......
此差异已折叠。
......@@ -1473,7 +1473,19 @@ void setCompactVnodeSql(SSqlInfo *pInfo, int32_t type, SArray *pParam) {
pInfo->list = pParam;
}
void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd) {
bool removeSingleQuota(SStrToken* pStr) {
char * p1 = pStr->z;
char * p2 = pStr->z + pStr->n - 1;
if (pStr->n > 2 && *p1 == '\'' && *p2 == '\'') {
pStr->z ++;
pStr->n -= 2;
return true;
}
return false;
}
void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd, SStrToken *pTags) {
pInfo->type = TSDB_SQL_CREATE_USER;
if (pInfo->pMiscInfo == NULL) {
pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo));
......@@ -1483,9 +1495,14 @@ void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd) {
pInfo->pMiscInfo->user.user = *pName;
pInfo->pMiscInfo->user.passwd = *pPasswd;
// set tags if have
if (pTags) {
pInfo->pMiscInfo->user.tags = *pTags;
removeSingleQuota(&pInfo->pMiscInfo->user.tags);
}
}
void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* pPwd, SStrToken *pPrivilege) {
void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* pPwd, SStrToken *pPrivilege, SStrToken *pTags) {
pInfo->type = TSDB_SQL_ALTER_USER;
if (pInfo->pMiscInfo == NULL) {
pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo));
......@@ -1508,6 +1525,14 @@ void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken*
} else {
pUser->privilege.type = TSDB_DATA_TYPE_NULL;
}
// tags
if (pTags != NULL) {
pUser->tags = *pTags;
removeSingleQuota(&pUser->tags);
} else {
pUser->tags.type = TSDB_DATA_TYPE_NULL;
}
}
void setKillSql(SSqlInfo *pInfo, int32_t type, SStrToken *id) {
......
此差异已折叠。
......@@ -611,7 +611,6 @@ void taosHashClear(SHashObj *pHashObj) {
for (int32_t i = 0; i < pHashObj->capacity; ++i) {
SHashEntry *pEntry = pHashObj->hashList[i];
if (pEntry->num == 0) {
assert(pEntry->next == NULL);
continue;
}
......
......@@ -13,6 +13,7 @@
import sys
import taos
import numpy as np
from util.log import tdLog
from util.cases import tdCases
from util.sql import tdSql
......@@ -162,6 +163,39 @@ class TDTestCase:
tdSql.error("select twa(c) from tb group by c")
# TD-14678
tdSql.execute("create database test4")
tdSql.execute("use test4")
tdSql.execute("create table stb(ts timestamp, c int) tags(t1 int)")
ts = 1630000000000
sql = "insert into t1 using stb tags(1) values"
for i in range(100):
sql += "(%d, %d)" % (ts + i * 1000, i % 100)
tdSql.execute(sql)
tdSql.query("select COUNT(*) from stb interval(13m) sliding(3m) group by tbname order by ts desc")
tdSql.checkData(0, 1, 20)
tdSql.checkData(1, 1, 100)
tdSql.checkData(2, 1, 100)
tdSql.checkData(3, 1, 100)
tdSql.checkData(4, 1, 100)
tdSql.query("select COUNT(*) from stb interval(13m) sliding(3m) group by tbname order by ts")
tdSql.checkData(0, 1, 100)
tdSql.checkData(1, 1, 100)
tdSql.checkData(2, 1, 100)
tdSql.checkData(3, 1, 100)
tdSql.checkData(4, 1, 20)
# TD-14698
tdSql.query("select SPREAD(_c0) from (select * from stb) where ts between 1630000001000 and 1630100001000 interval(12h) Fill(NULL) order by ts")
matrix = np.array(tdSql.queryResult)
list = matrix[:, 0]
if all(sorted(list) == list):
tdLog.info("sql:%s, column : ts is sorted in accending order as expected" % (tdSql.sql))
else:
tdLog.exit("sql:%s, column : ts is not sorted in accending order as expected" % (tdSql.sql))
def stop(self):
tdSql.close()
......
......@@ -121,6 +121,9 @@ class TDTestCase:
tdSql.query("select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id")
tdSql.checkRows(6)
tdSql.query("select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id order by ts desc limit 1 offset 1")
tdSql.checkRows(1)
tdSql.error("select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.pid, stb_p.id, stb_p.dscrption, stb_p.pressure,stb_v.velocity from stb_p, stb_t, stb_v where stb_p.ts=stb_t.ts and stb_p.ts=stb_v.ts and stb_p.id = stb_t.id")
# test case for https://jira.taosdata.com:18080/browse/TD-1250
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册