未验证 提交 ff1e30f2 编写于 作者: S shenglian-zhou 提交者: GitHub

Merge branch '2.6' into szhou/2.6/fixbugs

......@@ -16,7 +16,7 @@ class MockDataSource implements Iterator {
private int currentTbId = -1;
// mock values
String[] location = {"LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"};
String[] location = {"California.LosAngeles", "California.SanDiego", "California.SanJose", "California.Campbell", "California.SanFrancisco"};
float[] current = {8.8f, 10.7f, 9.9f, 8.9f, 9.4f};
int[] voltage = {119, 116, 111, 113, 118};
float[] phase = {0.32f, 0.34f, 0.33f, 0.329f, 0.141f};
......@@ -50,4 +50,4 @@ class MockDataSource implements Iterator {
return sb.toString();
}
}
\ No newline at end of file
}
......@@ -42,7 +42,7 @@ def get_connection():
# ANCHOR: MockDataSource
class MockDataSource:
location = ["LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"]
location = ["California.LosAngeles", "California.SanDiego", "California.SanJose", "California.Campbell", "California.SanFrancisco"]
current = [8.8, 10.7, 9.9, 8.9, 9.4]
voltage = [119, 116, 111, 113, 118]
phase = [0.32, 0.34, 0.33, 0.329, 0.141]
......
......@@ -3,11 +3,11 @@ import time
class MockDataSource:
samples = [
"8.8,119,0.32,LosAngeles,0",
"10.7,116,0.34,SanDiego,1",
"9.9,111,0.33,Hollywood,2",
"8.9,113,0.329,Compton,3",
"9.4,118,0.141,San Francisco,4"
"8.8,119,0.32,California.LosAngeles,0",
"10.7,116,0.34,California.SanDiego,1",
"9.9,111,0.33,California.SanJose,2",
"8.9,113,0.329,California.Campbell,3",
"9.4,118,0.141,California.SanFrancisco,4"
]
def __init__(self, tb_name_prefix, table_count):
......
......@@ -132,7 +132,7 @@ Query OK, 2 row(s) in set (0.003128s)
taosBenchmark
```
该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "San Francisco" 或者 "Los Angeles"等城市名称。
该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "California.SanFrancisco" 或者 "California.LosAngeles"等城市名称。
这条命令很快完成 1 亿条记录的插入。具体时间取决于硬件性能,即使在一台普通的 PC 服务器往往也仅需十几秒。
......@@ -154,10 +154,10 @@ taos> select count(*) from test.meters;
taos> select avg(current), max(voltage), min(phase) from test.meters;
```
查询 location="San Francisco" 的记录总条数:
查询 location="California.SanFrancisco" 的记录总条数:
```sql
taos> select count(*) from test.meters where location="San Francisco";
taos> select count(*) from test.meters where location="California.SanFrancisco";
```
查询 groupId=10 的所有记录的平均值、最大值、最小值等:
......
......@@ -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;
......@@ -60,6 +374,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;
......
......@@ -1261,8 +1261,6 @@ static void insertBatchClean(STscStmt* pStmt) {
taosHashClear(pCmd->insertParam.pTableBlockHashList);
tscFreeSqlResult(pSql);
tscFreeSubobj(pSql);
tfree(pSql->pSubs);
pSql->subState.numOfSub = 0;
}
static int insertBatchStmtExecute(STscStmt* pStmt) {
......
......@@ -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);
......@@ -3392,7 +3400,6 @@ int tscRenewTableMeta(SSqlObj *pSql) {
pthread_mutex_lock(&rootSql->mtxSubs);
tscFreeSubobj(rootSql);
pthread_mutex_unlock(&rootSql->mtxSubs);
tfree(rootSql->pSubs);
tscResetSqlCmd(&rootSql->cmd, true, rootSql->self);
code = getMultiTableMetaFromMnode(rootSql, pNameList, vgroupList, NULL, tscTableMetaCallBack, true);
......
......@@ -232,8 +232,6 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
tscFreeSqlResult(pStream->pSql);
tscFreeSubobj(pStream->pSql);
tfree(pStream->pSql->pSubs);
pStream->pSql->subState.numOfSub = 0;
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
tscSetRetryTimer(pStream, pStream->pSql, retryDelay);
......@@ -610,8 +608,6 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
tscFreeSqlResult(pSql);
tscFreeSubobj(pSql);
tfree(pSql->pSubs);
pSql->subState.numOfSub = 0;
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
tscSetNextLaunchTimer(pStream, pSql);
}
......
......@@ -695,6 +695,12 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
}
void freeJoinSubqueryObj(SSqlObj* pSql) {
if (pSql->subState.numOfSub == 0) {
return;
}
pthread_mutex_lock(&pSql->subState.mutex);
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
SSqlObj* pSub = pSql->pSubs[i];
if (pSub == NULL) {
......@@ -707,13 +713,13 @@ void freeJoinSubqueryObj(SSqlObj* pSql) {
taos_free_result(pSub);
pSql->pSubs[i] = NULL;
}
if (pSql->subState.states) {
pthread_mutex_destroy(&pSql->subState.mutex);
}
tfree(pSql->subState.states);
pSql->subState.numOfSub = 0;
pthread_mutex_unlock(&pSql->subState.mutex);
pthread_mutex_destroy(&pSql->subState.mutex);
}
static int32_t quitAllSubquery(SSqlObj* pSqlSub, SSqlObj* pSqlObj, SJoinSupporter* pSupporter) {
......@@ -901,7 +907,6 @@ bool tscReparseSql(SSqlObj *sql, int32_t code){
}
tscFreeSubobj(sql);
tfree(sql->pSubs);
sql->res.code = TSDB_CODE_SUCCESS;
sql->retry++;
......@@ -2180,7 +2185,6 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
assert((pQueryInfo->type & TSDB_QUERY_TYPE_SUBQUERY) == 0);
int32_t code = TSDB_CODE_SUCCESS;
pSql->subState.numOfSub = pQueryInfo->numOfTables;
if (pSql->subState.states == NULL) {
pSql->subState.states = calloc(pSql->subState.numOfSub, sizeof(*pSql->subState.states));
......@@ -2192,6 +2196,8 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
pthread_mutex_init(&pSql->subState.mutex, NULL);
}
pSql->subState.numOfSub = pQueryInfo->numOfTables;
memset(pSql->subState.states, 0, sizeof(*pSql->subState.states) * pSql->subState.numOfSub);
tscDebug("0x%"PRIx64" reset all sub states to 0, start subquery, total:%d", pSql->self, pQueryInfo->numOfTables);
......@@ -2251,7 +2257,12 @@ 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) {
pthread_mutex_unlock(&pSql->subState.mutex);
return;
}
for(int32_t i = 0; i < numOfSubs; ++i) {
SSqlObj* pSub = pSql->pSubs[i];
......@@ -2261,6 +2272,7 @@ void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs) {
taos_free_result(pSub);
}
pthread_mutex_unlock(&pSql->subState.mutex);
}
void tscLockByThread(int64_t *lockedBy) {
......@@ -2365,8 +2377,10 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
if (code != TSDB_CODE_SUCCESS) {
tscFreeFirstRoundSup(&param);
taos_free_result(pSql);
pthread_mutex_lock(&pParent->subState.mutex);
pParent->subState.numOfSub = 0;
tfree(pParent->pSubs);
pthread_mutex_unlock(&pParent->subState.mutex);
pParent->res.code = code;
tscAsyncResultOnError(pParent);
return;
......@@ -2469,9 +2483,11 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
tscFreeFirstRoundSup(&param);
taos_free_result(pSql);
pthread_mutex_lock(&pParent->subState.mutex);
pParent->subState.numOfSub = 0;
tfree(pParent->pSubs);
pthread_mutex_unlock(&pParent->subState.mutex);
if (resRows == 0) {
pParent->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
(*pParent->fp)(pParent->param, pParent, 0);
......@@ -2493,8 +2509,10 @@ void tscFirstRoundCallback(void* param, TAOS_RES* tres, int code) {
tscFreeFirstRoundSup(&param);
taos_free_result(pSql);
pthread_mutex_lock(&parent->subState.mutex);
parent->subState.numOfSub = 0;
tfree(parent->pSubs);
pthread_mutex_unlock(&parent->subState.mutex);
parent->res.code = c;
tscAsyncResultOnError(parent);
return;
......@@ -3014,7 +3032,6 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
}
tscFreeSubobj(userSql);
tfree(userSql->pSubs);
userSql->res.code = TSDB_CODE_SUCCESS;
userSql->retry++;
......@@ -3382,7 +3399,9 @@ static bool needRetryInsert(SSqlObj* pParentObj, int32_t numOfSub) {
}
static void doFreeInsertSupporter(SSqlObj* pSqlObj) {
assert(pSqlObj != NULL && pSqlObj->subState.numOfSub > 0);
if (pSqlObj == NULL || pSqlObj->subState.numOfSub <= 0) {
return;
}
for(int32_t i = 0; i < pSqlObj->subState.numOfSub; ++i) {
SSqlObj* pSql = pSqlObj->pSubs[i];
......
......@@ -1682,6 +1682,8 @@ void tscFreeSubobj(SSqlObj* pSql) {
return;
}
pthread_mutex_lock(&pSql->subState.mutex);
tscDebug("0x%"PRIx64" start to free sub SqlObj, numOfSub:%d", pSql->self, pSql->subState.numOfSub);
for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
......@@ -1695,12 +1697,14 @@ void tscFreeSubobj(SSqlObj* pSql) {
pSql->pSubs[i] = NULL;
}
if (pSql->subState.states) {
pthread_mutex_destroy(&pSql->subState.mutex);
}
tfree(pSql->subState.states);
pSql->subState.numOfSub = 0;
tfree(pSql->pSubs);
pthread_mutex_unlock(&pSql->subState.mutex);
pthread_mutex_destroy(&pSql->subState.mutex);
}
/**
......@@ -1768,9 +1772,6 @@ void tscFreeSqlObj(SSqlObj* pSql) {
pSql->fp = NULL;
tfree(pSql->sqlstr);
tfree(pSql->pBuf);
tfree(pSql->pSubs);
pSql->subState.numOfSub = 0;
pSql->self = 0;
tscFreeSqlResult(pSql);
......@@ -4161,10 +4162,7 @@ static void tscSubqueryCompleteCallback(void* param, TAOS_RES* tres, int code) {
}
tscFreeSubobj(pParentSql);
tfree(pParentSql->pSubs);
tscFreeSubobj(rootObj);
tfree(rootObj->pSubs);
rootObj->res.code = TSDB_CODE_SUCCESS;
rootObj->retry++;
......@@ -4207,19 +4205,9 @@ static void tscSubqueryCompleteCallback(void* param, TAOS_RES* tres, int code) {
int32_t doInitSubState(SSqlObj* pSql, int32_t numOfSubqueries) {
//bug fix. Above doInitSubState level, the loop invocation with the same SSqlObj will be fail.
//assert(pSql->subState.numOfSub == 0 && pSql->pSubs == NULL && pSql->subState.states == NULL);
if(pSql->pSubs) {
free(pSql->pSubs);
pSql->pSubs = NULL;
}
if(pSql->subState.states) {
free(pSql->subState.states);
pSql->subState.states = NULL;
}
pSql->subState.numOfSub = numOfSubqueries;
tscFreeSubobj(pSql);
pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES);
pSql->pSubs = calloc(numOfSubqueries, POINTER_BYTES);
pSql->subState.states = calloc(pSql->subState.numOfSub, sizeof(int8_t));
int32_t code = pthread_mutex_init(&pSql->subState.mutex, NULL);
......@@ -4227,6 +4215,8 @@ int32_t doInitSubState(SSqlObj* pSql, int32_t numOfSubqueries) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
pSql->subState.numOfSub = numOfSubqueries;
return TSDB_CODE_SUCCESS;
}
......@@ -4332,6 +4322,7 @@ void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) {
return;
_error:
for(int32_t i = 0; i < numOfInit; ++i) {
SSqlObj* p = pSql->pSubs[i];
tscFreeSqlObj(p);
......@@ -4616,16 +4607,7 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) {
pRes->final = finalBk;
pRes->numOfTotal = num;
pthread_mutex_lock(&pSql->subState.mutex);
for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
taos_free_result(pSql->pSubs[i]);
}
tfree(pSql->pSubs);
tfree(pSql->subState.states);
pSql->subState.numOfSub = 0;
pthread_mutex_unlock(&pSql->subState.mutex);
pthread_mutex_destroy(&pSql->subState.mutex);
tscFreeSubobj(pSql);
pSql->fp = fp;
......
......@@ -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 2dba49cf57cde998f768bb033619b4d8c5143127
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;
......
......@@ -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; }
......
......@@ -3158,23 +3158,42 @@ static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlock
}
}
} else {
getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w);
int64_t ekey = pBlockInfo->window.ekey;
getAlignQueryTimeWindow(pQueryAttr, ekey, sk, ek, &w);
assert(w.skey <= pBlockInfo->window.ekey);
if (w.skey > pBlockInfo->window.skey) {
return true;
}
while (1) {
getNextTimeWindow(pQueryAttr, &w);
while(w.skey < pBlockInfo->window.ekey) {
// add one slding
if (pQueryAttr->interval.slidingUnit == 'n' || pQueryAttr->interval.slidingUnit == 'y')
ekey = taosTimeAdd(ekey, pQueryAttr->interval.sliding, pQueryAttr->interval.slidingUnit, pQueryAttr->precision);
else
ekey += pQueryAttr->interval.sliding;
// not in range sk~ek, break
if (!(ekey >= sk && ekey <= ek)) {
break;
}
// get align
getAlignQueryTimeWindow(pQueryAttr, ekey, sk, ek, &w);
}
while(1) {
if (w.ekey < pBlockInfo->window.skey) {
break;
}
assert(w.skey < pBlockInfo->window.skey);
if (w.ekey < pBlockInfo->window.ekey && w.ekey >= pBlockInfo->window.skey) {
// window start point in block window range return true
if (w.skey >= pBlockInfo->window.skey && w.skey <= pBlockInfo->window.ekey) {
return true;
}
// window end point in block window ragne return true
if (w.ekey <= pBlockInfo->window.ekey && w.ekey >= pBlockInfo->window.skey) {
return true;
}
getNextTimeWindow(pQueryAttr, &w);
}
}
......@@ -6313,15 +6332,19 @@ SOperatorInfo* createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI
goto _clean;
}
for (int32_t i = 0; i < numOfOutput; ++i) {
SColumnInfoData col = {{0}};
col.info.colId = pExpr[i].base.colInfo.colId;
col.info.bytes = pExpr[i].base.resBytes;
col.info.type = pExpr[i].base.resType;
taosArrayPush(pDataBlock->pDataBlock, &col);
if (col.info.colId == pOrderVal->orderColId) {
pInfo->colIndex = i;
bool found = false;
for (int32_t i = 0; i < numOfOutput; ++i) {
SColumnInfoData col = {{0}};
col.info.colId = pExpr[i].base.colInfo.colId;
col.info.bytes = pExpr[i].base.resBytes;
col.info.type = pExpr[i].base.resType;
taosArrayPush(pDataBlock->pDataBlock, &col);
if (!found && col.info.colId == pOrderVal->orderColId) {
pInfo->colIndex = i;
found = true;
}
}
}
......@@ -10140,8 +10163,8 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
pTableqinfo->pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES);
pTableqinfo->numOfTables = pTableGroupInfo->numOfTables;
pTableqinfo->map =
taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
pTableqinfo->map = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
}
pQInfo->pBuf = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
......@@ -10342,10 +10365,13 @@ static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) {
}
taosArrayDestroy(&pTableqinfoGroupInfo->pGroupList);
taosHashCleanup(pTableqinfoGroupInfo->map);
SHashObj *pmap = pTableqinfoGroupInfo->map;
if (pmap == atomic_val_compare_exchange_ptr(&pTableqinfoGroupInfo->map, pmap, NULL)) {
taosHashCleanup(pmap);
}
pTableqinfoGroupInfo->pGroupList = NULL;
pTableqinfoGroupInfo->map = NULL;
pTableqinfoGroupInfo->numOfTables = 0;
}
......
......@@ -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;
}
......
......@@ -22,9 +22,9 @@ from util.dnodes import *
class TDTestCase:
def caseDescription(self):
'''
"""
[TD-13823] taosBenchmark test cases
'''
"""
return
def init(self, conn, logSql):
......@@ -34,19 +34,19 @@ class TDTestCase:
def getPath(self, tool="taosBenchmark"):
selfPath = os.path.dirname(os.path.realpath(__file__))
if ("community" in selfPath):
projPath = selfPath[:selfPath.find("community")]
if "community" in selfPath:
projPath = selfPath[: selfPath.find("community")]
else:
projPath = selfPath[:selfPath.find("tests")]
projPath = selfPath[: selfPath.find("tests")]
paths = []
for root, dirs, files in os.walk(projPath):
if ((tool) in files):
if (tool) in files:
rootRealPath = os.path.dirname(os.path.realpath(root))
if ("packaging" not in rootRealPath):
if "packaging" not in rootRealPath:
paths.append(os.path.join(root, tool))
break
if (len(paths) == 0):
if len(paths) == 0:
tdLog.exit("taosBenchmark not found!")
return
else:
......@@ -55,7 +55,7 @@ class TDTestCase:
def run(self):
binPath = self.getPath()
cmd = "%s -n 100 -t 100 -y" %binPath
cmd = "%s -n 100 -t 100 -y" % binPath
tdLog.info("%s" % cmd)
os.system("%s" % cmd)
tdSql.execute("use test")
......@@ -77,14 +77,16 @@ class TDTestCase:
tdSql.checkData(4, 3, "TAG")
tdSql.checkData(5, 0, "location")
tdSql.checkData(5, 1, "BINARY")
tdSql.checkData(5, 2, 16)
tdSql.checkData(5, 2, 24)
tdSql.checkData(5, 3, "TAG")
tdSql.query("select count(*) from test.meters where groupid >= 0")
tdSql.checkData(0, 0, 10000)
tdSql.query("select count(*) from test.meters where location = 'San Francisco' or location = 'Los Angles' or location = 'San Diego' or location = 'San Jose' or \
location = 'Palo Alto' or location = 'Campbell' or location = 'Mountain View' or location = 'Sunnyvale' or location = 'Santa Clara' or location = 'Cupertino' ")
tdSql.query(
"select count(*) from test.meters where location = 'California.SanFrancisco' or location = 'California.LosAngles' or location = 'California.SanDiego' or location = 'California.SanJose' or \
location = 'California.PaloAlto' or location = 'California.Campbell' or location = 'California.MountainView' or location = 'California.Sunnyvale' or location = 'California.SantaClara' or location = 'California.Cupertino' "
)
tdSql.checkData(0, 0, 10000)
def stop(self):
......@@ -93,4 +95,4 @@ class TDTestCase:
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
\ No newline at end of file
tdCases.addLinux(__file__, TDTestCase())
......@@ -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.
先完成此消息的编辑!
想要评论请 注册