From fa36001c9f767b6a998338aa254dcd4e0b9b414b Mon Sep 17 00:00:00 2001 From: "chao.feng" Date: Tue, 1 Aug 2023 17:32:06 +0800 Subject: [PATCH 01/16] add CI test case for ts-3479 by charles --- .../0-others/user_privilege_multi_users.py | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 tests/system-test/0-others/user_privilege_multi_users.py diff --git a/tests/system-test/0-others/user_privilege_multi_users.py b/tests/system-test/0-others/user_privilege_multi_users.py new file mode 100644 index 0000000000..8812f42e7b --- /dev/null +++ b/tests/system-test/0-others/user_privilege_multi_users.py @@ -0,0 +1,126 @@ +from itertools import product +import taos +import random +from taos.tmq import * +from util.cases import * +from util.common import * +from util.log import * +from util.sql import * +from util.sqlset import * + + +class TDTestCase: + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug("start to execute %s" % __file__) + # init the tdsql + tdSql.init(conn.cursor()) + self.setsql = TDSetSql() + # user info + self.userNum = 100 + self.basic_username = "user" + self.password = "pwd" + + # db info + self.dbname = "user_privilege_multi_users" + self.stbname = 'stb' + self.ctbname_num = 100 + self.column_dict = { + 'ts': 'timestamp', + 'col1': 'float', + 'col2': 'int', + } + self.tag_dict = { + 'ctbname': 'binary(10)' + } + + self.privilege_list = [] + + def prepare_data(self): + """Create the db and data for test + """ + # create datebase + tdSql.execute(f"create database {self.dbname}") + tdLog.debug("sql:" + f"create database {self.dbname}") + tdSql.execute(f"use {self.dbname}") + tdLog.debug("sql:" + f"use {self.dbname}") + + # create super table + tdSql.execute(self.setsql.set_create_stable_sql(self.stbname, self.column_dict, self.tag_dict)) + tdLog.debug("Create stable {} successfully".format(self.stbname)) + for ctbIndex in range(self.ctbname_num): + ctname = f"ctb{ctbIndex}" + tdSql.execute(f"create table {ctname} using {self.stbname} tags('{ctname}')") + tdLog.debug("sql:" + f"create table {ctname} using {self.stbname} tags('{ctname}')") + + def create_multiusers(self): + """Create the user for test + """ + for userIndex in range(self.userNum): + username = f"{self.basic_username}{userIndex}" + tdSql.execute(f'create user {username} pass "{self.password}"') + tdLog.debug("sql:" + f'create user {username} pass "{self.password}"') + + def grant_privilege(self): + """Add the privilege for the users + """ + try: + for userIndex in range(self.userNum): + username = f"{self.basic_username}{userIndex}" + privilege = random.choice(["read", "write", "all"]) + condition = f"ctbname='ctb{userIndex}'" + self.privilege_list.append({ + "username": username, + "privilege": privilege, + "condition": condition + }) + tdSql.execute(f'grant {privilege} on {self.dbname}.{self.stbname} with {condition} to {username}') + tdLog.debug("sql:" + f'grant {privilege} on {self.dbname}.{self.stbname} with {condition} to {username}') + except Exception as ex: + tdLog.exit(ex) + + def remove_privilege(self): + """Remove the privilege for the users + """ + try: + for item in self.privilege_list: + username = item["username"] + privilege = item["privilege"] + condition = item["condition"] + tdSql.execute(f'revoke {privilege} on {self.dbname}.{self.stbname} with {condition} from {username}') + tdLog.debug("sql:" + f'revoke {privilege} on {self.dbname}.{self.stbname} with {condition} from {username}') + except Exception as ex: + tdLog.exit(ex) + + def run(self): + """ + Check the information from information_schema.ins_user_privileges + """ + self.create_multiusers() + self.prepare_data() + # grant privilege to users + self.grant_privilege() + # check information_schema.ins_user_privileges + tdSql.query("select * from information_schema.ins_user_privileges;") + tdLog.debug("Current information_schema.ins_user_privileges values: {}".format(tdSql.queryResult)) + if len(tdSql.queryResult) >= self.userNum: + tdLog.debug("case passed") + else: + tdLog.exit("The privilege number in information_schema.ins_user_privileges is incorrect") + + def stop(self): + # remove the privilege + self.remove_privilege() + # clear env + tdSql.execute(f"drop database {self.dbname}") + # remove the users + for userIndex in range(self.userNum): + username = f"{self.basic_username}{userIndex}" + tdSql.execute(f'drop user {username}') + # close the connection + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) From 973bb073a2ec804847531a83e0778aa9d8063328 Mon Sep 17 00:00:00 2001 From: slzhou Date: Thu, 27 Jul 2023 09:07:13 +0800 Subject: [PATCH 02/16] enhance: subquery can use expr primary key +/- value as primary key --- source/libs/parser/src/parTranslater.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 8ce68a5c8c..554dc7cce8 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -821,7 +821,19 @@ static bool isPrimaryKeyImpl(SNode* pExpr) { FUNCTION_TYPE_IROWTS == pFunc->funcType) { return true; } - } + } else if (QUERY_NODE_OPERATOR == nodeType(pExpr)) { + SOperatorNode* pOper = (SOperatorNode*)pExpr; + if (OP_TYPE_ADD != pOper->opType && OP_TYPE_SUB != pOper->opType) { + return false; + } + if (!isPrimaryKeyImpl(pOper->pLeft)) { + return false; + } + if (QUERY_NODE_VALUE != nodeType(pOper->pRight)) { + return false; + } + return true; + } return false; } From d3a9429c3b5ad4c69bbdec2e305b824d511d80ea Mon Sep 17 00:00:00 2001 From: slzhou Date: Fri, 4 Aug 2023 14:17:18 +0800 Subject: [PATCH 03/16] fix: add test case --- tests/parallel_test/cases.task | 1 + tests/script/tsim/query/join_pk.sim | 42 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/script/tsim/query/join_pk.sim diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 89572d1c06..1883a50e59 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -954,6 +954,7 @@ ,,n,script,./test.sh -f tsim/query/udfpy.sim ,,y,script,./test.sh -f tsim/query/udf_with_const.sim ,,y,script,./test.sh -f tsim/query/join_interval.sim +,,y,script,./test.sh -f tsim/query/join_pk.sim ,,y,script,./test.sh -f tsim/query/unionall_as_table.sim ,,y,script,./test.sh -f tsim/query/multi_order_by.sim ,,y,script,./test.sh -f tsim/query/sys_tbname.sim diff --git a/tests/script/tsim/query/join_pk.sim b/tests/script/tsim/query/join_pk.sim new file mode 100644 index 0000000000..66bb20da24 --- /dev/null +++ b/tests/script/tsim/query/join_pk.sim @@ -0,0 +1,42 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sql connect + +sql create database test; +sql use test; +sql create table st(ts timestamp, f int) tags(t int); +sql insert into ct1 using st tags(1) values(now, 0)(now+1s, 1) +sql insert into ct2 using st tags(2) values(now+2s, 2)(now+3s, 3) +sql select * from (select _wstart - 1s as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +if $rows != 3 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data11 != 1 then + return -1 +endi + +if $data21 != 1 then + return -1 +endi +if $data03 != 1 then + return -1 +endi + +if $data13 != 1 then + return -1 +endi +if $data23 != 1 then + return -1 +endi +sql select * from (select _wstart - 1d as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +sql select * from (select _wstart + 1a as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +sql_error select * from (select _wstart * 3 as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts +#system sh/exec.sh -n dnode1 -s stop -x SIGINT + From 5154d0e1a3a23eb79b2446e02e428b36cdbdfccc Mon Sep 17 00:00:00 2001 From: Shungang Li Date: Fri, 4 Aug 2023 17:24:35 +0800 Subject: [PATCH 04/16] fix: alter ttlChangeOnWrite note info --- source/dnode/mnode/impl/src/mndDnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 1f566b14c7..234e81a670 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -41,7 +41,7 @@ static const char *offlineReason[] = { "timezone not match", "locale not match", "charset not match", - "ttl change on write not match" + "ttlChangeOnWrite not match", "unknown", }; From 4b137f1ca0e65c7d583d8515fb9aa8f4a0d817cc Mon Sep 17 00:00:00 2001 From: jiacy-jcy <714897623@qq.com> Date: Sun, 6 Aug 2023 23:32:54 +0800 Subject: [PATCH 05/16] fix: mktime on windows platform --- source/os/src/osTime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/os/src/osTime.c b/source/os/src/osTime.c index 39d1de0437..a9965c57c2 100644 --- a/source/os/src/osTime.c +++ b/source/os/src/osTime.c @@ -368,7 +368,7 @@ int32_t taosGetTimeOfDay(struct timeval *tv) { time_t taosTime(time_t *t) { return time(t); } time_t taosMktime(struct tm *timep) { -#ifdef WINDOWS +#ifdef WINDOWS_STASH struct tm tm1 = {0}; LARGE_INTEGER t; FILETIME f; From 773a9454d513f40ee2820a34cb0958ec4508518a Mon Sep 17 00:00:00 2001 From: slzhou Date: Thu, 27 Jul 2023 09:07:13 +0800 Subject: [PATCH 06/16] enhance: subquery can use expr primary key +/- value as primary key --- source/libs/parser/src/parTranslater.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 8ce68a5c8c..554dc7cce8 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -821,7 +821,19 @@ static bool isPrimaryKeyImpl(SNode* pExpr) { FUNCTION_TYPE_IROWTS == pFunc->funcType) { return true; } - } + } else if (QUERY_NODE_OPERATOR == nodeType(pExpr)) { + SOperatorNode* pOper = (SOperatorNode*)pExpr; + if (OP_TYPE_ADD != pOper->opType && OP_TYPE_SUB != pOper->opType) { + return false; + } + if (!isPrimaryKeyImpl(pOper->pLeft)) { + return false; + } + if (QUERY_NODE_VALUE != nodeType(pOper->pRight)) { + return false; + } + return true; + } return false; } From 3e7187b2229f5705429446a0d5d3e90f4a33258c Mon Sep 17 00:00:00 2001 From: slzhou Date: Fri, 4 Aug 2023 14:17:18 +0800 Subject: [PATCH 07/16] fix: add test case --- tests/parallel_test/cases.task | 1 + tests/script/tsim/query/join_pk.sim | 42 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/script/tsim/query/join_pk.sim diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 586425ec1d..7a1e8d61c8 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -954,6 +954,7 @@ ,,n,script,./test.sh -f tsim/query/udfpy.sim ,,y,script,./test.sh -f tsim/query/udf_with_const.sim ,,y,script,./test.sh -f tsim/query/join_interval.sim +,,y,script,./test.sh -f tsim/query/join_pk.sim ,,y,script,./test.sh -f tsim/query/unionall_as_table.sim ,,y,script,./test.sh -f tsim/query/multi_order_by.sim ,,y,script,./test.sh -f tsim/query/sys_tbname.sim diff --git a/tests/script/tsim/query/join_pk.sim b/tests/script/tsim/query/join_pk.sim new file mode 100644 index 0000000000..66bb20da24 --- /dev/null +++ b/tests/script/tsim/query/join_pk.sim @@ -0,0 +1,42 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sql connect + +sql create database test; +sql use test; +sql create table st(ts timestamp, f int) tags(t int); +sql insert into ct1 using st tags(1) values(now, 0)(now+1s, 1) +sql insert into ct2 using st tags(2) values(now+2s, 2)(now+3s, 3) +sql select * from (select _wstart - 1s as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +if $rows != 3 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data11 != 1 then + return -1 +endi + +if $data21 != 1 then + return -1 +endi +if $data03 != 1 then + return -1 +endi + +if $data13 != 1 then + return -1 +endi +if $data23 != 1 then + return -1 +endi +sql select * from (select _wstart - 1d as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +sql select * from (select _wstart + 1a as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +sql_error select * from (select _wstart * 3 as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts +#system sh/exec.sh -n dnode1 -s stop -x SIGINT + From 6cccc155eb547336325f04c2acf611cef399e256 Mon Sep 17 00:00:00 2001 From: slzhou Date: Mon, 7 Aug 2023 13:39:30 +0800 Subject: [PATCH 08/16] enhance: enhance test case --- tests/script/tsim/query/join_pk.sim | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/script/tsim/query/join_pk.sim b/tests/script/tsim/query/join_pk.sim index 66bb20da24..da5c13e9c0 100644 --- a/tests/script/tsim/query/join_pk.sim +++ b/tests/script/tsim/query/join_pk.sim @@ -38,5 +38,18 @@ sql select * from (select _wstart - 1d as ts, count(*) as num1 from st interval( sql select * from (select _wstart + 1a as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts sql_error select * from (select _wstart * 3 as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts +sql create table sst(ts timestamp, ts2 timestamp, f int) tags(t int); +sql insert into sct1 using sst tags(1) values('2023-08-07 13:30:56', '2023-08-07 13:30:56', 0)('2023-08-07 13:30:57', '2023-08-07 13:30:57', 1) +sql insert into sct2 using sst tags(2) values('2023-08-07 13:30:58', '2023-08-07 13:30:58', 2)('2023-08-07 13:30:59', '2023-08-07 13:30:59', 3) +sql select * from (select ts - 1s as jts from sst) as t1 inner join (select ts-1s as jts from sst) as t2 on t1.jts = t2.jts +if $rows != 4 then + return -1 +endi +sql select * from (select ts - 1s as jts from sst) as t1 inner join (select ts as jts from sst) as t2 on t1.jts = t2.jts +if $rows != 3 then + return -1 +endi +sql_error select * from (select ts2 - 1s as jts from sst) as t1 inner join (select ts2 as jts from sst) as t2 on t1.jts = t2.jts + #system sh/exec.sh -n dnode1 -s stop -x SIGINT From 6fd2ae138e7ab2d67d6212d654ab2b9e98218244 Mon Sep 17 00:00:00 2001 From: jiacy-jcy <714897623@qq.com> Date: Mon, 7 Aug 2023 17:32:20 +0800 Subject: [PATCH 09/16] fix: taosMktime on windows platform --- include/os/osTime.h | 2 ++ source/common/src/ttime.c | 40 ------------------------------ source/os/src/osTime.c | 51 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/include/os/osTime.h b/include/os/osTime.h index 51a285a139..87df3a2650 100644 --- a/include/os/osTime.h +++ b/include/os/osTime.h @@ -95,6 +95,8 @@ struct tm *taosLocalTime(const time_t *timep, struct tm *result, char *buf); struct tm *taosLocalTimeNolock(struct tm *result, const time_t *timep, int dst); time_t taosTime(time_t *t); time_t taosMktime(struct tm *timep); +int64_t user_mktime64(const uint32_t year, const uint32_t mon, const uint32_t day, const uint32_t hour, + const uint32_t min, const uint32_t sec, int64_t time_zone); #ifdef __cplusplus } diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index 7a5581efbe..e9313e0591 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -25,46 +25,6 @@ #include "tlog.h" -/* - * mktime64 - Converts date to seconds. - * Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * A leap second can be indicated by calling this function with sec as - * 60 (allowable under ISO 8601). The leap second is treated the same - * as the following second since they don't exist in UNIX time. - * - * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight - * tomorrow - (allowable under ISO 8601) is supported. - */ -static int64_t user_mktime64(const uint32_t year0, const uint32_t mon0, const uint32_t day, const uint32_t hour, - const uint32_t min, const uint32_t sec, int64_t time_zone) { - uint32_t mon = mon0, year = year0; - - /* 1..12 -> 11,12,1..10 */ - if (0 >= (int32_t)(mon -= 2)) { - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - - // int64_t res = (((((int64_t) (year/4 - year/100 + year/400 + 367*mon/12 + day) + - // year*365 - 719499)*24 + hour)*60 + min)*60 + sec); - int64_t res; - res = 367 * ((int64_t)mon) / 12; - res += year / 4 - year / 100 + year / 400 + day + ((int64_t)year) * 365 - 719499; - res = res * 24; - res = ((res + hour) * 60 + min) * 60 + sec; - - return (res + time_zone); -} // ==== mktime() kernel code =================// static int64_t m_deltaUtc = 0; diff --git a/source/os/src/osTime.c b/source/os/src/osTime.c index 39d1de0437..0430dd70fc 100644 --- a/source/os/src/osTime.c +++ b/source/os/src/osTime.c @@ -367,8 +367,50 @@ int32_t taosGetTimeOfDay(struct timeval *tv) { time_t taosTime(time_t *t) { return time(t); } +/* + * mktime64 - Converts date to seconds. + * Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. + * + * [For the Julian calendar (which was used in Russia before 1917, + * Britain & colonies before 1752, anywhere else before 1582, + * and is still in use by some communities) leave out the + * -year/100+year/400 terms, and add 10.] + * + * This algorithm was first published by Gauss (I think). + * + * A leap second can be indicated by calling this function with sec as + * 60 (allowable under ISO 8601). The leap second is treated the same + * as the following second since they don't exist in UNIX time. + * + * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight + * tomorrow - (allowable under ISO 8601) is supported. + */ +int64_t user_mktime64(const uint32_t year, const uint32_t mon, const uint32_t day, const uint32_t hour, + const uint32_t min, const uint32_t sec, int64_t time_zone) { + uint32_t _mon = mon, _year = year; + + /* 1..12 -> 11,12,1..10 */ + if (0 >= (int32_t)(_mon -= 2)) { + _mon += 12; /* Puts Feb last since it has leap day */ + _year -= 1; + } + + // int64_t _res = (((((int64_t) (_year/4 - _year/100 + _year/400 + 367*_mon/12 + day) + + // _year*365 - 719499)*24 + hour)*60 + min)*60 + sec); + int64_t _res; + _res = 367 * ((int64_t)_mon) / 12; + _res += _year / 4 - _year / 100 + _year / 400 + day + ((int64_t)_year) * 365 - 719499; + _res = _res * 24; + _res = ((_res + hour) * 60 + min) * 60 + sec; + + return (_res + time_zone); +} + time_t taosMktime(struct tm *timep) { #ifdef WINDOWS +#if 0 struct tm tm1 = {0}; LARGE_INTEGER t; FILETIME f; @@ -405,6 +447,15 @@ time_t taosMktime(struct tm *timep) { t.QuadPart -= offset.QuadPart; return (time_t)(t.QuadPart / 10000000); +#else +#ifdef _MSC_VER +#if _MSC_VER >= 1900 + int64_t tz = _timezone; +#endif +#endif + return user_mktime64(timep->tm_year + 1900, timep->tm_mon + 1, timep->tm_mday, timep->tm_hour, timep->tm_min, + timep->tm_sec, tz); +#endif #else return mktime(timep); #endif From 59100a7251fa358c43cded44a1bf054ffc485e02 Mon Sep 17 00:00:00 2001 From: kailixu Date: Mon, 7 Aug 2023 17:52:43 +0800 Subject: [PATCH 10/16] enh: code optimize for mktime --- source/os/src/osTime.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/os/src/osTime.c b/source/os/src/osTime.c index 0430dd70fc..e758055529 100644 --- a/source/os/src/osTime.c +++ b/source/os/src/osTime.c @@ -399,13 +399,12 @@ int64_t user_mktime64(const uint32_t year, const uint32_t mon, const uint32_t da // int64_t _res = (((((int64_t) (_year/4 - _year/100 + _year/400 + 367*_mon/12 + day) + // _year*365 - 719499)*24 + hour)*60 + min)*60 + sec); - int64_t _res; - _res = 367 * ((int64_t)_mon) / 12; + int64_t _res = 367 * ((int64_t)_mon) / 12; _res += _year / 4 - _year / 100 + _year / 400 + day + ((int64_t)_year) * 365 - 719499; - _res = _res * 24; + _res *= 24; _res = ((_res + hour) * 60 + min) * 60 + sec; - return (_res + time_zone); + return _res + time_zone; } time_t taosMktime(struct tm *timep) { From b598c2651df65f5c91b5bfad301ce78d3777a096 Mon Sep 17 00:00:00 2001 From: kailixu Date: Mon, 7 Aug 2023 19:30:54 +0800 Subject: [PATCH 11/16] fix: use mktime after 19700101 on windows --- source/os/src/osTime.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/os/src/osTime.c b/source/os/src/osTime.c index e758055529..05233065fa 100644 --- a/source/os/src/osTime.c +++ b/source/os/src/osTime.c @@ -447,6 +447,10 @@ time_t taosMktime(struct tm *timep) { t.QuadPart -= offset.QuadPart; return (time_t)(t.QuadPart / 10000000); #else + time_t result = mktime(timep); + if (result != -1) { + return result; + } #ifdef _MSC_VER #if _MSC_VER >= 1900 int64_t tz = _timezone; From 9b4bdd819bc4f9a2d2ceef8ac2b7928bc9590980 Mon Sep 17 00:00:00 2001 From: slzhou Date: Thu, 27 Jul 2023 09:07:13 +0800 Subject: [PATCH 12/16] enhance: subquery can use expr primary key +/- value as primary key --- source/libs/parser/src/parTranslater.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 8ce68a5c8c..554dc7cce8 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -821,7 +821,19 @@ static bool isPrimaryKeyImpl(SNode* pExpr) { FUNCTION_TYPE_IROWTS == pFunc->funcType) { return true; } - } + } else if (QUERY_NODE_OPERATOR == nodeType(pExpr)) { + SOperatorNode* pOper = (SOperatorNode*)pExpr; + if (OP_TYPE_ADD != pOper->opType && OP_TYPE_SUB != pOper->opType) { + return false; + } + if (!isPrimaryKeyImpl(pOper->pLeft)) { + return false; + } + if (QUERY_NODE_VALUE != nodeType(pOper->pRight)) { + return false; + } + return true; + } return false; } From d43db6e8a8250dbfd87de01e32ead4ccf299b7b7 Mon Sep 17 00:00:00 2001 From: slzhou Date: Fri, 4 Aug 2023 14:17:18 +0800 Subject: [PATCH 13/16] fix: add test case --- tests/parallel_test/cases.task | 1 + tests/script/tsim/query/join_pk.sim | 42 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/script/tsim/query/join_pk.sim diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 586425ec1d..7a1e8d61c8 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -954,6 +954,7 @@ ,,n,script,./test.sh -f tsim/query/udfpy.sim ,,y,script,./test.sh -f tsim/query/udf_with_const.sim ,,y,script,./test.sh -f tsim/query/join_interval.sim +,,y,script,./test.sh -f tsim/query/join_pk.sim ,,y,script,./test.sh -f tsim/query/unionall_as_table.sim ,,y,script,./test.sh -f tsim/query/multi_order_by.sim ,,y,script,./test.sh -f tsim/query/sys_tbname.sim diff --git a/tests/script/tsim/query/join_pk.sim b/tests/script/tsim/query/join_pk.sim new file mode 100644 index 0000000000..66bb20da24 --- /dev/null +++ b/tests/script/tsim/query/join_pk.sim @@ -0,0 +1,42 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sql connect + +sql create database test; +sql use test; +sql create table st(ts timestamp, f int) tags(t int); +sql insert into ct1 using st tags(1) values(now, 0)(now+1s, 1) +sql insert into ct2 using st tags(2) values(now+2s, 2)(now+3s, 3) +sql select * from (select _wstart - 1s as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +if $rows != 3 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data11 != 1 then + return -1 +endi + +if $data21 != 1 then + return -1 +endi +if $data03 != 1 then + return -1 +endi + +if $data13 != 1 then + return -1 +endi +if $data23 != 1 then + return -1 +endi +sql select * from (select _wstart - 1d as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +sql select * from (select _wstart + 1a as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts + +sql_error select * from (select _wstart * 3 as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts +#system sh/exec.sh -n dnode1 -s stop -x SIGINT + From 67d4647fd56962da5e5131061d0d690316a5daf3 Mon Sep 17 00:00:00 2001 From: slzhou Date: Mon, 7 Aug 2023 13:39:30 +0800 Subject: [PATCH 14/16] enhance: enhance test case --- tests/script/tsim/query/join_pk.sim | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/script/tsim/query/join_pk.sim b/tests/script/tsim/query/join_pk.sim index 66bb20da24..da5c13e9c0 100644 --- a/tests/script/tsim/query/join_pk.sim +++ b/tests/script/tsim/query/join_pk.sim @@ -38,5 +38,18 @@ sql select * from (select _wstart - 1d as ts, count(*) as num1 from st interval( sql select * from (select _wstart + 1a as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts sql_error select * from (select _wstart * 3 as ts, count(*) as num1 from st interval(1s)) as t1 inner join (select _wstart as ts, count(*) as num2 from st interval(1s)) as t2 on t1.ts = t2.ts +sql create table sst(ts timestamp, ts2 timestamp, f int) tags(t int); +sql insert into sct1 using sst tags(1) values('2023-08-07 13:30:56', '2023-08-07 13:30:56', 0)('2023-08-07 13:30:57', '2023-08-07 13:30:57', 1) +sql insert into sct2 using sst tags(2) values('2023-08-07 13:30:58', '2023-08-07 13:30:58', 2)('2023-08-07 13:30:59', '2023-08-07 13:30:59', 3) +sql select * from (select ts - 1s as jts from sst) as t1 inner join (select ts-1s as jts from sst) as t2 on t1.jts = t2.jts +if $rows != 4 then + return -1 +endi +sql select * from (select ts - 1s as jts from sst) as t1 inner join (select ts as jts from sst) as t2 on t1.jts = t2.jts +if $rows != 3 then + return -1 +endi +sql_error select * from (select ts2 - 1s as jts from sst) as t1 inner join (select ts2 as jts from sst) as t2 on t1.jts = t2.jts + #system sh/exec.sh -n dnode1 -s stop -x SIGINT From 0ce702f002da515a4d776c0231b0a55073b9bcac Mon Sep 17 00:00:00 2001 From: sunpeng Date: Tue, 8 Aug 2023 16:58:04 +0800 Subject: [PATCH 15/16] docs: fix connection param in taosws in python connector --- docs/en/14-reference/03-connector/07-python.mdx | 2 +- docs/zh/08-connector/30-python.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/14-reference/03-connector/07-python.mdx b/docs/en/14-reference/03-connector/07-python.mdx index 831e79eeb7..5067c33e2d 100644 --- a/docs/en/14-reference/03-connector/07-python.mdx +++ b/docs/en/14-reference/03-connector/07-python.mdx @@ -373,7 +373,7 @@ conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (locat ```python -conn = taosws.connect(url="ws://localhost:6041") +conn = taosws.connect("taosws://localhost:6041") # Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement. conn.execute("DROP DATABASE IF EXISTS test") conn.execute("CREATE DATABASE test") diff --git a/docs/zh/08-connector/30-python.mdx b/docs/zh/08-connector/30-python.mdx index 15c11d05c3..ab98b5b8de 100644 --- a/docs/zh/08-connector/30-python.mdx +++ b/docs/zh/08-connector/30-python.mdx @@ -375,7 +375,7 @@ conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (locat ```python -conn = taosws.connect(url="ws://localhost:6041") +conn = taosws.connect("taosws://localhost:6041") # Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement. conn.execute("DROP DATABASE IF EXISTS test") conn.execute("CREATE DATABASE test") From f02fd54298b7fb39f8f6c18d4c97dbcd4eb79f39 Mon Sep 17 00:00:00 2001 From: "chao.feng" Date: Tue, 1 Aug 2023 17:32:06 +0800 Subject: [PATCH 16/16] add test case to cases.task by charles --- tests/parallel_test/cases.task | 1 + .../0-others/user_privilege_multi_users.py | 126 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 tests/system-test/0-others/user_privilege_multi_users.py diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 89572d1c06..d8f178dcfa 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -154,6 +154,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_control.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_manage.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_privilege.py +,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_privilege_multi_users.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/fsync.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/multilevel.py ,,n,system-test,python3 ./test.py -f 0-others/compatibility.py diff --git a/tests/system-test/0-others/user_privilege_multi_users.py b/tests/system-test/0-others/user_privilege_multi_users.py new file mode 100644 index 0000000000..8812f42e7b --- /dev/null +++ b/tests/system-test/0-others/user_privilege_multi_users.py @@ -0,0 +1,126 @@ +from itertools import product +import taos +import random +from taos.tmq import * +from util.cases import * +from util.common import * +from util.log import * +from util.sql import * +from util.sqlset import * + + +class TDTestCase: + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug("start to execute %s" % __file__) + # init the tdsql + tdSql.init(conn.cursor()) + self.setsql = TDSetSql() + # user info + self.userNum = 100 + self.basic_username = "user" + self.password = "pwd" + + # db info + self.dbname = "user_privilege_multi_users" + self.stbname = 'stb' + self.ctbname_num = 100 + self.column_dict = { + 'ts': 'timestamp', + 'col1': 'float', + 'col2': 'int', + } + self.tag_dict = { + 'ctbname': 'binary(10)' + } + + self.privilege_list = [] + + def prepare_data(self): + """Create the db and data for test + """ + # create datebase + tdSql.execute(f"create database {self.dbname}") + tdLog.debug("sql:" + f"create database {self.dbname}") + tdSql.execute(f"use {self.dbname}") + tdLog.debug("sql:" + f"use {self.dbname}") + + # create super table + tdSql.execute(self.setsql.set_create_stable_sql(self.stbname, self.column_dict, self.tag_dict)) + tdLog.debug("Create stable {} successfully".format(self.stbname)) + for ctbIndex in range(self.ctbname_num): + ctname = f"ctb{ctbIndex}" + tdSql.execute(f"create table {ctname} using {self.stbname} tags('{ctname}')") + tdLog.debug("sql:" + f"create table {ctname} using {self.stbname} tags('{ctname}')") + + def create_multiusers(self): + """Create the user for test + """ + for userIndex in range(self.userNum): + username = f"{self.basic_username}{userIndex}" + tdSql.execute(f'create user {username} pass "{self.password}"') + tdLog.debug("sql:" + f'create user {username} pass "{self.password}"') + + def grant_privilege(self): + """Add the privilege for the users + """ + try: + for userIndex in range(self.userNum): + username = f"{self.basic_username}{userIndex}" + privilege = random.choice(["read", "write", "all"]) + condition = f"ctbname='ctb{userIndex}'" + self.privilege_list.append({ + "username": username, + "privilege": privilege, + "condition": condition + }) + tdSql.execute(f'grant {privilege} on {self.dbname}.{self.stbname} with {condition} to {username}') + tdLog.debug("sql:" + f'grant {privilege} on {self.dbname}.{self.stbname} with {condition} to {username}') + except Exception as ex: + tdLog.exit(ex) + + def remove_privilege(self): + """Remove the privilege for the users + """ + try: + for item in self.privilege_list: + username = item["username"] + privilege = item["privilege"] + condition = item["condition"] + tdSql.execute(f'revoke {privilege} on {self.dbname}.{self.stbname} with {condition} from {username}') + tdLog.debug("sql:" + f'revoke {privilege} on {self.dbname}.{self.stbname} with {condition} from {username}') + except Exception as ex: + tdLog.exit(ex) + + def run(self): + """ + Check the information from information_schema.ins_user_privileges + """ + self.create_multiusers() + self.prepare_data() + # grant privilege to users + self.grant_privilege() + # check information_schema.ins_user_privileges + tdSql.query("select * from information_schema.ins_user_privileges;") + tdLog.debug("Current information_schema.ins_user_privileges values: {}".format(tdSql.queryResult)) + if len(tdSql.queryResult) >= self.userNum: + tdLog.debug("case passed") + else: + tdLog.exit("The privilege number in information_schema.ins_user_privileges is incorrect") + + def stop(self): + # remove the privilege + self.remove_privilege() + # clear env + tdSql.execute(f"drop database {self.dbname}") + # remove the users + for userIndex in range(self.userNum): + username = f"{self.basic_username}{userIndex}" + tdSql.execute(f'drop user {username}') + # close the connection + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase())