Merge branch '3.0' into feat/TD-27463-3.0
This commit is contained in:
commit
e13e61f4d5
|
@ -1,6 +1,6 @@
|
|||
# openssl
|
||||
ExternalProject_Add(openssl
|
||||
URL https://www.openssl.org/source/openssl-3.1.3.tar.gz
|
||||
URL https://github.com/openssl/openssl/releases/download/openssl-3.1.3/openssl-3.1.3.tar.gz
|
||||
URL_HASH SHA256=f0316a2ebd89e7f2352976445458689f80302093788c466692fb2a188b2eacf6
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download"
|
||||
|
|
|
@ -47,10 +47,11 @@ typedef struct SCorEpSet {
|
|||
int32_t taosGetFqdnPortFromEp(const char* ep, SEp* pEp);
|
||||
void addEpIntoEpSet(SEpSet* pEpSet, const char* fqdn, uint16_t port);
|
||||
|
||||
bool isEpsetEqual(const SEpSet* s1, const SEpSet* s2);
|
||||
void epsetAssign(SEpSet* dst, const SEpSet* pSrc);
|
||||
void updateEpSet_s(SCorEpSet* pEpSet, SEpSet* pNewEpSet);
|
||||
SEpSet getEpSet_s(SCorEpSet* pEpSet);
|
||||
bool isEpsetEqual(const SEpSet* s1, const SEpSet* s2);
|
||||
void epsetAssign(SEpSet* dst, const SEpSet* pSrc);
|
||||
void updateEpSet_s(SCorEpSet* pEpSet, SEpSet* pNewEpSet);
|
||||
SEpSet getEpSet_s(SCorEpSet* pEpSet);
|
||||
void epsetSort(SEpSet* pEpSet);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -126,6 +126,7 @@ int32_t* taosGetErrno();
|
|||
|
||||
#define TSDB_CODE_IP_NOT_IN_WHITE_LIST TAOS_DEF_ERROR_CODE(0, 0x0134)
|
||||
#define TSDB_CODE_FAILED_TO_CONNECT_S3 TAOS_DEF_ERROR_CODE(0, 0x0135)
|
||||
#define TSDB_CODE_MSG_PREPROCESSED TAOS_DEF_ERROR_CODE(0, 0x0136) // internal
|
||||
|
||||
//client
|
||||
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200)
|
||||
|
@ -522,6 +523,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_QRY_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0x070F)
|
||||
// #define TSDB_CODE_QRY_INVALID_SCHEMA_VERSION TAOS_DEF_ERROR_CODE(0, 0x0710) // 2.x
|
||||
// #define TSDB_CODE_QRY_RESULT_TOO_LARGE TAOS_DEF_ERROR_CODE(0, 0x0711) // 2.x
|
||||
#define TSDB_CODE_QRY_INVALID_WINDOW_CONDITION TAOS_DEF_ERROR_CODE(0, 0x0712)
|
||||
#define TSDB_CODE_QRY_SCH_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0720)
|
||||
#define TSDB_CODE_QRY_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0721)
|
||||
#define TSDB_CODE_QRY_TASK_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0722)
|
||||
|
|
|
@ -15,11 +15,8 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "tmisce.h"
|
||||
#include "tjson.h"
|
||||
#include "tglobal.h"
|
||||
#include "tlog.h"
|
||||
#include "tname.h"
|
||||
|
||||
#include "tjson.h"
|
||||
int32_t taosGetFqdnPortFromEp(const char* ep, SEp* pEp) {
|
||||
pEp->port = 0;
|
||||
memset(pEp->fqdn, 0, TSDB_FQDN_LEN);
|
||||
|
@ -63,7 +60,7 @@ bool isEpsetEqual(const SEpSet* s1, const SEpSet* s2) {
|
|||
|
||||
void epsetAssign(SEpSet* pDst, const SEpSet* pSrc) {
|
||||
if (pSrc == NULL || pDst == NULL) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
pDst->inUse = pSrc->inUse;
|
||||
|
@ -73,6 +70,47 @@ void epsetAssign(SEpSet* pDst, const SEpSet* pSrc) {
|
|||
tstrncpy(pDst->eps[i].fqdn, pSrc->eps[i].fqdn, tListLen(pSrc->eps[i].fqdn));
|
||||
}
|
||||
}
|
||||
void epAssign(SEp* pDst, SEp* pSrc) {
|
||||
if (pSrc == NULL || pDst == NULL) {
|
||||
return;
|
||||
}
|
||||
memset(pDst->fqdn, 0, tListLen(pSrc->fqdn));
|
||||
tstrncpy(pDst->fqdn, pSrc->fqdn, tListLen(pSrc->fqdn));
|
||||
pDst->port = pSrc->port;
|
||||
}
|
||||
void epsetSort(SEpSet* pDst) {
|
||||
if (pDst->numOfEps <= 1) {
|
||||
return;
|
||||
}
|
||||
int validIdx = false;
|
||||
SEp ep = {0};
|
||||
if (pDst->inUse >= 0 && pDst->inUse < pDst->numOfEps) {
|
||||
validIdx = true;
|
||||
epAssign(&ep, &pDst->eps[pDst->inUse]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pDst->numOfEps - 1; i++) {
|
||||
for (int j = 0; j < pDst->numOfEps - 1 - i; j++) {
|
||||
SEp* f = &pDst->eps[j];
|
||||
SEp* s = &pDst->eps[j + 1];
|
||||
int cmp = strncmp(f->fqdn, s->fqdn, sizeof(f->fqdn));
|
||||
if (cmp > 0 || (cmp == 0 && f->port > s->port)) {
|
||||
SEp ep = {0};
|
||||
epAssign(&ep, f);
|
||||
epAssign(f, s);
|
||||
epAssign(s, &ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (validIdx == true)
|
||||
for (int i = 0; i < pDst->numOfEps; i++) {
|
||||
int cmp = strncmp(ep.fqdn, pDst->eps[i].fqdn, sizeof(ep.fqdn));
|
||||
if (cmp == 0 && ep.port == pDst->eps[i].port) {
|
||||
pDst->inUse = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateEpSet_s(SCorEpSet* pEpSet, SEpSet* pNewEpSet) {
|
||||
taosCorBeginWrite(&pEpSet->version);
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
#include "tcommon.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tdef.h"
|
||||
#include "tvariant.h"
|
||||
#include "tmisce.h"
|
||||
#include "ttime.h"
|
||||
#include "ttokendef.h"
|
||||
#include "tvariant.h"
|
||||
|
||||
namespace {
|
||||
//
|
||||
|
@ -25,11 +26,10 @@ int main(int argc, char** argv) {
|
|||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
|
||||
TEST(testCase, toUIntegerEx_test) {
|
||||
uint64_t val = 0;
|
||||
|
||||
char* s = "123";
|
||||
char* s = "123";
|
||||
int32_t ret = toUIntegerEx(s, strlen(s), TK_NK_INTEGER, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 123);
|
||||
|
@ -59,7 +59,7 @@ TEST(testCase, toUIntegerEx_test) {
|
|||
ASSERT_EQ(val, 18699);
|
||||
|
||||
s = "-1";
|
||||
ret = toUIntegerEx(s, strlen(s),TK_NK_INTEGER, &val);
|
||||
ret = toUIntegerEx(s, strlen(s), TK_NK_INTEGER, &val);
|
||||
ASSERT_EQ(ret, -1);
|
||||
|
||||
s = "-0b10010";
|
||||
|
@ -103,7 +103,7 @@ TEST(testCase, toUIntegerEx_test) {
|
|||
TEST(testCase, toIntegerEx_test) {
|
||||
int64_t val = 0;
|
||||
|
||||
char* s = "123";
|
||||
char* s = "123";
|
||||
int32_t ret = toIntegerEx(s, strlen(s), TK_NK_INTEGER, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 123);
|
||||
|
@ -166,7 +166,7 @@ TEST(testCase, toIntegerEx_test) {
|
|||
s = "-9223372036854775808";
|
||||
ret = toIntegerEx(s, strlen(s), TK_NK_INTEGER, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, -9223372036854775808);
|
||||
// ASSERT_EQ(val, -9223372036854775808);
|
||||
|
||||
// out of range
|
||||
s = "9323372036854775807";
|
||||
|
@ -186,7 +186,7 @@ TEST(testCase, toIntegerEx_test) {
|
|||
TEST(testCase, toInteger_test) {
|
||||
int64_t val = 0;
|
||||
|
||||
char* s = "123";
|
||||
char* s = "123";
|
||||
int32_t ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 123);
|
||||
|
@ -223,10 +223,10 @@ TEST(testCase, toInteger_test) {
|
|||
s = "-9223372036854775808";
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, -9223372036854775808);
|
||||
// ASSERT_EQ(val, -9223372036854775808);
|
||||
|
||||
// out of range
|
||||
s = "9323372036854775807";
|
||||
s = "9323372036854775807";
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, -1);
|
||||
|
||||
|
@ -418,9 +418,10 @@ void check_tm(const STm* tm, int32_t y, int32_t mon, int32_t d, int32_t h, int32
|
|||
ASSERT_EQ(tm->fsec, fsec);
|
||||
}
|
||||
|
||||
void test_timestamp_tm_conversion(int64_t ts, int32_t precision, int32_t y, int32_t mon, int32_t d, int32_t h, int32_t m, int32_t s, int64_t fsec) {
|
||||
int64_t ts_tmp;
|
||||
char buf[128] = {0};
|
||||
void test_timestamp_tm_conversion(int64_t ts, int32_t precision, int32_t y, int32_t mon, int32_t d, int32_t h,
|
||||
int32_t m, int32_t s, int64_t fsec) {
|
||||
int64_t ts_tmp;
|
||||
char buf[128] = {0};
|
||||
struct STm tm;
|
||||
taosFormatUtcTime(buf, 128, ts, precision);
|
||||
printf("formated ts of %ld, precision: %d is: %s\n", ts, precision, buf);
|
||||
|
@ -457,7 +458,7 @@ TEST(timeTest, timestamp2tm) {
|
|||
test_timestamp_tm_conversion(ts, TSDB_TIME_PRECISION_MILLI, 1970 - 1900, 0 /* mon start from 0*/, 1, 8, 0, 0,
|
||||
000000000L);
|
||||
|
||||
ts = -62198784343000; // milliseconds before epoch, Friday, January 1, -0001 12:00:00 AM GMT+08:06
|
||||
ts = -62198784343000; // milliseconds before epoch, Friday, January 1, -0001 12:00:00 AM GMT+08:06
|
||||
test_timestamp_tm_conversion(ts, TSDB_TIME_PRECISION_MILLI, -1 - 1900, 0 /* mon start from 0*/, 1,
|
||||
0 /* hour start from 0*/, 0, 0, 000000000L);
|
||||
}
|
||||
|
@ -472,7 +473,7 @@ void test_ts2char(int64_t ts, const char* format, int32_t precison, const char*
|
|||
TEST(timeTest, ts2char) {
|
||||
osDefaultInit();
|
||||
if (tsTimezone != TdEastZone8) GTEST_SKIP();
|
||||
int64_t ts;
|
||||
int64_t ts;
|
||||
const char* format = "YYYY-MM-DD";
|
||||
ts = 0;
|
||||
test_ts2char(ts, format, TSDB_TIME_PRECISION_MILLI, "1970-01-01");
|
||||
|
@ -493,12 +494,13 @@ TEST(timeTest, ts2char) {
|
|||
"2023-023-23-3-2023-023-23-3-年-OCTOBER -OCT-October -Oct-october "
|
||||
"-oct-月-286-13-6-286-13-6-FRIDAY -Friday -friday -日");
|
||||
#endif
|
||||
ts = 1697182085123L; // Friday, October 13, 2023 3:28:05.123 PM GMT+08:00
|
||||
ts = 1697182085123L; // Friday, October 13, 2023 3:28:05.123 PM GMT+08:00
|
||||
test_ts2char(ts, "HH24:hh24:HH12:hh12:HH:hh:MI:mi:SS:ss:MS:ms:US:us:NS:ns:PM:AM:pm:am", TSDB_TIME_PRECISION_MILLI,
|
||||
"15:15:03:03:03:03:28:28:05:05:123:123:123000:123000:123000000:123000000:PM:PM:pm:pm");
|
||||
|
||||
// double quotes normal output
|
||||
test_ts2char(ts, "\\\"HH24:hh24:HH12:hh12:HH:hh:MI:mi:SS:ss:MS:ms:US:us:NS:ns:PM:AM:pm:am\\\"", TSDB_TIME_PRECISION_MILLI,
|
||||
test_ts2char(ts, "\\\"HH24:hh24:HH12:hh12:HH:hh:MI:mi:SS:ss:MS:ms:US:us:NS:ns:PM:AM:pm:am\\\"",
|
||||
TSDB_TIME_PRECISION_MILLI,
|
||||
"\"15:15:03:03:03:03:28:28:05:05:123:123:123000:123000:123000000:123000000:PM:PM:pm:pm\"");
|
||||
test_ts2char(ts, "\\\"HH24:hh24:HH12:hh12:HH:hh:MI:mi:SS:ss:MS:ms:US:us:NS:ns:PM:AM:pm:am", TSDB_TIME_PRECISION_MILLI,
|
||||
"\"15:15:03:03:03:03:28:28:05:05:123:123:123000:123000:123000000:123000000:PM:PM:pm:pm");
|
||||
|
@ -506,14 +508,18 @@ TEST(timeTest, ts2char) {
|
|||
test_ts2char(ts, "\"HH24:hh24:HH12:hh12:HH:hh:MI:mi:SS:ss:MS:ms:US:us:NS:ns:PM:AM:pm:am", TSDB_TIME_PRECISION_MILLI,
|
||||
"HH24:hh24:HH12:hh12:HH:hh:MI:mi:SS:ss:MS:ms:US:us:NS:ns:PM:AM:pm:am");
|
||||
test_ts2char(ts, "yyyy-mm-dd hh24:mi:ss.nsamaaa", TSDB_TIME_PRECISION_MILLI, "2023-10-13 15:28:05.123000000pmaaa");
|
||||
test_ts2char(ts, "aaa--yyyy-mm-dd hh24:mi:ss.nsamaaa", TSDB_TIME_PRECISION_MILLI, "aaa--2023-10-13 15:28:05.123000000pmaaa");
|
||||
test_ts2char(ts, "add--yyyy-mm-dd hh24:mi:ss.nsamaaa", TSDB_TIME_PRECISION_MILLI, "a13--2023-10-13 15:28:05.123000000pmaaa");
|
||||
test_ts2char(ts, "aaa--yyyy-mm-dd hh24:mi:ss.nsamaaa", TSDB_TIME_PRECISION_MILLI,
|
||||
"aaa--2023-10-13 15:28:05.123000000pmaaa");
|
||||
test_ts2char(ts, "add--yyyy-mm-dd hh24:mi:ss.nsamaaa", TSDB_TIME_PRECISION_MILLI,
|
||||
"a13--2023-10-13 15:28:05.123000000pmaaa");
|
||||
|
||||
ts = 1693946405000;
|
||||
test_ts2char(ts, "Day, Month dd, YYYY hh24:mi:ss AM TZH:tzh", TSDB_TIME_PRECISION_MILLI, "Wednesday, September 06, 2023 04:40:05 AM +08:+08");
|
||||
test_ts2char(ts, "Day, Month dd, YYYY hh24:mi:ss AM TZH:tzh", TSDB_TIME_PRECISION_MILLI,
|
||||
"Wednesday, September 06, 2023 04:40:05 AM +08:+08");
|
||||
|
||||
ts = -62198784343000; // milliseconds before epoch, Friday, January 1, -0001 12:00:00 AM GMT+08:06
|
||||
test_ts2char(ts, "Day, Month dd, YYYY hh12:mi:ss AM", TSDB_TIME_PRECISION_MILLI, "Friday , January 01, -001 12:00:00 AM");
|
||||
ts = -62198784343000; // milliseconds before epoch, Friday, January 1, -0001 12:00:00 AM GMT+08:06
|
||||
test_ts2char(ts, "Day, Month dd, YYYY hh12:mi:ss AM", TSDB_TIME_PRECISION_MILLI,
|
||||
"Friday , January 01, -001 12:00:00 AM");
|
||||
}
|
||||
|
||||
TEST(timeTest, char2ts) {
|
||||
|
@ -609,7 +615,7 @@ TEST(timeTest, char2ts) {
|
|||
ASSERT_EQ(-1, TEST_char2ts("yyyyMMdd ", &ts, TSDB_TIME_PRECISION_MICRO, "2100/2/1"));
|
||||
// nothing to be converted to dd
|
||||
ASSERT_EQ(0, TEST_char2ts("yyyyMMdd ", &ts, TSDB_TIME_PRECISION_MICRO, "210012"));
|
||||
ASSERT_EQ(ts, 4131273600000000LL); // 2100-12-1
|
||||
ASSERT_EQ(ts, 4131273600000000LL); // 2100-12-1
|
||||
ASSERT_EQ(-1, TEST_char2ts("yyyyMMdd ", &ts, TSDB_TIME_PRECISION_MICRO, "21001"));
|
||||
ASSERT_EQ(-1, TEST_char2ts("yyyyMM-dd ", &ts, TSDB_TIME_PRECISION_MICRO, "23a1-1"));
|
||||
|
||||
|
@ -635,8 +641,55 @@ TEST(timeTest, char2ts) {
|
|||
ASSERT_EQ(0, TEST_char2ts("yyyy年 MM/ddTZH", &ts, TSDB_TIME_PRECISION_MICRO, "1970年 1/1+0"));
|
||||
ASSERT_EQ(ts, 0);
|
||||
ASSERT_EQ(0, TEST_char2ts("yyyy年 a a a MM/ddTZH", &ts, TSDB_TIME_PRECISION_MICRO, "1970年 a a a 1/1+0"));
|
||||
ASSERT_EQ(0, TEST_char2ts("yyyy年 a a a a a a a a a a a a a a a MM/ddTZH", &ts, TSDB_TIME_PRECISION_MICRO, "1970年 a "));
|
||||
ASSERT_EQ(0, TEST_char2ts("yyyy年 a a a a a a a a a a a a a a a MM/ddTZH", &ts, TSDB_TIME_PRECISION_MICRO,
|
||||
"1970年 a "));
|
||||
ASSERT_EQ(-3, TEST_char2ts("yyyy-mm-DDD", &ts, TSDB_TIME_PRECISION_MILLI, "1970-01-001"));
|
||||
}
|
||||
|
||||
TEST(timeTest, epSet) {
|
||||
{
|
||||
SEpSet ep = {0};
|
||||
addEpIntoEpSet(&ep, "local", 14);
|
||||
addEpIntoEpSet(&ep, "aocal", 13);
|
||||
addEpIntoEpSet(&ep, "abcal", 12);
|
||||
addEpIntoEpSet(&ep, "abcaleb", 11);
|
||||
epsetSort(&ep);
|
||||
ASSERT_EQ(strcmp(ep.eps[0].fqdn, "abcal"), 0);
|
||||
ASSERT_EQ(ep.eps[0].port, 12);
|
||||
|
||||
ASSERT_EQ(strcmp(ep.eps[1].fqdn, "abcaleb"), 0);
|
||||
ASSERT_EQ(ep.eps[1].port, 11);
|
||||
|
||||
ASSERT_EQ(strcmp(ep.eps[2].fqdn, "aocal"), 0);
|
||||
ASSERT_EQ(ep.eps[2].port, 13);
|
||||
|
||||
ASSERT_EQ(strcmp(ep.eps[3].fqdn, "local"), 0);
|
||||
ASSERT_EQ(ep.eps[3].port, 14);
|
||||
}
|
||||
{
|
||||
SEpSet ep = {0};
|
||||
addEpIntoEpSet(&ep, "local", 14);
|
||||
addEpIntoEpSet(&ep, "local", 13);
|
||||
addEpIntoEpSet(&ep, "local", 12);
|
||||
addEpIntoEpSet(&ep, "local", 11);
|
||||
epsetSort(&ep);
|
||||
ASSERT_EQ(strcmp(ep.eps[0].fqdn, "local"), 0);
|
||||
ASSERT_EQ(ep.eps[0].port, 11);
|
||||
|
||||
ASSERT_EQ(strcmp(ep.eps[0].fqdn, "local"), 0);
|
||||
ASSERT_EQ(ep.eps[1].port, 12);
|
||||
|
||||
ASSERT_EQ(strcmp(ep.eps[0].fqdn, "local"), 0);
|
||||
ASSERT_EQ(ep.eps[2].port, 13);
|
||||
|
||||
ASSERT_EQ(strcmp(ep.eps[0].fqdn, "local"), 0);
|
||||
ASSERT_EQ(ep.eps[3].port, 14);
|
||||
}
|
||||
{
|
||||
SEpSet ep = {0};
|
||||
addEpIntoEpSet(&ep, "local", 14);
|
||||
epsetSort(&ep);
|
||||
ASSERT_EQ(ep.numOfEps, 1);
|
||||
}
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
|
|
@ -169,11 +169,29 @@ static int32_t dmParseArgs(int32_t argc, char const *argv[]) {
|
|||
return -1;
|
||||
}
|
||||
} else if (strcmp(argv[i], "-a") == 0) {
|
||||
tstrncpy(global.apolloUrl, argv[++i], PATH_MAX);
|
||||
if(i < argc - 1) {
|
||||
if (strlen(argv[++i]) >= PATH_MAX) {
|
||||
printf("apollo url overflow");
|
||||
return -1;
|
||||
}
|
||||
tstrncpy(global.apolloUrl, argv[i], PATH_MAX);
|
||||
} else {
|
||||
printf("'-a' requires a parameter\n");
|
||||
return -1;
|
||||
}
|
||||
} else if (strcmp(argv[i], "-s") == 0) {
|
||||
global.dumpSdb = true;
|
||||
} else if (strcmp(argv[i], "-E") == 0) {
|
||||
tstrncpy(global.envFile, argv[++i], PATH_MAX);
|
||||
if(i < argc - 1) {
|
||||
if (strlen(argv[++i]) >= PATH_MAX) {
|
||||
printf("env file path overflow");
|
||||
return -1;
|
||||
}
|
||||
tstrncpy(global.envFile, argv[i], PATH_MAX);
|
||||
} else {
|
||||
printf("'-E' requires a parameter\n");
|
||||
return -1;
|
||||
}
|
||||
} else if (strcmp(argv[i], "-k") == 0) {
|
||||
global.generateGrant = true;
|
||||
} else if (strcmp(argv[i], "-C") == 0) {
|
||||
|
|
|
@ -321,7 +321,7 @@ static bool rpcRfp(int32_t code, tmsg_t msgType) {
|
|||
code == TSDB_CODE_SYN_RESTORING || code == TSDB_CODE_VND_STOPPED || code == TSDB_CODE_APP_IS_STARTING ||
|
||||
code == TSDB_CODE_APP_IS_STOPPING) {
|
||||
if (msgType == TDMT_SCH_QUERY || msgType == TDMT_SCH_MERGE_QUERY || msgType == TDMT_SCH_FETCH ||
|
||||
msgType == TDMT_SCH_MERGE_FETCH || msgType == TDMT_SCH_TASK_NOTIFY) {
|
||||
msgType == TDMT_SCH_MERGE_FETCH || msgType == TDMT_SCH_TASK_NOTIFY || msgType == TDMT_VND_DROP_TTL_TABLE) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -223,7 +223,7 @@ int32_t dmWriteEps(SDnodeData *pData) {
|
|||
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
||||
if((code == dmInitDndInfo(pData)) != 0) goto _OVER;
|
||||
if ((code == dmInitDndInfo(pData)) != 0) goto _OVER;
|
||||
pJson = tjsonCreateObject();
|
||||
if (pJson == NULL) goto _OVER;
|
||||
pData->engineVer = tsVersion;
|
||||
|
@ -289,6 +289,7 @@ static void dmResetEps(SDnodeData *pData, SArray *dnodeEps) {
|
|||
pData->mnodeEps.eps[mIndex] = pDnodeEp->ep;
|
||||
mIndex++;
|
||||
}
|
||||
epsetSort(&pData->mnodeEps);
|
||||
|
||||
for (int32_t i = 0; i < numOfEps; i++) {
|
||||
SDnodeEp *pDnodeEp = taosArrayGet(dnodeEps, i);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndMnode.h"
|
||||
#include "audit.h"
|
||||
#include "mndCluster.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndPrivilege.h"
|
||||
|
@ -22,7 +23,6 @@
|
|||
#include "mndSync.h"
|
||||
#include "mndTrans.h"
|
||||
#include "tmisce.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define MNODE_VER_NUMBER 2
|
||||
#define MNODE_RESERVE_SIZE 64
|
||||
|
@ -168,7 +168,7 @@ static SSdbRow *mndMnodeActionDecode(SSdbRaw *pRaw) {
|
|||
SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pObj->createdTime, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER)
|
||||
if(sver >=2){
|
||||
if (sver >= 2) {
|
||||
SDB_GET_INT32(pRaw, dataPos, &pObj->role, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pObj->lastIndex, _OVER)
|
||||
}
|
||||
|
@ -251,6 +251,7 @@ void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) {
|
|||
pEpSet->inUse = pEpSet->numOfEps;
|
||||
} else {
|
||||
pEpSet->inUse = (pEpSet->numOfEps + 1) % totalMnodes;
|
||||
// pEpSet->inUse = 0;
|
||||
}
|
||||
}
|
||||
if (pObj->pDnode != NULL) {
|
||||
|
@ -266,6 +267,7 @@ void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) {
|
|||
if (pEpSet->inUse >= pEpSet->numOfEps) {
|
||||
pEpSet->inUse = 0;
|
||||
}
|
||||
epsetSort(pEpSet);
|
||||
}
|
||||
|
||||
static int32_t mndSetCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) {
|
||||
|
@ -320,8 +322,8 @@ static int32_t mndBuildCreateMnodeRedoAction(STrans *pTrans, SDCreateMnodeReq *p
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndBuildAlterMnodeTypeRedoAction(STrans *pTrans,
|
||||
SDAlterMnodeTypeReq *pAlterMnodeTypeReq, SEpSet *pAlterMnodeTypeEpSet) {
|
||||
static int32_t mndBuildAlterMnodeTypeRedoAction(STrans *pTrans, SDAlterMnodeTypeReq *pAlterMnodeTypeReq,
|
||||
SEpSet *pAlterMnodeTypeEpSet) {
|
||||
int32_t contLen = tSerializeSDCreateMnodeReq(NULL, 0, pAlterMnodeTypeReq);
|
||||
void *pReq = taosMemoryMalloc(contLen);
|
||||
tSerializeSDCreateMnodeReq(pReq, contLen, pAlterMnodeTypeReq);
|
||||
|
@ -396,13 +398,12 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno
|
|||
pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
if(pMObj->role == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pMObj->role == TAOS_SYNC_ROLE_VOTER) {
|
||||
createReq.replicas[numOfReplicas].id = pMObj->id;
|
||||
createReq.replicas[numOfReplicas].port = pMObj->pDnode->port;
|
||||
memcpy(createReq.replicas[numOfReplicas].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
|
||||
numOfReplicas++;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
createReq.learnerReplicas[numOfLearnerReplicas].id = pMObj->id;
|
||||
createReq.learnerReplicas[numOfLearnerReplicas].port = pMObj->pDnode->port;
|
||||
memcpy(createReq.learnerReplicas[numOfLearnerReplicas].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
|
||||
|
@ -441,18 +442,17 @@ int32_t mndSetRestoreCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno
|
|||
pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
if(pMObj->id == pDnode->id) {
|
||||
if (pMObj->id == pDnode->id) {
|
||||
sdbRelease(pSdb, pMObj);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(pMObj->role == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pMObj->role == TAOS_SYNC_ROLE_VOTER) {
|
||||
createReq.replicas[createReq.replica].id = pMObj->id;
|
||||
createReq.replicas[createReq.replica].port = pMObj->pDnode->port;
|
||||
memcpy(createReq.replicas[createReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
|
||||
createReq.replica++;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
createReq.learnerReplicas[createReq.learnerReplica].id = pMObj->id;
|
||||
createReq.learnerReplicas[createReq.learnerReplica].port = pMObj->pDnode->port;
|
||||
memcpy(createReq.learnerReplicas[createReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
|
||||
|
@ -480,23 +480,22 @@ int32_t mndSetRestoreCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno
|
|||
}
|
||||
|
||||
static int32_t mndSetAlterMnodeTypeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SDAlterMnodeTypeReq alterReq = {0};
|
||||
SEpSet createEpset = {0};
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SDAlterMnodeTypeReq alterReq = {0};
|
||||
SEpSet createEpset = {0};
|
||||
|
||||
while (1) {
|
||||
SMnodeObj *pMObj = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
if(pMObj->role == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pMObj->role == TAOS_SYNC_ROLE_VOTER) {
|
||||
alterReq.replicas[alterReq.replica].id = pMObj->id;
|
||||
alterReq.replicas[alterReq.replica].port = pMObj->pDnode->port;
|
||||
memcpy(alterReq.replicas[alterReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
|
||||
alterReq.replica++;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
alterReq.learnerReplicas[alterReq.learnerReplica].id = pMObj->id;
|
||||
alterReq.learnerReplicas[alterReq.learnerReplica].port = pMObj->pDnode->port;
|
||||
memcpy(alterReq.learnerReplicas[alterReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
|
||||
|
@ -524,28 +523,27 @@ static int32_t mndSetAlterMnodeTypeRedoActions(SMnode *pMnode, STrans *pTrans, S
|
|||
}
|
||||
|
||||
int32_t mndSetRestoreAlterMnodeTypeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SDAlterMnodeTypeReq alterReq = {0};
|
||||
SEpSet createEpset = {0};
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SDAlterMnodeTypeReq alterReq = {0};
|
||||
SEpSet createEpset = {0};
|
||||
|
||||
while (1) {
|
||||
SMnodeObj *pMObj = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
if(pMObj->id == pDnode->id) {
|
||||
if (pMObj->id == pDnode->id) {
|
||||
sdbRelease(pSdb, pMObj);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(pMObj->role == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pMObj->role == TAOS_SYNC_ROLE_VOTER) {
|
||||
alterReq.replicas[alterReq.replica].id = pMObj->id;
|
||||
alterReq.replicas[alterReq.replica].port = pMObj->pDnode->port;
|
||||
memcpy(alterReq.replicas[alterReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
|
||||
alterReq.replica++;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
alterReq.learnerReplicas[alterReq.learnerReplica].id = pMObj->id;
|
||||
alterReq.learnerReplicas[alterReq.learnerReplica].port = pMObj->pDnode->port;
|
||||
memcpy(alterReq.learnerReplicas[alterReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
|
||||
|
@ -965,8 +963,11 @@ static void mndReloadSyncConfig(SMnode *pMnode) {
|
|||
void *pIter = NULL;
|
||||
int32_t updatingMnodes = 0;
|
||||
int32_t readyMnodes = 0;
|
||||
SSyncCfg cfg = {.myIndex = -1, .lastIndex = 0,};
|
||||
SyncIndex maxIndex = 0;
|
||||
SSyncCfg cfg = {
|
||||
.myIndex = -1,
|
||||
.lastIndex = 0,
|
||||
};
|
||||
SyncIndex maxIndex = 0;
|
||||
|
||||
while (1) {
|
||||
pIter = sdbFetchAll(pSdb, SDB_MNODE, pIter, (void **)&pObj, &objStatus, false);
|
||||
|
@ -992,17 +993,17 @@ static void mndReloadSyncConfig(SMnode *pMnode) {
|
|||
if (pObj->pDnode->id == pMnode->selfDnodeId) {
|
||||
cfg.myIndex = cfg.totalReplicaNum;
|
||||
}
|
||||
if(pNode->nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pNode->nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
cfg.replicaNum++;
|
||||
}
|
||||
cfg.totalReplicaNum++;
|
||||
if(pObj->lastIndex > cfg.lastIndex){
|
||||
if (pObj->lastIndex > cfg.lastIndex) {
|
||||
cfg.lastIndex = pObj->lastIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (objStatus == SDB_STATUS_DROPPING) {
|
||||
if(pObj->lastIndex > cfg.lastIndex){
|
||||
if (pObj->lastIndex > cfg.lastIndex) {
|
||||
cfg.lastIndex = pObj->lastIndex;
|
||||
}
|
||||
}
|
||||
|
@ -1012,10 +1013,10 @@ static void mndReloadSyncConfig(SMnode *pMnode) {
|
|||
sdbReleaseLock(pSdb, pObj, false);
|
||||
}
|
||||
|
||||
//if (readyMnodes <= 0 || updatingMnodes <= 0) {
|
||||
// mInfo("vgId:1, mnode sync not reconfig since readyMnodes:%d updatingMnodes:%d", readyMnodes, updatingMnodes);
|
||||
// return;
|
||||
//}
|
||||
// if (readyMnodes <= 0 || updatingMnodes <= 0) {
|
||||
// mInfo("vgId:1, mnode sync not reconfig since readyMnodes:%d updatingMnodes:%d", readyMnodes, updatingMnodes);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (cfg.myIndex == -1) {
|
||||
#if 1
|
||||
|
@ -1029,8 +1030,8 @@ static void mndReloadSyncConfig(SMnode *pMnode) {
|
|||
}
|
||||
|
||||
if (pMnode->syncMgmt.sync > 0) {
|
||||
mInfo("vgId:1, mnode sync reconfig, totalReplica:%d replica:%d myIndex:%d",
|
||||
cfg.totalReplicaNum, cfg.replicaNum, cfg.myIndex);
|
||||
mInfo("vgId:1, mnode sync reconfig, totalReplica:%d replica:%d myIndex:%d", cfg.totalReplicaNum, cfg.replicaNum,
|
||||
cfg.myIndex);
|
||||
|
||||
for (int32_t i = 0; i < cfg.totalReplicaNum; ++i) {
|
||||
SNodeInfo *pNode = &cfg.nodeInfo[i];
|
||||
|
|
|
@ -877,6 +877,7 @@ SEpSet mndGetVgroupEpset(SMnode *pMnode, const SVgObj *pVgroup) {
|
|||
addEpIntoEpSet(&epset, pDnode->fqdn, pDnode->port);
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
}
|
||||
epsetSort(&epset);
|
||||
|
||||
return epset;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ const char *sdbTableName(ESdbType type) {
|
|||
return "idx";
|
||||
case SDB_VIEW:
|
||||
return "view";
|
||||
case SDB_STREAM_SEQ:
|
||||
return "stream_seq";
|
||||
case SDB_COMPACT:
|
||||
return "compact";
|
||||
case SDB_COMPACT_DETAIL:
|
||||
|
|
|
@ -157,7 +157,8 @@ int vnodeShouldCommit(SVnode *pVnode, bool atExit) {
|
|||
taosThreadMutexLock(&pVnode->mutex);
|
||||
if (pVnode->inUse && diskAvail) {
|
||||
needCommit = (pVnode->inUse->size > pVnode->inUse->node.size) ||
|
||||
(atExit && (pVnode->inUse->size > 0 || pVnode->pMeta->changed));
|
||||
(atExit && (pVnode->inUse->size > 0 || pVnode->pMeta->changed ||
|
||||
pVnode->state.applied - pVnode->state.committed > 4096));
|
||||
}
|
||||
taosThreadMutexUnlock(&pVnode->mutex);
|
||||
return needCommit;
|
||||
|
|
|
@ -183,6 +183,11 @@ static int32_t vnodePreProcessDropTtlMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
ttlReq.pTbUids = tbUids;
|
||||
}
|
||||
|
||||
if (ttlReq.nUids == 0) {
|
||||
code = TSDB_CODE_MSG_PREPROCESSED;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
{ // prepare new content
|
||||
int32_t reqLenNew = tSerializeSVDropTtlTableReq(NULL, 0, &ttlReq);
|
||||
int32_t contLenNew = reqLenNew + sizeof(SMsgHead);
|
||||
|
@ -207,7 +212,7 @@ static int32_t vnodePreProcessDropTtlMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
_exit:
|
||||
taosArrayDestroy(tbUids);
|
||||
|
||||
if (code) {
|
||||
if (code && code != TSDB_CODE_MSG_PREPROCESSED) {
|
||||
vError("vgId:%d, %s:%d failed to preprocess drop ttl request since %s, msg type:%s", TD_VID(pVnode), __func__, lino,
|
||||
tstrerror(code), TMSG_INFO(pMsg->msgType));
|
||||
} else {
|
||||
|
@ -464,7 +469,7 @@ int32_t vnodePreProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (code) {
|
||||
if (code && code != TSDB_CODE_MSG_PREPROCESSED) {
|
||||
vError("vgId:%d, failed to preprocess write request since %s, msg type:%s", TD_VID(pVnode), tstrerror(code),
|
||||
TMSG_INFO(pMsg->msgType));
|
||||
}
|
||||
|
|
|
@ -95,6 +95,11 @@ static void inline vnodeHandleWriteMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
static void vnodeHandleProposeError(SVnode *pVnode, SRpcMsg *pMsg, int32_t code) {
|
||||
if (code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_SYN_RESTORING) {
|
||||
vnodeRedirectRpcMsg(pVnode, pMsg, code);
|
||||
} else if (code == TSDB_CODE_MSG_PREPROCESSED) {
|
||||
SRpcMsg rsp = {.code = TSDB_CODE_SUCCESS, .info = pMsg->info};
|
||||
if (rsp.info.handle != NULL) {
|
||||
tmsgSendRsp(&rsp);
|
||||
}
|
||||
} else {
|
||||
const STraceId *trace = &pMsg->info.traceId;
|
||||
vGError("vgId:%d, msg:%p failed to propose since %s, code:0x%x", pVnode->config.vgId, pMsg, tstrerror(code), code);
|
||||
|
@ -297,8 +302,10 @@ void vnodeProposeWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs)
|
|||
|
||||
code = vnodePreProcessWriteMsg(pVnode, pMsg);
|
||||
if (code != 0) {
|
||||
vGError("vgId:%d, msg:%p failed to pre-process since %s", vgId, pMsg, tstrerror(code));
|
||||
if (terrno != 0) code = terrno;
|
||||
if (code != TSDB_CODE_MSG_PREPROCESSED) {
|
||||
vGError("vgId:%d, msg:%p failed to pre-process since %s", vgId, pMsg, tstrerror(code));
|
||||
if (terrno != 0) code = terrno;
|
||||
}
|
||||
vnodeHandleProposeError(pVnode, pMsg, code);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
taosFreeQitem(pMsg);
|
||||
|
@ -759,7 +766,7 @@ void vnodeSyncCheckTimeout(SVnode *pVnode) {
|
|||
vError("vgId:%d, failed to propose since timeout and post block, start:%d cur:%d delta:%d seq:%" PRId64,
|
||||
pVnode->config.vgId, pVnode->blockSec, curSec, delta, pVnode->blockSeq);
|
||||
if (syncSendTimeoutRsp(pVnode->sync, pVnode->blockSeq) != 0) {
|
||||
#if 0
|
||||
#if 0
|
||||
SRpcMsg rpcMsg = {.code = TSDB_CODE_SYN_TIMEOUT, .info = pVnode->blockInfo};
|
||||
vError("send timeout response since its applyed, seq:%" PRId64 " handle:%p ahandle:%p", pVnode->blockSeq,
|
||||
rpcMsg.info.handle, rpcMsg.info.ahandle);
|
||||
|
|
|
@ -1858,7 +1858,7 @@ STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowI
|
|||
STimeWindow w = {0};
|
||||
if (pResultRowInfo->cur.pageId == -1) { // the first window, from the previous stored value
|
||||
getInitialStartTimeWindow(pInterval, ts, &w, (order == TSDB_ORDER_ASC));
|
||||
w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
w.ekey = taosTimeGetIntervalEnd(w.skey, pInterval);
|
||||
return w;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
typedef struct SSessionAggOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SAggSupporter aggSup;
|
||||
SExprSupp scalarSupp; // supporter for perform scalar function
|
||||
SGroupResInfo groupResInfo;
|
||||
SWindowRowsSup winSup;
|
||||
bool reptScan; // next round scan
|
||||
|
@ -1407,6 +1408,10 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
pBInfo->pRes->info.scanFlag = pBlock->info.scanFlag;
|
||||
if (pInfo->scalarSupp.pExprInfo != NULL) {
|
||||
SExprSupp* pExprSup = &pInfo->scalarSupp;
|
||||
projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL);
|
||||
}
|
||||
// the pDataBlock are always the same one, no need to call this again
|
||||
setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true);
|
||||
blockDataUpdateTsWindow(pBlock, pInfo->tsSlotId);
|
||||
|
@ -1531,6 +1536,8 @@ void destroySWindowOperatorInfo(void* param) {
|
|||
colDataDestroy(&pInfo->twAggSup.timeWindowData);
|
||||
|
||||
cleanupAggSup(&pInfo->aggSup);
|
||||
cleanupExprSupp(&pInfo->scalarSupp);
|
||||
|
||||
cleanupGroupResInfo(&pInfo->groupResInfo);
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
@ -1570,6 +1577,16 @@ SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SSessionW
|
|||
pInfo->reptScan = false;
|
||||
pInfo->binfo.inputTsOrder = pSessionNode->window.node.inputTsOrder;
|
||||
pInfo->binfo.outputTsOrder = pSessionNode->window.node.outputTsOrder;
|
||||
|
||||
if (pSessionNode->window.pExprs != NULL) {
|
||||
int32_t numOfScalar = 0;
|
||||
SExprInfo* pScalarExprInfo = createExprInfo(pSessionNode->window.pExprs, NULL, &numOfScalar);
|
||||
code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
}
|
||||
|
||||
code = filterInitFromNode((SNode*)pSessionNode->window.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "thash.h"
|
||||
#include "tsimplehash.h"
|
||||
#include "executor.h"
|
||||
#include "executorInt.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
|
@ -186,4 +187,20 @@ TEST(testCase, timewindow_natural) {
|
|||
ASSERT_EQ(w3.skey, w4.skey);
|
||||
ASSERT_EQ(w3.ekey, w4.ekey);
|
||||
}
|
||||
|
||||
|
||||
TEST(testCase, timewindow_active) {
|
||||
osSetTimezone("CST");
|
||||
int32_t precision = TSDB_TIME_PRECISION_MILLI;
|
||||
int64_t offset = (int64_t)2*365*24*60*60*1000;
|
||||
SInterval interval = createInterval(10, 10, offset, 'y', 'y', 0, precision);
|
||||
SResultRowInfo dumyInfo = {0};
|
||||
dumyInfo.cur.pageId = -1;
|
||||
int64_t key = (int64_t)1609430400*1000; // 2021-01-01
|
||||
STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, key, &interval, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&win, precision, key);
|
||||
printf("%ld win %ld, %ld\n", key, win.skey, win.ekey);
|
||||
ASSERT_EQ(win.skey, 1325376000000);
|
||||
ASSERT_EQ(win.ekey, 1640908799999);
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
|
@ -214,14 +214,15 @@ void nodesWalkExprsPostOrder(SNodeList* pList, FNodeWalker walker, void* pContex
|
|||
(void)walkExprs(pList, TRAVERSAL_POSTORDER, walker, pContext);
|
||||
}
|
||||
|
||||
static void checkParamIsFunc(SFunctionNode *pFunc) {
|
||||
static void checkParamIsFunc(SFunctionNode* pFunc) {
|
||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||
if (numOfParams > 1) {
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, i);
|
||||
if (nodeType(pPara) == QUERY_NODE_FUNCTION) {
|
||||
((SFunctionNode *)pPara)->node.asParam = true;
|
||||
}
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, i);
|
||||
if (numOfParams > 1 && nodeType(pPara) == QUERY_NODE_FUNCTION) {
|
||||
((SFunctionNode*)pPara)->node.asParam = true;
|
||||
}
|
||||
if (nodeType(pPara) == QUERY_NODE_COLUMN) {
|
||||
((SColumnNode*)pPara)->node.asParam = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1341,7 +1341,7 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) {
|
|||
res = translateColumnWithPrefix(pCxt, pCol);
|
||||
} else {
|
||||
bool found = false;
|
||||
if (SQL_CLAUSE_ORDER_BY == pCxt->currClause) {
|
||||
if (SQL_CLAUSE_ORDER_BY == pCxt->currClause && !(*pCol)->node.asParam) {
|
||||
res = translateColumnUseAlias(pCxt, pCol, &found);
|
||||
}
|
||||
if (DEAL_RES_ERROR != res && !found) {
|
||||
|
@ -1351,6 +1351,10 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) {
|
|||
res = translateColumnWithoutPrefix(pCxt, pCol);
|
||||
}
|
||||
}
|
||||
if(SQL_CLAUSE_ORDER_BY == pCxt->currClause && !(*pCol)->node.asParam
|
||||
&& res != DEAL_RES_CONTINUE && res != DEAL_RES_END) {
|
||||
res = translateColumnUseAlias(pCxt, pCol, &found);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -3999,6 +4003,42 @@ static int32_t translateSpecificWindow(STranslateContext* pCxt, SSelectStmt* pSe
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static EDealRes collectWindowsPseudocolumns(SNode* pNode, void* pContext) {
|
||||
SNodeList* pCols = (SNodeList*)pContext;
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
if (FUNCTION_TYPE_WSTART == pFunc->funcType || FUNCTION_TYPE_WEND == pFunc->funcType ||
|
||||
FUNCTION_TYPE_WDURATION == pFunc->funcType) {
|
||||
nodesListStrictAppend(pCols, nodesCloneNode(pNode));
|
||||
}
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t checkWindowsConditonValid(SNode* pNode) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if(QUERY_NODE_EVENT_WINDOW != nodeType(pNode)) return code;
|
||||
|
||||
SEventWindowNode* pEventWindowNode = (SEventWindowNode*)pNode;
|
||||
SNodeList* pCols = nodesMakeList();
|
||||
if (NULL == pCols) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
nodesWalkExpr(pEventWindowNode->pStartCond, collectWindowsPseudocolumns, pCols);
|
||||
if (pCols->length > 0) {
|
||||
code = TSDB_CODE_QRY_INVALID_WINDOW_CONDITION;
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
nodesWalkExpr(pEventWindowNode->pEndCond, collectWindowsPseudocolumns, pCols);
|
||||
if (pCols->length > 0) {
|
||||
code = TSDB_CODE_QRY_INVALID_WINDOW_CONDITION;
|
||||
}
|
||||
}
|
||||
|
||||
nodesDestroyList(pCols);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t translateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL == pSelect->pWindow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -4012,6 +4052,9 @@ static int32_t translateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateSpecificWindow(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkWindowsConditonValid(pSelect->pWindow);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -4533,6 +4576,9 @@ static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
|
|||
FOREACH(pProject, pProjectionList) {
|
||||
SExprNode* pExpr = (SExprNode*)pProject;
|
||||
if (0 == strcmp(((SColumnRefNode*)*pNode)->colName, pExpr->userAlias) && nodeType(*pNode) == nodeType(pProject)) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pProject) && !nodesEqualNode(*pNode, pProject)) {
|
||||
continue;
|
||||
}
|
||||
SNode* pNew = nodesCloneNode(pProject);
|
||||
if (NULL == pNew) {
|
||||
pCxt->pTranslateCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
|
|
@ -338,6 +338,7 @@ static void scanPathOptSetScanOrder(EScanOrder scanOrder, SScanLogicNode* pScan)
|
|||
if (pScan->sortPrimaryKey || pScan->scanSeq[0] > 1 || pScan->scanSeq[1] > 1) {
|
||||
return;
|
||||
}
|
||||
pScan->node.outputTsOrder = (SCAN_ORDER_ASC == scanOrder) ? ORDER_ASC : ORDER_DESC;
|
||||
switch (scanOrder) {
|
||||
case SCAN_ORDER_ASC:
|
||||
pScan->scanSeq[0] = 1;
|
||||
|
@ -1450,6 +1451,132 @@ static int32_t sortPrimaryKeyOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLo
|
|||
return sortPrimaryKeyOptimizeImpl(pCxt, pLogicSubplan, pSort);
|
||||
}
|
||||
|
||||
static int32_t sortForJoinOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SJoinLogicNode* pJoin) {
|
||||
SLogicNode* pLeft = (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0);
|
||||
SLogicNode* pRight = (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1);
|
||||
SScanLogicNode* pScan = NULL;
|
||||
|
||||
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pLeft) && ((SScanLogicNode*)pLeft)->node.outputTsOrder != SCAN_ORDER_BOTH) {
|
||||
pScan = (SScanLogicNode*)pLeft;
|
||||
} else if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pRight) && ((SScanLogicNode*)pRight)->node.outputTsOrder != SCAN_ORDER_BOTH) {
|
||||
pScan = (SScanLogicNode*)pRight;
|
||||
}
|
||||
|
||||
if (NULL != pScan) {
|
||||
switch (pScan->node.outputTsOrder) {
|
||||
case SCAN_ORDER_ASC:
|
||||
pScan->scanSeq[0] = 0;
|
||||
pScan->scanSeq[1] = 1;
|
||||
pScan->node.outputTsOrder = ORDER_DESC;
|
||||
goto _return;
|
||||
case SCAN_ORDER_DESC:
|
||||
pScan->scanSeq[0] = 1;
|
||||
pScan->scanSeq[1] = 0;
|
||||
pScan->node.outputTsOrder = ORDER_ASC;
|
||||
goto _return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (QUERY_NODE_OPERATOR != nodeType(pJoin->pPrimKeyEqCond)) {
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
bool res = false;
|
||||
SOperatorNode* pOp = (SOperatorNode*)pJoin->pPrimKeyEqCond;
|
||||
if (QUERY_NODE_COLUMN != nodeType(pOp->pLeft) || QUERY_NODE_COLUMN != nodeType(pOp->pRight)) {
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
SNode* pOrderByNode = NULL;
|
||||
SSHashObj* pLeftTables = NULL;
|
||||
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 0), &pLeftTables);
|
||||
|
||||
if (NULL != tSimpleHashGet(pLeftTables, ((SColumnNode*)pOp->pLeft)->tableAlias, strlen(((SColumnNode*)pOp->pLeft)->tableAlias))) {
|
||||
pOrderByNode = pOp->pLeft;
|
||||
} else if (NULL != tSimpleHashGet(pLeftTables, ((SColumnNode*)pOp->pRight)->tableAlias, strlen(((SColumnNode*)pOp->pRight)->tableAlias))) {
|
||||
pOrderByNode = pOp->pRight;
|
||||
}
|
||||
|
||||
tSimpleHashCleanup(pLeftTables);
|
||||
|
||||
if (NULL == pOrderByNode) {
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
SSortLogicNode* pSort = (SSortLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SORT);
|
||||
if (NULL == pSort) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pSort->node.outputTsOrder = (ORDER_ASC == pLeft->outputTsOrder) ? ORDER_DESC : ORDER_ASC;
|
||||
pSort->groupSort = false;
|
||||
SOrderByExprNode* pOrder = (SOrderByExprNode*)nodesMakeNode(QUERY_NODE_ORDER_BY_EXPR);
|
||||
if (NULL == pOrder) {
|
||||
nodesDestroyNode((SNode *)pSort);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nodesListMakeAppend(&pSort->pSortKeys, (SNode*)pOrder);
|
||||
pOrder->order = (ORDER_ASC == pLeft->outputTsOrder) ? ORDER_DESC : ORDER_ASC;
|
||||
pOrder->pExpr = nodesCloneNode(pOrderByNode);
|
||||
pOrder->nullOrder = (ORDER_ASC == pOrder->order) ? NULL_ORDER_FIRST : NULL_ORDER_LAST;
|
||||
if (!pOrder->pExpr) {
|
||||
nodesDestroyNode((SNode *)pSort);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pLeft->pParent = (SLogicNode*)pSort;
|
||||
nodesListMakeAppend(&pSort->node.pChildren, (SNode*)pLeft);
|
||||
pJoin->node.pChildren->pHead->pNode = (SNode*)pSort;
|
||||
pSort->node.pParent = (SLogicNode*)pJoin;;
|
||||
|
||||
_return:
|
||||
|
||||
pCxt->optimized = true;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static bool sortForJoinOptMayBeOptimized(SLogicNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_JOIN != nodeType(pNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SJoinLogicNode* pJoin = (SJoinLogicNode*)pNode;
|
||||
if (pNode->pChildren->length != 2 || !pJoin->hasSubQuery || pJoin->isLowLevelJoin) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SLogicNode* pLeft = (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0);
|
||||
SLogicNode* pRight = (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1);
|
||||
|
||||
if (ORDER_ASC != pLeft->outputTsOrder && ORDER_DESC != pLeft->outputTsOrder) {
|
||||
return false;
|
||||
}
|
||||
if (ORDER_ASC != pRight->outputTsOrder && ORDER_DESC != pRight->outputTsOrder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pLeft->outputTsOrder == pRight->outputTsOrder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int32_t sortForJoinOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||
SJoinLogicNode* pJoin = (SJoinLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, sortForJoinOptMayBeOptimized);
|
||||
if (NULL == pJoin) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
return sortForJoinOptimizeImpl(pCxt, pLogicSubplan, pJoin);
|
||||
}
|
||||
|
||||
|
||||
static bool smaIndexOptMayBeOptimized(SLogicNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(pNode) || NULL == pNode->pParent ||
|
||||
QUERY_NODE_LOGIC_PLAN_WINDOW != nodeType(pNode->pParent) ||
|
||||
|
@ -4197,6 +4324,7 @@ static const SOptimizeRule optimizeRuleSet[] = {
|
|||
{.pName = "StableJoin", .optimizeFunc = stableJoinOptimize},
|
||||
{.pName = "sortNonPriKeyOptimize", .optimizeFunc = sortNonPriKeyOptimize},
|
||||
{.pName = "SortPrimaryKey", .optimizeFunc = sortPrimaryKeyOptimize},
|
||||
{.pName = "SortForjoin", .optimizeFunc = sortForJoinOptimize},
|
||||
{.pName = "SmaIndex", .optimizeFunc = smaIndexOptimize},
|
||||
{.pName = "PushDownLimit", .optimizeFunc = pushDownLimitOptimize},
|
||||
{.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
||||
|
|
|
@ -1064,9 +1064,8 @@ static int32_t stbSplCreateMergeKeys(SNodeList* pSortKeys, SNodeList* pTargets,
|
|||
SNode* pTarget = NULL;
|
||||
bool found = false;
|
||||
FOREACH(pTarget, pTargets) {
|
||||
if ((QUERY_NODE_COLUMN == nodeType(pSortExpr) && nodesEqualNode((SNode*)pSortExpr, pTarget))
|
||||
// || (0 == strcmp(pSortExpr->aliasName, ((SColumnNode*)pTarget)->colName))
|
||||
) {
|
||||
if ((QUERY_NODE_COLUMN == nodeType(pSortExpr) && nodesEqualNode((SNode*)pSortExpr, pTarget)) ||
|
||||
(0 == strcmp(pSortExpr->aliasName, ((SColumnNode*)pTarget)->colName))) {
|
||||
code = nodesListMakeStrictAppend(&pMergeKeys, stbSplCreateOrderByExpr(pSortKey, pTarget));
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
break;
|
||||
|
|
|
@ -386,10 +386,13 @@ _return:
|
|||
int32_t schDumpJobExecRes(SSchJob *pJob, SExecResult *pRes) {
|
||||
pRes->code = atomic_load_32(&pJob->errCode);
|
||||
pRes->numOfRows = pJob->resNumOfRows;
|
||||
|
||||
SCH_LOCK(SCH_WRITE, &pJob->resLock);
|
||||
pRes->res = pJob->execRes.res;
|
||||
pRes->msgType = pJob->execRes.msgType;
|
||||
pRes->numOfBytes = pJob->execRes.numOfBytes;
|
||||
pJob->execRes.res = NULL;
|
||||
SCH_UNLOCK(SCH_WRITE, &pJob->resLock);
|
||||
|
||||
SCH_JOB_DLOG("execRes dumped, code: %s", tstrerror(pRes->code));
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "syncUtil.h"
|
||||
#include "syncVoteMgr.h"
|
||||
#include "tglobal.h"
|
||||
#include "tmisce.h"
|
||||
#include "tref.h"
|
||||
|
||||
static void syncNodeEqPingTimer(void* param, void* tmrId);
|
||||
|
@ -106,7 +107,7 @@ _err:
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t syncNodeGetConfig(int64_t rid, SSyncCfg *cfg){
|
||||
int32_t syncNodeGetConfig(int64_t rid, SSyncCfg* cfg) {
|
||||
SSyncNode* pSyncNode = syncNodeAcquire(rid);
|
||||
|
||||
if (pSyncNode == NULL) {
|
||||
|
@ -546,7 +547,7 @@ SSyncState syncGetState(int64_t rid) {
|
|||
state.progress = -1;
|
||||
}
|
||||
sDebug("vgId:%d, learner progress state, commitIndex:%" PRId64 " totalIndex:%" PRId64 ", "
|
||||
"progress:%lf, progress:%d",
|
||||
"progress:%lf, progress:%d",
|
||||
pSyncNode->vgId,
|
||||
pSyncNode->pLogBuf->commitIndex, pSyncNode->pLogBuf->totalIndex, progress, state.progress);
|
||||
*/
|
||||
|
@ -579,17 +580,21 @@ void syncGetRetryEpSet(int64_t rid, SEpSet* pEpSet) {
|
|||
SSyncNode* pSyncNode = syncNodeAcquire(rid);
|
||||
if (pSyncNode == NULL) return;
|
||||
|
||||
int j = 0;
|
||||
for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.totalReplicaNum; ++i) {
|
||||
if (pSyncNode->raftCfg.cfg.nodeInfo[i].nodeRole == TAOS_SYNC_ROLE_LEARNER) continue;
|
||||
SEp* pEp = &pEpSet->eps[i];
|
||||
SEp* pEp = &pEpSet->eps[j];
|
||||
tstrncpy(pEp->fqdn, pSyncNode->raftCfg.cfg.nodeInfo[i].nodeFqdn, TSDB_FQDN_LEN);
|
||||
pEp->port = (pSyncNode->raftCfg.cfg.nodeInfo)[i].nodePort;
|
||||
pEpSet->numOfEps++;
|
||||
sDebug("vgId:%d, sync get retry epset, index:%d %s:%d", pSyncNode->vgId, i, pEp->fqdn, pEp->port);
|
||||
j++;
|
||||
}
|
||||
if (pEpSet->numOfEps > 0) {
|
||||
pEpSet->inUse = (pSyncNode->raftCfg.cfg.myIndex + 1) % pEpSet->numOfEps;
|
||||
// pEpSet->inUse = 0;
|
||||
}
|
||||
epsetSort(pEpSet);
|
||||
|
||||
sInfo("vgId:%d, sync get retry epset numOfEps:%d inUse:%d", pSyncNode->vgId, pEpSet->numOfEps, pEpSet->inUse);
|
||||
syncNodeRelease(pSyncNode);
|
||||
|
@ -614,7 +619,7 @@ int32_t syncCheckMember(int64_t rid) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if(pSyncNode->myNodeInfo.nodeRole == TAOS_SYNC_ROLE_LEARNER){
|
||||
if (pSyncNode->myNodeInfo.nodeRole == TAOS_SYNC_ROLE_LEARNER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -682,24 +687,24 @@ int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak, int64_
|
|||
}
|
||||
|
||||
// optimized one replica
|
||||
if (syncNodeIsOptimizedOneReplica(pSyncNode, pMsg)) {
|
||||
if (syncNodeIsOptimizedOneReplica(pSyncNode, pMsg)) {
|
||||
SyncIndex retIndex;
|
||||
int32_t code = syncNodeOnClientRequest(pSyncNode, pMsg, &retIndex);
|
||||
if (code >= 0) {
|
||||
pMsg->info.conn.applyIndex = retIndex;
|
||||
pMsg->info.conn.applyTerm = raftStoreGetTerm(pSyncNode);
|
||||
|
||||
//after raft member change, need to handle 1->2 switching point
|
||||
//at this point, need to switch entry handling thread
|
||||
if(pSyncNode->replicaNum == 1){
|
||||
// after raft member change, need to handle 1->2 switching point
|
||||
// at this point, need to switch entry handling thread
|
||||
if (pSyncNode->replicaNum == 1) {
|
||||
sTrace("vgId:%d, propose optimized msg, index:%" PRId64 " type:%s", pSyncNode->vgId, retIndex,
|
||||
TMSG_INFO(pMsg->msgType));
|
||||
TMSG_INFO(pMsg->msgType));
|
||||
return 1;
|
||||
}
|
||||
else{
|
||||
sTrace("vgId:%d, propose optimized msg, return to normal, index:%" PRId64 " type:%s, "
|
||||
"handle:%p", pSyncNode->vgId, retIndex,
|
||||
TMSG_INFO(pMsg->msgType), pMsg->info.handle);
|
||||
} else {
|
||||
sTrace("vgId:%d, propose optimized msg, return to normal, index:%" PRId64
|
||||
" type:%s, "
|
||||
"handle:%p",
|
||||
pSyncNode->vgId, retIndex, TMSG_INFO(pMsg->msgType), pMsg->info.handle);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
|
@ -844,7 +849,7 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo, int32_t vnodeVersion) {
|
|||
goto _error;
|
||||
}
|
||||
|
||||
if(vnodeVersion > pSyncNode->raftCfg.cfg.changeVersion){
|
||||
if (vnodeVersion > pSyncNode->raftCfg.cfg.changeVersion) {
|
||||
if (pSyncInfo->syncCfg.totalReplicaNum > 0 && syncIsConfigChanged(&pSyncNode->raftCfg.cfg, &pSyncInfo->syncCfg)) {
|
||||
sInfo("vgId:%d, use sync config from input options and write to cfg file", pSyncNode->vgId);
|
||||
pSyncNode->raftCfg.cfg = pSyncInfo->syncCfg;
|
||||
|
@ -856,15 +861,13 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo, int32_t vnodeVersion) {
|
|||
sInfo("vgId:%d, use sync config from sync cfg file", pSyncNode->vgId);
|
||||
pSyncInfo->syncCfg = pSyncNode->raftCfg.cfg;
|
||||
}
|
||||
}
|
||||
else{
|
||||
sInfo("vgId:%d, skip save sync cfg file since request ver:%d <= file ver:%d",
|
||||
pSyncNode->vgId, vnodeVersion, pSyncInfo->syncCfg.changeVersion);
|
||||
} else {
|
||||
sInfo("vgId:%d, skip save sync cfg file since request ver:%d <= file ver:%d", pSyncNode->vgId, vnodeVersion,
|
||||
pSyncInfo->syncCfg.changeVersion);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// init by SSyncInfo
|
||||
// init by SSyncInfo
|
||||
pSyncNode->vgId = pSyncInfo->vgId;
|
||||
SSyncCfg* pCfg = &pSyncNode->raftCfg.cfg;
|
||||
bool updated = false;
|
||||
|
@ -879,7 +882,7 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo, int32_t vnodeVersion) {
|
|||
pNode->nodeId, pNode->clusterId);
|
||||
}
|
||||
|
||||
if(vnodeVersion > pSyncInfo->syncCfg.changeVersion){
|
||||
if (vnodeVersion > pSyncInfo->syncCfg.changeVersion) {
|
||||
if (updated) {
|
||||
sInfo("vgId:%d, save config info since dnode info changed", pSyncNode->vgId);
|
||||
if (syncWriteCfgFile(pSyncNode) != 0) {
|
||||
|
@ -888,7 +891,7 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo, int32_t vnodeVersion) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pSyncNode->pWal = pSyncInfo->pWal;
|
||||
pSyncNode->msgcb = pSyncInfo->msgcb;
|
||||
pSyncNode->syncSendMSg = pSyncInfo->syncSendMSg;
|
||||
|
@ -2335,47 +2338,49 @@ int32_t syncCacheEntry(SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry, LRUHand
|
|||
return code;
|
||||
}
|
||||
|
||||
void syncBuildConfigFromReq(SAlterVnodeReplicaReq *pReq, SSyncCfg *cfg){//TODO SAlterVnodeReplicaReq name is proper?
|
||||
void syncBuildConfigFromReq(SAlterVnodeReplicaReq* pReq, SSyncCfg* cfg) { // TODO SAlterVnodeReplicaReq name is proper?
|
||||
cfg->replicaNum = 0;
|
||||
cfg->totalReplicaNum = 0;
|
||||
|
||||
for (int i = 0; i < pReq->replica; ++i) {
|
||||
SNodeInfo *pNode = &cfg->nodeInfo[i];
|
||||
SNodeInfo* pNode = &cfg->nodeInfo[i];
|
||||
pNode->nodeId = pReq->replicas[i].id;
|
||||
pNode->nodePort = pReq->replicas[i].port;
|
||||
tstrncpy(pNode->nodeFqdn, pReq->replicas[i].fqdn, sizeof(pNode->nodeFqdn));
|
||||
pNode->nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
(void)tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort);
|
||||
sInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d nodeRole:%d", pReq->vgId, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId, pNode->nodeRole);
|
||||
sInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d nodeRole:%d", pReq->vgId, i, pNode->nodeFqdn, pNode->nodePort,
|
||||
pNode->nodeId, pNode->nodeRole);
|
||||
cfg->replicaNum++;
|
||||
}
|
||||
if(pReq->selfIndex != -1){
|
||||
if (pReq->selfIndex != -1) {
|
||||
cfg->myIndex = pReq->selfIndex;
|
||||
}
|
||||
for (int i = cfg->replicaNum; i < pReq->replica + pReq->learnerReplica; ++i) {
|
||||
SNodeInfo *pNode = &cfg->nodeInfo[i];
|
||||
SNodeInfo* pNode = &cfg->nodeInfo[i];
|
||||
pNode->nodeId = pReq->learnerReplicas[cfg->totalReplicaNum].id;
|
||||
pNode->nodePort = pReq->learnerReplicas[cfg->totalReplicaNum].port;
|
||||
pNode->nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
tstrncpy(pNode->nodeFqdn, pReq->learnerReplicas[cfg->totalReplicaNum].fqdn, sizeof(pNode->nodeFqdn));
|
||||
(void)tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort);
|
||||
sInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d nodeRole:%d", pReq->vgId, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId, pNode->nodeRole);
|
||||
sInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d nodeRole:%d", pReq->vgId, i, pNode->nodeFqdn, pNode->nodePort,
|
||||
pNode->nodeId, pNode->nodeRole);
|
||||
cfg->totalReplicaNum++;
|
||||
}
|
||||
cfg->totalReplicaNum += pReq->replica;
|
||||
if(pReq->learnerSelfIndex != -1){
|
||||
if (pReq->learnerSelfIndex != -1) {
|
||||
cfg->myIndex = pReq->replica + pReq->learnerSelfIndex;
|
||||
}
|
||||
cfg->changeVersion = pReq->changeVersion;
|
||||
}
|
||||
|
||||
int32_t syncNodeCheckChangeConfig(SSyncNode* ths, SSyncRaftEntry* pEntry){
|
||||
if(pEntry->originalRpcType != TDMT_SYNC_CONFIG_CHANGE){
|
||||
int32_t syncNodeCheckChangeConfig(SSyncNode* ths, SSyncRaftEntry* pEntry) {
|
||||
if (pEntry->originalRpcType != TDMT_SYNC_CONFIG_CHANGE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SMsgHead *head = (SMsgHead *)pEntry->data;
|
||||
void *pReq = POINTER_SHIFT(head, sizeof(SMsgHead));
|
||||
SMsgHead* head = (SMsgHead*)pEntry->data;
|
||||
void* pReq = POINTER_SHIFT(head, sizeof(SMsgHead));
|
||||
|
||||
SAlterVnodeTypeReq req = {0};
|
||||
if (tDeserializeSAlterVnodeReplicaReq(pReq, head->contLen, &req) != 0) {
|
||||
|
@ -2386,17 +2391,17 @@ int32_t syncNodeCheckChangeConfig(SSyncNode* ths, SSyncRaftEntry* pEntry){
|
|||
SSyncCfg cfg = {0};
|
||||
syncBuildConfigFromReq(&req, &cfg);
|
||||
|
||||
if(cfg.totalReplicaNum >= 1 && ths->state == TAOS_SYNC_STATE_LEADER){
|
||||
if (cfg.totalReplicaNum >= 1 && ths->state == TAOS_SYNC_STATE_LEADER) {
|
||||
bool incfg = false;
|
||||
for(int32_t j = 0; j < cfg.totalReplicaNum; ++j){
|
||||
if(strcmp(ths->myNodeInfo.nodeFqdn, cfg.nodeInfo[j].nodeFqdn) == 0
|
||||
&& ths->myNodeInfo.nodePort == cfg.nodeInfo[j].nodePort){
|
||||
for (int32_t j = 0; j < cfg.totalReplicaNum; ++j) {
|
||||
if (strcmp(ths->myNodeInfo.nodeFqdn, cfg.nodeInfo[j].nodeFqdn) == 0 &&
|
||||
ths->myNodeInfo.nodePort == cfg.nodeInfo[j].nodePort) {
|
||||
incfg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!incfg){
|
||||
if (!incfg) {
|
||||
SyncTerm currentTerm = raftStoreGetTerm(ths);
|
||||
syncNodeStepDown(ths, currentTerm);
|
||||
return 1;
|
||||
|
@ -2405,26 +2410,25 @@ int32_t syncNodeCheckChangeConfig(SSyncNode* ths, SSyncRaftEntry* pEntry){
|
|||
return 0;
|
||||
}
|
||||
|
||||
void syncNodeLogConfigInfo(SSyncNode* ths, SSyncCfg *cfg, char *str){
|
||||
sInfo("vgId:%d, %s. SyncNode, replicaNum:%d, peersNum:%d, lastConfigIndex:%" PRId64 ", changeVersion:%d, "
|
||||
"restoreFinish:%d",
|
||||
ths->vgId, str,
|
||||
ths->replicaNum, ths->peersNum, ths->raftCfg.lastConfigIndex, ths->raftCfg.cfg.changeVersion,
|
||||
void syncNodeLogConfigInfo(SSyncNode* ths, SSyncCfg* cfg, char* str) {
|
||||
sInfo("vgId:%d, %s. SyncNode, replicaNum:%d, peersNum:%d, lastConfigIndex:%" PRId64
|
||||
", changeVersion:%d, "
|
||||
"restoreFinish:%d",
|
||||
ths->vgId, str, ths->replicaNum, ths->peersNum, ths->raftCfg.lastConfigIndex, ths->raftCfg.cfg.changeVersion,
|
||||
ths->restoreFinish);
|
||||
|
||||
sInfo("vgId:%d, %s, myNodeInfo, clusterId:%" PRId64 ", nodeId:%d, Fqdn:%s, port:%d, role:%d",
|
||||
ths->vgId, str, ths->myNodeInfo.clusterId, ths->myNodeInfo.nodeId, ths->myNodeInfo.nodeFqdn,
|
||||
ths->myNodeInfo.nodePort, ths->myNodeInfo.nodeRole);
|
||||
sInfo("vgId:%d, %s, myNodeInfo, clusterId:%" PRId64 ", nodeId:%d, Fqdn:%s, port:%d, role:%d", ths->vgId, str,
|
||||
ths->myNodeInfo.clusterId, ths->myNodeInfo.nodeId, ths->myNodeInfo.nodeFqdn, ths->myNodeInfo.nodePort,
|
||||
ths->myNodeInfo.nodeRole);
|
||||
|
||||
for (int32_t i = 0; i < ths->peersNum; ++i){
|
||||
sInfo("vgId:%d, %s, peersNodeInfo%d, clusterId:%" PRId64 ", nodeId:%d, Fqdn:%s, port:%d, role:%d",
|
||||
ths->vgId, str, i, ths->peersNodeInfo[i].clusterId,
|
||||
ths->peersNodeInfo[i].nodeId, ths->peersNodeInfo[i].nodeFqdn,
|
||||
ths->peersNodeInfo[i].nodePort, ths->peersNodeInfo[i].nodeRole);
|
||||
for (int32_t i = 0; i < ths->peersNum; ++i) {
|
||||
sInfo("vgId:%d, %s, peersNodeInfo%d, clusterId:%" PRId64 ", nodeId:%d, Fqdn:%s, port:%d, role:%d", ths->vgId, str,
|
||||
i, ths->peersNodeInfo[i].clusterId, ths->peersNodeInfo[i].nodeId, ths->peersNodeInfo[i].nodeFqdn,
|
||||
ths->peersNodeInfo[i].nodePort, ths->peersNodeInfo[i].nodeRole);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < ths->peersNum; ++i){
|
||||
char buf[256];
|
||||
for (int32_t i = 0; i < ths->peersNum; ++i) {
|
||||
char buf[256];
|
||||
int32_t len = 256;
|
||||
int32_t n = 0;
|
||||
n += snprintf(buf + n, len - n, "%s", "{");
|
||||
|
@ -2434,37 +2438,33 @@ void syncNodeLogConfigInfo(SSyncNode* ths, SSyncCfg *cfg, char *str){
|
|||
}
|
||||
n += snprintf(buf + n, len - n, "%s", "}");
|
||||
|
||||
sInfo("vgId:%d, %s, peersEpset%d, %s, inUse:%d",
|
||||
ths->vgId, str, i, buf, ths->peersEpset->inUse);
|
||||
sInfo("vgId:%d, %s, peersEpset%d, %s, inUse:%d", ths->vgId, str, i, buf, ths->peersEpset->inUse);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < ths->peersNum; ++i){
|
||||
sInfo("vgId:%d, %s, peersId%d, addr:%"PRId64,
|
||||
ths->vgId, str, i, ths->peersId[i].addr);
|
||||
for (int32_t i = 0; i < ths->peersNum; ++i) {
|
||||
sInfo("vgId:%d, %s, peersId%d, addr:%" PRId64, ths->vgId, str, i, ths->peersId[i].addr);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < ths->raftCfg.cfg.totalReplicaNum; ++i){
|
||||
sInfo("vgId:%d, %s, nodeInfo%d, clusterId:%" PRId64 ", nodeId:%d, Fqdn:%s, port:%d, role:%d",
|
||||
ths->vgId, str, i, ths->raftCfg.cfg.nodeInfo[i].clusterId,
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodeId, ths->raftCfg.cfg.nodeInfo[i].nodeFqdn,
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodePort, ths->raftCfg.cfg.nodeInfo[i].nodeRole);
|
||||
for (int32_t i = 0; i < ths->raftCfg.cfg.totalReplicaNum; ++i) {
|
||||
sInfo("vgId:%d, %s, nodeInfo%d, clusterId:%" PRId64 ", nodeId:%d, Fqdn:%s, port:%d, role:%d", ths->vgId, str, i,
|
||||
ths->raftCfg.cfg.nodeInfo[i].clusterId, ths->raftCfg.cfg.nodeInfo[i].nodeId,
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodeFqdn, ths->raftCfg.cfg.nodeInfo[i].nodePort,
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodeRole);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < ths->raftCfg.cfg.totalReplicaNum; ++i){
|
||||
sInfo("vgId:%d, %s, replicasId%d, addr:%" PRId64,
|
||||
ths->vgId, str, i, ths->replicasId[i].addr);
|
||||
for (int32_t i = 0; i < ths->raftCfg.cfg.totalReplicaNum; ++i) {
|
||||
sInfo("vgId:%d, %s, replicasId%d, addr:%" PRId64, ths->vgId, str, i, ths->replicasId[i].addr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int32_t syncNodeRebuildPeerAndCfg(SSyncNode* ths, SSyncCfg *cfg){
|
||||
int32_t syncNodeRebuildPeerAndCfg(SSyncNode* ths, SSyncCfg* cfg) {
|
||||
int32_t i = 0;
|
||||
|
||||
//change peersNodeInfo
|
||||
// change peersNodeInfo
|
||||
i = 0;
|
||||
for(int32_t j = 0; j < cfg->totalReplicaNum; ++j){
|
||||
if(!(strcmp(ths->myNodeInfo.nodeFqdn, cfg->nodeInfo[j].nodeFqdn) == 0
|
||||
&& ths->myNodeInfo.nodePort == cfg->nodeInfo[j].nodePort)){
|
||||
for (int32_t j = 0; j < cfg->totalReplicaNum; ++j) {
|
||||
if (!(strcmp(ths->myNodeInfo.nodeFqdn, cfg->nodeInfo[j].nodeFqdn) == 0 &&
|
||||
ths->myNodeInfo.nodePort == cfg->nodeInfo[j].nodePort)) {
|
||||
ths->peersNodeInfo[i].nodeRole = cfg->nodeInfo[j].nodeRole;
|
||||
ths->peersNodeInfo[i].clusterId = cfg->nodeInfo[j].clusterId;
|
||||
tstrncpy(ths->peersNodeInfo[i].nodeFqdn, cfg->nodeInfo[j].nodeFqdn, TSDB_FQDN_LEN);
|
||||
|
@ -2483,11 +2483,11 @@ int32_t syncNodeRebuildPeerAndCfg(SSyncNode* ths, SSyncCfg *cfg){
|
|||
}
|
||||
ths->peersNum = i;
|
||||
|
||||
//change cfg nodeInfo
|
||||
// change cfg nodeInfo
|
||||
ths->raftCfg.cfg.replicaNum = 0;
|
||||
i = 0;
|
||||
for(int32_t j = 0; j < cfg->totalReplicaNum; ++j) {
|
||||
if(cfg->nodeInfo[j].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
for (int32_t j = 0; j < cfg->totalReplicaNum; ++j) {
|
||||
if (cfg->nodeInfo[j].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
ths->raftCfg.cfg.replicaNum++;
|
||||
}
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodeRole = cfg->nodeInfo[j].nodeRole;
|
||||
|
@ -2495,9 +2495,9 @@ int32_t syncNodeRebuildPeerAndCfg(SSyncNode* ths, SSyncCfg *cfg){
|
|||
tstrncpy(ths->raftCfg.cfg.nodeInfo[i].nodeFqdn, cfg->nodeInfo[j].nodeFqdn, TSDB_FQDN_LEN);
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodeId = cfg->nodeInfo[j].nodeId;
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodePort = cfg->nodeInfo[j].nodePort;
|
||||
if((strcmp(ths->myNodeInfo.nodeFqdn, cfg->nodeInfo[j].nodeFqdn) == 0
|
||||
&& ths->myNodeInfo.nodePort == cfg->nodeInfo[j].nodePort)){
|
||||
ths->raftCfg.cfg.myIndex = i;
|
||||
if ((strcmp(ths->myNodeInfo.nodeFqdn, cfg->nodeInfo[j].nodeFqdn) == 0 &&
|
||||
ths->myNodeInfo.nodePort == cfg->nodeInfo[j].nodePort)) {
|
||||
ths->raftCfg.cfg.myIndex = i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -2506,26 +2506,26 @@ int32_t syncNodeRebuildPeerAndCfg(SSyncNode* ths, SSyncCfg *cfg){
|
|||
return 0;
|
||||
}
|
||||
|
||||
void syncNodeChangePeerAndCfgToVoter(SSyncNode* ths, SSyncCfg *cfg){
|
||||
//change peersNodeInfo
|
||||
void syncNodeChangePeerAndCfgToVoter(SSyncNode* ths, SSyncCfg* cfg) {
|
||||
// change peersNodeInfo
|
||||
for (int32_t i = 0; i < ths->peersNum; ++i) {
|
||||
for(int32_t j = 0; j < cfg->totalReplicaNum; ++j){
|
||||
if(strcmp(ths->peersNodeInfo[i].nodeFqdn, cfg->nodeInfo[j].nodeFqdn) == 0
|
||||
&& ths->peersNodeInfo[i].nodePort == cfg->nodeInfo[j].nodePort){
|
||||
if(cfg->nodeInfo[j].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
for (int32_t j = 0; j < cfg->totalReplicaNum; ++j) {
|
||||
if (strcmp(ths->peersNodeInfo[i].nodeFqdn, cfg->nodeInfo[j].nodeFqdn) == 0 &&
|
||||
ths->peersNodeInfo[i].nodePort == cfg->nodeInfo[j].nodePort) {
|
||||
if (cfg->nodeInfo[j].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
ths->peersNodeInfo[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//change cfg nodeInfo
|
||||
// change cfg nodeInfo
|
||||
ths->raftCfg.cfg.replicaNum = 0;
|
||||
for (int32_t i = 0; i < ths->raftCfg.cfg.totalReplicaNum; ++i) {
|
||||
for(int32_t j = 0; j < cfg->totalReplicaNum; ++j){
|
||||
if(strcmp(ths->raftCfg.cfg.nodeInfo[i].nodeFqdn, cfg->nodeInfo[j].nodeFqdn) == 0
|
||||
&& ths->raftCfg.cfg.nodeInfo[i].nodePort == cfg->nodeInfo[j].nodePort){
|
||||
if(cfg->nodeInfo[j].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
for (int32_t j = 0; j < cfg->totalReplicaNum; ++j) {
|
||||
if (strcmp(ths->raftCfg.cfg.nodeInfo[i].nodeFqdn, cfg->nodeInfo[j].nodeFqdn) == 0 &&
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodePort == cfg->nodeInfo[j].nodePort) {
|
||||
if (cfg->nodeInfo[j].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
ths->raftCfg.cfg.nodeInfo[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
ths->raftCfg.cfg.replicaNum++;
|
||||
}
|
||||
|
@ -2534,8 +2534,8 @@ void syncNodeChangePeerAndCfgToVoter(SSyncNode* ths, SSyncCfg *cfg){
|
|||
}
|
||||
}
|
||||
|
||||
int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum){
|
||||
//1.rebuild replicasId, remove deleted one
|
||||
int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum) {
|
||||
// 1.rebuild replicasId, remove deleted one
|
||||
SRaftId oldReplicasId[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA];
|
||||
memcpy(oldReplicasId, ths->replicasId, sizeof(oldReplicasId));
|
||||
|
||||
|
@ -2545,9 +2545,8 @@ int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum
|
|||
syncUtilNodeInfo2RaftId(&ths->raftCfg.cfg.nodeInfo[i], ths->vgId, &ths->replicasId[i]);
|
||||
}
|
||||
|
||||
|
||||
//2.rebuild MatchIndex, remove deleted one
|
||||
SSyncIndexMgr *oldIndex = ths->pMatchIndex;
|
||||
// 2.rebuild MatchIndex, remove deleted one
|
||||
SSyncIndexMgr* oldIndex = ths->pMatchIndex;
|
||||
|
||||
ths->pMatchIndex = syncIndexMgrCreate(ths);
|
||||
|
||||
|
@ -2555,9 +2554,8 @@ int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum
|
|||
|
||||
syncIndexMgrDestroy(oldIndex);
|
||||
|
||||
|
||||
//3.rebuild NextIndex, remove deleted one
|
||||
SSyncIndexMgr *oldNextIndex = ths->pNextIndex;
|
||||
// 3.rebuild NextIndex, remove deleted one
|
||||
SSyncIndexMgr* oldNextIndex = ths->pNextIndex;
|
||||
|
||||
ths->pNextIndex = syncIndexMgrCreate(ths);
|
||||
|
||||
|
@ -2565,17 +2563,15 @@ int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum
|
|||
|
||||
syncIndexMgrDestroy(oldNextIndex);
|
||||
|
||||
|
||||
//4.rebuild pVotesGranted, pVotesRespond, no need to keep old vote state, only rebuild
|
||||
// 4.rebuild pVotesGranted, pVotesRespond, no need to keep old vote state, only rebuild
|
||||
voteGrantedUpdate(ths->pVotesGranted, ths);
|
||||
votesRespondUpdate(ths->pVotesRespond, ths);
|
||||
|
||||
|
||||
//5.rebuild logReplMgr
|
||||
for(int i = 0; i < oldtotalReplicaNum; ++i){
|
||||
sDebug("vgId:%d, old logReplMgrs i:%d, peerId:%d, restoreed:%d, [%" PRId64 " %" PRId64 ", %" PRId64 ")", ths->vgId, i,
|
||||
ths->logReplMgrs[i]->peerId, ths->logReplMgrs[i]->restored, ths->logReplMgrs[i]->startIndex,
|
||||
ths->logReplMgrs[i]->matchIndex, ths->logReplMgrs[i]->endIndex);
|
||||
// 5.rebuild logReplMgr
|
||||
for (int i = 0; i < oldtotalReplicaNum; ++i) {
|
||||
sDebug("vgId:%d, old logReplMgrs i:%d, peerId:%d, restoreed:%d, [%" PRId64 " %" PRId64 ", %" PRId64 ")", ths->vgId,
|
||||
i, ths->logReplMgrs[i]->peerId, ths->logReplMgrs[i]->restored, ths->logReplMgrs[i]->startIndex,
|
||||
ths->logReplMgrs[i]->matchIndex, ths->logReplMgrs[i]->endIndex);
|
||||
}
|
||||
|
||||
SSyncLogReplMgr* oldLogReplMgrs = NULL;
|
||||
|
@ -2584,32 +2580,32 @@ int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum
|
|||
if (NULL == oldLogReplMgrs) return -1;
|
||||
memset(oldLogReplMgrs, 0, length);
|
||||
|
||||
for(int i = 0; i < oldtotalReplicaNum; i++){
|
||||
for (int i = 0; i < oldtotalReplicaNum; i++) {
|
||||
oldLogReplMgrs[i] = *(ths->logReplMgrs[i]);
|
||||
}
|
||||
|
||||
syncNodeLogReplDestroy(ths);
|
||||
syncNodeLogReplInit(ths);
|
||||
|
||||
for(int i = 0; i < ths->totalReplicaNum; ++i){
|
||||
for(int j = 0; j < oldtotalReplicaNum; j++){
|
||||
for (int i = 0; i < ths->totalReplicaNum; ++i) {
|
||||
for (int j = 0; j < oldtotalReplicaNum; j++) {
|
||||
if (syncUtilSameId(&ths->replicasId[i], &oldReplicasId[j])) {
|
||||
*(ths->logReplMgrs[i]) = oldLogReplMgrs[j];
|
||||
ths->logReplMgrs[i]->peerId = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < ths->totalReplicaNum; ++i){
|
||||
sDebug("vgId:%d, new logReplMgrs i:%d, peerId:%d, restoreed:%d, [%" PRId64 " %" PRId64 ", %" PRId64 ")" , ths->vgId, i,
|
||||
ths->logReplMgrs[i]->peerId, ths->logReplMgrs[i]->restored, ths->logReplMgrs[i]->startIndex,
|
||||
ths->logReplMgrs[i]->matchIndex, ths->logReplMgrs[i]->endIndex);
|
||||
}
|
||||
}
|
||||
|
||||
//6.rebuild sender
|
||||
for(int i = 0; i < oldtotalReplicaNum; ++i){
|
||||
sDebug("vgId:%d, old sender i:%d, replicaIndex:%d, lastSendTime:%" PRId64,
|
||||
ths->vgId, i, ths->senders[i]->replicaIndex, ths->senders[i]->lastSendTime)
|
||||
for (int i = 0; i < ths->totalReplicaNum; ++i) {
|
||||
sDebug("vgId:%d, new logReplMgrs i:%d, peerId:%d, restoreed:%d, [%" PRId64 " %" PRId64 ", %" PRId64 ")", ths->vgId,
|
||||
i, ths->logReplMgrs[i]->peerId, ths->logReplMgrs[i]->restored, ths->logReplMgrs[i]->startIndex,
|
||||
ths->logReplMgrs[i]->matchIndex, ths->logReplMgrs[i]->endIndex);
|
||||
}
|
||||
|
||||
// 6.rebuild sender
|
||||
for (int i = 0; i < oldtotalReplicaNum; ++i) {
|
||||
sDebug("vgId:%d, old sender i:%d, replicaIndex:%d, lastSendTime:%" PRId64, ths->vgId, i,
|
||||
ths->senders[i]->replicaIndex, ths->senders[i]->lastSendTime)
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) {
|
||||
|
@ -2633,13 +2629,12 @@ int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum
|
|||
sSDebug(pSender, "snapshot sender create while open sync node, data:%p", pSender);
|
||||
}
|
||||
|
||||
for(int i = 0; i < ths->totalReplicaNum; i++){
|
||||
sDebug("vgId:%d, new sender i:%d, replicaIndex:%d, lastSendTime:%" PRId64,
|
||||
ths->vgId, i, ths->senders[i]->replicaIndex, ths->senders[i]->lastSendTime)
|
||||
for (int i = 0; i < ths->totalReplicaNum; i++) {
|
||||
sDebug("vgId:%d, new sender i:%d, replicaIndex:%d, lastSendTime:%" PRId64, ths->vgId, i,
|
||||
ths->senders[i]->replicaIndex, ths->senders[i]->lastSendTime)
|
||||
}
|
||||
|
||||
|
||||
//7.rebuild synctimer
|
||||
// 7.rebuild synctimer
|
||||
syncNodeStopHeartbeatTimer(ths);
|
||||
|
||||
for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) {
|
||||
|
@ -2648,16 +2643,15 @@ int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum
|
|||
|
||||
syncNodeStartHeartbeatTimer(ths);
|
||||
|
||||
|
||||
//8.rebuild peerStates
|
||||
// 8.rebuild peerStates
|
||||
SPeerState oldState[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA] = {0};
|
||||
for(int i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; i++){
|
||||
for (int i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; i++) {
|
||||
oldState[i] = ths->peerStates[i];
|
||||
}
|
||||
|
||||
for(int i = 0; i < ths->totalReplicaNum; i++){
|
||||
for(int j = 0; j < oldtotalReplicaNum; j++){
|
||||
if (syncUtilSameId(&ths->replicasId[i], &oldReplicasId[j])){
|
||||
for (int i = 0; i < ths->totalReplicaNum; i++) {
|
||||
for (int j = 0; j < oldtotalReplicaNum; j++) {
|
||||
if (syncUtilSameId(&ths->replicasId[i], &oldReplicasId[j])) {
|
||||
ths->peerStates[i] = oldState[j];
|
||||
}
|
||||
}
|
||||
|
@ -2668,32 +2662,32 @@ int32_t syncNodeRebuildAndCopyIfExist(SSyncNode* ths, int32_t oldtotalReplicaNum
|
|||
return 0;
|
||||
}
|
||||
|
||||
void syncNodeChangeToVoter(SSyncNode* ths){
|
||||
//replicasId, only need to change replicaNum when 1->3
|
||||
void syncNodeChangeToVoter(SSyncNode* ths) {
|
||||
// replicasId, only need to change replicaNum when 1->3
|
||||
ths->replicaNum = ths->raftCfg.cfg.replicaNum;
|
||||
sDebug("vgId:%d, totalReplicaNum:%d", ths->vgId, ths->totalReplicaNum);
|
||||
for (int32_t i = 0; i < ths->totalReplicaNum; ++i){
|
||||
for (int32_t i = 0; i < ths->totalReplicaNum; ++i) {
|
||||
sDebug("vgId:%d, i:%d, replicaId.addr:%" PRIx64, ths->vgId, i, ths->replicasId[i].addr);
|
||||
}
|
||||
|
||||
//pMatchIndex, pNextIndex, only need to change replicaNum when 1->3
|
||||
// pMatchIndex, pNextIndex, only need to change replicaNum when 1->3
|
||||
ths->pMatchIndex->replicaNum = ths->raftCfg.cfg.replicaNum;
|
||||
ths->pNextIndex->replicaNum = ths->raftCfg.cfg.replicaNum;
|
||||
|
||||
sDebug("vgId:%d, pMatchIndex->totalReplicaNum:%d", ths->vgId, ths->pMatchIndex->totalReplicaNum);
|
||||
for (int32_t i = 0; i < ths->pMatchIndex->totalReplicaNum; ++i){
|
||||
for (int32_t i = 0; i < ths->pMatchIndex->totalReplicaNum; ++i) {
|
||||
sDebug("vgId:%d, i:%d, match.index:%" PRId64, ths->vgId, i, ths->pMatchIndex->index[i]);
|
||||
}
|
||||
|
||||
//pVotesGranted, pVotesRespond
|
||||
// pVotesGranted, pVotesRespond
|
||||
voteGrantedUpdate(ths->pVotesGranted, ths);
|
||||
votesRespondUpdate(ths->pVotesRespond, ths);
|
||||
|
||||
//logRepMgrs
|
||||
//no need to change logRepMgrs when 1->3
|
||||
// logRepMgrs
|
||||
// no need to change logRepMgrs when 1->3
|
||||
}
|
||||
|
||||
void syncNodeResetPeerAndCfg(SSyncNode* ths){
|
||||
void syncNodeResetPeerAndCfg(SSyncNode* ths) {
|
||||
SNodeInfo node = {0};
|
||||
for (int32_t i = 0; i < ths->peersNum; ++i) {
|
||||
memcpy(&ths->peersNodeInfo[i], &node, sizeof(SNodeInfo));
|
||||
|
@ -2704,13 +2698,13 @@ void syncNodeResetPeerAndCfg(SSyncNode* ths){
|
|||
}
|
||||
}
|
||||
|
||||
int32_t syncNodeChangeConfig(SSyncNode* ths, SSyncRaftEntry* pEntry, char* str){
|
||||
if(pEntry->originalRpcType != TDMT_SYNC_CONFIG_CHANGE){
|
||||
int32_t syncNodeChangeConfig(SSyncNode* ths, SSyncRaftEntry* pEntry, char* str) {
|
||||
if (pEntry->originalRpcType != TDMT_SYNC_CONFIG_CHANGE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SMsgHead *head = (SMsgHead *)pEntry->data;
|
||||
void *pReq = POINTER_SHIFT(head, sizeof(SMsgHead));
|
||||
SMsgHead* head = (SMsgHead*)pEntry->data;
|
||||
void* pReq = POINTER_SHIFT(head, sizeof(SMsgHead));
|
||||
|
||||
SAlterVnodeTypeReq req = {0};
|
||||
if (tDeserializeSAlterVnodeReplicaReq(pReq, head->contLen, &req) != 0) {
|
||||
|
@ -2719,141 +2713,143 @@ int32_t syncNodeChangeConfig(SSyncNode* ths, SSyncRaftEntry* pEntry, char* str){
|
|||
}
|
||||
|
||||
SSyncCfg cfg = {0};
|
||||
syncBuildConfigFromReq(&req, &cfg);
|
||||
syncBuildConfigFromReq(&req, &cfg);
|
||||
|
||||
if(cfg.changeVersion <= ths->raftCfg.cfg.changeVersion){
|
||||
sInfo("vgId:%d, skip conf change entry since lower version. "
|
||||
"this entry, index:%" PRId64 ", term:%" PRId64 ", totalReplicaNum:%d, changeVersion:%d; "
|
||||
"current node, replicaNum:%d, peersNum:%d, lastConfigIndex:%" PRId64", changeVersion:%d",
|
||||
ths->vgId,
|
||||
pEntry->index, pEntry->term, cfg.totalReplicaNum, cfg.changeVersion,
|
||||
ths->replicaNum, ths->peersNum, ths->raftCfg.lastConfigIndex, ths->raftCfg.cfg.changeVersion);
|
||||
if (cfg.changeVersion <= ths->raftCfg.cfg.changeVersion) {
|
||||
sInfo(
|
||||
"vgId:%d, skip conf change entry since lower version. "
|
||||
"this entry, index:%" PRId64 ", term:%" PRId64
|
||||
", totalReplicaNum:%d, changeVersion:%d; "
|
||||
"current node, replicaNum:%d, peersNum:%d, lastConfigIndex:%" PRId64 ", changeVersion:%d",
|
||||
ths->vgId, pEntry->index, pEntry->term, cfg.totalReplicaNum, cfg.changeVersion, ths->replicaNum, ths->peersNum,
|
||||
ths->raftCfg.lastConfigIndex, ths->raftCfg.cfg.changeVersion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strcmp(str, "Commit") == 0){
|
||||
sInfo("vgId:%d, change config from %s. "
|
||||
"this, i:%" PRId64 ", trNum:%d, vers:%d; "
|
||||
"node, rNum:%d, pNum:%d, trNum:%d, "
|
||||
"buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64 "), "
|
||||
"cond:(next i:%" PRId64 ", t:%" PRId64 " ==%s)",
|
||||
ths->vgId, str, pEntry->index - 1, cfg.totalReplicaNum, cfg.changeVersion,
|
||||
ths->replicaNum, ths->peersNum, ths->totalReplicaNum,
|
||||
ths->pLogBuf->startIndex, ths->pLogBuf->commitIndex, ths->pLogBuf->matchIndex, ths->pLogBuf->endIndex,
|
||||
pEntry->index, pEntry->term, TMSG_INFO(pEntry->originalRpcType));
|
||||
}
|
||||
else{
|
||||
sInfo("vgId:%d, change config from %s. "
|
||||
"this, i:%" PRId64 ", t:%" PRId64 ", trNum:%d, vers:%d; "
|
||||
"node, rNum:%d, pNum:%d, trNum:%d, "
|
||||
"buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64 "), "
|
||||
"cond:(pre i:%" PRId64 "==ci:%" PRId64 ", bci:%" PRId64 ")",
|
||||
ths->vgId, str, pEntry->index, pEntry->term, cfg.totalReplicaNum, cfg.changeVersion,
|
||||
ths->replicaNum, ths->peersNum, ths->totalReplicaNum,
|
||||
ths->pLogBuf->startIndex, ths->pLogBuf->commitIndex, ths->pLogBuf->matchIndex, ths->pLogBuf->endIndex,
|
||||
pEntry->index -1, ths->commitIndex, ths->pLogBuf->commitIndex);
|
||||
if (strcmp(str, "Commit") == 0) {
|
||||
sInfo(
|
||||
"vgId:%d, change config from %s. "
|
||||
"this, i:%" PRId64
|
||||
", trNum:%d, vers:%d; "
|
||||
"node, rNum:%d, pNum:%d, trNum:%d, "
|
||||
"buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64
|
||||
"), "
|
||||
"cond:(next i:%" PRId64 ", t:%" PRId64 " ==%s)",
|
||||
ths->vgId, str, pEntry->index - 1, cfg.totalReplicaNum, cfg.changeVersion, ths->replicaNum, ths->peersNum,
|
||||
ths->totalReplicaNum, ths->pLogBuf->startIndex, ths->pLogBuf->commitIndex, ths->pLogBuf->matchIndex,
|
||||
ths->pLogBuf->endIndex, pEntry->index, pEntry->term, TMSG_INFO(pEntry->originalRpcType));
|
||||
} else {
|
||||
sInfo(
|
||||
"vgId:%d, change config from %s. "
|
||||
"this, i:%" PRId64 ", t:%" PRId64
|
||||
", trNum:%d, vers:%d; "
|
||||
"node, rNum:%d, pNum:%d, trNum:%d, "
|
||||
"buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64
|
||||
"), "
|
||||
"cond:(pre i:%" PRId64 "==ci:%" PRId64 ", bci:%" PRId64 ")",
|
||||
ths->vgId, str, pEntry->index, pEntry->term, cfg.totalReplicaNum, cfg.changeVersion, ths->replicaNum,
|
||||
ths->peersNum, ths->totalReplicaNum, ths->pLogBuf->startIndex, ths->pLogBuf->commitIndex,
|
||||
ths->pLogBuf->matchIndex, ths->pLogBuf->endIndex, pEntry->index - 1, ths->commitIndex,
|
||||
ths->pLogBuf->commitIndex);
|
||||
}
|
||||
|
||||
syncNodeLogConfigInfo(ths, &cfg, "before config change");
|
||||
|
||||
|
||||
int32_t oldTotalReplicaNum = ths->totalReplicaNum;
|
||||
|
||||
if(cfg.totalReplicaNum == 1 || cfg.totalReplicaNum == 2){//remove replica
|
||||
|
||||
if (cfg.totalReplicaNum == 1 || cfg.totalReplicaNum == 2) { // remove replica
|
||||
|
||||
bool incfg = false;
|
||||
for(int32_t j = 0; j < cfg.totalReplicaNum; ++j){
|
||||
if(strcmp(ths->myNodeInfo.nodeFqdn, cfg.nodeInfo[j].nodeFqdn) == 0
|
||||
&& ths->myNodeInfo.nodePort == cfg.nodeInfo[j].nodePort){
|
||||
for (int32_t j = 0; j < cfg.totalReplicaNum; ++j) {
|
||||
if (strcmp(ths->myNodeInfo.nodeFqdn, cfg.nodeInfo[j].nodeFqdn) == 0 &&
|
||||
ths->myNodeInfo.nodePort == cfg.nodeInfo[j].nodePort) {
|
||||
incfg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(incfg){//remove other
|
||||
if (incfg) { // remove other
|
||||
syncNodeResetPeerAndCfg(ths);
|
||||
|
||||
//no need to change myNodeInfo
|
||||
// no need to change myNodeInfo
|
||||
|
||||
if(syncNodeRebuildPeerAndCfg(ths, &cfg) != 0){
|
||||
return -1;
|
||||
};
|
||||
|
||||
if(syncNodeRebuildAndCopyIfExist(ths, oldTotalReplicaNum) != 0){
|
||||
if (syncNodeRebuildPeerAndCfg(ths, &cfg) != 0) {
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
else{//remove myself
|
||||
//no need to do anything actually, to change the following to reduce distruptive server chance
|
||||
|
||||
if (syncNodeRebuildAndCopyIfExist(ths, oldTotalReplicaNum) != 0) {
|
||||
return -1;
|
||||
};
|
||||
} else { // remove myself
|
||||
// no need to do anything actually, to change the following to reduce distruptive server chance
|
||||
|
||||
syncNodeResetPeerAndCfg(ths);
|
||||
|
||||
//change myNodeInfo
|
||||
// change myNodeInfo
|
||||
ths->myNodeInfo.nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
|
||||
//change peer and cfg
|
||||
// change peer and cfg
|
||||
ths->peersNum = 0;
|
||||
memcpy(&ths->raftCfg.cfg.nodeInfo[0], &ths->myNodeInfo, sizeof(SNodeInfo));
|
||||
ths->raftCfg.cfg.replicaNum = 0;
|
||||
ths->raftCfg.cfg.totalReplicaNum = 1;
|
||||
|
||||
//change other
|
||||
if(syncNodeRebuildAndCopyIfExist(ths, oldTotalReplicaNum) != 0){
|
||||
// change other
|
||||
if (syncNodeRebuildAndCopyIfExist(ths, oldTotalReplicaNum) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
//change state
|
||||
// change state
|
||||
ths->state = TAOS_SYNC_STATE_LEARNER;
|
||||
}
|
||||
|
||||
ths->restoreFinish = false;
|
||||
}
|
||||
else{//add replica, or change replica type
|
||||
if(ths->totalReplicaNum == 3){ //change replica type
|
||||
sInfo("vgId:%d, begin change replica type", ths->vgId);
|
||||
ths->restoreFinish = false;
|
||||
} else { // add replica, or change replica type
|
||||
if (ths->totalReplicaNum == 3) { // change replica type
|
||||
sInfo("vgId:%d, begin change replica type", ths->vgId);
|
||||
|
||||
//change myNodeInfo
|
||||
for(int32_t j = 0; j < cfg.totalReplicaNum; ++j){
|
||||
if(strcmp(ths->myNodeInfo.nodeFqdn, cfg.nodeInfo[j].nodeFqdn) == 0
|
||||
&& ths->myNodeInfo.nodePort == cfg.nodeInfo[j].nodePort){
|
||||
if(cfg.nodeInfo[j].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
// change myNodeInfo
|
||||
for (int32_t j = 0; j < cfg.totalReplicaNum; ++j) {
|
||||
if (strcmp(ths->myNodeInfo.nodeFqdn, cfg.nodeInfo[j].nodeFqdn) == 0 &&
|
||||
ths->myNodeInfo.nodePort == cfg.nodeInfo[j].nodePort) {
|
||||
if (cfg.nodeInfo[j].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
ths->myNodeInfo.nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//change peer and cfg
|
||||
|
||||
// change peer and cfg
|
||||
syncNodeChangePeerAndCfgToVoter(ths, &cfg);
|
||||
|
||||
//change other
|
||||
// change other
|
||||
syncNodeChangeToVoter(ths);
|
||||
|
||||
//change state
|
||||
if(ths->state ==TAOS_SYNC_STATE_LEARNER){
|
||||
if(ths->myNodeInfo.nodeRole == TAOS_SYNC_ROLE_VOTER ){
|
||||
// change state
|
||||
if (ths->state == TAOS_SYNC_STATE_LEARNER) {
|
||||
if (ths->myNodeInfo.nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
ths->state = TAOS_SYNC_STATE_FOLLOWER;
|
||||
}
|
||||
}
|
||||
|
||||
ths->restoreFinish = false;
|
||||
}
|
||||
else{//add replica
|
||||
ths->restoreFinish = false;
|
||||
} else { // add replica
|
||||
sInfo("vgId:%d, begin add replica", ths->vgId);
|
||||
|
||||
//no need to change myNodeInfo
|
||||
// no need to change myNodeInfo
|
||||
|
||||
//change peer and cfg
|
||||
if(syncNodeRebuildPeerAndCfg(ths, &cfg) != 0){
|
||||
// change peer and cfg
|
||||
if (syncNodeRebuildPeerAndCfg(ths, &cfg) != 0) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
//change other
|
||||
if(syncNodeRebuildAndCopyIfExist(ths, oldTotalReplicaNum) != 0){
|
||||
// change other
|
||||
if (syncNodeRebuildAndCopyIfExist(ths, oldTotalReplicaNum) != 0) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
//no need to change state
|
||||
// no need to change state
|
||||
|
||||
if(ths->myNodeInfo.nodeRole == TAOS_SYNC_ROLE_LEARNER){
|
||||
if (ths->myNodeInfo.nodeRole == TAOS_SYNC_ROLE_LEARNER) {
|
||||
ths->restoreFinish = false;
|
||||
}
|
||||
}
|
||||
|
@ -2867,7 +2863,7 @@ int32_t syncNodeChangeConfig(SSyncNode* ths, SSyncRaftEntry* pEntry, char* str){
|
|||
|
||||
syncNodeLogConfigInfo(ths, &cfg, "after config change");
|
||||
|
||||
if(syncWriteCfgFile(ths) != 0){
|
||||
if (syncWriteCfgFile(ths) != 0) {
|
||||
sError("vgId:%d, failed to create sync cfg file", ths->vgId);
|
||||
return -1;
|
||||
};
|
||||
|
@ -2896,7 +2892,7 @@ int32_t syncNodeAppend(SSyncNode* ths, SSyncRaftEntry* pEntry) {
|
|||
code = 0;
|
||||
_out:;
|
||||
// proceed match index, with replicating on needed
|
||||
SyncIndex matchIndex = syncLogBufferProceed(ths->pLogBuf, ths, NULL, "Append");
|
||||
SyncIndex matchIndex = syncLogBufferProceed(ths->pLogBuf, ths, NULL, "Append");
|
||||
|
||||
sTrace("vgId:%d, append raft entry. index:%" PRId64 ", term:%" PRId64 " pBuf: [%" PRId64 " %" PRId64 " %" PRId64
|
||||
", %" PRId64 ")",
|
||||
|
@ -2927,7 +2923,7 @@ bool syncNodeHeartbeatReplyTimeout(SSyncNode* pSyncNode) {
|
|||
int32_t toCount = 0;
|
||||
int64_t tsNow = taosGetTimestampMs();
|
||||
for (int32_t i = 0; i < pSyncNode->peersNum; ++i) {
|
||||
if(pSyncNode->peersNodeInfo[i].nodeRole == TAOS_SYNC_ROLE_LEARNER){
|
||||
if (pSyncNode->peersNodeInfo[i].nodeRole == TAOS_SYNC_ROLE_LEARNER) {
|
||||
continue;
|
||||
}
|
||||
int64_t recvTime = syncIndexMgrGetRecvTime(pSyncNode->pMatchIndex, &(pSyncNode->peersId[i]));
|
||||
|
@ -3191,9 +3187,9 @@ int32_t syncNodeOnClientRequest(SSyncNode* ths, SRpcMsg* pMsg, SyncIndex* pRetIn
|
|||
pEntry = syncEntryBuildFromRpcMsg(pMsg, term, index);
|
||||
}
|
||||
|
||||
//1->2, config change is add in write thread, and will continue in sync thread
|
||||
//need save message for it
|
||||
if(pMsg->msgType == TDMT_SYNC_CONFIG_CHANGE){
|
||||
// 1->2, config change is add in write thread, and will continue in sync thread
|
||||
// need save message for it
|
||||
if (pMsg->msgType == TDMT_SYNC_CONFIG_CHANGE) {
|
||||
SRespStub stub = {.createTime = taosGetTimestampMs(), .rpcMsg = *pMsg};
|
||||
uint64_t seqNum = syncRespMgrAdd(ths->pSyncRespMgr, &stub);
|
||||
pEntry->seqNum = seqNum;
|
||||
|
@ -3209,21 +3205,21 @@ int32_t syncNodeOnClientRequest(SSyncNode* ths, SRpcMsg* pMsg, SyncIndex* pRetIn
|
|||
(*pRetIndex) = index;
|
||||
}
|
||||
|
||||
if(pEntry->originalRpcType == TDMT_SYNC_CONFIG_CHANGE){
|
||||
if (pEntry->originalRpcType == TDMT_SYNC_CONFIG_CHANGE) {
|
||||
int32_t code = syncNodeCheckChangeConfig(ths, pEntry);
|
||||
if(code < 0){
|
||||
if (code < 0) {
|
||||
sError("vgId:%d, failed to check change config since %s.", ths->vgId, terrstr());
|
||||
syncEntryDestroy(pEntry);
|
||||
pEntry = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(code > 0){
|
||||
|
||||
if (code > 0) {
|
||||
SRpcMsg rsp = {.code = pMsg->code, .info = pMsg->info};
|
||||
(void)syncRespMgrGetAndDel(ths->pSyncRespMgr, pEntry->seqNum, &rsp.info);
|
||||
if (rsp.info.handle != NULL) {
|
||||
tmsgSendRsp(&rsp);
|
||||
}
|
||||
}
|
||||
syncEntryDestroy(pEntry);
|
||||
pEntry = NULL;
|
||||
return -1;
|
||||
|
|
|
@ -103,6 +103,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_DATA_FMT, "Invalid data format")
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_CFG_VALUE, "Invalid configuration value")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_IP_NOT_IN_WHITE_LIST, "Not allowed to connect")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_FAILED_TO_CONNECT_S3, "Failed to connect to s3 server")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MSG_PREPROCESSED, "Message has been processed in preprocess")
|
||||
|
||||
//client
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_OPERATION, "Invalid operation")
|
||||
|
@ -427,6 +428,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JSON_IN_GROUP_ERROR, "Json not support in g
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JOB_NOT_EXIST, "Job not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_QWORKER_QUIT, "Vnode/Qnode is quitting")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR, "Geometry not support in this operator")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_WINDOW_CONDITION, "The time pseudo column is illegally used in the condition of the event window.")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR, "Executor internal error")
|
||||
|
||||
// grant
|
||||
|
|
|
@ -9,11 +9,12 @@ import time
|
|||
from frame.log import *
|
||||
from frame.cases import *
|
||||
from frame.sql import *
|
||||
from frame.srvCtl import *
|
||||
from frame.caseBase import *
|
||||
from frame import *
|
||||
from frame.autogen import *
|
||||
from frame.server.dnodes import *
|
||||
from frame.server.cluster import *
|
||||
# from frame.server.dnodes import *
|
||||
# from frame.server.cluster import *
|
||||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
|
@ -34,7 +35,7 @@ class TDTestCase(TBase):
|
|||
autoGen.create_child(self.stb, "d", self.childtable_count)
|
||||
autoGen.insert_data(1000)
|
||||
tdSql.execute(f"flush database {self.db}")
|
||||
clusterDnodes.stoptaosd(3)
|
||||
sc.dnodeStop(3)
|
||||
# clusterDnodes.stoptaosd(1)
|
||||
# clusterDnodes.starttaosd(3)
|
||||
# time.sleep(5)
|
||||
|
@ -56,7 +57,7 @@ class TDTestCase(TBase):
|
|||
# break
|
||||
self.snapshotAgg()
|
||||
time.sleep(10)
|
||||
clusterDnodes.stopAll()
|
||||
sc.dnodeStopAll()
|
||||
for i in range(1, 4):
|
||||
path = clusterDnodes.getDnodeDir(i)
|
||||
dnodesRootDir = os.path.join(path,"data","vnode", "vnode*")
|
||||
|
@ -66,9 +67,9 @@ class TDTestCase(TBase):
|
|||
tdLog.debug("delete dir: %s " % (dnodesRootDir))
|
||||
self.remove_directory(os.path.join(dir, "wal"))
|
||||
|
||||
clusterDnodes.starttaosd(1)
|
||||
clusterDnodes.starttaosd(2)
|
||||
clusterDnodes.starttaosd(3)
|
||||
sc.dnodeStart(1)
|
||||
sc.dnodeStart(2)
|
||||
sc.dnodeStart(3)
|
||||
sql = "show vnodes;"
|
||||
time.sleep(10)
|
||||
while True:
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
import taos
|
||||
import sys
|
||||
|
||||
from frame.log import *
|
||||
from frame.cases import *
|
||||
from frame.sql import *
|
||||
from frame.caseBase import *
|
||||
from frame import *
|
||||
|
||||
class TDTestCase(TBase):
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
#tdSql.init(conn.cursor())
|
||||
tdSql.init(conn.cursor(), logSql) # output sql.txt file
|
||||
|
||||
def run(self):
|
||||
dbname = "db"
|
||||
stbname = "ocloud_point"
|
||||
tbname = "ocloud_point_170658_3837620225_1701134595725266945"
|
||||
|
||||
tdSql.prepare()
|
||||
|
||||
tdLog.printNoPrefix("==========step1:create table")
|
||||
|
||||
tdSql.execute(
|
||||
f'''create stable if not exists {dbname}.{stbname}
|
||||
(wstart timestamp, point_value float) tags (location binary(64), groupId int)
|
||||
'''
|
||||
)
|
||||
|
||||
tdSql.execute(
|
||||
f'''create table if not exists {dbname}.{tbname} using {dbname}.{stbname} tags("California.SanFrancisco", 2)'''
|
||||
)
|
||||
|
||||
sqls = []
|
||||
for i in range(35, 41):
|
||||
if i == 38 or i == 40:
|
||||
sqls.append(f"insert into {dbname}.{tbname} values('2023-12-26 10:{i}:00.000', null)")
|
||||
else:
|
||||
sqls.append(f"insert into {dbname}.{tbname} values('2023-12-26 10:{i}:00.000', 5.0)")
|
||||
|
||||
# sqls.append(f"insert into {dbname}.{tbname} values('2023-12-26 10:36:00.000', 5.0)")
|
||||
# sqls.append(f"insert into {dbname}.{tbname} values('2023-12-26 10:37:00.000', 5.0)")
|
||||
# sqls.append(f"insert into {dbname}.{tbname} values('2023-12-26 10:38:00.000', null)")
|
||||
# sqls.append(f"insert into {dbname}.{tbname} values('2023-12-26 10:39:00.000', 5.0)")
|
||||
# sqls.append(f"insert into {dbname}.{tbname} values('2023-12-26 10:40:00.000', null)")
|
||||
|
||||
|
||||
tdSql.executes(sqls)
|
||||
|
||||
tdLog.printNoPrefix("==========step3:fill data")
|
||||
|
||||
tdSql.query(f"select first(point_value) as pointValue from {dbname}.{tbname} where wstart between '2023-12-26 10:35:00' and '2023-12-26 10:40:00' interval(1M) fill(prev) order by wstart desc limit 100")
|
||||
data = []
|
||||
for i in range(6):
|
||||
row = [5]
|
||||
data.append(row)
|
||||
tdSql.checkDataMem(data)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,447 @@
|
|||
from frame.log import *
|
||||
from frame.cases import *
|
||||
from frame.sql import *
|
||||
from frame.caseBase import *
|
||||
from frame import *
|
||||
from frame.eos import *
|
||||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
"""Verify the elapsed function
|
||||
"""
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor())
|
||||
self.dbname = 'db'
|
||||
self.table_dic = {
|
||||
"super_table": ["st1", "st2", "st_empty"],
|
||||
"child_table": ["ct1_1", "ct1_2", "ct1_empty", "ct2_1", "ct2_2", "ct2_empty"],
|
||||
"tags_value": [("2023-03-01 15:00:00", 1, 'bj'), ("2023-03-01 15:10:00", 2, 'sh'), ("2023-03-01 15:20:00", 3, 'sz'), ("2023-03-01 15:00:00", 4, 'gz'), ("2023-03-01 15:10:00", 5, 'cd'), ("2023-03-01 15:20:00", 6, 'hz')],
|
||||
"common_table": ["t1", "t2", "t_empty"]
|
||||
}
|
||||
self.start_ts = 1677654000000 # 2023-03-01 15:00:00.000
|
||||
self.row_num = 100
|
||||
|
||||
def prepareData(self):
|
||||
# db
|
||||
tdSql.execute(f"create database {self.dbname};")
|
||||
tdSql.execute(f"use {self.dbname};")
|
||||
tdLog.debug(f"Create database {self.dbname}")
|
||||
|
||||
# commont table
|
||||
for common_table in self.table_dic["common_table"]:
|
||||
tdSql.execute(f"create table {common_table} (ts timestamp, c_ts timestamp, c_int int, c_bigint bigint, c_double double, c_nchar nchar(16));")
|
||||
tdLog.debug("Create common table %s" % common_table)
|
||||
|
||||
# super table
|
||||
for super_table in self.table_dic["super_table"]:
|
||||
tdSql.execute(f"create stable {super_table} (ts timestamp, c_ts timestamp, c_int int, c_bigint bigint, c_double double, c_nchar nchar(16)) tags (t1 timestamp, t2 int, t3 binary(16));")
|
||||
tdLog.debug("Create super table %s" % super_table)
|
||||
|
||||
# child table
|
||||
for i in range(len(self.table_dic["child_table"])):
|
||||
if self.table_dic["child_table"][i].startswith("ct1"):
|
||||
tdSql.execute("create table {} using {} tags('{}', {}, '{}');".format(self.table_dic["child_table"][i], "st1", self.table_dic["tags_value"][i][0], self.table_dic["tags_value"][i][1], self.table_dic["tags_value"][i][2]))
|
||||
elif self.table_dic["child_table"][i].startswith("ct2"):
|
||||
tdSql.execute("create table {} using {} tags('{}', {}, '{}');".format(self.table_dic["child_table"][i], "st2", self.table_dic["tags_value"][i][0], self.table_dic["tags_value"][i][1], self.table_dic["tags_value"][i][2]))
|
||||
|
||||
# insert data
|
||||
table_list = ["t1", "t2", "ct1_1", "ct1_2", "ct2_1", "ct2_2"]
|
||||
for t in table_list:
|
||||
sql = "insert into {} values".format(t)
|
||||
for i in range(self.row_num):
|
||||
sql += "({}, {}, {}, {}, {}, '{}'),".format(self.start_ts + i * 1000, self.start_ts + i * 1000, 32767+i, 65535+i, i, t + str(i))
|
||||
sql += ";"
|
||||
tdSql.execute(sql)
|
||||
tdLog.debug("Insert data into table %s" % t)
|
||||
|
||||
def test_normal_query(self):
|
||||
# only one timestamp
|
||||
tdSql.query("select elapsed(ts) from t1 group by c_ts;")
|
||||
tdSql.checkRows(self.row_num)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
tdSql.query("select elapsed(ts, 1m) from t1 group by c_ts;")
|
||||
tdSql.checkRows(self.row_num)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
# child table with group by
|
||||
tdSql.query("select elapsed(ts) from ct1_2 group by tbname;")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 99000)
|
||||
|
||||
# empty super table
|
||||
tdSql.query("select elapsed(ts, 1s) from st_empty group by tbname;")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# empty child table
|
||||
tdSql.query("select elapsed(ts, 1s) from ct1_empty group by tbname;")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# empty common table
|
||||
tdSql.query("select elapsed(ts, 1s) from t_empty group by tbname;")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# unit as second
|
||||
tdSql.query("select elapsed(ts, 1s) from st2 group by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 0, 99)
|
||||
|
||||
# unit as minute
|
||||
tdSql.query("select elapsed(ts, 1m) from st2 group by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 0, 1.65)
|
||||
|
||||
# unit as hour
|
||||
tdSql.query("select elapsed(ts, 1h) from st2 group by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 0, 0.0275)
|
||||
|
||||
def test_query_with_filter(self):
|
||||
end_ts = 1677654000000 + 1000 * 99
|
||||
query_list = [
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 where ts >= 1677654000000 group by tbname;",
|
||||
"res": [(99.0, ), (99.0, )]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 where ts >= 1677654000000 and c_ts >= 1677654000000 group by tbname;",
|
||||
"res": [(99.0, ), (99.0, )]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 where ts >= 1677654000000 and c_ts >= 1677654000000 and t1='2023-03-01 15:10:00.000' group by tbname;",
|
||||
"res": [(99.0, )]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st_empty where ts >= 1677654000000 and c_ts >= 1677654000000 and t1='2023-03-01 15:10:00.000' group by tbname;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from ct1_1 where ts >= 1677654000000 group by tbname;",
|
||||
"res": [(99.0, )]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from ct1_2 where ts >= 1677654000000 and c_ts >= 1677654000000 group by tbname;",
|
||||
"res": [(99.0, )]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from ct1_empty where ts >= 1677654000000 and c_ts >= 1677654000000 group by tbname;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from t1 where ts >= 1677654000000 group by tbname;",
|
||||
"res": [(99.0, )]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from t2 where ts >= 1677654000000 and c_ts >= 1677654000000 group by tbname;",
|
||||
"res": [(99.0, )]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from t_empty where ts >= 1677654000000 and c_ts >= 1677654000000 group by tbname;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_ts > {} group by tbname;".format(end_ts),
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_ts > {} and t1='2023-03-01 15:10:00' group by tbname;".format(end_ts),
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_int < 1 group by tbname;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_int >= 1 and t1='2023-03-01 15:10:00' group by tbname;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_int <> 1 and t1='2023-03-01 15:10:00' group by tbname;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_nchar like 'ct2_%' and t1='2023-03-01 15:10:00' group by tbname;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_nchar like 'ct1_%' and t1='2023-03-01 15:10:00' group by tbname;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_nchar match '^ct2_' and t1='2023-03-01 15:10:00' group by tbname;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and c_nchar nmatch '^ct1_' and t1='2023-03-01 15:10:00' group by tbname;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st2 where ts >= 1677654000000 and t3 like 'g%' group by tbname;",
|
||||
"res": [(99,)]
|
||||
}
|
||||
]
|
||||
sql_list = []
|
||||
res_list = []
|
||||
for item in query_list:
|
||||
sql_list.append(item["sql"])
|
||||
res_list.append(item["res"])
|
||||
tdSql.queryAndCheckResult(sql_list, res_list)
|
||||
|
||||
def test_query_with_other_function(self):
|
||||
query_list = [
|
||||
{
|
||||
"sql": "select avg(c_int), count(*), elapsed(ts, 1s), leastsquares(c_int, 0, 1), spread(c_bigint), sum(c_int), hyperloglog(c_int) from st1;",
|
||||
"res": [(32816.5, 200, 99.0, '{slop:0.499962, intercept:32766.753731}', 99.0, 6563300, 100)]
|
||||
},
|
||||
{
|
||||
"sql": "select twa(c_int) * elapsed(ts, 1s) from ct1_1;",
|
||||
"res": [(3.248833500000000e+06,)]
|
||||
}
|
||||
]
|
||||
sql_list = []
|
||||
res_list = []
|
||||
for item in query_list:
|
||||
sql_list.append(item["sql"])
|
||||
res_list.append(item["res"])
|
||||
tdSql.queryAndCheckResult(sql_list, res_list)
|
||||
|
||||
def test_query_with_join(self):
|
||||
query_list = [
|
||||
{
|
||||
"sql": "select elapsed(st1.ts, 1s) from st1, st2 where st1.ts = st2.ts;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(st1.ts, 1s) from st1, st_empty where st1.ts = st_empty.ts and st1.c_ts = st_empty.c_ts;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(st1.ts, 1s) from st1, ct1_1 where st1.ts = ct1_1.ts;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ct1.ts, 1s) from ct1_1 ct1, ct1_2 ct2 where ct1.ts = ct2.ts;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ct1.ts, 1s) from ct1_1 ct1, ct1_empty ct2 where ct1.ts = ct2.ts;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(st1.ts, 1s) from st1, ct1_empty where st1.ts = ct1_empty.ts;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(st1.ts, 1s) from st1, t1 where st1.ts = t1.ts;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(st1.ts, 1s) from st1, t_empty where st1.ts = t_empty.ts;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ct1.ts, 1s) from ct1_1 ct1, t1 t2 where ct1.ts = t2.ts;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ct1.ts, 1s) from ct1_1 ct1, t_empty t2 where ct1.ts = t2.ts;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(st1.ts, 1s) from st1, st2, st_empty where st1.ts=st2.ts and st2.ts=st_empty.ts;",
|
||||
"res": []
|
||||
}
|
||||
]
|
||||
sql_list = []
|
||||
res_list = []
|
||||
for item in query_list:
|
||||
sql_list.append(item["sql"])
|
||||
res_list.append(item["res"])
|
||||
tdSql.queryAndCheckResult(sql_list, res_list)
|
||||
|
||||
def test_query_with_union(self):
|
||||
query_list = [
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 union select elapsed(ts, 1s) from st2;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 union all select elapsed(ts, 1s) from st2;",
|
||||
"res": [(99,),(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 union all select elapsed(ts, 1s) from st_empty;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from ct1_1 union all select elapsed(ts, 1s) from ct1_2;",
|
||||
"res": [(99,),(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from ct1_1 union select elapsed(ts, 1s) from ct1_2;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from ct1_1 union select elapsed(ts, 1s) from ct1_empty;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 where ts < '2023-03-01 15:05:00.000' union select elapsed(ts, 1s) from ct1_1 where ts >= '2023-03-01 15:01:00.000';",
|
||||
"res": [(39,),(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from ct1_empty union select elapsed(ts, 1s) from t_empty;",
|
||||
"res": []
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 group by tbname union select elapsed(ts, 1s) from st2 group by tbname;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 group by tbname union all select elapsed(ts, 1s) from st2 group by tbname;",
|
||||
"res": [(99,),(99,),(99,),(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st_empty group by tbname union all select elapsed(ts, 1s) from st2 group by tbname;",
|
||||
"res": [(99,),(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from t1 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:40.000' interval(10s) fill(next) union select elapsed(ts, 1s) from st2 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:49.000' interval(5s) fill(prev);",
|
||||
"res": [(9,), (None,), (4,), (5,),(10,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 group by tbname union select elapsed(ts, 1s) from st2 group by tbname union select elapsed(ts, 1s) from st_empty group by tbname;",
|
||||
"res": [(99,)]
|
||||
}
|
||||
]
|
||||
sql_list = []
|
||||
res_list = []
|
||||
for item in query_list:
|
||||
sql_list.append(item["sql"])
|
||||
res_list.append(item["res"])
|
||||
tdSql.queryAndCheckResult(sql_list, res_list)
|
||||
|
||||
def test_query_with_window(self):
|
||||
query_list = [
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:00:20.000' interval(10s) fill(next);",
|
||||
"res": [(10,),(10,)()]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from (select * from st1 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:20.000' and c_int > 100) where ts >= '2023-03-01 15:01:00.000' and ts < '2023-03-01 15:02:00.000' interval(10s) fill(prev);",
|
||||
"res": [(10,)(10,)(),(),(),()]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st1 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:00:20.000' session(ts, 2s);",
|
||||
"res": [(20,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from st_empty where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:00:20.000' session(ts, 2s);",
|
||||
"res": []
|
||||
}
|
||||
]
|
||||
sql_list = []
|
||||
res_list = []
|
||||
for item in query_list:
|
||||
sql_list.append(item["sql"])
|
||||
res_list.append(item["res"])
|
||||
tdSql.queryAndCheckResult(sql_list, res_list)
|
||||
|
||||
def test_nested_query(self):
|
||||
query_list = [
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from (select * from st1 where c_int > 10 and ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:40.000');",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select sum(v) from (select elapsed(ts, 1s) as v from st1 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:00:20.000' interval(10s) fill(next));",
|
||||
"res": [(20,)]
|
||||
},
|
||||
{
|
||||
"sql": "select avg(v) from (select elapsed(ts, 1s) as v from st2 group by tbname order by v);",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from (select * from st1 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:40.000') where c_int > 10;",
|
||||
"res": [(99,)]
|
||||
},
|
||||
{
|
||||
"sql": "select elapsed(ts, 1s) from (select * from st1 where c_int > 10 and ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:40.000') where c_int < 20;",
|
||||
"res": []
|
||||
}
|
||||
]
|
||||
sql_list = []
|
||||
res_list = []
|
||||
for item in query_list:
|
||||
sql_list.append(item["sql"])
|
||||
res_list.append(item["res"])
|
||||
tdSql.queryAndCheckResult(sql_list, res_list)
|
||||
|
||||
def test_abnormal_query(self):
|
||||
# incorrect parameter
|
||||
table_list = self.table_dic["super_table"] + self.table_dic["child_table"] + self.table_dic["common_table"]
|
||||
incorrect_parameter_list = ["()", "(null)", "(*)", "(c_ts)", "(c_ts, 1s)", "(c_int)", "(c_bigint)", "(c_double)", "(c_nchar)", "(ts, null)",
|
||||
"(ts, *)", "(2024-01-09 17:00:00)", "(2024-01-09 17:00:00, 1s)", "(t1)", "(t1, 1s)", "(t2)", "(t3)"]
|
||||
for table in table_list:
|
||||
for param in incorrect_parameter_list:
|
||||
if table.startswith("st"):
|
||||
tdSql.error("select elapsed{} from {} group by tbname order by ts;".format(param, table))
|
||||
else:
|
||||
tdSql.error("select elapsed{} from {};".format(param, table))
|
||||
tdSql.error("select elapsed{} from {} group by ".format(param, table))
|
||||
|
||||
# query with unsupported function, like leastsquares、diff、derivative、top、bottom、last_row、interp
|
||||
unsupported_sql_list = [
|
||||
"select elapsed(leastsquares(c_int, 1, 2)) from st1 group by tbname;",
|
||||
"select elapsed(diff(ts)) from st1;",
|
||||
"select elapsed(derivative(ts, 1s, 1)) from st1 group by tbname order by ts;",
|
||||
"select elapsed(top(ts, 5)) from st1 group by tbname order by ts;",
|
||||
"select top(elapsed(ts), 5) from st1 group by tbname order by ts;",
|
||||
"select elapsed(bottom(ts)) from st1 group by tbname order by ts;",
|
||||
"select bottom(elapsed(ts)) from st1 group by tbname order by ts;",
|
||||
"select elapsed(last_row(ts)) from st1 group by tbname order by ts;",
|
||||
"select elapsed(interp(ts, 0)) from st1 group by tbname order by ts;"
|
||||
]
|
||||
tdSql.errors(unsupported_sql_list)
|
||||
|
||||
# nested aggregate function
|
||||
nested_sql_list = [
|
||||
"select avg(elapsed(ts, 1s)) from st1 group by tbname order by ts;",
|
||||
"select elapsed(avg(ts), 1s) from st1 group by tbname order by ts;",
|
||||
"select elapsed(sum(ts), 1s) from st1 group by tbname order by ts;",
|
||||
"select elapsed(count(ts), 1s) from st1 group by tbname order by ts;",
|
||||
"select elapsed(min(ts), 1s) from st1 group by tbname order by ts;",
|
||||
"select elapsed(max(ts), 1s) from st1 group by tbname order by ts;",
|
||||
"select elapsed(first(ts), 1s) from st1 group by tbname order by ts;",
|
||||
"select elapsed(last(ts), 1s) from st1 group by tbname order by ts;"
|
||||
]
|
||||
tdSql.errors(nested_sql_list)
|
||||
|
||||
# other error
|
||||
other_sql_list = [
|
||||
"select elapsed(ts, 1s) from t1 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:40.000' interval(10s) fill(next) union select elapsed(ts, 1s) from st2 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:49.000' interval(5s) fill(prev) group by tbname;",
|
||||
"select elapsed(time ,1s) from (select elapsed(ts,1s) time from st1);",
|
||||
"select elapsed(ts , 1s) from (select elapsed(ts, 1s) ts from st2);",
|
||||
"select elapsed(time, 1s) from (select elapsed(ts, 1s) time from st1 group by tbname);",
|
||||
"select elapsed(ts , 1s) from (select elapsed(ts, 1s) ts from st2 group by tbname);",
|
||||
"select elapsed(ts, 1s) from (select * from st1 where ts between '2023-03-01 15:00:00.000' and '2023-03-01 15:01:40.000' interval(10s) fill(next)) where c_int > 10;"
|
||||
]
|
||||
tdSql.errors(other_sql_list)
|
||||
|
||||
def run(self):
|
||||
self.prepareData()
|
||||
self.test_normal_query()
|
||||
self.test_query_with_filter()
|
||||
self.test_query_with_other_function()
|
||||
self.test_query_with_join()
|
||||
self.test_query_with_union()
|
||||
self.test_abnormal_query()
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -128,7 +128,7 @@ class TDTestCase(TBase):
|
|||
self.checkInsertCorrect()
|
||||
|
||||
# check stream correct and drop stream
|
||||
self.checkStreamCorrect()
|
||||
# self.checkStreamCorrect()
|
||||
|
||||
# drop stream
|
||||
self.dropStream(self.sname)
|
||||
|
|
|
@ -22,6 +22,7 @@ class ClusterDnodes(TDDnodes):
|
|||
def init(self, dnodes_lists, deployPath, masterIp):
|
||||
self.dnodes = dnodes_lists # dnode must be TDDnode instance
|
||||
super(ClusterDnodes, self).init(deployPath, masterIp)
|
||||
self.model = "cluster"
|
||||
|
||||
clusterDnodes = ClusterDnodes()
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ class TDDnodes:
|
|||
self.valgrind = 0
|
||||
self.asan = False
|
||||
self.killValgrind = 0
|
||||
self.model = "single"
|
||||
|
||||
def init(self, path, remoteIP = ""):
|
||||
binPath = self.dnodes[0].getPath() + "/../../../"
|
||||
|
@ -268,6 +269,14 @@ class TDDnodes:
|
|||
def getAsan(self):
|
||||
return self.asan
|
||||
|
||||
def getModel(self):
|
||||
return self.model
|
||||
|
||||
def getDnodeCfgPath(self, index):
|
||||
self.check(index)
|
||||
return self.dnodes[index - 1].cfgPath
|
||||
|
||||
|
||||
def setLevelDisk(self, level, disk):
|
||||
for i in range(len(self.dnodes)):
|
||||
self.dnodes[i].level = int(level)
|
||||
|
|
|
@ -83,6 +83,49 @@ class TDSql:
|
|||
# do execute
|
||||
#
|
||||
|
||||
def errors(self, sql_list, expected_error_id_list=None, expected_error_info_list=None):
|
||||
"""Execute the sql query and check the error info, expected error id or info should keep the same order with sql list,
|
||||
expected_error_id_list or expected_error_info_list is None, then the error info will not be checked.
|
||||
:param sql_list: the sql list to be executed.
|
||||
:param expected_error_id: the expected error number.
|
||||
:param expected_error_info: the expected error info.
|
||||
:return: None
|
||||
"""
|
||||
try:
|
||||
if len(sql_list) > 0:
|
||||
for i in range(len(sql_list)):
|
||||
if expected_error_id_list and expected_error_info_list:
|
||||
self.error(sql_list[i], expected_error_id_list[i], expected_error_info_list[i])
|
||||
elif expected_error_id_list:
|
||||
self.error(sql_list[i], expectedErrno=expected_error_id_list[i])
|
||||
elif expected_error_info_list:
|
||||
self.error(sql_list[i], expectErrInfo=expected_error_info_list[i])
|
||||
else:
|
||||
self.error(sql_list[i])
|
||||
else:
|
||||
tdLog.exit("sql list is empty")
|
||||
except Exception as ex:
|
||||
tdLog.exit("Failed to execute sql list: %s, error: %s" % (sql_list, ex))
|
||||
|
||||
def queryAndCheckResult(self, sql_list, expect_result_list):
|
||||
"""Execute the sql query and check the result.
|
||||
:param sql_list: the sql list to be executed.
|
||||
:param expect_result_list: the expected result list.
|
||||
:return: None
|
||||
"""
|
||||
try:
|
||||
for index in range(len(sql_list)):
|
||||
self.query(sql_list[index])
|
||||
if len(expect_result_list[index]) == 0:
|
||||
self.checkRows(0)
|
||||
else:
|
||||
self.checkRows(len(expect_result_list[index]))
|
||||
for row in range(len(expect_result_list[index])):
|
||||
for col in range(len(expect_result_list[index][row])):
|
||||
self.checkData(row, col, expect_result_list[index][row][col])
|
||||
except Exception as ex:
|
||||
raise(ex)
|
||||
|
||||
def query(self, sql, row_tag=None, queryTimes=10, count_expected_res=None):
|
||||
self.sql = sql
|
||||
i=1
|
||||
|
@ -447,6 +490,48 @@ class TDSql:
|
|||
if(show):
|
||||
tdLog.info("check successfully")
|
||||
|
||||
def checkDataMem(self, mem):
|
||||
if not isinstance(mem, list):
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, self.sql)
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expect data is error, must is array[][]" % args)
|
||||
|
||||
if len(mem) != self.queryRows:
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, self.sql, len(mem), self.queryRows)
|
||||
tdLog.exit("%s(%d) failed: sql:%s, row:%d is larger than queryRows:%d" % args)
|
||||
# row, col, data
|
||||
for row, rowData in enumerate(mem):
|
||||
for col, colData in enumerate(rowData):
|
||||
self.checkData(row, col, colData)
|
||||
tdLog.info("check successfully")
|
||||
|
||||
def checkDataCsv(self, csvfilePath):
|
||||
if not isinstance(csvfilePath, str) or len(csvfilePath) == 0:
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, self.sql, csvfilePath)
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expect csvfile path error:%s" % args)
|
||||
|
||||
tdLog.info("read csvfile read begin")
|
||||
data = []
|
||||
try:
|
||||
with open(csvfilePath) as csvfile:
|
||||
csv_reader = csv.reader(csvfile) # csv.reader read csvfile\
|
||||
# header = next(csv_reader) # Read the header of each column in the first row
|
||||
for row in csv_reader: # csv file save to data
|
||||
data.append(row)
|
||||
except FileNotFoundError:
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, self.sql, csvfilePath)
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expect csvfile not find error:%s" % args)
|
||||
except Exception as e:
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, self.sql, csvfilePath, str(e))
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expect csvfile path:%s, read error:%s" % args)
|
||||
|
||||
tdLog.info("read csvfile read successfully")
|
||||
self.checkDataMem(data)
|
||||
|
||||
# return true or false replace exit, no print out
|
||||
def checkRowColNoExit(self, row, col):
|
||||
caller = inspect.getframeinfo(inspect.stack()[2][0])
|
||||
|
|
|
@ -18,6 +18,7 @@ import datetime
|
|||
|
||||
from frame.server.dnode import *
|
||||
from frame.server.dnodes import *
|
||||
from frame.server.cluster import *
|
||||
|
||||
|
||||
class srvCtl:
|
||||
|
@ -34,19 +35,32 @@ class srvCtl:
|
|||
|
||||
# start
|
||||
def dnodeStart(self, idx):
|
||||
if clusterDnodes.getModel() == 'cluster':
|
||||
return clusterDnodes.starttaosd(idx)
|
||||
|
||||
return tdDnodes.starttaosd(idx)
|
||||
|
||||
# stop
|
||||
def dnodeStop(self, idx):
|
||||
if clusterDnodes.getModel() == 'cluster':
|
||||
return clusterDnodes.stoptaosd(idx)
|
||||
|
||||
return tdDnodes.stoptaosd(idx)
|
||||
|
||||
def dnodeStopAll(self):
|
||||
if clusterDnodes.getModel() == 'cluster':
|
||||
return clusterDnodes.stopAll()
|
||||
|
||||
return tdDnodes.stopAll()
|
||||
#
|
||||
# about path
|
||||
#
|
||||
|
||||
# get cluster root path like /root/TDinternal/sim/
|
||||
def clusterRootPath(self):
|
||||
if clusterDnodes.getModel() == 'cluster':
|
||||
return clusterDnodes.getDnodesRootDir()
|
||||
|
||||
return tdDnodes.getDnodesRootDir()
|
||||
|
||||
# return dnode data files list
|
||||
|
@ -60,7 +74,9 @@ class srvCtl:
|
|||
|
||||
# taos.cfg position
|
||||
def dnodeCfgPath(self, idx):
|
||||
return tdDnodes.dnodes[idx-1].cfgPath
|
||||
if clusterDnodes.getModel() == 'cluster':
|
||||
return clusterDnodes.getDnodeCfgPath(idx)
|
||||
return tdDnodes.getDnodeCfgPath(idx)
|
||||
|
||||
|
||||
sc = srvCtl()
|
|
@ -17,11 +17,15 @@ fi
|
|||
,,y,army,./pytest.sh python3 ./test.py -f enterprise/multi-level/mlevel_basic.py -N 3 -L 3 -D 2
|
||||
,,y,army,./pytest.sh python3 ./test.py -f enterprise/s3/s3_basic.py -L 3 -D 1
|
||||
,,y,army,./pytest.sh python3 ./test.py -f community/cluster/snapshot.py -N 3 -L 3 -D 2
|
||||
,,y,army,./pytest.sh python3 ./test.py -f community/query/function/test_func_elapsed.py
|
||||
,,y,army,./pytest.sh python3 ./test.py -f community/query/fill/fill_desc.py -N 3 -L 3 -D 2
|
||||
,,y,army,./pytest.sh python3 ./test.py -f community/cluster/incSnapshot.py -N 3 -L 3 -D 2
|
||||
,,y,army,./pytest.sh python3 ./test.py -f community/query/query_basic.py -N 3
|
||||
|
||||
,,n,army,python3 ./test.py -f community/cmdline/fullopt.py
|
||||
|
||||
|
||||
|
||||
#
|
||||
# system test
|
||||
#
|
||||
|
@ -44,6 +48,7 @@ fi
|
|||
#,,n,system-test,python3 ./test.py -f 8-stream/snode_restart.py -N 4
|
||||
,,n,system-test,python3 ./test.py -f 8-stream/snode_restart_with_checkpoint.py -N 4
|
||||
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/partition_expr.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/project_group.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/tbname_vgroup.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/count_interval.py
|
||||
|
@ -232,10 +237,14 @@ fi
|
|||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-stb-select-duplicatedata.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-stb-select-duplicatedata-false.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-stb-select.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-stb-select-false.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-stb.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-stb-false.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-column.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-column-false.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-db.py -N 3 -n 3
|
||||
e
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeSplit-db-false.py -N 3 -n 3
|
||||
|
||||
,,y,system-test,./pytest.sh python3 test.py -f 7-tmq/tmqVnodeReplicate.py -M 3 -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TD-19201.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TD-21561.py
|
||||
|
@ -1109,6 +1118,7 @@ e
|
|||
,,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/join_order.sim
|
||||
,,y,script,./test.sh -f tsim/query/count_spread.sim
|
||||
,,y,script,./test.sh -f tsim/query/unionall_as_table.sim
|
||||
,,y,script,./test.sh -f tsim/query/multi_order_by.sim
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sql connect
|
||||
|
||||
sql drop database if exists db1;
|
||||
sql create database db1 vgroups 1;
|
||||
sql use db1;
|
||||
sql create stable sta (ts timestamp, col1 int) tags(t1 int);
|
||||
sql create table tba1 using sta tags(1);
|
||||
|
||||
sql insert into tba1 values ('2023-11-17 16:29:00', 1);
|
||||
sql insert into tba1 values ('2023-11-17 16:29:02', 3);
|
||||
sql insert into tba1 values ('2023-11-17 16:29:03', 4);
|
||||
sql insert into tba1 values ('2023-11-17 16:29:04', 5);
|
||||
|
||||
|
||||
sql select a.*,b.* from tba1 a, (select * from tba1 order by ts) b where a.ts=b.ts;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
sql select a.*,b.* from (select * from tba1 order by ts) a, tba1 b where a.ts=b.ts;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
sql select a.*,b.* from tba1 a, (select * from tba1 order by ts desc) b where a.ts=b.ts;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
sql select a.*,b.* from (select * from tba1 order by ts desc) a, tba1 b where a.ts=b.ts;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
sql select a.*,b.* from (select * from tba1 order by ts) a, (select * from tba1 order by ts) b where a.ts=b.ts;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
sql select a.*,b.* from (select * from tba1 order by ts desc) a, (select * from tba1 order by ts desc) b where a.ts=b.ts;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
sql select a.*,b.* from (select * from tba1 order by ts) a, (select * from tba1 order by ts desc) b where a.ts=b.ts;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
sql select a.*,b.* from (select * from tba1 order by ts desc) a, (select * from tba1 order by ts) b where a.ts=b.ts;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|
@ -19,12 +19,12 @@ class TDTestCase:
|
|||
tdSql.init(conn.cursor(), logSql)
|
||||
self.buffer_boundary = [3, 4097, 8193, 12289, 16384]
|
||||
# remove the value > free_memory, 70% is the weight to calculate the max value
|
||||
if platform.system() == "Linux" and platform.machine() == "aarch64":
|
||||
mem = psutil.virtual_memory()
|
||||
free_memory = mem.free * 0.7 / 1024 / 1024
|
||||
for item in self.buffer_boundary:
|
||||
if item > free_memory:
|
||||
self.buffer_boundary.remove(item)
|
||||
# if platform.system() == "Linux" and platform.machine() == "aarch64":
|
||||
# mem = psutil.virtual_memory()
|
||||
# free_memory = mem.free * 0.7 / 1024 / 1024
|
||||
# for item in self.buffer_boundary:
|
||||
# if item > free_memory:
|
||||
# self.buffer_boundary.remove(item)
|
||||
|
||||
self.buffer_error = [self.buffer_boundary[0] -
|
||||
1, self.buffer_boundary[-1]+1]
|
||||
|
@ -34,11 +34,14 @@ class TDTestCase:
|
|||
|
||||
def alter_buffer(self):
|
||||
tdSql.execute('create database db')
|
||||
for buffer in self.buffer_boundary:
|
||||
tdSql.execute(f'alter database db buffer {buffer}')
|
||||
tdSql.query(
|
||||
'select * from information_schema.ins_databases where name = "db"')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][8], buffer)
|
||||
if platform.system() == "Linux" and platform.machine() == "aarch64":
|
||||
tdLog.debug("Skip check points for Linux aarch64 due to environment settings")
|
||||
else:
|
||||
for buffer in self.buffer_boundary:
|
||||
tdSql.execute(f'alter database db buffer {buffer}')
|
||||
tdSql.query(
|
||||
'select * from information_schema.ins_databases where name = "db"')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][8], buffer)
|
||||
tdSql.execute('drop database db')
|
||||
tdSql.execute('create database db vgroups 10')
|
||||
for buffer in self.buffer_error:
|
||||
|
|
|
@ -168,8 +168,37 @@ class TDTestCase:
|
|||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9;")
|
||||
tdSql.checkRows(nonempty_tb_num)
|
||||
|
||||
def test_event_window(self, nonempty_tb_num):
|
||||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and 1=1;")
|
||||
tdSql.checkRows(nonempty_tb_num)
|
||||
|
||||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and 1=0;")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and tbname='sub_{self.stable}_0';")
|
||||
tdSql.checkRows(1)
|
||||
|
||||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and t2=0;")
|
||||
tdSql.checkRows(1)
|
||||
|
||||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _rowts>0;")
|
||||
tdSql.checkRows(nonempty_tb_num)
|
||||
|
||||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _qstart>0;")
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _qstart<0;")
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _qstart<_qend;")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.error(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _wstart<q_start;")
|
||||
tdSql.error(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _wstart - q_start > 0;")
|
||||
tdSql.error(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _irowts>0;")
|
||||
tdSql.error(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 and _wduration > 5s end with c2 = 9;")
|
||||
tdSql.error(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _wstart > 1299845454;")
|
||||
tdSql.error(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and _wduration + 1s > 5s;")
|
||||
tdSql.error(f"select tbname, count(*) from {self.dbname}.{self.stable} partition by tbname event_window start with c1 >= 0 end with c2 = 9 and count(*) > 10;")
|
||||
|
||||
|
||||
def test_error(self):
|
||||
tdSql.error(f"select * from {self.dbname}.{self.stable} group by t2")
|
||||
tdSql.error(f"select t2, count(*) from {self.dbname}.{self.stable} group by t2 where t2 = 1")
|
||||
|
@ -197,6 +226,7 @@ class TDTestCase:
|
|||
self.test_multi_group_key(self.tb_nums, nonempty_tb_num)
|
||||
self.test_multi_agg(self.tb_nums, nonempty_tb_num)
|
||||
self.test_window(nonempty_tb_num)
|
||||
self.test_event_window(nonempty_tb_num)
|
||||
|
||||
## test old version before changed
|
||||
# self.test_groupby('group', 0, 0)
|
||||
|
|
|
@ -302,6 +302,11 @@ class TDTestCase:
|
|||
|
||||
tdSql.error(f"SELECT last(ts) as t2, ts FROM t1 order by last(t2)")
|
||||
|
||||
tdSql.execute(f"alter local 'keepColumnName' '1'")
|
||||
tdSql.no_error(f"SELECT last(ts), first(ts) FROM t1 order by last(ts)")
|
||||
tdSql.no_error(f"SELECT last(c1), first(c1) FROM t1 order by last(c1)")
|
||||
tdSql.error(f"SELECT last(ts) as t, first(ts) as t FROM t1 order by last(t)")
|
||||
|
||||
def queryOrderByAmbiguousName(self):
|
||||
tdSql.error(sql="select c1 as name, c2 as name, c3 from t1 order by name", expectErrInfo='ambiguous',
|
||||
fullMatched=False)
|
||||
|
@ -315,6 +320,39 @@ class TDTestCase:
|
|||
|
||||
tdSql.no_error('select c1 as name from (select c1, c2 as name from st) order by name')
|
||||
|
||||
def queryOrderBySameCol(self):
|
||||
tdLog.info("query OrderBy same col ....")
|
||||
tdSql.execute(f"create stable sta (ts timestamp, col1 int) tags(t1 int);")
|
||||
tdSql.execute(f"create table tba1 using sta tags(1);")
|
||||
tdSql.execute(f"create table tba2 using sta tags(2);")
|
||||
|
||||
pd = datetime.datetime.now()
|
||||
ts = int(datetime.datetime.timestamp(pd)*1000*1000)
|
||||
tdSql.execute(f"insert into tba1 values ({ts}, 1);")
|
||||
tdSql.execute(f"insert into tba1 values ({ts+2}, 3);")
|
||||
tdSql.execute(f"insert into tba1 values ({ts+3}, 4);")
|
||||
tdSql.execute(f"insert into tba1 values ({ts+4}, 5);")
|
||||
tdSql.execute(f"insert into tba2 values ({ts}, 2);")
|
||||
tdSql.execute(f"insert into tba2 values ({ts+1}, 3);")
|
||||
tdSql.execute(f"insert into tba2 values ({ts+3}, 5);")
|
||||
tdSql.execute(f"insert into tba2 values ({ts+5}, 7);")
|
||||
tdSql.query(f"select a.col1, b.col1 from sta a inner join sta b on a.ts = b.ts and a.ts < {ts+2} order by a.col1, b.col1;")
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 0, 1)
|
||||
tdSql.checkData(1, 1, 2)
|
||||
tdSql.query(f"select a.col1, b.col1 from sta a inner join sta b on a.ts = b.ts and a.ts < {ts+2} order by a.col1, b.col1 desc;")
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.checkData(0, 1, 2)
|
||||
tdSql.checkData(1, 0, 1)
|
||||
tdSql.checkData(1, 1, 1)
|
||||
|
||||
tdSql.query(f"select a.col1, b.col1 from sta a inner join sta b on a.ts = b.ts and a.ts < {ts+2} order by a.col1 desc, b.col1 desc;")
|
||||
tdSql.checkData(1, 0, 2)
|
||||
tdSql.checkData(1, 1, 2)
|
||||
tdSql.checkData(2, 0, 2)
|
||||
tdSql.checkData(2, 1, 1)
|
||||
|
||||
# run
|
||||
def run(self):
|
||||
# prepare env
|
||||
|
@ -332,6 +370,8 @@ class TDTestCase:
|
|||
# td-28332
|
||||
self.queryOrderByAmbiguousName()
|
||||
|
||||
self.queryOrderBySameCol()
|
||||
|
||||
# stop
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
from wsgiref.headers import tspecials
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
import numpy as np
|
||||
|
||||
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor())
|
||||
|
||||
self.rowNum = 10
|
||||
self.batchNum = 5
|
||||
self.ts = 1537146000000
|
||||
|
||||
def run(self):
|
||||
dbname = "db"
|
||||
tdSql.prepare()
|
||||
|
||||
tdSql.execute(f'''create table sta(ts timestamp, f int, col2 bigint) tags(tg1 int, tg2 binary(20))''')
|
||||
tdSql.execute(f"create table sta1 using sta tags(1, 'a')")
|
||||
tdSql.execute(f"insert into sta1 values(1537146000001, 11, 110)")
|
||||
tdSql.execute(f"insert into sta1 values(1537146000002, 12, 120)")
|
||||
tdSql.execute(f"insert into sta1 values(1537146000003, 13, 130)")
|
||||
|
||||
tdSql.query("select _wstart, f+100, count(*) from db.sta partition by f+100 session(ts, 1a) order by _wstart");
|
||||
tdSql.checkData(0, 1, 111.0)
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -20,9 +20,10 @@ class TDTestCase:
|
|||
tdSql.execute("insert into td_28068.ct4 using td_28068.st (branch, scenario) tags ('3.1', 'scenario2') values (now(), 'query1', 9,10);")
|
||||
|
||||
def run(self):
|
||||
tdSql.error('select last(ts) as ts, last(branch) as branch, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch);')
|
||||
tdSql.error('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch), last(scenario); ')
|
||||
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch);')
|
||||
tdSql.checkRows(4)
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch), last(scenario); ')
|
||||
tdSql.checkRows(4)
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch); ')
|
||||
tdSql.checkRows(4)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import random
|
||||
import string
|
||||
import itertools
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
|
@ -15,56 +15,510 @@ class TDTestCase:
|
|||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor())
|
||||
self.dbname = 'db'
|
||||
self.stbname = 'st'
|
||||
self.ctbname_list = ["ct1", "ct2"]
|
||||
self.tag_value_list = ['{"instance":"100"}', '{"instance":"200"}']
|
||||
|
||||
self.metadata_dic = {
|
||||
"db_tag_json": {
|
||||
"supertables": [
|
||||
{
|
||||
"name": "st",
|
||||
"child_table_num": 2,
|
||||
"columns": [
|
||||
{
|
||||
"name": "ts",
|
||||
"type": "timestamp"
|
||||
},
|
||||
{
|
||||
"name": "col1",
|
||||
"type": "int"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"name": "t1",
|
||||
"type": "json"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"db": {
|
||||
"supertables": [
|
||||
{
|
||||
"name": "st1",
|
||||
"child_table_num": 2,
|
||||
"columns": [
|
||||
{
|
||||
"name": "ts",
|
||||
"type": "timestamp"
|
||||
},
|
||||
{
|
||||
"name": "col1",
|
||||
"type": "int"
|
||||
},
|
||||
{
|
||||
"name": "col2",
|
||||
"type": "bigint"
|
||||
},
|
||||
{
|
||||
"name": "col3",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "col4",
|
||||
"type": "double"
|
||||
},
|
||||
{
|
||||
"name": "col5",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "col6",
|
||||
"type": "binary(16)"
|
||||
},
|
||||
{
|
||||
"name": "col7",
|
||||
"type": "nchar(16)"
|
||||
},
|
||||
{
|
||||
"name": "col8",
|
||||
"type": "geometry(512)"
|
||||
},
|
||||
{
|
||||
"name": "col9",
|
||||
"type": "varbinary(32)"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"name": "t1",
|
||||
"type": "timestamp"
|
||||
},
|
||||
{
|
||||
"name": "t2",
|
||||
"type": "int"
|
||||
},
|
||||
{
|
||||
"name": "t3",
|
||||
"type": "bigint"
|
||||
},
|
||||
{
|
||||
"name": "t4",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "t5",
|
||||
"type": "double"
|
||||
},
|
||||
{
|
||||
"name": "t6",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "t7",
|
||||
"type": "binary(16)"
|
||||
},
|
||||
{
|
||||
"name": "t8",
|
||||
"type": "nchar(16)"
|
||||
},
|
||||
{
|
||||
"name": "t9",
|
||||
"type": "geometry(512)"
|
||||
},
|
||||
{
|
||||
"name": "t10",
|
||||
"type": "varbinary(32)"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "st2",
|
||||
"child_table_num": 2,
|
||||
"columns": [
|
||||
{
|
||||
"name": "ts",
|
||||
"type": "timestamp"
|
||||
},
|
||||
{
|
||||
"name": "col1",
|
||||
"type": "int"
|
||||
},
|
||||
{
|
||||
"name": "col2",
|
||||
"type": "bigint"
|
||||
},
|
||||
{
|
||||
"name": "col3",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "col4",
|
||||
"type": "double"
|
||||
},
|
||||
{
|
||||
"name": "col5",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "col6",
|
||||
"type": "binary(16)"
|
||||
},
|
||||
{
|
||||
"name": "col7",
|
||||
"type": "nchar(16)"
|
||||
},
|
||||
{
|
||||
"name": "col8",
|
||||
"type": "geometry(512)"
|
||||
},
|
||||
{
|
||||
"name": "col9",
|
||||
"type": "varbinary(32)"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"name": "t1",
|
||||
"type": "timestamp"
|
||||
},
|
||||
{
|
||||
"name": "t2",
|
||||
"type": "int"
|
||||
},
|
||||
{
|
||||
"name": "t3",
|
||||
"type": "bigint"
|
||||
},
|
||||
{
|
||||
"name": "t4",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "t5",
|
||||
"type": "double"
|
||||
},
|
||||
{
|
||||
"name": "t6",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "t7",
|
||||
"type": "binary(16)"
|
||||
},
|
||||
{
|
||||
"name": "t8",
|
||||
"type": "nchar(16)"
|
||||
},
|
||||
{
|
||||
"name": "t9",
|
||||
"type": "geometry(512)"
|
||||
},
|
||||
{
|
||||
"name": "t10",
|
||||
"type": "varbinary(32)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
def prepareData(self):
|
||||
# db
|
||||
tdSql.execute("create database {};".format(self.dbname))
|
||||
tdSql.execute("use {};".format(self.dbname))
|
||||
tdLog.debug("Create database %s" % self.dbname)
|
||||
for db in self.metadata_dic.keys():
|
||||
if db == "db_tag_json":
|
||||
# db
|
||||
tdSql.execute(f"create database {db};")
|
||||
tdSql.execute(f"use {db};")
|
||||
tdLog.debug(f"Create database {db}")
|
||||
|
||||
# super table
|
||||
tdSql.execute("create table {} (ts timestamp, col1 int) tags (t1 json);".format(self.stbname))
|
||||
tdLog.debug("Create super table %s" % self.stbname)
|
||||
# super table
|
||||
for item in self.metadata_dic[db]["supertables"]:
|
||||
sql = f"create table {item['name']} ("
|
||||
for column in item["columns"]:
|
||||
sql += f"{column['name']} {column['type']},"
|
||||
sql = sql[:-1] + ") tags ("
|
||||
for tag in item["tags"]:
|
||||
sql += f"{tag['name']} {tag['type']},"
|
||||
sql = sql[:-1] + ");"
|
||||
tdLog.debug(sql)
|
||||
tdSql.execute(sql)
|
||||
tdLog.debug(f"Create super table {item['name']}")
|
||||
|
||||
# child table
|
||||
for i in range(len(self.ctbname_list)):
|
||||
tdSql.execute("create table {} using {} tags('{}');".format(self.ctbname_list[i], self.stbname, self.tag_value_list[i]))
|
||||
tdLog.debug("Create child table %s" % self.ctbname_list)
|
||||
# child table
|
||||
tag_value_list = ['{"instance":"100"}', '{"instance":"200"}']
|
||||
for i in range(item["child_table_num"]):
|
||||
tdSql.execute(f"create table {'ct' + str(i+1)} using {item['name']} tags('{tag_value_list[i]}');")
|
||||
tdLog.debug(f"Create child table {'ct' + str(i+1)} successfully")
|
||||
|
||||
# insert data
|
||||
tdSql.execute("insert into {} values(now, 1)(now+1s, 2)".format(self.ctbname_list[0]))
|
||||
tdSql.execute("insert into {} values(now, null)(now+1s, null)".format(self.ctbname_list[1]))
|
||||
# insert data
|
||||
if i == 0:
|
||||
tdSql.execute(f"insert into {'ct' + str(i+1)} values(now, 1)(now+1s, 2)")
|
||||
elif i == 1:
|
||||
tdSql.execute(f"insert into {'ct' + str(i+1)} values(now, null)(now+1s, null)")
|
||||
elif db == "db":
|
||||
# create database db_empty
|
||||
tdSql.execute("create database db_empty;")
|
||||
tdSql.execute("use db_empty;")
|
||||
tdLog.debug("Create database db_empty successfully")
|
||||
|
||||
# super table
|
||||
for item in self.metadata_dic[db]["supertables"]:
|
||||
sql = f"create table {item['name']} ("
|
||||
for column in item["columns"]:
|
||||
sql += f"{column['name']} {column['type']},"
|
||||
sql = sql[:-1] + ") tags ("
|
||||
for tag in item["tags"]:
|
||||
sql += f"{tag['name']} {tag['type']},"
|
||||
sql = sql[:-1] + ");"
|
||||
tdLog.debug(sql)
|
||||
tdSql.execute(sql)
|
||||
tdLog.debug(f"Create super table {item['name']}")
|
||||
|
||||
# child table
|
||||
tag_value_list = [['2024-01-01 12:00:00.000', 1, 1111111111111, 1.11, 111111.1111, True, 'aaa', 'beijing', 'POINT (3.000000 6.000000)', '0x7661726331'],['2024-01-02 12:00:00.000', 2, 2222222222222, 2.22, 222222.2222, False, 'bbb', 'shanghai', 'LINESTRING (1.000000 1.000000, 2.000000 2.000000, 5.000000 5.000000)', '0x7f829000']]
|
||||
for i in range(item["child_table_num"]):
|
||||
sql = f"create table {'ct' + (str(i+1) if item['name'] == 'st1' else str(i+3))} using {item['name']} tags("
|
||||
for tag in tag_value_list[i]:
|
||||
if type(tag) == str:
|
||||
sql += f"'{tag}',"
|
||||
else:
|
||||
sql += f"{tag},"
|
||||
sql = sql[:-1] + ");"
|
||||
tdSql.execute(sql)
|
||||
tdLog.debug(f"Create child table {'ct' + (str(i+1) if item['name'] == 'st1' else str(i+3))} successfully")
|
||||
|
||||
# create database db_with_data
|
||||
tdSql.execute("create database db_with_data;")
|
||||
tdSql.execute("use db_with_data;")
|
||||
tdLog.debug("Create database db_with_data successfully")
|
||||
|
||||
# super table
|
||||
for item in self.metadata_dic[db]["supertables"]:
|
||||
sql = f"create table {item['name']} ("
|
||||
for column in item["columns"]:
|
||||
sql += f"{column['name']} {column['type']},"
|
||||
sql = sql[:-1] + ") tags ("
|
||||
for tag in item["tags"]:
|
||||
sql += f"{tag['name']} {tag['type']},"
|
||||
sql = sql[:-1] + ");"
|
||||
tdLog.debug(sql)
|
||||
tdSql.execute(sql)
|
||||
tdLog.debug(f"Create super table {item['name']}")
|
||||
|
||||
# child table
|
||||
tag_value_list = [['2024-01-01 12:00:00.000', 1, 1111111111111, 1.11, 111111.1111, True, 'aaa', 'beijing', 'POINT (3.000000 6.000000)', '0x7661726331'],['2024-01-02 12:00:00.000', 2, 2222222222222, 2.22, 222222.2222, False, 'bbb', 'shanghai', 'LINESTRING (1.000000 1.000000, 2.000000 2.000000, 5.000000 5.000000)', '0x7f829000']]
|
||||
for i in range(item["child_table_num"]):
|
||||
sql = f"create table {'ct' + (str(i+1) if item['name'] == 'st1' else str(i+3))} using {item['name']} tags("
|
||||
for tag in tag_value_list[i]:
|
||||
if type(tag) == str:
|
||||
sql += f"'{tag}',"
|
||||
else:
|
||||
sql += f"{tag},"
|
||||
sql = sql[:-1] + ");"
|
||||
tdSql.execute(sql)
|
||||
tdLog.debug(f"Create child table {'ct' + (str(i+1) if item['name'] == 'st1' else str(i+3))} successfully")
|
||||
|
||||
# insert into data
|
||||
start_ts = 1677654000000 # 2023-03-01 15:00:00.000
|
||||
sql = "insert into {} values".format("ct" + (str(i+1) if item["name"] == "st1" else str(i+3)))
|
||||
binary_vlist = ["ccc", "ddd", "eee", "fff"]
|
||||
nchar_vlist = ["guangzhou", "tianjing", "shenzhen", "hangzhou"]
|
||||
geometry_vlist = ["POINT (4.0 8.0)", "POINT (3.0 5.0)", "LINESTRING (1.000000 1.000000, 2.000000 2.000000, 5.000000 5.000000)", "POLYGON ((3.000000 6.000000, 5.000000 6.000000, 5.000000 8.000000, 3.000000 8.000000, 3.000000 6.000000))"]
|
||||
varbinary_vlist = ["0x7661726332", "0x7661726333", "0x7661726334", "0x7661726335"]
|
||||
st_index = i if item["name"] == "st1" else (i+2)
|
||||
for i in range(100):
|
||||
sql += f"({start_ts + 1000 * i}, {str(i+1)}, {str(i+1)}, {str(i+1)}, {str(i+1)}, {True if i % 2 == 0 else False}, '{binary_vlist[st_index % 4]}', '{nchar_vlist[st_index % 4]}', '{geometry_vlist[st_index % 4]}', '{varbinary_vlist[st_index % 4]}')"
|
||||
tdSql.execute(sql)
|
||||
tdLog.debug(f"Insert into data into child table {'ct' + (str(i+1) if item['name'] == 'st1' else str(i+3))} successfully")
|
||||
|
||||
def test_tag_json(self):
|
||||
tdSql.execute("use db_tag_json;")
|
||||
|
||||
# super table query with correct tag name of json type
|
||||
tdSql.query("select to_char(ts, 'yyyy-mm-dd hh24:mi:ss') as time, irate(col1) from st group by to_char(ts, 'yyyy-mm-dd hh24:mi:ss'), t1->'instance' order by time;")
|
||||
tdSql.checkRows(2)
|
||||
|
||||
# child table query with incorrect tag name of json type
|
||||
tdSql.query("select to_char(ts, 'yyyy-mm-dd hh24:mi:ss') as time, irate(col1) from ct1 group by to_char(ts, 'yyyy-mm-dd hh24:mi:ss'), t1->'name' order by time;")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# child table query with null value
|
||||
tdSql.query("select ts, avg(col1) from ct2 group by ts, t1->'name' order by ts;")
|
||||
tdSql.checkRows(2)
|
||||
|
||||
def test_db_empty(self):
|
||||
tdSql.execute("use db_empty;")
|
||||
table_list = ["st1", "ct1"]
|
||||
column_list = ["col1", "col2", "col3", "col4", "col5"]
|
||||
tag_list = ["t2", "t3", "t4", "t5", "t6"]
|
||||
operator_list = ["+", "-", "*", "/"]
|
||||
fun_list = ["avg", "count", "sum", "spread"]
|
||||
|
||||
# two columns with arithmetic operation
|
||||
for table in table_list:
|
||||
for columns in list(itertools.combinations(column_list + tag_list, 2)):
|
||||
operator = random.choice(operator_list)
|
||||
sql = f"select ({columns[0]} {operator} {columns[1]}) as total from {table};"
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# aggregation function
|
||||
for table in table_list:
|
||||
for columns in list(itertools.combinations(column_list[:-1] + tag_list[:-1], 2)):
|
||||
fun = random.sample(fun_list, 2)
|
||||
sql = f"select ({fun[0]}({columns[0]}) + {fun[1]}({columns[1]})) as total from {table};"
|
||||
tdSql.query(sql)
|
||||
if "count" in fun:
|
||||
# default config 'countAlwaysReturnValue' as 0
|
||||
tdSql.checkRows(1)
|
||||
else:
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# join
|
||||
table_list = ["st1", "st2", "ct1", "ct2", "ct3", "ct4"]
|
||||
column_list = ["col1", "col2", "col3", "col4", "col5"]
|
||||
tag_list = ["t2", "t3", "t4", "t5", "t6"]
|
||||
where_list = ["col1 > 100", "col2 < 237883294", "col3 >= 163.23", "col4 <= 674324.2374898237", "col5=true", "col6='aaa'",
|
||||
"col7='beijing'", "col8!='POINT (3.000000 6.000000)'", "col9='0x7661726331'"]
|
||||
for table in list(itertools.combinations(table_list,2)):
|
||||
where = random.choice(where_list)
|
||||
column = random.choice(column_list)
|
||||
tag = random.choice(tag_list)
|
||||
sql = f"select ({table[0] + '.' + column} + {table[1] + '.' + tag}) total from {table[0]} join {table[1]} on {table[0]+ '.ts=' + table[1] + '.ts'} where {table[0] + '.' + where};"
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# group by
|
||||
value_fun_list = ["sum(col1+col2)", "avg(col3+col4)", "count(col6+col7)", "stddev(col2+col4)", "spread(col2+col3)"]
|
||||
group_by_list = ["tbname", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10"]
|
||||
for table in table_list:
|
||||
value_fun = random.choice(value_fun_list)
|
||||
where = random.choice(where_list)
|
||||
group_by = random.choice(group_by_list)
|
||||
sql = f"select {value_fun} from {table} where {where} group by {group_by};"
|
||||
tdSql.query(sql)
|
||||
# default config 'countAlwaysReturnValue' as 0
|
||||
if "count" in value_fun and "st" in table:
|
||||
tdSql.checkRows(2)
|
||||
elif "count" in value_fun and "ct" in table:
|
||||
tdSql.checkRows(1)
|
||||
else:
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# window query
|
||||
for table in table_list:
|
||||
tag = random.choice(tag_list)
|
||||
if "st" in table:
|
||||
sql = f"select _wstart, {tag}, avg(col3+col4) from {table} where ts between '2024-03-01' and '2024-03-02' partition by {tag} interval(10s) sliding(5s) fill(linear);"
|
||||
elif "ct" in table:
|
||||
sql = f"select _wstart, sum(col1+col2) from {table} where ts between '2024-03-01' and '2024-03-02' partition by {tag} interval(10s) sliding(5s) fill(next);"
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# nested query
|
||||
for table in table_list:
|
||||
sql_list = [
|
||||
"select (col1 + col2) from (select sum(col1) as col1, avg(col2) as col2 from {} where col1 > 100 and ts between '2024-03-01' and '2024-03-02' group by tbname);".format(table),
|
||||
"select last(ts), avg(col2 - col3) from (select first(ts) as ts, sum(col2) as col2, last(col3) as col3 from {} where col9 != 'abc' partition by tbname interval(10s) sliding(5s));".format(table),
|
||||
"select elapsed(ts, 1s), sum(c1 + c2) from (select * from (select ts, (col1+col2) as c1, (col3 * col4) as c2, tbname from {} where col1 > 100 and ts between '2024-03-01' and '2024-03-02')) group by tbname;".format(table)
|
||||
]
|
||||
for sql in sql_list:
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# drop column/tag
|
||||
del_column_tag_list = ["col1", "t1"]
|
||||
error_sql_list = [
|
||||
"select first(t1), sum(col1) from st1 group by tbname;",
|
||||
"select last(ts), avg(col1) from st1 group by tbname;",
|
||||
"select count(col1) from (select * from st1 where ts between '2024-03-01' and '2024-03-02' and col1 > 100) group by tbname;",
|
||||
]
|
||||
for item in del_column_tag_list:
|
||||
if "col" in item:
|
||||
sql = f"alter table st1 drop column {item};"
|
||||
elif "t" in item:
|
||||
sql = f"alter table st1 drop tag {item};"
|
||||
tdSql.execute(sql)
|
||||
tdLog.debug("Delete {} successfully".format(str(del_column_tag_list)))
|
||||
|
||||
for table in table_list:
|
||||
for sql in error_sql_list:
|
||||
tdSql.error(sql)
|
||||
|
||||
# modify column for common table
|
||||
tdSql.execute("create table t1 (ts timestamp, col1 int, col2 bigint, col3 float, col4 double, col5 bool, col6 binary(16), col7 nchar(16), col8 geometry(512), col9 varbinary(32));")
|
||||
tdSql.execute("insert into t1 values(now, 1, 1111111111111, 1.11, 111111.1111, True, 'aaa', 'beijing', 'POINT (3.000000 6.000000)', '0x7661726331');")
|
||||
tdSql.execute("alter table t1 rename column col1 col11;")
|
||||
tdSql.error("select col1 from t1 where ts <= now and col3=1.11;")
|
||||
tdSql.query("select col11 from t1 where ts <= now and col3=1.11;")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 1)
|
||||
|
||||
def test_db_with_data(self):
|
||||
tdSql.execute("use db_with_data;")
|
||||
|
||||
sql_list = [
|
||||
"select pow(col1, null) from st1 where ts > now;",
|
||||
"select pow(null, col1) from st1 where ts > now;",
|
||||
"select log(null, col2) from st1 where col1 > 1000;",
|
||||
"select log(col2, null) from st1 where col1 > 1000;",
|
||||
"select avg(col1 + t2) from ct1 where ts between '2025-03-01' and '2025-03-02' and t2 < 0;",
|
||||
"select char_length(col6) from st1 where ts > now;",
|
||||
"select concat(col6, col7) from st1 where ts > now;",
|
||||
"select char_length(concat(col6, col7)) from st1 where ts > now;",
|
||||
"select rtrim(ltrim(concat(col6, col7))) from st1 where ts > now;",
|
||||
"select lower(rtrim(ltrim(concat(col6, col7)))) from st1 where ts > now;",
|
||||
"select upper(rtrim(ltrim(concat(col6, col7)))) from st1 where ts > now;",
|
||||
"select substr(rtrim(ltrim(concat(col6, col7))), 1, 10) from st1 where ts > now;",
|
||||
"select avg(col1 - col2) as v from st1 where ts between '2022-03-01' and '2022-03-02';",
|
||||
"select avg(col1 * col3) as v from st1 where ts between '2022-03-01' and '2022-03-02' and col1 > 100 group by tbname;",
|
||||
"select sum(col1 / col4) as cv, avg(t2 + t3) as tv from st1 where ts between '2022-03-01' and '2022-03-02' and col1 > 100 group by tbname;",
|
||||
"select sum(v1+v2) from (select first(ts) as time, avg(col1+col2) as v1, max(col3) as v2 from st1 where ts > now group by (col1+col2) order by (col1+col2));",
|
||||
"select first(ts), count(*), avg(col2 * t3) from (select ts, col1, col2, col3, t1, t2, t3, tbname from st1 where ts between '2022-03-01' and '2022-03-02' and col1 > 100) group by tbname;",
|
||||
"select cast(t8 as nchar(32)), sum(col1), avg(col2) from st1 where ts > now group by cast(t8 as nchar(32));",
|
||||
"select to_char(time, 'yyyy-mm-dd'), sum(v2 - v1) from (select first(ts) as time, avg(col2 + col3) as v1, max(col4) as v2 from st1 where ts < now group by (col2+col3) order by (col2+col3)) where time > now group by to_char(time, 'yyyy-mm-dd');",
|
||||
"select count(time) * sum(v) from (select to_iso8601(ts, '+00:00') as time, abs(col1+col2) as v, tbname from st1 where ts between '2023-03-01' and '2023-03-02' and col1 > 100) group by tbname;",
|
||||
"select avg(v) from (select apercentile(col1, 50) as v from st1 where ts between '2023-03-01' and '2023-03-02' group by tbname) where v > 50;",
|
||||
]
|
||||
for sql in sql_list:
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query("select total / v from (select elapsed(ts, 1s) as v, sum(col1) as total from st1 where ts between '2023-03-01' and '2023-03-02' interval(10s) fill(next));")
|
||||
tdSql.checkRows(8641)
|
||||
tdSql.checkData(0, 0, 11)
|
||||
|
||||
tdSql.query("select to_char(time, 'yyyy-mm-dd'), sum(v2 - v1) from (select first(ts) as time, avg(col2 + col3) as v1, max(col4) as v2 from st1 where ts < now group by (col2+col3) order by (col2+col3)) group by to_char(time, 'yyyy-mm-dd');")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, '2023-03-01')
|
||||
tdSql.checkData(0, 1, -5050)
|
||||
|
||||
tdSql.query("select avg(v) from (select apercentile(col1, 50) as v from st1 where ts between '2023-03-01' and '2023-03-02' group by tbname) group by (50 -v);")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 50)
|
||||
|
||||
# drop or modify column/tag
|
||||
tdSql.execute("alter stable st1 drop column col7;")
|
||||
tdLog.debug("Drop column col7 successfully")
|
||||
tdSql.error("select count(*) from (select upper(col7) from st1);")
|
||||
|
||||
tdSql.execute("alter stable st1 drop column col8;")
|
||||
tdLog.debug("Drop column col8 successfully")
|
||||
tdSql.error("select last(ts), avg(col1) from (select *, tbname from st1 where col8='POINT (3.0 6.0)') group by tbname;")
|
||||
|
||||
tdSql.execute("alter stable st1 rename tag t8 t88;")
|
||||
tdLog.debug("Rename tag t8 to t88 successfully")
|
||||
tdSql.error("select count(*) from st1 t1, (select * from st1 where t8 is not null order by ts limit 10) t2 where t1.ts=t2.ts;")
|
||||
|
||||
tdSql.execute("alter stable st1 rename tag t9 t99;")
|
||||
tdLog.debug("Rename tag t9 to t99 successfully")
|
||||
tdSql.error("select count(*) from st1 t1, (select * from st1 where t9='POINT (4.0 8.0)' limit 5) t2 where t1.ts=t2.ts;")
|
||||
|
||||
def run(self):
|
||||
self.prepareData()
|
||||
sql_list = [
|
||||
# super table query with correct tag name of json type
|
||||
{
|
||||
"sql": "select to_char(ts, 'yyyy-mm-dd hh24:mi:ss') as time, irate(col1) from st group by to_char(ts, 'yyyy-mm-dd hh24:mi:ss'), t1->'instance' order by time;",
|
||||
"result_check": "0.0"
|
||||
},
|
||||
# child table query with incorrect tag name of json type
|
||||
{
|
||||
"sql": "select to_char(ts, 'yyyy-mm-dd hh24:mi:ss') as time, irate(col1) from ct1 group by to_char(ts, 'yyyy-mm-dd hh24:mi:ss'), t1->'name' order by time;",
|
||||
"result_check": "None"
|
||||
},
|
||||
# child table query with null value
|
||||
{
|
||||
"sql": "select ts, avg(col1) from ct2 group by ts, t1->'name' order by ts;",
|
||||
"result_check": "None"
|
||||
}
|
||||
]
|
||||
for sql_dic in sql_list:
|
||||
tdSql.query(sql_dic["sql"])
|
||||
tdLog.debug("execute sql: %s" % sql_dic["sql"])
|
||||
for item in [row[1] for row in tdSql.queryResult]:
|
||||
if sql_dic["result_check"] in str(item):
|
||||
tdLog.debug("Check query result of '{}' successfully".format(sql_dic["sql"]))
|
||||
break
|
||||
self.test_tag_json()
|
||||
self.test_db_empty()
|
||||
self.test_db_with_data()
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
@ -72,4 +526,3 @@ class TDTestCase:
|
|||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
|
||||
import taos
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
import os
|
||||
import threading
|
||||
import math
|
||||
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.common import *
|
||||
from util.cluster import *
|
||||
sys.path.append("./7-tmq")
|
||||
from tmqCommon import *
|
||||
sys.path.append("./6-cluster")
|
||||
from clusterCommonCreate import *
|
||||
from clusterCommonCheck import clusterComCheck
|
||||
|
||||
class TDTestCase:
|
||||
def __init__(self):
|
||||
self.vgroups = 1
|
||||
self.ctbNum = 10
|
||||
self.rowsPerTbl = 1000
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
tdSql.init(conn.cursor(), True)
|
||||
|
||||
def getDataPath(self):
|
||||
selfPath = tdCom.getBuildPath()
|
||||
|
||||
return selfPath + '/../sim/dnode%d/data/vnode/vnode%d/wal/*';
|
||||
|
||||
def prepareTestEnv(self):
|
||||
tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ")
|
||||
paraDict = {'dbName': 'dbt',
|
||||
'dropFlag': 1,
|
||||
'event': '',
|
||||
'vgroups': 1,
|
||||
'stbName': 'stb',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}],
|
||||
'ctbPrefix': 'ctb',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 60,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
||||
paraDict['vgroups'] = self.vgroups
|
||||
paraDict['ctbNum'] = self.ctbNum
|
||||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
|
||||
tdCom.drop_all_db()
|
||||
tmqCom.initConsumerTable()
|
||||
tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], wal_retention_period=36000,vgroups=paraDict["vgroups"],replica=self.replicaVar)
|
||||
tdLog.info("create stb")
|
||||
tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"])
|
||||
return
|
||||
|
||||
def restartAndRemoveWal(self, deleteWal):
|
||||
tdDnodes = cluster.dnodes
|
||||
tdSql.query("select * from information_schema.ins_vnodes")
|
||||
for result in tdSql.queryResult:
|
||||
if result[2] == 'dbt':
|
||||
tdLog.debug("dnode is %d"%(result[0]))
|
||||
dnodeId = result[0]
|
||||
vnodeId = result[1]
|
||||
|
||||
tdDnodes[dnodeId - 1].stoptaosd()
|
||||
time.sleep(1)
|
||||
dataPath = self.getDataPath()
|
||||
dataPath = dataPath%(dnodeId,vnodeId)
|
||||
tdLog.debug("dataPath:%s"%dataPath)
|
||||
if deleteWal:
|
||||
if os.system('rm -rf ' + dataPath) != 0:
|
||||
tdLog.exit("rm error")
|
||||
|
||||
tdDnodes[dnodeId - 1].starttaosd()
|
||||
time.sleep(1)
|
||||
break
|
||||
tdLog.debug("restart dnode ok")
|
||||
|
||||
def splitVgroups(self):
|
||||
tdSql.query("select * from information_schema.ins_vnodes")
|
||||
vnodeId = 0
|
||||
for result in tdSql.queryResult:
|
||||
if result[2] == 'dbt':
|
||||
vnodeId = result[1]
|
||||
tdLog.debug("vnode is %d"%(vnodeId))
|
||||
break
|
||||
splitSql = "split vgroup %d" %(vnodeId)
|
||||
tdLog.debug("splitSql:%s"%(splitSql))
|
||||
tdSql.query(splitSql)
|
||||
tdLog.debug("splitSql ok")
|
||||
|
||||
def tmqCase1(self, deleteWal=False):
|
||||
tdLog.printNoPrefix("======== test case 1: ")
|
||||
paraDict = {'dbName': 'dbt',
|
||||
'dropFlag': 1,
|
||||
'event': '',
|
||||
'vgroups': 1,
|
||||
'stbName': 'stb',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}],
|
||||
'ctbPrefix': 'ctb1',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 180,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
||||
paraDict['vgroups'] = self.vgroups
|
||||
paraDict['ctbNum'] = self.ctbNum
|
||||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
|
||||
topicNameList = ['topic1']
|
||||
# expectRowsList = []
|
||||
tmqCom.initConsumerTable()
|
||||
|
||||
tdLog.info("create topics from stb with filter")
|
||||
queryString = "select * from %s.%s where c2 >= 0 "%(paraDict['dbName'], paraDict['stbName'])
|
||||
# sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName'])
|
||||
sqlString = "create topic %s as %s" %(topicNameList[0], queryString)
|
||||
tdLog.info("create topic sql: %s"%sqlString)
|
||||
tdSql.execute(sqlString)
|
||||
# tdSql.query(queryString)
|
||||
# expectRowsList.append(tdSql.getRows())
|
||||
|
||||
# init consume info, and start tmq_sim, then check consume result
|
||||
tdLog.info("insert consume info to consume processor")
|
||||
consumerId = 0
|
||||
expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2
|
||||
topicList = topicNameList[0]
|
||||
ifcheckdata = 1
|
||||
ifManualCommit = 1
|
||||
keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:200, auto.offset.reset:earliest'
|
||||
tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit)
|
||||
|
||||
tdLog.info("start consume processor")
|
||||
tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot'])
|
||||
tdLog.info("wait the consume result")
|
||||
|
||||
tdLog.info("create ctb1")
|
||||
tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'],
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx'])
|
||||
|
||||
tdLog.info("create ctb2")
|
||||
paraDict2 = paraDict.copy()
|
||||
paraDict2['ctbPrefix'] = "ctb2"
|
||||
tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict2['ctbPrefix'],
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx'])
|
||||
|
||||
tdLog.info("insert ctb1 data")
|
||||
pInsertThread = tmqCom.asyncInsertDataByInterlace(paraDict)
|
||||
|
||||
tmqCom.getStartConsumeNotifyFromTmqsim()
|
||||
tmqCom.getStartCommitNotifyFromTmqsim()
|
||||
|
||||
#restart dnode & remove wal
|
||||
self.restartAndRemoveWal(deleteWal)
|
||||
|
||||
# split vgroup
|
||||
self.splitVgroups()
|
||||
|
||||
|
||||
tdLog.info("insert ctb2 data")
|
||||
pInsertThread1 = tmqCom.asyncInsertDataByInterlace(paraDict2)
|
||||
pInsertThread.join()
|
||||
pInsertThread1.join()
|
||||
|
||||
expectRows = 1
|
||||
resultList = tmqCom.selectConsumeResult(expectRows)
|
||||
|
||||
if expectrowcnt / 2 > resultList[0]:
|
||||
tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectrowcnt / 2, resultList[0]))
|
||||
tdLog.exit("%d tmq consume rows error!"%consumerId)
|
||||
|
||||
# tmqCom.checkFileContent(consumerId, queryString)
|
||||
|
||||
time.sleep(2)
|
||||
for i in range(len(topicNameList)):
|
||||
tdSql.query("drop topic %s"%topicNameList[i])
|
||||
|
||||
if deleteWal == True:
|
||||
clusterComCheck.check_vgroups_status(vgroup_numbers=2,db_replica=self.replicaVar,db_name="dbt",count_number=240)
|
||||
|
||||
tdLog.printNoPrefix("======== test case 1 end ...... ")
|
||||
|
||||
def run(self):
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(False)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
event = threading.Event()
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -206,8 +206,6 @@ class TDTestCase:
|
|||
def run(self):
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(True)
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(False)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
|
||||
import taos
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
import os
|
||||
import threading
|
||||
import math
|
||||
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.common import *
|
||||
from util.cluster import *
|
||||
sys.path.append("./7-tmq")
|
||||
from tmqCommon import *
|
||||
sys.path.append("./6-cluster")
|
||||
from clusterCommonCreate import *
|
||||
from clusterCommonCheck import clusterComCheck
|
||||
|
||||
class TDTestCase:
|
||||
def __init__(self):
|
||||
self.vgroups = 1
|
||||
self.ctbNum = 10
|
||||
self.rowsPerTbl = 1000
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
tdSql.init(conn.cursor(), True)
|
||||
|
||||
def getDataPath(self):
|
||||
selfPath = tdCom.getBuildPath()
|
||||
|
||||
return selfPath + '/../sim/dnode%d/data/vnode/vnode%d/wal/*';
|
||||
|
||||
def prepareTestEnv(self):
|
||||
tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ")
|
||||
paraDict = {'dbName': 'dbt',
|
||||
'dropFlag': 1,
|
||||
'event': '',
|
||||
'vgroups': 1,
|
||||
'stbName': 'stb',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}],
|
||||
'ctbPrefix': 'ctb',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 180,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
||||
paraDict['vgroups'] = self.vgroups
|
||||
paraDict['ctbNum'] = self.ctbNum
|
||||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
|
||||
tdCom.drop_all_db()
|
||||
tmqCom.initConsumerTable()
|
||||
tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], wal_retention_period=36000,vgroups=paraDict["vgroups"],replica=self.replicaVar)
|
||||
tdLog.info("create stb")
|
||||
tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"])
|
||||
return
|
||||
|
||||
def restartAndRemoveWal(self, deleteWal):
|
||||
tdDnodes = cluster.dnodes
|
||||
tdSql.query("select * from information_schema.ins_vnodes")
|
||||
for result in tdSql.queryResult:
|
||||
if result[2] == 'dbt':
|
||||
tdLog.debug("dnode is %d"%(result[0]))
|
||||
dnodeId = result[0]
|
||||
vnodeId = result[1]
|
||||
|
||||
tdDnodes[dnodeId - 1].stoptaosd()
|
||||
time.sleep(1)
|
||||
dataPath = self.getDataPath()
|
||||
dataPath = dataPath%(dnodeId,vnodeId)
|
||||
tdLog.debug("dataPath:%s"%dataPath)
|
||||
if deleteWal:
|
||||
if os.system('rm -rf ' + dataPath) != 0:
|
||||
tdLog.exit("rm error")
|
||||
|
||||
tdDnodes[dnodeId - 1].starttaosd()
|
||||
time.sleep(1)
|
||||
break
|
||||
tdLog.debug("restart dnode ok")
|
||||
|
||||
def splitVgroups(self):
|
||||
tdSql.query("select * from information_schema.ins_vnodes")
|
||||
vnodeId = 0
|
||||
for result in tdSql.queryResult:
|
||||
if result[2] == 'dbt':
|
||||
vnodeId = result[1]
|
||||
tdLog.debug("vnode is %d"%(vnodeId))
|
||||
break
|
||||
splitSql = "split vgroup %d" %(vnodeId)
|
||||
tdLog.debug("splitSql:%s"%(splitSql))
|
||||
tdSql.query(splitSql)
|
||||
tdLog.debug("splitSql ok")
|
||||
|
||||
def tmqCase1(self, deleteWal=False):
|
||||
tdLog.printNoPrefix("======== test case 1: ")
|
||||
paraDict = {'dbName': 'dbt',
|
||||
'dropFlag': 1,
|
||||
'event': '',
|
||||
'vgroups': 1,
|
||||
'stbName': 'stb',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}],
|
||||
'ctbPrefix': 'ctb1',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 60,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
||||
paraDict['vgroups'] = self.vgroups
|
||||
paraDict['ctbNum'] = self.ctbNum
|
||||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
|
||||
topicNameList = ['topic1']
|
||||
# expectRowsList = []
|
||||
tmqCom.initConsumerTable()
|
||||
|
||||
tdLog.info("create topics from db")
|
||||
queryString = "database %s"%(paraDict['dbName'])
|
||||
# sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName'])
|
||||
sqlString = "create topic %s as %s" %(topicNameList[0], queryString)
|
||||
tdLog.info("create topic sql: %s"%sqlString)
|
||||
tdSql.execute(sqlString)
|
||||
# tdSql.query(queryString)
|
||||
# expectRowsList.append(tdSql.getRows())
|
||||
|
||||
# init consume info, and start tmq_sim, then check consume result
|
||||
tdLog.info("insert consume info to consume processor")
|
||||
consumerId = 0
|
||||
expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2
|
||||
topicList = topicNameList[0]
|
||||
ifcheckdata = 1
|
||||
ifManualCommit = 1
|
||||
keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:200, auto.offset.reset:earliest'
|
||||
tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit)
|
||||
|
||||
tdLog.info("start consume processor")
|
||||
tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot'])
|
||||
tdLog.info("wait the consume result")
|
||||
|
||||
tdLog.info("create ctb1")
|
||||
tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'],
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx'])
|
||||
|
||||
tdLog.info("create ctb2")
|
||||
paraDict2 = paraDict.copy()
|
||||
|
||||
paraDict2['ctbPrefix'] = "ctb2"
|
||||
tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict2['ctbPrefix'],
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx'])
|
||||
|
||||
tdLog.info("insert ctb1 data")
|
||||
pInsertThread = tmqCom.asyncInsertDataByInterlace(paraDict)
|
||||
|
||||
tmqCom.getStartConsumeNotifyFromTmqsim()
|
||||
tmqCom.getStartCommitNotifyFromTmqsim()
|
||||
|
||||
#restart dnode & remove wal
|
||||
self.restartAndRemoveWal(deleteWal)
|
||||
|
||||
# split vgroup
|
||||
self.splitVgroups()
|
||||
|
||||
|
||||
tdLog.info("insert ctb2 data")
|
||||
pInsertThread1 = tmqCom.asyncInsertDataByInterlace(paraDict2)
|
||||
pInsertThread.join()
|
||||
pInsertThread1.join()
|
||||
|
||||
expectRows = 1
|
||||
resultList = tmqCom.selectConsumeResult(expectRows)
|
||||
|
||||
if expectrowcnt / 2 > resultList[0]:
|
||||
tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectrowcnt / 2, resultList[0]))
|
||||
tdLog.exit("%d tmq consume rows error!"%consumerId)
|
||||
|
||||
# tmqCom.checkFileContent(consumerId, queryString)
|
||||
|
||||
time.sleep(2)
|
||||
for i in range(len(topicNameList)):
|
||||
tdSql.query("drop topic %s"%topicNameList[i])
|
||||
|
||||
if deleteWal == True:
|
||||
clusterComCheck.check_vgroups_status(vgroup_numbers=2,db_replica=self.replicaVar,db_name="dbt",count_number=240)
|
||||
|
||||
tdLog.printNoPrefix("======== test case 1 end ...... ")
|
||||
|
||||
def run(self):
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(False)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
event = threading.Event()
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -207,8 +207,6 @@ class TDTestCase:
|
|||
def run(self):
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(True)
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(False)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
|
@ -54,7 +54,7 @@ class TDTestCase:
|
|||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 60,
|
||||
'pollDelay': 180,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
|
|
@ -123,7 +123,7 @@ class TDTestCase:
|
|||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 120,
|
||||
'pollDelay': 180,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
|
Loading…
Reference in New Issue